Blame SOURCES/bz2069270-corosync-qnetd-new-ra.patch

38c30a
From d59a000da2766476538bb82d1889f5c0f3882f9f Mon Sep 17 00:00:00 2001
38c30a
From: Jan Friesse <jfriesse@redhat.com>
38c30a
Date: Wed, 2 Mar 2022 18:43:31 +0100
38c30a
Subject: [PATCH] corosync-qnetd: Add resource agent
38c30a
38c30a
Mostly for better monitor operation using corosync-qnetd-tool. As qnetd
38c30a
is (almost) stateless only directory which has to be copied (once)
38c30a
across the nodes is nss db directory (usually
38c30a
/etc/corosync/qnetd/nssdb).
38c30a
38c30a
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
38c30a
---
38c30a
 doc/man/Makefile.am      |   1 +
38c30a
 heartbeat/Makefile.am    |   1 +
38c30a
 heartbeat/corosync-qnetd | 353 +++++++++++++++++++++++++++++++++++++++
38c30a
 3 files changed, 355 insertions(+)
38c30a
 create mode 100755 heartbeat/corosync-qnetd
38c30a
38c30a
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
38c30a
index 1093717fe..013aa392d 100644
38c30a
--- a/doc/man/Makefile.am
38c30a
+++ b/doc/man/Makefile.am
38c30a
@@ -127,6 +127,7 @@ man_MANS                = ocf_heartbeat_AoEtarget.7 \
38c30a
                           ocf_heartbeat_azure-lb.7 \
38c30a
                           ocf_heartbeat_clvm.7 \
38c30a
                           ocf_heartbeat_conntrackd.7 \
38c30a
+                          ocf_heartbeat_corosync-qnetd.7 \
38c30a
                           ocf_heartbeat_crypt.7 \
38c30a
                           ocf_heartbeat_db2.7 \
38c30a
                           ocf_heartbeat_dhcpd.7 \
38c30a
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
38c30a
index 67b400679..38154e2da 100644
38c30a
--- a/heartbeat/Makefile.am
38c30a
+++ b/heartbeat/Makefile.am
38c30a
@@ -101,6 +101,7 @@ ocf_SCRIPTS	      = AoEtarget		\
38c30a
 			azure-lb		\
38c30a
 			clvm			\
38c30a
 			conntrackd		\
38c30a
+			corosync-qnetd		\
38c30a
 			crypt			\
38c30a
 			db2			\
38c30a
 			dhcpd			\
