Improve chdef performance and handling of tables with multiple keys
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3304 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -583,7 +583,14 @@ sub setobjdefs | ||||
|     my %objhash = %$hash_ref; | ||||
|     my %settableref; | ||||
|     my $ret = 0; | ||||
| 	my %allupdates; | ||||
| 	my $setattrs=0; | ||||
|  | ||||
| 	# for each object figure out: | ||||
| 	#	- what tables to update | ||||
| 	#	- which table attrs correspond to which object attrs | ||||
| 	#	- what the keys are for each table | ||||
| 	# update the tables a row at a time | ||||
|     foreach my $objname (keys %objhash) | ||||
|     { | ||||
|  | ||||
| @@ -699,7 +706,6 @@ sub setobjdefs | ||||
| 					%keyhash=(name=>$objname); | ||||
| 					%updates=($attr=>$val); | ||||
| 					$montable->setAttribs(\%keyhash, \%updates); | ||||
|  | ||||
| 				} else { | ||||
| 					# else it belongs in the monsetting table | ||||
| 					$keyhash{name} = $objname; | ||||
| @@ -711,14 +717,12 @@ sub setobjdefs | ||||
|  | ||||
| 			$montable->commit; | ||||
| 			$monsettable->commit; | ||||
|  | ||||
| 			next; | ||||
| 		} | ||||
|  | ||||
|         # handle the site table as a special case !!!!! | ||||
|         if ($type eq 'site') | ||||
|         { | ||||
|  | ||||
|             # if plus or minus then need to know current settings | ||||
|             my %DBhash; | ||||
|             $DBhash{$objname} = $type; | ||||
| @@ -749,7 +753,6 @@ sub setobjdefs | ||||
|                 my $val; | ||||
|                 if ($::plus_option) | ||||
|                 { | ||||
|  | ||||
|                     # add new to existing - at the end - comma separated | ||||
|                     if (defined($DBattrvals{$objname}{$attr})) | ||||
|                     { | ||||
| @@ -760,16 +763,13 @@ sub setobjdefs | ||||
|                     { | ||||
|                         $val = "$objhash{$objname}{$attr}"; | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|                 elsif ($::minus_option) | ||||
|                 { | ||||
|  | ||||
|                     # remove the specified list of values from the current | ||||
|                     #   attr values. | ||||
|                     if ($DBattrvals{$objname}{$attr}) | ||||
|                     { | ||||
|  | ||||
|                         # get the list of attrs to remove | ||||
|                         my @currentList = split(/,/, $DBattrvals{$objname}{$attr}); | ||||
|                         my @minusList   = split(/,/, $objhash{$objname}{$attr}); | ||||
| @@ -782,7 +782,6 @@ sub setobjdefs | ||||
|                             chomp $i; | ||||
|                             if (!grep(/^$i$/, @minusList)) | ||||
|                             { | ||||
|  | ||||
|                                 # set new groups list for node | ||||
|                                 if (!$first) | ||||
|                                 { | ||||
| @@ -794,7 +793,6 @@ sub setobjdefs | ||||
|                         } | ||||
|                         $val = $newlist; | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
| @@ -836,6 +834,10 @@ sub setobjdefs | ||||
|             next; | ||||
|         } | ||||
|  | ||||
| 		# | ||||
| 		#  handle the rest of the object types | ||||
| 		# | ||||
|  | ||||
|         # get the attr=vals for these objects from the DB - if any | ||||
|         #       - so we can figure out where to put additional attrs | ||||
|         my %DBhash; | ||||
| @@ -848,11 +850,11 @@ sub setobjdefs | ||||
|         # get the object type decription from Schema.pm | ||||
|         my $datatype = $xCAT::Schema::defspec{$type}; | ||||
|  | ||||
| 		# get the key to look for, for this object type | ||||
| 		# get the object key to look for, for this object type | ||||
|         my $objkey = $datatype->{'objkey'}; | ||||
|  | ||||
|         #  get a list of valid attr names | ||||
|         #               for this type object | ||||
|         #     for this type object | ||||
|         my %attrlist; | ||||
|         foreach my $entry (@{$datatype->{'attrs'}}) | ||||
|         { | ||||
| @@ -865,10 +867,10 @@ sub setobjdefs | ||||
|         foreach my $attr (keys %{$objhash{$objname}}) | ||||
|         { | ||||
|  | ||||
| 		if ($attr eq $objkey) | ||||
| 		{ | ||||
| 			next; | ||||
| 		} | ||||
| 			if ($attr eq $objkey) | ||||
| 			{ | ||||
| 				next; | ||||
| 			} | ||||
|  | ||||
|             if ($attr eq "objtype") | ||||
|             { | ||||
| @@ -894,10 +896,9 @@ sub setobjdefs | ||||
|         } | ||||
|  | ||||
|         #   we need to figure out what table to | ||||
|         #               store each attr | ||||
|         #      store each attr | ||||
|         #   And we must do this in the order given in defspec!! | ||||
|  | ||||
|  | ||||
| 		my @setattrlist=(); | ||||
| 		my @checkedattrs; | ||||
|  | ||||
| @@ -906,7 +907,7 @@ sub setobjdefs | ||||
|  | ||||
|             my %keyhash; | ||||
|             my %updates; | ||||
| 			my ($lookup_table, $lookup_attr); | ||||
| 			my ($lookup_table, $lookup_attr, $lookup_data); | ||||
|             my $attr_name = $this_attr->{attr_name}; | ||||
|  | ||||
| 			if ($attr_name eq $objkey) | ||||
| @@ -918,7 +919,6 @@ sub setobjdefs | ||||
|             #   - otherwise go to the next attr | ||||
|             if (defined($objhash{$objname}{$attr_name})) | ||||
|             { | ||||
|  | ||||
|                 # check the defspec to see where this attr goes | ||||
|  | ||||
|                 # the table for this attr might depend on the | ||||
| @@ -945,7 +945,6 @@ sub setobjdefs | ||||
|  | ||||
| 					if ( !($objhash{$objname}{$check_attr})  && !($DBattrvals{$objname}{$check_attr}) ) { | ||||
|                         # if I didn't already check for this attr | ||||
|                         # if ($::VERBOSE) { | ||||
|                         my $rsp; | ||||
|                         if (!grep(/^$attr_name$/, @checkedattrs)) { | ||||
|                             push @{$rsp->{data}}, "Cannot set the \'$attr_name\' attribute unless a value is provided for \'$check_attr\'.\n"; | ||||
| @@ -961,7 +960,6 @@ sub setobjdefs | ||||
|                             } | ||||
|                         } | ||||
| 						xCAT::MsgUtils->message("I", $rsp, $::callback); | ||||
|                        # } | ||||
| 						push(@checkedattrs, $attr_name); | ||||
|                         next; | ||||
|                     } | ||||
| @@ -996,16 +994,6 @@ sub setobjdefs | ||||
|                 next; | ||||
|             } | ||||
|  | ||||
|             # | ||||
|             # write to the DB table | ||||
|             # | ||||
|  | ||||
|             my $thistable; | ||||
|             my $needtocommit = 0; | ||||
|  | ||||
|             # ex. node= c68m3hvp03 (key in table) | ||||
|             $keyhash{$lookup_attr} = $objname; | ||||
|  | ||||
|             my $val; | ||||
|             if ($::plus_option) | ||||
|             { | ||||
| @@ -1070,67 +1058,20 @@ sub setobjdefs | ||||
|  | ||||
|             } | ||||
|  | ||||
|             # ex. nodetype = osi (attr=val or col = col value) | ||||
|             $updates{$::tabattr} = "$val"; | ||||
| 			$allupdates{$lookup_table}{$objname}{$lookup_attr}{$lookup_attr}=$objname; | ||||
| 			$allupdates{$lookup_table}{$objname}{$lookup_attr}{$::tabattr} = $val; | ||||
| 			$setattrs=1; | ||||
|  | ||||
|             if (ref($::settableref{$lookup_table})) | ||||
|             { | ||||
|  | ||||
|                 # if we already opened this table use the reference | ||||
|                 $thistable = $::settableref{$lookup_table}; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  | ||||
|                 # open the table | ||||
|                 $thistable = | ||||
|                   xCAT::Table->new( | ||||
|                                    $lookup_table, | ||||
|                                    -create     => 1, | ||||
|                                    -autocommit => 0 | ||||
|                                    ); | ||||
|  | ||||
|                 if (!$thistable) | ||||
|                 { | ||||
|                     my $rsp; | ||||
|                     $rsp->{data}->[0] = | ||||
|                       "Could not set the \'$thistable\' table."; | ||||
|                     xCAT::MsgUtils->message("E", $rsp, $::callback); | ||||
|                     return 1; | ||||
|                 } | ||||
|  | ||||
|                 # set the attr values in the DB | ||||
|                 my ($rc, $str) = $thistable->setAttribs(\%keyhash, \%updates); | ||||
|                 if (!defined($rc)) | ||||
|                 { | ||||
|                     if ($::verbose) | ||||
|                     { | ||||
|                         my $rsp; | ||||
|                         $rsp->{data}->[0] = | ||||
|                           "Could not set the \'$attr_name\' attribute of the \'$objname\' object in the xCAT database.\n"; | ||||
|                         $rsp->{data}->[1] = "Error returned is \'$str->errst | ||||
| r\'."; | ||||
|                         xCAT::MsgUtils->message("I", $rsp, $::callback); | ||||
|                     } | ||||
|                     $ret = 1; | ||||
| 					$thistable->commit; | ||||
|                     next; | ||||
|                 } | ||||
|  | ||||
|                 # $::settableref{$lookup_table} = $thistable; | ||||
| 				 | ||||
| 				push(@setattrlist, $attr_name); | ||||
|  | ||||
|                 $thistable->commit; | ||||
|  | ||||
|             } | ||||
| 			push(@setattrlist, $attr_name); | ||||
|  | ||||
|         }    # end - foreach attribute | ||||
|  | ||||
|  | ||||
| # TODO - need to get back to this | ||||
| if (0) { | ||||
| 		# | ||||
| 		#  check to see if all the attrs got set | ||||
| 		# | ||||
| 		# debug: print "attrprovided = @attrprovided, setattrlist = @setattrlist\n"; | ||||
|  | ||||
| 		my @errlist; | ||||
| 		foreach $a (@attrprovided) | ||||
| @@ -1149,8 +1090,68 @@ r\'."; | ||||
| 			xCAT::MsgUtils->message("E", $rsp, $::callback); | ||||
| 		} | ||||
|  | ||||
| } | ||||
|  | ||||
|     }    # end - foreach object | ||||
|  | ||||
| 	# now set the attribute values in the tables | ||||
| 	#   - handles all except site, monitoring & monsetting for now | ||||
| 	if ($setattrs) { | ||||
| 		foreach my $table (keys %allupdates) { | ||||
|  | ||||
| 			# get the keys for this table | ||||
| 			my $schema = xCAT::Table->getTableSchema($table); | ||||
| 			my $keys = $schema->{keys}; | ||||
|  | ||||
| 			# open the table | ||||
| 			my $thistable = xCAT::Table->new($table, -create => 1, -autocommit => 0); | ||||
| 			if (!$thistable) { | ||||
| 				my $rsp; | ||||
| 				$rsp->{data}->[0] = "Could not set the \'$thistable\' table."; | ||||
| 				xCAT::MsgUtils->message("E", $rsp, $::callback); | ||||
| 				return 1; | ||||
| 			} | ||||
|  | ||||
| 			ROW: foreach my $row (keys %{$allupdates{$table}}) { | ||||
| 				my %keyhash; | ||||
| 				my %updates; | ||||
| 				foreach my $key (keys %{$allupdates{$table}{$row}}) { | ||||
| 					foreach my $column (keys %{$allupdates{$table}{$row}{$key}}) { | ||||
| 						# make sure we have a value for each key | ||||
| 						foreach my $k (@$keys) { | ||||
| 							if (!$allupdates{$table}{$row}{$key}{$k}) { | ||||
| 								my $rsp; | ||||
| 								$rsp->{data}->[0] = "\nMissing required attribute values for the \'$row\' object. The required attributes are: @$keys\n"; | ||||
| 								xCAT::MsgUtils->message("E", $rsp, $::callback); | ||||
| 								$ret = 1; | ||||
| 								next ROW; | ||||
| 							} | ||||
| 						} | ||||
|  | ||||
| 						# need to add obj name | ||||
| 						if ( grep(/^$key$/, @$keys)) { | ||||
| 							# ex. $keyhash{netname}=clstr_net; | ||||
| 							$keyhash{$key}=$row; | ||||
| 						} else { | ||||
| 							$updates{$key}=$row; | ||||
| 						} | ||||
|  | ||||
| 						# if attrs are keys then add to keyhash | ||||
| 						if ( grep(/^$column$/, @$keys)) { | ||||
| 							# ex. $keyhash{node}= node1 | ||||
| 							$keyhash{$column}=$allupdates{$table}{$row}{$key}{$column}; | ||||
| 						} else { | ||||
| 							# ex.  $updates{os}= "AIX" | ||||
| 							$updates{$column} = $allupdates{$table}{$row}{$key}{$column}; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				# do table updates one object/row at a a time??? | ||||
| 				my ($rc, $str) = $thistable->setAttribs(\%keyhash, \%updates); | ||||
| 			} | ||||
| 			$thistable->commit; | ||||
| 		} | ||||
| 	} | ||||
|     return $ret; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -402,9 +402,9 @@ sub processArgs | ||||
|             { | ||||
|                 my $rsp; | ||||
|                 $rsp->{data}->[0] = | ||||
|                   "Type \'$t\' is not a valid xCAT object type.\n"; | ||||
|                 $rsp->{data}->[1] = "Skipping to the next type.\n"; | ||||
|                   "\nType \'$t\' is not a valid xCAT object type."; | ||||
|                 xCAT::MsgUtils->message("I", $rsp, $::callback); | ||||
| 				return 3; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -602,9 +602,9 @@ sub processArgs | ||||
|                         my $rsp; | ||||
|                         $rsp->{data}->[0] = | ||||
|                           "Could not get objects of type \'$t\'.\n"; | ||||
|                         $rsp->{data}->[1] = "Skipping to the next type.\n"; | ||||
|                         #$rsp->{data}->[1] = "Skipping to the next type.\n"; | ||||
|                         xCAT::MsgUtils->message("I", $rsp, $::callback); | ||||
|                         next; | ||||
|                         return 3; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
| @@ -902,7 +902,7 @@ sub defmk | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     foreach my $obj (keys %::FINALATTRS) | ||||
|     OBJ: foreach my $obj (keys %::FINALATTRS) | ||||
|     { | ||||
|  | ||||
|         my $type = $::FINALATTRS{$obj}{objtype}; | ||||
| @@ -917,18 +917,34 @@ sub defmk | ||||
|             next; | ||||
|         } | ||||
|  | ||||
| 		# we don't want to overwrite any existing table row.  This could | ||||
| 		#	happen if there are multiple table keys. (ex. networks table - | ||||
| 		#		where the object name is not either of the table keys - net  | ||||
| 		#		& mask) | ||||
| 		#  just handle network objects for now -  | ||||
| 		if ($type eq 'network') { | ||||
| 			my @nets = xCAT::DBobjUtils->getObjectsOfType('network'); | ||||
| 			my %objhash; | ||||
| 			foreach my $n (@nets) { | ||||
| 				$objhash{$n} = $type; | ||||
| 			} | ||||
| 			my %nethash = xCAT::DBobjUtils->getobjdefs(\%objhash); | ||||
| 			foreach my $o (keys %nethash) { | ||||
| 				if ( ($nethash{$o}{net} eq $::FINALATTRS{$o}{net})  && ($nethash{$o}{mask} eq $::FINALATTRS{$o}{mask}) ) { | ||||
| 					my $rsp; | ||||
| 					$rsp->{data}->[0] = "A network definition called \'$o\' already exists that contains the same net and mask values. Cannot create a definition for \'$obj\'.\n"; | ||||
| 					xCAT::MsgUtils->message("E", $rsp, $::callback); | ||||
| 					$error = 1; | ||||
| 					next OBJ; | ||||
| 				}	 | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|         # if object already exists | ||||
|         if (grep(/^$obj$/, @{$objTypeLists{$type}})) | ||||
|         { | ||||
|             if ($::verbose) | ||||
|             { | ||||
|                 my $rsp; | ||||
|                 $rsp->{data}->[0] = "defmk: object already exists, remove old ones"; | ||||
|                 xCAT::MsgUtils->message("I", $rsp, $::callback); | ||||
|             } | ||||
|             if ($::opt_f) | ||||
|             { | ||||
|  | ||||
|                 # remove the old object | ||||
| 				my %objhash; | ||||
|                 $objhash{$obj} = $type; | ||||
| @@ -2127,8 +2143,6 @@ sub defls | ||||
|     { | ||||
|         %objhash = %::ObjTypeHash; | ||||
|  | ||||
| print "defls: verb = $::VERBOSE\n"; | ||||
|  | ||||
|         %myhash = xCAT::DBobjUtils->getobjdefs(\%objhash, $::VERBOSE); | ||||
|         if (!defined(%myhash)) | ||||
|         { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user