diff --git a/db/Interface.pm.in b/db/Interface.pm.in index b62dfd7c787e0f6d31724e4afb82ebd352e085bf..21bb5257c0d54332534a0db5af1c464cad06a397 100644 --- a/db/Interface.pm.in +++ b/db/Interface.pm.in @@ -322,14 +322,38 @@ sub Create($$$) print STDERR Dumper($argref); 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', " . " card=$card, port=$port, role='$ifrole', ". " mac='$MAC', IP='$IP', mask='$mask', " . " interface_type='$iftype', iface='$iface', " . " current_speed='$max_speed', duplex='$duplex', ". - " uuid='$uuid'") - or return undef; + " uuid='$uuid'")) { + DBQueryWarn("unlock tables"); + return undef; + } if (!DBQueryWarn("insert into interface_state set ". " node_id='$node_id', " . @@ -337,6 +361,7 @@ sub Create($$$) DBQueryWarn("delete from interfaces ". "where node_id='$node_id' and card='$card' ". " and port='$port'"); + DBQueryWarn("unlock tables"); return undef; } @@ -359,9 +384,11 @@ sub Create($$$) DBQueryWarn("delete from interfaces ". "where node_id='$node_id' and card='$card' ". " and port='$port'"); + DBQueryWarn("unlock tables"); return undef; } } + DBQueryWarn("unlock tables"); return Interface->Lookup($node_id, $card, $port); } diff --git a/db/Node.pm.in b/db/Node.pm.in index a097bb9821e84ec7bb42ec4ddbc187222351dcde..863ea949fed1a0247858e1e42b6469f21aaf0d73 100644 --- a/db/Node.pm.in +++ b/db/Node.pm.in @@ -338,8 +338,11 @@ sub Create($$$$) # # Lock the tables to prevent concurrent creation # - DBQueryWarn("lock tables nodes write, widearea_nodeinfo write") - or return -1; + DBQueryWarn("lock tables nodes write, widearea_nodeinfo write, ". + "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) @@ -351,6 +354,17 @@ sub Create($$$$) $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 ". " node_id='$node_id', type='$type', " . " phys_nodeid='$node_id', role='$role', ". @@ -378,7 +392,6 @@ sub Create($$$$) return undef; } } - DBQueryWarn("unlock tables"); if ($role eq "testnode") { DBQueryWarn("insert into node_hostkeys (node_id) ". @@ -435,12 +448,14 @@ sub Create($$$$) "type='$vtype', count=$virtnode_capacity") or goto bad; } + DBQueryWarn("unlock tables"); return Node->Lookup($node_id); bad: foreach my $table (@cleantables) { DBQueryWarn("delete from $table where node_id='$node_id'"); } + DBQueryWarn("unlock tables"); return undef; }