]> xenbits.xensource.com Git - rumpuser-xen.git/commitdiff
rumprun, rumpconfig: Add support for setting guest environment.
authorMartin Lucina <martin@lucina.net>
Mon, 26 Jan 2015 11:40:11 +0000 (12:40 +0100)
committerMartin Lucina <martin@lucina.net>
Mon, 26 Jan 2015 11:40:11 +0000 (12:40 +0100)
Signed-off-by: Martin Lucina <martin@lucina.net>
app-tools/rumprun
rumpconfig.c
tests/hello/hello.c

index 2bdf6f34740160ee5f86088d23f0dc2d2de522c0..889bd57eb200cd377e495bd841a2f4f452678ab7 100755 (executable)
@@ -35,7 +35,7 @@ err() {
 
 usage() {
        cat <<EOM
-usage: rumprun STACK [ -ipd ] [ -D PORT ] [ -N NAME ] [ -M MEM ] [ -b BLKSPEC ] [ -n NETSPEC ] [ -- ] APP [ args ]
+usage: rumprun STACK [ -ipd ] [ -D PORT ] [ -N NAME ] [ -M MEM ] [ -b BLKSPEC ] [ -n NETSPEC ] [ -e VAR[=VALUE] ] [ -- ] APP [ args ]
     STACK is the rumprun stack to use. Only "xen" is currently supported
     APP is the rumprun application to start
     args will be passed to the application command line
@@ -45,6 +45,7 @@ usage: rumprun STACK [ -ipd ] [ -D PORT ] [ -N NAME ] [ -M MEM ] [ -b BLKSPEC ]
     -n NETSPEC configures a network interface, using one of:
        inet,dhcp - IPv4 with DHCP
        inet,static,ADDR/MASK[,GATEWAY] - IPv4 with static IP
+    -e set guest environment VAR to VALUE
     -i attaches to domain console on startup
     -p creates the domain but leaves it paused
     -d destroys the domain on poweroff
@@ -143,7 +144,7 @@ run_xen() {
        opt_name=
        opt_debug=
        sudo=''
-       while getopts "n:b:pidD:N:M:" opt; do
+       while getopts "n:b:e:pidD:N:M:" opt; do
                case "$opt" in
                        # -n: NETSPEC
                        n)
@@ -168,6 +169,21 @@ run_xen() {
                                        >>${xenstore}
                                bindex=$(expr $bindex + 1)
                                ;;
+                       # -e: Set guest environment variable.
+                       e)
+                               case "${OPTARG}" in
+                                       *=*)
+                                               key=${OPTARG%%=*}
+                                               value=${OPTARG#*=}
+                                               ;;
+                                       *)
+                                               key=${OPTARG}
+                                               value=
+                                               ;;
+                               esac
+                               [ -n "$key" ] || usage
+                               echo environ/${key} "${value}" >>${xenstore}
+                               ;;
                        # -p: Leave the domain paused after creation.
                        p)
                                opt_pause=1
@@ -237,8 +253,8 @@ EOM
        domid=$(${sudo} xl domid ${name})
        # Write provisioning information for domain to xenstore.
        prefix=/local/domain/${domid}/rumprun
-       cat ${xenstore} | while read line; do
-               xenstore-write ${prefix}/${line}
+       cat ${xenstore} | while read key value; do
+               xenstore-write "${prefix}/${key}" "${value}"
        done
        rm ${xenstore}
        # Attach debugger if requested.
index cec6a5def25013f257e906ab190fb94cdc732064..3c55fc44d8d7db9edd6e79a18100a12592d6ea95 100644 (file)
@@ -410,13 +410,66 @@ out:
        free(blk_fstype);
 }
 
+static int
+xs_read_environ(const char *name, char **value_out)
+{
+       char *value = NULL;
+       char buf[128];
+       char *xberr = NULL;
+       xenbus_transaction_t txn;
+       int xbretry = 0;
+
+       xberr = xenbus_transaction_start(&txn);
+       if (xberr) {
+               warnx("rumprun_config: xenbus_transaction_start() failed: %s",
+                       xberr);
+               return 1;
+       }
+       snprintf(buf, sizeof buf, "rumprun/environ/%s", name);
+       xberr = xenbus_read(txn, buf, &value);
+       if (xberr) {
+               warnx("rumprun_config: environ: read %s failed: %s",
+                       buf, xberr);
+               xenbus_transaction_end(txn, 0, &xbretry);
+               return 1;
+       }
+       xberr = xenbus_transaction_end(txn, 0, &xbretry);
+       if (xberr) {
+               warnx("rumprun_config: xenbus_transaction_end() failed: %s",
+                       xberr);
+               free(value);
+               return 1;
+       }
+       *value_out = value;
+       return 0;
+}
+
+static void
+rumprun_config_environ(const char *name)
+{
+       char *value = NULL;
+       int rv;
+
+       rv = xs_read_environ(name, &value);
+       if (rv != 0)
+               return;
+       if (setenv(name, value, 1) != 0) {
+               warnx("rumprun_config: setenv(%s) failed: %d", errno);
+               goto out;
+       }
+
+out:
+       free(value);
+}
+
 void
 _rumprun_config(void)
 {
        char *err = NULL;
        xenbus_transaction_t txn;
        char **netdevices = NULL,
-            **blkdevices = NULL;
+            **blkdevices = NULL,
+            **environ = NULL;
        int retry = 0,
            i;
 
@@ -438,6 +491,13 @@ _rumprun_config(void)
                xenbus_transaction_end(txn, 0, &retry);
                goto out_err;
        }
+       err = xenbus_ls(txn, "rumprun/environ", &environ);
+       if (err && strcmp(err, "ENOENT") != 0) {
+               warnx("rumprun_config: xenbus_ls(rumprun/environ) failed: %s",
+                               err);
+               xenbus_transaction_end(txn, 0, &retry);
+               goto out_err;
+       }
        err = xenbus_transaction_end(txn, 0, &retry);
        if (err) {
                warnx("rumprun_config: xenbus_transaction_end() failed: %s",
@@ -458,6 +518,13 @@ _rumprun_config(void)
                }
                free(blkdevices);
        }
+       if (environ) {
+               for(i = 0; environ[i]; i++) {
+                       rumprun_config_environ(environ[i]);
+                       free(environ[i]);
+               }
+               free(environ);
+       }
        return;
 
 out_err:
@@ -471,6 +538,11 @@ out_err:
                        free(blkdevices[i]);
                free(blkdevices);
        }
+       if (environ) {
+               for(i = 0; environ[i]; i++)
+                       free(environ[i]);
+               free(environ);
+       }
 }
 
 void
index 4859dbbc9858ebf5e46baf7603c820703923e148..3d97396d8d6370677d8484896944e1dcf3476f1b 100644 (file)
@@ -1,8 +1,13 @@
 #include <stdio.h>
+#include <stdlib.h>
 
 int main (int argc, char *argv[])
 {
-    printf ("Hello, world!\n");
+    char *world = getenv ("WORLD");
+    if (world)
+        printf ("Hello, %s!\n", world);
+    else
+        printf ("Hello, world!\n");
     printf ("Sleeping 5s...\n");
     sleep (5);
     printf ("Goodbye, world!\n");