38c30a
diff --git a/heartbeat/corosync-qnetd b/heartbeat/corosync-qnetd
38c30a
new file mode 100755
38c30a
index 000000000..6b9777711
38c30a
--- /dev/null
38c30a
+++ b/heartbeat/corosync-qnetd
38c30a
@@ -0,0 +1,353 @@
38c30a
+#!/bin/sh
38c30a
+#
38c30a
+# Copyright (C) 2022 Red Hat, Inc.  All rights reserved.
38c30a
+#
38c30a
+# Authors: Jan Friesse <jfriesse@redhat.com>
38c30a
+#
38c30a
+# This program is free software; you can redistribute it and/or modify
38c30a
+# it under the terms of version 2 of the GNU General Public License as
38c30a
+# published by the Free Software Foundation.
38c30a
+#
38c30a
+# This program is distributed in the hope that it would be useful, but
38c30a
+# WITHOUT ANY WARRANTY; without even the implied warranty of
38c30a
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
38c30a
+#
38c30a
+# Further, this software is distributed without any warranty that it is
38c30a
+# free of the rightful claim of any third person regarding infringement
38c30a
+# or the like.  Any license provided herein, whether implied or
38c30a
+# otherwise, applies only to this software file.  Patent licenses, if
38c30a
+# any, provided herein do not apply to combinations of this program with
38c30a
+# other software, or any other product whatsoever.
38c30a
+#
38c30a
+# You should have received a copy of the GNU General Public License
38c30a
+# along with this program; if not, write the Free Software Foundation,
38c30a
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
38c30a
+#
38c30a
+
38c30a
+# Initialization:
38c30a
+: "${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}"
38c30a
+. "${OCF_FUNCTIONS_DIR}/ocf-shellfuncs"
38c30a
+
38c30a
+# Use runuser if available for SELinux.
38c30a
+if [ -x "/sbin/runuser" ]; then
38c30a
+    SU="runuser"
38c30a
+else
38c30a
+    SU="su"
38c30a
+fi
38c30a
+
38c30a
+# Attempt to detect a default binary
38c30a
+OCF_RESKEY_binary_default=$(which corosync-qnetd 2> /dev/null)
38c30a
+if [ "${OCF_RESKEY_binary_default}" = "" ]; then
38c30a
+    OCF_RESKEY_binary_default="/usr/bin/corosync-qnetd"
38c30a
+fi
38c30a
+
38c30a
+# Defaults
38c30a
+OCF_RESKEY_qnetd_opts_default=""
38c30a
+OCF_RESKEY_qnetd_tool_binary_default="/usr/bin/corosync-qnetd-tool"
38c30a
+OCF_RESKEY_ip_default=""
38c30a
+OCF_RESKEY_port_default=""
38c30a
+OCF_RESKEY_nss_db_dir_default=""
38c30a
+OCF_RESKEY_pid_default="/var/run/corosync-qnetd/corosync-qnetd-${OCF_RESOURCE_INSTANCE}.pid"
38c30a
+OCF_RESKEY_ipc_sock_default="/var/run/corosync-qnetd/corosync-qnetd-${OCF_RESOURCE_INSTANCE}.sock"
38c30a
+OCF_RESKEY_user_default="coroqnetd"
38c30a
+OCF_RESKEY_group_default="${OCF_RESKEY_user_default}"
38c30a
+
38c30a
+: "${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}"
38c30a
+: "${OCF_RESKEY_qnetd_opts=${OCF_RESKEY_qnetd_opts_default}}"
38c30a
+: "${OCF_RESKEY_qnetd_tool_binary=${OCF_RESKEY_qnetd_tool_binary_default}}"
38c30a
+: "${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}}"
38c30a
+: "${OCF_RESKEY_port=${OCF_RESKEY_port_default}}"
38c30a
+: "${OCF_RESKEY_nss_db_dir=${OCF_RESKEY_nss_db_dir_default}}"
38c30a
+: "${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}"
38c30a
+: "${OCF_RESKEY_ipc_sock=${OCF_RESKEY_ipc_sock_default}}"
38c30a
+: "${OCF_RESKEY_user=${OCF_RESKEY_user_default}}"
38c30a
+: "${OCF_RESKEY_group=${OCF_RESKEY_group_default}}"
38c30a
+
38c30a
+corosync_qnetd_usage() {
38c30a
+    cat <
38c30a
+usage: $0 {start|stop|status|monitor|validate-all|meta-data}
38c30a
+
38c30a
+Expects to have a fully populated OCF RA-compliant environment set.
38c30a
+END
38c30a
+}
38c30a
+
38c30a
+corosync_qnetd_meta_data() {
38c30a
+        cat <
38c30a
+
38c30a
+
38c30a
+<resource-agent name="corosync-qnetd" version="1.0">
38c30a
+<version>1.0</version>
38c30a
+
38c30a
+<longdesc lang="en">OCF Resource script for corosync-qnetd. It manages a corosync-qnetd
38c30a
+instance as a HA resource. It is required to copy nss db directory (usually /etc/corosync/qnetd/nssdb)
38c30a
+across all nodes (only once - after database is initialized).</longdesc>
38c30a
+<shortdesc lang="en">Corosync QNet daemon resource agent</shortdesc>
38c30a
+
38c30a
+<parameters>
38c30a
+
38c30a
+<parameter name="binary">
38c30a
+    <longdesc lang="en">Location of the corosync-qnetd binary</longdesc>
38c30a
+    <shortdesc lang="en">corosync-qnetd binary</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_binary_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="qnetd_opts">
38c30a
+    <longdesc lang="en">
38c30a
+        Additional options for corosync-qnetd binary. "-4" for example.
38c30a
+    </longdesc>
38c30a
+    <shortdesc lang="en">corosync-qnetd extra options</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_qnetd_opts_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="qnetd_tool_binary">
38c30a
+    <longdesc lang="en">
38c30a
+        The absolute path to the corosync-qnetd-tool for monitoring with OCF_CHECK_LEVEL greater zero.
38c30a
+    </longdesc>
38c30a
+    <shortdesc lang="en">The absolute path to the corosync-qnetd-tool binary</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_qnetd_tool_binary_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="ip">
38c30a
+    <longdesc lang="en">
38c30a
+        IP address to listen on. By default the daemon listens on all addresses (wildcard).
38c30a
+    </longdesc>
38c30a
+    <shortdesc lang="en">IP address to listen on</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_ip_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="port">
38c30a
+    <longdesc lang="en">
38c30a
+        TCP port to listen on. Default port is 5403.
38c30a
+    </longdesc>
38c30a
+    <shortdesc lang="en">TCP port to listen on</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_port_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="nss_db_dir">
38c30a
+    <longdesc lang="en">
38c30a
+        Location of the corosync-qnetd nss db directory (empty for default - usually /etc/corosync/qnetd/nssdb)
38c30a
+    </longdesc>
38c30a
+    <shortdesc lang="en">corosync-qnetd nss db directory</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_nss_db_dir_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="pid">
38c30a
+    <longdesc lang="en">
38c30a
+        Location of the corosync-qnetd pid/lock
38c30a
+    </longdesc>
38c30a
+    <shortdesc lang="en">corosync-qnetd pid file</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_pid_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="ipc_sock">
38c30a
+    <longdesc lang="en">
38c30a
+        Location of the corosync-qnetd ipc socket
38c30a
+    </longdesc>
38c30a
+    <shortdesc lang="en">corosync-qnetd ipc socket file</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_ipc_sock_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="user">
38c30a
+    <longdesc lang="en">User running corosync-qnetd</longdesc>
38c30a
+    <shortdesc lang="en">corosync-qnetd user</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_user_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+<parameter name="group">
38c30a
+    <longdesc lang="en">Group running corosync-qnetd</longdesc>
38c30a
+    <shortdesc lang="en">corosync-qnetd group</shortdesc>
38c30a
+    <content type="string" default="${OCF_RESKEY_group_default}" />
38c30a
+</parameter>
38c30a
+
38c30a
+</parameters>
38c30a
+
38c30a
+<actions>
38c30a
+<action name="start" timeout="20s" />
38c30a
+<action name="stop" timeout="20s" />
38c30a
+<action name="status" timeout="20s" />
38c30a
+<action name="monitor" depth="0" timeout="20s" interval="10s" start-delay="10s" />
38c30a
+<action name="validate-all" timeout="20s" />
38c30a
+<action name="meta-data" timeout="20s" />
38c30a
+</actions>
38c30a
+</resource-agent>
38c30a
+END
38c30a
+}
38c30a
+
38c30a
+corosync_qnetd_status() {
38c30a
+    ocf_pidfile_status "${OCF_RESKEY_pid}" > /dev/null 2>&1
38c30a
+    case "$?" in
38c30a
+        0)
38c30a
+            rc="$OCF_SUCCESS"
38c30a
+            ;;
38c30a
+        1|2)
38c30a
+            rc="$OCF_NOT_RUNNING"
38c30a
+            ;;
38c30a
+        *)
38c30a
+            rc="$OCF_ERR_GENERIC"
38c30a
+            ;;
38c30a
+    esac
38c30a
+
38c30a
+    return "$rc"
38c30a
+}
38c30a
+
38c30a
+corosync_qnetd_start() {
38c30a
+    corosync_qnetd_validate_all
38c30a
+    rc="$?"
38c30a
+
38c30a
+    if [ "$rc" -ne 0 ]; then
38c30a
+        return "$rc"
38c30a
+    fi
38c30a
+
38c30a
+    # if resource is already running,no need to continue code after this.
38c30a
+    if corosync_qnetd_status; then
38c30a
+        ocf_log info "corosync-qnetd is already running"
38c30a
+        return "${OCF_SUCCESS}"
38c30a
+    fi
38c30a
+
38c30a
+    pid_dir=$(dirname "${OCF_RESKEY_pid}")
38c30a
+    sock_dir=$(dirname "${OCF_RESKEY_ipc_sock}")
38c30a
+
38c30a
+    for d in "$pid_dir" "$sock_dir";do
38c30a
+        if [ ! -d "$d" ];then
38c30a
+            mkdir -p "$d"
38c30a
+            chmod 0770 "$d"
38c30a
+            chown "${OCF_RESKEY_user}:${OCF_RESKEY_group}" "$d"
38c30a
+        fi
38c30a
+    done
38c30a
+
38c30a
+    params="-S \"local_socket_file=${OCF_RESKEY_ipc_sock}\" -S \"lock_file=${OCF_RESKEY_pid}\""
38c30a
+
38c30a
+    if [ -n "${OCF_RESKEY_nss_db_dir}" ];then
38c30a
+        params="$params -S \"nss_db_dir=${OCF_RESKEY_nss_db_dir}\""
38c30a
+    fi
38c30a
+
38c30a
+    if [ -n "${OCF_RESKEY_ip}" ];then
38c30a
+        params="$params -l \"${OCF_RESKEY_ip}\""
38c30a
+    fi
38c30a
+
38c30a
+    if [ -n "${OCF_RESKEY_port}" ];then
38c30a
+        params="$params -p \"${OCF_RESKEY_port}\""
38c30a
+    fi
38c30a
+
38c30a
+    params="$params ${OCF_RESKEY_qnetd_opts}"
38c30a
+
38c30a
+    ocf_run "$SU" -s "/bin/sh" "${OCF_RESKEY_user}" -c "${OCF_RESKEY_binary} $params"
38c30a
+
38c30a
+    while :; do
38c30a
+        corosync_qnetd_monitor "debug"
38c30a
+        rc="$?"
38c30a
+
38c30a
+        if [ "$rc" -eq "${OCF_SUCCESS}" ]; then
38c30a
+            break
38c30a
+        fi
38c30a
+        sleep 1
38c30a
+
38c30a
+        ocf_log debug "corosync-qnetd still hasn't started yet. Waiting..."
38c30a
+    done
38c30a
+
38c30a
+    ocf_log info "corosync-qnetd started"
38c30a
+    return "${OCF_SUCCESS}"
38c30a
+}
38c30a
+
38c30a
+corosync_qnetd_stop() {
38c30a
+    corosync_qnetd_status
38c30a
+
38c30a
+    if [ "$?" -ne "$OCF_SUCCESS" ]; then
38c30a
+        # Currently not running. Nothing to do.
38c30a
+        ocf_log info "corosync-qnetd is already stopped"
38c30a
+
38c30a
+        return "$OCF_SUCCESS"
38c30a
+    fi
38c30a
+
38c30a
+    pid=$(cat "${OCF_RESKEY_pid}")
38c30a
+    kill "$pid"
38c30a
+
38c30a
+    # Wait for process to stop
38c30a
+    while corosync_qnetd_monitor "debug"; do
38c30a
+        sleep 1
38c30a
+    done
38c30a
+
38c30a
+    ocf_log info "corosync-qnetd stopped"
38c30a
+    return "$OCF_SUCCESS"
38c30a
+}
38c30a
+
38c30a
+corosync_qnetd_monitor() {
38c30a
+    loglevel=${1:-err}
38c30a
+
38c30a
+    corosync_qnetd_status
38c30a
+    rc="$?"
38c30a
+
38c30a
+    if [ "$rc" -ne "$OCF_SUCCESS" ];then
38c30a
+        return "$rc"
38c30a
+    fi
38c30a
+
38c30a
+    out=$("${OCF_RESKEY_qnetd_tool_binary}" -s -p "${OCF_RESKEY_ipc_sock}" 2>&1 >/dev/null)
38c30a
+    rc="$?"
38c30a
+
38c30a
+    if [ "$rc" != 0 ];then
38c30a
+        ocf_log "$loglevel" "$out"
38c30a
+    fi
38c30a
+
38c30a
+    case "$rc" in
38c30a
+        "0") rc="$OCF_SUCCESS" ;;
38c30a
+        "3") rc="$OCF_NOT_RUNNING" ;;
38c30a
+        *) rc="$OCF_ERR_GENERIC" ;;
38c30a
+    esac
38c30a
+
38c30a
+    return "$rc"
38c30a
+}
38c30a
+
38c30a
+corosync_qnetd_validate_all() {
38c30a
+    check_binary "${OCF_RESKEY_binary}"
38c30a
+
38c30a
+    check_binary "${OCF_RESKEY_qnetd_tool_binary}"
38c30a
+}
38c30a
+
38c30a
+
38c30a
+# **************************** MAIN SCRIPT ************************************
38c30a
+
38c30a
+# Make sure meta-data and usage always succeed
38c30a
+case "$__OCF_ACTION" in
38c30a
+    meta-data)
38c30a
+        corosync_qnetd_meta_data
38c30a
+        exit "$OCF_SUCCESS"
38c30a
+        ;;
38c30a
+    usage|help)
38c30a
+        corosync_qnetd_usage
38c30a
+        exit "$OCF_SUCCESS"
38c30a
+        ;;
38c30a
+esac
38c30a
+
38c30a
+# This OCF agent script need to be run as root user.
38c30a
+if ! ocf_is_root; then
38c30a
+        echo "$0 agent script need to be run as root user."
38c30a
+        ocf_log debug "$0 agent script need to be run as root user."
38c30a
+        exit "$OCF_ERR_GENERIC"
38c30a
+fi
38c30a
+
38c30a
+# Translate each action into the appropriate function call
38c30a
+case "$__OCF_ACTION" in
38c30a
+    start)
38c30a
+        corosync_qnetd_start
38c30a
+        ;;
38c30a
+    stop)
38c30a
+        corosync_qnetd_stop
38c30a
+        ;;
38c30a
+    status)
38c30a
+        corosync_qnetd_status
38c30a
+        ;;
38c30a
+    monitor)
38c30a
+        corosync_qnetd_monitor
38c30a
+        ;;
38c30a
+    validate-all)
38c30a
+        corosync_qnetd_validate_all
38c30a
+        ;;
38c30a
+    *)
38c30a
+        corosync_qnetd_usage
38c30a
+        exit "$OCF_ERR_UNIMPLEMENTED"
38c30a
+        ;;
38c30a
+esac
38c30a
+
38c30a
+rc="$?"
38c30a
+exit "$rc"
38c30a
+# End of this script