diff --git a/perl-xCAT-2.0/xCAT/PPCvm.pm b/perl-xCAT-2.0/xCAT/PPCvm.pm index ecd8f8323..54fa75f06 100644 --- a/perl-xCAT-2.0/xCAT/PPCvm.pm +++ b/perl-xCAT-2.0/xCAT/PPCvm.pm @@ -133,9 +133,9 @@ sub mkvm_parse_args { "mkvm -h|--help", "mkvm -v|--version", "mkvm [-V|--verbose] singlenode -i id -n name", - "mkvm [-V|--verbose] singlecec -c cec", + "mkvm [-V|--verbose] srccec -c destcec", " -h writes usage information to standard output", - " -c target cec", + " -c copy lpars from srccec to destcec on single HMC", " -i new partition numeric id", " -n new partition name", " -v displays command version", @@ -187,8 +187,9 @@ sub mkvm_parse_args { # Check for non-zero integer #################################### if ( exists( $opt{i} )) { - if ( $opt{i} =~ /^[1-9]{1}$|^[1-9]{1}[0-9]+$/ ) { + if ( $opt{i} !~ /^[1-9]{1}|[1-9]{1}[0-9]+$/ ) { return(usage( "Invalid entry: $opt{i}" )); + } } #################################### @@ -370,26 +371,37 @@ sub lsvm_parse_args { ########################################################################## -# Clones all the partitions from one CEC to another +# Clones all the LPARs from one CEC to another (must be on same HMC) ########################################################################## sub clone { - my $cfgdata = shift; - my $d = shift; my $exp = shift; - my $opt = shift; + my $src = shift; + my $dest = shift; + my $srcd = shift; my $hwtype = @$exp[2]; - my $target = $opt->{c}; + my $server = @$exp[3]; my @values = (); - my $cecname; - + my @lpars = (); + my $srccec; + my $destcec; + my @cfgdata; + ##################################### # Always one source CEC specified ##################################### - my $lparid = @$d[0]; - my $mtms = @$d[2]; - my $type = @$d[4]; + my $lparid = @$srcd[0]; + my $type = @$srcd[4]; + ##################################### + # Not supported on IVM + ##################################### + if ( $hwtype eq "ivm" ) { + return( ["Not supported for IVM"] ); + } + ##################################### + # Source must be CEC + ##################################### if ( $type ne "fsp" ) { return( ["Node must be an FSP"] ); } @@ -406,55 +418,111 @@ sub clone { return( [@$cecs[0]] ); } ##################################### - # Find target CEC + # Find source CEC ##################################### foreach ( @$cecs ) { - if ( $target eq $_ ) { - $cecname = $_; - last; + if ( $src eq $_ ) { + $srccec = $_; + last; } } ##################################### - # Target CEC not found + # Source CEC not found ##################################### - if ( !defined( $cecname )) { - return( ["CEC '$target' not found"] ); + if ( !defined( $srccec )) { + return( ["Source CEC '$src' not found"] ); } ##################################### - # Modify read-back profile: - # - Rename "name" to "profile_name" - # - Rename "lpar_name" to "name" - # - Delete "virtual_serial_adapters" - # completely, these adapters are - # created automatically. - # - Preceed all double-quotes with - # backslashes. - # + # Find destination CEC ##################################### - foreach ( @$cfgdata ) { - s/^name=([^,]+)/profile_name=$1/; - s/lpar_name=/name=/; - s/\"virtual_serial_adapters=[^\"]+\",//; - s/\"/\\"/g; + foreach ( @$cecs ) { + if ( $dest eq $_ ) { + $destcec = $_; + last; + } + } + ##################################### + # Destination CEC not found + ##################################### + if ( !defined( $destcec )) { + return( ["Destination CEC '$dest' not found on '$server'"] ); + } + + ##################################### + # Get all LPARs on source CEC + ##################################### + my $filter = "name,lpar_id"; + my $result = xCAT::PPCcli::lssyscfg( + $exp, + "lpar", + $src, + $filter ); + $Rc = shift(@$result); + + ##################################### + # Return error + ##################################### + if ( $Rc != SUCCESS ) { + return( [@$result[0]] ); + } + ##################################### + # Get profile for each LPAR + ##################################### + foreach ( @$result ) { + my ($name,$id) = split /,/; + + ################################# + # Get source LPAR profile + ################################# + my $prof = xCAT::PPCcli::lssyscfg( + $exp, + "prof", + $src, + $id ); + + $Rc = shift(@$prof); + + ################################# + # Return error + ################################# + if ( $Rc != SUCCESS ) { + return( [@$prof[0]] ); + } + ################################# + # Save LPAR profile + ################################# + push @cfgdata, @$prof[0]; + } + ##################################### + # Modify read back profile + ##################################### + foreach my $cfg ( @cfgdata ) { + $cfg =~ s/^name=([^,]+|$)/profile_name=$1/; + $cfg =~ s/lpar_name=/name=/; + $cfg = strip_profile( $cfg, $hwtype); my $name = $1; - /lpar_id=([^,]+)/; + $cfg =~ /lpar_id=([^,]+)/; $lparid = $1; ################################# # Create new LPAR ################################# - my @temp = @$d; + my @temp = @$srcd; $temp[0] = $lparid; + $temp[2] = $dest; - my $result = xCAT::PPCcli::mksyscfg( $exp, \@temp, $_ ); + my $result = xCAT::PPCcli::mksyscfg( $exp, \@temp, $cfg ); $Rc = shift(@$result); ################################# # Success - add LPAR to database ################################# if ( $Rc == SUCCESS ) { - xCATdB( "mkvm", $d, $lparid, $name, $hwtype ); + my $err = xCATdB( "mkvm", $srcd, $lparid, $name, $hwtype ); + if ( defined( $err )) { + push @values, $err; + } next; } ################################# @@ -473,81 +541,104 @@ sub clone { # Removes logical partitions ########################################################################## sub remove { - - my $exp = shift; - my $d = shift; - my $lpar = shift; - my $lparid = @$d[0]; - my $mtms = @$d[2]; - my $type = @$d[4]; - my @lpars = (); - my @values = (); + + my $request = shift; + my $hash = shift; + my $exp = shift; + my @lpars = (); + my @values = (); - #################################### - # This is a single LPAR - #################################### - if ( $type eq "lpar" ) { - $lpars[0] = "$lpar,$lparid"; - } - #################################### - # This is a CEC - remove all LPARs - #################################### - else { - my $filter = "name,lpar_id"; - my $result = xCAT::PPCcli::lssyscfg( $exp, "lpar", $mtms, $filter ); - my $Rc = shift(@$result); + while (my ($mtms,$h) = each(%$hash) ) { + while (my ($lpar,$d) = each(%$h) ) { + my $lparid = @$d[0]; + my $mtms = @$d[2]; + my $type = @$d[4]; - ################################ - # Expect error - ################################ - if ( $Rc != SUCCESS ) { - return( [@$result[0]] ); + #################################### + # Must be CEC or LPAR + #################################### + if ( $type !~ /^lpar|fsp$/ ) { + push @values, [$lpar,"Node must be LPAR or CEC"]; + next; + } + #################################### + # This is a single LPAR + #################################### + if ( $type eq "lpar" ) { + $lpars[0] = "$lpar,$lparid"; + } + #################################### + # This is a CEC - remove all LPARs + #################################### + else { + my $filter = "name,lpar_id"; + my $result = xCAT::PPCcli::lssyscfg( + $exp, + "lpar", + $mtms, + $filter ); + my $Rc = shift(@$result); + + ################################ + # Expect error + ################################ + if ( $Rc != SUCCESS ) { + push @values, [$lpar, @$result[0]]; + next; + } + ################################ + # Success - save LPARs + ################################ + foreach ( @$result ) { + push @lpars, $_; + } + } + #################################### + # Remove the LPARs + #################################### + foreach ( @lpars ) { + my ($name,$id) = split /,/; + my $mtms = @$d[2]; + + ################################ + # id profile mtms hcp type frame + ################################ + my @d = ( $id,0,$mtms,0,"lpar",0 ); + + ################################ + # Send remove command + ################################ + my $result = xCAT::PPCcli::rmsyscfg( $exp, \@d ); + my $Rc = shift(@$result); + + ################################ + # Remove LPAR from database + ################################ + if ( $Rc == SUCCESS ) { + my $err = xCATdB( "rmvm", $name ); + if ( defined( $err )) { + push @values, [$lpar,$err]; + next; + } + } + push @values, [$lpar,@$result[0]]; + } } - ################################ - # Success - save LPARs - ################################ - foreach ( @$result ) { - push @lpars, $_; - } - } - #################################### - # Remove the LPARs - #################################### - foreach ( @lpars ) { - my ($name,$id) = split /,/; - my $mtms = @$d[2]; - - ################################ - # id profile mtms hcp type frame - ################################ - my @d = ( $id,0,$mtms,0,"lpar",0 ); - - ################################ - # Send remove command - ################################ - my $result = xCAT::PPCcli::rmsyscfg( $exp, \@d ); - my $Rc = shift(@$result); - - ################################ - # Remove LPAR from database - ################################ - if ( $Rc == SUCCESS ) { - xCATdB( "rmvm", $name ); - } - push @values, @$result[0]; } return( \@values ); } + ########################################################################## # Changes the configuration of an existing partition ########################################################################## -sub chcfg { +sub modify { my $request = shift; my $hash = shift; my $exp = shift; + my $hwtype = @$exp[2]; my $name = @{$request->{node}}[0]; my $cfgdata = $request->{stdin}; my @values; @@ -564,19 +655,18 @@ sub chcfg { my $text = "Invalid file format: must begin with 'name='"; return( [[$name,$text]] ); } - ####################################### - # Preceed double-quotes with '\' - ####################################### - $cfgdata =~ s/\"/\\"/g; - $cfgdata =~ s/\n//g; + ####################################### + # Send change profile command + ####################################### while (my ($cec,$h) = each(%$hash) ) { while (my ($lpar,$d) = each(%$h) ) { ############################### # Change configuration ############################### - my $result = xCAT::PPCcli::chsyscfg( $exp, $d, $cfgdata ); + my $cfg = strip_profile( $cfgdata, $hwtype ); + my $result = xCAT::PPCcli::chsyscfg( $exp, $d, $cfg ); my $Rc = shift(@$result); push @values, [$lpar,@$result[0]]; @@ -587,18 +677,111 @@ sub chcfg { } +########################################################################## +# Lists logical partitions +########################################################################## +sub list { + + my $request = shift; + my $hash = shift; + my $exp = shift; + my @values = (); + my @lpars = (); + my $result; + + while (my ($mtms,$h) = each(%$hash) ) { + while (my ($lpar,$d) = each(%$h) ) { + my $lparid = @$d[0]; + my $mtms = @$d[2]; + my $type = @$d[4]; + my $profile; + + #################################### + # Must be CEC or LPAR + #################################### + if ( $type !~ /^lpar|fsp$/ ) { + push @values, [$lpar,"Node must be LPAR or CEC"]; + next; + } + #################################### + # This is a single LPAR + #################################### + if ( $type eq "lpar" ) { + $lpars[0] = "$lpar,$lparid"; + } + #################################### + # This is a CEC - remove all LPARs + #################################### + else { + my $filter = "name,lpar_id"; + my $result = xCAT::PPCcli::lssyscfg( + $exp, + "lpar", + $mtms, + $filter ); + my $Rc = shift(@$result); + + ################################ + # Expect error + ################################ + if ( $Rc != SUCCESS ) { + push @values, [$lpar, @$result[0]]; + next; + } + ################################ + # Success - save LPARs + ################################ + foreach ( @$result ) { + push @lpars, $_; + } + } + #################################### + # Get LPAR profile + #################################### + foreach ( @lpars ) { + my ($name,$id) = split /,/; + + ################################# + # Get source LPAR profile + ################################# + my $prof = xCAT::PPCcli::lssyscfg( + $exp, + "prof", + $mtms, + $id ); + my $Rc = shift(@$prof); + + ################################# + # Return error + ################################# + if ( $Rc != SUCCESS ) { + push @values, [$lpar, @$prof[0]]; + next; + } + ################################# + # List LPAR profile + ################################# + $profile .= "@$prof[0]\n\n"; + } + push @values, [$lpar, $profile]; + } + } + return( \@values ); +} + + + ########################################################################## -# Creates/Removes/Lists logical partitions +# Creates/changes logical partitions ########################################################################## -sub vm { +sub create { my $request = shift; my $hash = shift; my $exp = shift; my $hwtype = @$exp[2]; my $opt = $request->{opt}; - my $cmd = $request->{command}; my @values = (); my $result; @@ -616,25 +799,21 @@ sub vm { next; } ##################################### - # Remove LPAR + # Clone all the LPARs on CEC ##################################### - if ( $cmd eq "rmvm" ) { - $result = remove( $exp, $d, $lpar ); - - ################################# - # Return result - ################################# - foreach ( @$result ) { + if ( exists( $opt->{c} )) { + my $result = clone( $exp, $lpar, $opt->{c}, $d ); + foreach ( @$result ) { push @values, [$lpar, $_]; } - next; + next; } ##################################### # Get source LPAR profile ##################################### my $prof = xCAT::PPCcli::lssyscfg( $exp, - ($lparid) ? "prof" : "cprof", + "prof", $mtms, $lparid ); my $Rc = shift(@$prof); @@ -647,89 +826,31 @@ sub vm { next; } ##################################### - # List LPAR profile - ##################################### - if ( $cmd eq "lsvm" ) { - my $text = join "\n\n", @$prof[0]; - push @values, [$lpar, $text]; - next; - } - ##################################### - # Clone all the LPARs on CEC - ##################################### - if ( exists( $opt->{c} )) { - if ( $hwtype eq "ivm" ) { - push @values, [$lpar, "Not supported for IVM"]; - } - else { - my $result = clone( $prof, $d, $exp, $opt ); - foreach ( @$result ) { - push @values, [$lpar, $_]; - } - } - next; - } - ################################# # Get command-line options - ################################# + ##################################### my $id = $opt->{i}; my $name = $opt->{n}; my $cfgdata = @$prof[0]; + ##################################### + # Modify read-back profile. + # See HMC or IVM mksyscfg man + # page for valid attributes. + # + ##################################### if ( $hwtype eq "hmc" ) { - ##################################### - # Modify read-back profile. See - # HMC mksyscfg man page for valid - # attributes: - # - # - Rename "name" to "profile_name" - # - Rename "lpar_name" to "name" - # - Delete "virtual_serial_adapters" - # completely, these adapters are - # created automatically. - # - Preceed all double-quotes with - # backslashes. - # - ##################################### - $cfgdata =~ s/^name=[^,]+/profile_name=$name/; - $cfgdata =~ s/lpar_name=[^,]+/name=$name/; - $cfgdata =~ s/lpar_id=[^,]+/lpar_id=$id/; - $cfgdata =~ s/\"virtual_serial_adapters=[^\"]+\",//; - $cfgdata =~ s/\"/\\"/g; + $cfgdata =~ s/^name=[^,]+|$/profile_name=$name/; + $cfgdata =~ s/lpar_name=[^,]+|$/name=$name/; + $cfgdata =~ s/lpar_id=[^,]+|$/lpar_id=$id/; } elsif ( $hwtype eq "ivm" ) { - ##################################### - # Modify read-back profile. See - # IVM mksyscfg man page for valid - # attributes: - # - # - Delete - # lpar_name - # virtual_serial_adapters - # lpar_name - # os_type - # all_resources - # lpar_io_pool_ids - # conn_monitoring - # power_ctrl_lpar_ids - # - Preceed all double-quotes with - # backslashes. - # - ##################################### - $cfgdata =~ s/^name=[^,]+/name=$name/; - $cfgdata =~ s/lpar_id=[^,]+/lpar_id=$id/; - $cfgdata =~ s/lpar_name=[^,]+,//; - $cfgdata =~ s/os_type=/lpar_env=/; - $cfgdata =~ s/all_resources=[^,]+,//; - $cfgdata =~ s/\"virtual_serial_adapters=[^\"]+\",//; - $cfgdata =~ s/lpar_io_pool_ids=[^,]+,//; - $cfgdata =~ s/virtual_scsi_adapters=[^,]+,//; - $cfgdata =~ s/conn_monitoring=[^,]+,//; - $cfgdata =~ s/,power_ctrl_lpar_ids=.*$//; - $cfgdata =~ s/\"/\\"/g; + $cfgdata =~ s/^name=[^,]+|$/name=$name/; + $cfgdata =~ s/lpar_id=[^,]+|$/lpar_id=$id/; } + $cfgdata = strip_profile( $cfgdata, $hwtype ); + ##################################### - # Create target LPAR + # Create new LPAR ##################################### $result = xCAT::PPCcli::mksyscfg( $exp, $d, $cfgdata ); $Rc = shift(@$result); @@ -738,7 +859,11 @@ sub vm { # Add new LPAR to database ##################################### if ( $Rc == SUCCESS ) { - xCATdB( $cmd, $name, $id, $d, $hwtype ); + my $err = xCATdB( "mkvm", $name, $id, $d, $hwtype, $lpar ); + if ( defined( $err )) { + push @values, [$name,$err]; + next; + } } push @values, [$name,@$result[0]]; } @@ -747,6 +872,44 @@ sub vm { } +########################################################################## +# Strips attributes from profile not valid for creation +########################################################################## +sub strip_profile { + + my $cfgdata = shift; + my $hwtype = shift; + + ##################################### + # Modify read-back profile. See + # HMC mksyscfg man page for valid + # attributes. + ##################################### + if ( $hwtype eq "hmc" ) { + $cfgdata =~ s/,*\"virtual_serial_adapters=[^\"]+\"//; + $cfgdata =~ s/,*electronic_err_reporting=[^,]+|$//; + $cfgdata =~ s/,*shared_proc_pool_id=[^,]+|$//; + $cfgdata =~ s/\"/\\"/g; + $cfgdata =~ s/\n//g; + return( $cfgdata ); + } + ##################################### + # Modify read-back profile. See + # IVM mksyscfg man page for valid + # attributes. + ##################################### + $cfgdata =~ s/,*lpar_name=[^,]+|$//; + $cfgdata =~ s/os_type=/lpar_env=/; + $cfgdata =~ s/,*all_resources=[^,]+|$//; + $cfgdata =~ s/,*\"virtual_serial_adapters=[^\"]+\"//; + $cfgdata =~ s/,*lpar_io_pool_ids=[^,]+|$//; + $cfgdata =~ s/,*virtual_scsi_adapters=[^,]+|$//; + $cfgdata =~ s/,*conn_monitoring=[^,]+|$//; + $cfgdata =~ s/,*power_ctrl_lpar_ids=[^,]+|$//; + $cfgdata =~ s/\"/\\"/g; + return( $cfgdata ); +} + ########################################################################## # Adds/removes LPARs from the xCAT database @@ -758,22 +921,48 @@ sub xCATdB { my $lparid = shift; my $d = shift; my $hwtype = shift; + my $lpar = shift; ####################################### # Remove entry ####################################### if ( $cmd eq "rmvm" ) { - xCAT::PPCdb::rm_ppchardware( $name ); + return( xCAT::PPCdb::rm_ppc( $name )); } ####################################### # Add entry ####################################### else { my ($model,$serial) = split /\*/,@$d[2]; - my $prof = $name; - my $frame = @$d[4]; - my $server = @$d[3]; + my $profile = $name; + my $server = @$d[3]; + my $fsp = @$d[2]; + ################################### + # Find FSP name in ppc database + ################################### + my $tab = xCAT::Table->new( "ppc" ); + + ################################### + # Error opening ppc database + ################################### + if ( !defined( $tab )) { + return( "Error opening 'ppc' database" ); + } + my ($ent) = $tab->getAttribs({node=>$lpar}, "parent" ); + + ################################### + # Node not found + ################################### + if ( !defined( $ent )) { + return( "'$lpar' not found in 'ppc' database" ); + } + ################################### + # Attributes not found + ################################### + if ( !exists( $ent->{parent} )) { + return( "'parent' attribute not found in 'ppc' database" ); + } my $values = join( ",", "lpar", $name, @@ -781,11 +970,12 @@ sub xCATdB { $model, $serial, $server, - $prof, - $frame ); + $profile, + $ent->{parent} ); - xCAT::PPCdb::add_ppc( $hwtype, [$values] ); + return( xCAT::PPCdb::add_ppc( $hwtype, [$values] )); } + return undef; } @@ -794,14 +984,14 @@ sub xCATdB { # Creates logical partitions ########################################################################## sub mkvm { - return( vm(@_) ); + return( create(@_) ); } ########################################################################## # Change logical partition ########################################################################## sub chvm { - return( chcfg(@_) ); + return( modify(@_) ); } @@ -809,14 +999,14 @@ sub chvm { # Removes logical partitions ########################################################################## sub rmvm { - return( vm(@_) ); + return( remove(@_) ); } ########################################################################## # Lists logical partition profile ########################################################################## sub lsvm { - return( vm(@_) ); + return( list(@_) ); }