diff --git a/GNUmakefile b/GNUmakefile index 0df84732cd..1f17bca056 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,354 +1,357 @@ # # Copyright 2008-2019 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # default: $(shell test ! -e configure && echo init) $(shell test -e configure && echo core) -include Makefile PACKAGE ?= pacemaker # Force 'make dist' to be consistent with 'make export' distdir = $(PACKAGE)-$(TAG) TARFILE = $(PACKAGE)-$(SHORTTAG).tar.gz DIST_ARCHIVES = $(TARFILE) RPM_ROOT = $(shell pwd) RPM_OPTS = --define "_sourcedir $(RPM_ROOT)" \ --define "_specdir $(RPM_ROOT)" \ --define "_srcrpmdir $(RPM_ROOT)" \ MOCK_OPTIONS ?= --resultdir=$(RPM_ROOT)/mock --no-cleanup-after # Default to building Fedora-compliant spec files # SLES: /etc/SuSE-release # openSUSE: /etc/SuSE-release # RHEL: /etc/redhat-release, /etc/system-release # Fedora: /etc/fedora-release, /etc/redhat-release, /etc/system-release # CentOS: /etc/centos-release, /etc/redhat-release, /etc/system-release F ?= $(shell test ! -e /etc/fedora-release && echo 0; test -e /etc/fedora-release && rpm --eval %{fedora}) ARCH ?= $(shell test -e /etc/fedora-release && rpm --eval %{_arch}) MOCK_CFG ?= $(shell test -e /etc/fedora-release && echo fedora-$(F)-$(ARCH)) DISTRO ?= $(shell test -e /etc/SuSE-release && echo suse; echo fedora) COMMIT ?= HEAD TAG ?= $(shell T=$$(git describe --all '$(COMMIT)' | sed -n 's|tags/\(.*\)|\1|p'); \ test -n "$${T}" && echo "$${T}" \ || git log --pretty=format:%H -n 1 '$(COMMIT)') lparen = ( rparen = ) SHORTTAG ?= $(shell case $(TAG) in Pacemaker-*$(rparen) echo '$(TAG)' | cut -c11-;; \ *$(rparen) git log --pretty=format:%h -n 1 '$(TAG)';; esac) SHORTTAG_ABBREV = $(shell printf %s '$(SHORTTAG)' | wc -c) WITH ?= --without doc #WITH ?= --without=doc --with=gcov LAST_RC ?= $(shell test -e /Volumes || git tag -l | grep Pacemaker | sort -Vr | grep rc | head -n 1) ifneq ($(origin VERSION), undefined) LAST_RELEASE ?= Pacemaker-$(VERSION) else LAST_RELEASE ?= $(shell git tag -l | grep Pacemaker | sort -Vr | grep -v rc | head -n 1) endif NEXT_RELEASE ?= $(shell echo $(LAST_RELEASE) | awk -F. '/[0-9]+\./{$$3+=1;OFS=".";print $$1,$$2,$$3}') BUILD_COUNTER ?= build.counter LAST_COUNT = $(shell test ! -e $(BUILD_COUNTER) && echo 0; test -e $(BUILD_COUNTER) && cat $(BUILD_COUNTER)) COUNT = $(shell expr 1 + $(LAST_COUNT)) SPECVERSION ?= $(COUNT) # rpmbuild wrapper that translates "--with[out] FEATURE" into RPM macros # # Unfortunately, at least recent versions of rpm do not support mentioned # switch. To work this around, we can emulate mechanism that rpm uses # internally: unfold the flags into respective macro definitions: # # --with[out] FOO -> --define "_with[out]_FOO --with[out]-FOO" # # $(1) ... WITH string (e.g., --with pre_release --without doc) # $(2) ... options following the initial "rpmbuild" in the command # $(3) ... final arguments determined with $2 (e.g., pacemaker.spec) # # Note that if $(3) is a specfile, extra case is taken so as to reflect # pcmkversion correctly (using in-place modification). # # Also note that both ways to specify long option with an argument # (i.e., what getopt and, importantly, rpm itself support) can be used: # # --with FOO # --with=FOO rpmbuild-with = \ WITH=$$(getopt -o "" -l with:,without: -- $(1)) || exit 1; \ CMD='rpmbuild $(2)'; PREREL=0; \ eval set -- "$${WITH}"; \ while true; do \ case "$$1" in \ --with) CMD="$${CMD} --define \"_with_$$2 --with-$$2\""; \ [ "$$2" != pre_release ] || PREREL=1; shift 2;; \ --without) CMD="$${CMD} --define \"_without_$$2 --without-$$2\""; \ [ "$$2" != pre_release ] || PREREL=0; shift 2;; \ --) shift ; break ;; \ *) echo "cannot parse WITH: $$1"; exit 1;; \ esac; \ done; \ case "$(3)" in \ *.spec) { [ $${PREREL} -eq 0 ] || [ $(LAST_RELEASE) = $(TAG) ]; } \ && sed -i "s/^\(%global pcmkversion \).*/\1$$(echo $(LAST_RELEASE) | sed -e s:Pacemaker-:: -e s:-.*::)/" $(3) \ || sed -i "s/^\(%global pcmkversion \).*/\1$$(echo $(NEXT_RELEASE) | sed -e s:Pacemaker-:: -e s:-.*::)/" $(3);; \ esac; \ CMD="$${CMD} $(3)"; \ eval "$${CMD}" init: ./autogen.sh export: rm -f $(PACKAGE)-dirty.tar.* $(PACKAGE)-tip.tar.* $(PACKAGE)-HEAD.tar.* if [ ! -f $(TARFILE) ]; then \ rm -f $(PACKAGE).tar.*; \ if [ $(TAG) = dirty ]; then \ git commit -m "DO-NOT-PUSH" -a; \ git archive --prefix=$(distdir)/ -o "$(TARFILE)" HEAD^{tree}; \ git reset --mixed HEAD^; \ else \ git archive --prefix=$(distdir)/ -o "$(TARFILE)" $(TAG)^{tree}; \ fi; \ echo `date`: Rebuilt $(TARFILE); \ else \ echo `date`: Using existing tarball: $(TARFILE); \ fi $(PACKAGE)-opensuse.spec: $(PACKAGE)-suse.spec cp $^ $@ @echo Rebuilt $@ $(PACKAGE)-suse.spec: $(PACKAGE).spec.in GNUmakefile rm -f $@ if [ x != x"`git ls-files -m | grep pacemaker.spec.in`" ]; then \ cp $(PACKAGE).spec.in $@; \ echo "Rebuilt $@ (local modifications)"; \ elif [ x = x"`git show $(TAG):pacemaker.spec.in 2>/dev/null`" ]; then \ cp $(PACKAGE).spec.in $@; \ echo "Rebuilt $@"; \ else \ git show $(TAG):$(PACKAGE).spec.in >> $@; \ echo "Rebuilt $@ from $(TAG)"; \ fi sed -i \ -e 's:%{_docdir}/%{name}:%{_docdir}/%{name}-%{version}:g' \ -e 's:%{name}-libs:lib%{name}3:g' \ -e 's: libtool-ltdl-devel\(%{?_isa}\)\?::g' \ -e 's:bzip2-devel:libbz2-devel:g' \ -e 's:docbook-style-xsl:docbook-xsl-stylesheets:g' \ -e 's: byacc::g' \ -e 's:gnutls-devel:libgnutls-devel:g' \ -e 's:corosynclib:libcorosync:g' \ -e 's:cluster-glue-libs:libglue:g' \ -e 's:shadow-utils:shadow:g' \ -e 's: publican::g' \ -e 's: 189: 90:g' \ -e 's:%{_libexecdir}/lcrso:%{_libdir}/lcrso:g' \ -e 's:procps-ng:procps:g' \ $@ @echo "Applied SUSE-specific modifications" # Works for all fedora based distros $(PACKAGE)-%.spec: $(PACKAGE).spec.in rm -f $@ if [ x != x"`git ls-files -m | grep pacemaker.spec.in`" ]; then \ cp $(PACKAGE).spec.in $(PACKAGE)-$*.spec; \ echo "Rebuilt $@ (local modifications)"; \ elif [ x = x"`git show $(TAG):pacemaker.spec.in 2>/dev/null`" ]; then \ cp $(PACKAGE).spec.in $(PACKAGE)-$*.spec; \ echo "Rebuilt $@"; \ else \ git show $(TAG):$(PACKAGE).spec.in >> $(PACKAGE)-$*.spec; \ echo "Rebuilt $@ from $(TAG)"; \ fi srpm-%: export $(PACKAGE)-%.spec rm -f *.src.rpm cp $(PACKAGE)-$*.spec $(PACKAGE).spec echo "* $(shell date +"%a %b %d %Y") Andrew Beekhof $(shell git describe --tags $(TAG) | sed -e s:Pacemaker-:: -e s:-.*::)-1" >> $(PACKAGE).spec echo " - See included ChangeLog file or https://raw.github.com/ClusterLabs/pacemaker/master/ChangeLog for full details" >> $(PACKAGE).spec if [ -e $(BUILD_COUNTER) ]; then \ echo $(COUNT) > $(BUILD_COUNTER); \ fi sed -e 's/global\ specversion\ .*/global\ specversion\ $(SPECVERSION)/' \ -e 's/global\ commit\ .*/global\ commit\ $(TAG)/' \ -e 's/global\ commit_abbrev\ .*/global\ commit_abbrev\ $(SHORTTAG_ABBREV)/' \ -i $(PACKAGE).spec $(call rpmbuild-with,$(WITH),-bs --define "dist .$*" $(RPM_OPTS),$(PACKAGE).spec) chroot: mock-$(MOCK_CFG) mock-install-$(MOCK_CFG) mock-sh-$(MOCK_CFG) echo "Done" mock-next: make F=$(shell expr 1 + $(F)) mock mock-rawhide: make F=rawhide mock mock-install-%: echo "Installing packages" mock --root=$* $(MOCK_OPTIONS) --install $(RPM_ROOT)/mock/*.rpm vi sudo valgrind lcov gdb fence-agents psmisc mock-install: mock-install-$(MOCK_CFG) echo "Done" mock-sh: mock-sh-$(MOCK_CFG) echo "Done" mock-sh-%: echo "Connecting" mock --root=$* $(MOCK_OPTIONS) --shell echo "Done" # eg. make WITH="--with pre_release" rpm mock-%: make srpm-$(firstword $(shell echo $(@:mock-%=%) | tr '-' ' ')) -rm -rf $(RPM_ROOT)/mock @echo "mock --root=$* --rebuild $(WITH) $(MOCK_OPTIONS) $(RPM_ROOT)/*.src.rpm" mock --root=$* --no-cleanup-after --rebuild $(WITH) $(MOCK_OPTIONS) $(RPM_ROOT)/*.src.rpm srpm: srpm-$(DISTRO) echo "Done" mock: mock-$(MOCK_CFG) echo "Done" rpm-dep: $(PACKAGE)-$(DISTRO).spec if [ x != x`which yum-builddep 2>/dev/null` ]; then \ echo "Installing with yum-builddep"; \ sudo yum-builddep $(PACKAGE)-$(DISTRO).spec; \ elif [ x != x`which yum 2>/dev/null` ]; then \ echo -e "Installing: $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' ')\n\n"; \ sudo yum install $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' '); \ elif [ x != x`which zypper` ]; then \ echo -e "Installing: $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' ')\n\n"; \ sudo zypper install $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' ');\ else \ echo "I don't know how to install $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' ')";\ fi rpm: srpm @echo To create custom builds, edit the flags and options in $(PACKAGE).spec first $(call rpmbuild-with,$(WITH),$(RPM_OPTS),--rebuild $(RPM_ROOT)/*.src.rpm) release: make TAG=$(LAST_RELEASE) rpm rc: make TAG=$(LAST_RC) rpm dirty: make TAG=dirty mock COVERITY_DIR = $(shell pwd)/coverity-$(TAG) COVFILE = $(PACKAGE)-coverity-$(TAG).tgz COVHOST ?= scan5.coverity.com COVPASS ?= password # Static analysis via coverity coverity-common: test -e configure || ./autogen.sh test -e Makefile || ./configure make core-clean rm -rf $(COVERITY_DIR) cov-build --dir $(COVERITY_DIR) make core coverity: coverity-common tar czf $(COVFILE) --transform=s@.*$(TAG)@cov-int@ $(COVERITY_DIR) @echo "Uploading to public Coverity instance..." curl --form file=@$(COVFILE) --form project=$(PACKAGE) --form password=$(COVPASS) --form email=andrew@beekhof.net http://$(COVHOST)/cgi-bin/upload.py rm -rf $(COVFILE) $(COVERITY_DIR) make core-clean coverity-corp: coverity-common test -e configure || ./autogen.sh test -e Makefile || ./configure make core-clean rm -rf $(COVERITY_DIR) cov-build --dir $(COVERITY_DIR) make core @echo "Waiting for a corporate Coverity license..." cov-analyze --dir $(COVERITY_DIR) --wait-for-license cov-format-errors --dir $(COVERITY_DIR) --emacs-style > $(TAG).coverity cov-format-errors --dir $(COVERITY_DIR) # rsync $(RSYNC_OPTS) "$(COVERITY_DIR)/c/output/errors/" "$(RSYNC_DEST)/$(PACKAGE)/coverity/$(TAG)/" make core-clean # cov-commit-defects --host $(COVHOST) --dir $(COVERITY_DIR) --stream $(PACKAGE) --user auto --password $(COVPASS) # rm -rf $(COVERITY_DIR) summary: @printf "\n* `date +"%a %b %d %Y"` `git config user.name` <`git config user.email`> $(NEXT_RELEASE)-1" @printf "\n- Changesets: `git log --pretty=oneline $(LAST_RELEASE)..HEAD | wc -l`" @printf "\n- Diff: " @git diff $(LAST_RELEASE)..HEAD --shortstat include lib daemons tools xml rc-changes: @make NEXT_RELEASE=$(shell echo $(LAST_RC) | sed s:-rc.*::) LAST_RELEASE=$(LAST_RC) changes changes: summary @printf "\n- Features added since $(LAST_RELEASE)\n" @git log --pretty=format:' +%s' --abbrev-commit $(LAST_RELEASE)..HEAD | grep -e Feature: | sed -e 's@Feature:@@' | sort -uf @printf "\n- Changes since $(LAST_RELEASE)\n" @git log --pretty=format:' +%s' --no-merges --abbrev-commit $(LAST_RELEASE)..HEAD \ | grep -e High: -e Fix: -e Bug | sed \ -e 's@\(Fix\|High\|Bug\):@@' \ -e 's@\(cib\|pacemaker-based\|based\):@CIB:@' \ -e 's@\(crmd\|pacemaker-controld\|controld\):@controller:@' \ -e 's@\(lrmd\|pacemaker-execd\|execd\):@executor:@' \ -e 's@\(Fencing\|stonithd\|stonith\|pacemaker-fenced\|fenced\):@fencing:@' \ -e 's@\(PE\|pengine\|pacemaker-schedulerd\|schedulerd\):@scheduler:@' \ | sort -uf +authors: + git log $(LAST_RELEASE)..$(COMMIT) --format='%an' | sort -u + changelog: @make changes > ChangeLog @printf "\n">> ChangeLog git show $(LAST_RELEASE):ChangeLog >> ChangeLog DO_NOT_INDENT = lib/gnu daemons/controld/controld_fsa.h indent: find . -name "*.[ch]" -exec ./p-indent \{\} \; git co HEAD $(DO_NOT_INDENT) rel-tags: tags find . -name TAGS -exec sed -i 's:\(.*\)/\(.*\)/TAGS:\2/TAGS:g' \{\} \; CLANG_analyzer = $(shell which scan-build) CLANG_checkers = # Use CPPCHECK_ARGS to pass extra cppcheck options, e.g.: # --enable={warning,style,performance,portability,information,all} # --inconclusive --std=posix CPPCHECK_ARGS ?= cppcheck: cppcheck $(CPPCHECK_ARGS) -I include --max-configs=25 -q replace lib daemons tools clang: test -e $(CLANG_analyzer) scan-build $(CLANG_checkers:%=-enable-checker %) make clean all # V3 = scandir unsetenv alphasort xalloc # V2 = setenv strerror strchrnul strndup # https://www.gnu.org/software/gnulib/manual/html_node/Initial-import.html#Initial-import # previously, this was crypto/md5, but got spoiled with streams/kernel crypto GNU_MODS = crypto/md5-buffer # stdint appears to be surrogate only for C99-lacking environments GNU_MODS_AVOID = stdint # only for plain crypto/md5: we make do without kernel-assisted crypto # GNU_MODS_AVOID += crypto/af_alg gnulib-update: -test -e maint/gnulib \ || git clone https://git.savannah.gnu.org/git/gnulib.git maint/gnulib cd maint/gnulib && git pull maint/gnulib/gnulib-tool \ --source-base=lib/gnu --lgpl=2 --no-vc-files --no-conditional-dependencies \ $(GNU_MODS_AVOID:%=--avoid %) --import $(GNU_MODS) diff --git a/cts/Makefile.am b/cts/Makefile.am index d6292c5c31..800bfef3ae 100644 --- a/cts/Makefile.am +++ b/cts/Makefile.am @@ -1,89 +1,91 @@ # # Copyright 2001-2019 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = $(cts_SCRIPTS) $(cts_DATA) halibdir = $(CRM_DAEMON_DIR) halib_SCRIPTS = cts-log-watcher cts-support # # Test commands and globally applicable test files should be in $(testdir), # and command-specific test data should be in a command-specific subdirectory. # testdir = $(datadir)/$(PACKAGE)/tests test_SCRIPTS = cts-coverage cts-regression cts-cli cts-exec cts-scheduler \ cts-fencing test_DATA = README.md valgrind-pcmk.suppressions ctslibdir = $(pythondir)/cts ctslib_PYTHON = __init__.py \ CTSvars.py \ CM_common.py \ CM_corosync.py \ CTS.py \ CTSaudits.py \ CTStests.py \ CTSscenarios.py \ CIB.py \ cib_xml.py \ environment.py \ logging.py \ patterns.py \ remote.py \ watcher.py ctsdir = $(testdir)/cts cts_DATA = pacemaker-cts-dummyd@.service if BUILD_UPSTART cts_DATA += pacemaker-cts-dummyd.conf endif cts_SCRIPTS = cts \ CTSlab.py \ lxc_autogen.sh \ LSBDummy \ fence_dummy \ pacemaker-cts-dummyd clidir = $(testdir)/cli cli_DATA = cli/regression.dates.exp cli/regression.tools.exp \ cli/regression.acls.exp cli/regression.validity.exp \ cli/regression.upgrade.exp cli/regression.rules.exp PE_TESTS = $(wildcard scheduler/*.scores) pedir = $(testdir)/scheduler pe_DATA = $(PE_TESTS) \ $(PE_TESTS:%.scores=%.xml) \ $(PE_TESTS:%.scores=%.exp) \ $(PE_TESTS:%.scores=%.dot) \ $(PE_TESTS:%.scores=%.summary) \ $(wildcard scheduler/*.stderr) # For "make check", run a single scheduler test TESTS = scheduler/bug-rh-1097457.xml TEST_EXTENSIONS = .xml XML_LOG_COMPILER = ./cts-scheduler AM_XML_LOG_FLAGS = -V --run scheduler-list: - echo $(shell ls -1 scheduler/*.xml) + @for T in "$(srcdir)"/scheduler/*.xml; do \ + echo $$(basename $$T .xml); \ + done clean-local: rm -f scheduler/*.pe.* SUBDIRS = benchmark cts-support-install: cts-support ./cts-support install cts-support-uninstall: cts-support ./cts-support uninstall diff --git a/doc/cib-example-1.xml b/doc/cib-example-1.xml deleted file mode 100644 index f53c0f932f..0000000000 --- a/doc/cib-example-1.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/stonith-ng.conf.example b/doc/stonith-ng.conf.example deleted file mode 100644 index 4ec56efe01..0000000000 --- a/doc/stonith-ng.conf.example +++ /dev/null @@ -1,75 +0,0 @@ -# Using Standalone Configuration -# -# The standalone configuration can only be applied to the -# pacemaker-fenced process while in standalone mode. This is achieved -# by using the --stand-alone option when launching pacemaker-fenced. -# When in standalone mode, pacemaker-fenced will look for a config -# file named stonith-ng.conf in the /etc/pacemaker directory. -# If the config file is present, it will be applied on startup. -# -# Below are examples of how to configure pacemaker-fenced in standalone -# mode using this configuration file. -# - -# Example 1: Standalone fence_ipmilan configuration -# for 2 hosts - -device stonith-1 fence_ipmilan auth=md5 lanplus=true method=onoff \ - power_wait=5 ipaddr=v02-a-control login=abc passwd=def - -# Since there are no ports in fence_ipmilan, just give it -# the host(s) that is controlled by stonith-1. fence_ipmilan -# happens to only be able to control 1 host at a time. -ports stonith-1 v02-a - -# There is no host checker for ipmilan and there is no host -# or port argument really, tell pacemaker-fenced this. -options stonith-1 host_argument=none - - -# -# Example 2: fence_apc controlling 4 hosts, 1 port each -# -# Port assignment implies connection to device -# -device stonith-2 fence_apc ipaddr=north-apc login=apc passwd=apc -ports stonith-2 north-01=2 north-02=3 north-03=4 north-04=5 - - -# -# Example 3: fence_wti controlling 2 hosts, 2 ports each -# -device stonith-3 fence_wti ipaddr=10.1.1.2 login=admin passwd=admin -ports stonith-3 v02-a="1,5" v02-b="2,6" - - -# -# Example 4: fence_xvm with special option -# -device stonith-4 fence_xvm - -# Non-fencing agent option to give pacemaker-fenced hints -options stonith-4 pcmk_arg_map="domain:uname" - - -# -# Example 5: external/ssh -# -device stonith-5 "external/ssh" livedangerously=yes -ports stonith-5 v02-a v02-b - - -# -# Example 6: Fence_scsi -# -# fence_scsi has no ports and no host list, so all we do is -# tell stonith what hosts it controls -# -device stonith-6 fence_scsi -ports stonith-6 v02-a v02-b - -# Try to fence v02-a using stonith-6 and stonith-3. If either -# fails, move on to stonith-5. -priority v02-a 1 stonith-6 stonith-3 -priority v02-a 2 stonith-5 - diff --git a/include/crm/cluster/election.h b/include/crm/cluster/election.h index 1dcc66c2f8..3eb90825f2 100644 --- a/include/crm/cluster/election.h +++ b/include/crm/cluster/election.h @@ -1,87 +1,85 @@ /* * Copyright 2009-2019 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef CRM_COMMON_ELECTION__H # define CRM_COMMON_ELECTION__H #ifdef __cplusplus extern "C" { #endif /** * \file * \brief Functions for conducting elections * * An election is useful for a daemon that runs on all nodes but needs any one * instance to perform a special role. * * Elections are closely tied to the cluster peer cache. Peers in the cache that * are active members are eligible to vote. Elections are named for logging * purposes, but only one election may exist at any time, so typically an * election would be created at daemon start-up and freed at shutdown. * * Pacemaker's election procedure has been heavily adapted from the * Invitation Algorithm variant of the Garcia-Molina Bully Algorithm: * * https://en.wikipedia.org/wiki/Bully_algorithm * * Elections are conducted via cluster messages. There are two types of * messages: a "vote" is a declaration of the voting node's candidacy, and is * always broadcast; a "no-vote" is a concession by the responding node, and is * always a reply to the preferred node's vote. (These correspond to "invite" * and "accept" in the traditional algorithm.) * * A vote together with any no-vote replies to it is considered an election * round. Rounds are numbered with a simple counter unique to each node * (this would be the group number in the traditional algorithm). Concurrent * election rounds are possible. * * An election round is started when any node broadcasts a vote. When a node * receives another node's vote, it compares itself against the sending node * according to certain metrics, and either starts a new round (if it prefers * itself) or replies to the other node with a no-vote (if it prefers that * node). * * If a node receives no-votes from all other active nodes, it declares itself * the winner. The library API does not notify other nodes of this; callers * must implement that if desired. - * - * \ingroup core */ typedef struct election_s election_t; /*! Possible election states */ enum election_result { election_start = 0, /*! new election needed */ election_in_progress, /*! election started but not all peers have voted */ election_lost, /*! local node lost most recent election */ election_won, /*! local node won most recent election */ election_error, /*! election message or election object invalid */ }; void election_fini(election_t *e); void election_reset(election_t *e); election_t *election_init(const char *name, const char *uname, guint period_ms, GSourceFunc cb); void election_timeout_set_period(election_t *e, guint period_ms); void election_timeout_stop(election_t *e); void election_vote(election_t *e); bool election_check(election_t *e); void election_remove(election_t *e, const char *uname); enum election_result election_state(election_t *e); enum election_result election_count_vote(election_t *e, xmlNode *vote, bool can_win); void election_clear_dampening(election_t *e); #ifdef __cplusplus } #endif #endif diff --git a/xml/Makefile.am b/xml/Makefile.am index ffa6a3f610..4ae2d67af4 100644 --- a/xml/Makefile.am +++ b/xml/Makefile.am @@ -1,221 +1,217 @@ # # Copyright 2004-2019 the Pacemaker project contributors # # The version control history for this file may have further details. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in APIdir = $(CRM_SCHEMA_DIRECTORY)/api RNGdir = $(CRM_SCHEMA_DIRECTORY) xsltdir = $(RNGdir) dist_xslt_DATA = $(top_srcdir)/xml/upgrade-1.3.xsl \ $(top_srcdir)/xml/upgrade-2.10.xsl \ $(top_srcdir)/xml/upgrade-*enter.xsl \ $(top_srcdir)/xml/upgrade-*leave.xsl noinst_DATA = context-of.xsl # See Readme.md for details on updating schema files # Sorted list of available numeric RNG versions, # extracted from filenames like NAME-MAJOR[.MINOR][.MINOR-MINOR].rng numeric_versions = $(shell ls -1 $(1) \ | sed -n -e 's/^.*-\([0-9][0-9.]*\).rng$$/\1/p' \ | sort -u -t. -k 1,1n -k 2,2n -k 3,3n) version_pairs = $(join \ $(1),$(addprefix \ -,$(wordlist \ 2,$(words $(1)),$(1) \ ) next \ ) \ ) version_pairs_last = $(wordlist \ $(words \ $(wordlist \ 2,$(1),$(2) \ ) \ ),$(1),$(2) \ ) API_numeric_versions = $(call numeric_versions,${API_files}) RNG_numeric_versions = $(call numeric_versions,${RNG_files}) # The highest numeric version API_max ?= $(lastword $(API_numeric_versions)) RNG_max ?= $(lastword $(RNG_numeric_versions)) # A sorted list of all API and RNG versions (numeric and "next") API_versions = next $(API_numeric_versions) API_request_base = command-output stonith_admin version API_base = $(API_request_base) item status API_files = $(foreach base,$(API_base),$(wildcard api/$(base)*.rng)) RNG_versions = next $(RNG_numeric_versions) RNG_version_pairs = $(call version_pairs,${RNG_numeric_versions}) RNG_version_pairs_cnt = $(words ${RNG_version_pairs}) RNG_version_pairs_last = $(call version_pairs_last,${RNG_version_pairs_cnt},${RNG_version_pairs}) API_generated = api/api-result.rng $(foreach base,$(API_versions),api/api-result-$(base).rng) RNG_generated = pacemaker.rng $(foreach base,$(RNG_versions),pacemaker-$(base).rng) versions.rng RNG_cfg_base = options nodes resources constraints fencing acls tags alerts RNG_base = cib $(RNG_cfg_base) status score rule nvset RNG_files = $(foreach base,$(RNG_base),$(wildcard $(base).rng $(base)-*.rng)) # List of non-Pacemaker RNGs RNG_extra = crm_mon.rng dist_API_DATA = $(API_files) dist_RNG_DATA = $(RNG_files) $(RNG_extra) nodist_API_DATA = $(API_generated) nodist_RNG_DATA = $(RNG_generated) EXTRA_DIST = best-match.sh versions: echo "Max: $(RNG_max)" echo "Available: $(RNG_versions)" api-versions: echo "Max: $(API_max)" echo "Available: $(API_versions)" versions.rng: Makefile.am echo " RNG $@" echo '' > $@ echo '' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' none' >> $@ echo ' pacemaker-0.6' >> $@ echo ' transitional-0.6' >> $@ echo ' pacemaker-0.7' >> $@ echo ' pacemaker-1.1' >> $@ for rng in $(RNG_versions); do echo " pacemaker-$$rng" >> $@; done echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo '' >> $@ api/api-result.rng: api/api-result-$(API_max).rng echo " RNG $@" cp $(top_builddir)/xml/$< $@ pacemaker.rng: pacemaker-$(RNG_max).rng echo " RNG $@" cp $(top_builddir)/xml/$< $@ api/api-result-%.rng: $(API_files) Makefile.am echo " RNG $@" echo '' > $@ echo '' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ for rng in $(API_request_base); do $(top_srcdir)/xml/best-match.sh api/$$rng $(*) $(@) " " || :; done echo ' ' >> $@ echo ' ' >> $@ $(top_srcdir)/xml/best-match.sh api/status $(*) $(@) " " || : echo ' ' >> $@ echo ' ' >> $@ echo '' >> $@ pacemaker-%.rng: $(RNG_files) best-match.sh Makefile.am echo " RNG $@" echo '' > $@ echo '' >> $@ echo ' ' >> $@ echo ' ' >> $@ $(top_srcdir)/xml/best-match.sh cib $(*) $(@) " " echo ' ' >> $@ echo ' ' >> $@ for rng in $(RNG_cfg_base); do $(top_srcdir)/xml/best-match.sh $$rng $(*) $(@) " " || :; done echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ $(top_srcdir)/xml/best-match.sh status $(*) $(@) " " echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo ' ' >> $@ echo '' >> $@ # diff fails with ec=2 if no predecessor is found; # this uses '=' GNU extension to sed, if that's not available, # one can use: hline=`echo "$${p}" | grep -Fn "$${hunk}" | cut -d: -f1`; # XXX: use line information from hunk to avoid "not detected" for ambiguity version_diff = \ @for p in $(1); do \ set `echo "$${p}" | tr '-' ' '`; \ echo "\#\#\# *-$$2.rng vs. predecessor"; \ for v in *-$$2.rng; do \ echo "\#\#\#\# $${v} vs. predecessor"; b=`echo "$${v}" | cut -d- -f1`; \ old=`./best-match.sh $${b} $$1`; \ p=`diff -u "$${old}" "$${v}" 2>/dev/null`; \ case $$? in \ 1) echo "$${p}" | sed -n -e '/^@@ /!d;=;p' \ -e ':l;n;/^\([- ]\|+.*<[^ />]\+\([^/>]\+="ID\|>$$\)\)/bl;s/^[+ ]\(.*\)/\1/p' \ | while read hline; do \ read h && read i || break; \ iline=`grep -Fn "$${i}" "$${v}" | cut -d: -f1`; \ ctxt="(not detected)"; \ if test `echo "$${iline}" | wc -l` -eq 1; then \ ctxt=`{ sed -n -e "1,$$(($${iline}-1))p" "$${v}"; \ echo "$${i}"; \ sed -n -e "$$(($${iline}+1)),$$ p" "$${v}"; \ } | $(XSLTPROC) --param skip 1 context-of.xsl -`; \ fi; \ echo "$${p}" | sed -n -e "$$(($${hline}-2)),$${hline}!d" \ -e '/^\(+++\|---\)/p'; \ echo "$${h} context: $${ctxt}"; \ echo "$${p}" | sed -n -e "1,$${hline}d" \ -e '/^\(---\|@@ \)/be;p;d;:e;n;be'; \ done; \ ;; \ 2) echo "\#\#\#\#\# $${v} has no predecessor";; \ esac; \ done; \ done diff: best-match.sh @echo "# Comparing changes in + since $(RNG_max)" $(call version_diff,${RNG_version_pairs_last}) fulldiff: best-match.sh @echo "# Comparing all changes across all the subsequent increments" $(call version_diff,${RNG_version_pairs}) -sync: - git rm -f $(wildcard *-next.rng) - make pacemaker-next.rng - CLEANFILES = $(API_generated) $(RNG_generated)