diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 687ec92b7..3b4034d3c 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1,168 +1,169 @@ # # doc: Linux-HA resource agents # # Copyright (C) 2009 Florian Haas # # 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 EXTRA_DIST = $(doc_DATA) $(REFENTRY_STYLESHEET) \ mkappendix.sh ralist.sh CLEANFILES = $(man_MANS) $(xmlfiles) metadata-*.xml STYLESHEET_PREFIX ?= http://docbook.sourceforge.net/release/xsl/current MANPAGES_STYLESHEET ?= $(STYLESHEET_PREFIX)/manpages/docbook.xsl HTML_STYLESHEET ?= $(STYLESHEET_PREFIX)/xhtml/docbook.xsl FO_STYLESHEET ?= $(STYLESHEET_PREFIX)/fo/docbook.xsl REFENTRY_STYLESHEET ?= ra2refentry.xsl XSLTPROC_OPTIONS ?= --xinclude XSLTPROC_MANPAGES_OPTIONS ?= $(XSLTPROC_OPTIONS) XSLTPROC_HTML_OPTIONS ?= $(XSLTPROC_OPTIONS) XSLTPROC_FO_OPTIONS ?= $(XSLTPROC_OPTIONS) radir = $(top_srcdir)/heartbeat # OCF_ROOT=. is necessary due to a sanity check in ocf-shellfuncs # (which tests whether $OCF_ROOT points to a directory metadata-%.xml: $(radir)/% OCF_ROOT=. OCF_FUNCTIONS_DIR=$(radir) $< meta-data > $@ metadata-IPv6addr.xml: ../../heartbeat/IPv6addr OCF_ROOT=. OCF_FUNCTIONS_DIR=$(radir) $< meta-data > $@ # Please note: we can't name the man pages # ocf:heartbeat:. Believe me, I've tried. It looks like it # works, but then it doesn't. While make can deal correctly with # colons in target names (when properly escaped), it royally messes up # when it is deals with _dependencies_ that contain colons. See Bug # 12126 on savannah.gnu.org. But, maybe it gets fixed soon, it was # first reported in 1995 and added to Savannah in in 2005... if BUILD_DOC man_MANS = ocf_heartbeat_AoEtarget.7 \ ocf_heartbeat_AudibleAlarm.7 \ ocf_heartbeat_ClusterMon.7 \ ocf_heartbeat_CTDB.7 \ ocf_heartbeat_Delay.7 \ ocf_heartbeat_Dummy.7 \ ocf_heartbeat_EvmsSCC.7 \ ocf_heartbeat_Evmsd.7 \ ocf_heartbeat_Filesystem.7 \ ocf_heartbeat_ICP.7 \ ocf_heartbeat_IPaddr.7 \ ocf_heartbeat_IPaddr2.7 \ ocf_heartbeat_IPsrcaddr.7 \ ocf_heartbeat_LVM.7 \ ocf_heartbeat_LinuxSCSI.7 \ ocf_heartbeat_MailTo.7 \ ocf_heartbeat_ManageRAID.7 \ ocf_heartbeat_ManageVE.7 \ ocf_heartbeat_Pure-FTPd.7 \ ocf_heartbeat_Raid1.7 \ ocf_heartbeat_Route.7 \ ocf_heartbeat_SAPDatabase.7 \ ocf_heartbeat_SAPInstance.7 \ ocf_heartbeat_SendArp.7 \ ocf_heartbeat_ServeRAID.7 \ ocf_heartbeat_SphinxSearchDaemon.7 \ ocf_heartbeat_Squid.7 \ ocf_heartbeat_Stateful.7 \ ocf_heartbeat_SysInfo.7 \ ocf_heartbeat_VIPArip.7 \ ocf_heartbeat_VirtualDomain.7 \ ocf_heartbeat_WAS.7 \ ocf_heartbeat_WAS6.7 \ ocf_heartbeat_WinPopup.7 \ ocf_heartbeat_Xen.7 \ ocf_heartbeat_Xinetd.7 \ ocf_heartbeat_anything.7 \ ocf_heartbeat_apache.7 \ ocf_heartbeat_asterisk.7 \ ocf_heartbeat_clvm.7 \ ocf_heartbeat_conntrackd.7 \ ocf_heartbeat_db2.7 \ ocf_heartbeat_dhcpd.7 \ ocf_heartbeat_eDir88.7 \ ocf_heartbeat_ethmonitor.7 \ ocf_heartbeat_exportfs.7 \ ocf_heartbeat_fio.7 \ + ocf_heartbeat_galera.7 \ ocf_heartbeat_iSCSILogicalUnit.7 \ ocf_heartbeat_iSCSITarget.7 \ ocf_heartbeat_iface-bridge.7 \ ocf_heartbeat_iface-vlan.7 \ ocf_heartbeat_ids.7 \ ocf_heartbeat_iscsi.7 \ ocf_heartbeat_jboss.7 \ ocf_heartbeat_kamailio.7 \ ocf_heartbeat_lxc.7 \ ocf_heartbeat_mysql.7 \ ocf_heartbeat_mysql-proxy.7 \ ocf_heartbeat_named.7 \ ocf_heartbeat_nfsnotify.7 \ ocf_heartbeat_nfsserver.7 \ ocf_heartbeat_nginx.7 \ ocf_heartbeat_oracle.7 \ ocf_heartbeat_oralsnr.7 \ ocf_heartbeat_pgsql.7 \ ocf_heartbeat_pingd.7 \ ocf_heartbeat_portblock.7 \ ocf_heartbeat_postfix.7 \ ocf_heartbeat_pound.7 \ ocf_heartbeat_proftpd.7 \ ocf_heartbeat_rsyncd.7 \ ocf_heartbeat_rsyslog.7 \ ocf_heartbeat_scsi2reservation.7 \ ocf_heartbeat_sfex.7 \ ocf_heartbeat_slapd.7 \ ocf_heartbeat_symlink.7 \ ocf_heartbeat_syslog-ng.7 \ ocf_heartbeat_tomcat.7 \ ocf_heartbeat_varnish.7 \ ocf_heartbeat_vmware.7 \ ocf_heartbeat_zabbixserver.7 if USE_IPV6ADDR_AGENT man_MANS += ocf_heartbeat_IPv6addr.7 endif xmlfiles = $(man_MANS:.7=.xml) %.1 %.5 %.7 %.8: %.xml $(XSLTPROC) \ $(XSLTPROC_MANPAGES_OPTIONS) \ $(MANPAGES_STYLESHEET) $< ocf_heartbeat_%.xml: metadata-%.xml $(srcdir)/$(REFENTRY_STYLESHEET) $(XSLTPROC) --novalid \ --stringparam package $(PACKAGE_NAME) \ --stringparam version $(VERSION) \ --output $@ \ $(srcdir)/$(REFENTRY_STYLESHEET) $< ocf_resource_agents.xml: $(xmlfiles) mkappendix.sh ./mkappendix.sh $(xmlfiles) > $@ %.html: %.xml $(XSLTPROC) \ $(XSLTPROC_HTML_OPTIONS) \ --output $@ \ $(HTML_STYLESHEET) $< xml: ocf_resource_agents.xml endif diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am index ea47666e4..49208a915 100644 --- a/heartbeat/Makefile.am +++ b/heartbeat/Makefile.am @@ -1,152 +1,153 @@ # Makefile.am for OCF RAs # # Author: Sun Jing Dong # Copyright (C) 2004 IBM # # 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 EXTRA_DIST = $(ocf_SCRIPTS) $(ocfcommon_DATA) \ $(common_DATA) $(hb_DATA) $(dtd_DATA) \ README AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/linux-ha halibdir = $(libexecdir)/heartbeat ocfdir = $(OCF_RA_DIR_PREFIX)/heartbeat dtddir = $(datadir)/$(PACKAGE_NAME) dtd_DATA = ra-api-1.dtd if USE_IPV6ADDR_AGENT ocf_PROGRAMS = IPv6addr else ocf_PROGRAMS = endif if IPV6ADDR_COMPATIBLE halib_PROGRAMS = send_ua else halib_PROGRAMS = endif IPv6addr_SOURCES = IPv6addr.c IPv6addr_utils.c send_ua_SOURCES = send_ua.c IPv6addr_utils.c IPv6addr_LDADD = -lplumb $(LIBNETLIBS) send_ua_LDADD = $(LIBNETLIBS) ocf_SCRIPTS = ClusterMon \ CTDB \ Dummy \ IPaddr \ IPaddr2 \ anything \ AoEtarget \ apache \ asterisk \ nginx \ AudibleAlarm \ clvm \ conntrackd \ db2 \ dhcpd \ Delay \ dnsupdate \ eDir88 \ EvmsSCC \ Evmsd \ ethmonitor \ exportfs \ Filesystem \ fio \ + galera \ ids \ iscsi \ ICP \ IPsrcaddr \ iSCSITarget \ iSCSILogicalUnit \ iface-bridge \ iface-vlan \ jboss \ kamailio \ LinuxSCSI \ LVM \ lxc \ MailTo \ ManageRAID \ ManageVE \ mysql \ mysql-proxy \ named \ nfsnotify \ nfsserver \ oracle \ oralsnr \ pingd \ portblock \ postfix \ pound \ pgsql \ proftpd \ Pure-FTPd \ Raid1 \ Route \ rsyncd \ rsyslog \ SAPDatabase \ SAPInstance \ SendArp \ ServeRAID \ slapd \ SphinxSearchDaemon \ Squid \ Stateful \ SysInfo \ scsi2reservation \ sfex \ symlink \ syslog-ng \ tomcat \ VIPArip \ VirtualDomain \ varnish \ vmware \ WAS \ WAS6 \ WinPopup \ Xen \ Xinetd \ zabbixserver ocfcommondir = $(OCF_LIB_DIR_PREFIX)/heartbeat ocfcommon_DATA = ocf-shellfuncs \ ocf-binaries \ ocf-directories \ ocf-returncodes \ ocf-rarun \ apache-conf.sh \ http-mon.sh \ sapdb-nosha.sh \ sapdb.sh \ ora-common.sh \ mysql-common.sh \ findif.sh # Legacy locations hbdir = $(sysconfdir)/ha.d hb_DATA = shellfuncs diff --git a/heartbeat/galera b/heartbeat/galera new file mode 100755 index 000000000..933458586 --- /dev/null +++ b/heartbeat/galera @@ -0,0 +1,567 @@ +#!/bin/sh +# +# Copyright (c) 2014 David Vossel +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# + +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. ${OCF_FUNCTIONS_DIR}/mysql-common.sh + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource script for managing galara database. + +Manages a galara instance + + + + +Location of the MySQL server binary + +MySQL server binary + + + + + +Location of the MySQL client binary + +MySQL client binary + + + + + +Configuration file + +MySQL config + + + + + +Directory containing databases + +MySQL datadir + + + + + +User running MySQL daemon + +MySQL user + + + + + +Group running MySQL daemon (for logfile and directory permissions) + +MySQL group + + + + + +The logfile to be used for mysqld. + +MySQL log file + + + + + +The pidfile to be used for mysqld. + +MySQL pid file + + + + + +The socket to be used for mysqld. + +MySQL socket + + + + + +If the MySQL database does not exist, it will be created + +Create the database if it does not exist + + + + + +Additional parameters which are passed to the mysqld on startup. +(e.g. --skip-external-locking or --skip-grant-tables) + +Additional parameters to pass to mysqld + + + + + + +The galera cluster address. This takes the form of: +gcomm://node,node,node + +Only nodes present in this node list will be allowed to start a galera instance. +It is expected that the galera node names listed in this address match valid +pacemaker node names. + +Galera cluster address + + + + + + + + + + + + + + + + + + + +END +} + +get_option_variable() +{ + local key=$1 + + echo 'SHOW VARIABLES;' | $MYSQL -u root 2>/dev/null | grep "^${key}[[:space:]]" | awk '{print $2}' +} + +get_status_variable() +{ + local key=$1 + + echo 'show status;' | $MYSQL -u root 2>/dev/null | grep "^${key}[[:space:]]" | awk '{print $2}' +} + +set_bootstrap_node() +{ + local node=$1 + + ${HA_SBIN_DIR}/crm_attribute -N $node -l reboot --name "${INSTANCE_ATTR_NAME}-bootstrap" -v "true" +} + +clear_bootstrap_node() +{ + ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-bootstrap" -D +} + +is_bootstrap() +{ + ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-bootstrap" -Q 2>/dev/null + +} + +clear_last_commit() +{ + ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -D +} + +set_last_commit() +{ + ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -v $1 +} + +get_last_commit() +{ + local node=$1 + + if [ -z "$node" ]; then + ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -Q 2>/dev/null + else + ${HA_SBIN_DIR}/crm_attribute -N $node -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -Q 2>/dev/null + fi +} + +is_readonly() +{ + local res=$(get_option_variable "read_only") + + if ! ocf_is_true "$res"; then + return 1 + fi + + cluster_status=$(get_status_variable "wsrep_cluster_status") + if ! [ "$cluster_status" = "Disconnected" ]; then + return 1 + fi + + return 0 +} + +master_exists() +{ + # determine if a master instance is already up and is healthy + crm_mon --as-xml | grep "resource.*id=\"${OCF_RESOURCE_INSTANCE}\".*role=\"Master\".*active=\"true\".*orphaned=\"false\".*failed=\"false\"" > /dev/null 2>&1 + return $? +} + +clear_master_score() +{ + local node=$1 + if [ -z "$node" ]; then + $CRM_MASTER -D + else + $CRM_MASTER -D -N $node + fi +} + +set_master_score() +{ + local node=$1 + + if [ -z "$node" ]; then + $CRM_MASTER -v 100 + else + $CRM_MASTER -N $node -v 100 + fi +} + +promote_everyone() +{ + + for node in $(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' '); do + + set_master_score $node + done +} + +detect_first_master() +{ + local best_commit=0 + local best_node="$NODENAME" + local last_commit=0 + local missing_nodes=0 + + for node in $(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' '); do + last_commit=$(get_last_commit $node) + + if [ -z "$last_commit" ]; then + ocf_log info "Waiting on node <${node}> to report database status before Master instances can start." + missing_nodes=1 + continue + fi + + # this means -1, or that no commit has occured yet. + if [ "$last_commit" = "18446744073709551615" ]; then + last_commit="0" + fi + + if [ "$last_commit" -ge "$best_commit" ]; then + best_node=$node + best_commit=$last_commit + fi + + done + + if [ $missing_nodes -eq 1 ]; then + return + fi + + ocf_log info "Promoting $best_node to be our bootstrap node" + set_master_score $best_node + set_bootstrap_node $best_node +} + +# For galera, promote is really start +galera_promote() +{ + local rc + local extra_opts + local bootstrap + + master_exists + if [ $? -eq 0 ]; then + # join without bootstrapping + extra_opts="--wsrep-cluster-address=${OCF_RESKEY_wsrep_cluster_address}" + else + bootstrap=$(is_bootstrap) + + if ocf_is_true $bootstrap; then + ocf_log info "Node <${NODENAME}> is bootstrapping the cluster" + extra_opts="--wsrep-cluster-address=gcomm://" + else + ocf_log err "Failure, Attempted to promote Master instance of $OCF_RESOURCE_INSTANCE before bootstrap node has been detected." + return $OCF_ERR_GENERIC + fi + + fi + + # make sure the read only instance is stopped + mysql_common_stop + rc=$? + if [ $rc -ne $OCF_SUCCESS ] && [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "Failed to stop read-only galera instance during promotion to Master" + return $rc + fi + + sleep 4 + + mysql_common_prepare_dirs + mysql_common_start "$extra_opts" + rc=$? + if [ $rc != $OCF_SUCCESS ]; then + return $rc + fi + + galera_monitor + rc=$? + if [ $rc != $OCF_SUCCESS -a $rc != $OCF_RUNNING_MASTER ]; then + ocf_log err "Failed initial monitor action" + return $rc + fi + + is_readonly + if [ $? -eq 0 ]; then + ocf_log err "Failure. Master instance started in read-only mode, check configuration." + return $OCF_ERR_GENERIC + fi + + if ocf_is_true $bootstrap; then + promote_everyone + clear_bootstrap_node + ocf_log info "Bootstrap complete, promoting the rest of the galera instances." + fi + + # last commit is no longer relevant once promoted + clear_last_commit + + ocf_log info "Galera started" + return $OCF_SUCCESS +} + +galera_demote() +{ + mysql_common_stop + rc=$? + if [ $rc -ne $OCF_SUCCESS ] && [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "Failed to stop Master galera instance during demotion to Master" + return $rc + fi + + # if this node was previously a bootstrap node, that is no longer the case. + clear_bootstrap_node + + # start again in slave mode so the new last commit is recorded + galera_start +} + +galera_start() +{ + local extra_opts='--read-only=true' + local last_commit + + echo $OCF_RESKEY_wsrep_cluster_address | grep -q $NODENAME + if [ $? -ne 0 ]; then + ocf_log err "local node <${NODENAME}> must be a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>to start this galera instance" + return $OCF_ERR_CONFIGURED + fi + + mysql_common_prepare_dirs + mysql_common_start "$extra_opts" + + is_readonly + if [ $? -ne 0 ]; then + ocf_log err "Failure. Slave instance did not start correctly in read-only mode, Make sure local galera.cnf does not have wsrep_cluster_address set." + return $OCF_ERR_GENERIC + fi + + ocf_log info "attempting to detect last commit version" + while [ -z "$last_commit" ]; do + last_commit=$(get_status_variable "wsrep_last_committed") + if [ -z "$last_commit" ]; then + sleep 1 + fi + done + ocf_log info "Last commit version found: $last_commit" + + set_last_commit $last_commit + + master_exists + if [ $? -eq 0 ]; then + ocf_log info "Master instances are already up, setting master score so this instance will join galera cluster." + set_master_score $NODENAME + else + clear_master_score + detect_first_master + fi + + return $OCF_SUCCESS +} + +galera_monitor() +{ + local rc + local status_loglevel="err" + + # Set loglevel to info during probe + if ocf_is_probe; then + status_loglevel="info" + fi + + mysql_common_status $status_loglevel + rc=$? + + # If status returned an error, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + echo $OCF_RESKEY_wsrep_cluster_address | grep -q $NODENAME + if [ $? -ne 0 ]; then + ocf_log err "local node <${NODENAME}> is started, but is not a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>" + return $OCF_ERR_GENERIC + fi + + is_readonly + if [ $? -ne 0 ]; then + if ocf_is_probe; then + # restore master score during probe + # if we detect this is a master instance + set_master_score + fi + rc=$OCF_RUNNING_MASTER + # TODO detect if cluster is connected or not here. + else + master_exists + if [ $? -ne 0 ]; then + detect_first_master + else + # a master instance exists and is healthy, promote this + # local read only instance + # so it can join the master galera cluster. + set_master_score + fi + fi + # TODO look at what is done in the wait script + + return $rc +} + +galera_stop() +{ + local rc + # make sure the process is stopped + mysql_common_stop + rc=$1 + + clear_last_commit + clear_master_score + clear_bootstrap_node + return $rc +} + +galera_validate() +{ + if ! ocf_is_ms; then + ocf_log err "Galera must be configured as a multistate Master/Slave resource." + return $OCF_ERR_CONFIGURED + fi + + if [ -z "$OCF_RESKEY_wsrep_cluster_address" ]; then + ocf_log err "Galera must be configured with a wsrep_cluster_address value." + return $OCF_ERR_CONFIGURED + fi + + mysql_common_validate +} + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +galera_validate +rc=$? +LSB_STATUS_STOPPED=3 +if [ $rc -ne 0 ]; then + case "$1" in + stop) exit $OCF_SUCCESS;; + monitor) exit $OCF_NOT_RUNNING;; + status) exit $LSB_STATUS_STOPPED;; + *) exit $rc;; + esac +fi + +# What kind of method was invoked? +case "$1" in + start) galera_start;; + stop) galera_stop;; + status) mysql_common_status err;; + monitor) galera_monitor;; + promote) galera_promote;; + demote) galera_demote;; + notify) galera_notify;; + validate-all) exit $OCF_SUCCESS;; + + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + +# vi:sw=4:ts=4:et: diff --git a/heartbeat/mysql-common.sh b/heartbeat/mysql-common.sh index 9748b08f2..5b6a99158 100755 --- a/heartbeat/mysql-common.sh +++ b/heartbeat/mysql-common.sh @@ -1,287 +1,279 @@ #!/bin/sh ####################################################################### # Attempt to detect a default binary OCF_RESKEY_binary_default=$(which mysqld_safe 2> /dev/null) if [ "$OCF_RESKEY_binary_default" = "" ]; then OCF_RESKEY_binary_default=$(which safe_mysqld 2> /dev/null) fi # Fill in some defaults if no values are specified HOSTOS=`uname` if [ "X${HOSTOS}" = "XOpenBSD" ];then if [ "$OCF_RESKEY_binary_default" = "" ]; then OCF_RESKEY_binary_default="/usr/local/bin/mysqld_safe" fi OCF_RESKEY_config_default="/etc/my.cnf" OCF_RESKEY_datadir_default="/var/mysql" OCF_RESKEY_user_default="_mysql" OCF_RESKEY_group_default="_mysql" OCF_RESKEY_log_default="/var/log/mysqld.log" OCF_RESKEY_pid_default="/var/mysql/mysqld.pid" OCF_RESKEY_socket_default="/var/run/mysql/mysql.sock" else if [ "$OCF_RESKEY_binary_default" = "" ]; then OCF_RESKEY_binary_default="/usr/bin/safe_mysqld" fi OCF_RESKEY_config_default="/etc/my.cnf" OCF_RESKEY_datadir_default="/var/lib/mysql" OCF_RESKEY_user_default="mysql" OCF_RESKEY_group_default="mysql" OCF_RESKEY_log_default="/var/log/mysqld.log" OCF_RESKEY_pid_default="/var/run/mysql/mysqld.pid" OCF_RESKEY_socket_default="/var/lib/mysql/mysql.sock" fi OCF_RESKEY_client_binary_default="mysql" OCF_RESKEY_test_user_default="root" OCF_RESKEY_test_table_default="mysql.user" OCF_RESKEY_test_passwd_default="" OCF_RESKEY_enable_creation_default=0 OCF_RESKEY_additional_parameters_default="" OCF_RESKEY_replication_port_default="3306" OCF_RESKEY_max_slave_lag_default="3600" OCF_RESKEY_evict_outdated_slaves_default="false" OCF_RESKEY_reader_attribute_default="readable" : ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} MYSQL_BINDIR=`dirname ${OCF_RESKEY_binary}` : ${OCF_RESKEY_client_binary=${OCF_RESKEY_client_binary_default}} : ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} : ${OCF_RESKEY_datadir=${OCF_RESKEY_datadir_default}} : ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} : ${OCF_RESKEY_group=${OCF_RESKEY_group_default}} : ${OCF_RESKEY_log=${OCF_RESKEY_log_default}} : ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} : ${OCF_RESKEY_socket=${OCF_RESKEY_socket_default}} : ${OCF_RESKEY_test_user=${OCF_RESKEY_test_user_default}} : ${OCF_RESKEY_test_table=${OCF_RESKEY_test_table_default}} : ${OCF_RESKEY_test_passwd=${OCF_RESKEY_test_passwd_default}} : ${OCF_RESKEY_enable_creation=${OCF_RESKEY_enable_creation_default}} : ${OCF_RESKEY_additional_parameters=${OCF_RESKEY_additional_parameters_default}} : ${OCF_RESKEY_replication_user=${OCF_RESKEY_replication_user_default}} : ${OCF_RESKEY_replication_passwd=${OCF_RESKEY_replication_passwd_default}} : ${OCF_RESKEY_replication_port=${OCF_RESKEY_replication_port_default}} : ${OCF_RESKEY_max_slave_lag=${OCF_RESKEY_max_slave_lag_default}} : ${OCF_RESKEY_evict_outdated_slaves=${OCF_RESKEY_evict_outdated_slaves_default}} : ${OCF_RESKEY_reader_attribute=${OCF_RESKEY_reader_attribute_default}} ####################################################################### # Convenience variables MYSQL=$OCF_RESKEY_client_binary MYSQL_OPTIONS_LOCAL="-S $OCF_RESKEY_socket --connect_timeout=10" MYSQL_OPTIONS_REPL="$MYSQL_OPTIONS_LOCAL --user=$OCF_RESKEY_replication_user --password=$OCF_RESKEY_replication_passwd" MYSQL_OPTIONS_TEST="$MYSQL_OPTIONS_LOCAL --user=$OCF_RESKEY_test_user --password=$OCF_RESKEY_test_passwd" MYSQL_TOO_MANY_CONN_ERR=1040 CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot " NODENAME=$(ocf_local_nodename) CRM_ATTR="${HA_SBIN_DIR}/crm_attribute -N $NODENAME " INSTANCE_ATTR_NAME=`echo ${OCF_RESOURCE_INSTANCE}| awk -F : '{print $1}'` CRM_ATTR_REPL_INFO="${HA_SBIN_DIR}/crm_attribute --type crm_config --name ${INSTANCE_ATTR_NAME}_REPL_INFO -s mysql_replication" ####################################################################### mysql_common_validate() { check_binary $OCF_RESKEY_binary check_binary $OCF_RESKEY_client_binary if [ ! -f $OCF_RESKEY_config ]; then ocf_log err "Config $OCF_RESKEY_config doesn't exist"; return $OCF_ERR_INSTALLED; fi if [ ! -d $OCF_RESKEY_datadir ]; then ocf_log err "Datadir $OCF_RESKEY_datadir doesn't exist"; return $OCF_ERR_INSTALLED; fi getent passwd $OCF_RESKEY_user >/dev/null 2>&1 if [ ! $? -eq 0 ]; then ocf_log err "User $OCF_RESKEY_user doesn't exit"; return $OCF_ERR_INSTALLED; fi getent group $OCF_RESKEY_group >/dev/null 2>&1 if [ ! $? -eq 0 ]; then ocf_log err "Group $OCF_RESKEY_group doesn't exist"; return $OCF_ERR_INSTALLED; fi return $OCF_SUCCESS } mysql_common_status() { - if [ ! -e $OCF_RESKEY_pid ]; then - ocf_log $1 "MySQL is not running" - return $OCF_NOT_RUNNING; - fi + local loglevel=$1 + local pid=$2 + if [ -z "$pid" ]; then + if [ ! -e $OCF_RESKEY_pid ]; then + ocf_log $loglevel "MySQL is not running" + return $OCF_NOT_RUNNING; + fi - pid=`cat $OCF_RESKEY_pid`; + pid=`cat $OCF_RESKEY_pid`; + fi if [ -d /proc -a -d /proc/1 ]; then [ "u$pid" != "u" -a -d /proc/$pid ] else kill -s 0 $pid >/dev/null 2>&1 fi if [ $? -eq 0 ]; then return $OCF_SUCCESS; else - ocf_log $1 "MySQL not running: removing old PID file" + ocf_log $loglevel "MySQL not running: removing old PID file" rm -f $OCF_RESKEY_pid return $OCF_NOT_RUNNING; fi } mysql_common_prepare_dirs() { local rc touch $OCF_RESKEY_log chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_log chmod 0640 $OCF_RESKEY_log [ -x /sbin/restorecon ] && /sbin/restorecon $OCF_RESKEY_log if ocf_is_true "$OCF_RESKEY_enable_creation" && [ ! -d $OCF_RESKEY_datadir/mysql ] ; then ocf_log info "Initializing MySQL database: " $MYSQL_BINDIR/mysql_install_db --datadir=$OCF_RESKEY_datadir rc=$? if [ $rc -ne 0 ] ; then ocf_log err "Initialization failed: $rc"; exit $OCF_ERR_GENERIC fi chown -R $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_datadir fi pid_dir=`dirname $OCF_RESKEY_pid` if [ ! -d $pid_dir ] ; then ocf_log info "Creating PID dir: $pid_dir" mkdir -p $pid_dir chown $OCF_RESKEY_user:$OCF_RESKEY_group $pid_dir fi socket_dir=`dirname $OCF_RESKEY_socket` if [ ! -d $socket_dir ] ; then ocf_log info "Creating socket dir: $socket_dir" mkdir -p $socket_dir chown $OCF_RESKEY_user:$OCF_RESKEY_group $socket_dir fi # Regardless of whether we just created the directory or it # already existed, check whether it is writable by the configured # user for dir in $pid_dir $socket_dir; do if ! su -s /bin/sh - $OCF_RESKEY_user -c "test -w $dir"; then ocf_log err "Directory $dir is not writable by $OCF_RESKEY_user" exit $OCF_ERR_PERM; fi done } mysql_common_start() { local mysql_extra_params="$1" local pid ${OCF_RESKEY_binary} --defaults-file=$OCF_RESKEY_config \ --pid-file=$OCF_RESKEY_pid \ --socket=$OCF_RESKEY_socket \ --datadir=$OCF_RESKEY_datadir \ --log-error=$OCF_RESKEY_log \ --user=$OCF_RESKEY_user $OCF_RESKEY_additional_parameters \ $mysql_extra_params >/dev/null 2>&1 & pid=$! # Spin waiting for the server to come up. # Let the CRM/LRM time us out if required. start_wait=1 while [ $start_wait = 1 ]; do if ! ps $pid > /dev/null 2>&1; then wait $pid - ocf_log err "MySQL server failed to start (rc=$?), please check your installation" + ocf_log err "MySQL server failed to start (pid=$pid) (rc=$?), please check your installation" return $OCF_ERR_GENERIC fi mysql_common_status info rc=$? if [ $rc = $OCF_SUCCESS ]; then start_wait=0 elif [ $rc != $OCF_NOT_RUNNING ]; then ocf_log info "MySQL start failed: $rc" return $rc fi sleep 2 done return $OCF_SUCCESS } mysql_common_stop() { local pid local rc if [ ! -f $OCF_RESKEY_pid ]; then ocf_log info "MySQL is not running" return $OCF_SUCCESS fi pid=`cat $OCF_RESKEY_pid 2> /dev/null ` /bin/kill $pid > /dev/null rc=$? if [ $rc != 0 ]; then ocf_log err "MySQL couldn't be stopped" return $OCF_ERR_GENERIC fi # stop waiting shutdown_timeout=15 if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) fi count=0 while [ $count -lt $shutdown_timeout ] do - mysql_common_status info + mysql_common_status info $pid rc=$? if [ $rc = $OCF_NOT_RUNNING ]; then break fi count=`expr $count + 1` sleep 1 ocf_log debug "MySQL still hasn't stopped yet. Waiting..." done - mysql_common_status info + mysql_common_status info $pid if [ $? != $OCF_NOT_RUNNING ]; then ocf_log info "MySQL failed to stop after ${shutdown_timeout}s using SIGTERM. Trying SIGKILL..." /bin/kill -KILL $pid > /dev/null fi ocf_log info "MySQL stopped"; rm -f /var/lock/subsys/mysqld rm -f $OCF_RESKEY_socket return $OCF_SUCCESS } - - - - - - - - - - - -