2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-29 09:13:08 +00:00

Merge pull request #3586 from gurevichmark/openbmc_rflash_activate_pnor

Openbmc rflash activate pnor
This commit is contained in:
Victor Hu 2017-08-02 15:29:49 -04:00 committed by GitHub
commit 36b025c4c7
4 changed files with 218 additions and 36 deletions

View File

@ -46,13 +46,20 @@ NeXtScale FPC specific:
\ **rflash**\ \ *noderange*\ \ *http_directory*\
OpenPOWER BMC specific:
=======================
OpenPOWER BMC specific (using IPMI):
====================================
\ **rflash**\ \ *noderange*\ [\ *hpm_file_path*\ | \ **-d=**\ \ *data_directory*\ ] [\ **-c | -**\ **-check**\ ] [\ **-**\ **-retry=**\ \ *count*\ ] [\ **-V**\ ]
OpenPOWER OpenBMC specific :
============================
\ **rflash**\ \ *noderange*\ [\ *tar_file_path*\ | \ *image_id*\ ] [\ **-c | -**\ **-check**\ ] [\ **-a | -**\ **-activate**\ ] [\ **-l | -**\ **-list**\ ] [\ **-u | -**\ **-upload**\ ]
*******************
\ **Description**\
@ -118,14 +125,22 @@ NeXtScale FPC specific:
The command will update firmware for NeXtScale FPC when given an FPC node and the http information needed to access the firmware. The http information required includes both the MN IP address as well as the directory containing the firmware. It is recommended that the firmware be downloaded and placed in the /install directory structure as the xCAT MN /install directory is configured with the correct permissions for http. Refer to the doc to get more details: XCAT_NeXtScale_Clusters
OpenPOWER specific:
===================
OpenPOWER specific (using IPMI):
================================
The command will update firmware for OpenPOWER BMC when given an OpenPOWER node and either the hpm formatted file path or path to a data directory.
\ **Note:**\ When using \ **rflash**\ in hierarchical environment, the hpm file or data directory must be accessible from Service Nodes.
OpenPOWER OpenBMC specific:
===========================
The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER node and either an update .tar file or an uploaded image id.
\ **Note:**\ When using \ **rflash**\ in hierarchical environment, the .tar file must be accessible from Service Nodes.
***************
\ **Options**\
@ -141,7 +156,7 @@ The command will update firmware for OpenPOWER BMC when given an OpenPOWER node
\ **-c|-**\ **-check**\
Check the firmware version of BMC and HPM file.
Check the firmware version of BMC and an update file.
@ -187,6 +202,24 @@ The command will update firmware for OpenPOWER BMC when given an OpenPOWER node
\ **-a|-**\ **-activate**\
Activate update image. Image id must be specified.
\ **-l|-**\ **-list**\
List currently uploaded update images. "(\*)" indicates currently active image.
\ **-u|-**\ **-upload**\
Upload update image. Specified file must be in .tar format.
\ **-v|-**\ **-version**\
Displays the command's version.

View File

