mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-30 19:02:27 +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