Commit a06d7439 authored by Leigh Stoller's avatar Leigh Stoller

Some refactoring and cleanup of OSinfo related things, for Protogeni.

parent 59fb170e
......@@ -160,7 +160,7 @@ use vars qw(@ISA @EXPORT);
TBAdmin TBOpsGuy TBProjAccessCheck TBNodeAccessCheck
TBExptAccessCheck MarkNodeDown
SetNodeBootStatus OSFeatureSupported NodeidToExp
SetNodeBootStatus NodeidToExp
ExpState
ExpNodes ExpNodeVnames ExpNodesOldReserved
DBDateTime DefaultImageID
......@@ -1129,34 +1129,6 @@ sub SetNodeBootStatus($$)
"where node_id='$node'");
}
#
# Check if a particular feature is supported by an OSID.
#
# usage: OSFeatureSupported(char *osid, char *feature)
# returns 1 if supported, 0 if not.
#
sub OSFeatureSupported($$) {
my($osid, $feature) = @_;
my $query_result =
DBQueryFatal("select osfeatures from os_info where osid='$osid'");
# Invalid OSID?
if ($query_result->numrows < 1) {
return 0;
}
my $osfeatures = $query_result->fetchrow_array();
if (defined($osfeatures)) {
foreach my $osfeature (split(',', $osfeatures)) {
if ($feature eq $osfeature) {
return 1;
}
}
}
return 0;
}
#
# Find out what osid a node will boot next time it comes up,
# Usually (but not always) the currently running OS as well.
......@@ -1320,19 +1292,15 @@ sub TBImageID ($$) {
# returns osid if its valid.
# returns 0 if not valid.
#
sub TBOSID ($$) {
my($pid, $osname) = @_;
sub TBOSID($$) {
my ($pid, $osname) = @_;
my $query_result =
DBQueryFatal("select osid from os_info ".
"where pid='$pid' and osname='$osname'");
if (! $query_result->num_rows) {
return 0;
}
require OSinfo;
my @row = $query_result->fetchrow_array();
return $row[0];
my $osinfo = OSinfo->Lookup($pid, $osname);
return 0
if (!defined($osinfo));
return $osinfo->osid();
}
#
......@@ -1345,14 +1313,12 @@ sub TBOSID ($$) {
sub TBOsidToPid ($$) {
my($osid, $ppid) = @_;
my $query_result =
DBQueryFatal("select pid from os_info where osid='$osid'");
require OSinfo;
if (! $query_result->num_rows) {
return 0;
}
my ($pid) = $query_result->fetchrow_array();
$$ppid = $pid;
my $osinfo = OSinfo->Lookup($osid);
return 0
if (!defined($osinfo));
$$ppid = $osinfo->pid();
return 1;
}
......@@ -1366,17 +1332,14 @@ sub TBOsidToPid ($$) {
#
sub TBOSMaxConcurrent ($)
{
my($osid) = @_;
my ($osid) = @_;
my $query_result =
DBQueryFatal("select max_concurrent from os_info where osid='$osid'");
if (! $query_result->num_rows) {
return 0;
}
require OSinfo;
my @row = $query_result->fetchrow_array();
return $row[0];
my $osinfo = OSinfo->Lookup($osid);
return 0
if (!defined($osinfo));
return $osinfo->max_concurrent();
}
#
......@@ -1389,17 +1352,14 @@ sub TBOSMaxConcurrent ($)
#
sub TBOSIDRebootWaittime ($)
{
my($osid) = @_;
my ($osid) = @_;
my $query_result =
DBQueryFatal("select reboot_waittime from os_info where osid='$osid'");
require OSinfo;
if (! $query_result->num_rows) {
return 0;
}
my @row = $query_result->fetchrow_array();
return $row[0];
my $osinfo = OSinfo->Lookup($osid);
return 0
if (!defined($osinfo));
return $osinfo->reboot_waittime();
}
#
......@@ -1439,83 +1399,26 @@ sub TBOSCountInstances ($;@)
sub TBResolveNextOSID($;$$)
{
my ($osid,$pid,$eid) = @_;
my $next_osid = $osid;
my $input_osid = $osid;
my $count = 0;
do {
#
# Just a guard to make sure we don't end up in a loop
#
if ($count++ > 10) {
warn "Resolving $input_osid: Circular reference\n";
}
my $experiment;
$osid = $next_osid;
my $result = DBQueryWarn("select nextosid from os_info where
osid='$osid';");
require OSinfo;
if ($result->num_rows() != 1) {
warn "Resolving $input_osid: Unable to fetch os_info for $osid!\n";
if (defined($pid) && defined($eid)) {
$experiment = Experiment->Lookup($pid, $eid);
if (! defined($experiment)) {
warn "TBResolveNextOSID: No such experiment $pid/$eid\n";
return undef;
}
($next_osid) = $result->fetchrow();
#
# See if we need to resolve using a map.
# Maps currently are only indexed by modification time;
# i.e., we look at the last modification time of the experiment to
# determine what OSID should be used.
#
# NOTE: mapping used to be done based on experiment *creation* time
# but that left no ability to "update" an experiment to use current
# images, at least short of creating a new experiment with the same
# ns file.
#
# next_osid used to be MAP:osid_map, but now its an integer field
# so just look for a 0 index, which is not a "valid" osid.
#
if (defined($next_osid) && $next_osid == 0) {
my $map = "osid_map";
my $timestr;
if (defined($pid) && defined($eid)) {
my $m_result =
DBQueryWarn("select e.expt_created, s.swapmod_last ".
"from experiments as e, experiment_stats as s ".
"where e.idx=s.exptidx and ".
"e.pid='$pid' and e.eid='$eid'");
if (!$m_result || $m_result->num_rows() == 0) {
warn "Resolving $input_osid: no experiment $pid/$eid!\n";
return undef;
}
my ($ctime,$mtime) = $m_result->fetchrow();
if (defined($mtime) && $mtime ne "") {
$timestr = "'$mtime'";
} else {
$timestr = "'$ctime'";
}
} else {
$timestr = "now()";
}
$result = DBQueryWarn("select nextosid from $map ".
"where osid='$osid' and ".
"$timestr between btime and etime");
if (!$result) {
warn "No such osid map $map!\n";
return undef;
}
if ($result->num_rows() == 0) {
warn "Resolving $input_osid: Unable to map $osid!\n";
return undef;
}
($next_osid) = $result->fetchrow();
}
} while ($next_osid);
return $osid;
}
my $osinfo = OSinfo->Lookup($osid);
if (! defined($osinfo)) {
warn "TBResolveNextOSID: No such osid $osid\n";
return undef;
}
my $nextosinfo = $osinfo->ResolveNextOSID($experiment);
return undef
if (!defined($nextosinfo));
return $nextosinfo->osid();
}
#
......@@ -3587,24 +3490,6 @@ sub TBSetNodeHistory($$$$$)
return $node->SetNodeHistory($op, $this_user, $experiment);
}
sub TBGetOSBootCmd($$$)
{
my ($osid, $role, $default_cmdline) = @_;
my $retval = $default_cmdline;
my $query_result =
DBQueryFatal("SELECT ob.boot_cmd_line FROM os_info as oi ".
"LEFT JOIN os_boot_cmd as ob on ob.OS=oi.OS and ".
" ob.version=oi.version ".
"WHERE oi.osid='$osid' and ob.role='$role'");
if ($query_result->num_rows == 1) {
($retval) = $query_result->fetchrow_array();
}
return $retval;
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# Copyright (c) 2000-2009 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -115,6 +115,7 @@ use Experiment;
use Node;
use NodeType;
use Lan;
use OSinfo;
use libadminctrl;
use libtblog;
use libtblog qw(*SOUT *SERR);
......@@ -409,24 +410,6 @@ sub nodetypeisdedicatedremote($) {
return 0;
}
#
# osids: Information from the os_info table from the DB, indexed by osid
#
my %osids = ();
sub osidpath($) { return $osids{$_[0]}->{"path"}; }
sub osidos($) { return $osids{$_[0]}->{"OS"}; }
sub osidhaspath($) { my $path = osidpath($_[0]);
return (defined $path) && ($path ne "")};
sub osidnextosid($) {
my $retval = $osids{$_[0]}->{"nextosid"};
if (!defined($retval)) {
$retval = $_[0];
}
return $retval;
}
#
# interface_capabilities: We need this to find out the bandwidths of the devices
# we actually have on the testbed. Index by interface type name.
......@@ -538,6 +521,7 @@ my $experiment_idx;
my $useprepass;
my $delaycap_override;
my $elabinelab = 0;
my $experiment;
#
# Notes on virtual interfaces.
......@@ -724,6 +708,66 @@ my $veth_id = 0;
# are inserted. This hash maintains the rtabids per vnode
my %vnode2rtabid = ();
#
# OSinfo lookups.
#
sub osidlookup($)
{
my $osid = $_[0];
my $osinfo = OSinfo->Lookup($osid);
if (!defined($osinfo)) {
tbwarn("No such OSID $osid\n");
return undef;
}
return $osinfo;
}
sub osidpath($)
{
my $osinfo = osidlookup($_[0]);
return (defined($osinfo) ? $osinfo->path() : undef);
}
sub osidos($)
{
my $osinfo = osidlookup($_[0]);
return (defined($osinfo) ? $osinfo->OS() : undef);
}
sub osidfeaturesupported($$)
{
my $osinfo = osidlookup($_[0]);
return (defined($osinfo) ? $osinfo->FeatureSupported($_[1]) : 0);
}
sub osidhaspath($)
{
my $path = osidpath($_[0]);
return (defined($path) && ($path ne ""));
}
sub osidnextosinfo($)
{
my $osinfo = osidlookup($_[0]);
return undef
if (!defined($osinfo));
return $osinfo
if (!defined($osinfo->nextosid()));
my $nextosinfo = $osinfo->ResolveNextOSID($experiment);
return undef
if (!defined($nextosinfo));
return $nextosinfo;
}
sub osidnextosid($)
{
my $nextosinfo = osidnextosinfo($_[0]);
return (defined($nextosinfo) ? $nextosinfo->osid() : undef);
}
sub osidbootcmd($$$)
{
my ($osid, $role, $default) = @_;
my $nextosinfo = osidnextosinfo($osid);
return undef
if (!defined($nextosinfo) ||
$nextosinfo->OSBootCmd($role, \$default) != 0);
return $default;
}
######################################################################
# Step 1 - Setup virtual topology
#
......@@ -761,7 +805,7 @@ my %vnode2rtabid = ();
# Slowly convert to using Experiment module.
my $experiment = Experiment->Lookup($pid, $eid);
$experiment = Experiment->Lookup($pid, $eid);
if (!defined($experiment)) {
fatal("Could not lookup experiment object!")
}
......@@ -3001,10 +3045,9 @@ sub InitPnode($$)
else {
$osid = nodejailosid($pnode);
}
my $cmdline = TBGetOSBootCmd(osidnextosid($osid),
"vnodehost",
"/kernel.jail");
my $cmdline = osidbootcmd($osid, "vnodehost", "/kernel.jail");
fatal("Unexpected error determining boot command line for $pnode")
if (!defined($cmdline));
DBQueryFatal("UPDATE nodes set def_boot_cmd_line='$cmdline'," .
" startstatus='none'," .
......@@ -3082,9 +3125,9 @@ sub InitPnode($$)
fatal("No OSID is defined for internal node $vname!")
if (!defined($osid));
$cmdline = TBGetOSBootCmd(osidnextosid($osid),
$cmdline_role,
$cmdline);
$cmdline = osidbootcmd($osid, $cmdline_role, $cmdline);
fatal("Unexpected error determining boot command line for $pnode")
if (!defined($cmdline));
DBQueryFatal("UPDATE nodes set ".
" def_boot_cmd_line='$cmdline'," .
......@@ -3117,18 +3160,16 @@ sub InitPnode($$)
# If the user hasn't overridden the command line, try to find a
# default for this OSID.
if (virtnodeneedslinkdelays($vnode)) {
$cmdline = TBGetOSBootCmd(osidnextosid($osid),
"linkdelay",
"");
$cmdline = osidbootcmd($osid, "linkdelay", "");
}
elsif (defined($inner_elab_role) &&
($inner_elab_role eq "boss" ||
$inner_elab_role eq "boss+router")) {
$cmdline = TBGetOSBootCmd(osidnextosid($osid),
"linkdelay",
"");
$cmdline = osidbootcmd($osid, "linkdelay", "");
}
}
fatal("Unexpected error determining boot command line for $pnode")
if (!defined($cmdline));
#
# NOTE: We no longer include tarballs and RPMs in this update, because
......@@ -3194,10 +3235,6 @@ my %porthigh = ();
sub TBExptSetPortRange {
my @nodelist = ();
my $newlow;
my $newhigh;
my $lastlow;
my $lasthigh;
#
# See if any virtual nodes. If not, no need to do anything since
......@@ -3222,51 +3259,9 @@ sub TBExptSetPortRange {
#
# Otherwise find a free slot in the table.
#
DBQueryFatal("lock tables ipport_ranges write");
my $range_result =
DBQueryFatal("select low,high from ipport_ranges order by low");
my ($newlow,$newhigh) = $experiment->SetPortRange($impotent);
if (!$range_result->num_rows) {
$newlow = TBDB_LOWVPORT;
}
else {
($lastlow, $lasthigh) = $range_result->fetchrow_array();
# A hole at the bottom of the range ...
if ($lastlow >= TBDB_LOWVPORT + TBDB_PORTRANGE) {
$newlow = TBDB_LOWVPORT;
}
# Else, find a free hole.
else {
while (my ($thislow,$thishigh) = $range_result->fetchrow_array()) {
if ($thislow != $lasthigh + 1 &&
$thislow - $lasthigh > TBDB_PORTRANGE) {
$newlow = $lasthigh + 1;
last;
}
$lasthigh = $thishigh;
}
}
}
if (!defined($newlow)) {
# No holes, tack onto the end.
$newlow = $lasthigh + 1;
}
if ($newlow >= TBDB_MAXVPORT) {
DBQueryFatal("unlock tables");
return -1;
}
$newhigh = $newlow + TBDB_PORTRANGE - 1;
if (! $impotent) {
DBQueryFatal("insert into ipport_ranges ".
" (exptidx, pid, eid, low, high) ".
"values ('$experiment_idx', ".
" '$pid', '$eid', $newlow, $newhigh)");
}
DBQueryFatal("unlock tables");
printdb "Setting ipport range to $newlow,$newhigh\n";
printdb "ipport range was set to $newlow,$newhigh\n";
#
# Now set the port range for those nodes hosting virtual nodes.
......@@ -3938,23 +3933,6 @@ sub LoadPhysInfo()
}
}
}
#
# Get paths from os_info, so that we can identify OSKit/MFS OSes, basically
# those which do not load a disk image
#
$query_result =
DBQueryFatal("select osid,path,nextosid,OS from os_info");
while (my ($osid, $path, $nextosid, $OS) = $query_result->fetchrow()) {
$osids{$osid} = {};
if ($path) {
$osids{$osid}->{"path"} = $path;
}
if (defined($nextosid)) {
$osids{$osid}->{"nextosid"} = TBResolveNextOSID($osid,$pid,$eid);
}
$osids{$osid}->{"OS"} = $OS;
}
}
sub interfacespeedmbps($$) {
return $interface_capabilities{$_[0]}->{$_[1] . "_defspeed"} / 1000.0;
......@@ -4761,14 +4739,14 @@ sub CreateTopFile()
if (!exists($osdoesmlink{$osid})) {
$osdoesmlink{$osid} =
OSFeatureSupported($osid, 'mlinks');
osidfeaturesupported($osid, 'mlinks');
$osdoesveth{$osid} =
OSFeatureSupported($osid, 'veths');
osidfeaturesupported($osid, 'veths');
$osdoesvlan{$osid} =
OSFeatureSupported($osid, 'vlans');
osidfeaturesupported($osid, 'vlans');
# Need this for phys nodes requesting lindelays.
$osdoeslinkdelays{$osid} =
OSFeatureSupported($osid, 'linkdelays');
osidfeaturesupported($osid, 'linkdelays');
}
} else {
# XXX If the user doesn't explicitly set an OS on a PC.
......@@ -5721,7 +5699,12 @@ sub nodejailosid($)
my $vnode = $vnodelist[0];
my $osid = virtnodeosid($vnode);
my $nextosid = osidnextosid($osid);
printdb "Mapping jail osid to $osid ($nextosid) on $pnode\n";
if (defined($nextosid)) {
printdb "Mapping jail osid to $osid ($nextosid) on $pnode\n";
}
else {
tbwarn("Could not map jail osid to real osid on $pnode\n");
}
return $nextosid;
}
......
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