diff --git a/db/libdb.pm.in b/db/libdb.pm.in index 5894a09ac9093e007b49c9551a6caaec9005a467..ae5caf9e2fbfa056e083c5905634010dec454150 100644 --- a/db/libdb.pm.in +++ b/db/libdb.pm.in @@ -87,7 +87,7 @@ use Exporter; TBDB_NODESTATE_ISUP TBDB_NODESTATE_REBOOTING TBDB_NODESTATE_REBOOTED TBDB_NODESTATE_SHUTDOWN TBDB_NODESTATE_BOOTING TBDB_NODESTATE_TBSETUP TBDB_NODESTATE_RELOADSETUP TBDB_NODESTATE_RELOADING - TBDB_NODESTATE_RELOADDONE TBDB_NODESTATE_UNKNOWN + TBDB_NODESTATE_RELOADDONE TBDB_NODESTATE_UNKNOWN TBDB_NODESTATE_PXEWAIT TBDB_NODEOPMODE_NORMAL TBDB_NODEOPMODE_DELAYING TBDB_NODEOPMODE_UNKNOWNOS TBDB_NODEOPMODE_RELOADING @@ -167,6 +167,7 @@ use Exporter; TBSiteVarExists TBGetSiteVar TBActivityReport GatherSwapStats GatherAssignStats + TBAvailablePCs TBDB_IFACEROLE_CONTROL TBDB_IFACEROLE_EXPERIMENT TBDB_IFACEROLE_JAIL TBDB_IFACEROLE_FAKE TBDB_IFACEROLE_OTHER @@ -448,6 +449,7 @@ sub TBDB_NODESTATE_RELOADSETUP() { "RELOADSETUP"; } sub TBDB_NODESTATE_RELOADING() { "RELOADING"; } sub TBDB_NODESTATE_RELOADDONE() { "RELOADDONE"; } sub TBDB_NODESTATE_UNKNOWN() { "UNKNOWN"; }; +sub TBDB_NODESTATE_PXEWAIT() { "PXEWAIT"; } sub TBDB_NODEOPMODE_ANY { "*"; } # A wildcard opmode sub TBDB_NODEOPMODE_NORMAL { "NORMAL"; } @@ -3430,6 +3432,35 @@ sub TBActivityReport($) "where node_id='$node'"); } +# +# Return the number of *available* nodes. These are nodes that are not +# reserved and in the proper state. See corresponding code in ptopgen +# and in the web server which reports the free node counts to users. +# +# usage: TBAvailablePCs(char *pid) +# Returns count. +# +sub TBAvailablePCs(;$) +{ + my ($pid) = @_; + my $clause = (defined($pid) ? "or p.pid='$pid'" : ""); + + my $query_result = + DBQueryFatal("select count(a.node_id) from nodes as a ". + "left join reserved as b on a.node_id=b.node_id ". + "left join node_types as nt on a.type=nt.type ". + "left join nodetypeXpid_permissions as p ". + " on a.type=p.type ". + "where b.node_id is null and a.role='testnode' and ". + " nt.class='pc' and ". + " (a.eventstate='" . TBDB_NODESTATE_ISUP . "' or ". + " a.eventstate='" . TBDB_NODESTATE_PXEWAIT . "') and". + " (p.pid is null $clause)"); + + my ($count) = $query_result->fetchrow_array(); + return $count; +} + # # Gather Swap stats. # diff --git a/tbsetup/assign_wrapper.in b/tbsetup/assign_wrapper.in index 27c390cba64ec2491d6daf391dbfd9f6d7279174..0f4ddea2a8a88020d323cee9f18b773109b5a395 100644 --- a/tbsetup/assign_wrapper.in +++ b/tbsetup/assign_wrapper.in @@ -519,13 +519,7 @@ sub RunAssign ($) TBDebugTimeStamp("ptopgen finished"); # Get number of nodes - my $numnodes_result = - DBQueryFatal("select a.node_id,a.type from" . - " nodes as a left join reserved as b" . - " on a.node_id=b.node_id" . - " where b.node_id is null" . - " and a.role='testnode' and a.type!='dnard'"); - $numnodes = $numnodes_result->numrows; + my $numnodes = TBAvailablePCs($pid); if ($numnodes < ($minimum_nodes - $reserved_pcount)) { fatal($WRAPPER_FAILED|$WRAPPER_FAILED_CANRECOVER, diff --git a/tbsetup/ptopgen.in b/tbsetup/ptopgen.in index 4bdec54209f646e9ece2fef4ab64faf47792e832..61edb28838d774784a20727e7a7c9bcb9742eba1 100644 --- a/tbsetup/ptopgen.in +++ b/tbsetup/ptopgen.in @@ -212,7 +212,9 @@ else { # # the ordinary free condition for a local node. -my $free_condition = "(b.node_id is null)"; +my $free_condition = "(b.node_id is null and ". + " (np.eventstate='" . TBDB_NODESTATE_ISUP . "' or ". + " np.eventstate='" . TBDB_NODESTATE_PXEWAIT . "')) "; # if the user has specified an exempt pid/eid, # then view any node which is reserved to that experiment as available. @@ -226,6 +228,7 @@ $result = "from nodes as a ". "left join reserved as b on a.node_id=b.node_id ". "left join reserved as m on a.phys_nodeid=m.node_id ". + "left join nodes as np on a.phys_nodeid=np.node_id ". "left join node_types as t on t.type=a.type ". "where $free_condition and ". " (a.role='testnode' and t.isremotenode=0)"); diff --git a/www/dbdefs.php3.in b/www/dbdefs.php3.in index eec19b2a630a74aeeb1ad1c22e21538cefbaa03f..4d58eb5efea9ce06e49aa85b2cd7211d10ff129b 100644 --- a/www/dbdefs.php3.in +++ b/www/dbdefs.php3.in @@ -138,6 +138,10 @@ define("TBDB_IFACEROLE_FAKE", "fake"); define("TBDB_IFACEROLE_GW", "gw"); define("TBDB_IFACEROLE_OTHER", "other"); +# Node states that the web page cares about. +define("TBDB_NODESTATE_ISUP", "ISUP"); +define("TBDB_NODESTATE_PXEWAIT", "PXEWAIT"); + # User Interface types define("TBDB_USER_INTERFACE_EMULAB", "emulab"); define("TBDB_USER_INTERFACE_PLAB", "plab"); @@ -1409,22 +1413,34 @@ function TBExpUidLastLogins($pid, $eid) } # -# Number of globally free PCs. +# Number of globally free PCs. See ptopgen and libdb for corresponding +# usage of the eventstate. A node is not really considered free for use +# unless it is also in the ISUP/PXEWAIT state. # function TBFreePCs() { $query_result = - DBQueryFatal("select a.node_id from nodes as a ". + DBQueryFatal("select count(a.node_id) from nodes as a ". "left join reserved as b on a.node_id=b.node_id ". "left join node_types as nt on a.type=nt.type ". "left join nodetypeXpid_permissions as p ". " on a.type=p.type ". "where b.node_id is null and a.role='testnode' ". - " and nt.class = 'pc' and p.pid is null"); - - return mysql_num_rows($query_result); + " and nt.class = 'pc' and p.pid is null and ". + " (a.eventstate='" . TBDB_NODESTATE_ISUP . "' or ". + " a.eventstate='" . TBDB_NODESTATE_PXEWAIT . "') and". + " (p.pid is null)"); + + if (mysql_num_rows($query_result) == 0) { + return 0; + } + $row = mysql_fetch_row($query_result); + return $row[0]; } +# +# Number of PCs a user has reserved to his experiments. +# function TBUserPCs($uid) { $query_result =