@ -342,8 +342,10 @@ my %usage = (
rflash <noderange> -p <rpm_directory> [--activate {disruptive|deferred}] [-d <data_directory>]
rflash <noderange> [--commit | --recover] [-V|--verbose]
rflash <noderange> [--bpa_acdl]
PPC64LE (using BMC Management) specific:
rflash <noderange> [-c | --check] [--retry=<count>] [-V] [<hpm_file>|-d=<data_directory>]",
PPC64LE (using IPMI Management) specific:
rflash <noderange> [-c|--check] [--retry=<count>] [-V] [<hpm_file>|-d=<data_directory>]
PPC64LE (using OpenBMC Management) specific:
rflash <noderange> [-c|--check] [-l|--list] [-a|--activate] [-u|--upload] [<tar_file>|<image_id>]",
"mkhwconn" =>
"Usage:
mkhwconn [-h|--help]

View File

@ -22,10 +22,14 @@ B<rflash> I<noderange> {B<--commit>|B<--recover>}
B<rflash> I<noderange> I<http_directory>
=head2 OpenPOWER BMC specific:
=head2 OpenPOWER BMC specific (using IPMI):
B<rflash> I<noderange> [I<hpm_file_path> | B<-d=>I<data_directory>] [B<-c>|B<--check>] [B<--retry=>I<count>] [B<-V>]
=head2 OpenPOWER OpenBMC specific :
B<rflash> I<noderange> [I<tar_file_path> | I<image_id>] [B<-c>|B<--check>] [B<-a>|B<--activate>] [B<-l>|B<--list>] [B<-u>|B<--upload>]
=head1 B<Description>
The B<rflash> command initiates Firmware updates on supported xCAT nodes. Licensed Internal Code (also known as microcode) updates are performed on supported HMC-attached POWER5 and POWER6 pSeries nodes, and POWER7 systems using Direct FSP management.
@ -79,11 +83,16 @@ For more details about the Firmware Update using Direct FSP/BPA Management, refe
The command will update firmware for NeXtScale FPC when given an FPC node and the http information needed to access the firmware. The http information required includes both the MN IP address as well as the directory containing the firmware. It is recommended that the firmware be downloaded and placed in the /install directory structure as the xCAT MN /install directory is configured with the correct permissions for http. Refer to the doc to get more details: XCAT_NeXtScale_Clusters
=head2 OpenPOWER specific:
=head2 OpenPOWER specific (using IPMI):
The command will update firmware for OpenPOWER BMC when given an OpenPOWER node and either the hpm formatted file path or path to a data directory.
B<Note:> When using B<rflash> in hierarchical environment, the hpm file or data directory must be accessible from Service Nodes.
=head2 OpenPOWER OpenBMC specific:
The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER node and either an update .tar file or an uploaded image id.
B<Note:> When using B<rflash> in hierarchical environment, the .tar file must be accessible from Service Nodes.
=head1 B<Options>
=over 7
@ -94,7 +103,7 @@ Writes the command's usage statement to standard output.
=item B<-c|--check>
Check the firmware version of BMC and HPM file.
Check the firmware version of BMC and an update file.
=item B<-p> I<directory>
@ -124,6 +133,18 @@ Used to recover the flash image in the permanent side of the chip to the tempora
Specify number of times to retry the update if failure is detected. Default value is 2. Value of 0 can be used to indicate no retries.
=item B<-a|--activate>
Activate update image. Image id must be specified.
=item B<-l|--list>
List currently uploaded update images. "(*)" indicates currently active image.
=item B<-u|--upload>
Upload update image. Specified file must be in .tar format.
=item B<-v|--version>
Displays the command's version.

View File

@ -156,6 +156,29 @@ my %status_info = (
RFLASH_FILE_UPLOAD_RESPONSE => {
process => \&rflash_response,
},
RFLASH_UPDATE_ACTIVATE_REQUEST => {
method => "PUT",
init_url => "$openbmc_project_url/software",
data => "xyz.openbmc_project.Software.Activation.RequestedActivations.Active",
},
RFLASH_UPDATE_ACTIVATE_RESPONSE => {
process => \&rflash_response,
},
RFLASH_UPDATE_CHECK_STATE_REQUEST => {
method => "GET",
init_url => "$openbmc_project_url/software",
},
RFLASH_UPDATE_CHECK_STATE_RESPONSE => {
process => \&rflash_response,
},
RFLASH_SET_PRIORITY_REQUEST => {
method => "PUT",
init_url => "$openbmc_project_url/software",
data => "false", # Priority state of 0 sets image to active
},
RFLASH_SET_PRIORITY_RESPONSE => {
process => \&rflash_response,
},
RINV_REQUEST => {
method => "GET",
@ -560,28 +583,48 @@ sub parse_args {
}
} elsif ($command eq "rflash") {
#
# disable function until fully tested
# disable function until fully supported by openbmc
# Currently waiting for issue https://github.com/openbmc/openbmc/issues/2074 to be fixed
#
$check = unsupported($callback); if (ref($check) eq "ARRAY") { return $check; }
my $filename_passed = 0;
my $updateid_passed = 0;
my $option_flag;
foreach my $opt (@$extrargs) {
# Only files ending on .tar are allowed
if ($opt =~ /.*\.tar$/i) {
$filename_passed = 1;
next;
}
if ($filename_passed) {
# Filename was passed, check flags allowed with file
if ($opt !~ /^-c$|^--check$|^-d$|^--delete$|^-u$|^--upload$/) {
return ([ 1, "Invalid option specified when a file is provided: $opt" ]);
# Check if hex number for the updateid is passed
if ($opt =~ /^[[:xdigit:]]+$/i) {
$updateid_passed = 1;
next;
}
# check if option starting with - was passed
if ($opt =~ /^-/) {
$option_flag = $opt;
}
}
if ($filename_passed) {
# Filename was passed, check flags allowed with file
if ($option_flag !~ /^-c$|^--check$|^-d$|^--delete$|^-u$|^--upload$/) {
return ([ 1, "Invalid option specified when a file is provided: $option_flag" ]);
}
}
else {
if ($updateid_passed) {
# Updateid was passed, check flags allowed with update id
if ($option_flag !~ /^^-d$|^--delete$|^-a$|^--activate$/) {
return ([ 1, "Invalid option specified when an update id is provided: $option_flag" ]);
}
}
else {
# Filename was not passed, check flags allowed without file
if ($opt !~ /^-c$|^--check$|^-l$|^--list/) {
return ([ 1, "Invalid option specified: $opt" ]);
}
}
# Neither Filename nor updateid was not passed, check flags allowed without file or updateid
if ($option_flag !~ /^-c$|^--check$|^-l$|^--list/) {
return ([ 1, "Invalid option specified: $option_flag" ]);
}
}
}
} else {
return ([ 1, "Command is not supported." ]);
@ -775,22 +818,25 @@ sub parse_command_status {
my $list = 0;
my $delete = 0;
my $upload = 0;
my $activate = 0;
my $update_file;
if ($$subcommands[-1] =~ /c|check/) {
$check_version = 1;
pop(@$subcommands);
} elsif ($$subcommands[-1] =~ /l|list/) {
$list = 1;
pop(@$subcommands);
} elsif ($$subcommands[-1] =~ /d|delete/) {
$delete = 1;
pop(@$subcommands);
} elsif ($$subcommands[-1] =~ /u|upload/) {
$upload = 1;
pop(@$subcommands);
foreach $subcommand (@$subcommands) {
if ($subcommand =~ /-c|--check/) {
$check_version = 1;
} elsif ($subcommand =~ /-l|--list/) {
$list = 1;
} elsif ($subcommand =~ /-d|--delete/) {
$delete = 1;
} elsif ($subcommand =~ /-u|--upload/) {
$upload = 1;
} elsif ($subcommand =~ /-a|--activate/) {
$activate = 1;
} else {
$update_file = $subcommand;
}
}
my $update_file = $$subcommands[0];
my $filename = undef;
my $file_id = undef;
my $grep_cmd = "/usr/bin/grep -a";
@ -822,7 +868,13 @@ sub parse_command_status {
}
}
else {
# TODO Process file id passed in
# Check if hex number for the updateid is passed
if ($update_file =~ /^[[:xdigit:]]+$/i) {
# Update init_url to include the id of the update
$status_info{RFLASH_UPDATE_ACTIVATE_REQUEST}{init_url} .= "/$update_file/attr/RequestedActivation";
$status_info{RFLASH_SET_PRIORITY_REQUEST}{init_url} .= "/$update_file/attr/Priority";
$status_info{RFLASH_UPDATE_CHECK_STATE_REQUEST}{init_url} .= "/$update_file";
}
}
}
if ($check_version) {
@ -844,6 +896,19 @@ sub parse_command_status {
$next_status{LOGIN_RESPONSE} = "RFLASH_FILE_UPLOAD_REQUEST";
$next_status{"RFLASH_FILE_UPLOAD_REQUEST"} = "RFLASH_FILE_UPLOAD_RESPONSE";
}
if ($activate) {
# Activation of an update was requested.
# First we query the update image for its Activation state. If image is in "Ready" we
# need to set "RequestedActivation" attribute to "Active". If image is in "Active" we
# need to set "Priority" to 0.
$next_status{LOGIN_RESPONSE} = "RFLASH_UPDATE_ACTIVATE_REQUEST";
$next_status{"RFLASH_UPDATE_ACTIVATE_REQUEST"} = "RFLASH_UPDATE_ACTIVATE_RESPONSE";
$next_status{"RFLASH_UPDATE_ACTIVATE_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
$next_status{"RFLASH_UPDATE_CHECK_STATE_REQUEST"} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE";
$next_status{"RFLASH_SET_PRIORITY_REQUEST"} = "RFLASH_SET_PRIORITY_RESPONSE";
$next_status{"RFLASH_SET_PRIORITY_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
}
}
print Dumper(\%next_status) . "\n";
@ -1737,10 +1802,11 @@ sub rflash_response {
my $update_activation;
my $update_purpose;
my $update_version;
my $update_priority = -1;
if ($node_info{$node}{cur_status} eq "RFLASH_LIST_RESPONSE") {
# Display "list" option header and data
xCAT::SvrUtils::sendmsg("ID Purpose State Version", $callback, $node);
xCAT::SvrUtils::sendmsg("ID Purpose State Version", $callback, $node);
xCAT::SvrUtils::sendmsg("-" x 55, $callback, $node);
foreach my $key_url (keys %{$response_info->{data}}) {
@ -1756,7 +1822,15 @@ sub rflash_response {
if (defined($content{Purpose}) and $content{Purpose}) {
$update_purpose = (split(/\./, $content{Purpose}))[ -1 ];
}
xCAT::SvrUtils::sendmsg(sprintf("%-8s %-7s %-8s %s", $update_id, $update_purpose, $update_activation, $update_version), $callback, $node);
if (defined($content{Priority})) {
$update_priority = (split(/\./, $content{Priority}))[ -1 ];
}
# Priority attribute of 0 indicates the "really" active update image
if ($update_priority == 0) {
$update_activation = $update_activation . "(*)";
$update_priority = -1; # Reset update priority for next loop iteration
}
xCAT::SvrUtils::sendmsg(sprintf("%-8s %-7s %-10s %s", $update_id, $update_purpose, $update_activation, $update_version), $callback, $node);
}
xCAT::SvrUtils::sendmsg("", $callback, $node); #Separate output in case more than 1 endpoint
}
@ -1797,6 +1871,58 @@ sub rflash_response {
}
}
}
if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_ACTIVATE_RESPONSE") {
xCAT::SvrUtils::sendmsg("rflash started, please wait...", $callback, $node);
}
if ($node_info{$node}{cur_status} eq "RFLASH_SET_PRIORITY_RESPONSE") {
print "Update priority has been set";
}
if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_CHECK_STATE_RESPONSE") {
my $activation_state;
my $progress_state;
my $priority_state;
foreach my $key_url (keys %{$response_info->{data}}) {
my $content = ${ $response_info->{data} }{$key_url};
# Get values of some attributes to determine activation status
if ($key_url eq "Activation") {
$activation_state = ${ $response_info->{data} }{$key_url};
}
if ($key_url eq "Progress") {
$progress_state = ${ $response_info->{data} }{$key_url};
}
if ($key_url eq "Priority") {
$priority_state = ${ $response_info->{data} }{$key_url};
}
}
if ($activation_state =~ /Software.Activation.Activations.Failed/) {
# Activation failed. Report error and exit
xCAT::SvrUtils::sendmsg([1,"Activation of firmware failed"], $callback, $node);
}
if ($activation_state =~ /Software.Activation.Activations.Active/) {
if (scalar($priority_state) == 0) {
# Activation state of active and priority of 0 indicates the activation has been completed
xCAT::SvrUtils::sendmsg("Firmware update successfully activated", $callback, $node);
$wait_node_num--;
return;
}
else {
# Activation state of active and priority of non 0 - need to just set priority to 0 to activate
print "Update is already active, just need to set priority to 0";
$next_status{ $node_info{$node}{cur_status} } = "RFLASH_SET_PRIORITY_REQUEST";
}
}
if ($activation_state =~ /Software.Activation.Activations.Activating/) {
# Activation still going, sleep for a bit, then print the progress value
sleep(15);
xCAT::SvrUtils::sendmsg("Activating firmware update. $progress_state\%", $callback, $node);
# Set next state to come back here to chect the activation status again.
$next_status{ $node_info{$node}{cur_status} } = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
}
}
if ($next_status{ $node_info{$node}{cur_status} }) {
$node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };