From d0b403f79e9326c0e2a6002cc072247fabc6e84a Mon Sep 17 00:00:00 2001 From: "Leigh B. Stoller" Date: Thu, 24 Sep 2009 13:47:10 +0000 Subject: [PATCH] Beef up Create() routine, used from the Protogeni cooked mode to create "proxy" nodes for remote geni nodes. Clean up method access to reserved table slots. Changes/Fixes to CreateVnodes() to support cooked mode Protogeni nodes. --- db/Node.pm.in | 272 +++++++++++++++++++++++++++++++------------------- 1 file changed, 167 insertions(+), 105 deletions(-) diff --git a/db/Node.pm.in b/db/Node.pm.in index 044aa6f47..2b507dc0d 100644 --- a/db/Node.pm.in +++ b/db/Node.pm.in @@ -253,6 +253,11 @@ sub AUTOLOAD { # # Create a new node. # +# The list of table we have to clear if anything goes wrong. +my @cleantables = ("nodes", "node_hostkeys", "node_status", + "node_activity", "node_utilization", + "node_auxtypes", "reserved", "widearea_nodeinfo"); + sub Create($$$$) { my ($class, $node_id, $experiment, $argref) = @_; @@ -286,30 +291,56 @@ sub Create($$$$) print STDERR "*** No virtnode_capacity for $type! Using zero.\n"; $virtnode_capacity = 0; } - if ($typeinfo->adminmfs_osid(\$adminmfs_osid)) { - print STDERR "*** No adminmfs osid for $type!\n"; - return undef; - } - # Find object for the adminfs. - if (defined($adminmfs_osid)) { - $adminmfs = OSinfo->Lookup($adminmfs_osid); + if ($isremote) { + $osid = 0; + $opmode = ""; + + if (defined($typeinfo->default_osid())) { + $osid = $typeinfo->default_osid(); + + my $osinfo = OSinfo->Lookup($osid); + if (!defined($osinfo)) { + print STDERR + "*** Could not find OSinfo object for $osid!\n"; + return undef; + } + $osid = $osinfo->osid(); + $opmode = $osinfo->op_mode(); + } } else { - $adminmfs = OSinfo->Lookup(TBOPSPID(), $MFS_INITIAL); - } - if (!defined($adminmfs)) { - print STDERR "*** Could not find OSinfo object for adminmfs!\n"; - return undef; + if ($typeinfo->adminmfs_osid(\$adminmfs_osid)) { + print STDERR "*** No adminmfs osid for $type!\n"; + return undef; + } + # Find object for the adminfs. + if (defined($adminmfs_osid)) { + $adminmfs = OSinfo->Lookup($adminmfs_osid); + } + else { + $adminmfs = OSinfo->Lookup(TBOPSPID(), $MFS_INITIAL); + } + if (!defined($adminmfs)) { + print STDERR + "*** Could not find OSinfo object for adminmfs!\n"; + return undef; + } + $osid = $adminmfs->osid(); + $opmode = $adminmfs->op_mode(); } - $osid = $adminmfs->osid(); - $opmode = $adminmfs->op_mode(); } else { $osid = 0; $opmode = ""; } $state = $STATE_INITIAL; - + + # + # Lock the tables to prevent concurrent creation + # + DBQueryWarn("lock tables nodes write, widearea_nodeinfo write") + or return -1; + # # Make up a priority (just used for sorting) # @@ -319,21 +350,35 @@ sub Create($$$$) else { $priority = 1; } - # The list of table we have to clear if anything goes wrong. - my @cleantables = ("nodes", "node_hostkeys", "node_status", - "node_activity", "node_utilization", - "node_auxtypes", "reserved"); - - DBQueryWarn("insert into nodes set ". - " node_id='$node_id', type='$type', " . - " phys_nodeid='$node_id', role='$role', ". - " priority=$priority, " . - " eventstate='$state', op_mode='$opmode', " . - " def_boot_osid='$osid', " . - " inception=now(), uuid=$uuid, ". - " state_timestamp=unix_timestamp(NOW()), " . - " op_mode_timestamp=unix_timestamp(NOW())") - or goto bad; + + if (!DBQueryWarn("insert into nodes set ". + " node_id='$node_id', type='$type', " . + " phys_nodeid='$node_id', role='$role', ". + " priority=$priority, " . + " eventstate='$state', op_mode='$opmode', " . + " def_boot_osid='$osid', " . + " inception=now(), uuid=$uuid, ". + " state_timestamp=unix_timestamp(NOW()), " . + " op_mode_timestamp=unix_timestamp(NOW())")) { + DBQueryWarn("unlock tables"); + return undef; + } + if ($isremote) { + my $hostname = $argref->{'hostname'}; + my $external = $argref->{'external_node_id'}; + my $IP = $argref->{'IP'}; + + if (!DBQueryWarn("replace into widearea_nodeinfo ". + " (node_id, contact_uid, contact_idx, hostname," . + " external_node_id, IP) ". + " values ('$node_id', 'nobody', '0', ". + " '$hostname', '$external', '$IP')")) { + DBQueryWarn("delete from nodes where node_id='$node_id'"); + DBQueryWarn("unlock tables"); + return undef; + } + } + DBQueryWarn("unlock tables"); if ($role eq "testnode") { DBQueryWarn("insert into node_hostkeys (node_id) ". @@ -399,6 +444,20 @@ sub Create($$$$) return undef; } +# +# Only use this for Create() errors. +# +sub Delete($) +{ + my ($self) = @_; + my $node_id = $self->node_id(); + + foreach my $table (@cleantables) { + DBQueryWarn("delete from $table where node_id='$node_id'"); + } + return 0; +} + # # Refresh a class instance by reloading from the DB. # @@ -984,43 +1043,29 @@ sub HasVirtualNodes($) return $query_result->numrows; } -# Need to create a set of access methods for the reservation. -sub vname($) -{ - my ($self) = @_; - - return undef - if (! ref($self)); - - return undef - if (! $self->IsReserved()); - - return $self->{"RSRV"}->{'vname'}; -} -sub sharing_mode($) +# +# Access methods for the reservation. +# +sub __reservation($$) { - my ($self) = @_; + my ($self, $slotname) = @_; return undef if (! ref($self)); - return undef if (! $self->IsReserved()); - - return $self->{"RSRV"}->{'sharing_mode'}; -} -sub erole($) -{ - my ($self) = @_; - return undef - if (! ref($self)); + if (! exists($self->{"RSRV"}->{$slotname})); - return undef - if (! $self->IsReserved()); - - return $self->{"RSRV"}->{'erole'}; + return $self->{"RSRV"}->{$slotname}; } +sub vname($) { return __reservation($_[0], 'vname'); } +sub sharing_mode($) { return __reservation($_[0], 'sharing_mode'); } +sub erole($) { return __reservation($_[0], 'erole'); } +sub external_resource_index($) { + return __reservation($_[0], 'external_resource_index'); } +sub external_resource_id($) { + return __reservation($_[0], 'external_resource_id'); } # # Lookup a specific attribute in the node_attributes table, @@ -1174,7 +1219,8 @@ sub Update($$) my $val = $argref->{$key}; # Treat NULL special. - push (@sets, "${key}=" . ($val eq "NULL" ? "NULL" : "'$val'")); + push (@sets, "${key}=" . ($val eq "NULL" ? + "NULL" : DBQuoteSpecial($val))); } my $query = "update nodes set " . join(",", @sets) . @@ -1534,8 +1580,9 @@ sub CreateVnodes($$) print STDERR "*** CreateVnodes: Not a dynamic node type: '$vtype'\n"; return -1; } - my $isremote = $nodetype->isremotenode(); - my $isjailed = $nodetype->isjailed(); + my $isremote = $nodetype->isremotenode(); + my $isjailed = $nodetype->isjailed(); + my $isfednode = $nodetype->isfednode(); # # Make up a priority (just used for sorting). We need the name prefix @@ -1544,7 +1591,13 @@ sub CreateVnodes($$) my $nodeprefix; my $nodenum; my $ipbase; - if ($pnode =~ /^(.*\D)(\d+)$/) { + + if ($isfednode) { + $nodeprefix = $nodetype->type(); + $nodenum = ""; + $ipbase = 0; + } + elsif ($pnode =~ /^(.*\D)(\d+)$/) { $nodeprefix = $1; $nodenum = $2; $ipbase = $nodenum; @@ -1553,25 +1606,29 @@ sub CreateVnodes($$) $nodeprefix = $pnode; $nodenum = ""; - # - # Determine ipbase from the control IP. - # - my $interface = Interface->LookupControl($node); - if (!defined($interface)) { - print STDERR "*** CreateVnodes: No control interface for $node\n"; - return -1; - } - my $ctrlip = $interface->IP(); - if (!defined($ctrlip) || $ctrlip eq "") { - print STDERR "*** CreateVnodes: No control IP for $interface\n"; - return -1; - } - my $tmp = ~inet_aton($CONTROL_NETMASK) & inet_aton($ctrlip); - $ipbase = unpack("N", $tmp); - if ($ipbase == 0 || $ipbase < 0 || $ipbase > 0x3fff) { - print STDERR - "*** CreateVnodes: Bad ipbase '$ipbase' for $interface\n"; - return -1; + if ($isjailed) { + # + # Determine ipbase from the control IP (jailed nodes). + # + my $interface = Interface->LookupControl($node); + if (!defined($interface)) { + print STDERR + "*** CreateVnodes: No control interface for $node\n"; + return -1; + } + my $ctrlip = $interface->IP(); + if (!defined($ctrlip) || $ctrlip eq "") { + print STDERR + "*** CreateVnodes: No control IP for $interface\n"; + return -1; + } + my $tmp = ~inet_aton($CONTROL_NETMASK) & inet_aton($ctrlip); + $ipbase = unpack("N", $tmp); + if ($ipbase == 0 || $ipbase < 0 || $ipbase > 0x3fff) { + print STDERR + "*** CreateVnodes: Bad ipbase '$ipbase' for $interface\n"; + return -1; + } } } @@ -1632,7 +1689,7 @@ sub CreateVnodes($$) $node->FlushReserved(); my $sharing_mode = $node->sharing_mode(); - if (!$impotent) { + if (! ($impotent || $isfednode)) { my $reservation = $node->Reservation(); if (!defined($reservation)) { print STDERR "*** CreateVnodes: no reservation for $node!\n"; @@ -1688,33 +1745,36 @@ sub CreateVnodes($$) # # Create a bunch. # - foreach my $i (@tocreate) { - my $vpriority = 10000000 + ($ipbase * 1000) + $i; - my $vnodeid = $nodeprefix . "vm" . $nodenum . "-" . $i; - - # - # Construct the vnode IP. The general form is: - # ... - # but if is greater than 254 we have to increment - # IPBASE2. - # - # XXX at Utah our second big cluster of nodes starts at - # nodenum=201 and I would like our vnode IPs to align - # at that boundary, so 254 becomes 200. - # - my $nodenumlimit = $ISUTAH ? 200 : 254; - my $pnet = $IPBASE2; - my $pnode2 = int($ipbase); - while ($pnode2 > $nodenumlimit) { - $pnet++; - $pnode2 -= $nodenumlimit; + foreach my $n (@tocreate) { + my $vpriority = 10000000 + ($ipbase * 1000) + $n; + my $vnodeid = $nodeprefix . "vm" . $nodenum . "-" . $n; + my $jailip; + + if ($isjailed) { + # + # Construct the vnode IP. The general form is: + # ... + # but if is greater than 254 we have to increment + # IPBASE2. + # + # XXX at Utah our second big cluster of nodes starts at + # nodenum=201 and I would like our vnode IPs to align + # at that boundary, so 254 becomes 200. + # + my $nodenumlimit = $ISUTAH ? 200 : 254; + my $pnet = $IPBASE2; + my $pnode2 = int($ipbase); + while ($pnode2 > $nodenumlimit) { + $pnet++; + $pnode2 -= $nodenumlimit; + } + $jailip = "${IPBASE1}.${pnet}.${pnode2}.${n}"; } - my $jailip = "${IPBASE1}.${pnet}.${pnode2}.${i}"; # Need to keep the UUIDs consistent across regression mode. my $uuid; if ($regression) { - $uuid = "${pnode2}${i}-1111-2222-3333-44444444"; + $uuid = "0000${n}-1111-2222-3333-44444444"; } else { $uuid = (@uuids ? shift(@uuids) : NewUUID()); @@ -1725,7 +1785,9 @@ sub CreateVnodes($$) } if ($verbose) { - print STDERR "Jail IP for $vnodeid is $jailip\n"; + print STDERR "Jail IP for $vnodeid is $jailip\n" + if ($jailip); + if ($impotent) { print STDERR "Would allocate $vnodeid on $pnode ($vtype, $osid)\n"; -- GitLab