Commit af99c03f authored by Robert Ricci's avatar Robert Ricci

Move the max_concurrent restriction from being per-image to being

per-OS. Also, moved the functionality to check for this into libdb,
so we can call it from other places (like the batch daemon.)
parent 1fbc001c
......@@ -119,7 +119,9 @@ use Exporter;
ExpNodes DBDateTime DefaultImageID GroupLeader TBGroupUnixInfo
TBValidNodeLogType TBValidNodeName TBSetNodeLogEntry
TBSetSchedReload MapNodeOSID TBLockExp TBUnLockExp TBSetExpSwapTime
TBUnixGroupList TBOSID TBImageID TBdbfork VnameToNodeid TBExpLocked
TBUnixGroupList TBOSID TBOSMaxConcurrent TBOSCountInstances
TBOSLoadMaxOkay TBImageLoadMaxOkay TBImageID
TBdbfork VnameToNodeid TBExpLocked
TBIsNodeRemote TBExptSetLogFile TBExptClearLogFile TBExptGetLogFile
TBIsNodeVirtual TBControlNetIP TBPhysNodeID
TBExptOpenLogFile TBExptCloseLogFile TBExptCreateLogFile
......@@ -1577,6 +1579,121 @@ sub TBOSID ($$) {
return $row[0];
}
#
# Returns the maximum number of concurrent instantiations of an image.
#
# usage: TBOSMaxConcurrent(char *osid)
# returns >= 1 if there is a maximum number of concurrent instantiations
# returns undef if there is no limi
# returns 0 if not valid.
#
sub TBOSMaxConcurrent ($)
{
my($osid) = @_;
my $query_result =
DBQueryFatal("select max_concurrent from os_info where osid='$osid'");
if (! $query_result->num_rows) {
return 0;
}
my @row = $query_result->fetchrow_array();
return $row[0];
}
#
# Returns the number of nodes that are supposedly booting an OS. A list of
# nodes that should be excluded from this count can be given.
#
# usage: TBOSCountInstances(char *osid; char *nodeid ...)
# returns the number of nodes booting the OSID
#
sub TBOSCountInstances ($;@)
{
my($osid,@exclude) = @_;
my $nodelist = join(" or ",map("node_id='$_'",@exclude));
if (!@exclude) {
$nodelist = "0";
}
my $query_result = DBQueryFatal("select distinct node_id from partitions " .
"where osid='$osid' and !($nodelist)");
my $current_count = $query_result->num_rows();
return $current_count;
}
#
# Check whether or not it's permissible, given max_concurrent restrictions, to
# load an OSID onto a number of nodes - the nodes themselves can be passed, so
# that they do no count twice (once in the count of current loads, and once in
# the count of potential loads.)
#
# usage: TBOSLoadMaxOkay(char *osid, int node_count; char *nodeid ... )
# returns 1 if loading the given OS on the given number of nodes would
# not go over the max_concurrent limit for the OS
# returns 0 otherwise
#
sub TBOSLoadMaxOkay($$;@)
{
my($osid,$node_count,@nodes) = @_;
if (TBAdmin()) {
return 1;
}
my $max_instances = TBOSMaxConcurrent($osid);
if (!$max_instances) {
return 1;
}
my $current_instances = TBOSCountInstances($osid,@nodes);
if (($current_instances + $node_count) > $max_instances) {
return 0;
} else {
return 1;
}
}
#
#
# Check whether or not it's permissible, given max_concurrent restrictions, to
# load an image onto a number of nodes - simply checks all OSIDs on the image.
#
# usage: TBImageLoadMaxOkay(char *imageid, int node_count; char *nodeid ... )
# returns 1 if loading the given image on the given number of nodes
# would not go over the max_concurrent limit for any OS im the
# image
# returns 0 otherwise
#
sub TBImageLoadMaxOkay($$;@)
{
my($imageid,$node_count,@nodes) = @_;
my $query_result = DBQueryFatal("select part1_osid, part2_osid, " .
"part3_osid, part4_osid from images where imageid='$imageid'");
if ($query_result->num_rows() != 1) {
#
# XXX - Just pretend everything is OK, something else will presumably
# have to check the imageid anyway
#
return 1;
}
foreach my $OS ($query_result->fetchrow()) {
if ($OS && (!TBOSLoadMaxOkay($imageid,$node_count,@nodes))) {
return 0;
}
}
return 1;
}
#
# Map login (db uid) to a user_name and user_email.
#
......
......@@ -202,7 +202,7 @@ CREATE TABLE experiment_stats (
minlinks tinyint(3) unsigned default '0',
maxlinks tinyint(3) unsigned default '0',
batch tinyint(3) unsigned default '0',
PRIMARY KEY (eid,pid,idx)
PRIMARY KEY (eid,pid,idx),
KEY idx (idx)
) TYPE=MyISAM;
......@@ -389,7 +389,6 @@ CREATE TABLE images (
shared tinyint(4) NOT NULL default '0',
global tinyint(4) NOT NULL default '0',
updated datetime default NULL,
max_concurrent int(11) default NULL,
PRIMARY KEY (imagename,pid),
KEY imageid (imageid),
KEY gid (gid)
......@@ -840,6 +839,7 @@ CREATE TABLE os_info (
mustclean tinyint(4) NOT NULL default '1',
op_mode varchar(20) NOT NULL default 'MINIMAL',
nextosid varchar(35) default NULL,
max_concurrent int(11) default NULL,
PRIMARY KEY (osname,pid),
KEY osid (osid),
KEY OS (OS)
......
......@@ -416,3 +416,10 @@ last_net_act,last_cpu_act,last_ext_act);
alter table virt_lans add usevethiface tinyint(4) default '0'
after nobwshaping;
1.142: Made the max_concurrent value per-OS rather than per-image. If you have
any images with this restriction, you'll need to move it over to the
OS by hand, but I think the main database on boss is the only place with
any of these!
alter table os_info add column max_concurrent int(11) default NULL;
alter table images drop column max_concurrent;
......@@ -196,7 +196,6 @@ foreach my $node (@nodes) {
my $loadlen = $imageid_row{'loadlength'};
my $imagepath = $imageid_row{'path'};
my $defosid = $imageid_row{'default_osid'};
my $max_concurrent = $imageid_row{'max_concurrent'};
# Check for a few errors early!
if (!defined($imagepath)) {
......@@ -217,21 +216,10 @@ foreach my $node (@nodes) {
# XXX This could go outside the @nodes loop, but so could most of this
# stuff
#
if ($max_concurrent && !TBAdmin($UID)) {
# Exclude nodes in this load from the count
my $nodelist = join(" or ",map("node_id='$_'",@nodes));
if (!@nodes) {
$nodelist = "1";
}
my $count_result = DBQueryFatal("select count(*) from nodes where " .
"def_boot_osid='$defosid' and !($nodelist)");
my ($current_count) = $count_result->fetchrow();
if ($current_count + @nodes > $max_concurrent) {
die("*** $0:\n".
" This image is limited to $max_concurrent concurrent " .
" loads, and $current_count\nnodes are already running ".
" $defosid\n");
}
if (!TBImageLoadMaxOkay($imageid,scalar(@nodes),@nodes)) {
die("*** $0:\n".
" This image has a limited number of maximum concurrent " .
"instances\n");
}
#
......
......@@ -956,19 +956,20 @@ DBQueryFatal("INSERT INTO images ".
"(imagename, imageid, ezid, description, loadpart, loadlength, ".
" part" . "$bootpart" . "_osid, ".
" default_osid, path, pid, global, creator, created, ".
" max_concurrent, gid, shared) ".
" gid, shared) ".
"VALUES ".
" ('$imagename', '$imageid', 1, '$description', $loadpart, ".
" $loadlen, '$imageid', '$imageid', '$path', '$pid', $global, ".
" '$uid', now(), $max_concurrent, '$gid', $shared)");
" '$uid', now(), '$gid', $shared)");
DBQueryFatal("INSERT INTO os_info ".
"(osname, osid, ezid, description, OS, version, path, magic, ".
" osfeatures, pid, creator, shared, created, op_mode) ".
" osfeatures, pid, creator, shared, created, op_mode, ".
" max_concurrent) ".
"VALUES ".
" ('$imagename', '$imageid', 1, '$description', '$os_name', ".
" '$os_version', NULL, NULL, '$os_features', '$pid', ".
" '$uid', $global, now(), '$op_mode')");
" '$uid', $global, now(), '$op_mode', $max_concurrent)");
for ($i = 0; $i < count($mtypes_array); $i++) {
DBQueryFatal("REPLACE INTO osidtoimageid ".
......
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