diff -Nru corosync-2.3.0/ChangeLog corosync-2.3.3/ChangeLog --- corosync-2.3.0/ChangeLog 2013-01-18 08:53:46.000000000 +0000 +++ corosync-2.3.3/ChangeLog 2014-01-14 15:15:26.000000000 +0000 @@ -1,3 +1,642 @@ +2014-01-14 Jan Friesse + + Properly check result of symlink + Error message is displayed when it's impossible to create symlink to + fdata file. + + Reviewed-by: Christine Caulfield + + Fix cppchecks warning + Reviewed-by: Christine Caulfield + + Close devnull file handler + Reviewed-by: Christine Caulfield + +2014-01-14 Christine Caulfield + + 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 + + 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 + Reviewed-by: Jan Friesse + +2014-01-13 Jan Friesse + + 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 + +2014-01-13 Christine Caulfield + + 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 + +2014-01-07 Christine Caulfield + + 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 + + cfgtool: return error on reload failure + If reload fails, return code is set to value >0 to indicate error. + + Reviewed-by: Christine Caulfield + +2013-11-08 Christine Caulfield + + man pages: Note that votequorum's allow_downscale is unsupported + Reviewed-by: Fabio M. Di Nitto + +2013-11-04 Jan Friesse + + 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 + +2013-10-24 Masatake YAMATO + + 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 + +2013-09-20 Yevheniy Demchenko + + 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 + + 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 + + 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 + + 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 + +2013-09-12 Christine Caulfield + + 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 + + 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 + + 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 + + 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 + +2013-09-10 Jan Friesse + + icmap: Add func to test equality of two key values + Reviewed-by: Christine Caulfield + +2013-09-10 Christine Caulfield + + [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 + +2013-09-03 Christine Caulfield + + 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 + +2013-08-29 Jan Friesse + + icmap: Add map copy function + Reviewed-by: Christine Caulfield + + 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 + + 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 + + icmap: Add function to return global icmap + Reviewed-by: Christine Caulfield + +2013-08-27 Jan Friesse + + 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 + +2013-08-19 Michael Chapman + + 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 + +2013-07-10 Jan Friesse + + Remove dir pragma for xml2conf.xsl in specfile + Reviewed-by: Fabio M. Di Nitto + +2013-07-09 Jan Friesse + + cts: Update DC_IDLE pattern + +2013-07-08 Kazunori INOUE + + Use restart policy in the corosync-notifyd unit + Reviewed-by: Jan Friesse + +2013-07-04 David Vossel + + ipc_glue: proper ref counting during service connection iteration + Reviewed-by: Jan Friesse + + 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 + + ipc_glue: Fixes connection ref count leak + Reviewed-by: Jan Friesse + +2013-07-01 Kazunori INOUE + + systemd: fix typo in unit file + Reviewed-by: Jan Friesse + + notifyd: fix handle dispatch functions results + Reviewed-by: Jan Friesse + +2013-06-27 Christine Caulfield + + 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 + Reviewed-By: Jan Friesse + +2013-06-21 Jan Friesse + + 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 + + totemconfig: Prevent leak of cluster_name str + Reviewed-by: Christine Caulfield + + service: Fix memleak in service_unlink_and_exit + Reviewed-by: Christine Caulfield + +2013-06-20 Eric Raymond + + 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 + +2013-06-18 Jan Friesse + + cpg: Set umask in memory_map function + Reviewed-by: Christine Caulfield + + ipc_glue: Check service name len + Reviewed-by: Christine Caulfield + + ipc_glue: Introduce constant for service name len + Reviewed-by: Christine Caulfield + + cfg: Check interface status and name length + Reviewed-by: Christine Caulfield + + cfg: Check number of interfaces + Reviewed-by: Christine Caulfield + + cfg: Introduce CFG_MAX constants + Instead of magic numbers, use constant. + + Reviewed-by: Christine Caulfield + + totemrrp: Make status string shorter + Status string should be same lenght as needed for cfg + ringstatusget function. + + Reviewed-by: Christine Caulfield + + totem: Don't leak instance variable on crypto fail + Reviewed-by: Fabio M. Di Nitto + + totemudpu: Handle fd leak in totemudpu + Reviewed-by: Fabio M. Di Nitto + + totemconfig: Check length of rrp_mode string + Reviewed-by: Fabio M. Di Nitto + + coroparse: Ensure that config items fits into cmap + Reviewed-by: Fabio M. Di Nitto + + cpg: Check cpg zc buffer path name length + Reviewed-by: Fabio M. Di Nitto + +2013-06-17 Jan Friesse + + votequorum: Prevent leak in qdevice_is_configured + Also LEAVE from function is now properly logged. + + Reviewed-by: Fabio M. Di Nitto + +2013-06-13 Jan Friesse + + ipc_cfg: Make coverity happy + Reviewed-by: Fabio M. Di Nitto + + Initialize error variable in ykd_init + Reviewed-by: Fabio M. Di Nitto + + Initialize node_found in nodelist_to_interface fun + Reviewed-by: Fabio M. Di Nitto + + Initialize item in cmap_mcast_send + Reviewed-by: Fabio M. Di Nitto + + cmapctl: Remove unnecessary access check + Reviewed-by: Fabio M. Di Nitto + + votequrorum: Assert sender nodeid is known + Reviewed-by: Fabio M. Di Nitto + + 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 + + Handle errors when getting SC_PAGESIZE + Reviewed-by: Fabio M. Di Nitto + + Check result of logsys_subsys_create + Reviewed-by: Fabio M. Di Nitto + + Check logsys_format_set result in logsys setup + Reviewed-by: Fabio M. Di Nitto + + Use proper totem_ip_address size in memset + Reviewed-by: Fabio M. Di Nitto + + Free icmap strings in logconfig + Reviewed-by: Fabio M. Di Nitto + + Properly break MAIN_CP_CB_DATA_STATE_QDEVICE state + Reviewed-by: Fabio M. Di Nitto + + Do not dereference format_buffer when it's NULL + Reviewed-by: Fabio M. Di Nitto + + 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 + + Handle dispatch functions results + On error, exit corosync-notifyd properly. + + Reviewed-by: Fabio M. Di Nitto + + Properly check result of stat func in coroparse + Reviewed-by: Fabio M. Di Nitto + + testcpg: Check length of input group name + Reviewed-by: Fabio M. Di Nitto + + common ta: Close client sockets + Reviewed-by: Fabio M. Di Nitto + + common ta: Close listener socket + Reviewed-by: Fabio M. Di Nitto + + test sam: Free temp str allocated by cmap + Reviewed-by: Fabio M. Di Nitto + + sam test agent: Assert results of send func + Reviewed-by: Fabio M. Di Nitto + + votequorum test agent: Assert results of send func + Reviewed-by: Fabio M. Di Nitto + + cpg test agent: Test len of name for cpg_join + Reviewed-by: Fabio M. Di Nitto + + cpg test agent: Cfg shutdown flag is not bitfield + Reviewed-by: Fabio M. Di Nitto + + cpg test agent: Assert results of send function + Reviewed-by: Fabio M. Di Nitto + + cpg test agent: Fix typo in assert + Assert should compare rc, instead of setting it. + + Reviewed-by: Fabio M. Di Nitto + + 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 + +2013-05-24 Michael van der Westhuizen + + Allow corotypes.h to be included from C++ code. + +2013-05-21 Jan Friesse + + 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 + Reviewed-by: Fabio M. Di Nitto + +2013-04-16 Jan Friesse + + Install sysconfig/corosync-notifyd in specfile + Reviewed-by: Fabio M. Di Nitto + + 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 + +2013-04-12 Masatake YAMATO + + Fix a typo in README.recovery + Fix a typo. + + Reviewed-by: Jan Friesse + +2013-04-10 Kazunori INOUE + + Add Upstart job configuration file + Reviewed-by: Fabio M. Di Nitto + +2013-04-08 Jan Friesse + + 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 + +2013-04-03 Andrei Belov + + 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 + +2013-04-02 Jan Friesse + + Support for numerical uid/gid + Reviewed-by: Fabio M. Di Nitto + +2013-04-02 Yuichi SEINO + + build: pass enable options to "make rpm" from configure + Reviewed-by: Fabio M. Di Nitto + +2013-03-28 Andrei Belov + + Improved POSIX-compliant handling of getpwnam_r() and getgrnam_r(). + Reviewed-by: Jan Friesse + +2013-03-27 Jan Friesse + + Make cts work with pacemaker 1.1.9 + This is counterpart of adcc21a30c70a40861736bc9d902c2ef2d4b42c4 in + pacemaker. + +2013-03-21 Jan Friesse + + totempg: Make iov_delv local variable + Reviewed-by: Fabio M. Di Nitto + + 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 + +2013-03-20 Jan Friesse + + cts: Output nodeid consistently as unsigned int + Reviewed-by: Fabio M. Di Nitto + +2013-03-19 Xia Li + + 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 + +2013-03-08 Jeremy Fitzhardinge + + 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 + + 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 + +2013-01-31 Jan Friesse + + 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 + + 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 + +2013-01-31 Fabio M. Di Nitto + + votequorum: port to sync API (take 2) + Reviewed-by: Jan Friesse + 2013-01-14 Fabio M. Di Nitto crypto config: update man pages and examples diff -Nru corosync-2.3.0/common_lib/Makefile.in corosync-2.3.3/common_lib/Makefile.in --- corosync-2.3.0/common_lib/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/common_lib/Makefile.in 2014-01-14 15:15:13.000000000 +0000 @@ -237,8 +237,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/conf/Makefile.in corosync-2.3.3/conf/Makefile.in --- corosync-2.3.0/conf/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/conf/Makefile.in 2014-01-14 15:15:13.000000000 +0000 @@ -211,8 +211,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/configure corosync-2.3.3/configure --- corosync-2.3.0/configure 2013-01-18 08:53:32.000000000 +0000 +++ corosync-2.3.3/configure 2014-01-14 15:15:12.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.63 for corosync 2.3.0. +# Generated by GNU Autoconf 2.63 for corosync 2.3.3. # # Report bugs to . # @@ -745,8 +745,8 @@ # Identity of this package. PACKAGE_NAME='corosync' PACKAGE_TARNAME='corosync' -PACKAGE_VERSION='2.3.0' -PACKAGE_STRING='corosync 2.3.0' +PACKAGE_VERSION='2.3.3' +PACKAGE_STRING='corosync 2.3.3' PACKAGE_BUGREPORT='discuss@lists.corosync.org' # Factoring default headers for most tests. @@ -807,8 +807,10 @@ SOMINOR SOMAJOR INITWRAPPERSDIR +UPSTARTDIR SYSTEMDDIR INITDDIR +VERSCRIPT_LDFLAGS BUILD_SNMP_FALSE BUILD_SNMP_TRUE SNMP_LIBS @@ -825,6 +827,8 @@ BUILD_QDEVICES_TRUE INSTALL_XMLCONF_FALSE INSTALL_XMLCONF_TRUE +INSTALL_UPSTART_FALSE +INSTALL_UPSTART_TRUE INSTALL_SYSTEMD_FALSE INSTALL_SYSTEMD_TRUE INSTALL_AUGEAS_FALSE @@ -861,6 +865,7 @@ ac_ct_CXX CXXFLAGS CXX +WITH_LIST AM_BACKSLASH AM_DEFAULT_VERBOSITY OTOOL64 @@ -993,8 +998,10 @@ enable_watchdog enable_augeas enable_systemd +enable_upstart with_initddir with_systemddir +with_upstartdir with_initwrappersdir enable_snmp enable_xmlconf @@ -1578,7 +1585,7 @@ # 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 2.3.0 to adapt to many kinds of systems. +\`configure' configures corosync 2.3.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1648,7 +1655,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of corosync 2.3.0:";; + short | recursive ) echo "Configuration of corosync 2.3.3:";; esac cat <<\_ACEOF @@ -1682,6 +1689,7 @@ --enable-watchdog : Watchdog support --enable-augeas : Install the augeas lens for corosync.conf --enable-systemd : Install systemd service files + --enable-upstart : Install upstart service files --enable-snmp : SNMP protocol support --enable-xmlconf : XML configuration support --enable-qdevices : Quorum devices support @@ -1694,6 +1702,7 @@ --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-initddir=DIR : path to init script directory. --with-systemddir=DIR : path to systemd unit files directory. + --with-upstartdir=DIR : path to upstart config files directory. --with-initwrappersdir=DIR : path to init wrappers files directory. Some influential environment variables: @@ -1794,7 +1803,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -corosync configure 2.3.0 +corosync configure 2.3.3 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1808,7 +1817,7 @@ 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 2.3.0, which was +It was created by corosync $as_me 2.3.3, which was generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ @@ -4511,7 +4520,7 @@ # Define the identity of the package. PACKAGE='corosync' - VERSION='2.3.0' + VERSION='2.3.3' cat >>confdefs.h <<_ACEOF @@ -5248,13 +5257,13 @@ else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:5251: $ac_compile\"" >&5) + (eval echo "\"\$as_me:5260: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:5254: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:5263: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:5257: output\"" >&5) + (eval echo "\"\$as_me:5266: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -6459,7 +6468,7 @@ ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6462 "configure"' > conftest.$ac_ext + echo '#line 6471 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7828,11 +7837,11 @@ -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:7831: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7840: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7835: \$? = $ac_status" >&5 + echo "$as_me:7844: \$? = $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. @@ -8167,11 +8176,11 @@ -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:8170: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8179: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8174: \$? = $ac_status" >&5 + echo "$as_me:8183: \$? = $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. @@ -8272,11 +8281,11 @@ -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:8275: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8284: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8279: \$? = $ac_status" >&5 + echo "$as_me:8288: \$? = $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 @@ -8327,11 +8336,11 @@ -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:8330: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8339: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8334: \$? = $ac_status" >&5 + echo "$as_me:8343: \$? = $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 @@ -11130,7 +11139,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11133 "configure" +#line 11142 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11226,7 +11235,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11229 "configure" +#line 11238 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11517,6 +11526,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +WITH_LIST="" + #Enable inter-library dependencies # Check whether --enable-interlib-deps was given. @@ -15311,11 +15322,11 @@ -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:15314: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15325: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15318: \$? = $ac_status" >&5 + echo "$as_me:15329: \$? = $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. @@ -15410,11 +15421,11 @@ -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:15413: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15424: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15417: \$? = $ac_status" >&5 + echo "$as_me:15428: \$? = $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 @@ -15462,11 +15473,11 @@ -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:15465: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15476: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15469: \$? = $ac_status" >&5 + echo "$as_me:15480: \$? = $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 @@ -23533,6 +23544,22 @@ fi +# Check whether --enable-upstart was given. +if test "${enable_upstart+set}" = set; then + enableval=$enable_upstart; +else + enable_upstart="no" +fi + + if test x$enable_upstart = xyes; then + INSTALL_UPSTART_TRUE= + INSTALL_UPSTART_FALSE='#' +else + INSTALL_UPSTART_TRUE='#' + INSTALL_UPSTART_FALSE= +fi + + # Check whether --with-initddir was given. if test "${with_initddir+set}" = set; then @@ -23552,6 +23579,15 @@ +# Check whether --with-upstartdir was given. +if test "${with_upstartdir+set}" = set; then + withval=$with_upstartdir; UPSTARTDIR="$withval" +else + UPSTARTDIR="$sysconfdir/init" +fi + + + # Check whether --with-initwrappersdir was given. if test "${with_initwrappersdir+set}" = set; then withval=$with_initwrappersdir; INITWRAPPERSDIR="$withval" @@ -23741,6 +23777,7 @@ _ACEOF PACKAGE_FEATURES="$PACKAGE_FEATURES dbus" + WITH_LIST="$WITH_LIST --with dbus" fi if test "x${enable_testagents}" = xyes; then @@ -23750,6 +23787,7 @@ _ACEOF PACKAGE_FEATURES="$PACKAGE_FEATURES testagents" + WITH_LIST="$WITH_LIST --with testagents" fi if test "x${enable_rdma}" = xyes; then @@ -23977,6 +24015,7 @@ _ACEOF PACKAGE_FEATURES="$PACKAGE_FEATURES rdma" + WITH_LIST="$WITH_LIST --with rdma" fi if test "x${enable_monitoring}" = xyes; then @@ -24095,6 +24134,7 @@ _ACEOF PACKAGE_FEATURES="$PACKAGE_FEATURES monitoring" + WITH_LIST="$WITH_LIST --with monitoring" fi if test "x${enable_watchdog}" = xyes; then @@ -24386,6 +24426,7 @@ _ACEOF PACKAGE_FEATURES="$PACKAGE_FEATURES watchdog" + WITH_LIST="$WITH_LIST --with watchdog" fi if test "x${enable_augeas}" = xyes; then @@ -24393,9 +24434,15 @@ fi if test "x${enable_systemd}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES systemd" + WITH_LIST="$WITH_LIST --with systemd" +fi +if test "x${enable_upstart}" = xyes; then + PACKAGE_FEATURES="$PACKAGE_FEATURES upstart" + WITH_LIST="$WITH_LIST --with upstart" fi if test "x${enable_xmlconf}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES xmlconf" + WITH_LIST="$WITH_LIST --with xmlconf" fi if test "x${enable_qdevices}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES qdevices" @@ -24846,6 +24893,7 @@ do_snmp=1 PACKAGE_FEATURES="$PACKAGE_FEATURES snmp" + WITH_LIST="$WITH_LIST --with snmp" cat >>confdefs.h <<_ACEOF #define ENABLE_SNMP $do_snmp @@ -25149,6 +25197,136 @@ fi fi +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts \"--as-needed\"" >&5 +$as_echo_n "checking whether $CC accepts \"--as-needed\"... " >&6; } +if test "${ap_cv_cc_as_needed+set}" = set; 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +static int foo[30000]; int main () { return 0; } +_ACEOF +rm -f 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:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ap_cv_cc_as_needed=yes +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 + +( exit $ac_status ) +ap_cv_cc_as_needed=no +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:$LINENO: result: $ap_cv_cc_as_needed" >&5 +$as_echo "$ap_cv_cc_as_needed" >&6; } + +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts \"--version-script\"" >&5 +$as_echo_n "checking whether $CC accepts \"--version-script\"... " >&6; } +if test "${ap_cv_cc_version_script+set}" = set; 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +static int foo[30000]; int main () { return 0; } +_ACEOF +rm -f 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:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ap_cv_cc_version_script=yes +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 + +( exit $ac_status ) +ap_cv_cc_version_script=no +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + rm -f conftest.versions + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:$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" @@ -25160,12 +25338,17 @@ $WERROR_CFLAGS $NSS_CFLAGS $LIBQB_CFLAGS \ $SNMP_INCLUDES" CPPFLAGS="$ENV_CPPFLAGS $ANSI_CPPFLAGS $INCLUDE_DIRS" -LDFLAGS="$ENV_LDFLAGS $lt_prog_compiler_pic $SEC_LDFLAGS -Wl,--as-needed $COVERAGE_LDFLAGS" +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: + INITWRAPPERSDIR=$(eval echo ${INITWRAPPERSDIR}) @@ -25174,7 +25357,7 @@ - if test -n "${enable_testagents}"; then + if test "${enable_testagents}" = "yes"; then INSTALL_TESTAGENTS_TRUE= INSTALL_TESTAGENTS_FALSE='#' else @@ -25407,6 +25590,13 @@ Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${INSTALL_UPSTART_TRUE}" && test -z "${INSTALL_UPSTART_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"INSTALL_UPSTART\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"INSTALL_UPSTART\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${INSTALL_XMLCONF_TRUE}" && test -z "${INSTALL_XMLCONF_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"INSTALL_XMLCONF\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -25785,7 +25975,7 @@ # 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 2.3.0, which was +This file was extended by corosync $as_me 2.3.3, which was generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25848,7 +26038,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -corosync config.status 2.3.0 +corosync config.status 2.3.3 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" @@ -28002,6 +28192,8 @@ $as_echo " System init.d directory = ${INITDDIR}" >&6; } { $as_echo "$as_me:$LINENO: result: System systemd directory = ${SYSTEMDDIR}" >&5 $as_echo " System systemd directory = ${SYSTEMDDIR}" >&6; } +{ $as_echo "$as_me:$LINENO: result: System upstart directory = ${UPSTARTDIR}" >&5 +$as_echo " System upstart directory = ${UPSTARTDIR}" >&6; } { $as_echo "$as_me:$LINENO: result: System init wraps dir = ${INITWRAPPERSDIR}" >&5 $as_echo " System init wraps dir = ${INITWRAPPERSDIR}" >&6; } { $as_echo "$as_me:$LINENO: result: corosync config dir = ${COROSYSCONFDIR}" >&5 diff -Nru corosync-2.3.0/configure.ac corosync-2.3.3/configure.ac --- corosync-2.3.0/configure.ac 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/configure.ac 2014-01-13 13:46:11.000000000 +0000 @@ -25,6 +25,7 @@ AC_LANG([C]) +AC_SUBST(WITH_LIST, [""]) #Enable inter-library dependencies AC_ARG_ENABLE(interlib-deps, @@ -342,6 +343,11 @@ [ enable_systemd="no" ]) AM_CONDITIONAL(INSTALL_SYSTEMD, test x$enable_systemd = xyes) +AC_ARG_ENABLE([upstart], + [ --enable-upstart : Install upstart service files],, + [ enable_upstart="no" ]) +AM_CONDITIONAL(INSTALL_UPSTART, test x$enable_upstart = xyes) + AC_ARG_WITH([initddir], [ --with-initddir=DIR : path to init script directory. ], [ INITDDIR="$withval" ], @@ -352,6 +358,11 @@ [ SYSTEMDDIR="$withval" ], [ SYSTEMDDIR="/lib/systemd/system" ]) +AC_ARG_WITH([upstartdir], + [ --with-upstartdir=DIR : path to upstart config files directory. ], + [ UPSTARTDIR="$withval" ], + [ UPSTARTDIR="$sysconfdir/init" ]) + AC_ARG_WITH([initwrappersdir], [ --with-initwrappersdir=DIR : path to init wrappers files directory. ], [ INITWRAPPERSDIR="$withval" ], @@ -398,11 +409,13 @@ 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_testagents}" = xyes; then AC_DEFINE_UNQUOTED([HAVE_TESTAGENTS], 1, [have testagents]) PACKAGE_FEATURES="$PACKAGE_FEATURES testagents" + WITH_LIST="$WITH_LIST --with testagents" fi if test "x${enable_rdma}" = xyes; then @@ -410,12 +423,14 @@ PKG_CHECK_MODULES([ibverbs],[ibverbs]) AC_DEFINE_UNQUOTED([HAVE_RDMA], 1, [have rdmacm]) PACKAGE_FEATURES="$PACKAGE_FEATURES rdma" + WITH_LIST="$WITH_LIST --with rdma" fi if test "x${enable_monitoring}" = xyes; then PKG_CHECK_MODULES([statgrab], [libstatgrab]) 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 @@ -423,6 +438,7 @@ 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 @@ -430,9 +446,15 @@ fi if test "x${enable_systemd}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES systemd" + WITH_LIST="$WITH_LIST --with systemd" +fi +if test "x${enable_upstart}" = xyes; then + PACKAGE_FEATURES="$PACKAGE_FEATURES upstart" + WITH_LIST="$WITH_LIST --with upstart" fi if test "x${enable_xmlconf}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES xmlconf" + WITH_LIST="$WITH_LIST --with xmlconf" fi if test "x${enable_qdevices}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES qdevices" @@ -477,6 +499,7 @@ 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.]) @@ -601,6 +624,28 @@ fi fi +AC_CACHE_CHECK([whether $CC accepts "--as-needed"], [ap_cv_cc_as_needed], [ + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,--as-needed" + AC_TRY_RUN([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_TRY_RUN([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" @@ -612,12 +657,17 @@ $WERROR_CFLAGS $NSS_CFLAGS $LIBQB_CFLAGS \ $SNMP_INCLUDES" CPPFLAGS="$ENV_CPPFLAGS $ANSI_CPPFLAGS $INCLUDE_DIRS" -LDFLAGS="$ENV_LDFLAGS $lt_prog_compiler_pic $SEC_LDFLAGS -Wl,--as-needed $COVERAGE_LDFLAGS" +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([UPSTARTDIR]) INITWRAPPERSDIR=$(eval echo ${INITWRAPPERSDIR}) AC_SUBST([INITWRAPPERSDIR]) @@ -626,7 +676,7 @@ AC_SUBST([SOMICRO]) AC_SUBST([SONAME]) -AM_CONDITIONAL(INSTALL_TESTAGENTS, test -n "${enable_testagents}") +AM_CONDITIONAL(INSTALL_TESTAGENTS, test "${enable_testagents}" = "yes") AM_CONDITIONAL(INSTALL_MIB, test "${do_snmp}" = "1") AM_CONDITIONAL(INSTALL_DBUSCONF, test "${enable_dbus}" = "yes") AM_CONDITIONAL(AUGTOOL, test -n "${AUGTOOL}") @@ -660,6 +710,7 @@ AC_MSG_RESULT([ System configuration = ${sysconfdir}]) AC_MSG_RESULT([ System init.d directory = ${INITDDIR}]) AC_MSG_RESULT([ System systemd directory = ${SYSTEMDDIR}]) +AC_MSG_RESULT([ System upstart directory = ${UPSTARTDIR}]) AC_MSG_RESULT([ System init wraps dir = ${INITWRAPPERSDIR}]) AC_MSG_RESULT([ corosync config dir = ${COROSYSCONFDIR}]) AC_MSG_RESULT([ Features =${PACKAGE_FEATURES}]) diff -Nru corosync-2.3.0/corosync.spec.in corosync-2.3.3/corosync.spec.in --- corosync-2.3.0/corosync.spec.in 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/corosync.spec.in 2014-01-13 13:46:11.000000000 +0000 @@ -12,6 +12,7 @@ %bcond_with dbus %bcond_with rdma %bcond_with systemd +%bcond_with upstart %bcond_with xmlconf %bcond_with runautogen @@ -102,11 +103,15 @@ %if %{with systemd} --enable-systemd \ %endif +%if %{with upstart} + --enable-upstart \ +%endif %if %{with xmlconf} --enable-xmlconf \ %endif --with-initddir=%{_initrddir} \ - --with-systemddir=%{_unitdir} + --with-systemddir=%{_unitdir} \ + --with-upstartdir=%{_sysconfdir}/init make %{_smp_mflags} @@ -126,6 +131,10 @@ 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 %clean rm -rf %{buildroot} @@ -173,7 +182,7 @@ %{_bindir}/corosync-xmlproc %config(noreplace) %{_sysconfdir}/corosync/corosync.xml.example %dir %{_datadir}/corosync -%dir %{_datadir}/corosync/xml2conf.xsl +%{_datadir}/corosync/xml2conf.xsl %{_mandir}/man8/corosync-xmlproc.8* %{_mandir}/man5/corosync.xml.5* %endif @@ -181,6 +190,7 @@ %dir %{_sysconfdir}/corosync/uidgid.d %config(noreplace) %{_sysconfdir}/corosync/corosync.conf.example %config(noreplace) %{_sysconfdir}/corosync/corosync.conf.example.udpu +%config(noreplace) %{_sysconfdir}/sysconfig/corosync-notifyd %if %{with dbus} %{_sysconfdir}/dbus-1/system.d/corosync-signals.conf %endif @@ -197,6 +207,10 @@ %{_initrddir}/corosync %{_initrddir}/corosync-notifyd %endif +%if %{with upstart} +%{_sysconfdir}/init/corosync.conf +%{_sysconfdir}/init/corosync-notifyd.conf +%endif %dir %{_localstatedir}/lib/corosync %dir %{_localstatedir}/log/cluster %{_mandir}/man8/corosync_overview.8* diff -Nru corosync-2.3.0/cts/agents/common_test_agent.c corosync-2.3.3/cts/agents/common_test_agent.c --- corosync-2.3.0/cts/agents/common_test_agent.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/cts/agents/common_test_agent.c 2014-01-13 13:46:11.000000000 +0000 @@ -49,10 +49,14 @@ #include "common_test_agent.h" +#define MAX_CLIENTS 64 + static char big_and_buf_rx[HOW_BIG_AND_BUF]; ta_do_command_fn do_command; static qb_loop_t *poll_handle; static pre_exit_fn pre_exit = NULL; +static int client_fds[MAX_CLIENTS]; +static int client_fds_pos = 0; qb_loop_t *ta_poll_handle_get(void) { @@ -184,6 +188,10 @@ return (0); /* This is an error, but -1 would indicate disconnect from poll loop */ } + client_fds[client_fds_pos] = new_fd; + client_fds_pos++; + assert(client_fds_pos < MAX_CLIENTS); + qb_loop_poll_add (poll_handle, QB_LOOP_MED, new_fd, @@ -283,6 +291,7 @@ ta_do_command_fn func, pre_exit_fn exit_fn) { int listener; + int i; qb_log_init(prog_name, LOG_DAEMON, LOG_DEBUG); qb_log_format_set(QB_LOG_SYSLOG, "%n() [%p] %b"); @@ -311,6 +320,12 @@ qb_loop_run (poll_handle); + close(listener); + + for (i = 0; i < client_fds_pos; i++) { + close(client_fds[client_fds_pos]); + } + qb_log (LOG_INFO, "EXITING"); qb_log_fini(); return 0; diff -Nru corosync-2.3.0/cts/agents/cpg_test_agent.c corosync-2.3.3/cts/agents/cpg_test_agent.c --- corosync-2.3.0/cts/agents/cpg_test_agent.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/cts/agents/cpg_test_agent.c 2014-01-13 13:46:11.000000000 +0000 @@ -178,7 +178,7 @@ log_pt = malloc (sizeof(log_entry_t)); list_init (&log_pt->list); - snprintf (log_pt->log, LOG_STR_SIZE, "%d:%d:%d:%s;", + snprintf (log_pt->log, LOG_STR_SIZE, "%u:%d:%d:%s;", msg_pt->nodeid, msg_pt->seq, my_seq, err_status_string (status_buf, 20, status)); list_add_tail (&log_pt->list, &msg_log_head); @@ -212,7 +212,7 @@ if (record_config_events_g > 0) { log_pt = malloc (sizeof(log_entry_t)); list_init (&log_pt->list); - snprintf (log_pt->log, LOG_STR_SIZE, "%s,%d,%d,left", + snprintf (log_pt->log, LOG_STR_SIZE, "%s,%u,%u,left", groupName->value, left_list[i].nodeid,left_list[i].pid); list_add_tail(&log_pt->list, &config_chg_log_head); qb_log (LOG_INFO, "cpg event %s", log_pt->log); @@ -222,7 +222,7 @@ if (record_config_events_g > 0) { log_pt = malloc (sizeof(log_entry_t)); list_init (&log_pt->list); - snprintf (log_pt->log, LOG_STR_SIZE, "%s,%d,%d,join", + snprintf (log_pt->log, LOG_STR_SIZE, "%s,%u,%u,join", groupName->value, joined_list[i].nodeid,joined_list[i].pid); list_add_tail (&log_pt->list, &config_chg_log_head); qb_log (LOG_INFO, "cpg event %s", log_pt->log); @@ -239,7 +239,7 @@ corosync_cfg_shutdown_flags_t flags) { qb_log (LOG_CRIT, "flags:%d", flags); - if (flags & COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST) { + if (flags == COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST) { corosync_cfg_replyto_shutdown (cfg_handle, COROSYNC_CFG_SHUTDOWN_FLAG_YES); } } @@ -262,12 +262,16 @@ static void record_config_events (int sock) { char response[100]; + ssize_t rc; + size_t send_len; record_config_events_g = 1; qb_log (LOG_INFO, "record:%d", record_config_events_g); snprintf (response, 100, "%s", OK_STR); - send (sock, response, strlen (response), 0); + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } static void read_config_event (int sock) @@ -275,16 +279,21 @@ const char *empty = "None"; struct list_head * list = config_chg_log_head.next; log_entry_t *entry; + ssize_t rc; + size_t send_len; if (list != &config_chg_log_head) { entry = list_entry (list, log_entry_t, list); - send (sock, entry->log, strlen (entry->log), 0); + send_len = strlen (entry->log); + rc = send (sock, entry->log, send_len, 0); list_del (&entry->list); free (entry); } else { qb_log (LOG_DEBUG, "no events in list"); - send (sock, empty, strlen (empty), 0); + send_len = strlen (empty); + rc = send (sock, empty, send_len, 0); } + assert(rc == send_len); } static void read_messages (int sock, char* atmost_str) @@ -325,7 +334,7 @@ } } rc = send (sock, big_and_buf, strlen (big_and_buf), 0); - assert(rc = strlen (big_and_buf)); + assert(rc == strlen (big_and_buf)); } static qb_loop_timer_handle more_messages_timer_handle; @@ -529,6 +538,8 @@ { char response[100]; char *cmp; + ssize_t rc; + size_t send_len; cpg_context_set (cpg_handle, response); cpg_context_get (cpg_handle, (void**)&cmp); @@ -538,7 +549,9 @@ else { snprintf (response, 100, "%s", OK_STR); } - send (sock, response, strlen (response), 0); + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } static void msg_blaster_zcb (int sock, char* num_to_send_str) @@ -614,6 +627,8 @@ int result; char response[100]; struct cpg_name group_name; + ssize_t rc; + size_t send_len; qb_log (LOG_TRACE, "RPC:%s() called.", func); @@ -628,7 +643,10 @@ cpg_mcast_joined (cpg_handle, CPG_TYPE_AGREED, iov, num_args); } else if (strcmp ("cpg_join",func) == 0) { - + if (strlen(args[0]) >= CPG_MAX_NAME_LENGTH) { + qb_log (LOG_ERR, "Invalid group name"); + exit (1); + } strcpy (group_name.value, args[0]); group_name.length = strlen(args[0]); result = cpg_join (cpg_handle, &group_name); @@ -681,7 +699,9 @@ cpg_local_get (cpg_handle, &local_nodeid); snprintf (response, 100, "%u",local_nodeid); - send (sock, response, strlen (response), 0); + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } else if (strcmp ("cpg_finalize", func) == 0) { if (cpg_handle > 0) { @@ -707,8 +727,9 @@ context_test (sock); } else if (strcmp ("are_you_ok_dude", func) == 0) { snprintf (response, 100, "%s", OK_STR); - send (sock, response, strlen (response), 0); - + send_len = strlen (response); + rc = send (sock, response, strlen (response), 0); + assert(rc == send_len); } else if (strcmp ("cfg_shutdown", func) == 0) { qb_log (LOG_INFO, "calling %s() called!", func); diff -Nru corosync-2.3.0/cts/agents/Makefile.in corosync-2.3.3/cts/agents/Makefile.in --- corosync-2.3.0/cts/agents/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/cts/agents/Makefile.in 2014-01-14 15:15:13.000000000 +0000 @@ -269,8 +269,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/cts/agents/sam_test_agent.c corosync-2.3.3/cts/agents/sam_test_agent.c --- corosync-2.3.0/cts/agents/sam_test_agent.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/cts/agents/sam_test_agent.c 2014-01-13 13:46:11.000000000 +0000 @@ -808,6 +808,7 @@ if (strcmp(str, "quit") != 0) { qb_log (LOG_INFO, "Recovery key \"%s\" is not \"quit\".", key_name); + free(str); return (2); } free(str); @@ -821,6 +822,7 @@ if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); + free(str); return (2); } free(str); @@ -840,6 +842,7 @@ if (strcmp(str, "running") != 0) { qb_log (LOG_INFO, "State key is not \"running\"."); + free(str); return (2); } free(str); @@ -859,6 +862,7 @@ if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); + free(str); return (2); } free(str); @@ -874,6 +878,7 @@ if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); + free(str); return (2); } free(str); @@ -893,6 +898,7 @@ if (strcmp(str, "running") != 0) { qb_log (LOG_INFO, "State key is not \"running\"."); + free(str); return (2); } free(str); @@ -952,6 +958,7 @@ if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); + free(str); return (2); } free(str); @@ -977,8 +984,10 @@ if (strcmp(str, "failed") != 0) { qb_log (LOG_INFO, "State key is not \"failed\"."); + free(str); return (2); } + free(str); return (0); } @@ -1030,6 +1039,7 @@ if (strcmp(str, "restart") != 0) { qb_log (LOG_INFO, "Recovery key \"%s\" is not \"restart\".", str); + free(str); return (2); } free(str); @@ -1043,6 +1053,7 @@ if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); + free(str); return (2); } free(str); @@ -1062,6 +1073,7 @@ if (strcmp(str, "running") != 0) { qb_log (LOG_INFO, "State key is not \"running\"."); + free(str); return (2); } free(str); @@ -1103,6 +1115,7 @@ if (strcmp(str, "failed") != 0) { qb_log (LOG_INFO, "State key is not \"failed\"."); + free(str); return (2); } free(str); @@ -1196,6 +1209,8 @@ { char response[100]; int err = 0; + ssize_t rc; + size_t send_len; qb_log (LOG_INFO, "RPC:%s() called.", func); if (strncmp ("test", func, 4) == 0) { @@ -1225,7 +1240,9 @@ snprintf (response, 100, "%s", FAIL_STR); qb_log (LOG_ERR, "%s() failed (%d).", func, err); } - send (sock, response, strlen (response) + 1, 0); + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } int diff -Nru corosync-2.3.0/cts/agents/votequorum_test_agent.c corosync-2.3.3/cts/agents/votequorum_test_agent.c --- corosync-2.3.0/cts/agents/votequorum_test_agent.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/cts/agents/votequorum_test_agent.c 2014-01-13 13:46:11.000000000 +0000 @@ -172,6 +172,8 @@ int ret; struct votequorum_info info; char response[100]; + ssize_t rc; + size_t send_len; q_lib_init (); @@ -190,7 +192,9 @@ info.quorum); send_response: - send (sock, response, strlen (response), 0); + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } @@ -198,6 +202,8 @@ { int ret; char response[100]; + ssize_t rc; + size_t send_len; q_lib_init (); @@ -211,13 +217,17 @@ snprintf (response, 100, "%s", OK_STR); send_response: - send (sock, response, strlen (response) + 1, 0); + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } static void setvotes (int sock, char *arg) { int ret; char response[100]; + ssize_t rc; + size_t send_len; q_lib_init (); @@ -231,7 +241,9 @@ snprintf (response, 100, "%s", OK_STR); send_response: - send (sock, response, strlen (response), 0); + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } @@ -240,6 +252,8 @@ int ret; int quorate; char response[100]; + ssize_t rc; + size_t send_len; q_lib_init (); @@ -253,7 +267,9 @@ snprintf (response, 100, "%d", quorate); send_response: - send (sock, response, strlen (response), 0); + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } static void context_test (int sock) @@ -262,6 +278,8 @@ char *cmp; cs_error_t rc1; cs_error_t rc2; + ssize_t send_rc; + size_t send_len; snprintf (response, 100, "%s", OK_STR); @@ -280,12 +298,16 @@ qb_log (LOG_ERR, "quorum context not the same %d %d", rc1, rc2); } - send (sock, response, strlen (response) + 1, 0); + send_len = strlen (response); + send_rc = send (sock, response, send_len, 0); + assert(send_rc == send_len); } static void do_command (int sock, char* func, char*args[], int num_args) { char response[100]; + ssize_t rc; + size_t send_len; q_lib_init (); @@ -304,12 +326,18 @@ } else if (strcmp ("are_you_ok_dude", func) == 0 || strcmp ("init", func) == 0) { snprintf (response, 100, "%s", OK_STR); - send (sock, response, strlen (response) + 1, 0); + goto send_response; } else { qb_log (LOG_ERR,"%s RPC:%s not supported!", __func__, func); snprintf (response, 100, "%s", NOT_SUPPORTED_STR); - send (sock, response, strlen (response), 0); + goto send_response; } + + return ; +send_response: + send_len = strlen (response); + rc = send (sock, response, send_len, 0); + assert(rc == send_len); } static void my_pre_exit(void) diff -Nru corosync-2.3.0/cts/Makefile.in corosync-2.3.3/cts/Makefile.in --- corosync-2.3.0/cts/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/cts/Makefile.in 2014-01-14 15:15:13.000000000 +0000 @@ -221,8 +221,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/debian/changelog corosync-2.3.3/debian/changelog --- corosync-2.3.0/debian/changelog 2013-12-16 05:03:21.000000000 +0000 +++ corosync-2.3.3/debian/changelog 2014-03-20 15:47:11.000000000 +0000 @@ -1,3 +1,26 @@ +corosync (2.3.3-1ubuntu1) trusty; urgency=medium + + * Merge with Debian; remaining changes: + - debian/control: Build-Depend on libdbus-1-dev + - debian/corosync.example-config: Modify to correctly use quorum for + Pacemaker clusters instead of the plugin. + - debian/control: Make all the -dev packages depend on its libraries. + - debian/control: libcorosync-common-dev should depend on libqb-dev. + - debian/control: libcorosync-dev needs to depend on libcfg-dev. + - Build with dh-autoreconf for new libtool. + + -- Matthias Klose Thu, 20 Mar 2014 16:42:53 +0100 + +corosync (2.3.3-1) experimental; urgency=medium + + * New upstream release + * Upload to experimental + * Disable the resource monitoring feature due to an incompatibility with + SG (And according to Jan Friesse, the feature is 'useless' anyway) + * debian/control: Bump Standards-Version to 3.9.5 + + -- Martin Loschwitz Fri, 21 Feb 2014 12:22:49 +0000 + corosync (2.3.0-1ubuntu5) trusty; urgency=medium * Build with dh-autoreconf for new libtool. diff -Nru corosync-2.3.0/debian/control corosync-2.3.3/debian/control --- corosync-2.3.0/debian/control 2013-12-16 05:03:15.000000000 +0000 +++ corosync-2.3.3/debian/control 2014-03-20 15:45:41.000000000 +0000 @@ -4,7 +4,7 @@ Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Debian HA Maintainers Uploaders: Martin Loschwitz , Guido Günther -Standards-Version: 3.9.3 +Standards-Version: 3.9.5 Build-Depends: debhelper (>> 5), libnss3-dev, pkg-config, groff, libqb-dev, librdmacm-dev, libibverbs-dev, libxml2-dev, libaugeas-dev, zlib1g-dev, chrpath, libstatgrab-dev, hardening-wrapper, libdbus-1-dev, dh-autoreconf Vcs-Git: git://git.debian.org/debian-ha/corosync.git Vcs-Browser: http://git.debian.org/?p=debian-ha/corosync.git;a=summary diff -Nru corosync-2.3.0/debian/libvotequorum-dev.install corosync-2.3.3/debian/libvotequorum-dev.install --- corosync-2.3.0/debian/libvotequorum-dev.install 2013-03-20 21:45:05.000000000 +0000 +++ corosync-2.3.3/debian/libvotequorum-dev.install 2014-02-21 12:40:01.000000000 +0000 @@ -26,3 +26,13 @@ usr/share/man/man3/votequorum_initialize.3 usr/share/man/man3/votequorum_setexpected.3 usr/share/man/man3/votequorum_setvotes.3 +usr/share/doc/corosync/html/votequorum_qdevice_update.3.html +usr/share/doc/corosync/html/votequorum_qdevice_register.3.html +usr/share/doc/corosync/html/votequorum_qdevice_poll.3.html +usr/share/doc/corosync/html/votequorum_qdevice_master_wins.3.html +usr/share/doc/corosync/html/votequorum_qdevice_unregister.3.html +usr/share/man/man3/votequorum_qdevice_master_wins.3 +usr/share/man/man3/votequorum_qdevice_register.3 +usr/share/man/man3/votequorum_qdevice_poll.3 +usr/share/man/man3/votequorum_qdevice_update.3 +usr/share/man/man3/votequorum_qdevice_unregister.3 diff -Nru corosync-2.3.0/debian/rules corosync-2.3.3/debian/rules --- corosync-2.3.0/debian/rules 2013-12-16 05:03:15.000000000 +0000 +++ corosync-2.3.3/debian/rules 2014-03-20 15:45:41.000000000 +0000 @@ -27,11 +27,14 @@ --enable-dbus \ --enable-testagents \ --enable-rdma \ - --enable-monitoring \ + --disable-monitoring \ --enable-watchdog \ --enable-augeas --enable-snmp \ - --enable-xmlconf + --enable-xmlconf \ + --enable-systemd \ + --enable-upstart \ + --enable-qdevices touch configure-stamp build: configure-stamp build-arch build-indep diff -Nru corosync-2.3.0/exec/cfg.c corosync-2.3.3/exec/cfg.c --- corosync-2.3.0/exec/cfg.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/cfg.c 2014-01-13 13:46:11.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2005-2006 MontaVista Software, Inc. - * Copyright (c) 2006-2012 Red Hat, Inc. + * Copyright (c) 2006-2013 Red Hat, Inc. * * All rights reserved. * @@ -64,13 +64,15 @@ #include #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_SHUTDOWN = 2, + MESSAGE_REQ_EXEC_CFG_RELOAD_CONFIG = 3 }; #define DEFAULT_SHUTDOWN_TIMEOUT 5 @@ -122,6 +124,10 @@ const void *message, unsigned int nodeid); +static void message_handler_req_exec_cfg_reload_config ( + const void *message, + unsigned int nodeid); + static void exec_cfg_killnode_endian_convert (void *msg); static void message_handler_req_lib_cfg_ringstatusget ( @@ -152,6 +158,10 @@ void *conn, const void *msg); +static void message_handler_req_lib_cfg_reload_config ( + void *conn, + const void *msg); + /* * Service Handler Definition */ @@ -184,6 +194,10 @@ { /* 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_NOT_REQUIRED } }; @@ -198,6 +212,9 @@ }, { /* 2 */ .exec_handler_fn = message_handler_req_exec_cfg_shutdown, + }, + { /* 3 */ + .exec_handler_fn = message_handler_req_exec_cfg_reload_config, } }; @@ -231,6 +248,11 @@ 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_killnode { struct qb_ipc_request_header header __attribute__((aligned(8))); mar_uint32_t nodeid __attribute__((aligned(8))); @@ -526,6 +548,196 @@ 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) +{ + 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.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.vsftype"); + 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, "qb.ipc_type"); +} + +/* + * 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; + icmap_map_t temp_map; + const char *error_string; + int res = CS_OK; + + ENTER(); + + log_printf(LOGSYS_LEVEL_NOTICE, "Config reload requested by node %d", nodeid); + + /* + * 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; + } + + /* + * 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_LIBRARY; + goto reload_return; + } + + /* Tell interested listeners that we have started a reload */ + 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 entries that cannot be changed */ + remove_ro_entries(temp_map); + + /* + * Copy new keys into live config. + * If this fails we will have a partially loaded config because some keys (above) might + * have been reset to defaults - I'm not sure what to do here, we might have to quit. + */ + 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"); + } + + /* All done - let clients know */ + icmap_set_uint8("config.reload_in_progress", 0); + +reload_fini: + /* Finished with the temporary storage */ + icmap_fini_r(temp_map); + +reload_return: + /* 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(); +} + /* * Library Interface Implementation */ @@ -539,12 +751,12 @@ char **status; const char *totem_ip_string; 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); - res_lib_cfg_ringstatusget.header.error = CS_OK; api->totem_ifaces_get ( api->totem_nodeid_get(), @@ -553,16 +765,34 @@ &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 (strlen(totem_ip_string) >= CFG_INTERFACE_NAME_MAX_LEN) { + log_printf(LOGSYS_LEVEL_ERROR, "String representation of interface %u is too long", i); + res = CS_ERR_NAME_TOO_LONG; + goto send_response; + } + + 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], totem_ip_string); } + +send_response: + res_lib_cfg_ringstatusget.header.error = res; api->ipc_response_send ( conn, &res_lib_cfg_ringstatusget, @@ -829,3 +1059,25 @@ 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(); +} diff -Nru corosync-2.3.0/exec/cmap.c corosync-2.3.3/exec/cmap.c --- corosync-2.3.0/exec/cmap.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/cmap.c 2014-01-14 15:07:56.000000000 +0000 @@ -597,8 +597,8 @@ struct res_lib_cmap_iter_next res_lib_cmap_iter_next; cs_error_t ret; icmap_iter_t *iter; - size_t value_len; - icmap_value_types_t type; + 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); @@ -809,7 +809,7 @@ 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; + struct req_exec_cmap_mcast_item *item = NULL; struct iovec req_exec_cmap_iovec[MAX_REQ_EXEC_CMAP_MCAST_ITEMS + 1]; ENTER(); diff -Nru corosync-2.3.0/exec/coroparse.c corosync-2.3.3/exec/coroparse.c --- corosync-2.3.0/exec/coroparse.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/coroparse.c 2014-01-14 15:07:56.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2012 Red Hat, Inc. + * Copyright (c) 2006-2013 Red Hat, Inc. * * All rights reserved. * @@ -76,6 +76,7 @@ char *value, enum parser_cb_type type, const char **error_string, + icmap_map_t config_map, void *user_data); enum main_cp_cb_data_state { @@ -120,7 +121,7 @@ }; static int read_config_file_into_icmap( - const char **error_string); + const char **error_string, icmap_map_t config_map); static char error_string_response[512]; static int uid_determine (const char *req_user) @@ -130,7 +131,14 @@ struct passwd* pwdptr = &passwd; struct passwd* temp_pwd_pt; char *pwdbuffer; - int pwdlinelen; + int pwdlinelen, rc; + long int id; + char *ep; + + id = strtol(req_user, &ep, 10); + if (*ep == '\0' && id >= 0 && id <= UINT_MAX) { + return (id); + } pwdlinelen = sysconf (_SC_GETPW_R_SIZE_MAX); @@ -140,7 +148,25 @@ pwdbuffer = malloc (pwdlinelen); - if ((getpwnam_r (req_user, pwdptr, pwdbuffer, pwdlinelen, &temp_pwd_pt)) != 0) { + 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); @@ -159,7 +185,14 @@ struct group * grpptr = &group; struct group * temp_grp_pt; char *grpbuffer; - int grplinelen; + int grplinelen, rc; + long int id; + char *ep; + + id = strtol(req_group, &ep, 10); + if (*ep == '\0' && id >= 0 && id <= UINT_MAX) { + return (id); + } grplinelen = sysconf (_SC_GETGR_R_SIZE_MAX); @@ -169,7 +202,25 @@ grpbuffer = malloc (grplinelen); - if ((getgrnam_r (req_group, grpptr, grpbuffer, grplinelen, &temp_grp_pt)) != 0) { + 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); @@ -193,16 +244,16 @@ return ((char *) end_address); } -int coroparse_configparse (const char **error_string) +int coroparse_configparse (icmap_map_t config_map, const char **error_string) { - if (read_config_file_into_icmap(error_string)) { + if (read_config_file_into_icmap(error_string, config_map)) { return -1; } return 0; } -static char *remove_whitespace(char *string) +static char *remove_whitespace(char *string, int remove_colon_and_brace) { char *start; char *end; @@ -212,7 +263,7 @@ start++; end = start+(strlen(start))-1; - while ((*end == ' ' || *end == '\t' || *end == ':' || *end == '{') && end > start) + while ((*end == ' ' || *end == '\t' || (remove_colon_and_brace && (*end == ':' || *end == '{'))) && end > start) end--; if (end != start) *(end+1) = '\0'; @@ -225,7 +276,9 @@ static int parse_section(FILE *fp, char *path, const char **error_string, + int depth, parser_cb_f parser_cb, + icmap_map_t config_map, void *user_data) { char line[512]; @@ -235,7 +288,7 @@ char new_keyname[ICMAP_KEYNAME_MAXLEN]; if (strcmp(path, "") == 0) { - parser_cb("", NULL, NULL, PARSER_CB_START, error_string, user_data); + parser_cb("", NULL, NULL, PARSER_CB_START, error_string, config_map, user_data); } while (fgets (line, sizeof (line), fp)) { @@ -274,23 +327,29 @@ /* New section ? */ if ((loc = strchr_rs (line, '{'))) { - char *section = remove_whitespace(line); + char *section = remove_whitespace(line, 1); loc--; *loc = '\0'; + if (strlen(path) + strlen(section) + 1 >= ICMAP_KEYNAME_MAXLEN) { + *error_string = "parser error: Start of section makes total cmap path too long"; + return -1; + } strcpy(new_keyname, path); if (strcmp(path, "") != 0) { strcat(new_keyname, "."); } strcat(new_keyname, section); - if (!parser_cb(new_keyname, NULL, NULL, PARSER_CB_SECTION_START, error_string, user_data)) { + if (!parser_cb(new_keyname, NULL, NULL, PARSER_CB_SECTION_START, error_string, config_map, user_data)) { return -1; } - if (parse_section(fp, new_keyname, error_string, parser_cb, user_data)) + if (parse_section(fp, new_keyname, error_string, depth + 1, parser_cb, config_map, user_data)) return -1; + + continue ; } /* New key/value */ @@ -299,22 +358,34 @@ char *value; *(loc-1) = '\0'; - key = remove_whitespace(line); - value = remove_whitespace(loc); + key = remove_whitespace(line, 1); + value = remove_whitespace(loc, 0); + if (strlen(path) + strlen(key) + 1 >= ICMAP_KEYNAME_MAXLEN) { + *error_string = "parser error: New key makes total cmap path too long"; + return -1; + } strcpy(new_keyname, path); if (strcmp(path, "") != 0) { strcat(new_keyname, "."); } strcat(new_keyname, key); - if (!parser_cb(new_keyname, key, value, PARSER_CB_ITEM, error_string, user_data)) { + if (!parser_cb(new_keyname, key, value, PARSER_CB_ITEM, error_string, config_map, user_data)) { return -1; } + + continue ; } if (strchr_rs (line, '}')) { - if (!parser_cb(path, NULL, NULL, PARSER_CB_SECTION_END, error_string, user_data)) { + if (depth == 0) { + *error_string = "parser error: Unexpected closing brace"; + + return -1; + } + + if (!parser_cb(path, NULL, NULL, PARSER_CB_SECTION_END, error_string, config_map, user_data)) { return -1; } @@ -323,12 +394,12 @@ } if (strcmp(path, "") != 0) { - *error_string = "Missing closing brace"; + *error_string = "parser error: Missing closing brace"; return -1; } if (strcmp(path, "") == 0) { - parser_cb("", NULL, NULL, PARSER_CB_END, error_string, user_data); + parser_cb("", NULL, NULL, PARSER_CB_END, error_string, config_map, user_data); } return 0; @@ -387,6 +458,7 @@ char *value, enum parser_cb_type type, const char **error_string, + icmap_map_t config_map, void *user_data) { int i; @@ -418,7 +490,7 @@ if (safe_atoi(value, &i) != 0) { goto atoi_error; } - icmap_set_uint32(path, i); + icmap_set_uint32_r(config_map, path, i); add_as_string = 0; } break; @@ -430,11 +502,12 @@ if (safe_atoi(value, &i) != 0) { goto atoi_error; } - icmap_set_uint32(path, i); + icmap_set_uint32_r(config_map, path, i); 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) || @@ -442,7 +515,7 @@ if (safe_atoi(value, &i) != 0) { goto atoi_error; } - icmap_set_uint8(path, i); + icmap_set_uint8_r(config_map, path, i); add_as_string = 0; } break; @@ -452,16 +525,17 @@ if (safe_atoi(value, &i) != 0) { goto atoi_error; } - icmap_set_uint32(path, i); + icmap_set_uint32_r(config_map, path, i); add_as_string = 0; } if ((strcmp(path, "quorum.device.master_wins") == 0)) { if (safe_atoi(value, &i) != 0) { goto atoi_error; } - icmap_set_uint8(path, i); + icmap_set_uint8_r(config_map, path, i); add_as_string = 0; } + break; case MAIN_CP_CB_DATA_STATE_TOTEM: if ((strcmp(path, "totem.version") == 0) || (strcmp(path, "totem.nodeid") == 0) || @@ -491,14 +565,14 @@ if (safe_atoi(value, &i) != 0) { goto atoi_error; } - icmap_set_uint32(path, i); + icmap_set_uint32_r(config_map,path, i); add_as_string = 0; } if (strcmp(path, "totem.config_version") == 0) { if (str_to_ull(value, &ull) != 0) { goto atoi_error; } - icmap_set_uint64(path, ull); + icmap_set_uint64_r(config_map, path, ull); add_as_string = 0; } if (strcmp(path, "totem.ip_version") == 0) { @@ -679,7 +753,7 @@ } snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.uid.%u", uid); - icmap_set_uint8(key_name, 1); + icmap_set_uint8_r(config_map, key_name, 1); add_as_string = 0; } else if (strcmp(key, "gid") == 0) { gid = gid_determine(value); @@ -689,7 +763,7 @@ } snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.gid.%u", gid); - icmap_set_uint8(key_name, 1); + icmap_set_uint8_r(config_map, key_name, 1); add_as_string = 0; } else { *error_string = "uidgid: Only uid and gid are allowed items"; @@ -733,7 +807,7 @@ goto atoi_error; } - icmap_set_uint32(key_name, i); + icmap_set_uint32_r(config_map, key_name, i); add_as_string = 0; } @@ -742,14 +816,14 @@ } if (add_as_string) { - icmap_set_string(key_name, value); + icmap_set_string_r(config_map, key_name, value); add_as_string = 0; } break; } if (add_as_string) { - icmap_set_string(path, value); + icmap_set_string_r(config_map, path, value); } break; case PARSER_CB_SECTION_START: @@ -812,7 +886,7 @@ if (data->bindnetaddr != NULL) { snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr", data->ringnumber); - icmap_set_string(key_name, data->bindnetaddr); + icmap_set_string_r(config_map, key_name, data->bindnetaddr); free(data->bindnetaddr); data->bindnetaddr = NULL; @@ -821,7 +895,7 @@ if (data->mcastaddr != NULL) { snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr", data->ringnumber); - icmap_set_string(key_name, data->mcastaddr); + icmap_set_string_r(config_map, key_name, data->mcastaddr); free(data->mcastaddr); data->mcastaddr = NULL; @@ -830,7 +904,7 @@ if (data->broadcast != NULL) { snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast", data->ringnumber); - icmap_set_string(key_name, data->broadcast); + icmap_set_string_r(config_map, key_name, data->broadcast); free(data->broadcast); data->broadcast = NULL; @@ -839,13 +913,13 @@ if (data->mcastport > -1) { snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport", data->ringnumber); - icmap_set_uint16(key_name, data->mcastport); + icmap_set_uint16_r(config_map, key_name, data->mcastport); } if (data->ttl > -1) { snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.ttl", data->ringnumber); - icmap_set_uint8(key_name, data->ttl); + icmap_set_uint8_r(config_map, key_name, data->ttl); } i = 0; @@ -855,7 +929,7 @@ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.member.%u", data->ringnumber, i); - icmap_set_string(key_name, kv_item->value); + icmap_set_string_r(config_map, key_name, kv_item->value); iter_next = iter->next; @@ -886,7 +960,7 @@ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.%s", data->subsys, kv_item->key); - icmap_set_string(key_name, kv_item->value); + icmap_set_string_r(config_map, key_name, kv_item->value); iter_next = iter->next; @@ -897,7 +971,7 @@ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys", data->subsys); - icmap_set_string(key_name, data->subsys); + icmap_set_string_r(config_map, key_name, data->subsys); free(data->subsys); @@ -937,7 +1011,7 @@ kv_item->key); } } - icmap_set_string(key_name, kv_item->value); + icmap_set_string_r(config_map, key_name, kv_item->value); iter_next = iter->next; @@ -950,21 +1024,21 @@ if (strcmp(data->logging_daemon_name, "corosync") != 0) { snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.name", data->logging_daemon_name); - icmap_set_string(key_name, data->logging_daemon_name); + 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); - icmap_set_string(key_name, data->subsys); + 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); - icmap_set_string(key_name, data->subsys); + icmap_set_string_r(config_map, key_name, data->subsys); snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.name", data->logging_daemon_name, data->subsys); - icmap_set_string(key_name, data->logging_daemon_name); + icmap_set_string_r(config_map, key_name, data->logging_daemon_name); } } @@ -1016,6 +1090,7 @@ char *value, enum parser_cb_type type, const char **error_string, + icmap_map_t config_map, void *user_data) { char key_name[ICMAP_KEYNAME_MAXLEN]; @@ -1035,7 +1110,7 @@ } snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.uid.%u", uid); - icmap_set_uint8(key_name, 1); + icmap_set_uint8_r(config_map, key_name, 1); } else if (strcmp(path, "uidgid.gid") == 0) { gid = gid_determine(value); if (gid == -1) { @@ -1044,7 +1119,7 @@ } snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.gid.%u", gid); - icmap_set_uint8(key_name, 1); + icmap_set_uint8_r(config_map, key_name, 1); } else { *error_string = "uidgid: Only uid and gid are allowed items"; return (0); @@ -1064,7 +1139,8 @@ } static int read_uidgid_files_into_icmap( - const char **error_string) + const char **error_string, + icmap_map_t config_map) { FILE *fp; const char *dirname; @@ -1097,15 +1173,15 @@ return_code = readdir_r(dp, entry, &dirent)) { snprintf(filename, sizeof (filename), "%s/%s", dirname, dirent->d_name); - stat (filename, &stat_buf); - if (S_ISREG(stat_buf.st_mode)) { + 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; - res = parse_section(fp, key_name, error_string, uidgid_config_parser_cb, NULL); + res = parse_section(fp, key_name, error_string, 0, uidgid_config_parser_cb, config_map, NULL); fclose (fp); @@ -1124,7 +1200,8 @@ /* Read config file and load into icmap */ static int read_config_file_into_icmap( - const char **error_string) + const char **error_string, + icmap_map_t config_map) { FILE *fp; const char *filename; @@ -1150,12 +1227,12 @@ key_name[0] = 0; - res = parse_section(fp, key_name, error_string, main_config_parser_cb, &data); + res = parse_section(fp, key_name, error_string, 0, main_config_parser_cb, config_map, &data); fclose(fp); if (res == 0) { - res = read_uidgid_files_into_icmap(error_string); + res = read_uidgid_files_into_icmap(error_string, config_map); } if (res == 0) { diff -Nru corosync-2.3.0/exec/cpg.c corosync-2.3.3/exec/cpg.c --- corosync-2.3.0/exec/cpg.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/cpg.c 2014-01-13 13:46:11.000000000 +0000 @@ -1603,7 +1603,6 @@ void **buf) { int32_t fd; - void *addr_orig; void *addr; int32_t res; @@ -1620,18 +1619,10 @@ goto error_close_unlink; } - addr_orig = mmap (NULL, bytes, PROT_NONE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + addr = mmap (NULL, bytes, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); - if (addr_orig == MAP_FAILED) { - goto error_close_unlink; - } - - addr = mmap (addr_orig, bytes, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, fd, 0); - - if (addr != addr_orig) { - munmap(addr_orig, bytes); + if (addr == MAP_FAILED) { goto error_close_unlink; } #ifdef MADV_NOSYNC @@ -1642,7 +1633,7 @@ if (res) { return (-1); } - *buf = addr_orig; + *buf = addr; return (0); error_close_unlink: diff -Nru corosync-2.3.0/exec/icmap.c corosync-2.3.3/exec/icmap.c --- corosync-2.3.0/exec/icmap.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/icmap.c 2014-01-13 13:46:11.000000000 +0000 @@ -52,7 +52,11 @@ char value[]; }; -static qb_map_t *icmap_map; +struct icmap_map { + qb_map_t *qb_map; +}; + +static icmap_map_t icmap_global_map; struct icmap_track { char *key_name; @@ -114,12 +118,25 @@ /* * 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( +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 */ static int32_t icmap_tt_to_qbtt(int32_t track_type) @@ -183,19 +200,29 @@ } } -cs_error_t icmap_init(void) +cs_error_t icmap_init_r(icmap_map_t *result) { int32_t err; - icmap_map = qb_trie_create(); - if (icmap_map == NULL) + *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) return (CS_ERR_INIT); - err = qb_map_notify_add(icmap_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL); + 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 list_head *iter = icmap_ro_access_item_list_head.next; @@ -222,8 +249,18 @@ } } +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: @@ -232,9 +269,16 @@ * -> 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! :) */ - qb_map_destroy(icmap_map); + icmap_fini_r(icmap_global_map); icmap_set_ro_access_free(); - return; + + return ; +} + +icmap_map_t icmap_get_global_map(void) +{ + + return (icmap_global_map); } static int icmap_is_valid_name_char(char c) @@ -313,7 +357,11 @@ } if (type == ICMAP_VALUETYPE_STRING) { - if (value_len > strlen((const char *)value)) { + /* + * 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); @@ -348,7 +396,30 @@ return (0); } -cs_error_t icmap_set( +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, @@ -367,7 +438,7 @@ return (CS_ERR_INVALID_PARAM); } - item = qb_map_get(icmap_map, key_name); + item = qb_map_get(map->qb_map, key_name); if (item != NULL) { /* * Check that key is really changed @@ -422,82 +493,158 @@ ((char *)new_item->value)[new_value_len - 1] = 0; } - qb_map_put(icmap_map, new_item->key_name, new_item); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT8)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT8)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT16)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT16)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT32)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT32)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT64)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT64)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_FLOAT)); + 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(key_name, &value, sizeof(value), ICMAP_VALUETYPE_DOUBLE)); + return (icmap_set_double_r(icmap_global_map, key_name, value)); } cs_error_t icmap_set_string(const char *key_name, const char *value) { - if (value == NULL) { - return (CS_ERR_INVALID_PARAM); - } - - return (icmap_set(key_name, value, strlen(value), ICMAP_VALUETYPE_STRING)); + return (icmap_set_string_r(icmap_global_map, key_name, value)); } -cs_error_t icmap_delete(const char *key_name) +cs_error_t icmap_delete_r(const icmap_map_t map, const char *key_name) { struct icmap_item *item; @@ -505,21 +652,28 @@ return (CS_ERR_INVALID_PARAM); } - item = qb_map_get(icmap_map, key_name); + item = qb_map_get(map->qb_map, key_name); if (item == NULL) { return (CS_ERR_NOT_EXIST); } - if (qb_map_rm(icmap_map, item->key_name) != QB_TRUE) { + if (qb_map_rm(map->qb_map, item->key_name) != QB_TRUE) { return (CS_ERR_NOT_EXIST); } return (CS_OK); } -cs_error_t icmap_get( +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, + void **value, size_t *value_len, icmap_value_types_t *type) { @@ -529,7 +683,7 @@ return (CS_ERR_INVALID_PARAM); } - item = qb_map_get(icmap_map, key_name); + item = qb_map_get(map->qb_map, key_name); if (item == NULL) { return (CS_ERR_NOT_EXIST); } @@ -538,24 +692,62 @@ *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 = item->value_len; + *value_len = tmp_value_len; } } else { - if (value_len == NULL || *value_len < item->value_len) { + if (value_len == NULL || *value_len < tmp_value_len) { return (CS_ERR_INVALID_PARAM); } - *value_len = item->value_len; + *value_len = tmp_value_len; - memcpy(value, item->value, item->value_len); + memcpy(value, tmp_value, tmp_value_len); } return (CS_OK); } -static cs_error_t icmap_get_int( +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)); +} + +static cs_error_t icmap_get_int_r( + const icmap_map_t map, const char *key_name, void *value, icmap_value_types_t type) @@ -581,64 +773,124 @@ 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_int8(const char *key_name, int8_t *i8) { - return (icmap_get_int(key_name, i8, ICMAP_VALUETYPE_INT8)); + 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_int(key_name, u8, ICMAP_VALUETYPE_UINT8)); + 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_int(key_name, i16, ICMAP_VALUETYPE_INT16)); + 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_int(key_name, u16, ICMAP_VALUETYPE_UINT16)); + 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_int(key_name, i32, ICMAP_VALUETYPE_INT32)); + 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_int(key_name, u32, ICMAP_VALUETYPE_UINT32)); + 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_int(key_name, i64, ICMAP_VALUETYPE_INT64)); + 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_int(key_name, u64, ICMAP_VALUETYPE_UINT64)); + 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_int(key_name, flt, ICMAP_VALUETYPE_FLOAT)); + 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_int(key_name, dbl, ICMAP_VALUETYPE_DOUBLE)); + return (icmap_get_double_r(icmap_global_map, key_name, dbl)); } cs_error_t icmap_get_string(const char *key_name, char **str) @@ -675,7 +927,8 @@ return (res); } -cs_error_t icmap_adjust_int( +cs_error_t icmap_adjust_int_r( + const icmap_map_t map, const char *key_name, int32_t step) { @@ -690,7 +943,7 @@ return (CS_ERR_INVALID_PARAM); } - item = qb_map_get(icmap_map, key_name); + item = qb_map_get(map->qb_map, key_name); if (item == NULL) { return (CS_ERR_NOT_EXIST); } @@ -731,7 +984,16 @@ return (err); } -cs_error_t icmap_fast_adjust_int( +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) { @@ -742,7 +1004,7 @@ return (CS_ERR_INVALID_PARAM); } - item = qb_map_get(icmap_map, key_name); + item = qb_map_get(map->qb_map, key_name); if (item == NULL) { return (CS_ERR_NOT_EXIST); } @@ -773,37 +1035,71 @@ } if (err == CS_OK) { - qb_map_put(icmap_map, item->key_name, item); + 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_adjust_int(key_name, 1)); + 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_adjust_int(key_name, -1)); + 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_adjust_int(key_name, 1)); + 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_adjust_int(key_name, -1)); + 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 (qb_map_pref_iter_create(icmap_map, 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; @@ -899,7 +1195,7 @@ (*icmap_track)->notify_fn = notify_fn; (*icmap_track)->user_data = user_data; - if ((err = qb_map_notify_add(icmap_map, (*icmap_track)->key_name, icmap_notify_fn, + 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); @@ -917,7 +1213,7 @@ { int32_t err; - if ((err = qb_map_notify_del_2(icmap_map, icmap_track->key_name, + 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)); } @@ -1006,3 +1302,37 @@ 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 -Nru corosync-2.3.0/exec/ipc_glue.c corosync-2.3.3/exec/ipc_glue.c --- corosync-2.3.0/exec/ipc_glue.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/ipc_glue.c 2014-01-13 13:46:11.000000000 +0000 @@ -70,10 +70,12 @@ 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[256]; + char name[CS_IPCS_MAPPER_SERV_NAME]; }; struct outq_item { @@ -90,6 +92,7 @@ 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 = { @@ -417,6 +420,8 @@ return res; } + qb_loop_job_del(cs_poll_handle_get(), QB_LOOP_HIGH, c, outq_flush); + cnx = qb_ipcs_context_get(c); snprintf(prefix, ICMAP_KEYNAME_MAXLEN, "%s.", cnx->icmap_path); @@ -471,7 +476,6 @@ if (rc < 0 && rc != -EAGAIN) { errno = -rc; qb_perror(LOG_ERR, "qb_ipcs_event_send"); - qb_ipcs_connection_unref(conn); return; } else if (rc == -EAGAIN) { break; @@ -490,7 +494,6 @@ context->queued, context->sent); context->queued = 0; context->sent = 0; - qb_ipcs_connection_unref(conn); } else { qb_loop_job_add(cs_poll_handle_get(), QB_LOOP_HIGH, conn, outq_flush); } @@ -520,7 +523,6 @@ context->queued = 0; context->sent = 0; context->queuing = QB_TRUE; - qb_ipcs_connection_ref(conn); 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); @@ -529,14 +531,12 @@ } outq_item = malloc (sizeof (struct outq_item)); if (outq_item == NULL) { - qb_ipcs_connection_unref(conn); qb_ipcs_disconnect(conn); return; } outq_item->msg = malloc (bytes_msg); if (outq_item->msg == NULL) { free (outq_item); - qb_ipcs_connection_unref(conn); qb_ipcs_disconnect(conn); return; } @@ -746,7 +746,7 @@ int32_t i; struct qb_ipcs_stats srv_stats; struct qb_ipcs_connection_stats stats; - qb_ipcs_connection_t *c; + qb_ipcs_connection_t *c, *prev; struct cs_ipcs_conn_context *cnx; char key_name[ICMAP_KEYNAME_MAXLEN]; @@ -756,8 +756,9 @@ } qb_ipcs_stats_get(ipcs_mapper[i].inst, &srv_stats, QB_FALSE); - for (c = qb_ipcs_connection_first_get(ipcs_mapper[i].inst); c; - c = qb_ipcs_connection_next_get(ipcs_mapper[i].inst, c)) { + for (c = qb_ipcs_connection_first_get(ipcs_mapper[i].inst); + c; + prev = c, c = qb_ipcs_connection_next_get(ipcs_mapper[i].inst, prev), qb_ipcs_connection_unref(prev)) { cnx = qb_ipcs_context_get(c); if (cnx == NULL) continue; @@ -796,7 +797,6 @@ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s.overload", cnx->icmap_path); icmap_set_uint64(key_name, cnx->overload); - qb_ipcs_connection_unref(c); } } } @@ -840,15 +840,25 @@ 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]", - cs_ipcs_serv_short_name(service->id), + 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, cs_ipcs_serv_short_name(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, diff -Nru corosync-2.3.0/exec/logconfig.c corosync-2.3.3/exec/logconfig.c --- corosync-2.3.0/exec/logconfig.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/logconfig.c 2014-01-13 13:46:11.000000000 +0000 @@ -155,6 +155,7 @@ /* nothing to do here */ } else { error_reason = "unknown value for fileline"; + free(value); goto parse_error; } @@ -183,6 +184,7 @@ /* nothing to do here */ } else { error_reason = "unknown value for function_name"; + free(value); goto parse_error; } @@ -206,6 +208,7 @@ /* nothing to do here */ } else { error_reason = "unknown value for timestamp"; + free(value); goto parse_error; } @@ -345,6 +348,8 @@ " 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; @@ -354,7 +359,6 @@ error_reason = "unable to set syslog level"; goto parse_error; } - free(value); } snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "syslog_priority"); @@ -362,6 +366,7 @@ 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; @@ -371,7 +376,6 @@ error_reason = "unable to set syslog priority"; goto parse_error; } - free(value); } #ifdef LOGCONFIG_USE_ICMAP @@ -403,6 +407,7 @@ 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; @@ -412,7 +417,6 @@ error_reason = "unable to set logfile priority"; goto parse_error; } - free(value); } snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "debug"); @@ -420,22 +424,26 @@ 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); @@ -534,6 +542,22 @@ #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 @@ -554,6 +578,12 @@ 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) @@ -565,6 +595,12 @@ 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 diff -Nru corosync-2.3.0/exec/logsys.c corosync-2.3.3/exec/logsys.c --- corosync-2.3.0/exec/logsys.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/logsys.c 2014-01-14 15:07:56.000000000 +0000 @@ -301,35 +301,20 @@ (strlen(mainsystem) >= LOGSYS_MAX_SUBSYS_NAMELEN)) { return -1; } + /* * Setup libqb as a subsys */ - i = _logsys_subsys_create ("QB", "array.c"); - _logsys_subsys_filename_add (i, "log.c"); - _logsys_subsys_filename_add (i, "log_syslog.c"); - _logsys_subsys_filename_add (i, "log_blackbox.c"); - _logsys_subsys_filename_add (i, "log_format.c"); - _logsys_subsys_filename_add (i, "log_file.c"); - _logsys_subsys_filename_add (i, "log_dcs.c"); - _logsys_subsys_filename_add (i, "log_thread.c"); - _logsys_subsys_filename_add (i, "ipc_shm.c"); - _logsys_subsys_filename_add (i, "ipcs.c"); - _logsys_subsys_filename_add (i, "ipc_us.c"); - _logsys_subsys_filename_add (i, "loop.c"); - _logsys_subsys_filename_add (i, "loop_poll_epoll.c"); - _logsys_subsys_filename_add (i, "loop_job.c"); - _logsys_subsys_filename_add (i, "loop_poll_poll.c"); - _logsys_subsys_filename_add (i, "loop_poll_kqueue.c"); - _logsys_subsys_filename_add (i, "loop_timerlist.c"); - _logsys_subsys_filename_add (i, "loop_poll.c"); - _logsys_subsys_filename_add (i, "ringbuffer.c"); - _logsys_subsys_filename_add (i, "ringbuffer_helper.c"); - _logsys_subsys_filename_add (i, "trie.c"); - _logsys_subsys_filename_add (i, "map.c"); - _logsys_subsys_filename_add (i, "skiplist.c"); - _logsys_subsys_filename_add (i, "rpl_sem.c"); - _logsys_subsys_filename_add (i, "hdb.c"); - _logsys_subsys_filename_add (i, "unix.c"); + 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"); @@ -368,7 +353,10 @@ qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_THREADED, QB_FALSE); qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE); - logsys_format_set(NULL); + if (logsys_format_set(NULL) == -1) { + return -1; + } + qb_log_tags_stringify_fn_set(_logsys_tags_stringify); logsys_loggers[i].init_status = LOGSYS_LOGGER_INIT_DONE; @@ -569,7 +557,6 @@ int logsys_format_set (const char *format) { - int ret = 0; int i; int c; int w; @@ -584,8 +571,9 @@ format_buffer = strdup(format ? format : "%7p [%6g] %b"); if (format_buffer == NULL) { - ret = -1; + return -1; } + qb_log_format_set(QB_LOG_STDERR, format_buffer); logsys_file_format_get(file_format, 128); @@ -622,7 +610,7 @@ } qb_log_format_set(QB_LOG_SYSLOG, syslog_format); - return ret; + return 0; } char *logsys_format_get (void) diff -Nru corosync-2.3.0/exec/main.c corosync-2.3.3/exec/main.c --- corosync-2.3.0/exec/main.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/main.c 2014-01-14 15:07:56.000000000 +0000 @@ -128,7 +128,7 @@ #endif LOGSYS_DECLARE_SYSTEM ("corosync", - LOGSYS_MODE_OUTPUT_STDERR, + LOGSYS_MODE_OUTPUT_STDERR | LOGSYS_MODE_OUTPUT_SYSLOG, LOG_DAEMON, LOG_INFO); @@ -209,7 +209,10 @@ qb_log_blackbox_write_to_file(fname); unlink(LOCALSTATEDIR "/lib/corosync/fdata"); - symlink(fname, LOCALSTATEDIR "/lib/corosync/fdata"); + if (symlink(fname, LOCALSTATEDIR "/lib/corosync/fdata") == -1) { + log_printf(LOGSYS_LEVEL_ERROR, "Can't create symlink to '%s' for corosync blackbox file '%s'", + fname, LOCALSTATEDIR "/lib/corosync/fdata"); + } } static void unlink_all_completed (void) @@ -232,6 +235,7 @@ 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; } @@ -397,7 +401,7 @@ static void corosync_tty_detach (void) { - FILE *r; + int devnull; /* * Disconnect from TTY if this is not a debug run @@ -423,18 +427,17 @@ /* * Map stdin/out/err to /dev/null. */ - r = freopen("/dev/null", "r", stdin); - if (r == NULL) { - corosync_exit_error (COROSYNC_DONE_STD_TO_NULL_REDIR); - } - r = freopen("/dev/null", "a", stderr); - if (r == NULL) { + devnull = open("/dev/null", O_RDWR); + if (devnull == -1) { corosync_exit_error (COROSYNC_DONE_STD_TO_NULL_REDIR); } - r = freopen("/dev/null", "a", stdout); - if (r == NULL) { + + 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) @@ -562,8 +565,8 @@ void *user_data) { int res; - int ring_no; - int member_no; + unsigned int ring_no; + unsigned int member_no; struct totem_ip_address member; int add_new_member = 0; int remove_old_member = 0; @@ -786,6 +789,51 @@ 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; + + 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) { + log_printf (LOGSYS_LEVEL_WARNING, "Corosync main process was not scheduled for %0.4f ms " + "(threshold is %0.4f ms). Consider token timeout increase.", + (float)tv_diff / QB_TIME_NS_IN_MSEC, (float)timeout_data->max_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); +} + + static void corosync_setscheduler (void) { #if defined(HAVE_PTHREAD_SETSCHEDPARAM) && defined(HAVE_SCHED_GET_PRIORITY_MAX) && defined(HAVE_SCHED_SETSCHEDULER) @@ -1038,6 +1086,7 @@ char corosync_lib_dir[PATH_MAX]; enum e_corosync_done flock_err; uint64_t totem_config_warnings; + struct scheduler_pause_timeout_data scheduler_pause_timeout_data; /* default configuration */ @@ -1049,7 +1098,6 @@ switch (ch) { case 'f': background = 0; - logsys_config_mode_set (NULL, LOGSYS_MODE_OUTPUT_STDERR|LOGSYS_MODE_THREADED|LOGSYS_MODE_FORK); break; case 'p': break; @@ -1104,7 +1152,7 @@ */ api = apidef_get (); - res = coroparse_configparse(&error_string); + res = coroparse_configparse(icmap_get_global_map(), &error_string); if (res == -1) { log_printf (LOGSYS_LEVEL_ERROR, "%s", error_string); corosync_exit_error (COROSYNC_DONE_MAINCONFIGREAD); @@ -1175,7 +1223,10 @@ ip_version = totem_config.ip_version; totem_config.totem_logging_configuration = totem_logging_configuration; - totem_config.totem_logging_configuration.log_subsys_id = _logsys_subsys_create("TOTEM", "totem"); + totem_config.totem_logging_configuration.log_subsys_id = _logsys_subsys_create("TOTEM", "totem," + "totemmrp.c,totemrrp.c,totemip.c,totemconfig.c,totemcrypto.c,totemsrp.c," + "totempg.c,totemiba.c,totemudp.c,totemudpu.c,totemnet.c"); + 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; @@ -1194,6 +1245,10 @@ 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, diff -Nru corosync-2.3.0/exec/main.h corosync-2.3.3/exec/main.h --- corosync-2.3.0/exec/main.h 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/main.h 2014-01-13 13:46:11.000000000 +0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include extern unsigned long long *(*main_clm_get_by_nodeid) (unsigned int node_id); @@ -121,6 +122,6 @@ extern void cs_ipc_allow_connections(int32_t allow); -int coroparse_configparse (const char **error_string); +int coroparse_configparse (icmap_map_t config_map, const char **error_string); #endif /* MAIN_H_DEFINED */ diff -Nru corosync-2.3.0/exec/Makefile.in corosync-2.3.3/exec/Makefile.in --- corosync-2.3.0/exec/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/exec/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -278,8 +278,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/exec/service.c corosync-2.3.3/exec/service.c --- corosync-2.3.0/exec/service.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/service.c 2014-01-13 13:46:11.000000000 +0000 @@ -285,13 +285,13 @@ } snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "internal_configuration.service.%hu.name", service_id); - free(found_service_name); 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; } @@ -300,6 +300,7 @@ service_found = 1; break; } + free(found_service_name); } icmap_iter_finalize(iter); diff -Nru corosync-2.3.0/exec/totemconfig.c corosync-2.3.3/exec/totemconfig.c --- corosync-2.3.0/exec/totemconfig.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/totemconfig.c 2014-01-14 15:07:56.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2002-2005 MontaVista Software, Inc. - * Copyright (c) 2006-2012 Red Hat, Inc. + * Copyright (c) 2006-2013 Red Hat, Inc. * * All rights reserved. * @@ -83,6 +83,57 @@ static void add_totem_config_notification(struct totem_config *totem_config); + +/* All the volatile parameters are uint32s, luckily */ +static uint32_t *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_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.rrp_token_expired_timeout") == 0) + return &totem_config->rrp_token_expired_timeout; + if (strcmp(param_name, "totem.rrp_problem_count_timeout") == 0) + return &totem_config->rrp_problem_count_timeout; + if (strcmp(param_name, "totem.rrp_problem_count_threshold") == 0) + return &totem_config->rrp_problem_count_threshold; + if (strcmp(param_name, "totem.rrp_problem_count_mcast_threshold") == 0) + return &totem_config->rrp_problem_count_mcast_threshold; + if (strcmp(param_name, "totem.rrp_autorecovery_check_timeout") == 0) + return &totem_config->rrp_autorecovery_check_timeout; + 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; + + return NULL; +} + + static void totem_volatile_config_read (struct totem_config *totem_config) { char *str; @@ -215,7 +266,7 @@ } clusterid = generate_cluster_id(cluster_name) + ringnumber; - memset (res, 0, sizeof(res)); + memset (res, 0, sizeof(*res)); switch (bindnet->family) { case AF_INET: @@ -241,7 +292,7 @@ icmap_iter_t iter; const char *iter_key; int res = 0; - int node_pos; + unsigned int node_pos; int local_node_pos = -1; struct totem_ip_address bind_addr; int interface_up, interface_num; @@ -292,7 +343,7 @@ icmap_iter_t iter, iter2; const char *iter_key, *iter_key2; int res = 0; - int node_pos; + unsigned int node_pos; char tmp_key[ICMAP_KEYNAME_MAXLEN]; char tmp_key2[ICMAP_KEYNAME_MAXLEN]; char *node_addr_str; @@ -343,7 +394,7 @@ icmap_iter_t iter; const char *iter_key; int res = 0; - int node_pos; + unsigned int node_pos; char tmp_key[ICMAP_KEYNAME_MAXLEN]; char tmp_key2[ICMAP_KEYNAME_MAXLEN]; char *node_addr_str; @@ -352,7 +403,7 @@ struct list_head *list; struct totem_ip_if_address *if_addr; struct totem_ip_address node_addr; - int node_found; + int node_found = 0; if (totemip_getifaddrs(&addrs) == -1) { return ; @@ -467,6 +518,12 @@ } if (icmap_get_string("totem.rrp_mode", &str) == CS_OK) { + if (strlen(str) >= TOTEM_RRP_MODE_BYTES) { + *error_string = "totem.rrp_mode is too long"; + free(str); + + return -1; + } strcpy (totem_config->rrp_mode, str); free(str); } @@ -485,7 +542,9 @@ icmap_get_uint32("totem.netmtu", &totem_config->net_mtu); - icmap_get_string("totem.cluster_name", &cluster_name); + if (icmap_get_string("totem.cluster_name", &cluster_name) != CS_OK) { + cluster_name = NULL; + } totem_config->ip_version = AF_INET; if (icmap_get_string("totem.ip_version", &str) == CS_OK) { @@ -528,6 +587,8 @@ ringnumber = atoi(ringnumber_key); if (ringnumber >= INTERFACE_MAX) { + free(cluster_name); + snprintf (error_string_response, sizeof(error_string_response), "parse error in config: interface ring number %u is bigger then allowed maximum %u\n", ringnumber, INTERFACE_MAX - 1); @@ -693,80 +754,12 @@ return 0; } -int totem_config_validate ( +static int totem_set_volatile_defaults ( 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; - unsigned int interface_max = INTERFACE_MAX; - - if (totem_config->interface_count == 0) { - error_reason = "No interfaces defined"; - goto parse_error; - } - - for (i = 0; i < totem_config->interface_count; i++) { - /* - * Some error checking of parsed data to make sure its valid - */ - - struct totem_ip_address null_addr; - memset (&null_addr, 0, sizeof (struct totem_ip_address)); - - if ((totem_config->transport_number == 0) && - memcmp (&totem_config->interfaces[i].mcast_addr, &null_addr, - sizeof (struct totem_ip_address)) == 0) { - error_reason = "No multicast address specified"; - goto parse_error; - } - - if (totem_config->interfaces[i].ip_port == 0) { - error_reason = "No multicast port specified"; - goto parse_error; - } - - if (totem_config->interfaces[i].ttl > 255) { - error_reason = "Invalid TTL (should be 0..255)"; - goto parse_error; - } - if (totem_config->transport_number != TOTEM_TRANSPORT_UDP && - totem_config->interfaces[i].ttl != 1) { - error_reason = "Can only set ttl on multicast transport types"; - goto parse_error; - } - - if (totem_config->interfaces[i].mcast_addr.family == AF_INET6 && - totem_config->node_id == 0) { - - error_reason = "An IPV6 network requires that a node ID be specified."; - goto parse_error; - } - - if (totem_config->broadcast_use == 0 && totem_config->transport_number == 0) { - if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) { - error_reason = "Multicast address family does not match bind address family"; - goto parse_error; - } - - if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) { - error_reason = "Not all bind address belong to the same IP family"; - goto parse_error; - } - if (totemip_is_mcast (&totem_config->interfaces[i].mcast_addr) != 0) { - error_reason = "mcastaddr is not a correct multicast address."; - goto parse_error; - } - } - } - - if (totem_config->version != 2) { - error_reason = "This totem parser can only parse version 2 configurations."; - goto parse_error; - } - if (totem_config->token_retransmits_before_loss_const == 0) { totem_config->token_retransmits_before_loss_const = @@ -878,16 +871,15 @@ goto parse_error; } - /* - * RRP values validation - */ - if (strcmp (totem_config->rrp_mode, "none") && - strcmp (totem_config->rrp_mode, "active") && - strcmp (totem_config->rrp_mode, "passive")) { - snprintf (local_error_reason, sizeof(local_error_reason), - "The RRP mode \"%s\" specified is invalid. It must be none, active, or passive.\n", totem_config->rrp_mode); - goto parse_error; + if (totem_config->fail_to_recv_const == 0) { + totem_config->fail_to_recv_const = FAIL_TO_RECV_CONST; + } + if (totem_config->seqno_unchanged_const == 0) { + totem_config->seqno_unchanged_const = SEQNO_UNCHANGED_CONST; } + +/* RRP volatile values */ + if (totem_config->rrp_problem_count_timeout == 0) { totem_config->rrp_problem_count_timeout = RRP_PROBLEM_COUNT_TIMEOUT; } @@ -931,54 +923,127 @@ totem_config->rrp_autorecovery_check_timeout = RRP_AUTORECOVERY_CHECK_TIMEOUT; } - if (strcmp (totem_config->rrp_mode, "none") == 0) { - interface_max = 1; - } - if (interface_max < totem_config->interface_count) { - snprintf (parse_error, sizeof(parse_error), - "%d is too many configured interfaces for the rrp_mode setting %s.", - totem_config->interface_count, - totem_config->rrp_mode); - error_reason = 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); + +} + +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; + unsigned int interface_max = INTERFACE_MAX; + + if (totem_config->interface_count == 0) { + error_reason = "No interfaces defined"; goto parse_error; } + for (i = 0; i < totem_config->interface_count; i++) { + /* + * Some error checking of parsed data to make sure its valid + */ - if (totem_config->fail_to_recv_const == 0) { - totem_config->fail_to_recv_const = FAIL_TO_RECV_CONST; - } - if (totem_config->seqno_unchanged_const == 0) { - totem_config->seqno_unchanged_const = SEQNO_UNCHANGED_CONST; + struct totem_ip_address null_addr; + memset (&null_addr, 0, sizeof (struct totem_ip_address)); + + if ((totem_config->transport_number == 0) && + memcmp (&totem_config->interfaces[i].mcast_addr, &null_addr, + sizeof (struct totem_ip_address)) == 0) { + error_reason = "No multicast address specified"; + goto parse_error; + } + + if (totem_config->interfaces[i].ip_port == 0) { + error_reason = "No multicast port specified"; + goto parse_error; + } + + if (totem_config->interfaces[i].ttl > 255) { + error_reason = "Invalid TTL (should be 0..255)"; + goto parse_error; + } + if (totem_config->transport_number != TOTEM_TRANSPORT_UDP && + totem_config->interfaces[i].ttl != 1) { + error_reason = "Can only set ttl on multicast transport types"; + goto parse_error; + } + + if (totem_config->interfaces[i].mcast_addr.family == AF_INET6 && + totem_config->node_id == 0) { + + error_reason = "An IPV6 network requires that a node ID be specified."; + goto parse_error; + } + + if (totem_config->broadcast_use == 0 && totem_config->transport_number == 0) { + if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) { + error_reason = "Multicast address family does not match bind address family"; + goto parse_error; + } + + if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) { + error_reason = "Not all bind address belong to the same IP family"; + goto parse_error; + } + if (totemip_is_mcast (&totem_config->interfaces[i].mcast_addr) != 0) { + error_reason = "mcastaddr is not a correct multicast address."; + goto parse_error; + } + } } - if (totem_config->net_mtu == 0) { - totem_config->net_mtu = 1500; + + if (totem_config->version != 2) { + error_reason = "This totem parser can only parse version 2 configurations."; + goto parse_error; } - if ((MESSAGE_QUEUE_MAX) < totem_config->max_messages) { + totem_set_volatile_defaults(totem_config, error_string); + + /* + * RRP values validation + */ + if (strcmp (totem_config->rrp_mode, "none") && + strcmp (totem_config->rrp_mode, "active") && + strcmp (totem_config->rrp_mode, "passive")) { snprintf (local_error_reason, sizeof(local_error_reason), - "The max_messages parameter (%d messages) may not be greater then (%d messages).", - totem_config->max_messages, MESSAGE_QUEUE_MAX); + "The RRP mode \"%s\" specified is invalid. It must be none, active, or passive.\n", totem_config->rrp_mode); goto parse_error; } - if (totem_config->threads > SEND_THREADS_MAX) { - totem_config->threads = SEND_THREADS_MAX; + if (strcmp (totem_config->rrp_mode, "none") == 0) { + interface_max = 1; } - if (totem_config->net_mtu > FRAME_SIZE_MAX) { - error_reason = "This net_mtu parameter is greater then the maximum frame size"; + if (interface_max < totem_config->interface_count) { + snprintf (parse_error, sizeof(parse_error), + "%d is too many configured interfaces for the rrp_mode setting %s.", + totem_config->interface_count, + totem_config->rrp_mode); + error_reason = parse_error; goto parse_error; } - if (totem_config->vsf_type == NULL) { - totem_config->vsf_type = "none"; + + if (totem_config->net_mtu == 0) { + totem_config->net_mtu = 1500; } - return (0); + 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 ( @@ -1097,7 +1162,69 @@ struct icmap_notify_value old_val, void *user_data) { - totem_volatile_config_read((struct totem_config *)user_data); + uint32_t *param; + const char *error_string; + uint8_t reloading; + + /* + * 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); + if (!param) + return; + + switch (event) + { + case ICMAP_TRACK_DELETE: + if (new_val.type == ICMAP_VALUETYPE_UINT32) + *param = 0; + totem_set_volatile_defaults((struct totem_config *)user_data, &error_string); + break; + case ICMAP_TRACK_ADD: + case ICMAP_TRACK_MODIFY: + if (new_val.type == ICMAP_VALUETYPE_UINT32) + memcpy(param, new_val.data, new_val.len); + /* Other value types not supported, or needed (yet) */ + break; + default: + break; + } +} + +static void totem_reload_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 local_node_pos; + + /* Reload has completed */ + if (*(uint8_t *)new_val.data == 0) { + int i, j; + + /* Clear out udpu nodelist so we can put the new one in if neede */ + for (i=0; iinterface_count; i++) { + for (j=0; jinterfaces[i].member_list[j], 0, sizeof(struct totem_ip_address)); + } + } + + put_nodelist_members_to_config (totem_config); + totem_volatile_config_read (totem_config); + + /* Reinstate the local_node_pos */ + local_node_pos = find_local_node_in_nodelist(totem_config); + if (local_node_pos != -1) { + icmap_set_uint32("nodelist.local_node_pos", local_node_pos); + } + } } static void add_totem_config_notification(struct totem_config *totem_config) @@ -1109,4 +1236,10 @@ totem_change_notify, totem_config, &icmap_track); + + icmap_track_add("config.reload_in_progress", + ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY, + totem_reload_notify, + totem_config, + &icmap_track); } diff -Nru corosync-2.3.0/exec/totemiba.c corosync-2.3.3/exec/totemiba.c --- corosync-2.3.0/exec/totemiba.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/totemiba.c 2014-01-14 15:07:56.000000000 +0000 @@ -229,7 +229,7 @@ struct ibv_recv_wr recv_wr; struct ibv_sge sge; struct ibv_mr *mr; - char buffer[MAX_MTU_SIZE]; + char buffer[MAX_MTU_SIZE + sizeof (struct ibv_grh)]; }; struct send_buf { @@ -272,7 +272,7 @@ } send_buf->mr = ibv_reg_mr (instance->mcast_pd, send_buf->buffer, - 2048, IBV_ACCESS_LOCAL_WRITE); + MAX_MTU_SIZE, IBV_ACCESS_LOCAL_WRITE); if (send_buf->mr == NULL) { log_printf (LOGSYS_LEVEL_ERROR, "couldn't register memory range"); free (send_buf); @@ -309,7 +309,7 @@ } send_buf->mr = ibv_reg_mr (instance->send_token_pd, send_buf->buffer, - 2048, IBV_ACCESS_LOCAL_WRITE); + MAX_MTU_SIZE, IBV_ACCESS_LOCAL_WRITE); if (send_buf->mr == NULL) { log_printf (LOGSYS_LEVEL_ERROR, "couldn't register memory range"); free (send_buf); @@ -356,7 +356,7 @@ } recv_buf->mr = ibv_reg_mr (instance->recv_token_pd, &recv_buf->buffer, - 2048, + MAX_MTU_SIZE + sizeof (struct ibv_grh), IBV_ACCESS_LOCAL_WRITE); recv_buf->recv_wr.next = NULL; @@ -364,7 +364,7 @@ recv_buf->recv_wr.num_sge = 1; recv_buf->recv_wr.wr_id = (uintptr_t)recv_buf; - recv_buf->sge.length = 2048; + recv_buf->sge.length = MAX_MTU_SIZE + sizeof (struct ibv_grh); recv_buf->sge.lkey = recv_buf->mr->lkey; recv_buf->sge.addr = (uintptr_t)recv_buf->buffer; @@ -423,7 +423,7 @@ } mr = ibv_reg_mr (instance->mcast_pd, &recv_buf->buffer, - 2048, + MAX_MTU_SIZE + sizeof (struct ibv_grh), IBV_ACCESS_LOCAL_WRITE); recv_buf->recv_wr.next = NULL; @@ -431,7 +431,7 @@ recv_buf->recv_wr.num_sge = 1; recv_buf->recv_wr.wr_id = (uintptr_t)recv_buf; - recv_buf->sge.length = 2048; + recv_buf->sge.length = MAX_MTU_SIZE + sizeof (struct ibv_grh); recv_buf->sge.lkey = mr->lkey; recv_buf->sge.addr = (uintptr_t)recv_buf->buffer; @@ -468,10 +468,11 @@ recv_buf = wrid2void(wr_id); addr = &recv_buf->buffer[sizeof (struct ibv_grh)]; + bytes -= sizeof (struct ibv_grh); instance->totemiba_deliver_fn (instance->rrp_context, addr, bytes); } -static int mcast_cq_send_event_fn (int events, int suck, void *context) +static int mcast_cq_send_event_fn (int fd, int events, void *context) { struct totemiba_instance *instance = (struct totemiba_instance *)context; struct ibv_wc wc[32]; @@ -494,7 +495,7 @@ return (0); } -static int mcast_cq_recv_event_fn (int events, int suck, void *context) +static int mcast_cq_recv_event_fn (int fd, int events, void *context) { struct totemiba_instance *instance = (struct totemiba_instance *)context; struct ibv_wc wc[64]; @@ -518,7 +519,7 @@ return (0); } -static int mcast_rdma_event_fn (int events, int suck, void *context) +static int mcast_rdma_event_fn (int fd, int events, void *context) { struct totemiba_instance *instance = (struct totemiba_instance *)context; struct rdma_cm_event *event; @@ -591,7 +592,7 @@ return (0); } -static int recv_token_cq_recv_event_fn (int events, int suck, void *context) +static int recv_token_cq_recv_event_fn (int fd, int events, void *context) { struct totemiba_instance *instance = (struct totemiba_instance *)context; struct ibv_wc wc[32]; @@ -621,6 +622,14 @@ return (0); } + qb_loop_poll_del ( + instance->totemiba_poll_handle, + instance->recv_token_recv_completion_channel->fd); + + qb_loop_poll_del ( + instance->totemiba_poll_handle, + instance->recv_token_send_completion_channel->fd); + rdma_destroy_qp (instance->recv_token_cma_id); recv_token_recv_buf_post_destroy (instance); @@ -637,14 +646,6 @@ rdma_destroy_id (instance->recv_token_cma_id); - qb_loop_poll_del ( - instance->totemiba_poll_handle, - instance->recv_token_recv_completion_channel->fd); - - qb_loop_poll_del ( - instance->totemiba_poll_handle, - instance->recv_token_send_completion_channel->fd); - return (0); } @@ -743,7 +744,7 @@ return (res); }; -static int recv_token_rdma_event_fn (int events, int suck, void *context) +static int recv_token_rdma_event_fn (int fd, int events, void *context) { struct totemiba_instance *instance = (struct totemiba_instance *)context; struct rdma_cm_event *event; @@ -775,7 +776,7 @@ return (0); } -static int send_token_cq_send_event_fn (int events, int suck, void *context) +static int send_token_cq_send_event_fn (int fd, int events, void *context) { struct totemiba_instance *instance = (struct totemiba_instance *)context; struct ibv_wc wc[32]; @@ -798,7 +799,7 @@ return (0); } -static int send_token_cq_recv_event_fn (int events, int suck, void *context) +static int send_token_cq_recv_event_fn (int fd, int events, void *context) { struct totemiba_instance *instance = (struct totemiba_instance *)context; struct ibv_wc wc[32]; @@ -821,7 +822,7 @@ return (0); } -static int send_token_rdma_event_fn (int events, int suck, void *context) +static int send_token_rdma_event_fn (int fd, int events, void *context) { struct totemiba_instance *instance = (struct totemiba_instance *)context; struct rdma_cm_event *event; @@ -1051,6 +1052,7 @@ static int recv_token_bind (struct totemiba_instance *instance) { int res; + struct ibv_port_attr port_attr; instance->listen_recv_token_channel = rdma_create_event_channel(); if (instance->listen_recv_token_channel == NULL) { @@ -1072,6 +1074,20 @@ return (-1); } + /* + * Determine active_mtu of port and compare it with the configured one (160 is aproximation of all totem + * structures. + * + * TODO: Implement MTU discovery also for IP and handle MTU correctly for all structures inside totemsrp, + * crypto, ... + */ + res = ibv_query_port (instance->listen_recv_token_cma_id->verbs, instance->listen_recv_token_cma_id->port_num, &port_attr); + if ( (1 << (port_attr.active_mtu + 7)) < instance->totem_config->net_mtu + 160) { + log_printf (LOGSYS_LEVEL_ERROR, "requested net_mtu is %d and is larger than the active port mtu %d\n",\ + instance->totem_config->net_mtu + 160, (1 << (port_attr.active_mtu + 7))); + return (-1); + } + /* * Resolve the recv_token address into a GUID */ diff -Nru corosync-2.3.0/exec/totemip.c corosync-2.3.3/exec/totemip.c --- corosync-2.3.0/exec/totemip.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/totemip.c 2014-01-13 13:46:11.000000000 +0000 @@ -466,7 +466,7 @@ if (boundto->family == AF_INET && boundto->nodeid == 0) { unsigned int nodeid = 0; memcpy (&nodeid, boundto->addr, sizeof (int)); -#if __BYTE_ORDER == __BIG_ENDIAN +#if __BYTE_ORDER == __LITTLE_ENDIAN nodeid = swab32 (nodeid); #endif if (mask_high_bit) { diff -Nru corosync-2.3.0/exec/totempg.c corosync-2.3.3/exec/totempg.c --- corosync-2.3.0/exec/totempg.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/totempg.c 2014-01-13 13:46:11.000000000 +0000 @@ -236,8 +236,6 @@ static int fragment_continuation = 0; -static struct iovec iov_delv; - static int totempg_waiting_transack = 0; struct totempg_group_instance { @@ -630,6 +628,7 @@ int start; const char *data; int datasize; + struct iovec iov_delv; assembly = assembly_ref (nodeid); assert (assembly); diff -Nru corosync-2.3.0/exec/totemrrp.c corosync-2.3.3/exec/totemrrp.c --- corosync-2.3.0/exec/totemrrp.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/totemrrp.c 2014-01-13 13:46:11.000000000 +0000 @@ -180,7 +180,7 @@ }; -#define STATUS_STR_LEN 1024 +#define STATUS_STR_LEN 512 struct totemrrp_instance { qb_loop_t *poll_handle; diff -Nru corosync-2.3.0/exec/totemsrp.c corosync-2.3.3/exec/totemsrp.c --- corosync-2.3.0/exec/totemsrp.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/totemsrp.c 2014-01-14 15:07:56.000000000 +0000 @@ -524,6 +524,45 @@ 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 */ @@ -586,7 +625,7 @@ static void memb_ring_id_create_or_load (struct totemsrp_instance *, struct memb_ring_id *); 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, int gather_from); +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); @@ -617,6 +656,7 @@ 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); void main_deliver_fn ( void *context, @@ -659,6 +699,16 @@ fmt ": %s (%d)\n", ##args, _error_ptr, err_num); \ } while(0) +static const char* gsfrom_to_msg(enum gather_state_from gsfrom) +{ + if (0 <= gsfrom && 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)); @@ -1601,7 +1651,7 @@ memb_set_merge (no_consensus_list, no_consensus_list_entries, instance->my_failed_list, &instance->my_failed_list_entries); - memb_state_gather_enter (instance, 0); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_CONSENSUS_TIMEOUT); } } @@ -1623,7 +1673,7 @@ static void memb_recovery_state_token_loss (struct totemsrp_instance *instance) { old_ring_state_restore (instance); - memb_state_gather_enter (instance, 5); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_RECOVERY_STATE); instance->stats.recovery_token_lost++; } @@ -1638,7 +1688,7 @@ log_printf (instance->totemsrp_log_level_notice, "A processor failed, forming new configuration."); totemrrp_iface_check (instance->totemrrp_context); - memb_state_gather_enter (instance, 2); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_OPERATIONAL_STATE); instance->stats.operational_token_lost++; break; @@ -1646,14 +1696,14 @@ log_printf (instance->totemsrp_log_level_debug, "The consensus timeout expired."); memb_state_consensus_timeout_expired (instance); - memb_state_gather_enter (instance, 3); + 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, 4); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_COMMIT_STATE); instance->stats.commit_token_lost++; break; @@ -1796,6 +1846,8 @@ unsigned int left_list[PROCESSOR_COUNT_MAX]; unsigned int i; unsigned int res; + char left_node_msg[1024]; + char joined_node_msg[1024]; memb_consensus_reset (instance); @@ -1932,12 +1984,36 @@ 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, " %d", joined_list_totemip[i]); + } + } + else { + joined_node_msg[0] = '\0'; + } + + if (instance->my_left_memb_entries) { + int sptr = 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, " %d", left_list[i]); + } + } + else { + left_node_msg[0] = '\0'; + } + log_printf (instance->totemsrp_log_level_debug, "entering OPERATIONAL state."); log_printf (instance->totemsrp_log_level_notice, - "A processor joined or left the membership and a new membership (%s:%lld) was formed.", + "A new membership (%s:%lld) was formed. Members%s%s", totemip_print (&instance->my_ring_id.rep), - instance->my_ring_id.seq); + instance->my_ring_id.seq, + joined_node_msg, + left_node_msg); instance->memb_state = MEMB_STATE_OPERATIONAL; instance->stats.operational_entered++; @@ -1960,7 +2036,7 @@ static void memb_state_gather_enter ( struct totemsrp_instance *instance, - int gather_from) + enum gather_state_from gather_from) { instance->orf_token_discard = 1; @@ -2007,12 +2083,13 @@ memb_consensus_set (instance, &instance->my_id); log_printf (instance->totemsrp_log_level_debug, - "entering GATHER state from %d.", gather_from); + "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 == 3) { + if (TOTEMSRP_GSFROM_THE_CONSENSUS_TIMEOUT_EXPIRED == 3) { /* * State 3 means gather, so we are continuously gathering. */ @@ -3693,7 +3770,7 @@ instance->my_failed_list, &instance->my_failed_list_entries); - memb_state_gather_enter (instance, 6); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_FAILED_TO_RECEIVE); } else { instance->my_token_seq = token->token_seq; token->token_seq += 1; @@ -3948,7 +4025,7 @@ memb_set_merge ( &mcast_header.system_from, 1, instance->my_proc_list, &instance->my_proc_list_entries); - memb_state_gather_enter (instance, 7); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_FOREIGN_MESSAGE_IN_OPERATIONAL_STATE); break; case MEMB_STATE_GATHER: @@ -3960,7 +4037,7 @@ memb_set_merge (&mcast_header.system_from, 1, instance->my_proc_list, &instance->my_proc_list_entries); - memb_state_gather_enter (instance, 8); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_FOREIGN_MESSAGE_IN_GATHER_STATE); return (0); } break; @@ -4052,7 +4129,7 @@ case MEMB_STATE_OPERATIONAL: memb_set_merge (&memb_merge_detect.system_from, 1, instance->my_proc_list, &instance->my_proc_list_entries); - memb_state_gather_enter (instance, 9); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_MERGE_DURING_OPERATIONAL_STATE); break; case MEMB_STATE_GATHER: @@ -4064,7 +4141,7 @@ memb_set_merge (&memb_merge_detect.system_from, 1, instance->my_proc_list, &instance->my_proc_list_entries); - memb_state_gather_enter (instance, 10); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_MERGE_DURING_GATHER_STATE); return (0); } break; @@ -4191,7 +4268,7 @@ } } } - memb_state_gather_enter (instance, 11); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_MERGE_DURING_JOIN); gather_entered = 1; } @@ -4199,7 +4276,7 @@ if (gather_entered == 0 && instance->memb_state == MEMB_STATE_OPERATIONAL) { - memb_state_gather_enter (instance, 12); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_JOIN_DURING_OPERATIONAL_STATE); } } @@ -4323,6 +4400,36 @@ srp_addr_copy_endian_convert (&out->system_from, &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; + + 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; + + 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 (&memb_join->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, @@ -4353,7 +4460,9 @@ } switch (instance->memb_state) { case MEMB_STATE_OPERATIONAL: - memb_join_process (instance, memb_join); + if (!ignore_join_under_operational (instance, memb_join)) { + memb_join_process (instance, memb_join); + } break; case MEMB_STATE_GATHER: @@ -4369,7 +4478,7 @@ memb_join->ring_seq >= instance->my_ring_id.seq) { memb_join_process (instance, memb_join); - memb_state_gather_enter (instance, 13); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_JOIN_DURING_COMMIT_STATE); } break; @@ -4383,7 +4492,7 @@ memb_join_process (instance, memb_join); memb_recovery_state_token_loss (instance); - memb_state_gather_enter (instance, 14); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_JOIN_DURING_RECOVERY); } break; } @@ -4572,7 +4681,7 @@ } if (instance->iface_changes >= instance->totem_config->interface_count) { - memb_state_gather_enter (instance, 15); + memb_state_gather_enter (instance, TOTEMSRP_GSFROM_INTERFACE_CHANGE); } } diff -Nru corosync-2.3.0/exec/totemudp.c corosync-2.3.3/exec/totemudp.c --- corosync-2.3.0/exec/totemudp.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/totemudp.c 2014-01-13 13:46:11.000000000 +0000 @@ -1154,6 +1154,7 @@ instance->totemudp_log_level_error, instance->totemudp_subsys_id); if (instance->crypto_inst == NULL) { + free(instance); return (-1); } /* diff -Nru corosync-2.3.0/exec/totemudpu.c corosync-2.3.3/exec/totemudpu.c --- corosync-2.3.0/exec/totemudpu.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/totemudpu.c 2014-01-13 13:46:11.000000000 +0000 @@ -785,6 +785,7 @@ instance->totemudpu_log_level_error, instance->totemudpu_subsys_id); if (instance->crypto_inst == NULL) { + free(instance); return (-1); } /* @@ -1034,7 +1035,7 @@ if (res == -1) { LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning, "Could not set non-blocking operation on token socket"); - return (-1); + goto error_close_fd; } /* @@ -1047,6 +1048,9 @@ 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 + */ } /* @@ -1057,11 +1061,14 @@ if (res == -1) { LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning, "bind token socket failed"); - return (-1); + goto error_close_fd; } return (fd); +error_close_fd: + close(fd); + return (-1); } int totemudpu_member_add ( diff -Nru corosync-2.3.0/exec/votequorum.c corosync-2.3.3/exec/votequorum.c --- corosync-2.3.0/exec/votequorum.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/votequorum.c 2014-01-14 15:07:56.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Red Hat, Inc. + * Copyright (c) 2009-2014 Red Hat, Inc. * * All rights reserved. * @@ -36,7 +36,10 @@ #include #include +#include +#include #include +#include #include @@ -85,6 +88,10 @@ 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 */ @@ -225,13 +232,19 @@ * Service Interfaces required by service_message_handler struct */ -static void votequorum_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, +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; /* @@ -379,7 +392,10 @@ .exec_exit_fn = votequorum_exec_exit_fn, .exec_engine = votequorum_exec_engine, .exec_engine_count = sizeof (votequorum_exec_engine) / sizeof (struct corosync_exec_handler), - .confchg_fn = votequorum_confchg_fn + .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) @@ -580,6 +596,47 @@ 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, LOCALSTATEDIR "/lib/corosync/ev_tracking"); + + ev_tracking_fd = open(filename, O_RDWR, 0700); + if (ev_tracking_fd != -1) { + res = read (ev_tracking_fd, &ev_tracking_barrier, sizeof(uint32_t)); + 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); + } + 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(); @@ -635,6 +692,32 @@ 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!!!"); + } + fdatasync(ev_tracking_fd); + + LEAVE(); +} + /* * quorum calculation core bits */ @@ -783,7 +866,8 @@ } } - if (quorum_change) { + if ((quorum_change) && + (sync_in_progress == 0)) { quorum_callback(quorum_members, quorum_members_entries, cluster_is_quorate, &quorum_ringid); } @@ -844,6 +928,11 @@ 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); are_we_quorate(total_votes); @@ -917,25 +1006,28 @@ 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) && - (strlen(qdevice_model))) { - free(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_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; + } + update_qdevice_can_operate(1); + ret = 1; } - update_qdevice_can_operate(1); - return 1; + + free(qdevice_model); } LEAVE(); - return 0; + return ret; } #define VOTEQUORUM_READCONFIG_STARTUP 0 @@ -1009,6 +1101,21 @@ icmap_get_uint8("quorum.auto_tie_breaker", &auto_tie_breaker); icmap_get_uint8("quorum.last_man_standing", &last_man_standing); icmap_get_uint32("quorum.last_man_standing_window", &last_man_standing_window); + icmap_get_uint8("quorum.expected_votes_tracking", &ev_tracking); + + /* 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); + } + } /* @@ -1131,6 +1238,11 @@ /* * 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; @@ -1624,6 +1736,9 @@ 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; @@ -1650,7 +1765,7 @@ us->expected_votes = req_exec_quorum_nodeinfo->expected_votes; } - if (node->flags & NODE_FLAGS_QUORATE) { + if (node->flags & NODE_FLAGS_QUORATE || (ev_tracking)) { node->expected_votes = req_exec_quorum_nodeinfo->expected_votes; } else { node->expected_votes = us->expected_votes; @@ -1667,7 +1782,6 @@ } recalculate: - if ((new_node) || (nodeid == us->node_id) || (node->flags & NODE_FLAGS_FIRST) || @@ -1723,6 +1837,9 @@ } 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; @@ -1756,6 +1873,11 @@ ret = votequorum_exec_send_nodeinfo(us->node_id); } + if ((ev_tracking) && (ev_tracking_fd != -1)) { + close(ev_tracking_fd); + } + + LEAVE(); return ret; } @@ -1838,25 +1960,41 @@ LEAVE(); } -static void votequorum_confchg_fn ( - enum totem_configuration_type configuration_type, +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 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 i, j; + int found; + int left_nodes; struct cluster_node *node; ENTER(); + sync_in_progress = 1; + if (member_list_entries > 1) { us->flags &= ~NODE_FLAGS_FIRST; } - if (left_list_entries) { - for (i = 0; i< left_list_entries; i++) { - node = find_node_by_nodeid(left_list[i]); + /* + * 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; } @@ -1864,7 +2002,7 @@ } if (last_man_standing) { - if (((member_list_entries >= quorum) && (left_list_entries)) || + if (((member_list_entries >= quorum) && (left_nodes)) || ((member_list_entries <= quorum) && (auto_tie_breaker) && (check_low_node_id_partition() == 1))) { if (last_man_standing_timer_set) { corosync_api->timer_delete(last_man_standing_timer); @@ -1877,31 +2015,36 @@ } } - if (member_list_entries) { - memcpy(quorum_members, member_list, sizeof(unsigned int) * member_list_entries); - quorum_members_entries = member_list_entries; - 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); - } - } - + 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 (left_list_entries) { - recalculate_quorum(0, 0); - } + LEAVE(); +} - if (configuration_type == TOTEM_CONFIGURATION_REGULAR) { - quorum_callback(quorum_members, quorum_members_entries, - cluster_is_quorate, &quorum_ringid); +static int votequorum_sync_process (void) +{ + 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); } + return 0; +} - LEAVE(); +static void votequorum_sync_activate (void) +{ + recalculate_quorum(0, 0); + quorum_callback(quorum_members, quorum_members_entries, + cluster_is_quorate, &quorum_ringid); + 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) diff -Nru corosync-2.3.0/exec/vsf_ykd.c corosync-2.3.3/exec/vsf_ykd.c --- corosync-2.3.0/exec/vsf_ykd.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/exec/vsf_ykd.c 2014-01-13 13:46:11.000000000 +0000 @@ -512,7 +512,7 @@ struct corosync_api_v1 *corosync_api, quorum_set_quorate_fn_t set_primary) { - char *error; + const char *error = ""; ykd_primary_callback_fn = set_primary; api = corosync_api; diff -Nru corosync-2.3.0/include/corosync/cfg.h corosync-2.3.3/include/corosync/cfg.h --- corosync-2.3.0/include/corosync/cfg.h 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/include/corosync/cfg.h 2014-01-13 13:46:11.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2005 MontaVista Software, Inc. - * Copyright (c) 2006-2012 Red Hat, Inc. + * Copyright (c) 2006-2013 Red Hat, Inc. * * All rights reserved. * @@ -157,6 +157,9 @@ corosync_cfg_handle_t handle, unsigned int *local_nodeid); +cs_error_t corosync_cfg_reload_config ( + corosync_cfg_handle_t handle); + #ifdef __cplusplus } #endif diff -Nru corosync-2.3.0/include/corosync/corotypes.h corosync-2.3.3/include/corosync/corotypes.h --- corosync-2.3.0/include/corosync/corotypes.h 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/include/corosync/corotypes.h 2014-01-13 13:46:11.000000000 +0000 @@ -41,6 +41,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + typedef int64_t cs_time_t; #define CS_FALSE 0 @@ -136,5 +140,9 @@ const char * cs_strerror(cs_error_t err); cs_error_t hdb_error_to_cs (int res); +#ifdef __cplusplus +} +#endif + #endif /* COROTYPES_H_DEFINED */ diff -Nru corosync-2.3.0/include/corosync/icmap.h corosync-2.3.3/include/corosync/icmap.h --- corosync-2.3.0/include/corosync/icmap.h 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/include/corosync/icmap.h 2014-01-13 13:46:11.000000000 +0000 @@ -107,6 +107,15 @@ void *user_data); /* + * 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; + +/* * Itterator type */ typedef qb_map_iter_t *icmap_iter_t; @@ -117,13 +126,46 @@ typedef struct icmap_track *icmap_track_t; /* - * Initialize icmap + * Initialize global icmap */ extern cs_error_t icmap_init(void); + +/* + * Initialize additional (local, reentrant) icmap_map. Content of variable + * result is undefined if return code is not CS_OK. + */ +extern cs_error_t icmap_init_r(icmap_map_t *result); + +/* + * Finalize global icmap + */ extern void icmap_fini(void); /* - * Store value with value_len length and type as key_name name in icmap. + * Finalize local, reentrant icmap + */ +extern void icmap_fini_r(const icmap_map_t map); + +/* + * Return global icmap + */ +extern icmap_map_t icmap_get_global_map(void); + +/* + * 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. + */ +extern int icmap_key_value_eq( + const icmap_map_t map1, + const char *key_name1, + const icmap_map_t map2, + const char *key_name2); + +/* + * Store value with value_len length and type as key_name name in global icmap. */ extern cs_error_t icmap_set( const char *key_name, @@ -132,6 +174,16 @@ icmap_value_types_t type); /* + * Reentrant version of icmap_set + */ +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); @@ -146,11 +198,25 @@ 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); + /* * Delete key from map */ extern cs_error_t icmap_delete(const char *key_name); +extern cs_error_t icmap_delete_r(const icmap_map_t map, const char *key_name); + /* * 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 @@ -166,6 +232,16 @@ icmap_value_types_t *type); /* + * Same as icmap_get but it's reentrant and operates on given icmap_map + */ +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); @@ -178,6 +254,21 @@ 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); + /* * Shortcut for icmap_get for string type. Returned string is newly allocated and * caller is responsible for freeing memory @@ -189,6 +280,8 @@ */ extern cs_error_t icmap_adjust_int(const char *key_name, int32_t step); +extern cs_error_t icmap_adjust_int_r(const icmap_map_t map, const char *key_name, int32_t step); + /* * 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 @@ -197,33 +290,45 @@ */ extern cs_error_t icmap_fast_adjust_int(const char *key_name, int32_t step); +extern cs_error_t icmap_fast_adjust_int_r(const icmap_map_t map, const char *key_name, int32_t step); + /* * Increase stored value by one */ extern cs_error_t icmap_inc(const char *key_name); +extern cs_error_t icmap_inc_r(const icmap_map_t map, const char *key_name); + /* * Decrease stored value by one */ extern cs_error_t icmap_dec(const char *key_name); +extern cs_error_t icmap_dec_r(const icmap_map_t map, const char *key_name); + /* * Increase stored value by one. Difference between this function and icmap_inc * is same as between icmap_adjust_int and icmap_fast_adjust_int. */ extern cs_error_t icmap_fast_inc(const char *key_name); +extern cs_error_t icmap_fast_inc_r(const icmap_map_t map, const char *key_name); + /* * Decrease stored value by one. Difference between this function and icmap_dec * is same as between icmap_adjust_int and icmap_fast_adjust_int. */ extern cs_error_t icmap_fast_dec(const char *key_name); +extern cs_error_t icmap_fast_dec_r(const icmap_map_t map, const char *key_name); + /* * Initialize iterator with given prefix */ extern icmap_iter_t icmap_iter_init(const char *prefix); +extern icmap_iter_t icmap_iter_init_r(const icmap_map_t map, const char *prefix); + /* * 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 @@ -276,6 +381,11 @@ */ extern void icmap_convert_name_to_valid_name(char *key_name); +/* + * Copy content of src_map icmap to dst_map icmap. + */ +extern cs_error_t icmap_copy_map(icmap_map_t dst_map, const icmap_map_t src_map); + #ifdef __cplusplus } #endif diff -Nru corosync-2.3.0/include/corosync/ipc_cfg.h corosync-2.3.3/include/corosync/ipc_cfg.h --- corosync-2.3.0/include/corosync/ipc_cfg.h 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/include/corosync/ipc_cfg.h 2014-01-13 13:46:11.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2005 MontaVista Software, Inc. - * Copyright (c) 2009-2012 Red Hat, Inc. + * Copyright (c) 2009-2013 Red Hat, Inc. * * All rights reserved. * @@ -39,6 +39,14 @@ #include #include +#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 + enum req_lib_cfg_types { MESSAGE_REQ_CFG_RINGSTATUSGET = 0, MESSAGE_REQ_CFG_RINGREENABLE = 1, @@ -47,7 +55,8 @@ MESSAGE_REQ_CFG_REPLYTOSHUTDOWN = 4, MESSAGE_REQ_CFG_GET_NODE_ADDRS = 5, MESSAGE_REQ_CFG_LOCAL_GET = 6, - MESSAGE_REQ_CFG_CRYPTO_SET = 7 + MESSAGE_REQ_CFG_RELOAD_CONFIG = 7, + MESSAGE_REQ_CFG_CRYPTO_SET = 8 }; enum res_lib_cfg_types { @@ -66,6 +75,7 @@ MESSAGE_RES_CFG_LOCAL_GET = 12, MESSAGE_RES_CFG_REPLYTOSHUTDOWN = 13, MESSAGE_RES_CFG_CRYPTO_SET = 14, + MESSAGE_RES_CFG_RELOAD_CONFIG = 15 }; struct req_lib_cfg_ringstatusget { @@ -75,8 +85,8 @@ 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[16][128] __attribute__((aligned(8))); - char interface_status[16][512] __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))); }; struct req_lib_cfg_ringreenable { @@ -129,7 +139,8 @@ struct qb_ipc_response_header header __attribute__((aligned(8))); unsigned int family; unsigned int num_addrs; - char addrs[TOTEMIP_ADDRLEN][0]; + /* array of TOTEMIP_ADDRLEN items */ + char addrs[]; }; struct req_lib_cfg_local_get { @@ -141,6 +152,14 @@ mar_uint32_t local_nodeid __attribute__((aligned(8))); }; +struct req_lib_cfg_reload_config { + struct qb_ipc_request_header header __attribute__((aligned(8))); +}; + +struct res_lib_cfg_reload_config { + struct qb_ipc_response_header header __attribute__((aligned(8))); +}; + typedef enum { AIS_AMF_ADMINISTRATIVETARGET_SERVICEUNIT = 0, AIS_AMF_ADMINISTRATIVETARGET_SERVICEGROUP = 1, diff -Nru corosync-2.3.0/include/corosync/ipc_cpg.h corosync-2.3.3/include/corosync/ipc_cpg.h --- corosync-2.3.0/include/corosync/ipc_cpg.h 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/include/corosync/ipc_cpg.h 2014-01-13 13:46:11.000000000 +0000 @@ -40,6 +40,8 @@ #include #include +#define CPG_ZC_PATH_LEN 128 + enum req_cpg_types { MESSAGE_REQ_CPG_JOIN = 0, MESSAGE_REQ_CPG_LEAVE = 1, @@ -298,7 +300,7 @@ typedef struct { struct qb_ipc_request_header header __attribute__((aligned(8))); size_t map_size __attribute__((aligned(8))); - char path_to_file[128] __attribute__((aligned(8))); + char path_to_file[CPG_ZC_PATH_LEN] __attribute__((aligned(8))); } mar_req_coroipcc_zc_alloc_t __attribute__((aligned(8))); typedef struct { diff -Nru corosync-2.3.0/include/Makefile.in corosync-2.3.3/include/Makefile.in --- corosync-2.3.0/include/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/include/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -208,8 +208,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/init/corosync.conf.in corosync-2.3.3/init/corosync.conf.in --- corosync-2.3.0/init/corosync.conf.in 1970-01-01 00:00:00.000000000 +0000 +++ corosync-2.3.3/init/corosync.conf.in 2014-01-13 13:46:11.000000000 +0000 @@ -0,0 +1,52 @@ +# corosync - Corosync Cluster Engine +# +# Starts corosync + +expect fork + +env prog=corosync +env rpm_sysconf=@SYSCONFDIR@/sysconfig/corosync +env rpm_lockfile=@LOCALSTATEDIR@/lock/subsys/corosync +env deb_sysconf=@SYSCONFDIR@/default/corosync +env deb_lockfile=@LOCALSTATEDIR@/lock/corosync + +script + [ -f "$rpm_sysconf" ] && . $rpm_sysconf + [ -f "$deb_sysconf" ] && . $deb_sysconf + exec $prog +end script + +pre-start script + mkdir -p @LOCALSTATEDIR@/run +end script + +post-start script +wait_for_ipc() +{ + try=0 + while [ "$try" -le "20" ]; do + if corosync-cfgtool -s > /dev/null 2>&1; then + return 0 + fi + sleep 0.5 + try=$((try + 1)) + done + logger -i -t "$UPSTART_JOB" "ERROR: Any interfaces are faulty!" + return 1 +} + wait_for_ipc || { stop; exit 1; } + + [ -f "$rpm_sysconf" ] && . $rpm_sysconf + [ -f "$deb_sysconf" ] && . $deb_sysconf + [ -z "$LOCK_FILE" -a -d @SYSCONFDIR@/sysconfig ] && LOCK_FILE="$rpm_lockfile" + [ -z "$LOCK_FILE" -a -d @SYSCONFDIR@/default ] && LOCK_FILE="$deb_lockfile" + touch $LOCK_FILE +end script + +post-stop script + [ -f "$rpm_sysconf" ] && . $rpm_sysconf + [ -f "$deb_sysconf" ] && . $deb_sysconf + [ -z "$LOCK_FILE" -a -d @SYSCONFDIR@/sysconfig ] && LOCK_FILE="$rpm_lockfile" + [ -z "$LOCK_FILE" -a -d @SYSCONFDIR@/default ] && LOCK_FILE="$deb_lockfile" + rm -f $LOCK_FILE +end script diff -Nru corosync-2.3.0/init/corosync-notifyd.conf.in corosync-2.3.3/init/corosync-notifyd.conf.in --- corosync-2.3.0/init/corosync-notifyd.conf.in 1970-01-01 00:00:00.000000000 +0000 +++ corosync-2.3.3/init/corosync-notifyd.conf.in 2014-01-13 13:46:11.000000000 +0000 @@ -0,0 +1,38 @@ +# corosync-notifyd - Corosync Dbus and snmp notifier +# +# Starts corosync-notifyd + +expect fork +respawn + +env prog=corosync-notifyd +env rpm_sysconf=@SYSCONFDIR@/sysconfig/corosync-notifyd +env rpm_lockfile=@LOCALSTATEDIR@/lock/subsys/corosync-notifyd +env deb_sysconf=@SYSCONFDIR@/default/corosync-notifyd +env deb_lockfile=@LOCALSTATEDIR@/lock/corosync-notifyd + +script + [ -f "$rpm_sysconf" ] && . $rpm_sysconf + [ -f "$deb_sysconf" ] && . $deb_sysconf + exec $prog $OPTIONS +end script + +pre-start script + mkdir -p @LOCALSTATEDIR@/run +end script + +post-start script + [ -f "$rpm_sysconf" ] && . $rpm_sysconf + [ -f "$deb_sysconf" ] && . $deb_sysconf + [ -z "$LOCK_FILE" -a -d @SYSCONFDIR@/sysconfig ] && LOCK_FILE="$rpm_lockfile" + [ -z "$LOCK_FILE" -a -d @SYSCONFDIR@/default ] && LOCK_FILE="$deb_lockfile" + touch $LOCK_FILE +end script + +post-stop script + [ -f "$rpm_sysconf" ] && . $rpm_sysconf + [ -f "$deb_sysconf" ] && . $deb_sysconf + [ -z "$LOCK_FILE" -a -d @SYSCONFDIR@/sysconfig ] && LOCK_FILE="$rpm_lockfile" + [ -z "$LOCK_FILE" -a -d @SYSCONFDIR@/default ] && LOCK_FILE="$deb_lockfile" + rm -f $LOCK_FILE +end script diff -Nru corosync-2.3.0/init/corosync-notifyd.service.in corosync-2.3.3/init/corosync-notifyd.service.in --- corosync-2.3.0/init/corosync-notifyd.service.in 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/init/corosync-notifyd.service.in 2014-01-13 13:46:11.000000000 +0000 @@ -4,9 +4,10 @@ After=corosync.service [Service] -EnvironmentFile=@SYSCONFIGDIR@/corosync-notifyd +EnvironmentFile=@SYSCONFDIR@/sysconfig/corosync-notifyd ExecStart=@SBINDIR@/corosync-notifyd -f $OPTIONS Type=simple +Restart=on-failure [Install] WantedBy=multi-user.target diff -Nru corosync-2.3.0/init/corosync.service.in corosync-2.3.3/init/corosync.service.in --- corosync-2.3.0/init/corosync.service.in 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/init/corosync.service.in 2014-01-14 15:07:56.000000000 +0000 @@ -1,8 +1,8 @@ [Unit] Description=Corosync Cluster Engine ConditionKernelCommandLine=!nocluster -Requires=network.target -After=network.target +Requires=network-online.target +After=network-online.target [Service] ExecStart=@INITWRAPPERSDIR@/corosync start diff -Nru corosync-2.3.0/init/Makefile.am corosync-2.3.3/init/Makefile.am --- corosync-2.3.0/init/Makefile.am 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/init/Makefile.am 2014-01-13 13:46:11.000000000 +0000 @@ -34,7 +34,7 @@ MAINTAINERCLEANFILES = Makefile.in -EXTRA_DIST = corosync.in corosync-notifyd.in corosync.service.in corosync-notifyd.service.in +EXTRA_DIST = corosync.in corosync-notifyd.in corosync.service.in corosync-notifyd.service.in corosync.conf.in corosync-notifyd.conf.in if INSTALL_SYSTEMD systemdconfdir = $(SYSTEMDDIR) @@ -45,6 +45,11 @@ endif initscript_SCRIPTS = corosync corosync-notifyd +if INSTALL_UPSTART +upstartconfdir = $(UPSTARTDIR) +upstartconf_DATA = corosync.conf corosync-notifyd.conf +endif + %: %.in Makefile rm -f $@-t $@ cat $< | sed \ @@ -57,7 +62,7 @@ > $@-t mv $@-t $@ -all-local: $(initscript_SCRIPTS) $(systemdconf_DATA) +all-local: $(initscript_SCRIPTS) $(systemdconf_DATA) $(upstartconf_DATA) clean-local: - rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA) + rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA) $(upstartconf_DATA) diff -Nru corosync-2.3.0/init/Makefile.in corosync-2.3.3/init/Makefile.in --- corosync-2.3.0/init/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/init/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -108,7 +108,7 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(initscriptdir)" \ - "$(DESTDIR)$(systemdconfdir)" + "$(DESTDIR)$(systemdconfdir)" "$(DESTDIR)$(upstartconfdir)" SCRIPTS = $(initscript_SCRIPTS) AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) @@ -118,7 +118,7 @@ am__v_at_0 = @ SOURCES = DIST_SOURCES = -DATA = $(systemdconf_DATA) +DATA = $(systemdconf_DATA) $(upstartconf_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ @@ -211,8 +211,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ @@ -275,12 +278,14 @@ 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 +EXTRA_DIST = corosync.in corosync-notifyd.in corosync.service.in corosync-notifyd.service.in corosync.conf.in corosync-notifyd.conf.in @INSTALL_SYSTEMD_TRUE@systemdconfdir = $(SYSTEMDDIR) @INSTALL_SYSTEMD_TRUE@systemdconf_DATA = corosync.service corosync-notifyd.service @INSTALL_SYSTEMD_FALSE@initscriptdir = $(INITDDIR) @INSTALL_SYSTEMD_TRUE@initscriptdir = $(INITWRAPPERSDIR) initscript_SCRIPTS = corosync corosync-notifyd +@INSTALL_UPSTART_TRUE@upstartconfdir = $(UPSTARTDIR) +@INSTALL_UPSTART_TRUE@upstartconf_DATA = corosync.conf corosync-notifyd.conf all: all-am .SUFFIXES: @@ -374,6 +379,26 @@ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(systemdconfdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(systemdconfdir)" && rm -f $$files +install-upstartconfDATA: $(upstartconf_DATA) + @$(NORMAL_INSTALL) + test -z "$(upstartconfdir)" || $(MKDIR_P) "$(DESTDIR)$(upstartconfdir)" + @list='$(upstartconf_DATA)'; test -n "$(upstartconfdir)" || list=; \ + 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)$(upstartconfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(upstartconfdir)" || exit $$?; \ + done + +uninstall-upstartconfDATA: + @$(NORMAL_UNINSTALL) + @list='$(upstartconf_DATA)'; test -n "$(upstartconfdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(upstartconfdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(upstartconfdir)" && rm -f $$files tags: TAGS TAGS: @@ -415,7 +440,7 @@ check: check-am all-am: Makefile $(SCRIPTS) $(DATA) all-local installdirs: - for dir in "$(DESTDIR)$(initscriptdir)" "$(DESTDIR)$(systemdconfdir)"; do \ + for dir in "$(DESTDIR)$(initscriptdir)" "$(DESTDIR)$(systemdconfdir)" "$(DESTDIR)$(upstartconfdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -464,7 +489,8 @@ info-am: -install-data-am: install-initscriptSCRIPTS install-systemdconfDATA +install-data-am: install-initscriptSCRIPTS install-systemdconfDATA \ + install-upstartconfDATA install-dvi: install-dvi-am @@ -508,7 +534,8 @@ ps-am: -uninstall-am: uninstall-initscriptSCRIPTS uninstall-systemdconfDATA +uninstall-am: uninstall-initscriptSCRIPTS uninstall-systemdconfDATA \ + uninstall-upstartconfDATA .MAKE: install-am install-strip @@ -520,11 +547,12 @@ 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 uninstall uninstall-am uninstall-initscriptSCRIPTS \ - uninstall-systemdconfDATA + install-systemdconfDATA install-upstartconfDATA installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-initscriptSCRIPTS uninstall-systemdconfDATA \ + uninstall-upstartconfDATA %: %.in Makefile @@ -539,10 +567,10 @@ > $@-t mv $@-t $@ -all-local: $(initscript_SCRIPTS) $(systemdconf_DATA) +all-local: $(initscript_SCRIPTS) $(systemdconf_DATA) $(upstartconf_DATA) clean-local: - rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA) + rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA) $(upstartconf_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. diff -Nru corosync-2.3.0/lib/cfg.c corosync-2.3.3/lib/cfg.c --- corosync-2.3.0/lib/cfg.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/lib/cfg.c 2014-01-13 13:46:11.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2002-2005 MontaVista Software, Inc. - * Copyright (c) 2006-2011 Red Hat, Inc. + * Copyright (c) 2006-2013 Red Hat, Inc. * * All rights reserved. * @@ -617,6 +617,45 @@ 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); } diff -Nru corosync-2.3.0/lib/cpg.c corosync-2.3.3/lib/cpg.c --- corosync-2.3.0/lib/cpg.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/lib/cpg.c 2014-01-13 13:46:11.000000000 +0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,11 @@ #define MAP_ANONYMOUS MAP_ANON #endif +/* + * ZCB files have following umask (umask is same as used in libqb) + */ +#define CPG_MEMORY_MAP_UMASK 077 + struct cpg_inst { qb_ipcc_connection_t *c; int finalize; @@ -730,20 +736,25 @@ memory_map (char *path, const char *file, void **buf, size_t bytes) { int32_t fd; - void *addr_orig; 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); } @@ -753,7 +764,11 @@ if (res == -1) { goto error_close_unlink; } - page_size = (size_t)sysconf(_SC_PAGESIZE); + 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; @@ -772,28 +787,21 @@ } free (buffer); - addr_orig = mmap (NULL, bytes, PROT_NONE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - - if (addr_orig == MAP_FAILED) { - goto error_close_unlink; - } - - addr = mmap (addr_orig, bytes, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, fd, 0); + addr = mmap (NULL, bytes, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); - if (addr != addr_orig) { + if (addr == MAP_FAILED) { goto error_close_unlink; } #ifdef MADV_NOSYNC - madvise(addr_orig, bytes, MADV_NOSYNC); + madvise(addr, bytes, MADV_NOSYNC); #endif res = close (fd); if (res) { return (-1); } - *buf = addr_orig; + *buf = addr; return 0; @@ -826,6 +834,12 @@ 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; diff -Nru corosync-2.3.0/lib/Makefile.am corosync-2.3.3/lib/Makefile.am --- corosync-2.3.0/lib/Makefile.am 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/lib/Makefile.am 2014-01-13 13:46:11.000000000 +0000 @@ -49,7 +49,7 @@ # override global LIBS that pulls in lots of craft we don't need here LIBS = -version-number $(call get_soname,$<) \ - -Wl,-version-script=$(srcdir)/lib$(call get_libname,$<).versions \ + @VERSCRIPT_LDFLAGS@ \ -lpthread \ $(top_builddir)/common_lib/libcorosync_common.la \ $(LIBQB_LIBS) diff -Nru corosync-2.3.0/lib/Makefile.in corosync-2.3.3/lib/Makefile.in --- corosync-2.3.0/lib/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/lib/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -221,7 +221,7 @@ # override global LIBS that pulls in lots of craft we don't need here LIBS = -version-number $(call get_soname,$<) \ - -Wl,-version-script=$(srcdir)/lib$(call get_libname,$<).versions \ + @VERSCRIPT_LDFLAGS@ \ -lpthread \ $(top_builddir)/common_lib/libcorosync_common.la \ $(LIBQB_LIBS) @@ -263,8 +263,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/Makefile.am corosync-2.3.3/Makefile.am --- corosync-2.3.0/Makefile.am 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/Makefile.am 2014-01-13 13:46:11.000000000 +0000 @@ -59,6 +59,17 @@ 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 \ @@ -156,11 +167,11 @@ srpm: clean $(MAKE) $(SPEC) $(TARFILE) - rpmbuild $(RPMBUILDOPTS) --nodeps -bs $(SPEC) + rpmbuild $(WITH_LIST) $(RPMBUILDOPTS) --nodeps -bs $(SPEC) rpm: clean _version $(MAKE) $(SPEC) $(TARFILE) - rpmbuild $(RPMBUILDOPTS) -ba $(SPEC) + rpmbuild $(WITH_LIST) $(RPMBUILDOPTS) -ba $(SPEC) # release/versioning BUILT_SOURCES = .version diff -Nru corosync-2.3.0/Makefile.in corosync-2.3.3/Makefile.in --- corosync-2.3.0/Makefile.in 2013-01-18 08:53:35.000000000 +0000 +++ corosync-2.3.3/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -264,8 +264,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ @@ -988,6 +991,17 @@ 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 \ @@ -1071,11 +1085,11 @@ srpm: clean $(MAKE) $(SPEC) $(TARFILE) - rpmbuild $(RPMBUILDOPTS) --nodeps -bs $(SPEC) + rpmbuild $(WITH_LIST) $(RPMBUILDOPTS) --nodeps -bs $(SPEC) rpm: clean _version $(MAKE) $(SPEC) $(TARFILE) - rpmbuild $(RPMBUILDOPTS) -ba $(SPEC) + rpmbuild $(WITH_LIST) $(RPMBUILDOPTS) -ba $(SPEC) .version: echo $(VERSION) > $@-t && mv $@-t $@ diff -Nru corosync-2.3.0/man/cmap_keys.8 corosync-2.3.3/man/cmap_keys.8 --- corosync-2.3.0/man/cmap_keys.8 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/man/cmap_keys.8 2014-01-13 13:46:11.000000000 +0000 @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2013 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -269,6 +269,13 @@ Informations about users/groups which are allowed to do IPC connection to corosync. +.TP +config.reload_in_progress +This value will be set to 1 (or created) when 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. + .SH DYNAMIC CHANGE USER/GROUP PERMISSION TO USE COROSYNC IPC Is very same as in configuration file. To add UID 500 use diff -Nru corosync-2.3.0/man/corosync-cfgtool.8 corosync-2.3.3/man/corosync-cfgtool.8 --- corosync-2.3.0/man/corosync-cfgtool.8 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/man/corosync-cfgtool.8 2014-01-13 13:46:11.000000000 +0000 @@ -68,6 +68,9 @@ .B -k Kill a node identified by node id. .TP +.B -R +Tell all instances of corosync in this cluster to reload corosync.conf +.TP .B -H Shutdown corosync cleanly on this node. .SH "SEE ALSO" diff -Nru corosync-2.3.0/man/corosync.conf.5 corosync-2.3.3/man/corosync.conf.5 --- corosync-2.3.0/man/corosync.conf.5 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/man/corosync.conf.5 2014-01-13 13:46:11.000000000 +0000 @@ -547,11 +547,10 @@ .B copytruncate. eg. -.IP -.RS .ne 18 +.RS .nf -.ta 4n 30n 33n +.ft CW /var/log/corosync.log { missingok compress @@ -560,12 +559,9 @@ rotate 7 copytruncate } -.ta +.ft .fi .RE -.IP -.PP - .TP logfile diff -Nru corosync-2.3.0/man/Makefile.am corosync-2.3.3/man/Makefile.am --- corosync-2.3.0/man/Makefile.am 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/man/Makefile.am 2014-01-14 15:07:56.000000000 +0000 @@ -1,5 +1,5 @@ # Copyright (c) 2004 MontaVista Software, Inc. -# Copyright (c) 2009, 2012 Red Hat, Inc. +# Copyright (c) 2009, 2012, 2014 Red Hat, Inc. # # Authors: Steven Dake (sdake@redhat.com) # Fabio M. Di Nitto (fdinitto@redhat.com) @@ -77,6 +77,11 @@ 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 \ diff -Nru corosync-2.3.0/man/Makefile.in corosync-2.3.3/man/Makefile.in --- corosync-2.3.0/man/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/man/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -16,7 +16,7 @@ @SET_MAKE@ # Copyright (c) 2004 MontaVista Software, Inc. -# Copyright (c) 2009, 2012 Red Hat, Inc. +# Copyright (c) 2009, 2012, 2014 Red Hat, Inc. # # Authors: Steven Dake (sdake@redhat.com) # Fabio M. Di Nitto (fdinitto@redhat.com) @@ -214,8 +214,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ @@ -320,6 +323,11 @@ 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 \ diff -Nru corosync-2.3.0/man/votequorum.5 corosync-2.3.3/man/votequorum.5 --- corosync-2.3.0/man/votequorum.5 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/man/votequorum.5 2014-01-14 15:07:56.000000000 +0000 @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2014 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -275,6 +275,8 @@ .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 @@ -315,6 +317,27 @@ 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 /var/lib/corosync/ev_tracking 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 diff -Nru corosync-2.3.0/man/votequorum_qdevice_master_wins.3.in corosync-2.3.3/man/votequorum_qdevice_master_wins.3.in --- corosync-2.3.0/man/votequorum_qdevice_master_wins.3.in 1970-01-01 00:00:00.000000000 +0000 +++ corosync-2.3.3/man/votequorum_qdevice_master_wins.3.in 2014-01-14 15:07:56.000000000 +0000 @@ -0,0 +1,77 @@ +.\"/* +.\" * Copyright (c) 2014 Red Hat, Inc. +.\" * +.\" * All rights reserved. +.\" * +.\" * Author: Christine Caulfield +.\" * +.\" * 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 +.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 (8), +.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 -Nru corosync-2.3.0/man/votequorum_qdevice_poll.3.in corosync-2.3.3/man/votequorum_qdevice_poll.3.in --- corosync-2.3.0/man/votequorum_qdevice_poll.3.in 1970-01-01 00:00:00.000000000 +0000 +++ corosync-2.3.3/man/votequorum_qdevice_poll.3.in 2014-01-14 15:07:56.000000000 +0000 @@ -0,0 +1,77 @@ +.\"/* +.\" * Copyright (c) 2009,2012,2014 Red Hat, Inc. +.\" * +.\" * All rights reserved. +.\" * +.\" * Author: Christine Caulfield +.\" * +.\" * 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 +.sp +.BI "int votequorum_qdevice_poll(votequorum_handle_t " handle ", const char * " name ", unsigned int " cast_vote ");" +.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. +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 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 +quorum.quorumdev_poll. +.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 (8), +.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 -Nru corosync-2.3.0/man/votequorum_qdevice_register.3.in corosync-2.3.3/man/votequorum_qdevice_register.3.in --- corosync-2.3.0/man/votequorum_qdevice_register.3.in 1970-01-01 00:00:00.000000000 +0000 +++ corosync-2.3.3/man/votequorum_qdevice_register.3.in 2014-01-14 15:07:56.000000000 +0000 @@ -0,0 +1,83 @@ +.\"/* +.\" * Copyright (c) 2009,2012,2014 Red Hat, Inc. +.\" * +.\" * All rights reserved. +.\" * +.\" * Author: Christine Caulfield +.\" * +.\" * 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 +.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 (8), +.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 -Nru corosync-2.3.0/man/votequorum_qdevice_unregister.3.in corosync-2.3.3/man/votequorum_qdevice_unregister.3.in --- corosync-2.3.0/man/votequorum_qdevice_unregister.3.in 1970-01-01 00:00:00.000000000 +0000 +++ corosync-2.3.3/man/votequorum_qdevice_unregister.3.in 2014-01-14 15:07:56.000000000 +0000 @@ -0,0 +1,68 @@ +.\"/* +.\" * Copyright (c) 2009,2012,2014 Red Hat, Inc. +.\" * +.\" * All rights reserved. +.\" * +.\" * Author: Christine Caulfield +.\" * +.\" * 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 +.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 (8), +.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 -Nru corosync-2.3.0/man/votequorum_qdevice_update.3.in corosync-2.3.3/man/votequorum_qdevice_update.3.in --- corosync-2.3.0/man/votequorum_qdevice_update.3.in 1970-01-01 00:00:00.000000000 +0000 +++ corosync-2.3.3/man/votequorum_qdevice_update.3.in 2014-01-14 15:07:56.000000000 +0000 @@ -0,0 +1,69 @@ +.\"/* +.\" * Copyright (c) 2014 Red Hat, Inc. +.\" * +.\" * All rights reserved. +.\" * +.\" * Author: Christine Caulfield +.\" * +.\" * 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 +.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 (8), +.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 -Nru corosync-2.3.0/pkgconfig/Makefile.in corosync-2.3.3/pkgconfig/Makefile.in --- corosync-2.3.0/pkgconfig/Makefile.in 2013-01-18 08:53:34.000000000 +0000 +++ corosync-2.3.3/pkgconfig/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -182,8 +182,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/qdevices/Makefile.in corosync-2.3.3/qdevices/Makefile.in --- corosync-2.3.0/qdevices/Makefile.in 2013-01-18 08:53:35.000000000 +0000 +++ corosync-2.3.3/qdevices/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -220,8 +220,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/README.recovery corosync-2.3.3/README.recovery --- corosync-2.3.0/README.recovery 2012-11-07 12:55:15.000000000 +0000 +++ corosync-2.3.3/README.recovery 2014-01-13 13:46:11.000000000 +0000 @@ -1,7 +1,7 @@ SYNCHRONIZATION ALGORITHM: ------------------------- The synchronization algorithm is used for every service in corosync to -synchronize state of he system. +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 diff -Nru corosync-2.3.0/.tarball-version corosync-2.3.3/.tarball-version --- corosync-2.3.0/.tarball-version 2013-01-18 08:53:46.000000000 +0000 +++ corosync-2.3.3/.tarball-version 2014-01-14 15:15:26.000000000 +0000 @@ -1 +1 @@ -2.3.0 +2.3.3 diff -Nru corosync-2.3.0/test/Makefile.in corosync-2.3.3/test/Makefile.in --- corosync-2.3.0/test/Makefile.in 2013-01-18 08:53:35.000000000 +0000 +++ corosync-2.3.3/test/Makefile.in 2014-01-14 15:15:14.000000000 +0000 @@ -284,8 +284,11 @@ SONAME = @SONAME@ STRIP = @STRIP@ SYSTEMDDIR = @SYSTEMDDIR@ +UPSTARTDIR = @UPSTARTDIR@ +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@ diff -Nru corosync-2.3.0/test/testcpg.c corosync-2.3.3/test/testcpg.c --- corosync-2.3.0/test/testcpg.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/test/testcpg.c 2014-01-13 13:46:11.000000000 +0000 @@ -84,7 +84,7 @@ static char buffer[100]; if (show_ip) { struct in_addr saddr; -#if __BYTE_ORDER == __BIG_ENDIAN +#if __BYTE_ORDER == __LITTLE_ENDIAN saddr.s_addr = swab32(nodeid); #else saddr.s_addr = nodeid; @@ -334,6 +334,11 @@ } 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]); } diff -Nru corosync-2.3.0/test/testcpgzc.c corosync-2.3.3/test/testcpgzc.c --- corosync-2.3.0/test/testcpgzc.c 2012-11-07 12:55:15.000000000 +0000 +++ corosync-2.3.3/test/testcpgzc.c 2014-01-13 13:46:11.000000000 +0000 @@ -180,6 +180,11 @@ } 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; } diff -Nru corosync-2.3.0/test/testsam.c corosync-2.3.3/test/testsam.c --- corosync-2.3.0/test/testsam.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/test/testsam.c 2014-01-13 13:46:11.000000000 +0000 @@ -768,6 +768,7 @@ } if (strcmp(str, "testquorum") != 0) { printf ("Provider is not testquorum. Test skipped\n"); + free(str); return (1); } free(str); @@ -911,6 +912,7 @@ if (strcmp(str, "quit") != 0) { printf ("Recovery key \"%s\" is not \"quit\".\n", key_name); + free(str); return (2); } free(str); @@ -924,6 +926,7 @@ if (strcmp(str, "stopped") != 0) { printf ("State key is not \"stopped\".\n"); + free(str); return (2); } free(str); @@ -943,6 +946,7 @@ if (strcmp(str, "running") != 0) { printf ("State key is not \"running\".\n"); + free(str); return (2); } free(str); @@ -962,6 +966,7 @@ if (strcmp(str, "stopped") != 0) { printf ("State key is not \"stopped\".\n"); + free(str); return (2); } free(str); @@ -977,6 +982,7 @@ if (strcmp(str, "stopped") != 0) { printf ("State key is not \"stopped\".\n"); + free(str); return (2); } free(str); @@ -996,6 +1002,7 @@ if (strcmp(str, "running") != 0) { printf ("State key is not \"running\".\n"); + free(str); return (2); } free(str); @@ -1055,6 +1062,7 @@ if (strcmp(str, "stopped") != 0) { printf ("State key is not \"stopped\".\n"); + free(str); return (2); } free(str); @@ -1080,8 +1088,10 @@ if (strcmp(str, "failed") != 0) { printf ("State key is not \"failed\".\n"); + free(str); return (2); } + free(str); return (0); } @@ -1133,6 +1143,7 @@ if (strcmp(str, "restart") != 0) { printf ("Recovery key \"%s\" is not \"restart\".\n", str); + free(str); return (2); } free(str); @@ -1146,6 +1157,7 @@ if (strcmp(str, "stopped") != 0) { printf ("State key is not \"stopped\".\n"); + free(str); return (2); } free(str); @@ -1165,6 +1177,7 @@ if (strcmp(str, "running") != 0) { printf ("State key is not \"running\".\n"); + free(str); return (2); } free(str); @@ -1210,6 +1223,7 @@ if (strcmp(str, "failed") != 0) { printf ("State key is not \"failed\".\n"); + free(str); return (2); } free(str); diff -Nru corosync-2.3.0/test/testvotequorum2.c corosync-2.3.3/test/testvotequorum2.c --- corosync-2.3.0/test/testvotequorum2.c 2013-01-18 08:52:13.000000000 +0000 +++ corosync-2.3.3/test/testvotequorum2.c 2014-01-14 15:07:56.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Red Hat, Inc. + * Copyright (c) 2009-2014 Red Hat, Inc. * * All rights reserved. * @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -44,86 +45,132 @@ static votequorum_handle_t handle; -static void print_info(int ok_to_fail) +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) + 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\n"); + printf("alive "); } if (info.flags & VOTEQUORUM_INFO_QDEVICE_CAST_VOTE) { - printf("cast vote\n"); + printf("cast-vote "); } if (info.flags & VOTEQUORUM_INFO_QDEVICE_MASTER_WINS) { - printf("master wins\n"); + printf("master-wins"); } - printf("\n"); + printf("\n\n"); } + return 0; +} + +static void usage(const char *command) +{ + printf("%s [-p ] [-t