From 448e377b862e1c0b1dc12f5abf3b5552c4799448 Mon Sep 17 00:00:00 2001 From: Mike Hibler <mike@flux.utah.edu> Date: Sat, 16 Dec 2006 00:05:32 +0000 Subject: [PATCH] Attempt to reconcile the definition of some program-agent environment variables on cluster and plab nodes. NODECNET (new) The fully-qualified (Emulab) name of the node this program agent is running on. This name resolves to the IP address of the control network interface of the node. NODECNETIP (new) The IP address of the control network interface. This address should not be advertised to, or used by, applications within an experiment as it will cause all traffic to flow over the control network rather than the experimental network. NODE The unqualified name of the node this program agent is running on. For nodes with experimental interfaces, this name resolves to the IP address of an experimental interface on the node. For nodes with more than one experimental interface, there is no guarantee which one it will resolve to. For nodes with no experimental interfaces, the name will not resolve. NODEIP The IP address of the experiment network interface that NODE resolves to. For nodes with no experimental interfaces, this variable will not be set. --- event/program-agent/program-agent.8 | 27 +++++++-- event/program-agent/program-agent.c | 87 ++++++++++++++++++++++++----- tmcd/common/config/rc.progagent | 2 +- tmcd/plab/rc.inplab | 15 +++-- www/tutorial/eventsystem.html | 28 ++++++++-- 5 files changed, 127 insertions(+), 32 deletions(-) diff --git a/event/program-agent/program-agent.8 b/event/program-agent/program-agent.8 index d2a07348cc..a2e543487d 100644 --- a/event/program-agent/program-agent.8 +++ b/event/program-agent/program-agent.8 @@ -1,6 +1,6 @@ .\" .\" EMULAB-COPYRIGHT -.\" Copyright (c) 2004, 2005 University of Utah and the Flux Group. +.\" Copyright (c) 2004, 2005, 2006 University of Utah and the Flux Group. .\" All rights reserved. .\" .TH PROGRAM-AGENT 8 "November 6, 2004" "Emulab" "Emulab Commands Manual" @@ -221,14 +221,29 @@ The project ID for the experiment this agent is running within. .B EID The experiment ID for the experiment this agent is running within. .TP -.B NODE -The name of the node this program agent is running on. Note that this is the -short name and +.B NODECNET +The fully-qualified name of the node this program agent is running on. +This name resolves to the IP address of the control network interface +of the node. +.TP +.B NODECNETIP +The IP address of the control network interface. +This address should .I not -the fully qualified host name that would refer to the control interface. +be advertised to, or used by, applications within an experiment as it will +cause all traffic to flow over the control network rather than the experimental +network. +.TP +.B NODE +The unqualified name of the node this program agent is running on. +For nodes with experimental interfaces, +this name resolves to the IP address of an experimental interface on the node. +For nodes with more than one experimental interface, there is no guarantee +which one it will resolve to. +For nodes with no experimental interfaces, the name will not resolve. .TP .B NODEIP -The IP address of the experiment network interface that the node name maps to. +The IP address of the experiment network interface that NODE resolves to. For nodes with no experimental interfaces, this variable will not be set. .TP set opt(\f(BIVAR\fR) \f(BIvalues\fR diff --git a/event/program-agent/program-agent.c b/event/program-agent/program-agent.c index 408c4d8045..fd3e0250f7 100644 --- a/event/program-agent/program-agent.c +++ b/event/program-agent/program-agent.c @@ -128,6 +128,12 @@ static char *pideid; */ static char *tokenfile; +/** + * Non-zero if this is a plab node + * XXX hack to allow adjustment of NODE environment variable + */ +static int isplab; + /** * Elvin error object. */ @@ -433,7 +439,7 @@ main(int argc, char **argv) progname = argv[0]; bzero(agentlist, sizeof(agentlist)); - while ((c = getopt(argc, argv, "hVdrs:p:l:u:i:e:c:k:f:o:v:t:")) != -1){ + while ((c = getopt(argc, argv, "hVdrs:p:l:u:i:e:c:k:f:o:v:t:P")) != -1){ switch (c) { case 'h': usage(progname); @@ -510,6 +516,9 @@ main(int argc, char **argv) if (strcmp(vnode, "ops") == 0) isops = 1; break; + case 'P': + isplab = 1; + break; default: usage(progname); } @@ -659,34 +668,82 @@ main(int argc, char **argv) setenv("HOME", pw->pw_dir, 1); setenv("PID", pid, 1); setenv("EID", eid, 1); + + /* + * Find the host's control net name/IP. This will always be the + * fully qualified name. Note that if we cannot resolve the FQN + * (which often happens on planetlab nodes) we dig the IP out of + * the Emulab DB info. + */ gethostname(buf, sizeof(buf)); - if ((idx = strchr(buf, '.')) != NULL) { - *idx = '\0'; - } - setenv("NODE", buf, 1); if ((he = gethostbyname(buf)) == NULL) { /* XXX should not be hardwired */ char *ipfile = "/var/emulab/boot/myip"; - warning("warning: cannot resolve hostname '%s' to obtain IP address," - " reading IP from %s instead\n", buf, ipfile); + warning("WARNING: cannot resolve hostname '%s'" + " to obtain IP address, reading IP from %s instead\n", + buf, ipfile); fp = fopen(ipfile, "r"); if (fp == NULL) - warning("warning: cannot get IP address for hostname '%s'," - " assuming no network links available\n", buf); + warning("WARNING: cannot get IP address for hostname '%s'," + " assuming no network links available\n", buf); else { - fgets(buf, sizeof(buf), fp); - (void) fclose(fp); - if ((idx = strchr(buf, '\n')) != NULL) - *idx = '\0'; - setenv("NODEIP", buf, 1); + char ipbuf[BUFSIZ]; + + fgets(ipbuf, sizeof(ipbuf), fp); + (void) fclose(fp); + if ((idx = strchr(ipbuf, '\n')) != NULL) + *idx = '\0'; + setenv("NODECNETIP", ipbuf, 1); } } else { struct in_addr ia; memcpy(&ia, he->h_addr, he->h_length); - setenv("NODEIP", inet_ntoa(ia), 1); + setenv("NODECNETIP", inet_ntoa(ia), 1); + } + + /* + * XXX for planetlab, hostname is the official hostname as opposed + * to the per-experiment Emulab alias. To be consistent, we want + * NODECNET (and hence NODE) to reflect the Emulab name. + */ + if (isplab) { + /* XXX should not be hardwired */ + char *alfile = "/var/emulab/boot/nickname"; + + fp = fopen(alfile, "r"); + if (fp != NULL) { + fgets(buf, sizeof(buf), fp); + (void) fclose(fp); + if ((idx = strchr(buf, '\n')) != NULL) { + *idx++ = '.'; + strncat(buf, OURDOMAIN, + sizeof(buf) - (idx - buf) - 1); + } + setenv("NODECNET", buf, 1); + } + } else + setenv("NODECNET", buf, 1); + + /* + * Now find "the default" experimental network interface by stripping + * the domain qualifier and looking that up. If the short name fails + * to resolve, we assume there are no experimental interfaces. + * + * XXX for backwards compat, we always set NODE even if it does not + * resolve. It might still be useful as a tag. + */ + if ((idx = strchr(buf, '.')) != NULL) { + *idx = '\0'; + } + setenv("NODE", buf, 1); + if ((he = gethostbyname(buf)) != NULL) { + struct in_addr ia; + + memcpy(&ia, he->h_addr, he->h_length); + setenv("NODEIP", inet_ntoa(ia), 1); } /* XXX Need to eval the ENV parts of the config file after we've diff --git a/tmcd/common/config/rc.progagent b/tmcd/common/config/rc.progagent index ada93d9480..e3e189da48 100755 --- a/tmcd/common/config/rc.progagent +++ b/tmcd/common/config/rc.progagent @@ -208,7 +208,7 @@ sub doboot() # this failure should not happen fatal("invalid format for plabconfig info"); } - system("$PAGENT -e $pid/$eid -s localhost -l $LOGFILE ". + system("$PAGENT -P -e $pid/$eid -s localhost -l $LOGFILE ". "-d -i $PIDFILE -k " . TMEVENTKEY() . " -c $CONFIG ". "-v $vname -r -p $elvind_port -t $TOKEN"); } diff --git a/tmcd/plab/rc.inplab b/tmcd/plab/rc.inplab index 3b654f1e96..962511cb11 100755 --- a/tmcd/plab/rc.inplab +++ b/tmcd/plab/rc.inplab @@ -7,6 +7,9 @@ use English; use Getopt::Std; +# XXX should not be hardwired +my $ELABDOMAIN = "emulab.net"; + # # This script is the plab vserver equiv of ../common/rc.bootsetup. It runs # inside the vserver and does a limited set of bootstrapping tasks. @@ -314,16 +317,20 @@ sub doplabconfig() "}\n\n"); # Make it look like it's in Emulab domain - # XXX This shouldn't be hardcoded - print RC "setconfigopt /etc/resolv.conf domain emulab.net\n"; - print RC "setconfigopt /etc/resolv.conf search emulab.net\n\n"; + print RC "setconfigopt /etc/resolv.conf domain $ELABDOMAIN\n"; + print RC "setconfigopt /etc/resolv.conf search $ELABDOMAIN\n\n"; # XXX make sure we can resolve our own name print RC "if ! ping -c 1 `hostname` >/dev/null 2>&1; then\n". " myip=`cat /var/emulab/boot/myip`\n". " myhn=`hostname`\n". " if [ -n \"\$myip\" -a -n \"\$myhn\" ]; then\n". - " setconfigopt /etc/hosts \$myip \$myhn\n". + " myal=\"\"\n". + " mynn=`cat /var/emulab/boot/nickname`\n". + " if [ -n \"\$mynn\" ]; then\n". + " myal=\"\$mynn.$ELABDOMAIN\"\n". + " fi\n". + " setconfigopt /etc/hosts \$myip \"\$myhn \$myal\"\n". " fi\n". "fi\n"; diff --git a/www/tutorial/eventsystem.html b/www/tutorial/eventsystem.html index ff39504fce..6c5e94b11e 100644 --- a/www/tutorial/eventsystem.html +++ b/www/tutorial/eventsystem.html @@ -398,18 +398,34 @@ directory containing Emulab specific binaries.</td> <td>The experiment ID for the experiment this agent is running within.</td> </tr> +<tr> +<td>NODECNET</td> +<td>The fully-qualified name of the node this program agent is running on. +This name resolves to the IP address of the control network interface +of the node.</td> +</tr> + +<tr> +<td>NODECNETIP</td> +<td>The IP address of the control network interface. +This address should <i>not</i> be advertised to, or used by, applications +within an experiment as it will cause all traffic to flow over the control +network rather than the experimental network. + <tr> <td>NODE</td> -<td>The name of the node this program agent is running on. Note that this is -the short name and <i>not</i> the fully qualified host name that would refer to -the control interface.</td> +<td>The unqualified name of the node this program agent is running on. +For nodes with experimental interfaces, +this name resolves to the IP address of an experimental interface on the node. +For nodes with more than one experimental interface, there is no guarantee +which one it will resolve to. +For nodes with no experimental interfaces, the name will not resolve.</td> </tr> <tr> <td>NODEIP</td> -<td>The IP address of the experiment network interface that the node name maps -to. For nodes with no experimental interfaces, this variable will not be -set.</td> +<td>The IP address of the experiment network interface that NODE resolves to. +For nodes with no experimental interfaces, this variable will not be set.</td> </tr> <tr> -- GitLab