Hi,
On Thu, Sep 11, 2008 at 04:51:16PM -0500, Jeremy Linton wrote:
> I have updated the synaccess stonith script, to support multiple
> synaccess
> devices and multiple power outlets with the same name. This allows
> redundant power circuits to drive redundant power supplies in the cluster
> nodes. Because the devices can now be chained together this should also
> simplify configuring large clusters.
>
> This version also works around a couple of issues that have been
> discovered with the synaccess devices. More details can be found in the
> appropriate sections (search for sleep) of the script.
>
> Syntactically this version should be a drop in replacement for the
> previous version.
I can't find the previous version. And I can't recall having ever
seen it. Where was it kept?
> The only difference is the ability to specify more than
> one synaccess device in the ip list delimited by spaces or commas. This now
> matches the behavior of some of the other stonith plug-ins.
>
>
> The diff was quite large, so I again both attached and pasted the whole
> script below.
Many thanks for the contribution!
Before we accept it, we have to get (for legal reasons) an
official mail from you that you did it on your own time (if your
contract allows that) or from your boss that the company is happy
with the contribution.
Thanks,
Dejan
>
> #!/bin/bash
> #
> # External STONITH module for synaccess.
> #
> # Copyright (c) 2008 Gresham Enterprise Storage
> # Jeremy Linton <[EMAIL PROTECTED]>
> #
> # 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.
> #
> #
> #
> # The original version only controlled a single synaccess device
> # this version adds the ability to combine multiple devices to control larger
> # clusters, or alternatively to have multiple synaccess devices on different
> power
> # circuits for redundant power supplies.
>
> #
> # This script requires a few things:
> # net-snmp
> # SYNACCESS-MIB.txt
> # the hostnames that are controlled are placed in the "power outlet" "name"
> field.
> # The Synaccess device must have SNMP turned on
> # The script must have the IP/Hostname of the synaccess device passed in via
> "synaccessip"
> #
> # finally, if you are using multiple synaccess devices on different power
> circuits plugged
> # into redundant power ports, you can specify multiple IPs for the
> synaccessip variable.
> # Outlets with the same name on diffrent synaccess devices will be turned
> on/off/reset in parallel.
>
>
> # in order to use this script you must have installed the MIB that came with
> the synaccess device
> # in /usr/share/snmp/mibs/SYNACCESS-MIB.txt or similar. From then on the
> net-snmp utilities
> # are aware of the proper names.
> # if you are having problems detecting the proper power status make sure the
> mib power status reads:
> #outletStatus OBJECT-TYPE
> #SYNTAX INTEGER {
> #off(0),
> #on(1),
> #off(2),
> #on(257),
> #off(256)
> #}
> # Check the synaccess specific mib with
> # snmpwalk -c public -m SYNACCESS-MIB -v 1 x.x.x.x synAcc
>
>
> # default to 5 seconds of sleep time after all the outlets have been turned
> off
> # before we turn them back on
> reset_delay=${reset_delay:-"5"}
> # drop "public" in if the community isn't set
> community=${community:-"public"}
> # rewrite the ip list to accept , or space as a delimiter
> synaccessip=`echo $synaccessip | tr ',' ' '`
>
>
> # commands used to get/set snmp object id (oid) values
> SNMP_GETCOMMAND="/usr/bin/snmpget -c $community -m SYNACCESS-MIB -v 1"
> SNMP_SETCOMMAND="/usr/bin/snmpset -c $community -m SYNACCESS-MIB -v 1"
>
> # pass the IP and then the name
> get_snmp_value()
> {
> device_ip=$1
> oid=$2
> echo `$SNMP_GETCOMMAND $device_ip $oid 2>&1|cut -d: -f4`
> }
>
> # the port name given in the web interface must match the switched port number
> # this discovers all the hostnames set as the outlet name
> discover_hostlist()
> {
> synaccessdeviceip=$1
>
> portcount=`get_snmp_value $synaccessdeviceip
> SYNACCESS-MIB::powerOutletNum.0`
> for ((i=1; $i <= ${portcount:-"0"};i++)); do
> portname=`get_snmp_value $synaccessdeviceip
> SYNACCESS-MIB::outletName.$i`
> if [[ "$portname" && "$portname" != "Undefined" ]]; then
> # only save unique host names
> if [[ !("$hostlist" =~ "$portname ") ]]; then
> hostlist="$hostlist$portname "
> fi
> fi
> done
> }
>
> # this looks up the port number based on the passed hostname, using the power
> outlet name
> get_port_for_host()
> {
> synaccessdeviceip=$1
> hostlookup=$2
>
> portcount=`get_snmp_value $synaccessdeviceip
> SYNACCESS-MIB::powerOutletNum.0`
> if [[ -z "$portcount" ]]; then
> # device isn't responding
> return 0
> else
> ret_code=2 #default to not finding any matching hosts on this device
> for ((i=1; $i <= $portcount ;i++)); do
> portname=`get_snmp_value $synaccessdeviceip
> SYNACCESS-MIB::outletName.$i`
> if [[ "$portname" == "$hostlookup" ]]; then
> echo "$i "
> ret_code=1
> fi
> # the error handling leaves a possible race, if the device dies
> while we are
> # scanning the ports, we just assume the outlet isn't found, if
> this happens
> # and there is more than one synaccess device its possible we
> only set the state
> # for one power rail.
> done
> # if ret_code=2 everything was responding but we didn't find the
> # named port assume it doesn't exist. It could be a configuration error,
> # but we can't tell.
> return $ret_code
> fi
> }
>
> # this sends a ON/OFF/RESET action to the given hostname
> do_port_action()
> {
> synaccessdeviceip=$1
> controlledhost=$2
> newportstate=$3
>
> portnum=`get_port_for_host $synaccessdeviceip $controlledhost`
> portret=$?
> if [[ "$portret" == "1" ]]; then
> for curport in $portnum ; do
> out=`$SNMP_SETCOMMAND $synaccessdeviceip
> "SYNACCESS-MIB::outletAction.$curport" = $newportstate`
> # this sleep is here, because commands fired in rapid succession
> don't always take affect, the
> # snmp values get updated, but the device fails to internally
> trigger on the change
> sleep 1
> #TODO check to see if port was successfuly set
> done
> fi
> return $portret
> }
>
> # this takes the list of synaccess devices, and calls do_port_action for each
> one
> # this makes sure that if there are multiple synaccess devices with a
> particular host plugged
> # in all the outlets are set, this allows multiple circuit configurations
> set_all_ports()
> {
> host_to_update=$1
> new_port_state=$2
>
> failed_to_set_all=0
> set_atleast_one=0
>
> for deviceip in $synaccessip ; do
> do_port_action $deviceip $host_to_update $new_port_state
> port_set_ok=$?
> case $port_set_ok in
> 0)
> # if any of the syanaccess devices fail, then assume
> # that the whole operation failed, this is because we can
> never
> # know if that device may still be providing power on a
> redunant circuit to the
> # machine
> failed_to_set_all=1
> ;;
> 1)
> set_atleast_one=1
> ;;
> 2)
> # this device doesn't have a port configured with the given
> hostname, ignore it
> ;;
> esac
> done
> if [[ "$set_atleast_one" == "0" ]]; then
> # none of the synaccess devices had a port with the given name
> # fail the operation
> failed_to_set_all=1
> fi
> return $failed_to_set_all
> }
>
>
> # Handle script commands
> case $1 in
> gethosts)
> for deviceip in $synaccessip ; do
> discover_hostlist $deviceip
> done
> for h in $hostlist ; do
> echo $h
> done
> exit 0
> ;;
> on)
> set_all_ports $2 1
> exit $?
> ;;
> off)
> set_all_ports $2 2
> exit $?
> ;;
> reset)
> # The synaccess devices have a nice "reboot" function which
> # turns the power off and after a configured length turns
> # it back on. The only problem is that its really a power toggle
> function.
> # If the power is off, then it turns it on, and then back off
> # So, before we use that function, we make sure that the power is
> turned on
> # (which in general it should be)
> # BTW: the setting for the port delay is in the telnet menu, and not in
> the
> # web interface.
> #set_all_ports $2 1
> #set_all_ports $2 3
> #
> # For now the reboot seems to have to many side effects to be truly
> useful
> # instead lets just manually set it off/on
> #
> set_all_ports $2 2 # turn it off
> # wait a few seconds for the power supplies to drain (some have pretty
> long holdup times)
> sleep $reset_delay
> set_all_ports $2 1 # turn it on
> exit $?
> ;;
>
> status)
> # if any of the given devices fail to responed then assume failure
> for deviceip in $synaccessip ; do
> portcount=`get_snmp_value $deviceip
> SYNACCESS-MIB::powerOutletNum.0`
> if [[ -z $portcount ]]; then
> exit 1
> fi
> done
> exit 0
> ;;
> getconfignames)
> echo "synaccessip community"
> exit 0
> ;;
> getinfo-devid)
> echo "synaccess"
> exit 0
> ;;
> getinfo-devname)
> for deviceip in $synaccessip ; do
> synModel=`get_snmp_value $deviceip SYNACCESS-MIB::systemModel.0`
> synName=`get_snmp_value $deviceip SYNACCESS-MIB::systemName.0`
> echo "Synaccess netBooter $synModel $synName"
> done
> exit 0
> ;;
> getinfo-devdescr)
> echo "synaccess netbooter STONITH device"
> exit 0
> ;;
> getinfo-devurl)
> echo "http://www.synaccess-net.com"
> exit 0
> ;;
> getinfo-xml)
> # Parameters (hostname, synaccess IP, synaccess port)
> cat << SAXML
> <parameters>
> <parameter name="synaccessip" unique="1" required="1">
> <content type="string" />
> <shortdesc lang="en">SynaccessIp</shortdesc>
> <longdesc lang="en">The IPs of the synaccess devices controlling the
> hosts</longdesc>
> </parameter>
> <parameter name="community" unique="1" required="0">
> <content type="string" />
> <shortdesc lang="en">Community</shortdesc>
> <longdesc lang="en">The SNMP Community string</longdesc>
> </parameter>
> </parameters>
> SAXML
> exit 0
> ;;
> *)
> exit 1
> ;;
> esac
> #!/bin/bash
> #
> # External STONITH module for synaccess.
> #
> # Copyright (c) 2008 Gresham Enterprise Storage
> # Jeremy Linton <[EMAIL PROTECTED]>
> #
> # 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.
> #
> #
> #
> # The original version only controlled a single synaccess device
> # this version adds the ability to combine multiple devices to control larger
> # clusters, or alternatively to have multiple synaccess devices on different
> power
> # circuits for redundant power supplies.
>
> #
> # This script requires a few things:
> # net-snmp
> # SYNACCESS-MIB.txt
> # the hostnames that are controlled are placed in the "power outlet" "name"
> field.
> # The Synaccess device must have SNMP turned on
> # The script must have the IP/Hostname of the synaccess device passed in via
> "synaccessip"
> #
> # finally, if you are using multiple synaccess devices on different power
> circuits plugged
> # into redundant power ports, you can specify multiple IPs for the
> synaccessip variable.
> # Outlets with the same name on diffrent synaccess devices will be turned
> on/off/reset in parallel.
>
>
> # in order to use this script you must have installed the MIB that came with
> the synaccess device
> # in /usr/share/snmp/mibs/SYNACCESS-MIB.txt or similar. From then on the
> net-snmp utilities
> # are aware of the proper names.
> # if you are having problems detecting the proper power status make sure the
> mib power status reads:
> #outletStatus OBJECT-TYPE
> #SYNTAX INTEGER {
> #off(0),
> #on(1),
> #off(2),
> #on(257),
> #off(256)
> #}
> # Check the synaccess specific mib with
> # snmpwalk -c public -m SYNACCESS-MIB -v 1 x.x.x.x synAcc
>
>
> # default to 5 seconds of sleep time after all the outlets have been turned
> off
> # before we turn them back on
> reset_delay=${reset_delay:-"5"}
> # drop "public" in if the community isn't set
> community=${community:-"public"}
> # rewrite the ip list to accept , or space as a delimiter
> synaccessip=`echo $synaccessip | tr ',' ' '`
>
>
> # commands used to get/set snmp object id (oid) values
> SNMP_GETCOMMAND="/usr/bin/snmpget -c $community -m SYNACCESS-MIB -v 1"
> SNMP_SETCOMMAND="/usr/bin/snmpset -c $community -m SYNACCESS-MIB -v 1"
>
> # pass the IP and then the name
> get_snmp_value()
> {
> device_ip=$1
> oid=$2
> echo `$SNMP_GETCOMMAND $device_ip $oid 2>&1|cut -d: -f4`
> }
>
> # the port name given in the web interface must match the switched port number
> # this discovers all the hostnames set as the outlet name
> discover_hostlist()
> {
> synaccessdeviceip=$1
>
> portcount=`get_snmp_value $synaccessdeviceip
> SYNACCESS-MIB::powerOutletNum.0`
> for ((i=1; $i <= ${portcount:-"0"};i++)); do
> portname=`get_snmp_value $synaccessdeviceip
> SYNACCESS-MIB::outletName.$i`
> if [[ "$portname" && "$portname" != "Undefined" ]]; then
> # only save unique host names
> if [[ !("$hostlist" =~ "$portname ") ]]; then
> hostlist="$hostlist$portname "
> fi
> fi
> done
> }
>
> # this looks up the port number based on the passed hostname, using the power
> outlet name
> get_port_for_host()
> {
> synaccessdeviceip=$1
> hostlookup=$2
>
> portcount=`get_snmp_value $synaccessdeviceip
> SYNACCESS-MIB::powerOutletNum.0`
> if [[ -z "$portcount" ]]; then
> # device isn't responding
> return 0
> else
> ret_code=2 #default to not finding any matching hosts on this device
> for ((i=1; $i <= $portcount ;i++)); do
> portname=`get_snmp_value $synaccessdeviceip
> SYNACCESS-MIB::outletName.$i`
> if [[ "$portname" == "$hostlookup" ]]; then
> echo "$i "
> ret_code=1
> fi
> # the error handling leaves a possible race, if the device dies
> while we are
> # scanning the ports, we just assume the outlet isn't found, if
> this happens
> # and there is more than one synaccess device its possible we
> only set the state
> # for one power rail.
> done
> # if ret_code=2 everything was responding but we didn't find the
> # named port assume it doesn't exist. It could be a configuration error,
> # but we can't tell.
> return $ret_code
> fi
> }
>
> # this sends a ON/OFF/RESET action to the given hostname
> do_port_action()
> {
> synaccessdeviceip=$1
> controlledhost=$2
> newportstate=$3
>
> portnum=`get_port_for_host $synaccessdeviceip $controlledhost`
> portret=$?
> if [[ "$portret" == "1" ]]; then
> for curport in $portnum ; do
> out=`$SNMP_SETCOMMAND $synaccessdeviceip
> "SYNACCESS-MIB::outletAction.$curport" = $newportstate`
> # this sleep is here, because commands fired in rapid succession
> don't always take affect, the
> # snmp values get updated, but the device fails to internally
> trigger on the change
> sleep 1
> #TODO check to see if port was successfuly set
> done
> fi
> return $portret
> }
>
> # this takes the list of synaccess devices, and calls do_port_action for each
> one
> # this makes sure that if there are multiple synaccess devices with a
> particular host plugged
> # in all the outlets are set, this allows multiple circuit configurations
> set_all_ports()
> {
> host_to_update=$1
> new_port_state=$2
>
> failed_to_set_all=0
> set_atleast_one=0
>
> for deviceip in $synaccessip ; do
> do_port_action $deviceip $host_to_update $new_port_state
> port_set_ok=$?
> case $port_set_ok in
> 0)
> # if any of the syanaccess devices fail, then assume
> # that the whole operation failed, this is because we can
> never
> # know if that device may still be providing power on a
> redunant circuit to the
> # machine
> failed_to_set_all=1
> ;;
> 1)
> set_atleast_one=1
> ;;
> 2)
> # this device doesn't have a port configured with the given
> hostname, ignore it
> ;;
> esac
> done
> if [[ "$set_atleast_one" == "0" ]]; then
> # none of the synaccess devices had a port with the given name
> # fail the operation
> failed_to_set_all=1
> fi
> return $failed_to_set_all
> }
>
>
> # Handle script commands
> case $1 in
> gethosts)
> for deviceip in $synaccessip ; do
> discover_hostlist $deviceip
> done
> for h in $hostlist ; do
> echo $h
> done
> exit 0
> ;;
> on)
> set_all_ports $2 1
> exit $?
> ;;
> off)
> set_all_ports $2 2
> exit $?
> ;;
> reset)
> # The synaccess devices have a nice "reboot" function which
> # turns the power off and after a configured length turns
> # it back on. The only problem is that its really a power toggle
> function.
> # If the power is off, then it turns it on, and then back off
> # So, before we use that function, we make sure that the power is
> turned on
> # (which in general it should be)
> # BTW: the setting for the port delay is in the telnet menu, and not in
> the
> # web interface.
> #set_all_ports $2 1
> #set_all_ports $2 3
> #
> # For now the reboot seems to have to many side effects to be truly
> useful
> # instead lets just manually set it off/on
> #
> set_all_ports $2 2 # turn it off
> # wait a few seconds for the power supplies to drain (some have pretty
> long holdup times)
> sleep $reset_delay
> set_all_ports $2 1 # turn it on
> exit $?
> ;;
>
> status)
> # if any of the given devices fail to responed then assume failure
> for deviceip in $synaccessip ; do
> portcount=`get_snmp_value $deviceip
> SYNACCESS-MIB::powerOutletNum.0`
> if [[ -z $portcount ]]; then
> exit 1
> fi
> done
> exit 0
> ;;
> getconfignames)
> echo "synaccessip community"
> exit 0
> ;;
> getinfo-devid)
> echo "synaccess"
> exit 0
> ;;
> getinfo-devname)
> for deviceip in $synaccessip ; do
> synModel=`get_snmp_value $deviceip SYNACCESS-MIB::systemModel.0`
> synName=`get_snmp_value $deviceip SYNACCESS-MIB::systemName.0`
> echo "Synaccess netBooter $synModel $synName"
> done
> exit 0
> ;;
> getinfo-devdescr)
> echo "synaccess netbooter STONITH device"
> exit 0
> ;;
> getinfo-devurl)
> echo "http://www.synaccess-net.com"
> exit 0
> ;;
> getinfo-xml)
> # Parameters (hostname, synaccess IP, synaccess port)
> cat << SAXML
> <parameters>
> <parameter name="synaccessip" unique="1" required="1">
> <content type="string" />
> <shortdesc lang="en">SynaccessIp</shortdesc>
> <longdesc lang="en">The IPs of the synaccess devices controlling the
> hosts</longdesc>
> </parameter>
> <parameter name="community" unique="1" required="0">
> <content type="string" />
> <shortdesc lang="en">Community</shortdesc>
> <longdesc lang="en">The SNMP Community string</longdesc>
> </parameter>
> </parameters>
> SAXML
> exit 0
> ;;
> *)
> exit 1
> ;;
> esac
> _______________________________________________________
> Linux-HA-Dev: [email protected]
> http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
> Home Page: http://linux-ha.org/
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/