Commit bed7c3ee authored by Leigh Stoller's avatar Leigh Stoller

libdb: Add TBIPtoNodeID utility function. Also some minor jail related

changes; add optinal jailflag argument to TBIsNodeVirtual, and add some
constants for assigning port ranges to jailed nodes.

newwanode: Allow reuse of existing node. So, if called with an IP that
already exists in the DB, reuse those records (nodes, interfaces,
reserved) rather than creating a new one. The web page makes sure that
the calling node has a valid IP (REMOTE_ADDR equals IP it gives us),
so it typically means an exiting node is being reinstalled (happening
with RON nodes right now!).
parent 4f0c3572
......@@ -92,6 +92,8 @@ use Exporter;
TBDB_TBCONTROL_RESET TBDB_TBCONTROL_RELOADDONE
TBDB_TBCONTROL_TIMEOUT TBDB_NO_STATE_TIMEOUT
TBDB_LOWVPORT TBDB_MAXVPORT TBDB_PORTRANGE
TBAdmin TBProjAccessCheck TBNodeAccessCheck TBOSIDAccessCheck
TBImageIDAccessCheck TBExptAccessCheck ExpLeader MarkNodeDown
SetNodeBootStatus OSFeatureSupported IsShelved NodeidToExp
......@@ -106,7 +108,7 @@ use Exporter;
TBExptOpenLogFile TBExptCloseLogFile TBExptCreateLogFile
TBNodeUpdateAccountsByPid TBNodeUpdateAccountsByType
TBSaveExpLogFiles TBExptWorkDir TBExptUserDir TBExptLogDir
TBExptDestroy
TBExptDestroy TBIPtoNodeID
TBDB_WIDEAREA_LOCALNODE
TBWideareaNodeID
......@@ -380,6 +382,17 @@ sub TBDB_WIDEAREA_LOCALNODE { "boss"; }
#
sub DBLIMIT_NSFILESIZE() { (1024 * 16); }
#
# Virtual nodes must operate within a restricted port range. The range
# is effective across all virtual nodes in the experiment. When an
# experiment is swapped in, allocate a subrange from this and setup
# all the vnodes to allocate from that range. We tell the user this
# range so this they can set up their programs to operate in that range.
#
sub TBDB_LOWVPORT() { 30000; }
sub TBDB_MAXVPORT() { 60000; }
sub TBDB_PORTRANGE() { 256; }
#
# Auth stuff.
#
......@@ -1789,18 +1802,18 @@ sub TBIsNodeRemote($)
}
#
# Is a node virtual (or "multiplexed").
# Is a node virtual (or "multiplexed"). Optionally return jailflag.
#
# usage TBIsNodeVirtual(char *node)
# usage TBIsNodeVirtual(char *node, int *jailed)
# Returns 1 if yes.
# Returns 0 if no.
#
sub TBIsNodeVirtual($)
sub TBIsNodeVirtual($;$)
{
my ($nodeid) = @_;
my ($nodeid, $jailed) = @_;
my $query_result =
DBQueryFatal("select isvirtnode from node_types as t ".
DBQueryFatal("select isvirtnode,n.jailflag from node_types as t ".
"left join nodes as n on t.type=n.type ".
"where n.node_id='$nodeid'");
......@@ -1809,6 +1822,9 @@ sub TBIsNodeVirtual($)
}
my @row = $query_result->fetchrow_array();
if (defined($jailed)) {
$$jailed = $row[1];
}
return($row[0]);
}
......@@ -2034,6 +2050,35 @@ sub TBControlNetIP($$)
return 0;
}
#
# Map network IP for a node to its nodeid
#
# usage TBIPtoNodeID(char *ip, char \*nodeid)
# Return 1 if success.
# Return 0 if error.
#
sub TBIPtoNodeID($$)
{
my ($ip, $pnodeid) = @_;
my $query_result =
DBQueryFatal("select n.node_id from interfaces as i ".
"left join nodes as n on n.node_id=i.node_id ".
"left join node_types as t ".
" on t.type=n.type and i.card=t.control_net ".
"where i.IP='$ip'");
if ($query_result->numrows == 0) {
return 0;
}
my @row = $query_result->fetchrow_array();
if (defined($row[0])) {
$$pnodeid = $row[0];
return 1;
}
return 0;
}
#
# Get the underlying physical node. Might be the same as the node if its
# not a virtual node.
......
......@@ -25,8 +25,6 @@ my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBLOGS = "@TBLOGSEMAIL@";
my $named_setup = "$TB/sbin/named_setup";
my $FIRSTIPPORT = 40000;
my $PERNODEPORTS= 256;
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/usr/site/bin';
......@@ -54,10 +52,15 @@ if ($UID != getpwnam("nobody") && !TBAdmin($UID)) {
my $nodetype;
my $nodeip;
my $fromweb = 0;
my $reuse = 0;
my $nickname;
my $nodename;
my $nodevtype;
my $nodevname;
my $pid;
my $eid;
my $nextid;
my $nextpri;
#
# Parse command arguments. Once we return from getopts, all that should be
......@@ -150,109 +153,142 @@ if (defined($nodevtype)) {
" No such nodevtype $nodevtype is defined in the DB!\n");
}
}
else {
#
# Create the virtual type name. Again, this is bogus.
#
if ($nodetype eq "pcwa") {
$nodevtype = "pcvwainet";
}
else {
$nodevtype = "pcvroninet";
}
}
#
# We need the next id and priority.
#
DBQueryFatal("lock tables nextfreenode write");
$query_result =
DBQueryFatal("select nextid,nextpri from nextfreenode ".
"where nodetype='$nodetype'");
if (!$query_result->numrows) {
fatal("nodetype $nodetype is not in the nextfreenode table!");
# Again, this is bogus.
#
if ($nodetype eq "pcwa") {
$pid = "emulab-ops";
$eid = "widearea-nodes";
}
else {
$pid = "ron";
$eid = "all";
}
my %row = $query_result->fetchhash();
my $nextid = $row{'nextid'};
my $nextpri = $row{'nextpri'};
DBQueryFatal("update nextfreenode ".
"set nextid=nextid+1,nextpri=nextpri+1 ".
"where nodetype='$nodetype'");
DBQueryFatal("unlock tables");
#
# Form a new node name! Bogus. need more DB state.
# Lets see if a known IP. If so we want to reuse the existing record.
#
if ($nodetype =~ /^pc(\w+)$/) {
$nodename = "${1}${nextid}";
if (TBIPtoNodeID($nodeip, \$nodename)) {
#
# We need the existing priority for creating the vnodes below.
#
$query_result =
DBQueryFatal("select priority from nodes where node_id='$nodename'");
my %row = $query_result->fetchhash();
$nextpri = $row{'priority'};
$reuse = 1;
}
else {
fatal("Could not determine a name from type for $nodetype!");
#
# We need the next id and priority.
#
DBQueryFatal("lock tables nextfreenode write");
$query_result =
DBQueryFatal("select nextid,nextpri from nextfreenode ".
"where nodetype='$nodetype'");
if (!$query_result->numrows) {
fatal("nodetype $nodetype is not in the nextfreenode table!");
}
my %row = $query_result->fetchhash();
$nextid = $row{'nextid'};
$nextpri = $row{'nextpri'};
DBQueryFatal("update nextfreenode ".
"set nextid=nextid+1,nextpri=nextpri+1 ".
"where nodetype='$nodetype'");
DBQueryFatal("unlock tables");
#
# Form a new node name! Bogus. need more DB state.
#
if ($nodetype =~ /^pc(\w+)$/) {
$nodename = "${1}${nextid}";
}
else {
fatal("Could not determine a name from type for $nodetype!");
}
}
if (!defined($nickname)) {
$nickname = $nodename;
}
#
# Create the virtual type name. Again, this is bogus.
# Enter the records
#
if (!defined($nodevtype)) {
if ($nodetype eq "pcwa") {
$nodevtype = "pcvwainet";
}
else {
$nodevtype = "pcvroninet";
}
if ($reuse) {
print "Reusing exiting record for $nodename. IP=$nodeip\n";
}
else {
print "Creating widearea node $nodename ...\n";
DBQueryFatal("insert into nodes ".
"(node_id, type, phys_nodeid, role, priority, ".
" status, op_mode, def_boot_osid) ".
"values ('$nodename', '$nodetype', '$nodename', ".
" 'testnode', $nextpri, 'down', 'NORMAL', ".
" '$defosid') ");
#
# Enter the records
#
print "Creating widearea node $nodename ...\n";
DBQueryFatal("insert into nodes ".
"(node_id, type, phys_nodeid, role, priority, ".
" status, op_mode, def_boot_osid) ".
"values ('$nodename', '$nodetype', '$nodename', ".
" 'testnode', $nextpri, 'down', 'NORMAL', '$defosid') ");
DBQueryFatal("insert into interfaces ".
"(node_id, card, port, IP, interface_type, iface) ".
"values ('$nodename', $control_net, 1, '$nodeip', ".
" 'fxp', 'eth0')");
DBQueryFatal("insert into reserved ".
"(node_id, pid, eid, rsrv_time, vname) ".
"values ('$nodename', '$pid', '$eid', now(), '$nickname')");
}
#
# Always create these. I'll kill off the old ones as needed for now.
#
for ($i = 1; $i < 9; $i++) {
my $priority = ($nextpri * 100) + $i;
$nodevname = "v${nodename}-${i}";
# Per vnode ports.
my $portlow = $FIRSTIPPORT + (($i - 1) * $PERNODEPORTS);
my $porthigh = $portlow + $PERNODEPORTS - 1;
if (TBValidNodeName($nodevname)) {
next;
}
print "Creating widearea virtual node $nodevname ...\n";
DBQueryFatal("insert into nodes ".
"(node_id, type, phys_nodeid, role, priority, ".
" status, op_mode, def_boot_osid, update_accounts, ".
" ipport_low, ipport_high) ".
" status, op_mode, def_boot_osid, update_accounts) ".
"values ('$nodevname', '$nodevtype', '$nodename', ".
" 'virtnode', $priority, 'down', 'NORMAL', ".
" '$defosid', 1, $portlow, $porthigh) ");
" '$defosid', 1) ");
}
DBQueryFatal("insert into interfaces ".
"(node_id, card, port, IP, interface_type, iface) ".
"values ('$nodename', $control_net, 1, '$nodeip', ".
" 'fxp', 'eth0')");
#
# Again, this is bogus.
# Lets log it.
#
my $pid;
my $eid;
if ($nodetype eq "pcwa") {
$pid = "emulab-ops";
$eid = "widearea-nodes";
}
my $subject;
my $message;
if ($reuse) {
$subject = "Existing WA node has reinstalled";
$message = "Existing WA node has been reinstalled";
}
else {
$pid = "ron";
$eid = "all";
$subject = "New WA node created";
$message = "New Wide Area node has been created";
}
DBQueryFatal("insert into reserved ".
"(node_id, pid, eid, rsrv_time, vname) ".
"values ('$nodename', '$pid', '$eid', now(), '$nickname')");
#
# Lets log it.
#
SENDMAIL($TBLOGS, "New WA node created",
"New Wide Area node has been created.\n".
SENDMAIL($TBLOGS, $subject,
"$message\n".
"\n".
"Type: $nodetype\n".
"Name: $nodename\n".
......
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