diff options
31 files changed, 301 insertions, 116 deletions
@@ -1,3 +1,31 @@ +* Wed Apr 24 2024 resource-agents contributors +- stable release 4.14.0 +- doc: writing-python-agents: add description of is_probe() and distro() + +* Wed Apr 17 2024 resource-agents contributors +- release candidate 4.14.0 rc1 +- all agents: remove -S state/status that are either ignored, or give an error message in newer versions of Pacemaker +- configure: fix "C preprocessor "gcc -E" fails sanity check" error caused by autoconf 2.72 +- configure: prepare to not build with -ansi by default in the future +- docs: writing-python-agents: update required Python version to 3.6+ +- spec: use /usr/sbin paths for Fedora 40+ +- LVM-activate: avoid false positive for VG activation (fail when system_id_source and volume_list are set) +- aws-vpc-move-ip/aws-vpc-route53/awseip/awsvip: add auth_type parameter and AWS Policy based authentication type +- azure-lb: support IPv6 with Azure load balancer when using socat +- db2: fix OCF_SUCESS typo in db2_notify +- docker: return OCF_NOT_RUNNING when Docker isn't running +- findif.sh: fix corner cases +- findif.sh: fix loopback handling +- findif: check that netmaskbits != EOS in addition to != NULL in all cases +- galera: allow joiner to report non-Primary during initial IST +- nfsserver: fix "server scope" functionality for both potentially other dropins AND multiple ExecStart +- ocivip: fix PRIMARY_IFACE variable when it returns two lines +- openstack-info: ensure no newlines in openstack_ports +- portblock: accept numeric protocol from iptables (to fix regression in iptables 1.8.9 that has shipped in some distros) +- portblock: remove write to tcp_tw_recycle +- storage_mon: fix file handler out of scope leak and uninitialized values +- storage_mon: use memset() to fix "uninitialized value" covscan error, as qb_ipcc_recv() will always set a message + * Wed Oct 11 2023 resource-agents contributors - stable release 4.13.0 - findif.sh: dont use table parameter as it returns no netmask (tested with diff --git a/configure.ac b/configure.ac index d930cd8..76c8251 100644 --- a/configure.ac +++ b/configure.ac @@ -81,6 +81,7 @@ fi AC_PROG_CC dnl Can force other with environment variable "CC". AM_PROG_CC_C_O AC_PROG_CC_STDC +AC_PROG_CPP AC_PROG_AWK AC_PROG_LN_S AC_PROG_INSTALL @@ -185,7 +186,7 @@ AC_SUBST(PKGNAME) AC_ARG_ENABLE([ansi], [ --enable-ansi force GCC to compile to ANSI/ANSI standard for older compilers. - [default=yes]]) + [default=no]]) AC_ARG_ENABLE([fatal-warnings], [ --enable-fatal-warnings very pedantic and fatal warnings for gcc @@ -1062,7 +1063,7 @@ dnl ***************** AC_MSG_RESULT([]) AC_MSG_RESULT([$PACKAGE configuration:]) AC_MSG_RESULT([ Version = ${VERSION}]) -AC_MSG_RESULT([ Build Version = 204f146196774ded1581aed1b6acd0d562b4f958]) +AC_MSG_RESULT([ Build Version = 72b4771db9437c36931c0f673210f6fe6ed4f8ed]) AC_MSG_RESULT([]) AC_MSG_RESULT([ Prefix = ${prefix}]) AC_MSG_RESULT([ Executables = ${sbindir}]) diff --git a/doc/dev-guides/writing-python-agents.md b/doc/dev-guides/writing-python-agents.md index f26313f..1b05e23 100644 --- a/doc/dev-guides/writing-python-agents.md +++ b/doc/dev-guides/writing-python-agents.md @@ -5,8 +5,7 @@ A simple library for authoring resource agents in Python is provided in the `ocf.py` library. -Agents written in Python should be ideally compatible both with Python -2.7+ and Python 3.3+. +Agents written in Python should be compatible with Python 3.6+. The library provides various helper constants and functions, a logging implementation as well as a run loop and metadata generation facility. @@ -53,7 +52,11 @@ logger.error("Something went terribly wrong.") * `ocf_exit_reason`: Prints the exit error string to stderr. * `have_binary`: Returns True if the given binary is available. * `is_true`: Converts an OCF truth value to a Python boolean. +* `is_probe`: Returns True when running a probe action. Used to return + OCF_NOT_RUNNING instead of error code that would cause unexpected actions + like fencing before starting the resource or when it is disabled. * `get_parameter`: Looks up the matching `OCF_RESKEY_` environment variable. +* `distro`: Returns <Distro>/<Version> or <Distro> if version info is unavailable. * `Agent`: Class which helps to generate the XML metadata. * `run`: OCF run loop implementation. diff --git a/heartbeat/Delay b/heartbeat/Delay index 5aa8f46..c96da0e 100755 --- a/heartbeat/Delay +++ b/heartbeat/Delay @@ -4,22 +4,9 @@ # Support: users@clusterlabs.org # License: GNU General Public License (GPL) # -# This script is a test resource for introducing delay. +# This script is a resource for introducing a delay. # -# usage: $0 {start|stop|status|monitor|meta-data} -# -# OCF parameters are as below: -# OCF_RESKEY_startdelay -# OCF_RESKEY_stopdelay -# OCF_RESKEY_mondelay -# -# -# OCF_RESKEY_startdelay defaults to 20 (seconds) -# OCF_RESKEY_stopdelay defaults to $OCF_RESKEY_startdelay -# OCF_RESKEY_mondelay defaults to $OCF_RESKEY_startdelay -# -# -# This is really a test resource script. +# usage: $0 {start|stop|status|monitor|meta-data} # ####################################################################### @@ -54,7 +41,7 @@ meta_data() { <version>1.0</version> <longdesc lang="en"> -This script is a test resource for introducing delay. +This script is a resource for introducing a delay. </longdesc> <shortdesc lang="en">Waits for a defined timespan</shortdesc> diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem index 0665628..e1378f7 100755 --- a/heartbeat/Filesystem +++ b/heartbeat/Filesystem @@ -704,7 +704,7 @@ timeout_child() { wait $pid ret=$? - # ret would be 127 + child exit code if the timeout expired + # ret would be 127 + child exit code if the timeout expired (see "man wait" for more info) [ $ret -lt 128 ] && kill -s KILL $killer return $ret } diff --git a/heartbeat/IPaddr2 b/heartbeat/IPaddr2 index 97a7431..5f30b8f 100755 --- a/heartbeat/IPaddr2 +++ b/heartbeat/IPaddr2 @@ -624,7 +624,7 @@ find_interface() { # List interfaces but exclude FreeS/WAN ipsecN virtual interfaces # local iface="`$IP2UTIL -o -f $FAMILY addr show \ - | grep "\ $ipaddr/$netmask" \ + | grep " $ipaddr/$netmask" \ | cut -d ' ' -f2 \ | grep -v '^ipsec[0-9][0-9]*$'`" diff --git a/heartbeat/LVM-activate b/heartbeat/LVM-activate index f6f24a3..3858ed8 100755 --- a/heartbeat/LVM-activate +++ b/heartbeat/LVM-activate @@ -448,6 +448,10 @@ systemid_check() { # system_id_source is set in lvm.conf source=$(lvmconfig 'global/system_id_source' 2>/dev/null | cut -d"=" -f2) + + # Is volume_list set in lvm.conf + vol_list=$(lvmconfig 'activation/volume_list' 2>/dev/null | cut -d"=" -f2) + if [ "$source" = "" ] || [ "$source" = "none" ]; then ocf_exit_reason "system_id_source in lvm.conf is not set correctly!" exit $OCF_ERR_ARGS @@ -458,6 +462,11 @@ systemid_check() exit $OCF_ERR_ARGS fi + if [ -n "$source" ] && [ -n "$vol_list" ]; then + ocf_exit_reason "Both system_id_source & volume_list cannot be defined!" + exit $OCF_ERR_ARGS + fi + return $OCF_SUCCESS } diff --git a/heartbeat/SysInfo.in b/heartbeat/SysInfo.in index c57b7b6..8a268d7 100644 --- a/heartbeat/SysInfo.in +++ b/heartbeat/SysInfo.in @@ -119,7 +119,7 @@ UpdateStat() { name=$1; shift value="$*" echo -e "$name:\t$value" - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n $name -v "$value" + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n $name -v "$value" } SysInfoStats() { diff --git a/heartbeat/aws-vpc-move-ip b/heartbeat/aws-vpc-move-ip index dee0403..54806f6 100755 --- a/heartbeat/aws-vpc-move-ip +++ b/heartbeat/aws-vpc-move-ip @@ -36,6 +36,7 @@ # Defaults OCF_RESKEY_awscli_default="/usr/bin/aws" +OCF_RESKEY_auth_type_default="key" OCF_RESKEY_profile_default="default" OCF_RESKEY_region_default="" OCF_RESKEY_ip_default="" @@ -48,6 +49,7 @@ OCF_RESKEY_monapi_default="false" OCF_RESKEY_lookup_type_default="InstanceId" : ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}} +: ${OCF_RESKEY_auth_type=${OCF_RESKEY_auth_type_default}} : ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}} : ${OCF_RESKEY_region=${OCF_RESKEY_region_default}} : ${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}} @@ -58,8 +60,6 @@ OCF_RESKEY_lookup_type_default="InstanceId" : ${OCF_RESKEY_iflabel=${OCF_RESKEY_iflabel_default}} : ${OCF_RESKEY_monapi=${OCF_RESKEY_monapi_default}} : ${OCF_RESKEY_lookup_type=${OCF_RESKEY_lookup_type_default}} - -[ -n "$OCF_RESKEY_region" ] && region_opt="--region $OCF_RESKEY_region" ####################################################################### @@ -83,6 +83,10 @@ cat <<END <longdesc lang="en"> Resource Agent to move IP addresses within a VPC of the Amazon Webservices EC2 by changing an entry in an specific routing table + +Credentials needs to be setup by running "aws configure", or by using AWS Policies. + +See https://aws.amazon.com/cli/ for more information about awscli. </longdesc> <shortdesc lang="en">Move IP within a VPC of the AWS EC2</shortdesc> @@ -95,6 +99,15 @@ Path to command line tools for AWS <content type="string" default="${OCF_RESKEY_awscli_default}" /> </parameter> +<parameter name="auth_type"> +<longdesc lang="en"> +Authentication type "key" for AccessKey and SecretAccessKey set via "aws configure", +or "role" to use AWS Policies. +</longdesc> +<shortdesc lang="en">Authentication type</shortdesc> +<content type="string" default="${OCF_RESKEY_auth_type_default}" /> +</parameter> + <parameter name="profile"> <longdesc lang="en"> Valid AWS CLI profile name (see ~/.aws/config and 'aws configure') @@ -198,7 +211,7 @@ END execute_cmd_as_role(){ cmd=$1 role=$2 - output="$($OCF_RESKEY_awscli sts assume-role --role-arn $role --role-session-name AWSCLI-RouteTableUpdate --profile $OCF_RESKEY_profile $region_opt --output=text)" + output="$($AWSCLI_CMD sts assume-role --role-arn $role --role-session-name AWSCLI-RouteTableUpdate --output=text)" export AWS_ACCESS_KEY_ID="$(echo $output | awk -F" " '$4=="CREDENTIALS" {print $5}')" export AWS_SECRET_ACCESS_KEY="$(echo $output | awk -F" " '$4=="CREDENTIALS" {print $7}')" export AWS_SESSION_TOKEN="$(echo $output | awk -F" " '$4=="CREDENTIALS" {print $8}')" @@ -220,11 +233,11 @@ ec2ip_set_address_param_compat(){ } ec2ip_validate() { - for cmd in $OCF_RESKEY_awscli ip curl; do + for cmd in "$OCF_RESKEY_awscli" ip curl; do check_binary "$cmd" done - if [ -z "$OCF_RESKEY_profile" ]; then + if [ "x${OCF_RESKEY_auth_type}" = "xkey" ] && [ -z "$OCF_RESKEY_profile" ]; then ocf_exit_reason "profile parameter not set" return $OCF_ERR_CONFIGURED fi @@ -262,7 +275,7 @@ ec2ip_monitor() { for rtb in $(echo $OCF_RESKEY_routing_table | sed -e 's/,/ /g'); do ocf_log info "monitor: check routing table (API call) - $rtb" if [ -z "${OCF_RESKEY_routing_table_role}" ]; then - cmd="$OCF_RESKEY_awscli --profile $OCF_RESKEY_profile $region_opt --output text ec2 describe-route-tables --route-table-ids $rtb --query RouteTables[*].Routes[?DestinationCidrBlock=='$OCF_RESKEY_ip/32'].$OCF_RESKEY_lookup_type" + cmd="$AWSCLI_CMD --output text ec2 describe-route-tables --route-table-ids $rtb --query RouteTables[*].Routes[?DestinationCidrBlock=='$OCF_RESKEY_ip/32'].$OCF_RESKEY_lookup_type" ocf_log debug "executing command: $cmd" ROUTE_TO_INSTANCE="$($cmd)" else @@ -368,7 +381,7 @@ ec2ip_get_and_configure() { EC2_NETWORK_INTERFACE_ID="$(ec2ip_get_instance_eni)" for rtb in $(echo $OCF_RESKEY_routing_table | sed -e 's/,/ /g'); do if [ -z "${OCF_RESKEY_routing_table_role}" ]; then - cmd="$OCF_RESKEY_awscli --profile $OCF_RESKEY_profile $region_opt --output text ec2 replace-route --route-table-id $rtb --destination-cidr-block ${OCF_RESKEY_ip}/32 --network-interface-id $EC2_NETWORK_INTERFACE_ID" + cmd="$AWSCLI_CMD --output text ec2 replace-route --route-table-id $rtb --destination-cidr-block ${OCF_RESKEY_ip}/32 --network-interface-id $EC2_NETWORK_INTERFACE_ID" ocf_log debug "executing command: $cmd" $cmd else @@ -475,6 +488,22 @@ if ! ocf_is_root; then exit $OCF_ERR_PERM fi +AWSCLI_CMD="${OCF_RESKEY_awscli}" +if [ "x${OCF_RESKEY_auth_type}" = "xkey" ]; then + AWSCLI_CMD="$AWSCLI_CMD --profile ${OCF_RESKEY_profile}" +elif [ "x${OCF_RESKEY_auth_type}" = "xrole" ]; then + if [ -z "${OCF_RESKEY_region}" ]; then + ocf_exit_reason "region needs to be set when using role-based authentication" + exit $OCF_ERR_CONFIGURED + fi +else + ocf_exit_reason "Incorrect auth_type: ${OCF_RESKEY_auth_type}" + exit $OCF_ERR_CONFIGURED +fi +if [ -n "${OCF_RESKEY_region}" ]; then + AWSCLI_CMD="$AWSCLI_CMD --region ${OCF_RESKEY_region}" +fi + ec2ip_set_address_param_compat ec2ip_validate diff --git a/heartbeat/aws-vpc-route53.in b/heartbeat/aws-vpc-route53.in index 22cbb35..18ab157 100644 --- a/heartbeat/aws-vpc-route53.in +++ b/heartbeat/aws-vpc-route53.in @@ -46,24 +46,22 @@ # Defaults OCF_RESKEY_awscli_default="/usr/bin/aws" +OCF_RESKEY_auth_type_default="key" OCF_RESKEY_profile_default="default" +OCF_RESKEY_region_default="" OCF_RESKEY_hostedzoneid_default="" OCF_RESKEY_fullname_default="" OCF_RESKEY_ip_default="local" OCF_RESKEY_ttl_default=10 : ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}} +: ${OCF_RESKEY_auth_type=${OCF_RESKEY_auth_type_default}} : ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}} +: ${OCF_RESKEY_region=${OCF_RESKEY_region_default}} : ${OCF_RESKEY_hostedzoneid:=${OCF_RESKEY_hostedzoneid_default}} : ${OCF_RESKEY_fullname:=${OCF_RESKEY_fullname_default}} : ${OCF_RESKEY_ip:=${OCF_RESKEY_ip_default}} : ${OCF_RESKEY_ttl:=${OCF_RESKEY_ttl_default}} -####################################################################### - - -AWS_PROFILE_OPT="--profile $OCF_RESKEY_profile --cli-connect-timeout 10" -####################################################################### - usage() { cat <<-EOT @@ -123,6 +121,15 @@ Path to command line tools for AWS <content type="string" default="${OCF_RESKEY_awscli_default}" /> </parameter> +<parameter name="auth_type"> +<longdesc lang="en"> +Authentication type "key" for AccessKey and SecretAccessKey set via "aws configure", +or "role" to use AWS Policies. +</longdesc> +<shortdesc lang="en">Authentication type</shortdesc> +<content type="string" default="${OCF_RESKEY_auth_type_default}" /> +</parameter> + <parameter name="profile"> <longdesc lang="en"> The name of the AWS CLI profile of the root account. This @@ -196,7 +203,7 @@ r53_validate() { # Check for required binaries ocf_log debug "Checking for required binaries" - for command in curl dig; do + for command in "${OCF_RESKEY_awscli}" curl dig; do check_binary "$command" done @@ -216,7 +223,10 @@ r53_validate() { esac # profile - [[ -z "$OCF_RESKEY_profile" ]] && ocf_log error "AWS CLI profile not set $OCF_RESKEY_profile!" && exit $OCF_ERR_CONFIGURED + if [ "x${OCF_RESKEY_auth_type}" = "xkey" ] && [ -z "$OCF_RESKEY_profile" ]; then + ocf_exit_reason "profile parameter not set" + return $OCF_ERR_CONFIGURED + fi # TTL [[ -z "$OCF_RESKEY_ttl" ]] && ocf_log error "TTL not set $OCF_RESKEY_ttl!" && exit $OCF_ERR_CONFIGURED @@ -417,7 +427,6 @@ _update_record() { } ############################################################################### - case $__OCF_ACTION in usage|help) usage @@ -427,6 +436,26 @@ case $__OCF_ACTION in metadata exit $OCF_SUCCESS ;; +esac + +AWSCLI_CMD="${OCF_RESKEY_awscli}" +if [ "x${OCF_RESKEY_auth_type}" = "xkey" ]; then + AWSCLI_CMD="$AWSCLI_CMD --profile ${OCF_RESKEY_profile}" +elif [ "x${OCF_RESKEY_auth_type}" = "xrole" ]; then + if [ -z "${OCF_RESKEY_region}" ]; then + ocf_exit_reason "region needs to be set when using role-based authentication" + exit $OCF_ERR_CONFIGURED + fi +else + ocf_exit_reason "Incorrect auth_type: ${OCF_RESKEY_auth_type}" + exit $OCF_ERR_CONFIGURED +fi +if [ -n "${OCF_RESKEY_region}" ]; then + AWSCLI_CMD="$AWSCLI_CMD --region ${OCF_RESKEY_region}" +fi +AWSCLI_CMD="$AWSCLI_CMD --cli-connect-timeout 10" + +case $__OCF_ACTION in start) r53_validate || exit $? r53_start diff --git a/heartbeat/awseip b/heartbeat/awseip index dc48460..49b0ca6 100755 --- a/heartbeat/awseip +++ b/heartbeat/awseip @@ -23,7 +23,8 @@ # # Prerequisites: # -# - preconfigured AWS CLI running environment (AccessKey, SecretAccessKey, etc.) +# - preconfigured AWS CLI running environment (AccessKey, SecretAccessKey, etc.) or +# (AWSRole) Setup up relevant AWS Policies to allow agent related functions to be executed. # - a reserved secondary private IP address for EC2 instances high availability # - IAM user role with the following permissions: # * DescribeInstances @@ -44,11 +45,15 @@ # Defaults # OCF_RESKEY_awscli_default="/usr/bin/aws" +OCF_RESKEY_auth_type_default="key" OCF_RESKEY_profile_default="default" +OCF_RESKEY_region_default="" OCF_RESKEY_api_delay_default="3" : ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}} +: ${OCF_RESKEY_auth_type=${OCF_RESKEY_auth_type_default}} : ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}} +: ${OCF_RESKEY_region=${OCF_RESKEY_region_default}} : ${OCF_RESKEY_api_delay=${OCF_RESKEY_api_delay_default}} meta_data() { @@ -63,7 +68,7 @@ Resource Agent for Amazon AWS Elastic IP Addresses. It manages AWS Elastic IP Addresses with awscli. -Credentials needs to be setup by running "aws configure". +Credentials needs to be setup by running "aws configure", or by using AWS Policies. See https://aws.amazon.com/cli/ for more information about awscli. </longdesc> @@ -79,6 +84,15 @@ command line tools for aws services <content type="string" default="${OCF_RESKEY_awscli_default}" /> </parameter> +<parameter name="auth_type"> +<longdesc lang="en"> +Authentication type "key" for AccessKey and SecretAccessKey set via "aws configure", +or "role" to use AWS Policies. +</longdesc> +<shortdesc lang="en">Authentication type</shortdesc> +<content type="string" default="${OCF_RESKEY_auth_type_default}" /> +</parameter> + <parameter name="profile"> <longdesc lang="en"> Valid AWS CLI profile name (see ~/.aws/config and 'aws configure') @@ -111,6 +125,14 @@ predefined private ip address for ec2 instance <content type="string" default="" /> </parameter> +<parameter name="region" required="0"> +<longdesc lang="en"> +Region for AWS resource (required for role-based authentication) +</longdesc> +<shortdesc lang="en">Region</shortdesc> +<content type="string" default="${OCF_RESKEY_region_default}" /> +</parameter> + <parameter name="api_delay" unique="0"> <longdesc lang="en"> a short delay between API calls, to avoid sending API too quick @@ -157,13 +179,13 @@ awseip_start() { NETWORK_ID=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC}/interface-id -H "X-aws-ec2-metadata-token: $TOKEN") fi done - $AWSCLI --profile $OCF_RESKEY_profile ec2 associate-address \ + $AWSCLI_CMD ec2 associate-address \ --network-interface-id ${NETWORK_ID} \ --allocation-id ${ALLOCATION_ID} \ --private-ip-address ${PRIVATE_IP_ADDRESS} RET=$? else - $AWSCLI --profile $OCF_RESKEY_profile ec2 associate-address \ + $AWSCLI_CMD ec2 associate-address \ --instance-id ${INSTANCE_ID} \ --allocation-id ${ALLOCATION_ID} RET=$? @@ -183,7 +205,7 @@ awseip_start() { awseip_stop() { awseip_monitor || return $OCF_SUCCESS - ASSOCIATION_ID=$($AWSCLI --profile $OCF_RESKEY_profile --output json ec2 describe-addresses \ + ASSOCIATION_ID=$($AWSCLI_CMD --output json ec2 describe-addresses \ --allocation-id ${ALLOCATION_ID} | grep -m 1 "AssociationId" | awk -F'"' '{print$4}') if [ -z "${ASSOCIATION_ID}" ]; then @@ -191,9 +213,7 @@ awseip_stop() { return $OCF_NOT_RUNNING fi - $AWSCLI --profile ${OCF_RESKEY_profile} \ - ec2 disassociate-address \ - --association-id ${ASSOCIATION_ID} + $AWSCLI_CMD ec2 disassociate-address --association-id ${ASSOCIATION_ID} RET=$? # delay to avoid sending request too fast @@ -208,7 +228,7 @@ awseip_stop() { } awseip_monitor() { - $AWSCLI --profile $OCF_RESKEY_profile ec2 describe-instances --instance-id "${INSTANCE_ID}" | grep -q "${ELASTIC_IP}" + $AWSCLI_CMD ec2 describe-instances --instance-id "${INSTANCE_ID}" | grep -q "${ELASTIC_IP}" RET=$? if [ $RET -ne 0 ]; then @@ -218,9 +238,9 @@ awseip_monitor() { } awseip_validate() { - check_binary ${AWSCLI} + check_binary "${OCF_RESKEY_awscli}" - if [ -z "$OCF_RESKEY_profile" ]; then + if [ "x${OCF_RESKEY_auth_type}" = "xkey" ] && [ -z "$OCF_RESKEY_profile" ]; then ocf_exit_reason "profile parameter not set" return $OCF_ERR_CONFIGURED fi @@ -238,9 +258,27 @@ case $__OCF_ACTION in meta_data exit $OCF_SUCCESS ;; -esac + usage|help) + awseip_usage + exit $OCF_SUCCESS + ;; +esac -AWSCLI="${OCF_RESKEY_awscli}" +AWSCLI_CMD="${OCF_RESKEY_awscli}" +if [ "x${OCF_RESKEY_auth_type}" = "xkey" ]; then + AWSCLI_CMD="$AWSCLI_CMD --profile ${OCF_RESKEY_profile}" +elif [ "x${OCF_RESKEY_auth_type}" = "xrole" ]; then + if [ -z "${OCF_RESKEY_region}" ]; then + ocf_exit_reason "region needs to be set when using role-based authentication" + exit $OCF_ERR_CONFIGURED + fi +else + ocf_exit_reason "Incorrect auth_type: ${OCF_RESKEY_auth_type}" + exit $OCF_ERR_CONFIGURED +fi +if [ -n "${OCF_RESKEY_region}" ]; then + AWSCLI_CMD="$AWSCLI_CMD --region ${OCF_RESKEY_region}" +fi ELASTIC_IP="${OCF_RESKEY_elastic_ip}" ALLOCATION_ID="${OCF_RESKEY_allocation_id}" PRIVATE_IP_ADDRESS="${OCF_RESKEY_private_ip_address}" @@ -272,10 +310,6 @@ case $__OCF_ACTION in validate|validate-all) awseip_validate ;; - usage|help) - awseip_usage - exit $OCF_SUCCESS - ;; *) awseip_usage exit $OCF_ERR_UNIMPLEMENTED diff --git a/heartbeat/awsvip b/heartbeat/awsvip index 037278e..bdb4d68 100755 --- a/heartbeat/awsvip +++ b/heartbeat/awsvip @@ -23,7 +23,8 @@ # # Prerequisites: # -# - preconfigured AWS CLI running environment (AccessKey, SecretAccessKey, etc.) +# - preconfigured AWS CLI running environment (AccessKey, SecretAccessKey, etc.) or +# (AWSRole) Setup up relevant AWS Policies to allow agent related functions to be executed. # - a reserved secondary private IP address for EC2 instances high availablity # - IAM user role with the following permissions: # * DescribeInstances @@ -43,11 +44,15 @@ # Defaults # OCF_RESKEY_awscli_default="/usr/bin/aws" +OCF_RESKEY_auth_type_default="key" OCF_RESKEY_profile_default="default" +OCF_RESKEY_region_default="" OCF_RESKEY_api_delay_default="3" : ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}} +: ${OCF_RESKEY_auth_type=${OCF_RESKEY_auth_type_default}} : ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}} +: ${OCF_RESKEY_region=${OCF_RESKEY_region_default}} : ${OCF_RESKEY_api_delay=${OCF_RESKEY_api_delay_default}} meta_data() { @@ -62,7 +67,7 @@ Resource Agent for Amazon AWS Secondary Private IP Addresses. It manages AWS Secondary Private IP Addresses with awscli. -Credentials needs to be setup by running "aws configure". +Credentials needs to be setup by running "aws configure", or by using AWS Policies. See https://aws.amazon.com/cli/ for more information about awscli. </longdesc> @@ -78,6 +83,15 @@ command line tools for aws services <content type="string" default="${OCF_RESKEY_awscli_default}" /> </parameter> +<parameter name="auth_type"> +<longdesc lang="en"> +Authentication type "key" for AccessKey and SecretAccessKey set via "aws configure", +or "role" to use AWS Policies. +</longdesc> +<shortdesc lang="en">Authentication type</shortdesc> +<content type="string" default="${OCF_RESKEY_auth_type_default}" /> +</parameter> + <parameter name="profile"> <longdesc lang="en"> Valid AWS CLI profile name (see ~/.aws/config and 'aws configure') @@ -94,6 +108,14 @@ reserved secondary private ip for ec2 instance <content type="string" default="" /> </parameter> +<parameter name="region" required="0"> +<longdesc lang="en"> +Region for AWS resource (required for role-based authentication) +</longdesc> +<shortdesc lang="en">Region</shortdesc> +<content type="string" default="${OCF_RESKEY_region_default}" /> +</parameter> + <parameter name="api_delay" unique="0"> <longdesc lang="en"> a short delay between API calls, to avoid sending API too quick @@ -131,7 +153,7 @@ END awsvip_start() { awsvip_monitor && return $OCF_SUCCESS - $AWSCLI --profile $OCF_RESKEY_profile ec2 assign-private-ip-addresses \ + $AWSCLI_CMD ec2 assign-private-ip-addresses \ --network-interface-id ${NETWORK_ID} \ --private-ip-addresses ${SECONDARY_PRIVATE_IP} \ --allow-reassignment @@ -151,7 +173,7 @@ awsvip_start() { awsvip_stop() { awsvip_monitor || return $OCF_SUCCESS - $AWSCLI --profile $OCF_RESKEY_profile ec2 unassign-private-ip-addresses \ + $AWSCLI_CMD ec2 unassign-private-ip-addresses \ --network-interface-id ${NETWORK_ID} \ --private-ip-addresses ${SECONDARY_PRIVATE_IP} RET=$? @@ -168,7 +190,7 @@ awsvip_stop() { } awsvip_monitor() { - $AWSCLI --profile ${OCF_RESKEY_profile} ec2 describe-instances \ + $AWSCLI_CMD ec2 describe-instances \ --instance-id "${INSTANCE_ID}" \ --query 'Reservations[].Instances[].NetworkInterfaces[].PrivateIpAddresses[].PrivateIpAddress[]' \ --output text | \ @@ -182,9 +204,9 @@ awsvip_monitor() { } awsvip_validate() { - check_binary ${AWSCLI} + check_binary "${OCF_RESKEY_awscli}" - if [ -z "$OCF_RESKEY_profile" ]; then + if [ "x${OCF_RESKEY_auth_type}" = "xkey" ] && [ -z "$OCF_RESKEY_profile" ]; then ocf_exit_reason "profile parameter not set" return $OCF_ERR_CONFIGURED fi @@ -202,9 +224,27 @@ case $__OCF_ACTION in meta_data exit $OCF_SUCCESS ;; + usage|help) + awsvip_usage + exit $OCF_SUCCESS + ;; esac -AWSCLI="${OCF_RESKEY_awscli}" +AWSCLI_CMD="${OCF_RESKEY_awscli}" +if [ "x${OCF_RESKEY_auth_type}" = "xkey" ]; then + AWSCLI_CMD="$AWSCLI_CMD --profile ${OCF_RESKEY_profile}" +elif [ "x${OCF_RESKEY_auth_type}" = "xrole" ]; then + if [ -z "${OCF_RESKEY_region}" ]; then + ocf_exit_reason "region needs to be set when using role-based authentication" + exit $OCF_ERR_CONFIGURED + fi +else + ocf_exit_reason "Incorrect auth_type: ${OCF_RESKEY_auth_type}" + exit $OCF_ERR_CONFIGURED +fi +if [ -n "${OCF_RESKEY_region}" ]; then + AWSCLI_CMD="$AWSCLI_CMD --region ${OCF_RESKEY_region}" +fi SECONDARY_PRIVATE_IP="${OCF_RESKEY_secondary_private_ip}" TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id -H "X-aws-ec2-metadata-token: $TOKEN") @@ -236,10 +276,6 @@ case $__OCF_ACTION in validate|validate-all) awsvip_validate ;; - usage|help) - awsvip_usage - exit $OCF_SUCCESS - ;; *) awsvip_usage exit $OCF_ERR_UNIMPLEMENTED diff --git a/heartbeat/azure-lb b/heartbeat/azure-lb index 7f585bf..198e71c 100755 --- a/heartbeat/azure-lb +++ b/heartbeat/azure-lb @@ -114,7 +114,7 @@ lb_start() { cmd="$OCF_RESKEY_nc -l -k $OCF_RESKEY_port" if [ $( basename $OCF_RESKEY_nc ) = 'socat' ]; then #socat has different parameters - cmd="$OCF_RESKEY_nc -U TCP-LISTEN:$OCF_RESKEY_port,backlog=10,fork,reuseaddr /dev/null" + cmd="$OCF_RESKEY_nc -U TCP6-LISTEN:$OCF_RESKEY_port,backlog=10,fork,reuseaddr /dev/null" fi if ! lb_monitor; then ocf_log debug "Starting $process: $cmd" diff --git a/heartbeat/db2 b/heartbeat/db2 index 95447ab..1cd66f1 100755 --- a/heartbeat/db2 +++ b/heartbeat/db2 @@ -848,7 +848,7 @@ db2_notify() { # only interested in pre-start [ $OCF_RESKEY_CRM_meta_notify_type = pre \ - -a $OCF_RESKEY_CRM_meta_notify_operation = start ] || return $OCF_SUCESS + -a $OCF_RESKEY_CRM_meta_notify_operation = start ] || return $OCF_SUCCESS # gets FIRST_ACTIVE_LOG db2_get_cfg $dblist || return $? diff --git a/heartbeat/docker b/heartbeat/docker index 2adcade..50523db 100755 --- a/heartbeat/docker +++ b/heartbeat/docker @@ -293,8 +293,8 @@ docker_simple_status() VERSION_OUT=$(docker version) version_ret=$? if [ $version_ret -eq 1 ]; then - ocf_exit_reason "Docker service is in error state while checking for ${CONTAINER}, based on image, ${OCF_RESKEY_image}: ${VERSION_OUT}" - return $OCF_ERR_GENERIC + ocf_log err "Docker service is not running or in error state while checking for ${CONTAINER}, based on image, ${OCF_RESKEY_image}: ${VERSION_OUT}" + return $OCF_NOT_RUNNING fi container_exists diff --git a/heartbeat/findif.sh b/heartbeat/findif.sh index 5f1c19e..13484f8 100644 --- a/heartbeat/findif.sh +++ b/heartbeat/findif.sh @@ -29,10 +29,10 @@ prefixcheck() { fi return 0 } -getnetworkinfo() +getloopbackinfo() { local line netinfo - ip -o -f inet route list match $OCF_RESKEY_ip scope host | (while read line; + ip -o -f inet route list match $OCF_RESKEY_ip table local scope host | (while read line; do netinfo=`echo $line | awk '{print $2}'` case $netinfo in @@ -215,14 +215,14 @@ findif() fi if [ -n "$nic" ] ; then # NIC supports more than two. - set -- $(ip -o -f $family route list match $match $scope | grep "dev $nic " | awk 'BEGIN{best=0} /\// { mask=$1; sub(".*/", "", mask); if( int(mask)>=best ) { best=int(mask); best_ln=$0; } } END{print best_ln}') + set -- $(ip -o -f $family route list match $match $scope | grep "dev $nic " | sed -e 's,^\([0-9.]\+\) ,\1/32 ,;s,^\([0-9a-f:]\+\) ,\1/128 ,' | sort -t/ -k2,2nr) else - set -- $(ip -o -f $family route list match $match $scope | awk 'BEGIN{best=0} /\// { mask=$1; sub(".*/", "", mask); if( int(mask)>=best ) { best=int(mask); best_ln=$0; } } END{print best_ln}') + set -- $(ip -o -f $family route list match $match $scope | sed -e 's,^\([0-9.]\+\) ,\1/32 ,;s,^\([0-9a-f:]\+\) ,\1/128 ,' | sort -t/ -k2,2nr) fi if [ $# = 0 ] ; then case $OCF_RESKEY_ip in 127.*) - set -- `getnetworkinfo` + set -- `getloopbackinfo` shift;; esac fi diff --git a/heartbeat/galera.in b/heartbeat/galera.in index 6aed3e4..b518595 100755 --- a/heartbeat/galera.in +++ b/heartbeat/galera.in @@ -822,6 +822,11 @@ galera_promote() return $rc fi + # At this point, the mysql pidfile is created on disk and the + # mysql server is reacheable via its UNIX socket. If we are a + # joiner, SST transfers (rsync) have finished, but an IST may + # still be requested or ongoing + galera_monitor rc=$? if [ $rc != $OCF_SUCCESS -a $rc != $OCF_RUNNING_MASTER ]; then @@ -835,12 +840,6 @@ galera_promote() return $OCF_ERR_GENERIC fi - is_primary - if [ $? -ne 0 ]; then - ocf_exit_reason "Failure. Master instance started, but is not in Primary mode." - return $OCF_ERR_GENERIC - fi - if ocf_is_true $bootstrap; then promote_everyone clear_bootstrap_node @@ -991,8 +990,18 @@ galera_monitor() fi rc=$OCF_RUNNING_MASTER else - ocf_exit_reason "local node <${NODENAME}> is started, but not in primary mode. Unknown state." - rc=$OCF_ERR_GENERIC + # It seems that with recent galera (26.4+), a joiner that is + # connected to a Primary component and is preparing its IST + # request might still temporarily report its state as + # Non-Primary. Do not fail in this case as the promote + # operation will loop until the IST finishes or the promote + # times out. + if [ "$__OCF_ACTION" = "promote" ] && ! ocf_is_true $(is_bootstrap); then + ocf_log info "local node <${NODENAME}> is receiving a State Transfer." + else + ocf_exit_reason "local node <${NODENAME}> is started, but not in primary mode. Unknown state." + rc=$OCF_ERR_GENERIC + fi fi return $rc diff --git a/heartbeat/lxd-info.in b/heartbeat/lxd-info.in index f9fb44a..88b15e5 100644 --- a/heartbeat/lxd-info.in +++ b/heartbeat/lxd-info.in @@ -89,7 +89,7 @@ END LXDInfoStats() { value=$(lxc list|grep -ci RUNNING) echo -e "lxd_containers:\t$value" - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n lxd_containers -v $value + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n lxd_containers -v $value } LXDInfo_usage() { @@ -108,7 +108,7 @@ LXDInfo_start() { LXDInfo_stop() { rm -f $OCF_RESKEY_pidfile - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -S state -n lxd_containers + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n lxd_containers exit $OCF_SUCCESS } diff --git a/heartbeat/machine-info.in b/heartbeat/machine-info.in index bfa7ce5..6bd328a 100644 --- a/heartbeat/machine-info.in +++ b/heartbeat/machine-info.in @@ -90,7 +90,7 @@ END MachineInfoStats() { value=$(machinectl|awk '/machines listed/ {print $1}') echo -e "machines:\t$value" - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n machines -v $value + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n machines -v $value } MachineInfo_usage() { @@ -109,7 +109,7 @@ MachineInfo_start() { MachineInfo_stop() { rm -f $OCF_RESKEY_pidfile - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -S state -n machines + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n machines exit $OCF_SUCCESS } diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver index 8838195..5793d7a 100755 --- a/heartbeat/nfsserver +++ b/heartbeat/nfsserver @@ -711,8 +711,17 @@ inject_unshare_uts_name_into_systemd_units () test -d "$dir" || mkdir -p "$dir" test -e "$dropin" && rm -f "$dropin" - # NOTE: additional ExecStart= might exist in the drop-in files, eg. openSUSE - edited_exec_start=$(systemctl cat $svc | sed -ne "s#^ExecStart=\\([-+:!@]*\\)\\(.\+\\)#ExecStart=\\1/usr/bin/unshare --uts /bin/sh -c 'hostname \${NFS_SERVER_SCOPE}; exec \"\$@\"' -- \\2#p" | tail -1) + # NOTE: multiple ExecStart may exist, + # even additional `ExecStart=` to reset the list might exist in the drop-in files. + # We are interested in only the "currently relevant" set of ExecStart. + local unshare_uts_set_hostname='/usr/bin/unshare --uts /bin/sh -c '\''hostname ${NFS_SERVER_SCOPE}; exec "$@"'\'' -- ' + edited_exec_start=$(systemctl cat $svc \ + | sed -n \ + -e '/^ExecStart=/ H;' \ + -e '/^ExecStart=[[:space:]]*$/ {s/.*//;h};' \ + -e '${g;s/^\n//;p}' \ + | sed -e 's#^\(ExecStart=[-+:!@]*\)\(.\+\)#\1'"$unshare_uts_set_hostname"'\2#' + ) cat > "$dropin" <<___ [Service] diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in index 6852163..a617e00 100644 --- a/heartbeat/ocf-shellfuncs.in +++ b/heartbeat/ocf-shellfuncs.in @@ -22,7 +22,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# Build version: 204f146196774ded1581aed1b6acd0d562b4f958 +# Build version: 72b4771db9437c36931c0f673210f6fe6ed4f8ed # TODO: Some of this should probably split out into a generic OCF # library for shell scripts, but for the time being, we'll just use it diff --git a/heartbeat/ocivip b/heartbeat/ocivip index 053646d..f146807 100755 --- a/heartbeat/ocivip +++ b/heartbeat/ocivip @@ -221,7 +221,7 @@ SECONDARY_PRIVATE_IP="${OCF_RESKEY_secondary_private_ip}" CIDR_NETMASK="${OCF_RESKEY_cidr_netmask}" INTERFACE_ALIAS="${OCF_RESKEY_interface_alias}" VNIC_ID="$(curl -s -H "Authorization: Bearer Oracle" -L http://169.254.169.254/opc/v2/vnics/ | jq -r '.[0].vnicId')" -PRIMARY_IFACE=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)') +PRIMARY_IFACE=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -n1) case $__OCF_ACTION in start) diff --git a/heartbeat/openstack-floating-ip b/heartbeat/openstack-floating-ip index 7317f19..a7c0728 100755 --- a/heartbeat/openstack-floating-ip +++ b/heartbeat/openstack-floating-ip @@ -143,13 +143,13 @@ osflip_monitor() { for port in $node_port_ids ; do if echo "$result" | grep -q $port ; then floating_ip=$(echo "$result" | awk '/floating_ip_address/ {print $2}') - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n openstack_floating_ip -v $floating_ip + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_floating_ip -v $floating_ip return $OCF_SUCCESS fi done - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -S state -n openstack_floating_ip + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_floating_ip ocf_log warn "$OCF_RESKEY_ip_id is not attached to any fixed address" return $OCF_NOT_RUNNING } diff --git a/heartbeat/openstack-info.in b/heartbeat/openstack-info.in index 6502f1d..876e833 100755 --- a/heartbeat/openstack-info.in +++ b/heartbeat/openstack-info.in @@ -164,10 +164,12 @@ OSInfoStats() { --format json \ --column fixed_ips \ ${port_id}") - subnet_id=$(echo "$subnet_result" | + subnet_ids=$(echo "$subnet_result" | grep -P '\"subnet_id\": \".*\",$' | grep -P -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}') - value="${value}${subnet_id}:${port_id}," + for subnet_id in $subnet_ids; do + value="${value}${subnet_id}:${port_id}," + done done value=${value%,} diff --git a/heartbeat/openstack-virtual-ip b/heartbeat/openstack-virtual-ip index 361357d..e54926a 100755 --- a/heartbeat/openstack-virtual-ip +++ b/heartbeat/openstack-virtual-ip @@ -137,12 +137,12 @@ osvip_monitor() { --column allowed_address_pairs \ ${node_port_id}") if echo "$result" | grep -q "$OCF_RESKEY_ip"; then - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n openstack_virtual_ip -v $OCF_RESKEY_ip + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_virtual_ip -v $OCF_RESKEY_ip return $OCF_SUCCESS fi - ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -S state -n openstack_virtual_ip + ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_virtual_ip ocf_log warn "$OCF_RESKEY_ip is not attached to any fixed address" return $OCF_NOT_RUNNING } diff --git a/heartbeat/portblock b/heartbeat/portblock index 06fcc19..e88ecc2 100755 --- a/heartbeat/portblock +++ b/heartbeat/portblock @@ -266,7 +266,14 @@ active_grep_pat() local src=$3 local dst=$any fi - echo "^DROP${w}${1}${w}--${w}${src}${w}${dst}${w}multiport${w}${4}ports${w}${2}$" + # iptables 1.8.9 briefly broke the output format, returning the + # numeric protocol value instead of a string. Support both variants. + if [ "$1" = "tcp" ]; then + local prot="(tcp|6)" + else + local prot="(udp|17)" + fi + echo "^DROP${w}${prot}${w}--${w}${src}${w}${dst}${w}multiport${w}${4}ports${w}${2}$" } #chain_isactive {udp|tcp} portno,portno ip chain @@ -274,7 +281,7 @@ chain_isactive() { [ "$4" = "OUTPUT" ] && ds="s" || ds="d" PAT=$(active_grep_pat "$1" "$2" "$3" "$ds") - $IPTABLES $wait -n -L "$4" | grep "$PAT" >/dev/null + $IPTABLES $wait -n -L "$4" | grep -qE "$PAT" } # netstat -tn and ss -Htn, split on whitespace and colon, @@ -321,7 +328,6 @@ save_tcp_connections() tickle_remote() { [ -z "$OCF_RESKEY_tickle_dir" ] && return - echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle f=$OCF_RESKEY_tickle_dir/$OCF_RESKEY_ip [ -r $f ] || return $TICKLETCP -n 3 < $f diff --git a/resource-agents.spec.in b/resource-agents.spec.in index 1cbf28c..930db6d 100644 --- a/resource-agents.spec.in +++ b/resource-agents.spec.in @@ -100,7 +100,7 @@ Requires: /usr/sbin/fuser %endif # Filesystem / fs.sh / netfs.sh -%if 0%{?suse_version} +%if 0%{?fedora} > 39 || 0%{?suse_version} Requires: /usr/sbin/fsck %else Requires: /sbin/fsck @@ -141,9 +141,14 @@ Requires: /usr/sbin/ethtool Requires: /sbin/rdisc /usr/sbin/arping /bin/ping /bin/ping6 # nfsexport.sh +%if 0%{?fedora} > 39 +Requires: /usr/sbin/findfs +Requires: /usr/sbin/quotaon /usr/sbin/quotacheck +%else Requires: /sbin/findfs Requires: /sbin/quotaon /sbin/quotacheck %endif +%endif %description A set of scripts to interface with several services to operate in a diff --git a/tools/findif.c b/tools/findif.c index a25395f..ab108a3 100644 --- a/tools/findif.c +++ b/tools/findif.c @@ -669,7 +669,7 @@ main(int argc, char ** argv) { } } - if (netmaskbits) { + if (netmaskbits != NULL && *netmaskbits != EOS) { best_netmask = netmask; }else if (best_netmask == 0L) { /* diff --git a/tools/ocft/exportfs b/tools/ocft/exportfs index 285a4b8..1ec3d4c 100644 --- a/tools/ocft/exportfs +++ b/tools/ocft/exportfs @@ -28,11 +28,6 @@ CASE "check base env" Include prepare AgentRun start OCF_SUCCESS -CASE "check base env: no 'OCF_RESKEY_fsid'" - Include prepare - Env OCF_RESKEY_fsid= - AgentRun start OCF_ERR_CONFIGURED - CASE "check base env: invalid 'OCF_RESKEY_directory'" Include prepare Env OCF_RESKEY_directory=/no_such diff --git a/tools/ocft/exportfs-multidir b/tools/ocft/exportfs-multidir index 00e41f0..ac6d5c7 100644 --- a/tools/ocft/exportfs-multidir +++ b/tools/ocft/exportfs-multidir @@ -28,11 +28,6 @@ CASE "check base env" Include prepare AgentRun start OCF_SUCCESS -CASE "check base env: no 'OCF_RESKEY_fsid'" - Include prepare - Env OCF_RESKEY_fsid= - AgentRun start OCF_ERR_CONFIGURED - CASE "check base env: invalid 'OCF_RESKEY_directory'" Include prepare Env OCF_RESKEY_directory=/no_such diff --git a/tools/storage_mon.c b/tools/storage_mon.c index 1aae29e..a9227ef 100644 --- a/tools/storage_mon.c +++ b/tools/storage_mon.c @@ -382,9 +382,11 @@ static int write_pid_file(const char *pidfile) syslog(LOG_ERR, "Failed to write '%s' to %s: %s", pid, pidfile, strerror(errno)); goto done; } - close(fd); rc = 0; done: + if (fd != -1) { + close(fd); + } if (pid != NULL) { free(pid); } @@ -653,6 +655,7 @@ storage_mon_client(void) int32_t rc; + memset(&response, 0, sizeof(response)); snprintf(ipcs_name, SMON_MAX_IPCSNAME, "storage_mon_%s", attrname); conn = qb_ipcc_connect(ipcs_name, 0); if (conn == NULL) { @@ -663,6 +666,7 @@ storage_mon_client(void) snprintf(request.message, SMON_MAX_MSGSIZE, "%s", SMON_GET_RESULT_COMMAND); request.hdr.id = 0; request.hdr.size = sizeof(struct storage_mon_check_value_req); + response.hdr.id = 0; rc = qb_ipcc_send(conn, &request, request.hdr.size); if (rc < 0) { syslog(LOG_ERR, "qb_ipcc_send error : %d\n", rc); @@ -683,7 +687,11 @@ storage_mon_client(void) /* greater than 0 : monitoring error. */ /* -1 : communication system error. */ /* -2 : Not all checks completed for first device in daemon mode. */ - rc = atoi(response.message); + if (strnlen(response.message, 1)) { + rc = atoi(response.message); + } else { + rc = -1; + } syslog(LOG_DEBUG, "daemon response[%d]: %s \n", response.hdr.id, response.message); |