From f6071c9f1ef49ff5b8d8c7887f82bac6a9df10c7 Mon Sep 17 00:00:00 2001 From: daniceexi Date: Mon, 17 May 2010 11:52:18 +0000 Subject: [PATCH] Code drop of HX5 support git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@6147 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/Usage.pm | 18 +- xCAT-client/pods/man1/lsflexnode.1.pod | 184 ++++++++++ xCAT-client/pods/man1/mkflexnode.1.pod | 62 ++++ xCAT-client/pods/man1/rmflexnode.1.pod | 62 ++++ xCAT-server/lib/xcat/plugins/blade.pm | 462 +++++++++++++++++++++++++ 5 files changed, 786 insertions(+), 2 deletions(-) create mode 100644 xCAT-client/pods/man1/lsflexnode.1.pod create mode 100644 xCAT-client/pods/man1/mkflexnode.1.pod create mode 100644 xCAT-client/pods/man1/rmflexnode.1.pod diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index 8c9caad49..b9368fde6 100644 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -242,7 +242,18 @@ Options: [attr=val [attr=val...]] Specifies one or more 'attribute equals value' pairs, separated by spaces. (AIX only)", - + "lsflexnode" => +"Usage: + lsflexnode [-h|--help|-v|--version] + lsflexnode ", + "mkflexnode" => +"Usage: + mkflexnode [-h|--help|-v|--version] + mkflexnode ", + "rmflexnode" => +"Usage: + rmflexnode [-h|--help|-v|--version] + rmflexnode ", ); my $vers = xCAT::Utils->Version(); my %version = ( @@ -263,7 +274,10 @@ my %version = ( "rmvm" => "$vers", "lsslp" => "$vers", "rflash" => "$vers", - "renergy" => "$vers" + "renergy" => "$vers", + "lsflexnode" => "$vers", + "mkflexnode" => "$vers", + "rmflexnode" => "$vers", ); #-------------------------------------------------------------------------------- diff --git a/xCAT-client/pods/man1/lsflexnode.1.pod b/xCAT-client/pods/man1/lsflexnode.1.pod new file mode 100644 index 000000000..259291ee3 --- /dev/null +++ b/xCAT-client/pods/man1/lsflexnode.1.pod @@ -0,0 +1,184 @@ +=head1 B + +B - Display the information of flexible node + + +=head1 B + +B [-h | --help] + +B [-v | --version] + +B I + + +=head1 B + +IBM BladeCenter HX5 offers flexibility ideal that the blades can be combined together for scalability. + +There are several concepts to support the HX5 multiple blades combination: + +=over 2 + +B: Multiple blades which combined by a scalability card is a complex. + +B: A logic concept which containing part of the B in a complex. Each partition can map to a system to install Operating System. Each partition could have 1HX5, 1HX5+1MD or 2HX5+2MD. (MD is the Memory Drawer) + +B: The physical blade which installed in the slot of a chassis. It can be a HX5 or MD. + +=back + +A B will be created automatically when a multiple blades combination is installed. In this B, every blade belongs to it is working as a B. + +A B can be created base on the B, each B can have one or multiple B. + +The I in the B can be a AMM node or a blade node. + + +=head1 B + +=over 4 + +=item B<-h | --help> + +Display the usage message. + +=item B<-v | --version> + +Display the version information. + +=back + + + +=head1 B + +The meaning of attributes which displayed by the B. The word 'node' in this section means B. + +=over 4 + +=item B + +The unique numeric identifier for a complex installed in the chassis. + +=item B + +The number of partitions currently defined for this complex. + +=item B + +The number of nodes existing in this complex, regardless of their assignment to any given partition. + +=item B + +The unique numeric identifier for a partition defined within a complex installed in the chassis. + +=item B + +The currently configured mode of this partition. It can be 'partition' or 'standalone'. + +=item B + +The number of nodes currently defined for this partition. + +=item B + +The current power status of this partition when the partition has a valid partition configuration. It can be 'poweredoff', 'poweredon', 'resetting' or 'invalid'. + +=item B + +The unique numeric identifier for this node, unique within the partition. If this node does not belong to a partition, the slot number will be displayed. + +=item B + +The physical power state of this node. It can be 'poweredoff', 'poweredon' or 'resetting'. + +=item B + +The base slot number where the node exists in the chassis. + +=item B + +A string providing a summary overview of the resources provided by this node. It includes the CPU number, CPU frequency and Memory size. + +=item B + +The general categorization of the node. It can be 'processor', 'memory' or 'io'. + +=item B + +Indicates if the node is assigned to a partition, and if so, provides an indication of whether the node is the primary node of the partition or not. + +=item B + +The state of a flexible node. It is the state of the partition which this node belongs to. If this node does NOT belong to a partition, the value should be 'invalid'. + +It can be 'poweredoff', 'poweredon', 'resetting' or 'invalid'. + +=item B + +The identifier of the complex this node belongs to. + +=item B + +The identifier of the partition this node belongs to. + + + +=head1 B + +=over 3 + +=item 1 + +Display all the B, B and B which managed by a AMM. + +B amm1 + +The output: + amm1: Complex - 24068 + amm1: ..Partition number - 1 + amm1: ..Complex node number - 2 + amm1: ..Partition = 1 + amm1: ....Partition Mode - partition + amm1: ....Partition node number - 1 + amm1: ....Partition status - poweredoff + amm1: ....Node - 0 (logic id) + amm1: ......Node state - poweredoff + amm1: ......Node slot - 14 + amm1: ......Node type - processor + amm1: ......Node resource - 2 (1866 MHz) / 8 (2 GB) + amm1: ......Node role - secondary + amm1: ..Partition = unassigned + amm1: ....Node - 13 (logic id) + amm1: ......Node state - poweredoff + amm1: ......Node slot - 13 + amm1: ......Node type - processor + amm1: ......Node resource - 2 (1866 MHz) / 8 (2 GB) + amm1: ......Node role - unassigned + +=item 2 + +Display a flexible node. + +B blade1 + +The output: + blade1: Flexnode state - poweredoff + blade1: Complex id - 24068 + blade1: Partition id - 1 + blade1: Slot14: Node state - poweredoff + blade1: Slot14: Node slot - 14 + blade1: Slot14: Node type - processor + blade1: Slot14: Node resource - 2 (1866 MHz) / 8 (2 GB) + blade1: Slot14: Node role - secondary + +=back + +=head1 B + +/opt/xcat/bin/lsflexnode + +=head1 SEE ALSO + +L, L diff --git a/xCAT-client/pods/man1/mkflexnode.1.pod b/xCAT-client/pods/man1/mkflexnode.1.pod new file mode 100644 index 000000000..a9dae8f47 --- /dev/null +++ b/xCAT-client/pods/man1/mkflexnode.1.pod @@ -0,0 +1,62 @@ +=head1 B + +B - Create a flexible node. + + +=head1 B + +B [-h | --help] + +B [-v | --version] + +B I + + +=head1 B + +A flexible node is a B in a complex. Creating a flexible node is to create a partition which including all the slots defined in the xCAT blade node. + +Before creating a flexible node, a general xCAT blade node should be defined. The I attribute of this node should be a node range like 'a-b', it means the blades installed in slots 'a-b' need to be assigned to the partition. 'a' is the start slot, 'b' is the end slot. If this partition only have one slot, the slot range can be 'a'. + +The action of creating flexible node will impact the hardware status. Before creating it, the blades in the slot range should be in B state. + +After the creating, use the B to check the status of the node. + +The I only can be a blade node. + +=head1 B + +=over 4 + +=item B<-h | --help> + +Display the usage message. + +=item B<-v | --version> + +Display the version information. + +=back + + +=head1 B + +=over 3 + +=item 1 + +Create a flexible node base on the xCAT node blade1. + +The blade1 should belong to a complex, the I attribute should be set correctly and all the slots should be in B state. + +B blade1 + +=back + +=head1 B + +/opt/xcat/bin/mkflexnode + +=head1 SEE ALSO + +L, L diff --git a/xCAT-client/pods/man1/rmflexnode.1.pod b/xCAT-client/pods/man1/rmflexnode.1.pod new file mode 100644 index 000000000..36e5f4ff4 --- /dev/null +++ b/xCAT-client/pods/man1/rmflexnode.1.pod @@ -0,0 +1,62 @@ +=head1 B + +B - Delete a flexible node. + + +=head1 B + +B [-h | --help] + +B [-v | --version] + +B I + + +=head1 B + +Delete a flexible node which created by the B command. + +The B command will delete the B which the slots in I attribute assigned to. + +The action of deleting flexible node will impact the hardware status. Before deleting it, the blades in the slot range should be in B state. + +After the deleting, use the B to check the status of the node. + +The I only can be a blade node. + +=head1 B + +=over 4 + +=item B<-h | --help> + +Display the usage message. + +=item B<-v | --version> + +Display the version information. + +=back + + +=head1 B + +=over 3 + +=item 1 + +Delete a flexible node base on the xCAT node blade1. + +The blade1 should belong to a complex, the I attribute should be set correctly and all the slots should be in B state. + +B blade1 + +=back + +=head1 B + +/opt/xcat/bin/rmflexnode + +=head1 SEE ALSO + +L, L diff --git a/xCAT-server/lib/xcat/plugins/blade.pm b/xCAT-server/lib/xcat/plugins/blade.pm index 19e9477e1..611dedf83 100644 --- a/xCAT-server/lib/xcat/plugins/blade.pm +++ b/xCAT-server/lib/xcat/plugins/blade.pm @@ -51,6 +51,9 @@ sub handled_commands { reventlog => 'nodehm:mgt', switchblade => 'nodehm:mgt', renergy => 'nodehm:mgt', + lsflexnode => 'blade', + mkflexnode => 'blade', + rmflexnode => 'blade', }; } @@ -2133,6 +2136,459 @@ sub renergy { } +# the mib object of complex table +my $comp_table_oid = ".1.3.6.1.4.1.2.3.51.2.24.1"; #scalableComplexTable +my $comppart_table_oid = ".1.3.6.1.4.1.2.3.51.2.24.2"; #scalableComplexPartitionTable +my $compnode_table_oid = ".1.3.6.1.4.1.2.3.51.2.24.3"; #scalableComplexNodeTable + +# the mib object used for flexnode management +my $comp_id_oid = ".1.3.6.1.4.1.2.3.51.2.24.1.1.1"; #scalableComplexIdentifier +my $comp_part_num_oid = ".1.3.6.1.4.1.2.3.51.2.24.1.1.2"; #scalableComplexNumPartitions +my $comp_node_num_oid = ".1.3.6.1.4.1.2.3.51.2.24.1.1.3"; #scalableComplexNumNodes + +# following two oid are used for create partition +my $comp_node_start_oid = ".1.3.6.1.4.1.2.3.51.2.24.1.1.4"; #scalableComplexPartStartSlot +my $comp_partnode_num_oid = ".1.3.6.1.4.1.2.3.51.2.24.1.1.5"; #scalableComplexPartNumNodes + +# operate for the partition +my $comp_action_oid = ".1.3.6.1.4.1.2.3.51.2.24.1.1.6"; #scalableComplexAction + + +# oid for complex partitions +my $comp_part_comp_id_oid = ".1.3.6.1.4.1.2.3.51.2.24.2.1.1"; #scalableComplexId +my $comp_part_mode_oid = ".1.3.6.1.4.1.2.3.51.2.24.2.1.3"; #scalableComplexPartitionMode +my $comp_part_nodenum_oid = ".1.3.6.1.4.1.2.3.51.2.24.2.1.4"; #scalableComplexPartitionNumNodes +my $comp_part_status_oid = ".1.3.6.1.4.1.2.3.51.2.24.2.1.5"; #scalableComplexPartitionStatus +my $comp_part_action_oid = ".1.3.6.1.4.1.2.3.51.2.24.2.1.6"; #scalableComplexPartitionAction + + +#oid for complex nodes +my $comp_node_slot_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.1"; #scalableComplexNodeSlot +my $comp_node_type_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.3"; #scalableComplexNodeType +my $comp_node_res_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.4"; #scalableComplexNodeResources +my $comp_node_role_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.5"; #scalableComplexNodeRole +my $comp_node_state_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.6"; #scalableComplexNodeState +my $comp_node_cid_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.10"; #scalableComplexNodeComplexID +my $comp_node_pid_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.11"; #scalableComplexNodePartitionID +my $comp_node_lid_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.12"; #scalableComplexNodeLogicalID +my $comp_node_action_oid = ".1.3.6.1.4.1.2.3.51.2.24.3.1.14"; #scalableComplexNodeAction + +my %compdata = (); + +# get all the attributes for a specified complex +sub getcomplex { + my ($complex_id) = @_; + + my $oid = $comp_part_num_oid.".$complex_id"; + my $data = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'Partition number'} = $data; + + $oid = $comp_node_num_oid.".$complex_id"; + $data = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'Complex node number'} = $data; +} + +# get all the attributes for a partition which belong a certain complex +sub getcomppart { + my ($complex_id, $part_id) = @_; + + my $oid = $comp_part_mode_oid.".$complex_id".".$part_id"; + my $data = $session->get([$oid]); + if ($data == 1) { + $data = "partition"; + } elsif ($data == 2) { + $data = "standalone"; + } + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'partition'}{$part_id}{'Partition Mode'} = $data; + + $oid = $comp_part_nodenum_oid.".$complex_id".".$part_id"; + $data = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'partition'}{$part_id}{'Partition node number'} = $data; + + $oid = $comp_part_status_oid.".$complex_id".".$part_id"; + $data = $session->get([$oid]); + if ($data == 1) { + $data = "poweredoff"; + } elsif ($data == 2) { + $data = "poweredon"; + } elsif ($data == 3) { + $data = "resetting"; + } else { + $data = "invalid"; + } + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'partition'}{$part_id}{'Partition status'} = $data; +} + +# get all the attributes for a node in a complex +sub getcomnode { + my ($node_id) = @_; + + my $oid = $comp_node_lid_oid.".$node_id"; + my $node_logic_id = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + $oid = $comp_node_cid_oid.".$node_id"; + my $complex_id = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + $oid = $comp_node_pid_oid.".$node_id"; + my $part_id = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + $oid = $comp_node_slot_oid.".$node_id"; + my $slot_id = $session->get([$oid]); + + if($part_id == 255) { + $part_id = "unassigned"; + $node_logic_id = $slot_id; + } + + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'partition'}{$part_id}{'node'}{$node_logic_id}{'Node slot'} = $slot_id; + + $oid = $comp_node_type_oid.".$node_id"; + my $data = $session->get([$oid]); + if ($data == 1) { + $data = "processor"; + } elsif ($data == 2) { + $data = "memory"; + } elsif ($data == 3) { + $data = "io"; + } + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'partition'}{$part_id}{'node'}{$node_logic_id}{'Node type'} = $data; + + $oid = $comp_node_res_oid.".$node_id"; + my $data = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'partition'}{$part_id}{'node'}{$node_logic_id}{'Node resource'} = $data; + + $oid = $comp_node_role_oid.".$node_id"; + my $data = $session->get([$oid]); + if ($data == 1) { + $data = "primary"; + } elsif ($data == 2) { + $data = "secondary"; + } else { + $data = "unassigned"; + } + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'partition'}{$part_id}{'node'}{$node_logic_id}{'Node role'} = $data; + + $oid = $comp_node_state_oid.".$node_id"; + my $data = $session->get([$oid]); + if ($data == 1) { + $data = "poweredoff"; + } elsif ($data == 2) { + $data = "poweredon"; + } elsif ($data == 3) { + $data = "resetting"; + } + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + $compdata{$complex_id}{'partition'}{$part_id}{'node'}{$node_logic_id}{'Node state'} = $data; + + return ($complex_id, $part_id, $node_logic_id); +} + +# display the flexnodes for amm +sub lsflexnode { + my ($mpa, $node, $slot, @moreslot) = @_; + + my @output = (); + %compdata = (); + + # if specify the mpa as node, then list all the complex, partition and node in this chassis + if ($node eq $mpa) { + my @attrs = ($comp_id_oid); + while (1) { + my $orig_oid = $attrs[0]; + $session->getnext(\@attrs); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + # if success of getnext, the @attrs will be set to (obj,iid,val,type) + my $complex_obj = $attrs[0]; + my $complex_id = $attrs[1]; + if ($orig_oid =~ /^$complex_obj/) { + &getcomplex($complex_id); + + # search all the partitions in the complex + my @part_attrs = ($comp_part_comp_id_oid.".$complex_id"); + while (1) { + my $orig_part_oid = $part_attrs[0]; + $session->getnext(\@part_attrs); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + my $part_obj = $part_attrs[0]; + my $part_id = $part_attrs[1]; + if ($orig_part_oid =~ /^$part_obj/) { + &getcomppart($complex_id, $part_id); + + } else { + last; + } + + @part_attrs = ($part_obj.".$part_id"); + } # end of searching partition + + } else { + last; + } + + @attrs = ($complex_obj.".$complex_id"); + } # end of searching complex + + # search all the nodes in the complex + my @node_attrs = ($comp_node_slot_oid); + while (1) { + my $orig_node_oid = $node_attrs[0]; + $session->getnext(\@node_attrs); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + my $node_obj = $node_attrs[0]; + my $node_id = $node_attrs[1]; + if ($orig_node_oid =~ /^$node_obj/) { + &getcomnode($node_id); + } else { + last; + } + + @node_attrs = ($node_obj.".$node_id"); + } + + # display complex, parition and nodes in a chassis + foreach my $comp (keys %compdata) { + push @output, "Complex - $comp"; + + foreach my $compattr (keys %{$compdata{$comp}}) { + if ($compattr ne "partition") { + push @output, "..$compattr - $compdata{$comp}{$compattr}"; + } else { + foreach my $part (sort(keys %{$compdata{$comp}{'partition'}})) { + push @output, "..Partition = $part"; + foreach my $partattr (keys %{$compdata{$comp}{'partition'}{$part}}) { + if ($partattr ne "node") { + push @output, "....$partattr - $compdata{$comp}{'partition'}{$part}{$partattr}"; + } else { + foreach my $node (sort(keys %{$compdata{$comp}{'partition'}{$part}{'node'}})) { + if ($node eq "unassigned") { + push @output, "....Node - $node (slot id)"; + } else { + push @output, "....Node - $node (logic id)"; + } + foreach my $nodeattr (keys %{$compdata{$comp}{'partition'}{$part}{'node'}{$node}}) { + push @output, "......$nodeattr - $compdata{$comp}{'partition'}{$part}{'node'}{$node}{$nodeattr}"; + } + } #end of node go ghrough + } + } #end of partition attributes + } #end of parition go through + } + } #end of complex attributes + } #end of complex go through + + } else { # display the information of a node + my @slots = ($slot, @moreslot); + my @sortslots = sort(@slots); + foreach (0..$#sortslots-1) { + if ($sortslots[$_]+1 != $sortslots[$_+1]) { + return (1, "The slots used to create flexed node should be consecutive."); + } + } + + #get the slot information + my $complex_flag = ""; + my $part_flag = ""; + foreach my $slot (@sortslots) { + my ($complex_id, $part_id, $node_id) = &getcomnode($slot); + if ($complex_id eq "NOSUCHINSTANCE") { + return (1, "This node should belong to a complex."); + } + if ($complex_flag ne "" && $complex_flag ne $complex_id) { + return (1, "All the slots of this flexnode should be located in one complex."); + } else { + $complex_flag = $complex_id; + } + if ($part_flag ne "" && $part_flag ne $part_id) { + return (1, "All the slots of this flexnode should belong to one parition."); + } else { + $part_flag = $part_id; + } + + if ($slot eq $sortslots[0]) { + my $oid = $comp_part_status_oid.".$complex_id".".$part_id"; + my $data = $session->get([$oid]); + if ($data == 1) { + $data = "poweredoff"; + } elsif ($data == 2) { + $data = "poweredon"; + } elsif ($data == 3) { + $data = "resetting"; + } else { + $data = "invalid"; + } + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + push @output, "Flexnode state - $data"; + push @output, "Complex id - $complex_id"; + push @output, "Partition id - $part_id"; + } + foreach my $nodeattr (keys %{$compdata{$complex_id}{'partition'}{$part_id}{'node'}{$node_id}}) { + push @output, "Slot$slot: $nodeattr - $compdata{$complex_id}{'partition'}{$part_id}{'node'}{$node_id}{$nodeattr}"; + } + } + } + + return (0, @output); +} + +# Create a flexnode +sub mkflexnode { + my ($mpa, $node, $slot, @moreslot) = @_; + + my @slots = ($slot, @moreslot); + + # the slots assigned for a partition must be consecutive + my @sortslots = sort(@slots); + foreach (0..$#sortslots-1) { + if ($sortslots[$_]+1 != $sortslots[$_+1]) { + return (1, "The slots used to create flexed node should be consecutive."); + } + } + + # get the status of all the nodes + my $complex_id = ""; + foreach my $slot (@sortslots) { + #get the complex of the node + my $oid = $comp_node_cid_oid.".$slot"; + my $node_comp = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + if ($node_comp eq 'NOSUCHINSTANCE') { + return (1, "The slot [$slot] is NOT a member of a complex."); + } + + # all the nodes should be located in one complex + if ($complex_id ne "" && $node_comp ne $complex_id) { + return (1, "All the slots of this flexnode should be located in one complex."); + } else { + $complex_id = $node_comp; + } + + $oid = $comp_node_pid_oid.".$slot"; + my $node_part = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + if ($node_part ne '255') { + return (1, "The slot [$slot] has been assigned to one partition."); + } + + $oid = $comp_node_state_oid.".$slot"; + my $node_state = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + if ($node_state != 1) { # 1 is power off + return (1, "The slot [$slot] is NOT in power off state."); + } + } + + # set the startslot + my $startslot = @sortslots[0]; + $session->set(new SNMP::Varbind([$comp_node_start_oid, $complex_id, $startslot, 'INTEGER'])); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + # set the slot number + my $slotnum = $#sortslots+1; + $session->set(new SNMP::Varbind([$comp_partnode_num_oid, $complex_id, $slotnum, 'INTEGER'])); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + # create the partition + $session->set(new SNMP::Varbind([$comp_action_oid, $complex_id, 3, 'INTEGER'])); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + # check to make sure the parition has been created + my $waiting = 60; #waiting time before creating parition take affect + while ($waiting > 0) { + sleep 1; + my $oid = $comp_node_pid_oid.".$slot"; + my $node_part = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + if ($node_part ne '255') { + my $slotlist = join(',', @slots); + return (0, "Creating flexed node succeeded with slots: $slotlist."); + } + $waiting--; + } + + return (1, "Failed to create the flexnode."); +} + +# remove a flexnode +sub rmflexnode { + my ($mpa, $node, $slot, @moreslot) = @_; + + my @slots = ($slot, @moreslot); + + # get the status of all the nodes + my $complex_id = ""; + my $part_id = ""; + foreach my $slot (@slots) { + #get the complex of the node + my $oid = $comp_node_cid_oid.".$slot"; + my $node_comp = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + if ($node_comp eq 'NOSUCHINSTANCE') { + return (1, "The slot [$slot] is NOT a member of one complex."); + } + + # all the nodes should be located in one complex + if ($complex_id ne "" && $node_comp ne $complex_id) { + return (1, "All the slots of this node should be located in one complex."); + } else { + $complex_id = $node_comp; + } + + # get the partition of the node + $oid = $comp_node_pid_oid.".$slot"; + my $node_part = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + if ($node_part eq '255') { + return (1, "The slot [$slot] was NOT assigned to a partition."); + } + + # all the nodes should belong to one parition + if ($part_id ne "" && $node_part ne $part_id) { + return (1, "All the slots of this flexnode should belong to one parition."); + } else { + $part_id = $node_part; + } + + $oid = $comp_node_state_oid.".$slot"; + my $node_state = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + if ($node_state != 1) { # 1 is power off + return (1, "The slot [$slot] is NOT in power off state."); + } + } + + my $output = $session->set(new SNMP::Varbind([$comp_part_action_oid.".$complex_id", $part_id, 1, 'INTEGER'])); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + + # check to make sure the parition has been deleted + my $waiting = 60; #waiting time before delete parition take affect + while ($waiting > 0) { + sleep 1; + my $oid = $comp_part_comp_id_oid.".$complex_id".".$part_id"; + my $part_comp = $session->get([$oid]); + if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); } + if ($part_comp eq 'NOSUCHINSTANCE') { + return (0, "The flexnode has been removed successfully."); + } + $waiting--; + } + return (1, "Failed to remove the flexnode."); +} + sub bladecmd { $mpa = shift; my $node = shift; @@ -2176,6 +2632,12 @@ sub bladecmd { return rscan(\@args); } elsif ($command eq "renergy") { return renergy($mpa, $node, $slot, @args); + } elsif ($command eq "lsflexnode") { + return lsflexnode($mpa, $node, $slot, @moreslots); + } elsif ($command eq "mkflexnode") { + return mkflexnode($mpa, $node, $slot, @moreslots); + } elsif ($command eq "rmflexnode") { + return rmflexnode($mpa, $node, $slot, @moreslots); } return (1,"$command not a supported command by blade method");