HP MC/ServiceGuard

HP MC/ServiceGuard

 
  • HP MC/ServiceGuard
  • Подготовка VG

  • Подготовка VG


    Раздавать SCSI-ID - хостадаптерам старшие (7,6,5...) ДИскам - поменьше, в порядке убывания приоритета (2,1,15,14,13...)

    Название группы: vg[порядковый номер группы][номер стартового узла] Минор - совпадающий с названием. 0x0[номер группы][номер узла]000 первый разряд - обязан быть 0, второй - у всех должен быть разным
    mkdir /dev/vg31 mknod /dev/vg31/group c 64 0x031000 vgcreate /dev/vg31/group /dev/dsk/c1t8d0 /dev/dsk/c1t9d0
    Экспорт группы на другой узел кластера
    vhchange -a n /dev/vg31 # Отключить, иначе не экспортирует vgexport -s -p -m /tmp/vg31 /dev/vg31
          -s - группа будет shared
          -p - preview (оставить оригинал на мете)
          -m mapfile rcp /tmp/vg31 node2:/tmp/vg31 rlogin node2 mkdir /dev/vg31 mknod /dev/vg31/group c 64 0x031000 vgimport -s -m /tmp/vg31 /dev/vg31
    vgchange -c y /dev/vg31 # Отдать кластеру vhchange -a e /dev/vg31 # Активировать vg монопольно vhchange -a n /dev/vg31 # Отключить
    vgchange -c n /dev/vg31 # Забрать у кластера vhchange -a y /dev/vg31 # Активировать vg немонопольно

    Komandy:
    /usr/sbin/cm*
    Generaciya konfigura
    cd /etc/cmcluster
    Wpisat' spisok uzlow w fajl /etc/cmcluster/cmclnodelist mos032 mos034

    klaster nodes packages services - programma, za nalichiem kotoroj klaster sledit. Perezapuskaet, skol'ko zakazano raz, esli ona umerla - paketu delaetsya halt, i on restartuetsya na nowom uzle. Esli w washem pakete net programm, kotorye startuyut w foregraunde, nado napisat' programmku monitor - kotoraya sama za nimi sledit,
    i swom okonchaniembudet goworit' klasteru - paket nado gasit'


    /usr/sbin/cmquerycl -C jj -n mos032 -n mos034
    # ********************************************************************** # ********* HIGH AVAILABILITY CLUSTER CONFIGURATION FILE *************** # ***** For complete details about cluster parameters and how to **** # ***** set them, consult the cmquerycl(1m) manpage or your manual. **** # **********************************************************************
    # Enter a name for this cluster. This name will be used to identify the # cluster when viewing or manipulating it.
    CLUSTER_NAME cluster1

    # Cluster Lock Device Parameters. This is the volume group that # holds the cluster lock which is used to break a cluster formation # tie. This volume group should not be used by any other cluster # as cluster lock device.
    FIRST_CLUSTER_LOCK_VG /dev/vg03

    # Definition of nodes in the cluster. # Repeat node definitions as necessary for additional nodes.
    NODE_NAME mos032
          NETWORK_INTERFACE lan0
          HEARTBEAT_IP 15.188.208.32
          NETWORK_INTERFACE lan1
          FIRST_CLUSTER_LOCK_PV /dev/dsk/c1t9d0 # List of serial device file names # For example: # SERIAL_DEVICE_FILE /dev/tty0p0
    # Possible standby Network Interfaces for lan0: lan1.
    NODE_NAME mos034
          NETWORK_INTERFACE lan0
          HEARTBEAT_IP 15.188.208.34
          NETWORK_INTERFACE lan1
          FIRST_CLUSTER_LOCK_PV /dev/dsk/c0t9d0 # List of serial device file names # For example: # SERIAL_DEVICE_FILE /dev/tty0p0
    # Possible standby Network Interfaces for lan0: lan1.

    # Cluster Timing Parmeters (microseconds).
    HEARTBEAT_INTERVAL 1000000 NODE_TIMEOUT 2000000

    # Configuration/Reconfiguration Timing Parameters (microseconds).
    AUTO_START_TIMEOUT 600000000 NETWORK_POLLING_INTERVAL 2000000
    # Package Configuration Parameters. # Enter the maximum number of packages which will be configured in the cluster. # You can not add packages beyond this limit. # This parameter is required. MAX_CONFIGURED_PACKAGES 0


    # List of cluster aware Volume Groups. These volume groups will # be used by package applications via the vgchange -a e command. # For example: # VOLUME_GROUP /dev/vgdatabase. # VOLUME_GROUP /dev/vg02.
    VOLUME_GROUP /dev/vg03



    cmmakepkg -s paket1.sh cmmakepkg -p paket1.conf

    # ********************************************************************** # ****** HIGH AVAILABILITY PACKAGE CONFIGURATION FILE (template) ******* # ********************************************************************** # ******* Note: This file MUST be edited before it can be used. ******** # * For complete details about package parameters and how to set them, * # * consult the MC/ServiceGuard or MC/LockManager manpages or manuals. * # **********************************************************************
    # Enter a name for this package. This name will be used to identify the # package when viewing or manipulating it. It must be different from # the other configured package names.
    PACKAGE_NAME

    # Enter the failover policy for this package. This policy will be used # to select an adoptive node whenever the package needs to be started. # The default policy unless otherwise specified is CONFIGURED_NODE. # This policy will select nodes in priority order from the list of # NODE_NAME entries specified below. # # The alternative policy is MIN_PACKAGE_NODE. This policy will select # the node, from the list of NODE_NAME entries below, which is # running the least number of packages at the time this package needs # to start.
    FAILOVER_POLICY CONFIGURED_NODE

    # Enter the failback policy for this package. This policy will be used # to determine what action to take when a package is not running on # its primary node and its primary node is capable of running the # package. The default policy unless otherwise specified is MANUAL. # The MANUAL policy means no attempt will be made to move the package # back to its primary node when it is running on an adoptive node. # # The alternative policy is AUTOMATIC. This policy will attempt to # move the package back to its primary node whenever the primary node # is capable of running the package.
    FAILBACK_POLICY MANUAL

    # Enter the names of the nodes configured for this package. Repeat # this line as necessary for additional adoptive nodes. # Order IS relevant. Put the second Adoptive Node AFTER the first # one. # Example : NODE_NAME original_node # NODE_NAME adoptive_node
    NODE_NAME

    # Enter the complete path for the run and halt scripts. In most cases # the run script and halt script specified here will be the same script, # the package control script generated by the cmmakepkg command. This # control script handles the run(ning) and halt(ing) of the package. # If the script has not completed by the specified timeout value, # it will be terminated. The default for each script timeout is # NO_TIMEOUT. Adjust the timeouts as necessary to permit full # execution of each script. # Note: The HALT_SCRIPT_TIMEOUT should be greater than the sum of # all SERVICE_HALT_TIMEOUT specified for all services.
    RUN_SCRIPT RUN_SCRIPT_TIMEOUT NO_TIMEOUT HALT_SCRIPT HALT_SCRIPT_TIMEOUT NO_TIMEOUT

    # Enter the SERVICE_NAME, the SERVICE_FAIL_FAST_ENABLED and the # SERVICE_HALT_TIMEOUT values for this package. Repeat these # three lines as necessary for additional service names. All # service names MUST correspond to the service names used by # cmrunserv and cmhaltserv commands in the run and halt scripts. # # The value for SERVICE_FAIL_FAST_ENABLED can be either YES or # NO. If set to YES, in the event of a service failure, the # cluster software will halt the node on which the service is # running. If SERVICE_FAIL_FAST_ENABLED is not specified, the # default will be NO. # # SERVICE_HALT_TIMEOUT is represented in the number of seconds. # This timeout is used to determine the length of time (in # seconds) the cluster software will wait for the service to # halt before a SIGKILL signal is sent to force the termination # of the service. In the event of a service halt, the cluster # software will first send a SIGTERM signal to terminate the # service. If the service does not halt, after waiting for the # specified SERVICE_HALT_TIMEOUT, the cluster software will send # out the SIGKILL signal to the service to force its termination. # This timeout value should be large enough to allow all cleanup # processes associated with the service to complete. If the # SERVICE_HALT_TIMEOUT is not specified, a zero timeout will be # assumed, meaning the cluster software will not wait at all # before sending the SIGKILL signal to halt the service. # # Example: SERVICE_NAME DB_SERVICE # SERVICE_FAIL_FAST_ENABLED NO # SERVICE_HALT_TIMEOUT 300 # # To configure a service, uncomment the following lines and # fill in the values for all of the keywords. # #SERVICE_NAME #SERVICE_FAIL_FAST_ENABLED #SERVICE_HALT_TIMEOUT

    # Enter the network subnet name that is to be monitored for this package. # Repeat this line as necessary for additional subnet names. If any of # the subnets defined goes down, the package will be switched to another # node that is configured for this package and has all the defined subnets # available.
    #SUBNET

    # The following keywords (RESOURCE_NAME, RESOURCE_POLLING_INTERVAL, and # RESOURCE_UP_VALUE) are used to specify Package Resource Dependencies. To # define a Package Resource Dependency, a RESOURCE_NAME line with a fully # qualified resource path name, and one or more RESOURCE_UP_VALUE lines are # required. A RESOURCE_POLLING_INTERVAL line (how often in seconds the resource # is to be monitored) is optional and defaults to 60 seconds. An operator and # a value are used with RESOURCE_UP_VALUE to define when the resource is to be # considered up. The operators are =, !=, >, <, >=, and <=, depending on the # type of value. Values can be string or numeric. If the type is string, then # only = and != are valid operators. If the string contains whitespace, it # must be enclosed in quotes. String values are case sensitive. For example, # # Resource is up when its value is # -------------------------------- # RESOURCE_UP_VALUE = UP "UP" # RESOURCE_UP_VALUE != DOWN Any value except "DOWN" # RESOURCE_UP_VALUE = "On Course" "On Course" # # If the type is numeric, then it can specify a threshold, or a range to # define a resource up condition. If it is a threshold, then any operator # may be used. If a range is to be specified, then only > or >= may be used # for the first operator, and only < or <= may be used for the second operator. # For example, # Resource is up when its value is # -------------------------------- # RESOURCE_UP_VALUE = 5 5 (threshold) # RESOURCE_UP_VALUE > 5.1 greater than 5.1 (threshold) # RESOURCE_UP_VALUE > -5 and < 10 between -5 and 10 (range) # # Note that "and" is required between the lower limit and upper limit # when specifying a range. The upper limit must be greater than the lower # limit. If RESOURCE_UP_VALUE is repeated within a RESOURCE_NAME block, then # they are inclusively OR'd together. Package Resource Dependencies may be # defined by repeating the entire RESOURCE_NAME block. # # Example : RESOURCE_NAME /net/interfaces/lan/status/lan0 # RESOURCE_POLLING_INTERVAL 120 # RESOURCE_UP_VALUE = RUNNING # RESOURCE_UP_VALUE = ONLINE # # Means that the value of resource /net/interfaces/lan/status/lan0 # will be checked every 120 seconds, and is considered to # be 'up' when its value is "RUNNING" or "ONLINE". # # Uncomment the following lines to specify Package Resource Dependencies. # #RESOURCE_NAME #RESOURCE_POLLING_INTERVAL #RESOURCE_UP_VALUE [and ]

    # The default for PKG_SWITCHING_ENABLED is YES. In the event of a # failure, this permits the cluster software to transfer the package # to an adoptive node. Adjust as necessary.
    PKG_SWITCHING_ENABLED YES

    # The default for NET_SWITCHING_ENABLED is YES. In the event of a # failure, this permits the cluster software to switch LANs locally # (transfer to a standby LAN card). Adjust as necessary.
    NET_SWITCHING_ENABLED YES

    # The default for NODE_FAIL_FAST_ENABLED is NO. If set to YES, # in the event of a failure, the cluster software will halt the node # on which the package is running. Adjust as necessary.
    NODE_FAIL_FAST_ENABLED NO
    cmcheckconf -C jj -P paket1.conf -P paket2.conf
    Sozdanie gologo klastera
    cmaplyconf -C jj cmruncl cmview -v cmhaltnode mos032 cmrunnode mos032 cmhaltcl
    Dobawlenie ili modifikaciya imeyushegosya paketa cmcheckconf -P paket1.conf cmaplyconf -P paket1.conf
    Ah, da, wse skripty obyazatel'no kopirowat' po wsem uzlam klastera
    cmhaltpkg paket1
    posle ostanowki paket awtomaticheski disablitsq na uzle, de on umer, dlq obratnogo enablirowaniq paketa:
    cmmodpkg -e paket1 cmmodpkg -n mos032 -e paket1 cmmodpkg -n mos034 -e paket1
    cmrunpkg [ -n mos032 ] paket1

    Prosmotr statusa klastera

    CLUSTER STATUS karelia up

          NODE STATUS STATE
          mos031 up running

          Network_Parameters:
          INTERFACE STATUS PATH NAME
          PRIMARY up 8/16/6 lan0
          STANDBY up 8/20/5/8 lan1

          PACKAGE STATUS STATE PKG_SWITCH NODE
          pkg28162 up running enabled mos031

          Policy_Parameters:
          POLICY_NAME CONFIGURED_VALUE
          Failover configured_node
          Failback automatic

          Script_Parameters:
          ITEM STATUS MAX_RESTARTS RESTARTS NAME
          Service up 3 0 qwerty
          Subnet up 15.188.208.0
          Resource up /system/filesystem/availMb/home
          Resource up /cluster/localNode/status/karelia

          Node_Switching_Parameters:
          NODE_TYPE STATUS SWITCHING NAME
          Primary up enabled mos031 (current)
          Alternate up enabled mos033

          NODE STATUS STATE
          mos033 up running

          Network_Parameters:
          INTERFACE STATUS PATH NAME
          PRIMARY up 8/16/6 lan0
          STANDBY up 8/20/5/8 lan1

          PACKAGE STATUS STATE PKG_SWITCH NODE
          nc starting starting enabled mos033

          Policy_Parameters:
          POLICY_NAME CONFIGURED_VALUE
          Failover configured_node
          Failback automatic

          Script_Parameters:
          ITEM STATUS MAX_RESTARTS RESTARTS NAME
          Service up 0 0 nc
          Subnet up 15.188.208.0
          Resource up /system/filesystem/availMb/home

          Node_Switching_Parameters:
          NODE_TYPE STATUS SWITCHING NAME
          Primary up enabled mos033 (current)
          Alternate up enabled mos031
    udalenie paketa
    cmdeleteconf -P paket2
    /usr/sbin/cmapplyconf /usr/sbin/cmhaltserv /usr/sbin/cmrunnode /usr/sbin/cmcheckconf /usr/sbin/cmmakepkg /usr/sbin/cmrunpkg /usr/sbin/cmdeleteconf /usr/sbin/cmmigrate /usr/sbin/cmrunserv /usr/sbin/cmgetconf /usr/sbin/cmmodnet /usr/sbin/cmscancl /usr/sbin/cmhaltcl /usr/sbin/cmmodpkg /usr/sbin/cmviewcl /usr/sbin/cmhaltnode /usr/sbin/cmquerycl /usr/sbin/cmviewconf /usr/sbin/cmhaltpkg /usr/sbin/cmruncl
    Prosmotr debaga
    tail -f /var/adm/syslog/syslog.log
    tail -f /etc/cmcluster/paket1.sh.log

    Obrashenie s resursami:
    Prosmotret' spiski dostupnyh resursow resls /net/interfaces/lan/status
    prosmotret' ih znachenie ya ne znayu kak
    poluchit' nastoyashie konfigurniki iz klastera
    cmgetconf -c cluster_name output_filename cmgetconf -p package_name output_filename #"(#) A.11.05 $Revision: 82.3 $ $Date: 98/11/03 10:56:49 $" # ********************************************************************** # * * # * HIGH AVAILABILITY PACKAGE CONTROL SCRIPT (template) * # * * # * Note: This file MUST be edited before it can be used. * # * * # **********************************************************************
    # UNCOMMENT the variables as you set them.
    # Set PATH to reference the appropriate directories. PATH=/sbin:/usr/bin:/usr/sbin:/etc:/bin
    # VOLUME GROUP ACTIVATION: # Specify the method of activation for volume groups. # Leave the default ("VGCHANGE="vgchange -a e") if you want volume # groups activated in exclusive mode. This assumes the volume groups have # been initialized with 'vgchange -c y' at the time of creation. # # Uncomment the first line (VGCHANGE="vgchange -a e -q n"), and comment # out the default, if your disks are mirrored on separate physical paths, # # Uncomment the second line (VGCHANGE="vgchange -a e -q n -s"), and comment # out the default, if your disks are mirrored on separate physical paths, # and you want the mirror resynchronization to ocurr in parallel with # the package startup. # # Uncomment the third line (VGCHANGE="vgchange -a y") if you wish to # use non-exclusive activation mode. Single node cluster configurations # must use non-exclusive activation. # # VGCHANGE="vgchange -a e -q n" # VGCHANGE="vgchange -a e -q n -s" # VGCHANGE="vgchange -a y" VGCHANGE="vgchange -a e" # Default
    # VOLUME GROUPS # Specify which volume groups are used by this package. Uncomment VG[0]="" # and fill in the name of your first volume group. You must begin with # VG[0], and increment the list in sequence. # # For example, if this package uses your volume groups vg01 and vg02, enter: # VG[0]=vg01 # VG[1]=vg02 # # The volume group activation method is defined above. The filesystems # associated with these volume groups are specified below. # #VG[0]=""
    # FILESYSTEMS # Specify the filesystems which are used by this package. Uncomment # LV[0]=""; FS[0]=""; FS_MOUNT_OPT[0]="" and fill in the name of your first # logical volume, filesystem and mount option for the file system. You must # begin with LV[0], FS[0] and FS_MOUNT_OPT[0] and increment the list in # sequence. # # For example, if this package uses the file systems pkg1a and pkg1b, # which are mounted on the logical volumes lvol1 and lvol2 with read and # write options enter: # LV[0]=/dev/vg01/lvol1; FS[0]=/pkg1a; FS_MOUNT_OPT[0]="-o rw" # LV[1]=/dev/vg01/lvol2; FS[1]=/pkg1b; FS_MOUNT_OPT[1]="-o rw" # # The filesystems are defined as triplets of entries specifying the logical # volume, the mount point and the mount options for the file system. Each # filesystem will be fsck'd prior to being mounted. The filesystems will be # mounted in the order specified during package startup and will be unmounted # in reverse order during package shutdown. Ensure that volume groups # referenced by the logical volume definitions below are included in # volume group definitions above. # #LV[0]=""; FS[0]=""; FS_MOUNT_OPT[0]=""
    # FILESYSTEM UNMOUNT COUNT # Specify the number of unmount attempts for each filesystem during package # shutdown. The default is set to 1. LV_UMOUNT_COUNT=1
    # IP ADDRESSES # Specify the IP and Subnet address pairs which are used by this package. # Uncomment IP[0]="" and SUBNET[0]="" and fill in the name of your first # IP and subnet address. You must begin with IP[0] and SUBNET[0] and # increment the list in sequence. # # For example, if this package uses an IP of 192.10.25.12 and a subnet of # 192.10.25.0 enter: # IP[0]=192.10.25.12 # SUBNET[0]=192.10.25.0 # (netmask=255.255.255.0) # # Hint: Run "netstat -i" to see the available subnets in the Network field. # # IP/Subnet address pairs for each IP address you want to add to a subnet # interface card. Must be set in pairs, even for IP addresses on the same # subnet. # #IP[0]="" #SUBNET[0]=""
    # SERVICE NAMES AND COMMANDS. # Specify the service name, command, and restart parameters which are # used by this package. Uncomment SERVICE_NAME[0]="", SERVICE_CMD[0]="", # SERVICE_RESTART[0]="" and fill in the name of the first service, command, # and restart parameters. You must begin with SERVICE_NAME[0], SERVICE_CMD[0], # and SERVICE_RESTART[0] and increment the list in sequence. # # For example: # SERVICE_NAME[0]=pkg1a # SERVICE_CMD[0]="/usr/bin/X11/xclock -display 192.10.25.54:0" # SERVICE_RESTART[0]="" # Will not restart the service. # # SERVICE_NAME[1]=pkg1b # SERVICE_CMD[1]="/usr/bin/X11/xload -display 192.10.25.54:0" # SERVICE_RESTART[1]="-r 2" # Will restart the service twice. # # SERVICE_NAME[2]=pkg1c # SERVICE_CMD[2]="/usr/sbin/ping" # SERVICE_RESTART[2]="-R" # Will restart the service an infinite # number of times. # # Note: No environmental variables will be passed to the command, this # includes the PATH variable. Absolute path names are required for the # service command definition. Default shell is /usr/bin/sh. # #SERVICE_NAME[0]="" #SERVICE_CMD[0]="" #SERVICE_RESTART[0]=""
    # DTC manager information for each DTC. # Example: DTC[0]=dtc_20 #DTC_NAME[0]=

    # START OF CUSTOMER DEFINED FUNCTIONS
    # This function is a place holder for customer define functions. # You should define all actions you want to happen here, before the service is # started. You can create as many functions as you need.
    function customer_defined_run_cmds { # ADD customer defined run commands. : # do nothing instruction, because a function must contain some command.
    test_return 51 }
    # This function is a place holder for customer define functions. # You should define all actions you want to happen here, before the service is # halted.
    function customer_defined_halt_cmds { # ADD customer defined halt commands. : # do nothing instruction, because a function must contain some command. test_return 52 }
    # END OF CUSTOMER DEFINED FUNCTIONS

    # START OF RUN FUNCTIONS

    function activate_volume_group { for I in ${VG[@]} do if [[ "${VGCHANGE}" = "vgchange -a y" ]] then
          print "$(date '+%b %e %X') - Node \"$(hostname)\": Activating volume group $I with non-exclusive option." else
          print "$(date '+%b %e %X') - \"$(hostname)\": Activating volume group $I with exclusive option." fi
    $VGCHANGE $I test_return 1
    # If the -s option has been specified, then we perform # the resynchronization as a background task # if [[ ${VGCHANGE#*-s} != ${VGCHANGE} ]] then { if /sbin/vgsync $I then print "$(date '+%b %e %X') - Node \"$(hostname)\": Resynchronized volume group $I" else print "$(date '+%b %e %X') - Node \"$(hostname)\": Resynchronization of volume group $I encountered an error" fi } & fi done }
    # For each {file system/logical volume} pair, fsck the file system # and mount it.
    function check_and_mount { integer R=0
    for I in ${LV[@]} do if [[ $(mount -p | awk '$1 == "'$I'"') = "" ]] then RLV[$R]="${I%/*}/r${I##*/}"

          if [ -x /usr/sbin/fstyp ]
          then
          fstype[$R]=$(fstyp $I) fi (( R = $R + 1 )) fi done
    # Verify that there is at least one file system to check and what type. if [[ ${RLV[@]} != "" ]] then print -n "$(date '+%b %e %X') - Node \"$(hostname)\": " print "Checking filesystems:" print ${LV[@]} | tr ' ' '\012' | sed -e 's/^/ /'
    # If there is more than one filesystem type being checked # then each filesystem is check individually. # R=$(print ${fstype[*]} | tr ' ' '\012' | sort -u | wc -l) if (( R > 1 )) then R=0 while (( R < ${#RLV[*]} )) do case ${fstype[$R]} in
    hfs) fsck -F hfs -P ${RLV[$R]} test_return 2 ;;
    vxfs) fsck -F vxfs -y ${RLV[$R]} test_return 2 ;;
    unk*) fsck ${RLV[$R]} test_return 2 ;;
    *) if [[ ${fstype[$R]} = "" ]] then fsck ${RLV[$R]} else fsck -F ${fstype[$R]} ${RLV[$R]} fi test_return 2 ;; esac (( R = R + 1 )) done
    # If there is only one filesystem type being checked, then # multiple invocations of fsck can be avoided. All filesystems # are specified on the command line to one fsck invocation. # else case ${fstype} in
    hfs) fsck -F hfs -P ${RLV[@]} test_return 2 ;;
    vxfs) fsck -F vxfs -y ${RLV[@]} test_return 2 ;;
    unk*) fsck ${RLV[@]} test_return 2 ;;
    *) if [[ ${fstype} = "" ]] then fsck ${RLV[@]} else fsck -F ${fstype} ${RLV[@]} fi test_return 2 ;; esac fi fi
    integer F=0 for I in ${LV[@]} do if [[ $(mount | grep -e $I" ") = "" ]] then print "$(date '+%b %e %X') - Node \"$(hostname)\": Mounting $I at ${FS[$F]}" mount ${FS_MOUNT_OPT[$F]} $I ${FS[$F]} test_return 3 else print "$(date '+%b %e %X') - Node \"$(hostname)\": WARNING: File system \"${FS[$F]}\" was already mounted." fi (( F = $F + 1 )) done }
    # For each {IP address/subnet} pair, add the IP address to the subnet # using cmmodnet(1m).
    function add_ip_address { integer S=0 integer error=0
    for I in ${IP[@]} do print "$(date '+%b %e %X') - Node \"$(hostname)\": Adding IP address $I to subnet ${SUBNET[$S]}" XX=$( cmmodnet -a -i $I ${SUBNET[$S]} 2>&1 ) if (( $? != 0 )) then
          if [[ $(echo $XX | grep "heartbeat IP") != "" ]]
          then
          # IP has been configured as a heartbeat IP address.
          print "$XX" >> $0.log
          (( error = 1 ))
          else
          YY=$( netstat -in | awk '$4 == "'${I}'"')
          if [[ -z $YY ]]
          then
          print "$XX" >> $0.log
          print "\tERROR: Failed to add IP $I to subnet ${SUBNET[$S]}"
          (( error = 1 ))
          else
          print "\tWARNING: IP $I is already configured on the subnet ${SUBNET[$S]}"
          fi
          fi fi (( S = $S + 1 )) done
    if (( error != 0 )) then
    # `let 0` is used to set the value of $? to 1. The function test_return # requires $? to be set to 1 if it has to print error message.

          let 0
          test_return 4 fi
    }
    # Own and reset the DTC connections
    function get_ownership_dtc { for I in ${DTC_NAME[@]} do print "$(date '+%b %e %X') - Node \"$(hostname)\": Assigning Ownership of the DTC $I" dtcmodifyconfs -o $I test_return 5
    for J in ${IP[@]} do print "$(date '+%b %e %X') - Node \"$(hostname)\": Resetting the DTC connections to IP address $J" dtcdiag -Q $J -q -f $I test_return 6 done done }

    # For each {service name/service command string} pair, start the # service command string at the service name using cmrunserv(1m).
    function start_services { integer C=0 for I in ${SERVICE_NAME[@]} do print "$(date '+%b %e %X') - Node \"$(hostname)\": Starting service $I using" print " \"${SERVICE_CMD[$C]}\""
          #
          # Check if cmrunserv should be called the old
          # way without a restart count.
          # if [[ "${SERVICE_RESTART[$C]}" = "" ]] then cmrunserv $I ">> $0.log 2>&1 ${SERVICE_CMD[$C]}" else cmrunserv ${SERVICE_RESTART[$C]} $I ">> $0.log 2>&1 ${SERVICE_CMD[$C]}" fi test_return 8 (( C = $C + 1 )) done }
    # END OF RUN FUNCTIONS.


    # START OF HALT FUNCTIONS
    # Halt each service using cmhaltserv(1m).
    function halt_services { for I in ${SERVICE_NAME[@]} do print "$(date '+%b %e %X') - Node \"$(hostname)\": Halting service $I" cmhaltserv $I test_return 9 done }
    # Disown the DTC.
    function disown_dtc { for I in ${DTC_NAME[@]} do print "$(date '+%b %e %X') - Node \"$(hostname)\": Disowning the DTC $I" dtcmodifyconfs -d $I test_return 11 done }
    # For each IP address/subnet pair, remove the IP address from the subnet # using cmmodnet(1m).
    function remove_ip_address { integer S=0 integer error=0
    for I in ${IP[@]} do print "$(date '+%b %e %X') - Node \"$(hostname)\": Remove IP address $I from subnet ${SUBNET[$S]}" XX=$( cmmodnet -r -i $I ${SUBNET[$S]} 2>&1 ) if (( $? != 0 )) then echo $XX | grep "is not configured on the subnet" if (( $? != 0 )) then print "$XX" >> $0.log (( error = 1 )) fi fi (( S = $S + 1 )) done if (( $error != 0 )) then
    # `let 0` is used to set the value of $? to 1. The function test_return # requires $? to be set to 1 if it has to print error message.
    let 0 test_return 12 fi }
    # Unmount each logical volume.
    function umount_fs { integer UM_CNT=${LV_UMOUNT_COUNT:-1}
    if [[ $UM_CNT < 1 ]] then
          UM_CNT=1 fi
    for I in $(print ${LV[@]} | awk '{ for(i=NF; i>0; i--) print $i }') do mount | grep -e $I" " > /dev/null 2>&1 if (( $? == 0 )) then print "$(date '+%b %e %X') - Node \"$(hostname)\": Unmounting filesystem on $I" print "\tWARNING: Running fuser to remove anyone using the file system directly." UM_COUNT=$UM_CNT while (( $UM_COUNT > 0 )) do fuser -ku $I umount $I if (( $? == 0 )) then (( UM_COUNT = 0 )) else if (( $UM_COUNT == 1 )) then let 0 test_return 13 fi (( UM_COUNT = $UM_COUNT - 1 )) sleep 1 if (( $UM_COUNT > 0 )) then print "\t$(date '+%b %e %X') - Unmount failed, trying again." fi fi done fi done }

    function deactivate_volume_group { for I in ${VG[@]} do print "$(date '+%b %e %X') - Node \"$(hostname)\": Deactivating volume group $I" vgchange -a n $I test_return 14 done }
    # END OF HALT FUNCTIONS.
    # FUNCTIONS COMMON TO BOTH RUN AND HALT.
    # Test return value of functions and exit with NO RESTART if bad. # Return value of 0 - 50 are reserved for use by Hewlett-Packard. # System administrators can use numbers above 50 for return values. function test_return { if (( $? != 0 )) then case $1 in 1) print "\tERROR: Function activate_volume_group" print "\tERROR: Failed to activate $I" deactivate_volume_group exit 1 ;;
    2) print "\tERROR: Function check_and_mount" print "\tERROR: Failed to fsck one of the logical volumes." exit_value=1 ;;
    3) print "\tERROR: Function check_and_mount" print "\tERROR: Failed to mount $I to ${FS[$F]}" umount_fs deactivate_volume_group exit 1 ;;
    4) print "\tERROR: Function add_ip_address" print "\tERROR: Failed to add IP address to subnet" remove_ip_address umount_fs deactivate_volume_group exit 1 ;;
    5) print "\tERROR: Function get_ownership_dtc" print "\tERROR: Failed to own $I" disown_dtc remove_ip_address umount_fs deactivate_volume_group exit 1 ;;
    6) print "\tERROR: Function get_ownership_dtc" print "\tERROR: Failed to switch $I" disown_dtc remove_ip_address umount_fs deactivate_volume_group exit 1 ;;
    8) print "\tERROR: Function start_services" print "\tERROR: Failed to start service ${SERVICE_NAME[$C]}" halt_services customer_defined_halt_cmds disown_dtc remove_ip_address umount_fs deactivate_volume_group exit 1 ;;
    9) print "\tFunction halt_services" print "\tWARNING: Failed to halt service $I" ;;
    11) print "\tERROR: Function disown_dtc" print "\tERROR: Failed to disown $I from ${SUBNET[$S]}" exit_value=1 ;;
    12) print "\tERROR: Function remove_ip_address" print "\tERROR: Failed to remove $I" exit_value=1 ;;
    13) print "\tERROR: Function umount_fs" print "\tERROR: Failed to unmount $I" exit_value=1 ;;
    14) print "\tERROR: Function deactivate_volume_group" print "\tERROR: Failed to deactivate $I" exit_value=1 ;;
    51) print "\tERROR: Function customer_defined_run_cmds" print "\tERROR: Failed to RUN customer commands" halt_services customer_defined_halt_cmds disown_dtc remove_ip_address umount_fs deactivate_volume_group exit 1 ;;
    52) print "\tERROR: Function customer_defined_halt_cmds" print "\tERROR: Failed to HALT customer commands" exit_value=1 ;;
    *) print "\tERROR: Failed, unknown error." ;; esac fi }
    # END OF FUNCTIONS COMMON TO BOTH RUN AND HALT
    #-------------------MAINLINE Control Script Code Starts Here----------------- # # FUNCTION STARTUP SECTION.
    typeset MIN_VERSION="A.10.03" # Minimum version this control script works on
    integer exit_value=0 typeset CUR_VERSION
    # # Check that this control script is being run on a A.10.03 or later release # of MC/ServiceGuard or MC/LockManager. The control scripts are forward # compatible but are not backward compatible because newer control # scripts use commands and option not available on older releases.
    CUR_VERSION="$(/usr/bin/what /usr/lbin/cmcld | /usr/bin/grep "Date" | \
          /usr/bin/egrep '[AB]\...\...|NTT\...\...' | \ cut -f2 -d" ")"
    if [[ "${CUR_VERSION}" = "" ]] || \
          [[ "${CUR_VERSION#*.}" < "${MIN_VERSION#*.}" ]] then
          print "ERROR: Mismatched control script version ($MIN_VERSION). You cannot run"
          print "\ta version ${MIN_VERSION} control_script on a node running pre"
          print "\t${MIN_VERSION} MC/ServiceGuard or MC/LockManager software"
          exit 1 fi
    # Test to see if we are being called to run the package, or halt the package.
    if [[ $1 = "start" ]] then print "\n\t########### Node \"$(hostname)\": Starting package at $(date) ###########"
    activate_volume_group
    check_and_mount
    add_ip_address
    get_ownership_dtc
    customer_defined_run_cmds
    start_services

    # Check exit value
    if (( $exit_value == 1 )) then print "\n\t########### Node \"$(hostname)\": Package start failed at $(date) ###########" exit 1 else print "\n\t########### Node \"$(hostname)\": Package start completed at $(date) ###########" exit 0 fi
    elif [[ $1 = "stop" ]] then print "\n\t########### Node \"$(hostname)\": Halting package at $(date) ###########"

    halt_services
    customer_defined_halt_cmds
    disown_dtc
    remove_ip_address
    umount_fs
    deactivate_volume_group
    # Check exit value if (( $exit_value == 1 )) then print "\n\t########### Node \"$(hostname)\": Package halt failed at $(date) ###########" exit 1 else print "\n\t########### Node \"$(hostname)\": Package halt completed at $(date) ###########" exit 0 fi
    fi











    Home | UK Shop Center |Contact | Buy Domain | Directory | Web Hosting | Resell Domains


    Copyleft 2005 ruslib.us