From d59a000da2766476538bb82d1889f5c0f3882f9f Mon Sep 17 00:00:00 2001 From: Jan Friesse Date: Wed, 2 Mar 2022 18:43:31 +0100 Subject: [PATCH] corosync-qnetd: Add resource agent Mostly for better monitor operation using corosync-qnetd-tool. As qnetd is (almost) stateless only directory which has to be copied (once) across the nodes is nss db directory (usually /etc/corosync/qnetd/nssdb). Signed-off-by: Jan Friesse --- doc/man/Makefile.am | 1 + heartbeat/Makefile.am | 1 + heartbeat/corosync-qnetd | 353 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 355 insertions(+) create mode 100755 heartbeat/corosync-qnetd diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 1093717fe..013aa392d 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -127,6 +127,7 @@ man_MANS = ocf_heartbeat_AoEtarget.7 \ ocf_heartbeat_azure-lb.7 \ ocf_heartbeat_clvm.7 \ ocf_heartbeat_conntrackd.7 \ + ocf_heartbeat_corosync-qnetd.7 \ ocf_heartbeat_crypt.7 \ ocf_heartbeat_db2.7 \ ocf_heartbeat_dhcpd.7 \ diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am index 67b400679..38154e2da 100644 --- a/heartbeat/Makefile.am +++ b/heartbeat/Makefile.am @@ -101,6 +101,7 @@ ocf_SCRIPTS = AoEtarget \ azure-lb \ clvm \ conntrackd \ + corosync-qnetd \ crypt \ db2 \ dhcpd \ diff --git a/heartbeat/corosync-qnetd b/heartbeat/corosync-qnetd new file mode 100755 index 000000000..6b9777711 --- /dev/null +++ b/heartbeat/corosync-qnetd @@ -0,0 +1,353 @@ +#!/bin/sh +# +# Copyright (C) 2022 Red Hat, Inc. All rights reserved. +# +# Authors: Jan Friesse +# +# 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" + +# Use runuser if available for SELinux. +if [ -x "/sbin/runuser" ]; then + SU="runuser" +else + SU="su" +fi + +# Attempt to detect a default binary +OCF_RESKEY_binary_default=$(which corosync-qnetd 2> /dev/null) +if [ "${OCF_RESKEY_binary_default}" = "" ]; then + OCF_RESKEY_binary_default="/usr/bin/corosync-qnetd" +fi + +# Defaults +OCF_RESKEY_qnetd_opts_default="" +OCF_RESKEY_qnetd_tool_binary_default="/usr/bin/corosync-qnetd-tool" +OCF_RESKEY_ip_default="" +OCF_RESKEY_port_default="" +OCF_RESKEY_nss_db_dir_default="" +OCF_RESKEY_pid_default="/var/run/corosync-qnetd/corosync-qnetd-${OCF_RESOURCE_INSTANCE}.pid" +OCF_RESKEY_ipc_sock_default="/var/run/corosync-qnetd/corosync-qnetd-${OCF_RESOURCE_INSTANCE}.sock" +OCF_RESKEY_user_default="coroqnetd" +OCF_RESKEY_group_default="${OCF_RESKEY_user_default}" + +: "${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}" +: "${OCF_RESKEY_qnetd_opts=${OCF_RESKEY_qnetd_opts_default}}" +: "${OCF_RESKEY_qnetd_tool_binary=${OCF_RESKEY_qnetd_tool_binary_default}}" +: "${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}}" +: "${OCF_RESKEY_port=${OCF_RESKEY_port_default}}" +: "${OCF_RESKEY_nss_db_dir=${OCF_RESKEY_nss_db_dir_default}}" +: "${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}" +: "${OCF_RESKEY_ipc_sock=${OCF_RESKEY_ipc_sock_default}}" +: "${OCF_RESKEY_user=${OCF_RESKEY_user_default}}" +: "${OCF_RESKEY_group=${OCF_RESKEY_group_default}}" + +corosync_qnetd_usage() { + cat < + + +1.0 + +OCF Resource script for corosync-qnetd. It manages a corosync-qnetd +instance as a HA resource. It is required to copy nss db directory (usually /etc/corosync/qnetd/nssdb) +across all nodes (only once - after database is initialized). +Corosync QNet daemon resource agent + + + + + Location of the corosync-qnetd binary + corosync-qnetd binary + + + + + + Additional options for corosync-qnetd binary. "-4" for example. + + corosync-qnetd extra options + + + + + + The absolute path to the corosync-qnetd-tool for monitoring with OCF_CHECK_LEVEL greater zero. + + The absolute path to the corosync-qnetd-tool binary + + + + + + IP address to listen on. By default the daemon listens on all addresses (wildcard). + + IP address to listen on + + + + + + TCP port to listen on. Default port is 5403. + + TCP port to listen on + + + + + + Location of the corosync-qnetd nss db directory (empty for default - usually /etc/corosync/qnetd/nssdb) + + corosync-qnetd nss db directory + + + + + + Location of the corosync-qnetd pid/lock + + corosync-qnetd pid file + + + + + + Location of the corosync-qnetd ipc socket + + corosync-qnetd ipc socket file + + + + + User running corosync-qnetd + corosync-qnetd user + + + + + Group running corosync-qnetd + corosync-qnetd group + + + + + + + + + + + + + + +END +} + +corosync_qnetd_status() { + ocf_pidfile_status "${OCF_RESKEY_pid}" > /dev/null 2>&1 + case "$?" in + 0) + rc="$OCF_SUCCESS" + ;; + 1|2) + rc="$OCF_NOT_RUNNING" + ;; + *) + rc="$OCF_ERR_GENERIC" + ;; + esac + + return "$rc" +} + +corosync_qnetd_start() { + corosync_qnetd_validate_all + rc="$?" + + if [ "$rc" -ne 0 ]; then + return "$rc" + fi + + # if resource is already running,no need to continue code after this. + if corosync_qnetd_status; then + ocf_log info "corosync-qnetd is already running" + return "${OCF_SUCCESS}" + fi + + pid_dir=$(dirname "${OCF_RESKEY_pid}") + sock_dir=$(dirname "${OCF_RESKEY_ipc_sock}") + + for d in "$pid_dir" "$sock_dir";do + if [ ! -d "$d" ];then + mkdir -p "$d" + chmod 0770 "$d" + chown "${OCF_RESKEY_user}:${OCF_RESKEY_group}" "$d" + fi + done + + params="-S \"local_socket_file=${OCF_RESKEY_ipc_sock}\" -S \"lock_file=${OCF_RESKEY_pid}\"" + + if [ -n "${OCF_RESKEY_nss_db_dir}" ];then + params="$params -S \"nss_db_dir=${OCF_RESKEY_nss_db_dir}\"" + fi + + if [ -n "${OCF_RESKEY_ip}" ];then + params="$params -l \"${OCF_RESKEY_ip}\"" + fi + + if [ -n "${OCF_RESKEY_port}" ];then + params="$params -p \"${OCF_RESKEY_port}\"" + fi + + params="$params ${OCF_RESKEY_qnetd_opts}" + + ocf_run "$SU" -s "/bin/sh" "${OCF_RESKEY_user}" -c "${OCF_RESKEY_binary} $params" + + while :; do + corosync_qnetd_monitor "debug" + rc="$?" + + if [ "$rc" -eq "${OCF_SUCCESS}" ]; then + break + fi + sleep 1 + + ocf_log debug "corosync-qnetd still hasn't started yet. Waiting..." + done + + ocf_log info "corosync-qnetd started" + return "${OCF_SUCCESS}" +} + +corosync_qnetd_stop() { + corosync_qnetd_status + + if [ "$?" -ne "$OCF_SUCCESS" ]; then + # Currently not running. Nothing to do. + ocf_log info "corosync-qnetd is already stopped" + + return "$OCF_SUCCESS" + fi + + pid=$(cat "${OCF_RESKEY_pid}") + kill "$pid" + + # Wait for process to stop + while corosync_qnetd_monitor "debug"; do + sleep 1 + done + + ocf_log info "corosync-qnetd stopped" + return "$OCF_SUCCESS" +} + +corosync_qnetd_monitor() { + loglevel=${1:-err} + + corosync_qnetd_status + rc="$?" + + if [ "$rc" -ne "$OCF_SUCCESS" ];then + return "$rc" + fi + + out=$("${OCF_RESKEY_qnetd_tool_binary}" -s -p "${OCF_RESKEY_ipc_sock}" 2>&1 >/dev/null) + rc="$?" + + if [ "$rc" != 0 ];then + ocf_log "$loglevel" "$out" + fi + + case "$rc" in + "0") rc="$OCF_SUCCESS" ;; + "3") rc="$OCF_NOT_RUNNING" ;; + *) rc="$OCF_ERR_GENERIC" ;; + esac + + return "$rc" +} + +corosync_qnetd_validate_all() { + check_binary "${OCF_RESKEY_binary}" + + check_binary "${OCF_RESKEY_qnetd_tool_binary}" +} + + +# **************************** MAIN SCRIPT ************************************ + +# Make sure meta-data and usage always succeed +case "$__OCF_ACTION" in + meta-data) + corosync_qnetd_meta_data + exit "$OCF_SUCCESS" + ;; + usage|help) + corosync_qnetd_usage + exit "$OCF_SUCCESS" + ;; +esac + +# This OCF agent script need to be run as root user. +if ! ocf_is_root; then + echo "$0 agent script need to be run as root user." + ocf_log debug "$0 agent script need to be run as root user." + exit "$OCF_ERR_GENERIC" +fi + +# Translate each action into the appropriate function call +case "$__OCF_ACTION" in + start) + corosync_qnetd_start + ;; + stop) + corosync_qnetd_stop + ;; + status) + corosync_qnetd_status + ;; + monitor) + corosync_qnetd_monitor + ;; + validate-all) + corosync_qnetd_validate_all + ;; + *) + corosync_qnetd_usage + exit "$OCF_ERR_UNIMPLEMENTED" + ;; +esac + +rc="$?" +exit "$rc" +# End of this script