From 06115c9cb860631e07683d35fd47added57e0561 Mon Sep 17 00:00:00 2001 From: daniceexi Date: Tue, 23 Dec 2014 02:42:16 -0500 Subject: [PATCH] more code change for P8 energy support --- perl-xCAT/xCAT/CIMUtils.pm | 141 ++++++++++- xCAT-server/lib/xcat/plugins/energy.pm | 319 +++++++++++++++---------- 2 files changed, 329 insertions(+), 131 deletions(-) diff --git a/perl-xCAT/xCAT/CIMUtils.pm b/perl-xCAT/xCAT/CIMUtils.pm index 2e31cf710..766f247a6 100644 --- a/perl-xCAT/xCAT/CIMUtils.pm +++ b/perl-xCAT/xCAT/CIMUtils.pm @@ -43,13 +43,17 @@ use Data::Dumper; 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: - A hash reference. The valid key includes: + 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. - value - Array of instances, each instance is a hash contains lots of properties. + + 2 - Array of instances, each instance is a hash contains lots of properties. + + 3 - The name path of instance =cut @@ -62,8 +66,9 @@ sub enum_instance my $cim_params = shift; + # This is a mandatory parameter unless ($cim_params->{classname}) { - return ({rc => 1, msg => "Miss the classname"}); + return ({rc => 1, msg => "Missed the classname"}); } unless ($cim_params->{namespace}) { @@ -152,6 +157,13 @@ sub enum_instance 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) { @@ -181,9 +193,128 @@ sub enum_instance } push @{$ret_value}, $ins_value; } - return ({rc =>0}, $ret_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; + } + + # if no http and cim error, the setting was succeeded + return ($ret); +} =head1 gen_http_request () Description: @@ -207,7 +338,7 @@ sub gen_http_request # 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 => "Miss the mandatory parameters: ip, port, user or password"}); + return ({rc => 1, msg => "Missed the mandatory parameters: ip, port, user or password"}); } # set the default value for parameters diff --git a/xCAT-server/lib/xcat/plugins/energy.pm b/xCAT-server/lib/xcat/plugins/energy.pm index dac0439ad..1c93e9d9c 100644 --- a/xCAT-server/lib/xcat/plugins/energy.pm +++ b/xCAT-server/lib/xcat/plugins/energy.pm @@ -152,24 +152,28 @@ sub parse_args { # make sure the attribute is valid if ($SET_ATTRS{$set_attr} != 1) { - return (1, &usage()); + return (1, &usage("Invalid attribute.")); + } + + if ($set_flag) { + return (1, &usage("Only supports to perform one setting at invoke.")); } # make sure the value for attirbute is valid if (($set_attr eq "savingstatus" || $set_attr eq "fsavingstatus") && ($set_value ne "on" && $set_value ne "off")) { - return (1, &usage()); + return (1, &usage("Incorrect Value")); } elsif ($set_attr eq "dsavingstatus" && ($set_value ne "off" && $set_value ne "on-norm" && $set_value ne "on-maxp")) { - return (1, &usage()); + return (1, &usage("Incorrect Value")); } elsif ($set_attr eq "cappingstatus" && ($set_value ne "on" && $set_value ne "off")) { - return (1, &usage()); + return (1, &usage("Incorrect Value")); } elsif ( ($set_attr eq "cappingwatt" || $set_attr eq "cappingperc" || $set_attr eq "ffovalue") && $set_value =~ /\D/) { - return (1, &usage()); + return (1, &usage("Incorrect Value")); } push @set_pair, $set_attr."=".$set_value; @@ -402,6 +406,7 @@ sub process_request { RETURN $ret - return code and messages $pum - a hash includes all the attributes + $namepath - the name path of pum instance =cut @@ -410,11 +415,12 @@ sub query_pum my $http_params = shift; my %cimargs = ( classname => 'FipS_PUMService' ); - my ($ret, $value) = xCAT::CIMUtils->enum_instance($http_params, \%cimargs); + my ($ret, $value, $namepath) = xCAT::CIMUtils->enum_instance($http_params, \%cimargs); if ($ret->{rc}) { return ($ret); } + # parse the return xml to get all the property of pum instance my $pum; foreach my $instance (@$value) { foreach my $pname (keys %{$instance->{property}}) { @@ -422,7 +428,7 @@ sub query_pum } } - return ($ret, $pum); + return ($ret, $pum, $namepath); } =head3 run_cim @@ -464,11 +470,11 @@ sub run_cim # Try to connect CIM Server to Enumerate CEC object; # If cannot access this ip, return 10 for caller to connect to the next ip - my %cimargs = ( + my $cimargs = { classname => 'fips_cec', - ); + }; $http_params->{timeout} = 5; - my ($ret, $value) = xCAT::CIMUtils->enum_instance($http_params, \%cimargs); + my ($ret, $value) = xCAT::CIMUtils->enum_instance($http_params, $cimargs); if ($ret->{rc}) { if ($ret->{msg} =~ /Couldn't connect to server/) { xCAT::MsgUtils->message("E", data => ["$node: Couldn not connect to server [$http_params->{ip}]."], $callback); @@ -480,149 +486,210 @@ sub run_cim } - - # start to handle the query and setting - my $query_pum_value; - # Pre-query some specific objects - my $query_pum_capabilities_flag; # set to query the instance for [FipS_PUMServiceCapabilities] + # ======start to handle the query and setting====== + + # Pre-query some specific instances since some instances are common for multiple energy attributes + #my $query_pum_capabilities_flag; # set to query the instance for [FipS_PUMServiceCapabilities] my $query_pum_flag; # set to query the instance for [FipS_PUMService] - foreach my $attr (split(',', $query_list)) { - if ($attr =~ /^(savingstatus|dsavingstatus|fsavingstatus)$/) { - $query_pum_flag = 1; + my $query_pum_value; # the rep queried PUM instance + my $namepath_pum; # the name path of PUM instance + + if ($query_list) { + foreach my $attr (split(',', $query_list)) { + if ($attr =~ /^(savingstatus|dsavingstatus|fsavingstatus)$/) { + $query_pum_flag = 1; + last; + } + if ($attr =~ /^(ffoMin|ffoVmin|ffoTurbo|ffoNorm|ffovalue)$/) { + $query_pum_flag = 1; + last; + } } - if ($attr =~ /^(ffoMin|ffoVmin|ffoTurbo|ffoNorm|ffovalue)$/) { + } + + if ($set_pair) { + my ($set_name, $set_value) = split('=', $set_pair); + if ($set_name =~/^(savingstatus|dsavingstatus|fsavingstatus|ffovalue)$/) { $query_pum_flag = 1; } } - + + # query the pre required instances if ($query_pum_flag) { - ($ret, $query_pum_value) = query_pum($http_params); + ($ret, $query_pum_value, $namepath_pum) = query_pum($http_params); if ($ret->{rc}) { xCAT::MsgUtils->message("E", {data => ["$node: $ret->{msg}"]}, $callback); return ($ret->{rc}); } } - foreach my $attr (split(',', $query_list)) { - if ($attr =~ /^(savingstatus|dsavingstatus|fsavingstatus)$/) { - if ($query_pum_flag) { - if (defined ($query_pum_value->{PowerUtilizationMode})) { - # 2 = None; 3 = Dynamic; 4 = Static; 32768 = Dynamic Favor Performance; 32769 = FFO - if ($query_pum_value->{PowerUtilizationMode} eq "2") { - push @output, "$node: $attr: off"; - } elsif ($query_pum_value->{PowerUtilizationMode} eq "3") { - if ($attr eq "dsavingstatus") { - push @output, "$node: $attr: on-norm"; - } else { - push @output, "$node: $attr: off"; + # perform the query request + if ($query_list) { + foreach my $attr (split(',', $query_list)) { + # Query the power saving status + if ($attr =~ /^(savingstatus|dsavingstatus|fsavingstatus)$/) { + if ($query_pum_flag) { + if (defined ($query_pum_value->{PowerUtilizationMode})) { + # 2 = None; 3 = Dynamic; 4 = Static; 32768 = Dynamic Favor Performance; 32769 = FFO + if ($query_pum_value->{PowerUtilizationMode} eq "2") { + push @output, "$node: $attr: off"; + } elsif ($query_pum_value->{PowerUtilizationMode} eq "3") { + if ($attr eq "dsavingstatus") { + push @output, "$node: $attr: on-norm"; + } else { + push @output, "$node: $attr: off"; + } + } elsif ($query_pum_value->{PowerUtilizationMode} eq "4") { + if ($attr eq "savingstatus") { + push @output, "$node: $attr: on"; + } else { + push @output, "$node: $attr: off"; + } + } elsif ($query_pum_value->{PowerUtilizationMode} eq "32768") { + if ($attr eq "dsavingstatus") { + push @output, "$node: $attr: on-maxp"; + } else { + push @output, "$node: $attr: off"; + } + } elsif ($query_pum_value->{PowerUtilizationMode} eq "32769") { + if ($attr eq "fsavingstatus") { + push @output, "$node: $attr: on"; + } else { + push @output, "$node: $attr: off"; + } } - } elsif ($query_pum_value->{PowerUtilizationMode} eq "4") { - if ($attr eq "savingstatus") { - push @output, "$node: $attr: on"; - } else { - push @output, "$node: $attr: off"; - } - } elsif ($query_pum_value->{PowerUtilizationMode} eq "32768") { - if ($attr eq "dsavingstatus") { - push @output, "$node: $attr: on-maxp"; - } else { - push @output, "$node: $attr: off"; - } - } elsif ($query_pum_value->{PowerUtilizationMode} eq "32769") { - if ($attr eq "fsavingstatus") { - push @output, "$node: $attr: on"; - } else { - push @output, "$node: $attr: off"; - } - } - } else { - push @output, "$node: $attr: na"; - } - } else { - push @output, "$node: $attr: na"; - } - } - - if ($attr =~ /^(ffoMin|ffoVmin|ffoTurbo|ffoNorm|ffovalue)$/) { - if ($query_pum_flag) { - if (defined ($query_pum_value->{FixedFrequencyPoints}) && defined ($query_pum_value->{FixedFrequencyPointValues})) { - my @ffo_point = split (',', $query_pum_value->{FixedFrequencyPoints}); - my @ffo_point_value = split (',', $query_pum_value->{FixedFrequencyPointValues}); - foreach my $index (0..$#ffo_point) { - if ($ffo_point[$index] eq '2' && $attr eq 'ffoNorm') { # Norminal - push @output, "$node: $attr: $ffo_point_value[$index]"; - } elsif ($ffo_point[$index] eq '3' && $attr eq 'ffoTurbo') { # Turbo - push @output, "$node: $attr: $ffo_point_value[$index]"; - } elsif ($ffo_point[$index] eq '4' && $attr eq 'ffoVmin') { # Vmin - push @output, "$node: $attr: $ffo_point_value[$index]"; - } elsif ($ffo_point[$index] eq '5' && $attr eq 'ffoMin') { # Min - push @output, "$node: $attr: $ffo_point_value[$index]"; - } - } - } else { - push @output, "$node: $attr: na"; - } - } else { - push @output, "$node: $attr: na"; - } - } - - if ($attr eq 'ffovalue') { - if ($query_pum_flag) { - if (defined ($query_pum_value->{FixedFrequencyOverrideFreq})) { - if ($query_pum_value->{FixedFrequencyOverrideFreq} eq '4294967295') { - push @output, "$node: $attr: 0"; } else { - push @output, "$node: $attr: $query_pum_value->{FixedFrequencyOverrideFreq}"; + push @output, "$node: $attr: na"; } } else { push @output, "$node: $attr: na"; } - } else { - push @output, "$node: $attr: na"; } - + + # Query the FFO settings + if ($attr =~ /^(ffoMin|ffoVmin|ffoTurbo|ffoNorm|ffovalue)$/) { + if ($query_pum_flag) { + if (defined ($query_pum_value->{FixedFrequencyPoints}) && defined ($query_pum_value->{FixedFrequencyPointValues})) { + my @ffo_point = split (',', $query_pum_value->{FixedFrequencyPoints}); + my @ffo_point_value = split (',', $query_pum_value->{FixedFrequencyPointValues}); + foreach my $index (0..$#ffo_point) { + if ($ffo_point[$index] eq '2' && $attr eq 'ffoNorm') { # Norminal + push @output, "$node: $attr: $ffo_point_value[$index]"; + } elsif ($ffo_point[$index] eq '3' && $attr eq 'ffoTurbo') { # Turbo + push @output, "$node: $attr: $ffo_point_value[$index]"; + } elsif ($ffo_point[$index] eq '4' && $attr eq 'ffoVmin') { # Vmin + push @output, "$node: $attr: $ffo_point_value[$index]"; + } elsif ($ffo_point[$index] eq '5' && $attr eq 'ffoMin') { # Min + push @output, "$node: $attr: $ffo_point_value[$index]"; + } + } + } else { + push @output, "$node: $attr: na"; + } + } else { + push @output, "$node: $attr: na"; + } + } + + # Query the FFO Value + if ($attr eq 'ffovalue') { + if ($query_pum_flag) { + if (defined ($query_pum_value->{FixedFrequencyOverrideFreq})) { + if ($query_pum_value->{FixedFrequencyOverrideFreq} eq '4294967295') { + push @output, "$node: $attr: 0"; + } else { + push @output, "$node: $attr: $query_pum_value->{FixedFrequencyOverrideFreq}"; + } + } else { + push @output, "$node: $attr: na"; + } + } else { + push @output, "$node: $attr: na"; + } + + } } } + # Perform the setting request + if ($set_pair) { + my ($set_name, $set_value) = split('=', $set_pair); + if ($set_name =~/^(savingstatus|dsavingstatus|fsavingstatus|ffovalue)$/) { + if ($query_pum_flag) { + if (defined ($query_pum_value->{PowerUtilizationMode})) { + + # set the power saving value + my $ps_value; + if ($set_name eq "savingstatus") { + if ($set_value eq 'on') { + $ps_value = '4'; + } elsif ($set_value eq 'off') { + $ps_value = '2'; + } + } elsif ($set_name eq "dsavingstatus") { + if ($set_value eq 'on-norm') { + $ps_value = '3'; + } elsif ($set_value eq 'on-maxp') { + $ps_value = '32768'; + }elsif ($set_value eq 'off') { + $ps_value = '2'; + } + } elsif ($set_name eq "fsavingstatus") { + if ($set_value eq 'on') { + $ps_value = '32769'; + } elsif ($set_value eq 'off') { + $ps_value = '2'; + } + } + + if ($set_name eq "ffovalue") { + # set ffo value + $cimargs = { + propertyname => 'FixedFrequencyOverrideFreq', + propertyvalue => $set_value, + namepath => $namepath_pum, + }; + $ret = xCAT::CIMUtils->set_property($http_params, $cimargs); + if ($ret->{rc}) { + push @output, "$node: Set $set_name failed. [$ret->{msg}]"; + } else { + push @output, "$node: Set $set_name succeeded"; + } + } else { + # set the power saving + if ($ps_value eq $query_pum_value->{PowerUtilizationMode}) { # do nothing if it already was the correct status + push @output, "$node: Set $set_name succeeded"; + } else { + # perform the setting + $cimargs = { + propertyname => 'PowerUtilizationMode', + propertyvalue => $ps_value, + namepath => $namepath_pum, + }; + $ret = xCAT::CIMUtils->set_property($http_params, $cimargs); + if ($ret->{rc}) { + push @output, "$node: Set $set_name failed. [$ret->{msg}]"; + } else { + push @output, "$node: Set $set_name succeeded"; + } + } + } + } else { + push @output, "$node: Set $set_name failed"; + } + } else { + push @output, "$node: Set $set_name failed"; + } + } + } + # Display the output my $rsp; push @{$rsp->{data}}, @output; xCAT::MsgUtils->message("I", $rsp, $callback); - return; - - - - %cimargs = ( - classname => 'CIM_PowerUtilizationManagementService', - #classname => 'FipS_PowerMetricValue', - ); - - ($ret, $value) = xCAT::CIMUtils->enum_instance($http_params, \%cimargs); - if ($ret->{rc}) { - xCAT::MsgUtils->message("E", {data => "$node: $ret->{msg}"}, $callback); - return; - } - - if ($cimargs{classname} eq 'FipS_PowerMetricValue') { - my %instance_id; - foreach my $instance (@$value) { - if (defined ($instance->{property}->{InstanceID})) { - my $i_id = $instance->{property}->{InstanceID}->{value}; - $i_id =~ s/ .*$//; - $instance_id{$i_id} = 1; - } - foreach my $pname (keys %{$instance->{property}}) { - xCAT::MsgUtils->message("I", "$pname: $instance->{property}->{$pname}->{value} ($instance->{property}->{$pname}->{type})\n", $callback); - } - } - #foreach (keys %instance_id) { - # print "Instance ID for FipS_PowerMetricValue: $_\n"; - #} - } else { - - } + return; } + 1;