mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-04 05:12:30 +00:00 
			
		
		
		
	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