Commit 42040c90 authored by Leigh B Stoller's avatar Leigh B Stoller

Add locking around node/interface creation to prevent concurrent

attempts by protogeni code.
parent abcbe37c
...@@ -322,14 +322,38 @@ sub Create($$$) ...@@ -322,14 +322,38 @@ sub Create($$$)
print STDERR Dumper($argref); print STDERR Dumper($argref);
return undef; return undef;
} }
DBQueryWarn("insert into interfaces set ".
#
# Lock the tables to prevent concurrent creation
#
DBQueryWarn("lock tables interfaces write, ".
" interface_state write, ".
" wires write")
or return undef;
#
# See if we have a record; if we do, we can stop now. This is
# not actually correct, since creating a node is not atomic.
#
my $query_result =
DBQueryWarn("select node_id from interfaces ".
"where node_id='$node_id' and ".
" card='$card' and port='$port'");
if ($query_result->numrows) {
DBQueryWarn("unlock tables");
return Interface->Lookup($node_id, $card, $port);
}
if (!DBQueryWarn("insert into interfaces set ".
" node_id='$node_id', " . " node_id='$node_id', " .
" card=$card, port=$port, role='$ifrole', ". " card=$card, port=$port, role='$ifrole', ".
" mac='$MAC', IP='$IP', mask='$mask', " . " mac='$MAC', IP='$IP', mask='$mask', " .
" interface_type='$iftype', iface='$iface', " . " interface_type='$iftype', iface='$iface', " .
" current_speed='$max_speed', duplex='$duplex', ". " current_speed='$max_speed', duplex='$duplex', ".
" uuid='$uuid'") " uuid='$uuid'")) {
or return undef; DBQueryWarn("unlock tables");
return undef;
}
if (!DBQueryWarn("insert into interface_state set ". if (!DBQueryWarn("insert into interface_state set ".
" node_id='$node_id', " . " node_id='$node_id', " .
...@@ -337,6 +361,7 @@ sub Create($$$) ...@@ -337,6 +361,7 @@ sub Create($$$)
DBQueryWarn("delete from interfaces ". DBQueryWarn("delete from interfaces ".
"where node_id='$node_id' and card='$card' ". "where node_id='$node_id' and card='$card' ".
" and port='$port'"); " and port='$port'");
DBQueryWarn("unlock tables");
return undef; return undef;
} }
...@@ -359,9 +384,11 @@ sub Create($$$) ...@@ -359,9 +384,11 @@ sub Create($$$)
DBQueryWarn("delete from interfaces ". DBQueryWarn("delete from interfaces ".
"where node_id='$node_id' and card='$card' ". "where node_id='$node_id' and card='$card' ".
" and port='$port'"); " and port='$port'");
DBQueryWarn("unlock tables");
return undef; return undef;
} }
} }
DBQueryWarn("unlock tables");
return Interface->Lookup($node_id, $card, $port); return Interface->Lookup($node_id, $card, $port);
} }
......
...@@ -338,8 +338,11 @@ sub Create($$$$) ...@@ -338,8 +338,11 @@ sub Create($$$$)
# #
# Lock the tables to prevent concurrent creation # Lock the tables to prevent concurrent creation
# #
DBQueryWarn("lock tables nodes write, widearea_nodeinfo write") DBQueryWarn("lock tables nodes write, widearea_nodeinfo write, ".
or return -1; "node_hostkeys write, node_status write, ".
"node_utilization write, ".
"node_activity write, reserved write, node_auxtypes write")
or return undef;
# #
# Make up a priority (just used for sorting) # Make up a priority (just used for sorting)
...@@ -351,6 +354,17 @@ sub Create($$$$) ...@@ -351,6 +354,17 @@ sub Create($$$$)
$priority = 1; $priority = 1;
} }
#
# See if we have a record; if we do, we can stop now and get the
# existing record.
#
my $query_result =
DBQueryWarn("select node_id from nodes where node_id='$node_id'");
if ($query_result->numrows) {
DBQueryWarn("unlock tables");
return Node->Lookup($node_id);
}
if (!DBQueryWarn("insert into nodes set ". if (!DBQueryWarn("insert into nodes set ".
" node_id='$node_id', type='$type', " . " node_id='$node_id', type='$type', " .
" phys_nodeid='$node_id', role='$role', ". " phys_nodeid='$node_id', role='$role', ".
...@@ -378,7 +392,6 @@ sub Create($$$$) ...@@ -378,7 +392,6 @@ sub Create($$$$)
return undef; return undef;
} }
} }
DBQueryWarn("unlock tables");
if ($role eq "testnode") { if ($role eq "testnode") {
DBQueryWarn("insert into node_hostkeys (node_id) ". DBQueryWarn("insert into node_hostkeys (node_id) ".
...@@ -435,12 +448,14 @@ sub Create($$$$) ...@@ -435,12 +448,14 @@ sub Create($$$$)
"type='$vtype', count=$virtnode_capacity") "type='$vtype', count=$virtnode_capacity")
or goto bad; or goto bad;
} }
DBQueryWarn("unlock tables");
return Node->Lookup($node_id); return Node->Lookup($node_id);
bad: bad:
foreach my $table (@cleantables) { foreach my $table (@cleantables) {
DBQueryWarn("delete from $table where node_id='$node_id'"); DBQueryWarn("delete from $table where node_id='$node_id'");
} }
DBQueryWarn("unlock tables");
return undef; return undef;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment