-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
xCAT support for Secured OF (Openfirmware) prompt #6637
Comments
Can you provide some information about the server model number and firmware version you are using? |
The Server is an IBM Power 9 E980 with Firmware FW940.02. |
HMC version is Version 9 Release 1 Maintenance 940 (V9 R1 M940) |
Hi
Did you have a look at this issue?. Thanks.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
signature_lab_services
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019 IBM
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: besawn <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Author
<[email protected]>
Date: 03/17/2020 01:44 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
Can you provide some information about the server model number and firmware
version you are using?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
We don't currently support "Secured OF" boot from xCAT. We can try to suggest a workaround if you can provide more information. Also please provide console output log file |
Hi
Thanks for the reply - I am already working on a workaround to add support
to "LparNetbootExp.pm" to get over this issue. Hopefully within next couple
of days I will be able to replace all commands and search on expected
results to match Secure OF so it will continue for my purpose.
Thanks again for the response.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
signature_lab_services
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019 IBM
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Author
<[email protected]>
Date: 03/19/2020 07:20 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
We don't currently support "Secured OF" boot from xCAT.
We can try to suggest a workaround if you can provide more information.
Please provide the lsdef output for the node in question.
Also please provide console output log file /var/log/consoles/<node>.log
from the partition boot showing the boot sequence including the failure
when the "Secured OF" prompt appears?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
@hgunasin Great, when you are done, would you be willing to share your solution here ? |
Hi Mark
Attached is the updated xCAT code to support "Secured OF". Is this
something that can be incorporated onto the new xCAT code so that in
future, when all P8/P9/etc systems are upgraded to Firmware 940 and beyond,
xCAT could continue to support the power control, remote installs?. In
addition, is there a process to get these updates to request to support
Secure OF on Power?.
I am more than happy to contribute/assist and support getting this
officially supported as we need this with future xCAT code distributions.
Please advice your thoughts. Thanks.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
signature_lab_services
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019 IBM
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 03/20/2020 03:56 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@hgunasin Great, when you are done, would you be willing to share your
solution here ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Fogot to attach the updated .pm
(See attached file: LparNetbootExp.pm)
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
signature_lab_services
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019 IBM
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Hemantha Gunasinghe/Australia/IBM
To: xcat2/xcat-core <reply
[email protected]>
Cc: Mention <[email protected]>, xcat2/xcat-core
<[email protected]>
Date: 04/01/2020 11:16 AM
Subject: Re: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured
OF (Openfirmware) prompt (#6637)
Hi Mark
Attached is the updated xCAT code to support "Secured OF". Is this
something that can be incorporated onto the new xCAT code so that in
future, when all P8/P9/etc systems are upgraded to Firmware 940 and beyond,
xCAT could continue to support the power control, remote installs?. In
addition, is there a process to get these updates to request to support
Secure OF on Power?.
I am more than happy to contribute/assist and support getting this
officially supported as we need this with future xCAT code distributions.
Please advice your thoughts. Thanks.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
signature_lab_services
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019 IBM
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 03/20/2020 03:56 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@hgunasin Great, when you are done, would you be willing to share your
solution here ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
@hgunasin It looks like your file did not get attached to the issue. Can you either drop the file directly into this issue's comment box or email the file directly to the email associated with my github id ? |
Hi
I attached the .pm as a .txt. Thanks.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
signature_lab_services
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019 IBM
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 04/02/2020 01:53 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@hgunasin It looks like your file did not get attached to the issue.
Can you either drop the file directly into this issue's comment box or
email the file directly to the email associated with my github id ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Hi Mark Did you have a chance to review the attachement?. I have a question with regard to getting "SecureOF" officially supported on Power Systems with xCAT. Do you know whom I need to reach out to take this support query forward?. Appreciate your help in advance. Thanks Hemantha |
@hgunasin
|
Hi Mark
Thanks for getting back to me. My answers to your questions are as per
below;
1. When you say getting "SecureOF" officially supported on Power Systems
with xCAT, is there more that needs to be done, other than merging in your
changes in LparNetbootExp ?
I would expect that once these changes are rolled onto the new versions,
it will ge generally available with xCAT code distributions as a
supported method to install with "SecureOF" prompt on Power systems. I
would assume that P8 systems are upgrded to same level of firmware, it
will be SecureOF similar to P9 systems. I did not have a test P8 system
to try out these changes with Firmware 940.
The expectation is that GA latest xCAT code to support SecureOF based
LPAR builds using xCAT and be able to log a IBM support call and get
official support under service maintenance.
2. You said you were unable to rinstall with netboot as when an LPAR is
powered on, in firmware 940 on P9. Does this mean it worked on P8 LPARs ?
The power 8 systems are fine with firmware level lower than 940
(traditional openfirmware prompt) and it works fine. However, I expect
when P8 systems are upgraded to Latest firmware level similar to 940,
the "SecureOF" will be enforced and xCAT at that point will not be able
to build without these modifications. Hence, the need to incorporate
this into GA code.
3. Once I install OP940 firmware that supports "SecureOF", how do I turn on
that feature ?
The SeureOF prompt is by default enabled when FW code level 940 is
installed. Once installed it cant be disabled. I have a variable defined
at the top of this .pm, which indicated to use SecureOF commands. In
SecureOF macros, there is a macro to test if it is traditional
openfirmware or Secured OF which can be used to switch between the two
automatically.
HHope this helps. Let me know if you need any further clarifications or
details.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 04/23/2020 12:20 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@hgunasin
This is still on our todo list, we just have not had time to setup test
environment to verify your changes.
Few questions for you, which might speed up that process:
When you say getting "SecureOF" officially supported on Power Systems
with xCAT, is there more that needs to be done, other than merging in
your changes in LparNetbootExp ?
You said you were unable to rinstall with netboot as when an LPAR is
powered on, in firmware 940 on P9. Does this mean it worked on P8
LPARs ?
Once I install OP940 firmware that supports "SecureOF", how do I turn
on that feature ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Hi There, i am experiencing the same problem with secure boot installing a cluster made of L922 servers. I just tried to test the Hemantha version of LparNetbootExp.pm with xCAT version 2.16 and rnetboot is failing with several perl error messages. syntax error at /opt/xcat/lib/perl/xCAT/LparNetbootExp.pm line 2231, near "else" |
@hgunasin The
|
Hi mark Let me try upload another copy for your reference. Thanks. |
LparNetbootExp.pm.txt Thanks. |
Hi
Please fine the my version. Thanks.
(See attached file: LparNetbootExp.pm.txt)
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
signature_lab_services
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019 IBM
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 07/09/2020 10:55 PM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@hgunasin The LparNetbootExp.txt you posted on April 2 seems to have
unmatched bracket.
perltidy flagged this:
1522: Should 'eq' be '==' here ?
2231: expecting 'else' to follow one of 'if|elsif|unless|case|when'
There is no previous '{' to match a '}' on line 2412
2412: }
^
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#
package xCAT::LparNetbootExp;
#-----------------------------------------------------------------------------
=head1 LparNetbootExp
Usage: Install partition
lpar_netboot [-v] [-x] [-f] [-w set_boot_order] [-A -D | [-D] | [-D] -m macaddress] -t ent -s speed -d duplex
-S server -G gateway -C client hostname profile managed_system lparid remote_host
Usage: Return macaddress
lpar_netboot -M -n [-v] -t ent [-f] [-x] [-D -s speed -d duplex -S server -G gateway -C client] hostname profile managed_system lparid remote_host
-n Do not boot partition
-t Specifies network type ent
-D Perform ping test, use adapter that successfully ping the server
-s Network adapter speed
-d Network adapter duplex
-S Server IP address
-G Gateway IP address
-C Client IP address
-m MAC Address
-v Verbose output
-x Debug output
-f Force close virtual terminal session
-w Set boot device order
0: Don't set boot device order
1: Set network as boot device
2: Set network as 1st boot device, disk as 2nd boot device
3: Set disk as 1st boot device, network as 2nd boot device
4: set disk as boot device
-M Discovery ethernet adapter mac address and location code
-a Use Secure OF
--help Prints this help
=cut
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATDIR = $ENV{'XCATDIR'} ? $ENV{'XCATDIR'} : '/etc/xcat';
}
use lib "$::XCATROOT/lib/perl";
use xCAT::Utils;
use Getopt::Long;
use xCAT::MsgUtils;
use Expect;
use strict;
use Data::Dumper;
my $adapter_found = 0;
my @adap_type;
my @full_path_name_array;
my @phandle_array;
my $macaddress;
my $phys_loc;
my $client_ip;
my $gateway_ip;
my $device_type;
my $server_ip;
my $secOF=1;
# List supported network adapters here. dev_pat is an array of regexp patterns
# the script searches for in the device tree listing. dev_type is the type
# of device displayed in the output.
my @dev_pat = (
"ethernet",
"token-ring",
"fddi"
);
my @dev_type = (
"ent",
"tok",
"fddi"
);
my $dev_count = scalar(@dev_type); #number of supported device type
#-------------------------------------------------------------------------------
=head3 nc_msg
PROCEDURE
Declare procedure to write status/error messages
We do it this way so that if /var is full (or some other error occurs)
we can trap it in a common section of code.
=cut
#-----------------------------------------------------------------------------
sub nc_msg
{
my $verbose = shift;
my $msg = shift;
my $rsp;
if ($verbose == 1) {
$rsp->{data}->[0] = $msg;
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
}
if ($verbose == 2) {
$rsp->{data}->[0] = $msg;
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
}
}
#-------------------------------------------------------------------------------
=head3 run_lssyscfg
Procedure to run the rpower command
test its return code and capture its output
=cut
#-----------------------------------------------------------------------------
sub run_lssyscfg
{
my $req = shift;
if (($req) && ($req =~ /xCAT::/))
{
$req = shift;
}
my $verbose = shift;
my $node = shift;
my $cmd;
my $out;
$out = xCAT::Utils->runxcmd(
{
command => ['rpower'],
node => [$node],
arg => ['state']
},
$req, 0, 1);
if ($::RUNCMD_RC != 0) {
nc_msg($verbose, "Unable to run rpower $node state.\n");
return undef;
}
my $output = join ',', @$out;
nc_msg($verbose, "Status: run_lssyscg : partition status : $output\n");
nc_msg($verbose, "####msg:$output#########\n");
###################################################################
# Slow down the requests speed to hcp, so that hcp will not busy on
# query. Instead, hcp should put more time on other activities.
# Another reason to set this sleep is giving some time to the lpars
# to be more stable.
###################################################################
sleep 4;
return $output;
}
#-------------------------------------------------------------------------------
=head3 usage
PROCEDURE
Declare procedure to write usage message and exit
=cut
#-----------------------------------------------------------------------------
sub usage {
my $msg = "Usage: Install partition \
\n\t \[-v\] \[-x\] \[-f\] \[-w set_boot_order\] \[-A -D | \[-D\] | \[-D\] -m macaddress\] -t ent -s speed -d duplex \
\n\t\t-S server -G gateway -C client hostname profile managed_system lparid remote_host\
\n \
\nUsage: Return macaddress \
\n\t -M -n \[-v\] -t ent \[-f] \[-x] \[-D -s speed -d duplex -S server -G gateway -C client\] hostname profile managed_system lparid remote_host\
\n \
\n\t-n\tDo not boot partition \
\n\t-t\tSpecifies network type ent \
\n\t-D\tPerform ping test, use adapter that successfully ping the server \
\n\t-s\tNetwork adapter speed \
\n\t-d\tNetwork adapter duplex \
\n\t-S\tServer IP address \
\n\t-G\tGateway IP address \
\n\t-C\tClient IP address \
\n\t-m\tMAC Address \
\n\t-v\tVerbose output \
\n\t-x\tDebug output \
\n\t-f\tForce close virtual terminal session \
\n\t-w\tSet boot device order \
\n\t\t\t0: Don't set boot device order \
\n\t\t\t1: Set network as boot device \
\n\t\t\t2: Set network as 1st boot device, disk as 2nd boot device \
\n\t\t\t3: Set disk as 1st boot device, network as 2nd boot device \
\n\t\t\t4: set disk as boot device \
\n\t-M\tDiscovery ethernet adapter mac address and location code \
\n\t--help\tPrints this help\n";
nc_msg(1, $msg);
return 0;
}
#-------------------------------------------------------------------------------
=head3 ck_args
PROCEDURE
Check command line arguments
=cut
#-----------------------------------------------------------------------------
sub ck_args {
my $opt = shift;
if (($opt) && ($opt =~ /xCAT::/))
{
$opt = shift;
}
my $verbose = shift;
my $node = $opt->{node};
my $mtms = $opt->{fsp};
my $hcp = $opt->{hcp};
my $lparid = $opt->{id};
my $profile = $opt->{pprofile};
if (exists($opt->{D}) and !exists($opt->{noping}) and (!exists($opt->{s}) or !exists($opt->{d}))) {
nc_msg($verbose, "Speed and duplex required\n");
usage;
return 1;
}
if (exists($opt->{D}) and !exists($opt->{noping}) and !exists($opt->{C})) {
nc_msg($verbose, "Client IP is required\n");
usage;
return 1;
}
if (exists($opt->{D}) and !exists($opt->{noping}) and !exists($opt->{S})) {
nc_msg($verbose, "Server IP is required\n");
usage;
return 1;
}
if (exists($opt->{D}) and !exists($opt->{noping}) and !exists($opt->{G})) {
nc_msg($verbose, "Gateway IP is required\n");
usage;
return 1;
}
unless ($node) {
nc_msg($verbose, "Node is required\n");
usage;
return 1;
} else {
nc_msg($verbose, "Node is $node\n");
}
unless ($mtms) {
nc_msg($verbose, "Managed system is required\n");
usage;
return 1;
} else {
nc_msg($verbose, "Managed system is $mtms.\n");
}
unless ($hcp) {
nc_msg($verbose, "Hardware control point address is required\n");
usage;
return 1;
} else {
nc_msg($verbose, "Hardware control point address is $hcp.\n");
}
unless ($lparid) {
nc_msg($verbose, "Lpar Id is required.\n");
usage;
return 1;
} else {
nc_msg($verbose, "LPAR Id is $lparid.\n");
}
unless ($profile) {
nc_msg($verbose, "Profile is required.\n");
usage;
return 1;
} else {
nc_msg($verbose, "profile $profile.\n");
}
if ($opt->{M} and $opt->{g}) {
nc_msg($verbose, "Can not specify -M and -g flags together.\n");
usage;
return 1;
}
if ($opt->{M} and ($opt->{m} or $opt->{l})) {
nc_msg($verbose, "Can not specify -M and -l or -m flags together.\n");
usage;
return 1;
}
if ($opt->{m} and $opt->{l}) {
nc_msg($verbose, "Can not specify -l and -m flags together.\n");
usage;
return 1;
}
if ($opt->{A} and ($opt->{m} or $opt->{l})) {
nc_msg($verbose, "Can not specify -A and -m or -l flags together.\n");
usage;
return 1;
}
if ($opt->{A} and !exists($opt->{D}) and !exists($opt->{n})) {
nc_msg($verbose, "Flag -A must be specify with flag -D for booting.\n");
usage;
return 1;
}
if ($opt->{M} and $opt->{D} and !exists($opt->{noping}) and (!exists($opt->{S}) or !exists($opt->{G}) or !exists($opt->{C}) or !exists($opt->{s}) or !exists($opt->{d}))) {
nc_msg($verbose, "Flag -M with -D require arguments for -C, -S, -G, -s and -d.\n");
usage;
return 1;
}
if ($opt->{M} and !exists($opt->{D}) and (!exists($opt->{S}) or !exists($opt->{G}) or !exists($opt->{C}) or !exists($opt->{s}) or !exists($opt->{d}))) {
nc_msg($verbose, "Flag -M with arguments for -C, -S, -G, -s and -d require -D flag.\n");
usage;
return 1;
}
if ($opt->{M} and !exists($opt->{n})) {
nc_msg($verbose, "-M flag requires -n.\n");
usage;
return 1;
}
if ($node =~ /(\[ ]+)-/) {
nc_msg($verbose, "Error : $node, node is required\n");
return 1;
}
if ($mtms =~ /(\[ ]+)-/) {
nc_msg($verbose, "Error : $mtms, Managed system is required\n");
return 1;
}
#if ($profile =~ /(\[ ]+)-/) {
# nc_msg($verbose, "Error : $profile, profile is required\n");
# return 1;
#}
return 0;
}
#-------------------------------------------------------------------------------
=head3 send_command
PROCEDURE
Declare procedure to send commands slowly. This is needed because
some bytes are missed by the service processor when sent at top speed.
The sleep was needed because a command was sent sometimes before the
results of the previous command had been received.
The Open Firmware is constrained on how quickly it can process input streams.
The following code causes expect to send 10 characters and then wait 1 second
before sending another 10 bytes.
=cut
#-----------------------------------------------------------------------------
sub send_command {
my $verbose = shift;
my $rconsole = shift;
my $cmd = shift;
nc_msg($verbose, "sending commands $cmd to expect \n");
my $msg;
$msg = $rconsole->send($cmd);
sleep 1;
return $msg;
}
#-------------------------------------------------------------------------------
=head3 get_phandle
PROCEDURE
Declare procedure to parse the full device tree that is displayed as a result
of an ls command. The information needed is the phandle and full device name
of a supported network card found in the device tree. The phandle is used in
other procedures to get and change properties of the network card. The full
device name is used to network boot from the network adapter.
=cut
#-----------------------------------------------------------------------------
sub get_phandle {
my $rconsole = shift;
my $node = shift;
my $verbose = shift;
my $timeout = 30;
my $done = 0;
my @Result;
my $expect_out;
my $retry_count;
my %path;
my $rc;
if ($secOF == 1) {
nc_msg($verbose, "Status: get_phandle: Using Secured OF..............\n");
send_command($verbose, $rconsole, "\r");
@Result = $rconsole->expect(
$timeout,
[ qr/ok/ =>
sub {
nc_msg($verbose, "Status: at root\n");
$rconsole->clear_accum();
}
],
[ qr/]/ =>
sub {
nc_msg($verbose, "Unexpected prompt\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ timeout =>
sub {
$rconsole->send("\r");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node");
$rconsole->clear_accum();
$rc = 1;
}
],
);
return 1 if ($rc == 1);
send_command($verbose, $rconsole, "DISPLAY_BOOT_DEVICES #network\r");
$timeout = 60;
$done = 0;
while (!$done) {
@Result = ();
@Result = $rconsole->expect(
$timeout,
[ qr/.*1GbE.*/ =>
sub {
nc_msg($verbose, "Parsing network adapters... \n");
}
],
[ qr/.*Interpartition Logical LAN.*/ =>
sub {
nc_msg($verbose, "Parsing network adapters... \n");
}
],
[ qr/>/ =>
sub {
nc_msg($verbose, "finished \n");
$rconsole->clear_accum();
$done = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout isolating single line of ls output\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node");
$rconsole->clear_accum();
$rc = 1;
}
],
);
return 1 if ($rc == 1);
if ($result[2] =~ /1GbE/) {
my $j = 0;
for ($j = 0 ; $j < $dev_count ; $j++) {
my @values1 = split('=', $result[2]);
my @values2 = split('\)', $values1[1]);
$full_path_name_array[$adapter_found] = $values2[0];
$phandle_array[$adapter_found] = $values2[0];
$adap_type[$adapter_found] = $dev_type[$j];
$adapter_found++;
last;
};
};
if ($result[2] =~ /Interpartition Logical LAN/) {
my $j = 0;
for ($j = 0 ; $j < $dev_count ; $j++) {
my @values1 = split('=', $result[2]);
my @values2 = split('\)', $values1[1]);
$full_path_name_array[$adapter_found] = $values2[0];
$phandle_array[$adapter_found] = $values2[0];
$adap_type[$adapter_found] = $dev_type[$j];
$adapter_found++;
last;
};
};
};
# Did we find one or more adapters?
if ($adapter_found > 0) {
return 0;
} else {
nc_msg($verbose, "No network adapters found\n");
return 1;
};
}
else
{
# This is the first procedure entered after getting to the ok prompt. On entry
# the current device is not root. The command 'dev /' is sent to get to the
# root of the device tree. There is no output from the dev command. The expected
# output is the ok prompt ('>').
#
# The pwd command can be used to determine what the current device is.
#
send_command($verbose, $rconsole, "dev /\r");
@Result = $rconsole->expect(
$timeout,
[ qr/ok/ =>
sub {
nc_msg($verbose, "Status: at root\n");
$rconsole->clear_accum();
}
],
[ qr/]/ =>
sub {
nc_msg($verbose, "Unexpected prompt\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ timeout =>
sub {
$rconsole->send("\r");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node");
$rconsole->clear_accum();
$rc = 1;
}
],
);
return 1 if ($rc == 1);
# Next, the 'ls' command is sent. The result is a display of the entire
# device tree. The code then looks at the
# output from the ls command one line at a time, trying to match it with the
# regexp pattern in dev_pat, an array that contains all the supported network
# adapters. When found, the adapter type, the phandle and path name are saved
# in array variables.
#
# The complicated part is that the full path name may be spread over more than
# one line. Each line contains information about a node. If the supported
# network adapter is found on an nth level node, the full path name is the
# concatenation of the node information from the 0th level to the nth level.
# Hence, the path name from each level of the device tree needs to be saved.
#
# The pattern "\n(\[^\r]*)\r" is worth a second look. It took
# many hours of debug and reading the expect book to get it right. When more
# than one line of data is returned to expect at once, it is tricky getting
# exactly one line of data to look at. This pattern works because it looks
# for a newline(\n), any character other than a carriage return(\[^\r]*), and
# then for a carriage return. This causes expect to match a single line.
# If (.*) is used instead of (\[^\r]*), multiple lines are matched. (that was
# attempt number 1)
#
# Once a single line is found, it tries to determine what level in the device
# tree this line is.
# searching through subsequent lines and subsequent levels until an
# adapter is found.
# The level of the current line, which
# is calculated based on the assumption of "Level = (Leading Spaces - 1)/2".
# Leading Spaces is the number of spaces between the first colon ':' and the
# first non-space character of each line.
#
# Using the -d flag helped a lot in finding the correct pattern.
#
send_command($verbose, $rconsole, "ls \r");
$timeout = 60;
$done = 0;
while (!$done) {
# this expect call isolates single lines
# This code uses the tcl regexp to parse the single line
# isolated by expect.
#
# When the ok prompt ('>') is matched, this indicates the end of
# the ls output, at which point the done variable is set, to break
# out of the loop.
#
# All other lines are ignored.
#
@Result = ();
@Result = $rconsole->expect(
$timeout,
[ qr/(\n)([^\r]*)(\r)/ =>
sub {
nc_msg($verbose, "Parsing network adapters... \n");
#$rconsole->clear_accum();
}
],
[ qr/>/ =>
sub {
nc_msg($verbose, "finished \n");
$rconsole->clear_accum();
$done = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout isolating single line of ls output\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node");
$rconsole->clear_accum();
$rc = 1;
}
],
);
return 1 if ($rc == 1);
if ($result[2] =~ /(\w*)\:(\s*)\/(\S*)/) {
my $x1 = $1;
my $x2 = $2; #number of space
my $x3 = $3; #device
# Each level is inspected for a match
my $level = (length($x2) - 1) / 2;
$path{$level} = $x3;
my $j = 0;
for ($j = 0 ; $j < $dev_count ; $j++) {
if ($x3 =~ /$dev_pat[$j]/) {
if ($x3 =~ /hfi-ethernet/ and $dev_pat[$j] eq "ethernet") {
next;
}
my $i = 0;
for ($i = 0 ; $i <= $level ; $i++)
{
$full_path_name_array[$adapter_found] .= "/" . $path{$i};
}
$phandle_array[$adapter_found] = $x1;
$adap_type[$adapter_found] = $dev_type[$j];
$adapter_found++;
last;
}
}
}
}
# Did we find one or more adapters?
if ($adapter_found > 0) {
return 0;
} else {
nc_msg($verbose, "No network adapters found\n");
return 1;
};
};
}
#-------------------------------------------------------------------------------
=head3 get_adap_prop
PROCEDURE
Declare procedure to obtain the list of valid adapter connector properties
from the adapter card. Connector types can be rj45, sc, 9pin, aui,
bnc, or mic. Speeds can be 10, 100, or 1000. Duplex can be half or
full. This procedure will use the "supported-network-types"
argument to the get-package-property command to get the list of
properties for the given adapter.
=cut
#-----------------------------------------------------------------------------
sub get_adap_prop {
my $phandle = shift;
my $rconsole = shift;
my $node = shift;
my $verbose = shift;
my $timeout = 120;
my $rc = 0;
my $state = 0;
my @cmd;
my @done;
my @msg;
my @pattern;
my @newstate;
my @Result;
my @adap_prop_array;
my $nw_type;
my $nw_speed;
my $nw_conn;
my $nw_duplex;
my $vtag;
nc_msg($verbose, " Status: get_adap_prop start\n");
if ($secOF == 1) {
nc_msg($verbose, " Status: get_adap_prop: Secured OF\n");
$nw_type="ethernet";
$nw_speed="100";
$nw_conn="rj45";
$nw_duplex="duplex";
push @adap_prop_array, $nw_speed . "," . $nw_conn . "," . $nw_duplex;
nc_msg($verbose, "Status: Adding adapter properties to list\n");
if (scalar(@adap_prop_array) != 0) {
return \@adap_prop_array;
} else {
return 0;
};
}
else {
# state 0, stack count 0
$done[0] = 0;
$cmd[0] = "\" supported-network-types\" " . $phandle . " get-package-property\r";
$msg[0] = "Status: rc and all supported network types now on stack\n";
#$pattern[0] = "(.*)3 >(.*)";
#$pattern[0] = "3 >";
$pattern[0] = "ok";
$newstate[0] = 1;
# state 1, return code and string on stack
$done[1] = 0;
$cmd[1] = ".\r";
$msg[1] = "Status: All supported network types now on stack\n";
#$pattern[1] = "(.*)2 >(.*)";
#$pattern[1] = "2 >";
$pattern[1] = "ok";
$newstate[1] = 2;
# state 2, data ready to decode
$done[2] = 0;
$cmd[2] = "decode-string\r";
$msg[2] = "Status: supported network type isolated on stack\n";
#$pattern[2] = "(.*)ok(.*)4 >(.*)";
$pattern[2] = "4 >";
$newstate[2] = 3;
# state 3, decoded string on stack
$done[3] = 0;
$cmd[3] = "dump\r";
$msg[3] = "Status: supported network type off stack\n";
#$pattern[3] = ".*:.*:(.*):.*:.*:(.*):.*(2 >)(.*)";
$pattern[3] = "ok";
$newstate[3] = 4;
# state 4, need to check for more data to decode
$done[4] = 0;
$cmd[4] = ".s\r";
$msg[4] = "Status: checking for more supported network types\n";
#$pattern[4] = ".s (\[0-9a-f]* )(.*)>";
$pattern[4] = "ok";
$newstate[4] = 5;
# state 5, done decoding string, clear stack
$done[5] = 0;
$cmd[5] = ".\r";
$msg[5] = "Status: one entry on stack cleared\n";
#$pattern[5] = "(.*)ok(.*)1 >(.*)";
$pattern[5] = "ok";
$newstate[5] = 6;
# state 6, finish clearing stack, choose correct adapter type
$done[6] = 0;
$cmd[6] = ".\r";
$msg[6] = "Status: finished clearing stack\n";
#$pattern[6] = "(.*)ok(.*)0 >(.*)";
$pattern[6] = "ok";
$newstate[6] = 7;
# state 7, done
$done[7] = 1;
while ($done[$state] == 0) {
nc_msg($verbose, "Status: command is $cmd[$state]\n");
send_command($verbose, $rconsole, $cmd[$state]);
@Result = ();
@Result = $rconsole->expect(
$timeout,
[ qr/$pattern[$state]/i,
sub {
if ($state == 1) {
if ($rconsole->before() =~ /-\d+/) {
nc_msg($verbose, "Status: Error getting adapter property for phandle=$phandle.\n");
$state = 7;
$rconsole->clear_accum();
$rc = 1;
return 1;
}
}
nc_msg($verbose, $msg[$state]);
$state = $newstate[$state];
$rconsole->clear_accum();
}
],
[ qr/]/,
sub {
nc_msg($verbose, "Unexpected prompt\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ qr/(.*)DEFAULT(.*)/,
sub {
nc_msg($verbose, " Default catch error\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout in getting adapter properpties\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node\n");
$rconsole->clear_accum();
$rc = 1;
}
]
);
return 1 if ($rc == 1);
# After state 3, the network type is parsed and the connector
# type extracted. If the type hasn't been found, add it to
# the list of supported connector types.
if ($state == 4) {
# Build the adapter properties from the string
#regexp .*,(.*),(.*),(.*) $nw_type dummy nw_speed nw_conn nw_duplex
#set adap_prop "$nw_speed,$nw_conn,$nw_duplex"
#nc_msg "Status: Adapter properties are $adap_prop\n"
# if it's not in the list, add it, otherwise continue
if ($result[3] =~ /(\w*):(.*):(\w*)\,(\w*)\,(\w*):/) {
$nw_type = $3;
$nw_speed = $4;
$nw_conn = $5;
nc_msg($verbose, "nwtype is $3, nwspeed is $4, nwconn is $5\n");
}
if ($result[3] =~ /(\w*):(.*):(\w*)\,(\w*):/) {
$nw_duplex = $4;
nc_msg($verbose, "nwduplex is $4\n");
}
}
#push @adap_prop_array, $nw_type.",".$nw_speed.",".$nw_conn.",".$nw_duplex;
push @adap_prop_array, $nw_speed . "," . $nw_conn . "," . $nw_duplex;
nc_msg($verbose, "Status: Adding adapter properties to list\n");
# After state 4, a test is done to see if all of the supported
# network types have been decoded. If they have been, the
# state variable is left alone. if not, the state variable is
# set to 2, causing a loop back to the step where the
# decode-string command is sent.
if ($state == 5) {
if ($result[3] =~ /2 > \.s \w+ (\w*)/) {
$state = 2 if ($1 != 0);
}
}
}
if (scalar(@adap_prop_array) != 0) {
return \@adap_prop_array;
} else {
return 0;
};
};
}
#-------------------------------------------------------------------------------
=head3 get_mac_addr
PROCEDURE
Declare procedure to obtain the ethernet or mac address property from the
ethernet card.
3 commands lines containing a total of 6 commands are used.
The get-package-property command is an example of a command
that takes it's arguments off the stack and puts the results back onto the
stack. Because of this, the arguments for the get-package-property command
are in front of the command verb.
The only reason this procedure is implemented in a loop is to avoid coding
3 expect commands.
=cut
#-----------------------------------------------------------------------------
sub get_mac_addr {
my $phandle = shift;
my $rconsole = shift;
my $node = shift;
my $verbose = shift;
my $timeout = 120;
my $state = 0;
my $nowdone = 0;
my @Result;
my $mac_rc;
my @cmd;
my @done;
my $newdone;
my @msg;
my @pattern;
my @newstate;
my $mac_address;
my $rc = 0;
if ($secOF == 1) {
nc_msg($verbose, " Status: get_mac_addr: Secured OF\n");
my $loc = substr($phandle,0,-1);
$rconsole->clear_accum();
while (!$newdone) {
@Result = ();
send_command($verbose, $rconsole, "DISPLAY_MAC_ADDRESS $loc\r");
@Result = $rconsole->expect(
$timeout,
[ qr/(\n)([^\r]*)(\r)/ =>
sub {
nc_msg($verbose, "Parsing MAC Address... \n");
#$rconsole->clear_accum();
}
],
[ qr/>/ =>
sub {
nc_msg($verbose, "finished \n");
$rconsole->clear_accum();
$newdone = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout isolating single line of ls output\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node");
$rconsole->clear_accum();
$rc = 1;
}
],
);
return 1 if ($rc == 1);
my @lines = grep(/MAC/, @Result);
my @values1 = split(' ', $lines[1]);
$mac_address = $values1[2];
nc_msg($verbose, "1GbE Adapter MAC Address: $mac_address \n");
# Return mac address
if ($mac_address) {
return $mac_address;
} else {
return undef;
};
}
}
else {
nc_msg($verbose, "Status: get_mac_addr start\n");
# cmd(0) could have been sent as 3 commands. " mac-address" (tcl forces
# the use of \") is the first command on this line. The result of entering
# " mac-address" is that 2 stack entries are created, and address and a length.
#
# The next command in cmd(0) is the phandle with no quotes. This results in
# one stack entry because the phandle is an address.
#
# the third command in cmd(0) is get-package-property. After this command, there
# are 3 stack entries (return code, address and length of mac-address).
# state 0, stack count 0, send command
$done[0] = 0;
$cmd[0] = "\" local-mac-address\" " . $phandle . " get-package-property\r";
$msg[0] = "Status: return code and mac-address now on stack\n";
$pattern[0] = "local-mac-address.*ok"; #"\s*3 >";
$newstate[0] = 1;
# cmd(1) is a dot (.). This is a stack manipulation command that removes one
# thing from the stack. pattern(1) is looking for a prompt with the 2 indicating
# that there are 2 things left on the stack.
# state 1, return code and mac-address on stack
$done[1] = 0;
$cmd[1] = ".\r";
$msg[1] = "Status: mac-address now on stack\n";
#$pattern[1] = "(.*)2 >(.*)";
$pattern[1] = "ok"; #"2 >";
$newstate[1] = 2;
# cmd(2) is the dump command. This takes an address and a length off the stack
# and displays the contents of that storage in ascii and hex. The long pattern
# puts the hex into the variable expect_out(3,string). The tcl verb 'join' is
# used to eliminate the spaces put in by the dump command.
# state 2, mac-address on stack
$done[2] = 0;
$cmd[2] = ": dump-mac ( prop-addr prop-len -- ) \
cr \
dup decode-bytes 2swap 2drop ( data-addr data-len ) \
( data-len ) 0 ?do \
dup c@ 2 u.r ( data-addr ) \
char+ ( data-addr' ) \
loop \
drop \
cr \
; \r";
$msg[2] = "Status: set command\n";
$pattern[2] = "ok";
$newstate[2] = 3;
$done[3] = 0;
$cmd[3] = "dump-mac\r";
$msg[3] = "Status: mac-address displayed, stack empty\n";
$pattern[3] = "dump-mac(\\s*)(\\w*)(\\s*)ok";
$newstate[3] = 4;
# state 4, all done
$done[4] = 1;
while ($done[$state] == 0) {
@Result = ();
send_command($verbose, $rconsole, $cmd[$state]);
@Result = $rconsole->expect(
$timeout,
[ qr/$pattern[$state]/ =>
sub {
if ($state == 1) {
if ($rconsole->before() =~ /-\d+/) {
nc_msg($verbose, "Status: Error getting MAC address for phandle=$phandle.\n");
$rconsole->clear_accum();
$state = 4;
$rc = 1;
return undef;
}
}
nc_msg($verbose, $msg[$state]);
$state = $newstate[$state];
$rconsole->clear_accum();
}
],
[ qr/1 > / =>
sub {
$rconsole->clear_accum();
if ($state eq 0) {
# An error occurred while obtaining the mac address. Log the error,
# but don't quit nodecond. instead, return NA for the address
#
send_command($verbose, $rconsole, ".\r");
$rconsole->expect(
$timeout,
#[ qr/(-*\[0-9\]*) ok(.*)0 >(.*)/i,
[ qr/0 >/i,
sub {
#$mac_rc = $expect_out;
nc_msg($verbose, "Status: Error getting MAC address for phandle=$phandle. RC=$mac_rc.\n");
nc_msg($verbose, "Could not obtain MAC address; setting MAX to NA\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout when getting mac address\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, " Cannot connect to $node\n");
$rconsole->clear_accum();
$rc = 1;
}
]
);
}
}
],
[ qr/]/ =>
sub {
nc_msg($verbose, "Unexpected prompt\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ qr/(.*)DEFAULT(.*)/ =>
sub {
nc_msg($verbose, "Default catch error\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout in getting mac address\n");
nc_msg($verbose, "timeout state is $state\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node");
$rconsole->clear_accum();
$rc = 1;
}
],
);
return undef if ($rc == 1);
}
# if the state is 0, 1, or 2, an error occurred and the join will fail
if ($state == 4) {
if ($result[2] =~ /dump-mac\s*(\w*)\s*ok/) {
$mac_address = $1;
}
return $mac_address;
} else {
return undef;
};
};
}
#-------------------------------------------------------------------------------
=head3 get_adaptr_loc
PROCEDURE
Declare procedure to obtain the list of ethernet adapters, their physical
location codes and MAC addresses.
The get-package-property command is an example of a command
that takes it's arguments off the stack and puts the results back onto the
stack. Because of this, the arguments for the get-package-property command
are in front of the command verb.
The only reason this procedure is implemented in a loop is to avoid coding
3 expect commands.
=cut
#-----------------------------------------------------------------------------
sub get_adaptr_loc {
my $phandle = shift;
my $rconsole = shift;
my $node = shift;
my $verbose = shift;
my @cmd;
my @done;
my @msg;
my @pattern;
my @newstate;
my $state = 0;
my $timeout = 60; # shouldn't take long
my @Result;
my @path;
my $loc_code;
my $rc = 0;
if ($secOF == 1) {
nc_msg($verbose, " Status: get_adaptr_loc: Secured OF\n");
return $phandle;
}
else {
nc_msg($verbose, "Status: get_adaptr_loc start\n");
# cmd(0) could have been sent as 3 commands. " ibm,loc-code" (tcl forces
# the use of \") is the first command on this line. The result of entering
# " ibm,loc-code" is that 2 stack entries are created, and address and a length.
#
# The next command in cmd(0) is the phandle with no quotes. This results in
# one stack entry because the phandle is an address.
#
# the third command in cmd(0) is get-package-property. After this command, there
# are 3 stack entries (return code, address and length of mac-address).
# state 0, stack count 0, send command
$done[0] = 0;
$cmd[0] = "\" ibm,loc-code\" $phandle get-package-property\r";
$msg[0] = "Status: return code and loc-code now on stack\n";
#$pattern[0] = "(.*)3 >(.*)";
#$pattern[0] = "3 >";
$pattern[0] = "ok";
$newstate[0] = 1;
# cmd(1) is a dot (.). This is a stack manipulation command that removes one
# thing from the stack. pattern(1) is looking for a prompt with the 2 indicating
# that there are 2 things left on the stack.
# state 1, return code and loc-code on stack
$done[1] = 0;
$cmd[1] = ".\r";
$msg[1] = "Status: loc-code now on stack\n";
#$pattern[1] = "(.*)2 >(.*)";
$pattern[1] = "ok"; #"2 >";
$newstate[1] = 2;
# state 2, loc-code on stack
$done[2] = 0;
$cmd[2] = "dump\r";
$msg[2] = "Status: loc-code displayed, stack empty\n";
#$pattern[2] = "(.*)(: )(.*)( :)(.*)(\.: ok)";
$pattern[2] = "ok";
$newstate[2] = 3;
# state 3, all done
$done[3] = 1;
while ($done[$state] eq 0) {
@Result = ();
nc_msg($verbose, "PROGRAM Status: command is $cmd[$state]\n");
send_command($verbose, $rconsole, $cmd[$state]);
@Result = $rconsole->expect(
$timeout,
[ qr/$pattern[$state]/ =>
sub {
if ($state == 1) {
if ($rconsole->before() =~ /-\d+/) {
nc_msg($verbose, "Status: Error getting adapter location for phandle=$phandle.");
$rconsole->clear_accum();
$state = 3;
$rc = 1;
return undef;
}
}
nc_msg($verbose, $msg[$state]);
$rconsole->clear_accum();
$state = $newstate[$state];
}
],
[ qr/1 >/ =>
sub {
$rconsole->clear_accum();
my $exp = shift;
if ($state eq 0) {
send_command($verbose, $rconsole, ".\r");
$exp->expect(
#[qr/(-*\[0-9\]*) ok(.*)0 >(.*)/=>
[ qr/0 >/ =>
sub {
$rconsole->clear_accum();
my $loc_rc = shift;
nc_msg($verbose, "Error getting adapter physical location.\n");
nc_msg($verbose, "Status: Error getting physical location for phandle=$phandle. RC=$loc_rc.\n");
$rc = 1;
}
],
[ timeout =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, "Timeout when openning console\n");
$rc = 1;
}
],
[ eof =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, "Cannot connect to the $node\n");
$rc = 1;
}
],
);
}
}
],
[ qr/]/ =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, "Unexpected prompt\n");
$rc = 1;
}
],
[ qr/(.*)DEFAULT(.*)/ =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, "Default catch error\n");
$rc = 1;
}
],
[ timeout =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, "Timeout when openning console\n");
$rc = 1;
}
],
[ eof =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, "Cannot connect to the $node\n");
$rc = 1;
}
],
);
return undef if ($rc == 1);
}
# Did we find one or more adapters?
my @loc_array = split /\n/, $result[3];
my $found = 0;
$loc_code = '';
foreach my $line (@loc_array) {
if ($line =~ /(\w*):(.*):([\w|\.|-]*):/) {
$loc_code .= $3;
$found = 1;
}
}
if ($found) {
$loc_code =~ s/\.$//;
return $loc_code;
} else {
return undef;
};
};
}
#-------------------------------------------------------------------------------
=head3 ping_server
PROCEDURE
Declare procedure to obtain the list of valid adapter connector properties
from the adapter card. Connector types can be rj45, sc, 9pin, aui,
bnc, or mic. Speeds can be 10, 100, or 1000. Duplex can be half or
full. This procedure will use the "supported-network-types"
argument to the get-package-property command to get the list of
properties for the given adapter.
=cut
#-----------------------------------------------------------------------------
sub ping_server {
my $phandle = shift;
my $full_path_name = shift;
my $rconsole = shift;
my $node = shift;
my $mac_address = shift;
my $verbose = shift;
my $adap_speed = shift;
my $adap_duplex = shift;
my $list_type = shift;
my $server_ip = shift;
my $client_ip = shift;
my $gateway_ip = shift;
my $adap_prop_list_array;
#my %env = shift;
my $command;
my $linklocal_ip;
my @Result;
my @done;
my $newdone=0;
my @cmd;
my @msg;
my @pattern;
my @newstate;
my $state = 0;
my $timeout;
my $j = 0;
my $tty_do_ping = 0;
my $stack_level = 0;
my $properties_matched = 0;
my $adap_conn;
my $speed_list;
my $duplex_list;
my @adap_conn_list;
my $i;
my $ping_debug;
my $ping_rc;
my $rc = 0;
my $netmask="255.255.255.0";
nc_msg($verbose, "Status: ping_server start\n");
if ($secOF == 1) {
nc_msg($verbose, " Status: ping_server: Secured OF\n");
nc_msg($verbose, " Adapter Location: \n");
my $loc = substr($phandle,0,-1);
$rconsole->clear_accum();
send_command($verbose, $rconsole, "PING $loc $server_ip,$client_ip,$gateway_ip,,$netmask \r");
while (!$newdone) {
@Result = ();
@Result = $rconsole->expect(
$timeout,
[ qr/(\n)([^\r]*)(\r)/ =>
sub {
nc_msg($verbose, "Pinging... \n");
#$rconsole->clear_accum();
}
],
[ qr/>/ =>
sub {
nc_msg($verbose, "finished \n");
$rconsole->clear_accum();
$newdone = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout isolating single line of ls output\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node");
$rconsole->clear_accum();
$rc = 1;
}
],
);
return 1 if ($rc == 1);
my $line = grep(/SMS Macro Operation Succeeded./, @Result);
if ($line eq 1) {
nc_msg($verbose, "# $full_path_name ping successful.\n");
$ping_rc=0;
last;
} else {
nc_msg($verbose, "# $full_path_name ping unsuccessful.\n");
$ping_rc=1;
};
};
return $ping_rc;
}
else {
# If the adapter type chosen is ethernet, need to set the speed and duplex
# of the adapter before we perform the ping. If token ring or fddi,
# this is not required, so begin with state 2.
#
# cmd(0) sets the given adapter as active, to allow setting of speed
# and duplex
#
# cmd(1) writes the settings to the current adapter
#
# cmd(2) selects the /packages/net node as the active package to access the
# ping command.
#
# The next command in cmd(3) is the ping command. This places the return code
# on the stack. A return code of 0 indicates success.
#
# state 0, set the current adapter
$done[0] = 0;
$cmd[0] = "dev $full_path_name\r";
$msg[0] = "Status: selected $full_path_name as the active adapter\n";
#$pattern[0] = ".*dev(.*)0 >(.*)";
$pattern[0] = "0 >";
$newstate[0] = 1;
# state 1, send property command to $selected type;
$done[1] = 0;
$cmd[1] = "\" ethernet,$adap_speed,$adap_conn,$adap_duplex\" encode-string \" chosen-network-type\" property\r";
$msg[1] = "Status: chosen network type set\n";
#$pattern[1] =".*ethernet(.*)0 >(.*)";
$pattern[1] = "0 >";
$newstate[1] = 2;
# state 2, activate /packages/net
$done[2] = 0;
$cmd[2] = "dev /packages/net\r";
$msg[2] = "Status: selected the /packages/net node as the active package\n";
$pattern[2] = ".*dev.*packages.*net(.*)ok(.*)0 >(.*)";
#$pattern[2] = "ok";
$newstate[2] = 3;
# state 3, ping the server
$done[3] = 0;
$msg[3] = "Status: ping return code now on stack\n";
$newstate[3] = 4;
# get the timeout for ping test
my $to4pt;
if ($ENV{TIMEOUT4PINGTEST} =~ /^\d+$/) {
$to4pt = ",$ENV{TIMEOUT4PINGTEST}";
}
#IPv6
if ($server_ip =~ /:/) {
#::1, calculate link local address
if ($client_ip eq "::1") {
my $command = "/opt/xcat/share/xcat/tools/mac2linklocal -m $mac_address";
$linklocal_ip = $rconsole->send($command);
} else {
$linklocal_ip = $client_ip;
}
$cmd[3] = "ping $full_path_name:ipv6,$server_ip,$linklocal_ip,$gateway_ip$to4pt\r";
} else {
###$cmd[3] = "ping $full_path_name:$server_ip,$client_ip,$gateway_ip$to4pt\r";
$cmd[3] = "ping $full_path_name:$server_ip,$client_ip,$gateway_ip$to4pt\r";
}
$pattern[3] = ".*ping(.*)ok(.*)0 >(.*)";
# state 4, all done
$done[4] = 0;
$cmd[4] = "0 to my-self\r";
$msg[4] = "Status: resetting pointer\n";
#$pattern[4] = "(.*)ok(.*)0 >(.*)";
$pattern[4] = "ok";
$newstate[4] = 5;
# state 5, all done
$done[5] = 1;
# for ping, only need to set speed and duplex for ethernet adapters
#
if ($list_type eq "ent") {
$state = 0;
# Get the list of properties for this adapter
#
$adap_prop_list_array = get_adap_prop($phandle, $rconsole, $node, $verbose);
if ($adap_prop_list_array == 1) {
nc_msg($verbose, "ERROR return from get_adap_prop\n");
return 1;
}
if ($adap_prop_list_array eq 0) {
nc_msg($verbose, "No properties found for adapter '$full_path_name'\n");
return 1;
}
# Now need to verify that the network params we were passed are valid for
# the given adapter
#
my $a_speed;
my $a_conn;
my $a_duplex;
for my $prop (@$adap_prop_list_array) {
if ($prop =~ /(.*),(.*),(.*)/) {
$a_speed = $1;
$a_conn = $2;
$a_duplex = $3;
if (($a_speed eq $adap_speed) && ($a_duplex eq $adap_duplex)) {
$properties_matched = 1;
if (grep { $_ eq $a_conn } @adap_conn_list) {
push @adap_conn_list, $a_conn;
}
}
}
}
if ($properties_matched eq 0) {
$adap_speed = $a_speed;
$adap_duplex = $a_duplex;
$properties_matched = 1;
push @adap_conn_list, $a_conn;
}
$i = scalar(@adap_conn_list);
if ($properties_matched eq 0) {
nc_msg($verbose, "'$adap_speed/$adap_duplex' settings are not supported on this adapter\n");
return 1;
}
} else {
$state = 2;
}
$timeout = 300;
while ($done[$state] eq 0) {
send_command($verbose, $rconsole, $cmd[$state]);
@Result = $rconsole->expect(
$timeout,
[ qr/$pattern[$state]/s =>
sub {
nc_msg($verbose, $msg[$state]);
$rconsole->clear_accum();
$state = $newstate[$state];
}
],
[ qr/]/ =>
sub {
nc_msg($verbose, "Unexpected prompt\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ qr/(.*)DEFAULT(.*)/ =>
sub {
nc_msg($verbose, "Default catch error\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout when openning console\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to the $node\n");
$rconsole->clear_accum();
$rc = 1;
}
],
);
return 1 if ($rc == 1);
if ($state == 1) {
$adap_conn = $adap_conn_list[$j];
$cmd[1] = "\" ethernet,$adap_speed,$adap_conn,$adap_duplex\" encode-string \" chosen-network-type\" property\r";
nc_msg($verbose, "Status: Trying connector type $adap_conn\n");
$j++;
}
if ((($tty_do_ping == 1) && ($state == 4)) || ($tty_do_ping != 1) && ($state == 3)) {
$ping_debug = $result[2];
}
if ((($tty_do_ping == 1) && ($state == 5)) || ($tty_do_ping != 1) && ($state == 4)) {
if (($tty_do_ping == 1) && ($state == 5)) {
#$ping_rc = $result[2];
$stack_level = length($result[4]);
} elsif (($state == 4) && ($tty_do_ping != 1) && ($result[2] =~ /PING SUCCESS/)) {
$ping_rc = 0;
} else {
$ping_rc = 1;
}
if ($ping_rc eq 0) {
nc_msg($verbose, "# $full_path_name ping successful.\n");
} elsif ($ping_rc == 1) {
nc_msg($verbose, "# $full_path_name ping unsuccessful.\n");
nc_msg($verbose, "# $full_path_name ping unsuccessful.\n");
nc_msg($verbose, "$ping_debug\n");
# An unsuccessful return may leave another item on the stack to
# be removed. Check for it, and remove if necessary
my $matchexp = 0;
my @exp_out;
while ($stack_level != 0) {
@exp_out = ();
send_command($verbose, $rconsole, ".\r");
@exp_out = $rconsole->expect(
[ qr/(\[0-9\]*) ok(.*)(\[0-1\]) >(.*)/s =>
sub {
$rconsole->clear_accum();
$matchexp = 1;
}
],
[ qr/]/ =>
sub {
nc_msg($verbose, "Unexpected prompt\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ qr/(.*)DEFAULT(.*)/ =>
sub {
nc_msg($verbose, "Default catch error\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ timeout =>
sub {
nc_msg($verbose, "Timeout in ping server\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[ eof =>
sub {
nc_msg($verbose, "Cannot connect to $node\n");
$rconsole->clear_accum();
$rc = 1;
}
],
);
if ($matchexp) {
$matchexp = 0;
$stack_level = length($exp_out[4]);
nc_msg($verbose, "Status: stack_level is <$stack_level>\n");
}
}
# Check if there are any more adapter connector types
# to try
#
if (($list_type eq "ent") && ($j < $i)) {
$adap_conn = $adap_conn_list[$j];
nc_msg($verbose, "Status: Trying connector type $adap_conn\n");
$j++;
# Need to work around a default catch problem in open
# firmware by sending a "0 to my-self" instruction
# following the ping. To make sure this happens in
# this rare case where we have an adapter with multiple connectors,
# we have to force the instruction into the 0th slot in
# the array. This is OK, since we only set the current
# adapter once, upon entering this procedure.
#
$done[0] = 0;
$cmd[0] = "0 to my-self\r";
$msg[0] = "Status: resetting pointer\n";
$pattern[0] = "(.*)ok(.*)0 >(.*)";
$newstate[0] = 1;
$state = 0;
}
} else {
nc_msg($verbose, "Unexpected ping return code\n");
return 1;
}
}
}
return $ping_rc;
};
}
#-------------------------------------------------------------------------------
=head3 set_disk_boot
PROCEDURE
Declare procedure to obtain the list of valid adapter connector properties
from the adapter card. Connector types can be rj45, sc, 9pin, aui,
bnc, or mic. Speeds can be 10, 100, or 1000. Duplex can be half or
full. This procedure will use the "supported-network-types"
argument to the get-package-property command to get the list of
properties for the given adapter.
=cut
#-----------------------------------------------------------------------------
sub set_disk_boot {
my @expect_out = shift;
my $rconsole = shift;
my $node = shift;
my $verbose = shift;
my $x0;
my $x1;
my $x2;
my $command;
my @done;
my @cmd;
my @msg;
my @pattern;
my @newstate;
my $timeout;
my $state;
my $rc = 0;
if ($secOF == 1) {
nc_msg($verbose, " Status: set_disk_boot: Secured OF\n");
# state 0, get SMS screen
$done[0] = 0;
$cmd[0] = "DISPLAY_BOOTSEQ\r";
$msg[0] = "Status: sending return to repaint SMS screen\n";
$pattern[0] = "(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)Storage(\r)";
$newstate[0] = 1;
# state 1, Set Default Boot Seq
$done[1] = 0;
$cmd[1] = "SET_DEFAULT_BOOTSEQ\r";
$msg[1] = "Status: Set default boot sequence\n";
$pattern[1] = "(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)Your default boot sequence has been restored(\r)";
$newstate[1] = 2;
# state 2, all done
$done[2] = 1;
$timeout = 30;
$state = 0;
while ($done[$state] eq 0) {
send_command($verbose, $rconsole, $cmd[$state]);
$rconsole->expect(
[ qr/$pattern[$state]/ =>
sub {
$rconsole->clear_accum();
$state = $newstate[$state];
}
],
[ qr/THE SELECTED DEVICES WERE NOT DETECTED IN THE SYSTEM/ =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, " Status: THE hard disk WERE NOT DETECTED IN THE SYSTEM!\n");
$rc = 1;
}
],
[ timeout =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, "Timeout in settin boot order\n");
$rc = 1;
}
],
[ eof =>
sub {
$rconsole->clear_accum();
nc_msg($verbose, "Cannot connect to $node\n");
$rc = 1;
}
],
);
if ($rc == 1) {
return 1;
} else {
return 0;
}
}
return 0;
}
else {
# state 0, get SMS screen
$done[0] = 0;
if ($expect_out[0] =~ /(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)Select Boot Options(\r)/) {
$x0 = $1;
$x1 = $2;
$x2 = $3;
$command = $4;
}
$cmd[0] = "$command\r";
$msg[0] = "Status: sending return to repaint SMS screen\n";
$pattern[0] = "(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)Configure Boot Device Order(\r)";
$newstate[0] = 1;
# state 1, Multiboot
$done[1] = 0;
$msg[1] = "Status: Multiboot\n";
$pattern[1] = "(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)Select 1st Boot Device(\r)";
$newstate[1] = 2;
# state 2, Configure Boot Device Order
$done[2] = 0;
$msg[2] = "Status: Configure Boot Device Order";
$pattern[2] = "(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)Hard Drive(.*)";
$newstate[2] = 3;
# state 3, Select Device Type
$done[3] = 0;
$msg[3] = "Status: Select Device Type";
$pattern[3] = "(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)SCSI(.*)";
$newstate[3] = 4;
# state 4, Select Media Type
$done[4] = 0;
$msg[4] = "Status: Select Media Type";
$pattern[4] = "(\n)(\[ ])(\[1])(\[.])(\[ ]+)(\\S+)(.*)";
$newstate[4] = 5;
# state 5, Select Media Adapter
$done[5] = 0;
$msg[5] = "Status: Select Media Adapter";
$pattern[5] = "(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)(\\S)(\[ ]+)SCSI (\[0-9]+) MB Harddisk(.*)loc=(.*)\[)]";
$newstate[5] = 6;
# state 6, Select Device
$done[6] = 0;
$msg[6] = "Status: Select Device";
$pattern[6] = "(\n)(\[ ])(\[0-9])(\[.])(\[ ]+)Set Boot Sequence(.*)";
$newstate[6] = 7;
# state 7, Select Task
$done[7] = 0;
$msg[7] = "Status: Select Task";
$pattern[7] = "(.*)Current Boot Sequence(.*)";
$newstate[7] = 8;
# state 8, Return to Main Menu
$done[8] = 0;
$cmd[8] = "M";
$msg[8] = "Status: Restored Default Setting
|
@wabe1968 Can you try the updated file ? |
@gurevichmark @hgunasin thanks, Walter Bernocchi IBM - Lab Services Cognitive Consultant |
Hi Mark
Hope you are well. Not sure if there is a way/how to make these updated
perl module published as a "Supported" code within xCAT distributions
adding support for "Secured Firmware"?. Any advice is much appreciated.
Thanks.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 07/11/2020 03:48 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@wabe1968 Can you try the updated file ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Hi Mark, sorry for my late reply but the system i was using for the testing has not been available for several days. |
@wabe1968 @hgunasin
|
Hi Mark
I had to hard code -a option with a variable due to the lack of time to get
going in my project. That bit of code need to test option and set
accordingly. I did not have time to do it. I think I mentioned that when I
provided this initially. I was also having difficulty getting -a option
passed over to the .pm properly. Thanks.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 08/13/2020 06:28 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@wabe1968 @hgunasin
I am trying to review the code you contributed, but I must be missing
something:
I can see the new option -a added to the Usage, but I do not see that
option examined anywhere in the code.
I can see several places where secOF flag is being tested - if
($secOF == 1). But it looks like it gets defined as my $secOF=1; and
then never gets set to anything else.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
@hgunasin Thank you for your contribution, it truly help us keep xCAT product up to date. Unfortunately we can not merge the submitted code as is, because of this hardcoded |
Hi Mark
Let me see if I could add this option properly. Is there any
pointers/documentation where I could refer to pass this in an appropriate
way to the .pm as when I tried doing this, it was not passing the option -a
option properly. Thanks.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 08/18/2020 11:10 PM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@hgunasin Thank you for your contribution, it truly help us keep xCAT
product up to date.
Unfortunately we can not merge the submitted code as is, because of this
hardcoded -a option.
Is there any way you can make changes to handle it properly ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
In function
Did you try to process
|
@hgunasin Are you still planning to make changes to your code to properly handle |
Hi Mark
Yes - I will do it within next few days and get back to you. Sorry for the
delay as I was busy. Thanks.
Regards,
HEMANTHA (Hemantha) GUNASINGHE
IT Specialist
Phone: 61-2-9354-7314 | Mobile: 61-422-004-019
E-mail: [email protected]
601 Pacific Highway
St Leonards, NSW
2065
Australia
From: Mark Gurevich <[email protected]>
To: xcat2/xcat-core <[email protected]>
Cc: Hemantha Gunasinghe <[email protected]>, Mention
<[email protected]>
Date: 09/09/2020 12:57 AM
Subject: [EXTERNAL] Re: [xcat2/xcat-core] xCAT support for Secured OF
(Openfirmware) prompt (#6637)
@hgunasin Are you still planning to make changes to your code to properly
handle -a option ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
@hgunasin Great. If you can, use this version of the file (https://github.com/xcat2/xcat-core/blob/3b4434c8c652757ccd9dabfdda1dfa106c4409f2/perl-xCAT/xCAT/LparNetbootExp.pm) from my PR #6793. |
Hi
Background
I use xCAT to build and deploy VIO Servers and Novalink for a large customer using Power8 and Power9 systems which are HMC connected and Novalink managed once built.
I have come across an issue where we are unable to rinstall with netboot as when an LPAR is powered on, in firmware 940 on P9 systems it uses a "Secured OF" prompt rather than the firmware prompt which it had on firmware level 930 and below. This is preventing the use of the xCAT capabiities to netboot and install VIO Servers and RHEL operating systems on a LPAR using HMCs.
Is there any plans to support these?. If no what would be the alternative we could use?. I need Urgent help at least to understand where we are going with xCAT with support for "Secured OF" prompt.
Thanks in advance and appreciate any comments on this urgently.
The text was updated successfully, but these errors were encountered: