IVM (comes with VIOS) has some differences from HMC, but is overall
pretty similar. Tested on VIOS 2.2.1.3 only.

Signed-off-by: Nishanth Aravamudan <[email protected]>
---
 conmux/drivers/ivm       |  425 ++++++++++++++++++++++++++++++++++++++++++++++
 conmux/drivers/module.mk |    2 +-
 2 files changed, 426 insertions(+), 1 deletions(-)
 create mode 100755 conmux/drivers/ivm

diff --git a/conmux/drivers/ivm b/conmux/drivers/ivm
new file mode 100755
index 0000000..c134c7a
--- /dev/null
+++ b/conmux/drivers/ivm
@@ -0,0 +1,425 @@
+#!/usr/bin/expect --
+#
+# ivm -- handle consoles and rebooting of VIOS based systems
+#
+# Allow connecting to the console of and rebooting of HMC connected
+# machines.  Machines are identified by the HMC IP address, connected
+# system name, and partition name.
+#
+# usage:
+#  ivm open-term|reboot -h <ivm IP> -p <partition> \
+#      -U <user> -P <password> -V <ivm version>
+#
+# example:
+#  ivm open-term -p FullSystemPartition -U hscroot -P passwd \
+#      -V 2.6 -h 1.2.3.4 
+#  ivm reboot -p FullSystemPartition -U hscroot -P passwd \
+#      -V 2.6 -h 1.2.3.4
+#
+# (C) Copyright IBM Corp. 2012
+# Author: Nishanth Aravamudan <[email protected]>
+# Based off hmc script, which is
+# (C) Copyright IBM Corp. 2004, 2005, 2006
+# Author: Andy Whitcroft <[email protected]>
+#
+# The Console Multiplexor is released under the GNU Public License V2
+#
+set P "ivm"
+
+# See interactions.
+log_user 0
+#exp_internal 1
+
+proc note {m} {
+       global P
+       puts "$P: $m"
+}
+proc warn {m} {
+       global P
+       puts "$P: WARNING: $m"
+}
+proc winge {m} {
+       global P
+       puts "$P: MACHINE ERROR: $m"
+}
+
+#
+# OPTIONS: options parser.
+#
+proc shift {_list} {
+       upvar $_list list
+
+       set res [lindex $list 0]
+       set list [lreplace $list 0 0]
+
+       return $res
+}
+proc arg {_list arg} {
+       upvar $_list list
+
+       if {[llength $list] < 1} {
+               winge "$arg: required argument missing"
+               exit 1
+       }
+       
+       return [shift list]
+}
+
+set user               {padmin}
+set host               {}
+set lpar               {}
+set mode               {norm}
+set passwd             {}
+set version            {}
+
+set cmd [lindex $argv 0]
+shift argv
+while {[llength $argv] > 0} {
+       switch -- [shift argv] {
+               -h      { set host [arg argv h]}
+               -l      { set lpar [arg argv l]}
+               -p      { set lpar [arg argv p]}
+               -b      { set mode [arg argv b]}
+               -U      { set user [arg argv P]}
+               -P      { set passwd [arg argv P]}
+               -V      { set version [arg argv P]}
+       }
+}
+
+if {[llength $argv] > 0} {
+       puts stderr "Usage: $P <cmd> -h <ivm> -p <lpar> -b <mode>"
+       exit 1
+}
+if {[string compare $host ""] == 0 ||
+    [string compare $lpar ""] == 0} \
+{
+       winge "ivm (-h), and lpar (-p) required"
+       exit 1
+}
+
+set prompt             {___EOF___IVM___EOF___}
+set iospath            {/usr/ios/lpm/bin}
+
+#log_file -a "$logfile"
+
+set elapsed_time 0
+set timeout 30
+
+# Ensure we have a terminal so we don't get prompted for one.
+if {![info exists env(TERM)]} {
+       set env(TERM) {vt100}
+}
+
+# If we have a password don't use any ssh-keys we may have been offered.
+if {[string compare $passwd ""] == 0} {
+       set command "ssh $env(SSH_OPTIONS) $user@$host"
+} else {
+       set command "ssh $user@$host"
+}
+
+# CONNECT: connect to the remote console.  Set the prompt up so we
+#          know when a command we execute has completed.
+note "Logging into IVM console with command \"$command\" ..."
+eval spawn $command
+send "PS1=$prompt\r"
+expect {
+       -re {[pP]assword:} {
+               if {[string compare $passwd ""] == 0} {
+                       winge "$host: requesting password - not hacked"
+                       exit 2
+               }
+               send "$passwd\r"
+               after 500
+               send "PS1=$prompt\r"
+               exp_continue
+       }
+       "Connection timed out" {
+               winge "$host: cannot connect to console"
+               exit 2
+       }
+       "Name or service not known" {
+               winge "$host: IVM name invalid"
+               exit 1
+       }
+       "Permission denied" {
+               winge "$host: authentication failure, permission denied"
+               exit 2
+       }
+       timeout {
+               winge "$host: IVM did not prompt us, timed out"
+               exit 2
+       }
+       eof {
+               winge "$host: IVM disconnected without prompting"
+               exit 2
+       }
+
+       "Terminal type?" {
+               send "vt100\r"
+               send "PS1=$prompt\r"
+               exp_continue
+       }
+
+       "PS1=$prompt" {
+               # Ignore us typing the change to the prompt.
+               exp_continue
+       }
+       "$prompt" {
+               # Prompt see, we are in and working, drop out.
+               ## note "prompt seen"
+       }
+
+       -re "^\[^\n]*\n" {
+               # We need to absorb any login information, motd etc.
+               ## puts "NOISE<$expect_out(buffer)>"
+               exp_continue
+       }
+}
+
+proc runit {cmd _out} {
+       upvar $_out out
+
+       global prompt
+
+       send "$cmd"
+
+       set text ""
+       set line 0
+
+       set timeout 120
+       expect {
+               
+               -re "^\[^\n]*\n" {
+                       ##note "LINE: $expect_out(buffer)"
+                       if { $line > 0 } {
+                               append text $expect_out(buffer)
+                       }
+                       incr line
+                       exp_continue
+               }
+
+               -re "$prompt" {
+                       #note "prompt seen"
+               }
+
+               timeout {
+                       set out "ivm: command timeout"
+                       return 255
+               }
+       }
+       set out [string trimright $text]
+
+       send "echo \$?\r"
+       set text ""
+       set line 0
+       set timeout 30
+       expect {
+               -re "^\[^\n]*\n" {
+                       ##note "LINE: $expect_out(buffer)"
+                       if { $line > 0 } {
+                               append text $expect_out(buffer)
+                       }
+                       incr line
+                       exp_continue
+               }
+
+               -re "$prompt" {
+                       #note "prompt seen"
+               }
+
+               timeout {
+                       set out "ivm: command status timeout"
+                       return 255
+               }
+       }
+       #note "EXIT: $text"
+
+       return [string trimright $text]
+}
+
+proc extract_names {out} {
+       set res {}
+       foreach sys [split $out] {
+               if {[string compare $sys ""] != 0} {
+                       lappend res $sys
+               }
+       }
+
+       return $res
+}
+
+# Find out the current version of the IVM software.
+if {[string compare $version ""] == 0} {
+       runit "ioslevel; echo ''\r" version
+}
+if {[string compare $version ""] == 0} {
+       winge "unable to obtain IVM code version"
+       exit 1
+}
+note "IVM revision v$version"
+
+# Based on the version of the IVM software select payload.
+if {$version < 3} {
+       #
+       # VERSION 2.6/3.0 specific support.
+       #
+       proc lpar_list {} {
+               global iospath
+
+               # Ask for a list of lpars for this system.
+               if {[runit "lssyscfg -r lpar -F name\r" out] != 0} {
+                       winge "unable to obtain list of lpars"
+                       exit 1
+               }
+
+               return [extract_names $out]
+       }
+       proc state {lpar} {
+               global iospath
+
+               # Ask for the lpar status.
+               if {[runit "lssyscfg -r lpar --filter lpar_names=$lpar -F 
state\r" out] != 0} {
+                       winge "$lpar: failed to get lpar status"
+                       exit 1
+               }
+
+               return $out
+       }
+       proc lparid {lpar} {
+               global iospath
+
+               # Ask for the corresponding ID of an LPAR by name
+               if {[ runit "lssyscfg -r lpar --filter lpar_names=$lpar -F 
lpar_id\r" out] != 0} {
+                       winge "$lpar: failed to get lpar ID"
+                       exit 1
+               }
+
+               return $out
+       }
+       proc reboot {lpar mode} {
+               global iospath
+
+               # Partitions in Error state are tricky, you _may_ either
+               # have to shut them down and then start them, or you may
+               # just have to start them.  So, if we are in Error start
+               # the partition, if it fails we can just drop through
+               # to the regular stop/start cycle.
+               if {[string compare [state $lpar] "Error"] == 0} {
+                       note "starting lpar (from Error)"
+                       if {[runit "chsysstate -r lpar -n $lpar -b $mode -o 
on\r" out] == 0} {
+                               note "started"
+                               return
+                       }
+                       note "start failed - attempting shutdown"
+               }
+
+               # See if the lpar is up, if so shut it down.
+               if {[string compare [state $lpar] "Ready"] != 0} {
+                       note "shutting down lpar"
+                       if {[runit "chsysstate -r lpar -n $lpar -o shutdown\r" 
out] != 0} {
+                               winge "$lpar: power off failed\n$out"
+                               exit 2
+                       }
+               }
+
+               while {[string compare [state $lpar] "Not Activated"] != 0} {
+                       note "waiting for shutdown"
+                       sleep 15
+               }
+
+               note "starting lpar"
+               if {[runit "chsysstate -r lpar -n $lpar -b $mode -o on\r" out] 
!= 0} {
+                       winge "$lpar: power on failed\n$out"
+                       exit 2
+               }
+               note "started"
+       }
+
+}
+
+#
+# VERSION: common
+#
+proc open-term {lpar lparid} {
+       global prompt
+       global iospath
+       global spawn_id
+
+       note "opening console ..."
+       send "ulimit -t 3600; mkvt -id $lparid\r"
+       expect {
+               "NVTS" { }
+               "Open in progress.." { }
+               "$prompt" {
+                       winge "$lpar: open console failed"
+                       exit 2
+               }
+       }
+
+       note "console open"
+       interact {
+               -i $spawn_id
+               " Connection has closed" {
+                       winge "$lpar: console connection closed"
+                       exit 2
+               }
+               {Error in communication path to the partition} {
+                       winge "$lpar: lost contact with lpar"
+                       exit 2
+               }
+               "$prompt" {
+                       winge "$lpar: open console failed"
+                       exit 2
+               }
+               eof {
+                       winge "$lpar: payload lost"
+                       exit 2
+               }
+               \000 {
+               }
+                       
+       }
+       note "console closed"
+}
+
+proc close-term {lpar lparid} {
+       global iospath
+
+       note "closing console ..."
+       if {[runit "rmvt -id $lparid\r" out] != 0} {
+               winge "$lpar: close console failed"
+               exit 2
+       }
+}
+
+set lpars [lpar_list]
+if {[lsearch -exact $lpars $lpar] < 0} {
+       winge "$system/$lpar: lpar not known; console knows: $lpars"
+       exit 1
+}
+
+# Ask for the lpar status, to see if it exists.
+set lstate [state $lpar]
+set lparid [lparid $lpar]
+note "$lpar (ID $lparid): found ($lstate)"
+
+#
+# COMMANDS: command.
+#
+switch -- $cmd {
+       {open-term}     {
+               close-term $lpar $lparid
+               open-term $lpar $lparid
+       }
+       {close-term}    {
+               close-term $lpar $lparid
+       }
+       {reboot}        {
+               reboot $lpar $mode
+       }
+       default         {
+               winge "$cmd: unknown command"
+       }
+}
+
+exit 0
diff --git a/conmux/drivers/module.mk b/conmux/drivers/module.mk
index 7c36663..c13fec0 100644
--- a/conmux/drivers/module.mk
+++ b/conmux/drivers/module.mk
@@ -3,7 +3,7 @@
 #
 # The Console Multiplexor is released under the GNU Public License V2
 
-DRIVERS:=blade dli-lpc hmc reboot-netfinity reboot-newisys reboot-numaq \
+DRIVERS:=blade dli-lpc hmc ivm reboot-netfinity reboot-newisys reboot-numaq \
        reboot-rsa reboot-rsa2 zseries-console x3270_glue.expect \
        reboot-acs48 reboot-apc reboot-laurel fence_apc_snmp.py
 
-- 
Nishanth Aravamudan <[email protected]>
IBM Linux Technology Center

_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to