From 00ce996d7435daff24546ac55d855477f8645112 Mon Sep 17 00:00:00 2001 From: daniceexi Date: Mon, 21 Sep 2009 06:33:27 +0000 Subject: [PATCH] Code drop of renergy command. This command uses the PPC.pm process to handle the common code git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@4175 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/PPCenergy.pm | 250 ++++++++++++++++++++++++++++ perl-xCAT/xCAT/Usage.pm | 9 +- xCAT-client/pods/man1/renergy.1.pod | 205 +++++++++++++++++++++++ xCAT-server/lib/perl/xCAT/PPC.pm | 46 +++-- xCAT-server/lib/xcat/plugins/fsp.pm | 3 +- xCAT-server/lib/xcat/plugins/hmc.pm | 3 +- 6 files changed, 503 insertions(+), 13 deletions(-) create mode 100644 perl-xCAT/xCAT/PPCenergy.pm create mode 100644 xCAT-client/pods/man1/renergy.1.pod diff --git a/perl-xCAT/xCAT/PPCenergy.pm b/perl-xCAT/xCAT/PPCenergy.pm new file mode 100644 index 000000000..a6038e3aa --- /dev/null +++ b/perl-xCAT/xCAT/PPCenergy.pm @@ -0,0 +1,250 @@ +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +package xCAT::PPCenergy; + +use strict; +use Getopt::Long; +use xCAT::Usage; +use xCAT::NodeRange; + + +%::QUERY_ATTRS = ( +'savingstatus' => 1, +'cappingstatus' => 1, +'cappingmaxmin' => 1, +'cappingvalue' => 1, +'cappingsoftmin' => 1, +'averageAC' => 1, +'averageDC' => 1, +'ambienttemp' => 1, +'exhausttemp' => 1, +'CPUspeed' => 1); + +%::SET_ATTRS = ( +'savingstatus' => 1, +'cappingstatus' => 1, +'cappingwatt' => 1, +'cappingperc' => 1, +); + +$::CIM_CLIENT_PATH = "$::XCATROOT/sbin/xCAT_cim_client"; + +# Parse the arguments of the command line for renergy command +sub parse_args { + my $request = shift; + + my %opt = (); + my $cmd = $request->{command}; + my $args = $request->{arg}; + my $nodes = $request->{node}; + + my $query_attrs = (); # The attributes list for query operation + my $set_pair = (); # The attribute need to be set. e.g. savingstatus=on + my $set_flag = (); # Indicate there's setting param in the argv + my $argv_flag = (); # Indicate there's param in the argv + my @notfspnodes = (); # The nodes list which are not fsp + + # set the usage subroutine + local *usage = sub { + my $usage_string = xCAT::Usage->getUsage($cmd); + return( [ $_[0], $usage_string] ); + }; + + if ($request->{arg}) { + @ARGV = @{$request->{arg}}; + $Getopt::Long::ignorecase = 0; + Getopt::Long::Configure( "bundling" ); + + if ($nodes) { + if (!GetOptions( 'V' => \$::VERBOSE )) { + return (&usage()); + } + + if ($::VERBOSE) { + $opt{verbose} = 1; + } + + if ($#ARGV < 0) { + return (&usage()); + } + + # Check the validity of the parameters of Query and Set + foreach my $attr (@ARGV) { + my ($set_attr, $set_value) = split (/=/, $attr); + if ($set_value) { + if ($argv_flag) { + return (&usage()); + } + if ($::SET_ATTRS{$set_attr} != 1) { + return (&usage()); + } + + if ($set_attr eq "savingstatus" + && ($set_value ne "on" && $set_value ne "off")) { + return (&usage()); + } elsif ($set_attr eq "cappingstatus" + && ($set_value ne "on" && $set_value ne "off")) { + return (&usage()); + } elsif ( ($set_attr eq "cappingwatt" + || $set_attr eq "cappingperc") + && $set_value =~ /\D/) { + return (&usage()); + } + + $set_pair = $set_attr."=".$set_value; + $set_flag = 1; + } else { + if ($set_flag) { + return (&usage()); + } + } + + $argv_flag = 1; + } + + if (!$set_flag) { + my @query_list = @ARGV; + + if ($query_list[0] eq "all" and $#query_list == 0) { + $query_attrs = "savingstatus,cappingstatus,cappingmaxmin,cappingvalue,cappingsoftmin,averageAC,averageDC,ambienttemp,exhausttemp,CPUspeed"; + } else { + my @no_dup_query_list = (); + foreach my $q_attr (@query_list) { + chomp($q_attr); + + if ($::QUERY_ATTRS{$q_attr} != 1) { + return (&usage()); + } + + if (!grep (/$q_attr/, @no_dup_query_list)) { + push @no_dup_query_list, $q_attr; + } + } + $query_attrs = join (',', @no_dup_query_list); + } + + } + } else { + # If has not nodes, the -h or -v option must be input + if (!GetOptions( 'h|help' => \$::HELP, + 'v|version' => \$::VERSION)) { + return (&usage()); + } + + if (! ($::HELP || $::VERSION) ) { + return (&usage()); + } + if ($::HELP) { + return (&usage()); + } + + if ($::VERSION) { + my $version_string = xCAT::Usage->getVersion('renergy'); + return( [ $_[0], $version_string] ); + } + } + } else { + return (&usage()); + } + + # Check whether the hardware type of nodes are fsp + my $nodetype_tb = xCAT::Table->new('nodetype'); + unless ($nodetype_tb) { + return (1, "Error: Cannot open the nodetype table"); + } + + my $nodetype_v = $nodetype_tb->getNodesAttribs($nodes, ['nodetype']); + foreach my $node (@{$nodes}) { + if ($nodetype_v->{$node}->[0]->{'nodetype'} ne 'fsp') { + push @notfspnodes, $node; + } + } + + if (@notfspnodes) { + return (1, "Error: The hardware type of following nodes are not fsp: ".join(',', @notfspnodes)); + } + + if ($query_attrs) { + $opt{'query'} = $query_attrs; + } elsif ($set_pair) { + $opt{'set'} = $set_pair; + } + + $request->{method} = $cmd; + return (\%opt); +} + +# Handle the energy query and setting work +sub renergy { + my $request = shift; + my $hcphost = shift; + my $nodehash = shift; + + my @return_msg = (); + + my $opt = $request->{'opt'}; + my $verbose = $opt->{'verbose'}; + + # Get the User and Password for the HCP + my $user = $request->{$hcphost}{'cred'}[0]; + my $password = $request->{$hcphost}{'cred'}[1]; + + # Get the CEC + + my ($node, $attrs) = %$nodehash; + my $cec_name = @$attrs[2]; + + if ($verbose) { + push @return_msg, [$node, "Attributes of $node:\n User=$user\n Password=$password\n CEC=$cec_name\n", 0]; + } + + if (! ($user || $password || $cec_name) ) { + return ([[$node, "ERROR: This node lack some mandatory attributes for renergy command.", 1]]); + } + + # Check the existence of cim client + if ( (! -f $::CIM_CLIENT_PATH) + || (! -x $::CIM_CLIENT_PATH) ) { + return ([[$node, "ERROR: Cannot find the xCAT CIM Client [$::CIM_CLIENT_PATH]. Please install the xCAT_cim_client package correctly.", 1]]); + } + + # Generate the url path for CIM communication + my $url_path = "https://"."$user".":"."$password"."\@"."$hcphost".":5989"; + + my $verb_arg = ""; + if ($verbose) { + $verb_arg = "-V"; + } + + # Execute the request + my $cmd = ""; + if ($opt->{'set'}) { + $cmd = "$::CIM_CLIENT_PATH $verb_arg -u $url_path -n $cec_name -o $opt->{'set'}"; + } elsif ($opt->{'query'}) { + $cmd = "$::CIM_CLIENT_PATH $verb_arg -u $url_path -n $cec_name -o $opt->{'query'}"; + } + + if ($verbose) { + push @return_msg, [$node, "Run following command: $cmd", 0]; + } + + # Disable the CHID signal before run the command. Otherwise the + # $? value of `$cmd` will come from handler of CHID signal + $SIG{CHLD} = (); + + # Call the xCAT_cim_client to query or set the energy capabilities + my @result = `$cmd 2>&1`; + my $rc = $? >> 8; + + foreach my $line (@result) { + chomp($line); + if ($line =~ /^\s*$/) { + next; + } + push @return_msg, [$node, $line, $rc]; + } + + return \@return_msg; +} + +1; diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index 23b851ccc..4abc9d6c6 100644 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -159,6 +159,12 @@ my %usage = ( "Usage: lshwconn [-h|--help] lshwconn noderange [-V|--verbose]", + "renergy" => +"Usage: + renergy [-h | --help] + renergy [-v | --version] + renergy noderange [-V] {all | {[savingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed]}} + renergy noderange [-V] {{savingstatus}={on | off} | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage}", ); my $vers = xCAT::Utils->Version(); my %version = ( @@ -178,7 +184,8 @@ my %version = ( "chvm" => "$vers", "rmvm" => "$vers", "lsslp" => "$vers", - "rflash" => "$vers" + "rflash" => "$vers", + "renergy" => "$vers" ); #-------------------------------------------------------------------------------- diff --git a/xCAT-client/pods/man1/renergy.1.pod b/xCAT-client/pods/man1/renergy.1.pod new file mode 100644 index 000000000..882bc99a0 --- /dev/null +++ b/xCAT-client/pods/man1/renergy.1.pod @@ -0,0 +1,205 @@ +=head1 B + +B - remote energy management tool + + +=head1 B + +B [-h | --help] + +B [-v | --version] + +B noderange [-V] {all | {[savingstatus] + [cappingstatus] [cappingmaxmin] [cappingvalue] + [cappingsoftmin] [averageAC] [averageDC] + [ambienttemp] [exhausttemp] [CPUspeed]}} + +B noderange [-V] {{savingstatus}={on | off} + | {cappingstatus}={on | off} | {cappingwatt}=watt + | {cappingperc}=percentage} + +=head1 B + +This renergy command can be used to manage the energy attributes of +a machine. Presently, it only supports IBM POWER6 rack-mounted servers. +Note: The keyword 'server' in this document is identical to +'rack-mounted server'. + +The parameter 'noderange' can be a list of server's name (CEC's name). +Note: Lpar's name is not acceptable. + +Renergy command can accept multiple attributes to query. If only +keywords list is specified, without the '=', it displays the current +value. +Renergy command only can set one attribute once running. + +For the attributes that not supported by certain server, the return +value will be 'na'. + +Prerequisite: +Before running the Renergy command, a prerequisite package +B needs to be downloaded form IBM web site and installed. +Note: +Each query operation for attribute CPUspeed, averageAC or averageDC +costs about 30 Second to complete the operation. Query others attributes +will get response immediately. + + +The energy capability of specific hardware: + +8204-E8A + Supports attributes: all + +9125-F2A, 9119-FHA + Supports attributes: savingstatus,CPUspeed,ambienttemp, + exhausttemp,averageAC + +9117-MMA (cpu speed should quicker than 4G) + Supports attributes: powersaving + +=head1 B + +-h | --help + Display the usage message. + +-v | --version + Display the version information. + +-V + Display the Verbose information. + + +all + Query all of the energy attributes. + +savingstatus + Query the Power Saving status. The result should be + 'on' or 'off'. + Note: To support the power saving attribute, POWER6 + processors should greater than or equal to 4.0 GHz. + +savingstatus={on | off} + Set the Power Saving status. The value must be 'on' + or 'off'. + Note: The setting value needs about 2 minutes to take + effect. + +cappingstatus + Query the Power Capping status. The result should be + 'on' of 'off'. + +cappingstatus={on | off} + Set the Power Capping status. The value must be 'on' + or 'off'. + +cappingwatt=watt + Set the Power Capping value base on the watt unit. + If the 'watt' > maximum of cappingmaxmin or 'watt' + < minimum of cappingmaxmim, The setting operation + will fail. + +cappingperc=percentage + Set the Power Capping value base on the percentage of + the max-min capping value. + +cappingmaxmin + Query the maximum and minimum of Power Capping value + that can be set for a machine. (Unit is watt) + +cappingvalue + Query the current Power Capping value. (Unit is watt) + +cappingsoftmin + Query the minimum value that can be assigned to Pcap + without guaranteed enforceability. (Unit is watt) + +averageAC + Query the average power consumed (Input). (Unit is watt) + Note: For HI and HE server, the value of attribute + averageAC is the aggregate for all of the servers in the + rack. + +averageDC + Query the average power consumed (Output). (Unit is + watt) + +ambienttemp + Query the current ambient temperature. (Unit is B0C) + +exhausttemp + Query the current exhaust temperature. (Unit is B0C) + +CPUspeed + Query the effective CPU speed. (Unit is MHz) + + +=head1 B + +0 The command completed successfully. + +1 An error has occurred. + + +=head1 B + +1. Query all the attributes which CEC1,CEC2 supported + B CEC1,CEC2 all + + The output of the query operation: + CEC1: savingstatus: on + CEC1: cappingstatus: on + CEC1: cappingmin: 782 W + CEC1: cappingmax: 850 W + CEC1: cappingvalue: 816 W + CEC1: cappingsoftmin: 200 W + CEC1: averageAC: 430 W + CEC1: averageDC: 364 W + CEC1: ambienttemp: 25 C + CEC1: exhausttemp: 32 C + CEC1: CPUspeed: 3621 MHz + CEC2: savingstatus: off + CEC2: cappingstatus: off + CEC2: cappingmin: na + CEC2: cappingmax: na + CEC2: cappingvalue: na + CEC2: cappingsoftmin: na + CEC2: averageAC: na + CEC2: averageDC: na + CEC2: ambienttemp: na + CEC2: exhausttemp: na + CEC2: CPUspeed: na + +2. Query the attributes savingstatus, cappingstatus + and CPUspeed of server CEC1 + B CEC1 savingstatus,cappingstatus,CPUspeed + + The output of the query operation: + CEC1: savingstatus: off + CEC1: cappingstatus: on + CEC1: CPUspeed: 3621 MHz + +3. Turn on the Power saving function of CEC1 + B CEC1 savingstatus=on + + The output of the setting operation: + CEC1: Set savingstatus succeeded. + CEC1: This setting may need some minutes to take effect. + +4. Set the Power Capping value base on the percentage of the + max-min capping value + B CEC1 -s cappingperc=50 + + If the maximum capping value of the CEC1 is 850w, and the + minimum capping value of the CEC1 is 782w, the Power Capping + value will be set as ((850-782)*50% + 782) = 816w. + + The output of the setting operation: + CEC1: Set cappingperc succeeded. + CEC1: cappingvalue: 816 + + +=head1 B + +/opt/xcat/bin/renergy + + diff --git a/xCAT-server/lib/perl/xCAT/PPC.pm b/xCAT-server/lib/perl/xCAT/PPC.pm index eb5108d1e..73900edd7 100644 --- a/xCAT-server/lib/perl/xCAT/PPC.pm +++ b/xCAT-server/lib/perl/xCAT/PPC.pm @@ -34,10 +34,11 @@ my %modules = ( getmacs => "xCAT::PPCmac", reventlog => "xCAT::PPClog", rspconfig => "xCAT::PPCcfg", - rflash => "xCAT::PPCrflash", - mkhwconn => "xCAT::PPCconn", - rmhwconn => "xCAT::PPCconn", - lshwconn => "xCAT::PPCconn" + rflash => "xCAT::PPCrflash", + mkhwconn => "xCAT::PPCconn", + rmhwconn => "xCAT::PPCconn", + lshwconn => "xCAT::PPCconn", + renergy => "xCAT::PPCenergy" ); ########################################## @@ -589,11 +590,12 @@ sub preprocess_nodes { # rscan - Nodes are hardware control pts # Direct-attached FSP ######################################## - if (( !$request->{hcp} && ($request->{hcp} ne "hmc" )) and - (( $request->{command} =~ /^(rscan|rspconfig)$/ ) or - ($request->{hwtype} eq "fsp" or $request->{hwtype} eq "bpa" ) or - ($request->{command} eq 'lshwconn' and $request->{nodetype} eq 'hmc')) -) { + if (( !$request->{hcp} && ($request->{hcp} ne "hmc" )) + and ($request->{command} !~ /^renergy$/) + and (( $request->{command} =~ /^(rscan|rspconfig)$/ ) + or ($request->{hwtype} eq "fsp" or $request->{hwtype} eq "bpa" ) + or ($request->{command} eq 'lshwconn' and $request->{nodetype} eq 'hmc')) + ) { my $result = resolve_hcp( $request, $noderange ); return( $result ); } @@ -712,7 +714,7 @@ sub preprocess_nodes { # single CEC, the CEC itself will serialize # them - fork one process per CEC. ########################################## - elsif ( $method =~ /^powercmd/ ) { + elsif ( $method =~ /^powercmd/ || $method =~ /^renergy/ ) { while (my ($hcp,$hash) = each(%nodehash) ) { while (my ($mtms,$h) = each(%$hash) ) { push @nodegroup,[$hcp,$h]; @@ -1026,6 +1028,30 @@ sub invoke_cmd { my $verbose_log; my @outhash; + ######################################## + # If the request command is renergy, just + # uses the xCAT CIM Client to handle it + ######################################## + if ( $request->{command} eq "renergy" ) { + my $result = &runcmd($request, $host, $nodes); + + ######################################## + # Format and send back to parent + ######################################## + foreach ( @$result ) { + my %output; + $output{node}->[0]->{name}->[0] = @$_[0]; + $output{node}->[0]->{data}->[0]->{contents}->[0] = @$_[1]; + $output{errorcode} = @$_[2]; + push @outhash, \%output; + } + my $out = $request->{pipe}; + print $out freeze( [@outhash] ); + print $out "\nENDOFFREEZE6sK4ci\n"; + + return; + } + ######################################## # Direct-attached FSP handler ######################################## diff --git a/xCAT-server/lib/xcat/plugins/fsp.pm b/xCAT-server/lib/xcat/plugins/fsp.pm index 2118b8de1..4b21fba1c 100644 --- a/xCAT-server/lib/xcat/plugins/fsp.pm +++ b/xCAT-server/lib/xcat/plugins/fsp.pm @@ -15,7 +15,8 @@ sub handled_commands { rspconfig => 'nodehm:mgt', mkhwconn => 'nodehm:mgt', rmhwconn => 'nodehm:mgt', - lshwconn => 'nodehm:mgt' + lshwconn => 'nodehm:mgt', + renergy => 'nodehm:mgt' }; } diff --git a/xCAT-server/lib/xcat/plugins/hmc.pm b/xCAT-server/lib/xcat/plugins/hmc.pm index e4585065a..a2476b654 100644 --- a/xCAT-server/lib/xcat/plugins/hmc.pm +++ b/xCAT-server/lib/xcat/plugins/hmc.pm @@ -24,7 +24,8 @@ sub handled_commands { rflash => 'nodehm:mgt', mkhwconn => 'nodehm:mgt', rmhwconn => 'nodehm:mgt', - lshwconn => 'nodehm:mgt' + lshwconn => 'nodehm:mgt', + renergy => 'nodehm.mgt' }; }