mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-07-24 13:21:12 +00:00
Code drop for energy management support for P8; port back from 2.10 branch
This commit is contained in:
462
perl-xCAT/xCAT/CIMUtils.pm
Normal file
462
perl-xCAT/xCAT/CIMUtils.pm
Normal file
@@ -0,0 +1,462 @@
|
||||
#! /usr/bin/env perl
|
||||
# IBM(c) 2014 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
# This package offers subroutines to access CIM server
|
||||
|
||||
package xCAT::CIMUtils;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use HTTP::Headers;
|
||||
use HTTP::Request;
|
||||
use LWP::UserAgent;
|
||||
|
||||
use XML::LibXML;
|
||||
use Data::Dumper;
|
||||
|
||||
=head1 HTTP_PARAMS
|
||||
|
||||
A hash which includes all the parameters for accessing HTTP server. The valid parameter:
|
||||
ip: The IP address of the HTTP server
|
||||
user: The user to access HTTP server.
|
||||
password: The password for the user.
|
||||
method: The http method. (GET, PUT, POST, DELETE). Default is GET
|
||||
protocol: The protocol which will be used to access HTTP server. (http/https). Default is https
|
||||
format: The format of payload. Default is xml
|
||||
payload: The payload of http
|
||||
|
||||
Example:
|
||||
my %http_params = ( ip => '192.168.1.1',
|
||||
port => '5989',
|
||||
user => 'HMC',
|
||||
password => 'admin',
|
||||
method => 'POST',
|
||||
protocol => 'https');
|
||||
|
||||
=cut
|
||||
|
||||
=head1 enum_instance ()
|
||||
Description:
|
||||
Enumerate CIM instances.
|
||||
|
||||
Arguments:
|
||||
http_params: A reference to HTTP_PARAMS
|
||||
cim_params: The CIM parameters
|
||||
classname - a mandatory param to specify the class that enumerate will target to.
|
||||
|
||||
Return:
|
||||
1 - A hash reference. The valid key includes:
|
||||
rc - The return code. 0 - success. > 0 - fail.
|
||||
cim_rc - The return code from CIM server.
|
||||
msg - Output message.
|
||||
|
||||
2 - Array of instances, each instance is a hash contains lots of properties.
|
||||
|
||||
3 - The name path of instance
|
||||
=cut
|
||||
|
||||
|
||||
sub enum_instance
|
||||
{
|
||||
my $http_params = shift;
|
||||
unless (ref($http_params)) {
|
||||
$http_params = shift;
|
||||
}
|
||||
|
||||
my $cim_params = shift;
|
||||
|
||||
# This is a mandatory parameter
|
||||
unless ($cim_params->{classname}) {
|
||||
return ({rc => 1, msg => "Missed the classname"});
|
||||
}
|
||||
|
||||
unless ($cim_params->{namespace}) {
|
||||
$cim_params->{namespace} = "ibmsd";
|
||||
}
|
||||
|
||||
# prepare the CIM payload
|
||||
my $tmpnode;
|
||||
|
||||
# create a new doc
|
||||
my $doc = XML::LibXML->createDocument('1.0','UTF-8');
|
||||
|
||||
# create and add the root element
|
||||
my $root = $doc->createElement("CIM");
|
||||
$root->setAttribute("CIMVERSION", "2.0");
|
||||
$root->setAttribute("DTDVERSION", "2.0");
|
||||
|
||||
$doc->setDocumentElement($root);
|
||||
|
||||
# create and add the MESSAGE element
|
||||
my $message = $doc->createElement("MESSAGE");
|
||||
$message->setAttribute("ID", "1000");
|
||||
$message->setAttribute("PROTOCOLVERSION", "1.0");
|
||||
|
||||
$root->addChild($message);
|
||||
|
||||
# add a SIMPLE REQUEST
|
||||
my $simple_request = $doc->createElement("SIMPLEREQ");
|
||||
$message->addChild($simple_request);
|
||||
|
||||
# add an IMETHOD CALL
|
||||
my $imethod_call = $doc->createElement("IMETHODCALL");
|
||||
$imethod_call->setAttribute("NAME", "EnumerateInstances");
|
||||
|
||||
$simple_request->addChild($imethod_call);
|
||||
|
||||
# add the local name space path
|
||||
my $localnamespacepath = $doc->createElement("LOCALNAMESPACEPATH");
|
||||
$tmpnode = $doc->createElement("NAMESPACE");
|
||||
$tmpnode->setAttribute("NAME", "root");
|
||||
$localnamespacepath->addChild($tmpnode);
|
||||
|
||||
$tmpnode = $doc->createElement("NAMESPACE");
|
||||
$tmpnode->setAttribute("NAME", $cim_params->{namespace});
|
||||
$localnamespacepath->addChild($tmpnode);
|
||||
|
||||
$imethod_call->addChild($localnamespacepath);
|
||||
|
||||
# add the target class name
|
||||
my $param_classname = $doc->createElement("IPARAMVALUE");
|
||||
$param_classname->setAttribute("NAME", "ClassName");
|
||||
$imethod_call->addChild($param_classname);
|
||||
|
||||
my $classname = $doc->createElement("CLASSNAME");
|
||||
$classname->setAttribute("NAME", $cim_params->{classname});
|
||||
$param_classname->addChild($classname);
|
||||
|
||||
# add several common parameters
|
||||
$imethod_call->appendWellBalancedChunk('<IPARAMVALUE NAME="DeepInheritance"><VALUE>TRUE</VALUE></IPARAMVALUE><IPARAMVALUE NAME="LocalOnly"><VALUE>FALSE</VALUE></IPARAMVALUE><IPARAMVALUE NAME="IncludeQualifiers"><VALUE>FALSE</VALUE></IPARAMVALUE><IPARAMVALUE NAME="IncludeClassOrigin"><VALUE>TRUE</VALUE></IPARAMVALUE>');
|
||||
|
||||
my $payload = $doc->toString();
|
||||
|
||||
# generate http request
|
||||
my $ret = gen_http_request($http_params, $payload);
|
||||
|
||||
if ($ret->{rc}) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
# send request to http server
|
||||
$ret = send_http_request($http_params, $ret->{request});
|
||||
if ($ret->{rc}) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
# parse the http response
|
||||
my $ret_value;
|
||||
my $parser = XML::LibXML->new();
|
||||
my $resp_doc = $parser->parse_string($ret->{payload});
|
||||
|
||||
# check the error message from CIM
|
||||
my $error_node = $resp_doc->getElementsByTagName("ERROR");
|
||||
if ($error_node) {
|
||||
my $msg = $error_node->[0]->getAttribute("DESCRIPTION");
|
||||
my $errorcode = $error_node->[0]->getAttribute("CODE");
|
||||
return ({rc => 1, cim_rc => $errorcode, msg => $error_node->[0]->getAttribute("DESCRIPTION")." [cim return code: $errorcode]"});
|
||||
}
|
||||
|
||||
# get the name path of the instance, which is used to set property
|
||||
my @namepath = $resp_doc->getElementsByTagName("INSTANCENAME");
|
||||
my $namepath_string;
|
||||
if (@namepath) {
|
||||
$namepath_string = $namepath[0]->toString();
|
||||
}
|
||||
|
||||
# get all the instance elements
|
||||
my @instances = $resp_doc->getElementsByTagName("VALUE.NAMEDINSTANCE");
|
||||
foreach my $instance (@instances) {
|
||||
# get all the property element for each instance
|
||||
my @properties = $instance->getElementsByTagName("PROPERTY");
|
||||
if (my @property_arrays = $instance->getElementsByTagName("PROPERTY.ARRAY")) {
|
||||
push @properties, @property_arrays;
|
||||
}
|
||||
my $ins_value;
|
||||
foreach my $property (@properties) {
|
||||
# get name, vlaue and type for each property. (only the one which has value)
|
||||
if (my $pname = $property->getAttribute("NAME")) {
|
||||
if (my $pvalue = $property->getAttribute("TYPE")) {
|
||||
$ins_value->{property}->{$pname}->{type} = $pvalue;
|
||||
}
|
||||
if ($property->getElementsByTagName("VALUE.ARRAY")) {
|
||||
my @nodelist = $property->getElementsByTagName("VALUE");
|
||||
my @value_array = ();
|
||||
foreach my $n (@nodelist) {
|
||||
push @value_array, $n->textContent;
|
||||
}
|
||||
$ins_value->{property}->{$pname}->{value} = join(',',@value_array);
|
||||
} elsif (my $node = $property->getElementsByTagName("VALUE")) {
|
||||
$ins_value->{property}->{$pname}->{value} = $node->[0]->textContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
push @{$ret_value}, $ins_value;
|
||||
}
|
||||
|
||||
return ({rc =>0}, $ret_value, $namepath_string);
|
||||
}
|
||||
|
||||
=head1 set_property ()
|
||||
Description:
|
||||
Set the property for an instance.
|
||||
|
||||
Arguments:
|
||||
http_params: A reference to HTTP_PARAMS
|
||||
cim_params: The CIM parameters
|
||||
namepath - a mandatory param to specify the path of the instance.
|
||||
It should be returned from 'enum_instance' subroutine.
|
||||
|
||||
Return:
|
||||
1 - A hash reference. The valid key includes:
|
||||
rc - The return code. 0 - success. > 0 - fail.
|
||||
cim_rc - The return code from CIM server.
|
||||
msg - Output message.
|
||||
=cut
|
||||
sub set_property
|
||||
{
|
||||
my $http_params = shift;
|
||||
unless (ref($http_params)) {
|
||||
$http_params = shift;
|
||||
}
|
||||
|
||||
my $cim_params = shift;
|
||||
|
||||
# This is a mandatory parameter
|
||||
unless ($cim_params->{namepath}) {
|
||||
return ({rc => 1, msg => "Missed the name path for the instance"});
|
||||
}
|
||||
|
||||
unless ($cim_params->{namespace}) {
|
||||
$cim_params->{namespace} = "ibmsd";
|
||||
}
|
||||
|
||||
# prepare the CIM payload
|
||||
my $tmpnode;
|
||||
|
||||
# create a new doc
|
||||
my $doc = XML::LibXML->createDocument('1.0','UTF-8');
|
||||
|
||||
# create and add the root element
|
||||
my $root = $doc->createElement("CIM");
|
||||
$root->setAttribute("CIMVERSION", "2.0");
|
||||
$root->setAttribute("DTDVERSION", "2.0");
|
||||
|
||||
$doc->setDocumentElement($root);
|
||||
|
||||
# create and add the MESSAGE element
|
||||
my $message = $doc->createElement("MESSAGE");
|
||||
$message->setAttribute("ID", "1000");
|
||||
$message->setAttribute("PROTOCOLVERSION", "1.0");
|
||||
|
||||
$root->addChild($message);
|
||||
|
||||
# add a SIMPLE REQUEST
|
||||
my $simple_request = $doc->createElement("SIMPLEREQ");
|
||||
$message->addChild($simple_request);
|
||||
|
||||
# add an IMETHOD CALL
|
||||
my $imethod_call = $doc->createElement("IMETHODCALL");
|
||||
$imethod_call->setAttribute("NAME", "SetProperty");
|
||||
|
||||
$simple_request->addChild($imethod_call);
|
||||
|
||||
# add the local name space path
|
||||
my $localnamespacepath = $doc->createElement("LOCALNAMESPACEPATH");
|
||||
$tmpnode = $doc->createElement("NAMESPACE");
|
||||
$tmpnode->setAttribute("NAME", "root");
|
||||
$localnamespacepath->addChild($tmpnode);
|
||||
|
||||
$tmpnode = $doc->createElement("NAMESPACE");
|
||||
$tmpnode->setAttribute("NAME", $cim_params->{namespace});
|
||||
$localnamespacepath->addChild($tmpnode);
|
||||
|
||||
$imethod_call->addChild($localnamespacepath);
|
||||
|
||||
# add the target property name
|
||||
my $param_propertyname = $doc->createElement("IPARAMVALUE");
|
||||
$param_propertyname->setAttribute("NAME", "PropertyName");
|
||||
$imethod_call->addChild($param_propertyname);
|
||||
|
||||
$tmpnode = $doc->createElement("VALUE");
|
||||
$tmpnode->appendTextNode($cim_params->{propertyname});
|
||||
$param_propertyname->addChild($tmpnode);
|
||||
|
||||
# add the target property value
|
||||
my $param_newvaluename = $doc->createElement("IPARAMVALUE");
|
||||
$param_newvaluename->setAttribute("NAME", "NewValue");
|
||||
$imethod_call->addChild($param_newvaluename);
|
||||
|
||||
$tmpnode = $doc->createElement("VALUE");
|
||||
$tmpnode->appendTextNode($cim_params->{propertyvalue});
|
||||
$param_newvaluename->addChild($tmpnode);
|
||||
|
||||
# add parameters of instance name path
|
||||
my $param_namepath = $doc->createElement("IPARAMVALUE");
|
||||
$param_namepath->setAttribute("NAME", "InstanceName");
|
||||
$param_namepath->appendWellBalancedChunk($cim_params->{namepath});
|
||||
$imethod_call->addChild($param_namepath);
|
||||
|
||||
my $payload = $doc->toString();
|
||||
|
||||
# generate http request
|
||||
my $ret = gen_http_request($http_params, $payload);
|
||||
|
||||
if ($ret->{rc}) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
# send request to http server
|
||||
$ret = send_http_request($http_params, $ret->{request});
|
||||
if ($ret->{rc}) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
# parse the http response
|
||||
my $ret_value;
|
||||
my $parser = XML::LibXML->new();
|
||||
my $resp_doc = $parser->parse_string($ret->{payload});
|
||||
|
||||
# check the error message from CIM
|
||||
my $error_node = $resp_doc->getElementsByTagName("ERROR");
|
||||
if ($error_node) {
|
||||
my $msg = $error_node->[0]->getAttribute("DESCRIPTION");
|
||||
my $errorcode = $error_node->[0]->getAttribute("CODE");
|
||||
return ({rc => 1, cim_rc => $errorcode, msg => $error_node->[0]->getAttribute("DESCRIPTION")." [cim return code: $errorcode]"});
|
||||
}
|
||||
|
||||
|
||||
# if no http and cim error, the setting was succeeded
|
||||
return ($ret);
|
||||
}
|
||||
|
||||
=head1 gen_http_request ()
|
||||
Description:
|
||||
Generate a http request.
|
||||
|
||||
Arguments:
|
||||
http_params: A reference to HTTP_PARAMS
|
||||
payload: The payload for the http request. It can be null if the payload has been set in http_params.
|
||||
|
||||
Return:
|
||||
A hash reference. The valid key includes:
|
||||
rc - The return code. 0 - success. > 0 - fail.
|
||||
msg - Output message
|
||||
request - The generated HTTP::Request object
|
||||
=cut
|
||||
|
||||
sub gen_http_request
|
||||
{
|
||||
my $http_params = shift;
|
||||
my $http_payload = shift;
|
||||
|
||||
# check the mandatory parameters
|
||||
unless (defined ($http_params->{ip}) && defined ($http_params->{port}) && defined($http_params->{user}) && defined($http_params->{password})) {
|
||||
return ({rc => 1, msg => "Missed the mandatory parameters: ip, port, user or password"});
|
||||
}
|
||||
|
||||
# set the default value for parameters
|
||||
unless (defined ($http_params->{protocol})) {
|
||||
$http_params->{protocol} = 'https';
|
||||
}
|
||||
unless (defined ($http_params->{format})) {
|
||||
$http_params->{format} = 'xml';
|
||||
}
|
||||
unless (defined ($http_params->{method})) {
|
||||
$http_params->{method} = 'GET';
|
||||
}
|
||||
|
||||
my $payload = '';
|
||||
if (defined ($http_params->{payload})) {
|
||||
$payload = $http_params->{payload};
|
||||
}
|
||||
if (defined ($http_payload)) {
|
||||
unless (ref($http_payload)) { #Todo: support payloasd to be a hash
|
||||
$payload = $http_payload;
|
||||
}
|
||||
}
|
||||
|
||||
# create the http head
|
||||
my $header = HTTP::Headers->new('content-type' => "application/$http_params->{format}",
|
||||
'Accept' => "application/$http_params->{format}",
|
||||
'User-Agent' => "xCAT/2",
|
||||
'Host' => "$http_params->{ip}:$http_params->{port}");
|
||||
|
||||
# set the user & password
|
||||
$header->authorization_basic($http_params->{user}, $http_params->{password});
|
||||
|
||||
# set the length of payload
|
||||
my $plen = length($payload);
|
||||
$header->push_header('Content-Length' => $plen);
|
||||
|
||||
# create the URL
|
||||
my $url = "$http_params->{protocol}://$http_params->{ip}:$http_params->{port}";
|
||||
my $request = HTTP::Request->new($http_params->{method}, $url, $header, $payload);
|
||||
|
||||
# set the http version
|
||||
$request->protocol('HTTP/1.1');
|
||||
|
||||
return ({rc => 0, request => $request});
|
||||
}
|
||||
|
||||
|
||||
=head1 send_http_request ()
|
||||
Description:
|
||||
Send http request to http server and waiting for the response.
|
||||
|
||||
Arguments:
|
||||
http_params: A reference to HTTP_PARAMS
|
||||
http_request: A HTTP::Request object
|
||||
|
||||
Return:
|
||||
A hash reference. The valid key includes:
|
||||
rc - The return code. 0 - success. > 0 - fail.
|
||||
http_rc - The return code of http. 200, 400 ...
|
||||
msg - Output message
|
||||
payload - The http response from http server
|
||||
=cut
|
||||
|
||||
sub send_http_request
|
||||
{
|
||||
my $http_params = shift;
|
||||
my $http_request = shift;
|
||||
|
||||
# Load the library LWP::Protocol::https for https support
|
||||
if ($http_params->{protocol} eq 'https') {
|
||||
eval { require LWP::Protocol::https};
|
||||
if ($@) {
|
||||
return ({rc => 1, msg => "Failed to load perl library LWP::Protocol::https"});
|
||||
}
|
||||
}
|
||||
|
||||
# create a new HTTP User Agent Object
|
||||
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0, SSL_verify_mode => 0});
|
||||
if ($http_params->{timeout}) {
|
||||
$ua->timeout($http_params->{timeout});
|
||||
} else {
|
||||
$ua->timeout(10); # the default timeout is 10s
|
||||
}
|
||||
|
||||
if (defined($http_params->{verbose}) && defined ($http_params->{callback})) {
|
||||
$http_params->{callback}({data => ["\n========CIM Request Start========", $http_request->as_string(), "=======CIM Request End======="]});
|
||||
}
|
||||
|
||||
# send request and receive the response
|
||||
my $response = $ua->request($http_request);
|
||||
|
||||
if (defined($http_params->{verbose}) && defined ($http_params->{callback}) && defined ($response->{_content})) {
|
||||
$http_params->{callback}({data => ["\n========CIM Response Start========", $response->{_content}, "=======CIM Response End======="]});
|
||||
}
|
||||
|
||||
# check the http response
|
||||
if (defined ($response) && defined ($response->{_rc}) && defined ($response->{_msg})) {
|
||||
if ($response->{_rc} eq "200" && $response->{_msg} eq "OK") {
|
||||
return ({rc => 0, http_rc => $response->{_rc}, msg => "$response->{_msg} [http return code: $response->{_rc}]", payload => $response->{_content}});
|
||||
}
|
||||
}
|
||||
|
||||
return ({rc => 1, http_rc => $response->{_rc}, msg => $response->{_msg}});
|
||||
}
|
||||
|
||||
|
||||
1;
|
@@ -333,12 +333,16 @@ my %usage = (
|
||||
renergy [-v | --version]
|
||||
|
||||
Power 6 server specific :
|
||||
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 }
|
||||
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 }
|
||||
|
||||
Power 7 server specific :
|
||||
renergy noderange [-V] { all | { [savingstatus] [dsavingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed] [syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin] [ffoTurbo] [ffoNorm] [ffovalue] } }
|
||||
renergy noderange [-V] { {savingstatus}={on | off} | {dsavingstatus}={on-norm | on-maxp | off} | {fsavingstatus}={on | off} | {ffovalue}=MHZ | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage }
|
||||
renergy noderange [-V] { all | { [savingstatus] [dsavingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed] [syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin] [ffoTurbo] [ffoNorm] [ffovalue] } }
|
||||
renergy noderange [-V] { {savingstatus}={on | off} | {dsavingstatus}={on-norm | on-maxp | off} | {fsavingstatus}={on | off} | {ffovalue}=MHZ | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage }
|
||||
|
||||
Power 8 server specific :
|
||||
renergy noderange [-V] { all | [savingstatus] [dsavingstatus] [averageAC] [averageAChistory] [averageDC] [averageDChistory] [ambienttemp] [ambienttemphistory] [exhausttemp] [exhausttemphistory] [fanspeed] [fanspeedhistory] [CPUspeed] [CPUspeedhistory] [syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin] [ffoTurbo] [ffoNorm] [ffovalue]}
|
||||
renergy noderange [-V] { savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} | fsavingstatus={on | off} | ffovalue=MHZ }
|
||||
|
||||
BladeCenter specific :
|
||||
For Management Modules:
|
||||
|
@@ -3298,13 +3298,68 @@ sub noderangecontainsMn
|
||||
return; # if no MN in the noderange, return nothing
|
||||
}
|
||||
|
||||
|
||||
# the MTM of P6 and P7 machine
|
||||
my %MTM_P6P7 = (
|
||||
# P6 systems
|
||||
'7998-60X' => 1,
|
||||
'7998-61X' => 1,
|
||||
'7778-23X' => 1,
|
||||
'8203-E4A' => 1,
|
||||
'8204-E8A' => 1,
|
||||
'8234-EMA' => 1,
|
||||
'9117-MMA' => 1,
|
||||
'9119-FHA' => 1,
|
||||
|
||||
# P7 systems
|
||||
'8406-70Y' => 1,
|
||||
'8406-71Y' => 1,
|
||||
'7891-73X' => 1,
|
||||
'7891-74X' => 1,
|
||||
'8231-E2B' => 1,
|
||||
'8202-E4B' => 1,
|
||||
'8231-E2B' => 1,
|
||||
'8205-E6B' => 1,
|
||||
'8233-E8B' => 1,
|
||||
'8236-E8C' => 1,
|
||||
'9117-MMB' => 1,
|
||||
'9179-MHB' => 1,
|
||||
'9119-FHB' => 1,
|
||||
);
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 isP6P7
|
||||
|
||||
Check whether a MTM is a P6 or P7 machine
|
||||
Parameter: MTM of Power machine
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub isP6P7
|
||||
{
|
||||
my $class = shift;
|
||||
my $mtm = shift;
|
||||
|
||||
if ($class !~ /Utils/) {
|
||||
$mtm = $class;
|
||||
}
|
||||
|
||||
if (defined $MTM_P6P7{$mtm} && $MTM_P6P7{$mtm} == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
=head3 filter_nodes
|
||||
##########################################################################
|
||||
# Fliter the nodes to specific groups
|
||||
# For specific command, figure out the node lists which should be handled by blade.pm, fsp.pm or ipmi.pm
|
||||
# mp group: the nodes will be handled by blade.pm
|
||||
# fsp group: the nodes will be handled by fsp.pm
|
||||
# bmc group: the nodes will be handled by ipmi.pm
|
||||
# mp group (argument: $mpnodes): the nodes will be handled by blade.pm
|
||||
# fsp group (argument: $fspnodes): the nodes will be handled by fsp.pm
|
||||
# bmc group (argument: $bmcnodes): the nodes will be handled by ipmi.pm
|
||||
# For rspconfig network, the NGP ppc blade will be included in the group of mp, othewise in the fsp group
|
||||
# For getmacs -D, the NGP ppc blade will be included in the group of common fsp, otherwise in the mp group
|
||||
# For renergy command, NGP blade will be moved to mp group
|
||||
@@ -3346,13 +3401,29 @@ sub filter_nodes{
|
||||
if ($ipmitab) {
|
||||
$ipmitabhash = $ipmitab->getNodesAttribs(\@nodes,['bmc']);
|
||||
}
|
||||
|
||||
# get the node attributes from the nodehm table
|
||||
my $nodehmhash;
|
||||
my $nodehmtab = xCAT::Table->new("nodehm");
|
||||
if ($nodehmtab) {
|
||||
$nodehmhash = $nodehmtab->getNodesAttribs(\@nodes,['mgt']);
|
||||
}
|
||||
|
||||
my (@mp, @ngpfsp, @ngpbmc, @commonfsp, @commonbmc, @unknow);
|
||||
# get the node attributes from the nodetype table
|
||||
my $nodetypehash;
|
||||
my $nodetypetab = xCAT::Table->new("nodetype");
|
||||
if ($nodetypetab) {
|
||||
$nodetypehash = $nodetypetab->getNodesAttribs(\@nodes, ['arch']);
|
||||
}
|
||||
|
||||
# get the node attributes from the vpd table
|
||||
my $vpdhash,
|
||||
my $vpdtab = xCAT::Table->new("vpd");
|
||||
if ($vpdtab) {
|
||||
$vpdhash = $vpdtab->getNodesAttribs(\@nodes, ['mtm']);
|
||||
}
|
||||
|
||||
my (@mp, @ngpfsp, @ngpbmc, @commonfsp, @commonbmc, @unknow, @nonppcle, @p6p7);
|
||||
|
||||
# if existing in both 'mpa' and 'ppc', a ngp power blade
|
||||
# if existing in both 'mpa' and 'ipmi', a ngp x86 blade
|
||||
@@ -3386,9 +3457,21 @@ sub filter_nodes{
|
||||
} elsif (defined ($ppctabhash->{$_}->[0]) && defined ($ppctabhash->{$_}->[0]->{'hcp'})) {
|
||||
# common power node
|
||||
push @commonfsp, $_;
|
||||
# whether is a Power 8 or higher with FSP
|
||||
if (defined ($vpdhash->{$_}->[0]) && defined ($vpdhash->{$_}->[0]->{'mtm'})) {
|
||||
if (isP6P7($vpdhash->{$_}->[0]->{'mtm'})) {
|
||||
push @p6p7, $_;
|
||||
}
|
||||
}
|
||||
} elsif (defined ($ipmitabhash->{$_}->[0]) && defined ($ipmitabhash->{$_}->[0]->{'bmc'})) {
|
||||
# common bmc node
|
||||
push @commonbmc, $_;
|
||||
# whether is a Power 8 or higher with FSP
|
||||
if (defined ($nodetypehash->{$_}->[0]) && defined ($nodetypehash->{$_}->[0]->{'arch'})) {
|
||||
if ($nodetypehash->{$_}->[0]->{'arch'} ne "ppc64le") {
|
||||
push @nonppcle, $_;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
push @unknow, $_;
|
||||
}
|
||||
@@ -3422,6 +3505,16 @@ sub filter_nodes{
|
||||
push @{$mpnodes}, @ngpfsp;
|
||||
}
|
||||
} elsif ($cmd eq "renergy") {
|
||||
# for renergy command, only the p6,p7 get to the general fsp.pm
|
||||
# P8 and higher will get in the energy.pm
|
||||
@{$fspnodes} = ();
|
||||
push @{$fspnodes}, @p6p7;
|
||||
|
||||
# for rnergy command, only the non-ppcle nodes get to the general ipmi.pm
|
||||
# ppcle of P8 and higher will get in the energy.pm
|
||||
@{$bmcnodes} = ();
|
||||
push @{$bmcnodes}, @nonppcle;
|
||||
|
||||
if (grep /^(relhistogram)/, @args) {
|
||||
push @{$bmcnodes}, @ngpbmc;
|
||||
} else {
|
||||
|
@@ -27,17 +27,34 @@ B<Power 7 server specific :>
|
||||
|
||||
=over 2
|
||||
|
||||
B<renergy> I<noderange> [-V] { all | [savingstatus] [dsavingstatus]
|
||||
[cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin]
|
||||
[averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed]
|
||||
[syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin]
|
||||
[ffoTurbo] [ffoNorm] [ffovalue]}
|
||||
|
||||
B<renergy> I<noderange> [-V] { savingstatus={on | off}
|
||||
| dsavingstatus={on-norm | on-maxp | off}
|
||||
| fsavingstatus={on | off} | ffovalue=MHZ
|
||||
| cappingstatus={on | off} | cappingwatt=watt
|
||||
| cappingperc=percentage }
|
||||
|
||||
=back
|
||||
|
||||
B<Power 8 server specific :>
|
||||
|
||||
=over 2
|
||||
|
||||
B<renergy> I<noderange> [-V] { all | [savingstatus] [dsavingstatus]
|
||||
[cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin]
|
||||
[averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed]
|
||||
[averageAC] [averageAChistory] [averageDC] [averageDChistory]
|
||||
[ambienttemp] [ambienttemphistory] [exhausttemp] [exhausttemphistory]
|
||||
[fanspeed] [fanspeedhistory] [CPUspeed] [CPUspeedhistory]
|
||||
[syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin]
|
||||
[ffoTurbo] [ffoNorm] [ffovalue]}
|
||||
|
||||
B<renergy> I<noderange> [-V] { savingstatus={on | off}
|
||||
| dsavingstatus={on-norm | on-maxp | off}
|
||||
| fsavingstatus={on | off} | ffovalue=MHZ
|
||||
| cappingstatus={on | off} | cappingwatt=watt
|
||||
| cappingperc=percentage }
|
||||
| fsavingstatus={on | off} | ffovalue=MHZ }
|
||||
|
||||
=back
|
||||
|
||||
@@ -127,10 +144,11 @@ user can query and set the power saving and power capping status, and also can
|
||||
query the average consumed energy, the ambient and exhaust temperature,
|
||||
the processor frequency for a server.
|
||||
|
||||
B<renergy> command supports IBM POWER6 and POWER7 rack-mounted servers,
|
||||
B<renergy> command supports IBM POWER6, POWER7 and POWER8 rack-mounted servers,
|
||||
BladeCenter management modules, blade servers, and iDataPlex servers.
|
||||
For system p rack-mounted servers, the following specific hardware types are supported:
|
||||
For I<Power6> and I<Power7> rack-mounted servers, the following specific hardware types are supported:
|
||||
I<8203-E4A>, I<8204-E8A>, I<9125-F2A>, I<8233-E8B>, I<8236-E8C>.
|
||||
For I<Power8> server, there's no hardware type restriction.
|
||||
|
||||
The parameter I<noderange> needs to be specified for the B<renergy> command to
|
||||
get the target servers. The I<noderange> should be a list of CEC node names, blade
|
||||
@@ -234,11 +252,13 @@ will get response immediately.
|
||||
|
||||
=head1 B<PREREQUISITES>
|
||||
|
||||
For the system p nodes, the B<renergy> command depends
|
||||
For the I<Power6> and I<Power7> nodes, the B<renergy> command depends
|
||||
on the Energy Management Plugin B<xCAT-pEnergy> to
|
||||
communicate with server. B<xCAT-pEnergy> can be downloaded from the IBM web site:
|
||||
http://www.ibm.com/support/fixcentral/. (Other Software -> EM)
|
||||
|
||||
NOTE: I<Power8> nodes don't need this specific energy management package.
|
||||
|
||||
For iDataPlex nodes, the B<renergy> command depends
|
||||
on the Energy Management Plugin B<xCAT-xEnergy> to
|
||||
communicate with server. This plugin must be requested from IBM.
|
||||
@@ -262,12 +282,14 @@ Display the version information.
|
||||
|
||||
Verbose output.
|
||||
|
||||
|
||||
=item B<all>
|
||||
|
||||
Query all energy attributes which supported by the specific
|
||||
type of hardware.
|
||||
|
||||
For I<Power8> machines, will not display the attributes
|
||||
for historical records.
|
||||
|
||||
=item B<pd1all>
|
||||
|
||||
Query all energy attributes of the power domain 1 for blade
|
||||
@@ -282,6 +304,10 @@ management module node.
|
||||
|
||||
Query the current ambient temperature. (Unit is centigrade)
|
||||
|
||||
=item B<ambienttemphistory>
|
||||
|
||||
Query the historical records which were generated in last one hour for B<ambienttemp>.
|
||||
|
||||
=item B<availableDC>
|
||||
|
||||
Query the total DC power available for the entire blade center chassis.
|
||||
@@ -298,10 +324,18 @@ averageAC is the total AC power being consumed by all modules
|
||||
in the chassis. It also includes power consumed by the Chassis
|
||||
Cooling Devices for BCH chassis.
|
||||
|
||||
=item B<averageAChistory>
|
||||
|
||||
Query the historical records which were generated in last one hour for B<averageAC>.
|
||||
|
||||
=item B<averageDC>
|
||||
|
||||
Query the average power consumed (Output). (Unit is watt)
|
||||
|
||||
=item B<averageDChistory>
|
||||
|
||||
Query the historical records which were generated in last one hour for B<averageDC>.
|
||||
|
||||
=item B<capability>
|
||||
|
||||
Query the Power Capabilities of the blade server.
|
||||
@@ -380,6 +414,10 @@ guaranteed.
|
||||
|
||||
Query the effective processor frequency. (Unit is MHz)
|
||||
|
||||
=item B<CPUspeedhistory>
|
||||
|
||||
Query the historical records which were generated in last one hour for B<CPUspeed>
|
||||
|
||||
=item B<dsavingstatus>
|
||||
|
||||
Query the dynamic power saving status. The result should
|
||||
@@ -410,6 +448,21 @@ B<savingstatus> is in turn off status.
|
||||
|
||||
Query the current exhaust temperature. (Unit is centigrade)
|
||||
|
||||
=item B<exhausttemphistory>
|
||||
|
||||
Query the historical records which were generated in last one hour for B<exhausttemp>
|
||||
|
||||
=item B<fanspeed>
|
||||
|
||||
Query the fan speed for all the fans which installed in this node. (Unit is RPM - Rotations Per Minute))
|
||||
|
||||
If there are multiple fans for a node, multiple lines will be output. And a fan name in bracket will be
|
||||
appended after B<fanspped> attribute name.
|
||||
|
||||
=item B<fanspeedhistory>
|
||||
|
||||
Query the historical records which were generated in last one hour for B<fanspeed>.
|
||||
|
||||
=item B<ffoMin>
|
||||
|
||||
Query the minimum cpu frequency which can be set for FFO. (Fixed
|
||||
@@ -455,7 +508,7 @@ The ffovalue setting operation needs about 1 minute to take effect.
|
||||
Query the status of FFO. The result should be 'on' or 'off'.
|
||||
'on' - enable; 'off' - disable.
|
||||
|
||||
=item B<fsavingstatus>={B<on> │ B<off>}
|
||||
=item B<fsavingstatus>={B<on> | B<off>}
|
||||
|
||||
Set the status of FFO. The value must be 'on' or 'off'.
|
||||
|
||||
@@ -574,7 +627,7 @@ Query the time used from FSP standby to OS standby.
|
||||
=item B<syssbpower>
|
||||
|
||||
Query the system power consumed prior to power on.
|
||||
(Unit is MHz)
|
||||
(Unit is Watt)
|
||||
|
||||
=item B<thermaloutput>
|
||||
|
||||
@@ -595,7 +648,7 @@ center chassis.
|
||||
|
||||
=item 1
|
||||
|
||||
Query all the attributes which CEC1,CEC2 supported.
|
||||
Query all attributes which CEC1,CEC2 supported.
|
||||
|
||||
B<renergy> CEC1,CEC2 all
|
||||
|
||||
@@ -629,6 +682,43 @@ The output of the query operation:
|
||||
|
||||
=item 2
|
||||
|
||||
Query the B<fanspeed> attribute for Power8 CEC.
|
||||
|
||||
B<renergy> CEC1 fanspeed
|
||||
|
||||
The output of the query operation:
|
||||
|
||||
CEC1: fanspeed (Fan U78CB.001.WZS00MA-A1 00002101): 5947 RPM
|
||||
CEC1: fanspeed (Fan U78CB.001.WZS00MA-A2 00002103): 6081 RPM
|
||||
CEC1: fanspeed (Fan U78CB.001.WZS00MA-A3 00002105): 6108 RPM
|
||||
CEC1: fanspeed (Fan U78CB.001.WZS00MA-A4 00002107): 6000 RPM
|
||||
CEC1: fanspeed (Fan U78CB.001.WZS00MA-A5 00002109): 6013 RPM
|
||||
CEC1: fanspeed (Fan U78CB.001.WZS00MA-A6 0000210B): 6013 RPM
|
||||
CEC1: fanspeed (Fan U78CB.001.WZS00MA-E1 0000210C): 4992 RPM
|
||||
CEC1: fanspeed (Fan U78CB.001.WZS00MA-E2 0000210D): 5016 RPM
|
||||
|
||||
=item 3
|
||||
|
||||
Query the historical records for the B<CPUspeed> attribute. (Power8 CEC)
|
||||
|
||||
B<renergy> CEC1 CPUspeedhistory
|
||||
|
||||
The output of the query operation:
|
||||
|
||||
CEC1: CPUspeedhistory: 2027 MHZ: 20141226042900
|
||||
CEC1: CPUspeedhistory: 2027 MHZ: 20141226042930
|
||||
CEC1: CPUspeedhistory: 2244 MHZ: 20141226043000
|
||||
CEC1: CPUspeedhistory: 2393 MHZ: 20141226043030
|
||||
CEC1: CPUspeedhistory: 2393 MHZ: 20141226043100
|
||||
CEC1: CPUspeedhistory: 2393 MHZ: 20141226043130
|
||||
CEC1: CPUspeedhistory: 2393 MHZ: 20141226043200
|
||||
CEC1: CPUspeedhistory: 2393 MHZ: 20141226043230
|
||||
CEC1: CPUspeedhistory: 2393 MHZ: 20141226043300
|
||||
CEC1: CPUspeedhistory: 2393 MHZ: 20141226043330
|
||||
...
|
||||
|
||||
=item 4
|
||||
|
||||
Query all the attirbutes for management module node MM1. (For chassis)
|
||||
|
||||
B<renergy> MM1 all
|
||||
@@ -658,7 +748,7 @@ The output of the query operation:
|
||||
in this power domain.
|
||||
mm1: thermaloutput: 9717.376000 BTU/hour
|
||||
|
||||
=item 3
|
||||
=item 5
|
||||
|
||||
Query all the attirbutes for blade server node blade1.
|
||||
|
||||
@@ -674,7 +764,7 @@ The output of the query operation:
|
||||
blade1: maxCPUspeed: 4204MHZ
|
||||
blade1: savingstatus: off
|
||||
|
||||
=item 4
|
||||
=item 6
|
||||
|
||||
Query the attributes savingstatus, cappingstatus
|
||||
and CPUspeed for server CEC1.
|
||||
@@ -687,7 +777,7 @@ The output of the query operation:
|
||||
CEC1: cappingstatus: on
|
||||
CEC1: CPUspeed: 3621 MHz
|
||||
|
||||
=item 5
|
||||
=item 7
|
||||
|
||||
Turn on the power saving function of CEC1.
|
||||
|
||||
@@ -698,7 +788,7 @@ The output of the setting operation:
|
||||
CEC1: Set savingstatus succeeded.
|
||||
CEC1: This setting may need some minutes to take effect.
|
||||
|
||||
=item 6
|
||||
=item 8
|
||||
|
||||
Set the power capping value base on the percentage of the
|
||||
max-min capping value. Here, set it to 50%.
|
||||
|
1027
xCAT-server/lib/xcat/plugins/energy.pm
Normal file
1027
xCAT-server/lib/xcat/plugins/energy.pm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -81,7 +81,7 @@ sub preprocess_request {
|
||||
my (@fspnodes, @nohandle);
|
||||
xCAT::Utils->filter_nodes($arg1, undef, \@fspnodes, undef, \@nohandle);
|
||||
if (@fspnodes) {
|
||||
$arg1->{noderange} = \@fspnodes;
|
||||
$arg1->{node} = \@fspnodes;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ AutoReqProv: no
|
||||
# also need to fix Requires for AIX
|
||||
%ifos linux
|
||||
BuildArch: noarch
|
||||
Requires: perl-IO-Socket-SSL perl-XML-Simple perl-XML-Parser perl-Digest-SHA1
|
||||
Requires: perl-IO-Socket-SSL perl-XML-Simple perl-XML-Parser perl-Digest-SHA1 perl(LWP::Protocol::https)
|
||||
Obsoletes: atftp-xcat
|
||||
%endif
|
||||
|
||||
|
Reference in New Issue
Block a user