diff --git a/perl-xCAT/xCAT/FSPUtils.pm b/perl-xCAT/xCAT/FSPUtils.pm index 01630196e..eb1dda4b6 100644 --- a/perl-xCAT/xCAT/FSPUtils.pm +++ b/perl-xCAT/xCAT/FSPUtils.pm @@ -368,11 +368,19 @@ sub fsp_api_action { } elsif( $parameter !=0 && $action =~ /^(on|reset)$/ ) { #powerinterval for lpars power on $cmd = "$fsp_api -a $action -i $parameter -T $tooltype -t $type:$fsp_ip:$id:$node_name:"; + } elsif ($action =~ /^part_set_lpar_def_state$/) { + $cmd = "$fsp_api -a $action -T $tooltype -s $parameter -t $type:$fsp_ip:$id:$node_name:"; + } elsif (exists($request->{opt}->{vios})) { + $cmd = "$fsp_api -a $action -T $tooltype -s 1 -t $type:$fsp_ip:$id:$node_name:$parameter"; } else { $cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:$parameter"; } } else { - $cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:"; + if (exists($request->{opt}->{vios})) { + $cmd = "$fsp_api -a $action -T $tooltype -s 1 -t $type:$fsp_ip:$id:$node_name:"; + } else { + $cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:"; + } } } xCAT::MsgUtils->verbose_message($request, "fsp_api_action cmd:$cmd."); diff --git a/perl-xCAT/xCAT/FSPvm.pm b/perl-xCAT/xCAT/FSPvm.pm index 29f2ed0d0..321b7e1f7 100644 --- a/perl-xCAT/xCAT/FSPvm.pm +++ b/perl-xCAT/xCAT/FSPvm.pm @@ -361,7 +361,7 @@ sub mkvm_parse_args { # if ( !GetOptions( \%opt, qw(V|verbose ibautocfg ibacap=s i=s l=s c=s p=s full) )) { # return( usage() ); # } - if ( !GetOptions( \%opt, qw(V|verbose i=s m=s r=s ) )) { + if ( !GetOptions( \%opt, qw(V|verbose i=s m=s r=s full part vios) )) { return( usage() ); } #################################### @@ -408,13 +408,14 @@ sub mkvm_parse_args { } else { return(usage( "Invalid entry: $opt{m}.\n For Power 775, the pending memory interleaving mode only could be interleaved(or 1), or non-interleaved(or 2)." )); } - } else { + } elsif (!exists($opt{full}) && !exists($opt{part}) && !exists($opt{vios})){ $opt{m} = 2 ;# non-interleaved, which is the default } - my @ratio = (1, 2, 3, 4, 5); - my %octant_cfg = (); if ( exists( $opt{r} ) ) { + my @ratio = (1, 2, 3, 4, 5); + my %octant_cfg = (); + my @elems = split(/\,/,$opt{r}); my $range=""; while (my $elem = shift @elems) { @@ -461,12 +462,12 @@ sub mkvm_parse_args { } } # end of "if .. else.." } # end of while + $opt{octant_cfg}{octant_cfg_value} = (\%octant_cfg); + $opt{octant_cfg}{memory_interleave} = $opt{m}; } #end of if - $opt{octant_cfg}{octant_cfg_value} = (\%octant_cfg); - $opt{octant_cfg}{memory_interleave} = $opt{m}; - - if ( !exists( $opt{i} ) || !exists( $opt{r} ) ) { + + if ( (!exists( $opt{i} ) || !exists( $opt{r} )) && !exists($opt{full}) && !exists($opt{part}) && !exists($opt{vios})) { return(usage()); } @@ -483,6 +484,10 @@ sub mkvm_parse_args { if ( !$p) { return(usage("Not found the parent of $node")); } + if (exists($opt{full}) and defined($other_p) and $other_p eq $p){ + return(usage("Only one full partition can be created in one CEC")); + } + if(! defined( $other_p)) { $other_p = $p; } @@ -490,9 +495,10 @@ sub mkvm_parse_args { return(usage("For Power 775, please make sure the noderange are in one CEC ")); } } - $request->{node} = [$other_p]; - $request->{noderange} = $other_p; - + if (!exists($opt{full}) && !exists($opt{part}) &&!exists($opt{vios})) { + $request->{node} = [$other_p]; + $request->{noderange} = $other_p; + } #################################### # No operands - add command name #################################### @@ -535,10 +541,14 @@ sub rmvm_parse_args { $Getopt::Long::ignorecase = 0; Getopt::Long::Configure( "bundling" ); - if ( !GetOptions( \%opt, qw(V|verbose service r) )) { + if ( !GetOptions( \%opt, qw(V|verbose service r p|part) )) { return( usage() ); } - return(usage( "rmvm doesn't support for Power 775." )); + + if (!exists($opt{p})) { + return(usage( "rmvm doesn't support for Power 775." )); + } + #################################### # Check for "-" with no option #################################### @@ -592,7 +602,7 @@ sub lsvm_parse_args { $Getopt::Long::ignorecase = 0; Getopt::Long::Configure( "bundling" ); - if ( !GetOptions( \%opt, qw(V|verbose l|long) )) { + if ( !GetOptions( \%opt, qw(V|verbose l|long p|part) )) { return( usage() ); } #################################### @@ -1423,7 +1433,428 @@ sub xCATdB { } return undef; } +######################## +#***** partition related +######################## +#my @partition_query_actions = qw(part_get_partition_cap part_get_num_of_lpar_slots part_get_hyp_config_process_and_mem part_get_hyp_avail_process_and_mem part_get_service_authority_lpar_id part_get_shared_processing_resource part_get_all_vio_info lpar_lhea_mac part_get_all_io_bus_info part_get_lpar_processing part_get_lpar_memory get_huge_page get_cec_bsr); +my @partition_query_actions = qw(part_get_partition_cap part_get_hyp_process_and_mem part_get_all_io_bus_info get_huge_page get_cec_bsr); + +sub parse_part_get_info { + my $hash = shift; + my $data = shift; + my @array = split /\n/, $data; + foreach my $line (@array) { + chomp($line); + if ($line =~ /Num of lpar slots: (\d+)/i) { + $hash->{num_of_lpars} = $1; + } elsif ($line =~ /HYP Configurable Memory[^\(]*\((\d+)\s*regions\)/i) { + $hash->{hyp_config_mem} = $1; + } elsif ($line =~ /HYP Available Memory[^\(]*\((\d+)\s*regions\)/i) { + $hash->{hyp_avail_mem} = $1; + } elsif ($line =~ /HYP Memory Region Size[^\(]*\((\d+)\s*MB\)/i) { + $hash->{mem_region_size} = $1; + } elsif ($line =~ /HYP Configurable Processors: (\d+),\s*Avail Processors: (\d+)/i) { + $hash->{process_units_config} = $1; + $hash->{process_units_avail} = $2; + } elsif ($line =~ /Authority Lpar id:(\w+)/i) { + $hash->{service_lparid} = $1; + } elsif ($line =~ /(\d+),(\d+),[^,]*,(\w+),[^,]*,[^,]*,\w*\(([\w| |-|_]*)\)/) { + $hash->{bus}->{$3}->{cur_lparid} = $1; + $hash->{bus}->{$3}->{bus_slot} = $2; + $hash->{bus}->{$3}->{des} = $4; + } elsif ($line =~ /Phy drc_index:(\w+), Port group: (\w+), Phy port id: (\w+)/) { + $hash->{phy_drc_group_port}->{$1}->{$2}->{$3} = '1'; + } elsif ($line =~ /adapter_id=(\w+),lpar_id=([\d|-]+).*port_group=(\d+),phys_port_id=(\d+).*drc_index=(\w+),.*/) { + if (($2 == -1) && ($4 == 255)) { + $hash->{logic_drc_phydrc}->{$3}->{$5} = $1; + #$hash->{logic_drc_phydrc}->{$5}->{$1} = [$2,$3,$4]; + } + #} elsif ($line =~ /lpar 0:: Curr Memory::min: 1,cur: (\d+),max:/i) { + } elsif ($line =~ /Curr Memory Req[^\(]*\((\d+)\s*regions\)/i) { + $hash->{lpar0_used_mem} = $1; + #print "===>lpar0_used_mem:$hash->{lpar0_used_mem}.\n"; + } elsif ($line =~ /Available huge page memory\(in pages\):\s*(\d+)/) { + $hash->{huge_page_avail} = $1; + } elsif ($line =~ /Available BSR array:\s*(\d+)/) { + $hash->{cec_bsr_avail} = $1; + } + } +} + +sub query_cec_info_actions { + my $request = shift; + my $name = shift; + my $td = shift; + my $usage = shift; + my $action_array = shift; + my $lparid = @$td[0]; + my $data; + my @array = (); + my %hash = (); + if (!defined($action_array) or ref($action_array) ne "ARRAY") { + $action_array = \@partition_query_actions; + } + + foreach my $action (@$action_array) { + #$data .= "======> ret info for $action:\n"; + my $values = xCAT::FSPUtils::fsp_api_action($request, $name, $td, $action); + chomp(@$values[1]); + if ($action eq "part_get_partition_cap" and (@$values[1] =~ /Error:/i or @$values[2] ne 0)) { + return ([[@$values]]); + } + if (@$values[1] =~ /^$/) { + next; + } + if ($usage eq 0) { + if ($lparid) { + if ($action eq "lpar_lhea_mac") { + my @output = split /\n/,@$values[1]; + foreach my $line (@output) { + if ($line =~ /adapter_id=\w+,lpar_id=$lparid,type=hea/) { + #$data .= "$line\n"; + push @array, [$name, $line, 0]; + } + } + #$data .= "\n"; + next; + } + if ($action eq "part_get_all_io_bus_info") { + my @output = split /\n/, @$values[1]; + foreach my $line (@output) { + if ($line =~ /$lparid,/) { + #$data .= "$line\n"; + push @array, [$name, $line, 0]; + } + } + #$data .= "\n"; + next; + } + } + #$data .= "@$values[1]\n\n"; + push @array, [$name, @$values[1], @$values[2]]; + } else { + &parse_part_get_info(\%hash, @$values[1]); + } + } + if ($usage eq 0) { + #return $data; + return \@array; + } else { + return \%hash; + } +} + +#my @partition_query_actions = qw(part_get_partition_cap part_get_num_of_lpar_slots part_get_hyp_config_process_and_mem part_get_hyp_avail_process_and_mem part_get_service_authority_lpar_id part_get_shared_processing_resource part_get_all_vio_info lpar_lhea_mac part_get_all_io_bus_info part_get_lpar_processing part_get_lpar_memory get_huge_page get_cec_bsr); +sub query_cec_info { + my $request = shift; + my $hash = shift; + my $args = $request->{opt}; + my @td = (); + my @result = (); + while (my ($mtms,$h) = each(%$hash) ) { + while (my ($name, $d) = each (%$h)) { + @td = @$d; + if (@$d[0] == 0 && @$d[4] ne "lpar") { + last; + } + #my $rethash = query_cec_info_actions($request, $name, $d, 0, ["part_get_lpar_processing","part_get_lpar_memory","part_get_all_vio_info","lpar_lhea_mac","part_get_all_io_bus_info","get_huge_page","get_cec_bsr"]); + my $rethash = query_cec_info_actions($request, $name, $d, 0, ["part_get_lpar_processing","part_get_lpar_memory","part_get_all_io_bus_info","get_huge_page","get_cec_bsr"]); + #push @result, [$name, $rethash, 0]; + push @result, @$rethash; + } + if (@td[0] == 0) { + my $rethash = query_cec_info_actions($request, @td[3],\@td, 0); + #push @result, [@td[3], $rethash, 0]; + push @result, @$rethash; + } + } + return \@result; +} + +######################## +#***** partition related +######################## + +my @partition_config_actions = qw/part_set_lpar_def_state part_set_lpar_pending_proc part_set_lpar_pending_mem part_set_pending_max_vslots part_set_lpar_shared_pool_util_auth part_set_lpar_group_id part_set_lpar_avail_priority part_set_partition_placement part_set_lhea_assign_info part_set_phea_port_info part_set_lhea_port_info part_set_veth_slot_config part_set_vscsi_slot_config part_set_vfchan_slot_config part_clear_vslot_config set_huge_page set_lpar_name/; + +sub set_lpar_undefined { + my $request = shift; + my $name = shift; + my $attr = shift; + my $values = xCAT::FSPUtils::fsp_api_action($request, $name, $attr, "part_set_lpar_def_state", 0, 0x0); + if (!@$values[2]) { + return ([$name,"Done",0]); + } + return $values; +} + +sub clear_service_authority_lpar { + my $request = shift; + my $name = shift; + my $attr = shift; + my $values = xCAT::FSPUtils::fsp_api_action($request, $name, $attr, "part_get_service_authority_lpar_id"); + my @array = split /\n/, @$values[1]; + my $service_lparid = undef; + foreach my $line (@array) { + if ($line =~ /Authority Lpar id:([-|\d]+)./i) { + $service_lparid = $1; + } + } + if (defined($service_lparid) and $service_lparid == @$attr[0]) { + xCAT::FSPUtils::fsp_api_action($request, $name, $attr, "part_set_service_authority_lpar_id"); + } +} + +sub remove { + my $request = shift; + my $hash = shift; + my @result = (); + while (my ($mtms, $h) = each (%$hash)) { + while (my ($name, $d) = each (%$h)) { + &clear_service_authority_lpar($request, $name, $d); + my $values = &set_lpar_undefined($request, $name, $d); + push @result, $values; + } + } + return \@result; +} + +sub deal_with_avail_mem { + my $request = shift; + my $name = shift; + my $d = shift; + my $lparhash = shift; + my ($before,$after,$res); + my @td = @$d; + @td[0] = 0; + my $values = xCAT::FSPUtils::fsp_api_action($request, $name, \@td, "part_get_lpar_memory"); + my %tmphash; + &parse_part_get_info(\%tmphash, @$values[1]); + if (exists($tmphash{lpar0_used_mem})) { + $before = $tmphash{lpar0_used_mem}; + } else { + return ([$name, "part_get_lpar_memory failed to get used memory for hypervisor.", 1]); + } + my $tmp_param = "1/1/".$lparhash->{hyp_config_mem}; + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_pending_mem", 0, $tmp_param); + if (@$values[2]) { + return $values; + } + $values = xCAT::FSPUtils::fsp_api_action($request, $name, \@td, "part_get_lpar_memory"); + &parse_part_get_info(\%tmphash, @$values[1]); + if (exists($tmphash{lpar0_used_mem})) { + $after = $tmphash{lpar0_used_mem}; + $res = $after - $before; + if ($res < 0) { + return([$name, "Parse reserverd regions failed, before $before, after $after.", 1]); + } elsif ($lparhash->{hyp_avail_mem} - $res < 0) { + return([$name, "Parse reserverd regions failed, no enough memory, availe:$lparhash->{hyp_avail_mem}.", -1]); + } + my $mem = $lparhash->{memory}; + $mem =~ /(\d+)\/(\d+)\/(\d+)/; + if ($2 > $lparhash->{hyp_avail_mem} - $res) { + my $new_avail_mem = $lparhash->{hyp_avail_mem} - $res; + $lparhash->{memory} = "$1/$new_avail_mem/$3"; + } + return 0; + } else { + return ([$name, "part_get_lpar_memory failed to get used memory for hypervisor.", 1]); + } +} + +sub create_lpar { + my $request = shift; + my $name = shift; + my $d = shift; + my $lparhash = shift; + my $values; + if (exists($request->{opt}->{vios})) { + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x03); + } else { + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x01); + } + if (@$values[2] ne 0) { + return ([[$name, @$values[1], @$values[0]]]); + } + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_lpar_name", 0, $name); + if (@$values[2] ne 0) { + $values = &set_lpar_undefined($request, $name, $d); + return ([$name, @$values[1], @$values[0]]); + } + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_shared_pool_util_auth"); + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_group_id"); + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_avail_priority"); + $values = &deal_with_avail_mem($request, $name, $d,$lparhash); + if (ref($values) eq "ARRAY") { + return ([@$values]); + } + #print "======>physlots:$lparhash->{physlots}.\n"; + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_io_slot_owner_uber", 0, $lparhash->{physlots}); + #$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_io_slot_owner", 0, join(",",@phy_io_array)); + if (@$values[2] ne 0) { + $values = &set_lpar_undefined($request, $name, $d); + return ([$name, @$values[1], @$values[2]]); + } + if (exists($lparhash->{phy_hea})) { + my $phy_hash = $lparhash->{phy_hea}; + foreach my $phy_drc (keys %$phy_hash) { + #print "======> set_lhea_assign_info: drc_index:$phy_drc.\n"; + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lhea_assign_info", 0, $phy_drc); + my $group_hash = $phy_hash->{$phy_drc}; + foreach my $group_id (keys %$group_hash) { + my @lhea_drc = (keys %{$lparhash->{logic_drc_phydrc}->{$group_id}}); + foreach my $phy_port_id (keys %{$group_hash->{$group_id}}) { + my $tmp_param = "$phy_drc,$group_id,$phy_port_id"; + #print "======> set_phea_port_info: $tmp_param.\n"; + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_phea_port_info", 0, $tmp_param); + my $tmp_lhea_param = $lhea_drc[$phy_port_id].",$phy_port_id"; + #print "======> set_lhea_port_info: $tmp_lhea_param.\n"; + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lhea_port_info", 0, $tmp_lhea_param); + } + delete ($lparhash->{logic_drc_phydrc}->{$group_id}->{$lhea_drc[0]}); + delete ($lparhash->{logic_drc_phydrc}->{$group_id}->{$lhea_drc[1]}); + } + } + } + + #print "======>cpus:$lparhash->{cpus}.\n"; + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_pending_proc", 0, $lparhash->{cpus}); + if (@$values[2] ne 0) { + $values = &set_lpar_undefined($request, $name, $d); + return ([$name, @$values[1], @$values[2]]); + } + #print "======>memory:$lparhash->{memory}.\n"; + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_pending_mem", 0, $lparhash->{memory}); + if (@$values[2] ne 0) { + $values = &set_lpar_undefined($request, $name, $d); + return ([$name, @$values[1], @$values[2]]); + } + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_comp_modes"); + #print "======>memory:$lparhash->{huge_page}.\n"; + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_huge_page", 0, $lparhash->{huge_page}); + #print "======>bsr:$lparhash->{bsr_num}.\n"; + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_lpar_bsr", 0, $lparhash->{bsr_num}); + xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_partition_placement"); + if (exists($request->{opt}->{vios})) { + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x04); + } else { + $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x02); + } + if (@$values[2] ne 0) { + return ([$name, @$values[1], @$values[2]]); + } + return ([$name, "Done", 0]); +} + +sub mkspeclpar { + my $request = shift; + my $hash = shift; + my $values; + my @result = (); + my $vmtab = xCAT::Table->new( 'vm'); + unless($vmtab) { + return([["Error","Cannot open vm table", 1]]); + } + while (my ($mtms, $h) = each (%$hash)) { + my $memhash; + my @nodes = keys(%$h); + my $ent = $vmtab->getNodesAttribs(\@nodes, ['cpus', 'memory','physlots', 'othersettings']); + while (my ($name, $d) = each (%$h)) { + if (!exists($memhash->{run})) { + my @td = @$d; + @td[0] = 0; + $memhash = &query_cec_info_actions($request, $name, \@td, 1, ["part_get_hyp_process_and_mem","lpar_lhea_mac"]); + $memhash->{run} = 1; + } + my $tmp_ent = $ent->{$name}->[0]; + if (!defined($tmp_ent) ) { + return ([[$name, "Not find params", 1]]); + } elsif (!exists($tmp_ent->{cpus}) || !exists($tmp_ent->{memory}) || !exists($tmp_ent->{physlots})) { + return ([[$name, "The attribute 'vmcpus', 'vmmemory' and 'vmphyslots' are all needed to be specified.", 1]]); + } + if ($tmp_ent->{memory} =~ /(\d+)(G|M)\/(\d+)(G|M)\/(\d+)(G|M)/i) { + my $memsize = $memhash->{mem_region_size}; + my $min = $1; + if ($2 == "G") { + $min = $min * 1024; + } + $min = $min/$memsize; + my $cur = $3; + if ($4 == "G") { + $cur = $cur * 1024; + } + $cur = $cur/$memsize; + my $max = $5; + if ($6 == "G") { + $max = $max * 1024; + } + $max = $max/$memsize; + $tmp_ent->{memory} = "$min/$cur/$max"; + } + $tmp_ent->{hyp_config_mem} = $memhash->{hyp_config_mem}; + $tmp_ent->{hyp_avail_mem} = $memhash->{hyp_avail_mem}; + $tmp_ent->{huge_page} = "0/0/0"; + $tmp_ent->{bsr_num} = "0"; + if (exists($tmp_ent->{othersettings})) { + my $setting = $tmp_ent->{othersettings}; + if ($setting =~ /hugepage:(\d+)/) { + my $tmp = $1; + $tmp_ent->{huge_page} = "1/".$tmp."/".$tmp; + } + if ($setting =~ /bsr:(\d+)/) { + $tmp_ent->{bsr_num} = $1; + } + } + $tmp_ent->{phy_hea} = $memhash->{phy_drc_group_port}; + $tmp_ent->{logic_drc_phydrc} = $memhash->{logic_drc_phydrc}; + $values = &create_lpar($request, $name, $d, $tmp_ent); + push @result, $values; + $name = undef; + $d = undef; + } + } + return \@result; +} + +sub mkfulllpar { + my $request = shift; + my $hash = shift; + my $values; + my @result = (); + while (my ($mtms, $h) = each (%$hash)) { + my $rethash; + while (my ($name, $d) = each (%$h)) { + if (!exists($rethash->{run})) { + my @td = @$d; + @td[0] = 0; + $rethash = query_cec_info_actions($request, $name, \@td, 1); + if (ref($rethash) ne 'HASH') { + return ([[$mtms, "Cann't get hypervisor info hash", 1]]); + } + $rethash->{run} = 1; + #print Dumper($rethash); + } + my %lpar_param = (); + $lpar_param{cpus} = "1/".$rethash->{process_units_avail}."/".$rethash->{process_units_config}; + $lpar_param{memory} = "1/".$rethash->{hyp_avail_mem}."/".$rethash->{hyp_config_mem}; + $lpar_param{hyp_config_mem} = $rethash->{hyp_config_mem}; + $lpar_param{hyp_avail_mem} = $rethash->{hyp_avail_mem}; + my @phy_io_array = keys(%{$rethash->{bus}}); + $lpar_param{physlots} = join(",", @phy_io_array); + $lpar_param{huge_page} = "1/".$rethash->{huge_page_avail}."/".$rethash->{huge_page_avail}; + $lpar_param{bsr_num} = $rethash->{cec_bsr_avail}; + $lpar_param{phy_hea} = $rethash->{phy_drc_group_port}; + $lpar_param{logic_drc_phydrc} = $rethash->{logic_drc_phydrc}; + $values = &create_lpar($request, $name, $d, \%lpar_param); + $rethash->{logic_drc_phydrc} = $lpar_param{logic_drc_phydrc}; + push @result, $values; + $name = undef; + $d = undef; + } + } + return \@result; +} ########################################################################## # Creates logical partitions @@ -1437,6 +1868,10 @@ sub mkvm { # create a full system partition for each CECs managed by the HMC. if ( exists($opt->{full})) { return( mkfulllpar(@_) ); + } elsif (exists($opt->{part})){ + return (mkspeclpar(@_)); + } elsif (exists($opt->{vios})) { + return (mkspeclpar(@_)); } else { # if no, it will execute the original function. @@ -1455,15 +1890,29 @@ sub chvm { ########################################################################## # No rmvm for Power 775 ########################################################################## -#sub rmvm { +sub rmvm { + my $request = $_[0]; + my $opt = $request->{opt}; + if (exists($opt->{p})) { + return( remove(@_) ); + } else { + return ([["lpar","rmvm only support Power Partitioning.", 1]]); + } # return( remove(@_) ); -#} +} ########################################################################## # Lists logical partition profile ########################################################################## sub lsvm { - return( list(@_) ); + my $request = shift; + my $hash = shift; + my $args = $request->{opt}; + if (exists($args->{p})) { + return (query_cec_info($request, $hash)); + } else { + return( list($request, $hash) ); + } } 1; diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 5c7f82422..2048fa3ce 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -228,6 +228,7 @@ vm => { 'datacenter' => "Optionally specify a datacenter for the VM to exist in (only applicable to VMWare)", 'cluster' => 'Specify to the underlying virtualization infrastructure a cluster membership for the hypervisor.', 'vidproto' => "Request a specific protocol for remote video access be set up. For example, spice in KVM.", + 'physlots' => "Specify the physical slots drc index that will assigned to the partition, the delimiter is ',', and the drc index must started with '0x'.", 'vidmodel' => "Model of video adapter to provide to guest. For example, qxl in KVM", 'vidpassword' => "Password to use instead of temporary random tokens for VNC and SPICE access", 'storagecache' => "Select caching scheme to employ. E.g. KVM understands 'none', 'writethrough' and 'writeback'", @@ -2235,6 +2236,14 @@ my @nodeattrs = ( tabentry => 'vm.storage', access_tabentry => 'vm.node=attr:node', }, + {attr_name => 'vmphyslots', + tabentry => 'vm.physlots', + access_tabentry => 'vm.node=attr:node', + }, + {attr_name => 'vmothersetting', + tabentry => 'vm.othersettings', + access_tabentry => 'vm.node=attr:node', + }, {attr_name => 'vmstoragemodel', tabentry => 'vm.storagemodel', access_tabentry => 'vm.node=attr:node', diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index 62ce7f9fe..2c63c3726 100644 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -199,10 +199,12 @@ my %usage = ( "Usage: Common: mkvm [-h|--help|-v|--version] - For PPC(with HMC): + For PPC(with HMC) specific: mkvm noderange -i id -l singlenode [-V|--verbose] mkvm noderange -c destcec -p profile [-V|--verbose] mkvm noderange --full [-V|--verbose] + PPC (using Direct FSP Management) specific: + mkvm noderange <--full|--part> For KVM mkvm noderange -m|--master mastername -s|--size disksize -f|--force For zVM @@ -216,7 +218,7 @@ my %usage = ( PPC (with HMC) specific: lsvm [-a|--all] PPC (using Direct FSP Management) specific: - lsvm [-l|--long] + lsvm [-l|--long] [-p|--part] zVM specific: lsvm noderange lsvm noderange --getnetworknames @@ -264,7 +266,9 @@ my %usage = ( "rmvm" => "Usage: rmvm [--service][-V|--verbose] rmvm [-h|--help|-v|--version], - rmvm [-p] [-f]", + rmvm [-p] [-f] + PPC (using Direct FSP Management) specific: + rmvm [-p|--part]", "lsslp" => "Usage: lsslp [-h|--help|-v|--version] lsslp [][-V|--verbose][-i ip[,ip..]][-w][-r|-x|-z][-n][-I][-s FRAME|CEC|MM|IVM|RSA|HMC|CMM|IMM2|FSP] diff --git a/xCAT-client/pods/man1/lsvm.1.pod b/xCAT-client/pods/man1/lsvm.1.pod index 8b10080a8..24cb47d81 100644 --- a/xCAT-client/pods/man1/lsvm.1.pod +++ b/xCAT-client/pods/man1/lsvm.1.pod @@ -16,6 +16,8 @@ B [B<-a>| B<--all>] I B [B<-l>| B<--long>] I +B [B<-p>| B<--part>] I + =head2 For zVM: B I @@ -73,6 +75,9 @@ B<-l> Show lparnames for lpars. +B<-p|--part> + +Show detailed information for lpars, such as processor, memory, physical IO slot, hugepage, BSR, etc. =head1 RETURN VALUE @@ -190,7 +195,6 @@ Output is similar to: Page Size(in GB): 16 Maximum huge page memory(in pages): 24 Requested huge page memory(in pages): 15 -======= Number of BSR arrays: 256,Bytes per BSR array: 4096,Available BSR array: 0; Available huge page memory(in pages): 0 Configurable huge page memory(in pages): 12 @@ -208,6 +212,59 @@ Output is similar to: gpok3: INCLUDE LNXDFLT gpok3: COMMAND SET VSWITCH VSW2 GRANT LNX3 +6. For normal power machine, list out the detailed resource information: + + lsvm cec -p + +Output is similar to: + + cec: HYP Configurable Processors: 16, Avail Processors: 16. + HYP Configurable Memory:32.00 GB(128 regions). + HYP Available Memory: 31.25 GB(125 regions). + HYP Memory Region Size: 0.25 GB(256 MB). + cec: All Physical I/O info: + 65535,519,U78AA.001.WZSGVU7-P1-C7,0x21010207,0,0,0xffff(Empty Slot) + 65535,518,U78AA.001.WZSGVU7-P1-C6,0x21010206,0,0,0xffff(Empty Slot) + 65535,517,U78AA.001.WZSGVU7-P1-C5,0x21010205,0,0,0xffff(Empty Slot) + 65535,516,U78AA.001.WZSGVU7-P1-C4,0x21010204,0,0,0xffff(Empty Slot) + 65535,514,U78AA.001.WZSGVU7-P1-C19,0x21010202,0,0,0xffff(Empty Slot) + 65535,513,U78AA.001.WZSGVU7-P1-T7,0x21010201,0,0,0xc03(USB Controller) + 65535,512,U78AA.001.WZSGVU7-P1-T9,0x21010200,0,0,0x104(RAID Controller) + cec: Huge Page Memory + Available huge page memory(in pages): 2 + Configurable huge page memory(in pages): 2 + Page Size(in GB): 16 + Maximum huge page memory(in pages): 4 + Requested huge page memory(in pages): 2 + cec: Barrier Synchronization Register(BSR) + Number of BSR arrays: 256 + Bytes per BSR array: 4096 + Available BSR array: 256 + +For partition on normal power machine, list out the detailed information: + + lsvm lpar1 -p + +Output is similar to: + + lpar1: Lpar Processor Info: + Curr Processor Min: 1. + Curr Processor Req: 16. + Curr Processor Max: 16. + lpar1: Lpar Memory Info: + Curr Memory Min: 0.25 GB(1 regions). + Curr Memory Req: 30.75 GB(123 regions). + Curr Memory Max: 32.00 GB(128 regions). + lpar1: 1,519,U78AA.001.WZSGVU7-P1-C7,0x21010207,0,0,0xffff(Empty Slot) + lpar1: 1,518,U78AA.001.WZSGVU7-P1-C6,0x21010206,0,0,0xffff(Empty Slot) + lpar1: 1,517,U78AA.001.WZSGVU7-P1-C5,0x21010205,0,0,0xffff(Empty Slot) + lpar1: 1,516,U78AA.001.WZSGVU7-P1-C4,0x21010204,0,0,0xffff(Empty Slot) + lpar1: 1,514,U78AA.001.WZSGVU7-P1-C19,0x21010202,0,0,0xffff(Empty Slot) + lpar1: 1,513,U78AA.001.WZSGVU7-P1-T7,0x21010201,0,0,0xc03(USB Controller) + lpar1: 1,512,U78AA.001.WZSGVU7-P1-T9,0x21010200,0,0,0x104(RAID Controller) + lpar1: 1/2/2 + lpar1: 256. + =head1 FILES /opt/xcat/bin/lsvm diff --git a/xCAT-client/pods/man1/mkvm.1.pod b/xCAT-client/pods/man1/mkvm.1.pod index 4b1d971cd..3cfe44cd0 100644 --- a/xCAT-client/pods/man1/mkvm.1.pod +++ b/xCAT-client/pods/man1/mkvm.1.pod @@ -10,7 +10,7 @@ B [B<-h>| B<--help>] B [B<-v>| B<--version>] -=head2 For PPC (with HMC): +=head2 For PPC (with HMC) specific: B [B<-V>| B<--verbose>] I B<-i> I B<-l> I @@ -18,6 +18,11 @@ B [B<-V>| B<--verbose>] I B<-c> I B<-p> I B [B<-V>| B<--verbose>] I B<--full> + +=head2 For PPC (using Direct FSP Management) specific: + +B [I B<--full> B<--part>] + =head2 For KVM: B I [B<-m|--master> I] [B<-s|--size> I] [B<--mem> I] [B<--cpus> I] [B<-f|--force>] @@ -34,9 +39,7 @@ B I [I] [B I] =head1 DESCRIPTION -=head2 For PPC: - -For PPC (with HMC) specific: +=head2 For PPC (with HMC) specific: The first form of mkvm command creates new partition(s) with the same profile/resources as the partition specified by I. The -i and I specify the starting numeric partition number and the I for the newly created partitions, respectively. The LHEA port numbers and the HCA index numbers will be automatically increased if they are defined in the source partition. @@ -46,6 +49,12 @@ Please make sure the nodes in the I is defined in the I tab Please note that the mkvm command currently only supports creating standard LPARs, not virtual LPARs working with VIOS server. +=head2 For PPC (using Direct FSP Management) specific: + +With option I, a partition using all the resources on a normal power machine will be created. + +With option I, a partition using the parameters specified with attributes such as 'vmcpus', 'vmmory', 'vmphyslots', 'vmothersetting' will be created. + =head2 For KVM and Vmware: The mkvm command creates new virtual machine(s) with the I size of hard disk, I size of memory and I number of cpu. @@ -78,6 +87,10 @@ The cpu count which will be created for the kvm/vmware virtual machine. Request to create a new full system partition for each CEC. +=item B<--part> + +Request to create a partition with the specified parameters. + =item B<-f|--force> If B<-f|--force> is specified, the storage will be destroyed first if it existed. @@ -221,6 +234,42 @@ Output is similar to: mkvm vm1 -s 10G --mem 2048 --cpus 2 +8. To create a full partition on normal power machine. + +First, define a node object: + + mkdef -t node -o lpar1 mgt=fsp cons=fsp nodetype=ppc,osi id=1 hcp=cec parent=cec hwtype=lpar groups=lpar,all + +Then, create the partion on the specified cec. + + mkvm lpar1 --full + +The output is similar to: + + lpar1: Done + +To query the resources allocated to node 'lpar1', please reference L. + +Note: The 'parent' attribute for node 'lpar1' is the object name of physical power machine that the full partition will be created on. + +9. To create a partition using some of the resources on normal power machine. + +After a node object is defined, the resources that will be used for the partition shall be specified like this: + + chdef lpar1 vmcpus=1/4/16 vmmemory=1G/4G/32G vmphyslots=0x21010201,0x21010200 vmothersetting=bsr:128,hugepage:2 + +Then, create the partion on the specified cec. + + mkvm lpar1 --part + +The outout is similar to: + + lpar1: Done + +To query the resources allocated to node 'lpar1', please reference L. + +Note: The 'vmplyslots' specify the drc index of the physical slot device. Every drc index shall be delimited with ','. The 'vmothersetting' specify two kinds of resource, bsr(Barrier Synchronization Register) specified the num of BSR arrays, hugepage(Huge Page Memory) specified the num of pages. + =head1 FILES /opt/xcat/bin/mkvm diff --git a/xCAT-client/pods/man1/rmvm.1.pod b/xCAT-client/pods/man1/rmvm.1.pod index 4b4ede25e..400306db0 100644 --- a/xCAT-client/pods/man1/rmvm.1.pod +++ b/xCAT-client/pods/man1/rmvm.1.pod @@ -15,6 +15,10 @@ I I +=head2 PPC (using Direct FSP Management) specific: + +I I<-p|--part> + =head1 DESCRIPTION The rmvm command removes the partitions specified in noderange. If noderange is an CEC, all the partitions associated with that CEC will be removed. Note that removed partitions are automatically removed from the xCAT database. For IVM-managed systems, care must be taken to not remove the VIOS partition, or all the associated partitions will be removed as well. @@ -34,6 +38,8 @@ B<--service> Remove the service partitions of the specified CECs. B<-p> Purge the existence of the VM from persistant storage. This will erase all storage related to the VM in addition to removing it from the active virtualization configuration. +B<-p|--part> Remove the specified partiton on normal power machine. + B<-f> Force remove the VM, even if the VM appears to be online. This will bring down a live VM if requested. =head1 RETURN VALUE @@ -87,6 +93,15 @@ Output is similar to: gpok4: Deleting virtual server LNX4... Done + +6. To remove a partition on normal power machine. + +I + +Output is similar to: + + lpar1: Done + =head1 FILES /opt/xcat/bin/rmvm diff --git a/xCAT-server/lib/perl/xCAT/PPC.pm b/xCAT-server/lib/perl/xCAT/PPC.pm index 2285601e7..e692f286a 100644 --- a/xCAT-server/lib/perl/xCAT/PPC.pm +++ b/xCAT-server/lib/perl/xCAT/PPC.pm @@ -57,6 +57,7 @@ my %modules = ( cec => "xCAT::FSPvm", }, rmvm => { hmc => "xCAT::PPCvm", + hmc => "xCAT::FSPvm", }, lsvm => { hmc => "xCAT::PPCvm", fsp => "xCAT::FSPvm", diff --git a/xCAT-server/lib/xcat/plugins/fsp.pm b/xCAT-server/lib/xcat/plugins/fsp.pm index 7a1f3950f..6d29d8c77 100644 --- a/xCAT-server/lib/xcat/plugins/fsp.pm +++ b/xCAT-server/lib/xcat/plugins/fsp.pm @@ -28,6 +28,7 @@ sub handled_commands { mkvm => 'nodehm:mgt', lsvm => 'nodehm:mgt', chvm => 'nodehm:mgt', + rmvm => 'nodehm:mgt', rscan => 'nodehm:mgt', getfspcon => 'nodehm:cons', getmulcon => 'fsp', diff --git a/xCAT-server/share/xcat/install/rh/storage.rhels6.pkglist b/xCAT-server/share/xcat/install/rh/storage.rhels6.pkglist new file mode 100644 index 000000000..53e36645e --- /dev/null +++ b/xCAT-server/share/xcat/install/rh/storage.rhels6.pkglist @@ -0,0 +1,38 @@ +#Please make sure there is a space between @ and group name +autofs +ksh +tcsh +ntp +tftp +xinetd +rsh +rsh-server +psacct +nfs-utils +net-snmp +rsync +yp-tools +ypserv +ypbind +m4 +sendmail-cf +gdb +binutils +openssh-server +util-linux +compat-libstdc++-33 +-kernel-xen +-kmod-cmirror-xen +-xen-devel +-kmod-gnbd-xen +-xen +-libvirt-devel +-libvirt-cim +-gnome-applet-vm +-kmod-gfs-xen +-xen-libs +-libvirt +-virt-viewer +-libvirt-python +-python-virtinst +-virt-manager diff --git a/xCAT/postscripts/configeth b/xCAT/postscripts/configeth index 22d633c5d..ab82f6b20 100755 --- a/xCAT/postscripts/configeth +++ b/xCAT/postscripts/configeth @@ -15,7 +15,7 @@ function v4mask2prefix(){ case $num_dec in 255) let num_bits+=8;; 254) let num_bits+=7;; - 253) let num_bits+=6;; + 252) let num_bits+=6;; 248) let num_bits+=5;; 240) let num_bits+=4;; 224) let num_bits+=3;; @@ -28,6 +28,72 @@ function v4mask2prefix(){ echo "$num_bits" } +function v4prefix2mask(){ + local a=$1 + local b=0 + local num_index=1 + local str_temp='' + local str_mask='' + + while [[ $num_index -le 4 ]] + do + if [ $a -ge 8 ];then + b=8 + a=$((a-8)) + else + b=$a + a=0 + fi + case $b in + 0) str_temp="0";; + 1) str_temp="128";; + 2) str_temp="192";; + 3) str_temp="224";; + 4) str_temp="240";; + 5) str_temp="248";; + 6) str_temp="252";; + 7) str_temp="254";; + 8) str_temp="255";; + esac + + str_mask=$str_mask$str_temp"." + + num_index=$((num_index+1)) + done + + str_mask=`echo $str_mask | sed 's/.$//'` + echo "$str_mask" +} + +function v4calcbcase(){ + local str_mask=$2 + echo $str_mask | grep '\.' + if [ $? -ne 0 ];then + str_mask=$(v4prefix2mask $str_mask) + fi + local str_bcast='' + local str_temp='' + local str_ifs=$IFS + IFS=$'.' + local array_ip=($1) + local array_mask=($str_mask) + IFS=$str_ifs + + if [ ${#array_ip[*]} -ne 4 -o ${#array_mask[*]} -ne 4 ];then + echo "255.255.255.255" + return + fi + + for index in {0..3} + do + str_temp=`echo $[ ${array_ip[$index]}|(${array_mask[$index]} ^ 255) ]` + str_bcast=$str_bcast$str_temp"." + done + + str_bcast=`echo $str_bcast | sed 's/.$//'` + echo "$str_bcast" +} + function configipv4(){ str_if_name=$1 str_v4ip=$2 @@ -230,8 +296,9 @@ function add_ip_temporary(){ str_label=$str_nic_name fi + str_bcase=$(calcbcase $str_ip $str_mask) #the label is ready, add the ip address directly - ip addr add $str_ip/${str_mask} dev $str_nic_name scope global label $str_label + ip addr add $str_ip/${str_mask} broadcast $str_bcase dev $str_nic_name scope global label $str_label fi fi } @@ -392,7 +459,7 @@ while [ $num_index -lt ${#array_nic_ips[*]} ];do #fetch the subnet and netmask in networks definition str_subnet=`echo $str_line | awk -F'net=' '{print $2}' | awk -F'|' '{print $1}'` - str_netmask=`echo $str_line | awk -F'mask=' '{print $2}' | awk -F'|' '{print $1}'` + str_netmask=`echo $str_line | awk -F'mask=' '{print $2}' | awk -F'|' '{print $1}' | sed 's:^/::'` str_gateway=`echo $str_line | awk -F'gateway=' '{print $2}' | awk -F'|' '{print $1}'` if [ ! $str_subnet -o ! $str_netmask ];then @@ -405,7 +472,8 @@ while [ $num_index -lt ${#array_nic_ips[*]} ];do array_nic_subnet[$num_index]=$str_subnet array_nic_netmask[$num_index]=$str_netmask array_nic_gateway[$num_index]=$str_gateway - if [ -n "$str_gateway" ];then + echo "$str_gateway" | grep ':' + if [ $? -eq 0 ];then str_ipv6_gateway=$str_gateway fi logger -t xcat -p local4.err "configeth: $str_ip, $str_subnet, $str_netmask, $str_gateway"