Adding functionality to inherit capabilities and pass capabilities as arguments.
authorRaphael Fuchs <raphaelfuchs@student.ethz.ch>
Fri, 22 Jun 2012 09:04:57 +0000 (11:04 +0200)
committerRaphael Fuchs <raphaelfuchs@student.ethz.ch>
Fri, 22 Jun 2012 09:04:57 +0000 (11:04 +0200)
The function 'spawn_domain_with_fdcap' was used to spawn a domain and
inherit the file descriptors of the current domain. A similar inheritance
mechanism is needed for session capabilities.

To this end, the function was renamed to 'spawn_domain_with_caps'. It no longer
expects an fdcap as one of the arguments but a CNode containing all the
capabilities, that should be inherited by the newly spawned domain. The layout
of this CNode is convention an defined in include/barrelfish/spawn_client.h.
Spawnd knows about these capabilities and copies them to the appropriate places.
For example, if the fdcap is present in the inherit CNode, spawnd copies it to
the corresponding slot in the task CNode.

Moreover, we need the ability to pass arbitrary capabilities to a domain at
startup for example to start a device driver. Spawnd does not have to know about
these capabilities. Which capabilities are passed in which order is an agreement
between spawner and spawnee. To this end, this patch adds another CNode argument
to the function 'spawn_domain_with_caps'. If a domain wants to pass certain
capabilites to another domain it therefore creates a CNode and places the
capabilities in this Cnode and the passes this CNode as an argument to
'spawn_domain_with_caps'. Spawnd makes this CNode available to the spawnee in
the ARGCN slot of the root CNode as either a CNode (if spawner and spawnee are
on the same core) or a ForeignCNode (if on different cores).

The first method of inheriting capabilities and the second method of passing
capabilities are intentionally kept as two arguments because of the following
reasons:
* To account for the difference in their handling. Spawnd knows about the
  inherited capabilities and places each of them to appropriate places in the
  spawnee's CSpace. As a result they are available early-on, i.e. before the
  library initialization code for this domain runs.
* Putting both kinds of capabilities in a single flat CNode, would require
  recompilation of the whole OS after adding a new capability, that should be
  inherited.

13 files changed:
errors/errno.fugu
if/spawn.if
include/barrelfish/capabilities.h
include/barrelfish/spawn_client.h
include/barrelfish_kpi/init.h
include/spawndomain/spawndomain.h
lib/barrelfish/capabilities.c
lib/barrelfish/spawn_client.c
lib/spawndomain/spawn.c
usr/monitor/spawn.c
usr/net-test/net-test.c
usr/spawnd/service.c
usr/testdesc/testdesc.c

index c965e9e..fbbaa3b 100644 (file)
@@ -531,10 +531,21 @@ errors spawn SPAWN_ERR_ {
     failure ARGSPG_OVERFLOW     "Overflow in arguments page: too many arguments or environment variables",
     failure SERIALISE_VSPACE    "Error in serialising vspace data",
 
+    // setup inherited caps
+    failure SETUP_INHERITED_CAPS "Failure setup inherited caps",
+
+    // setup argument caps
+    failure SETUP_ARGCN          "Failure setup CNode containing caps passed as arguments",
+    failure COPY_ARGCN           "Error copying CNode containing caps passed as arguments",
+
     // setup file descriptors
     failure SETUP_FDCAP         "Failure setting up frame for copying file descriptors",
     failure FDSPG_OVERFLOW     "Overflow in file descriptors page: too many file descriptors",
 
+    // setup session id cap
+    failure SETUP_SIDCAP        "Failure setting up session capability",
+    failure COPY_SIDCAP         "Failure copying session id capability",
+
     // spawn_free
     failure DELETE_ROOTCN       "Failure deleting root CNode cap in parent",
     failure FREE_ROOTCN         "Failure freeing slot for root CNode cap in parent",
index ba95238..0990dac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011, ETH Zurich.
+ * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -9,14 +9,17 @@
 
 interface spawn "Interface to spawn domains" {
     typedef struct {
-       uint8 status;
+    uint8 status;
     } ps_entry;
 
     rpc spawn_domain(in string path, in char argvbuf[argvbytes], in char envbuf[envbytes],
                      out errval err, out domainid domain_id);
-    rpc spawn_domain_with_fdcap(in string path, in char argvbuf[argvbytes], 
-                               in char envbuf[envbytes], in cap fdcap,
-                                out errval err, out domainid domain_id);
+
+    rpc spawn_domain_with_caps(in string path, in char argvbuf[argvbytes],
+                               in char envbuf[envbytes], in cap inheritcn_cap,
+                               in cap argcn_cap, out errval err,
+                               out domainid domain_id);
+
     rpc use_local_memserv();
     rpc kill(in domainid domain_id, out errval err);
 
index a601852..3f4bff5 100644 (file)
@@ -54,8 +54,7 @@ errval_t endpoint_create(size_t buflen, struct capref *retcap,
 errval_t idcap_alloc(struct capref *dest);
 errval_t idcap_create(struct capref dest);
 
-errval_t build_cnoderef_from_capref(struct cnoderef *cnoder,
-                                    struct capref capr);
+errval_t cnode_build_cnoderef(struct cnoderef *cnoder, struct capref capr);
 
 /**
  * \brief Mint (Copy changing type-specific parameters) a capability
index a7c4857..814b9c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, ETH Zurich.
+ * Copyright (c) 2010, 2011, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -23,13 +23,19 @@ struct spawn_ps_entry {
 
 #define SPAWN_FLAGS_DEFAULT (0)
 
+/* Inherit CNode, layout convention #spawn_program_with_caps expects */
+#define INHERITCN_SLOT_FDSPAGE   1  ///< cap for inherited file descriptors
+#define INHERITCN_SLOT_SESSIONID 2  ///< Session ID domain belongs to
+
+
 /* XXX: utility function that doesn't really belong here */
 const char *cpu_type_to_archstr(enum cpu_type cpu_type);
 
-errval_t spawn_program_with_fdcap(coreid_t coreid, const char *path,
-                       char *const argv[], char *const envp[],
-                       struct capref fdcap,
-                       spawn_flags_t flags, domainid_t *ret_domainid);
+errval_t spawn_program_with_caps(coreid_t coreid, const char *path,
+                                 char *const argv[], char *const envp[],
+                                 struct capref inheritcn_cap,
+                                 struct capref argcn_cap, spawn_flags_t flags,
+                                 domainid_t *ret_domainid);
 errval_t spawn_program(coreid_t coreid, const char *path,
                        char *const argv[], char *const envp[],
                        spawn_flags_t flags, domainid_t *ret_domainid);
@@ -44,4 +50,9 @@ errval_t spawn_get_domain_list(uint8_t **domains, size_t *len);
 errval_t spawn_get_status(uint8_t domain, struct spawn_ps_entry *pse,
                           char **argbuf, size_t *arglen, errval_t *reterr);
 
+errval_t alloc_inheritcn_with_fdcap(struct capref *inheritcn_capp,
+                                    struct capref fdcap);
+errval_t alloc_inheritcn_with_sidcap(struct capref *inheritcn_capp,
+                                     struct capref sidcap);
+
 #endif // BARRELFISH_SPAWN_CLIENT_H
index 59f2aca..5348905 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
+ * Copyright (c) 2007, 2008, 2009, 2010, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -84,7 +84,8 @@
 #define ROOTCN_SLOT_SLOT_ALLOC0  7   ///< Root of slot alloc0
 #define ROOTCN_SLOT_SLOT_ALLOC1  8   ///< Root of slot alloc1
 #define ROOTCN_SLOT_SLOT_ALLOC2  9   ///< Root of slot alloc2
-#define ROOTCN_SLOTS_USER        10  ///< First free slot in root cnode for user
+#define ROOTCN_SLOT_ARGCN        10  ///< Argcn slot in root cnode
+#define ROOTCN_SLOTS_USER        11  ///< First free slot in root cnode for user
 
 /* Size of CNodes in Root CNode if not the default size */
 #define SLOT_ALLOC_CNODE_BITS   (DEFAULT_CNODE_BITS * 2)
 #define TASKCN_SLOT_TRACEBUF    9   ///< Trace buffer cap in task cnode
 #define TASKCN_SLOT_ARGSPAGE    10  ///< ?
 #define TASKCN_SLOT_MON_URPC    11  ///< Frame cap for urpc comm.
-/* slot 12 is free */
-#define TASKCN_SLOT_FDSPAGE     13  ///< cap for performance monitoring
+#define TASKCN_SLOT_SESSIONID   12  ///< Session ID domain belongs to
+#define TASKCN_SLOT_FDSPAGE     13  ///< cap for inherited file descriptors
 #define TASKCN_SLOT_PERF_MON    14  ///< cap for performance monitoring
 #define TASKCN_SLOTS_USER       15  ///< First free slot in taskcn for user
 
index a47b244..327916b 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
+ * Copyright (c) 2007, 2008, 2009, 2010, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -34,7 +34,6 @@ struct spawninfo {
     struct capref      dcb __attribute__ ((aligned(4)));
     struct capref      argspg __attribute__ ((aligned(4)));
     struct capref      vtree __attribute__ ((aligned(4)));
-    struct capref   fdcap __attribute__ ((aligned(4)));
 
     // Slot (in segcn) from where elfload_allocate should allocate frames from
     cslot_t elfload_slot;
@@ -67,7 +66,7 @@ errval_t spawn_load_image(struct spawninfo *si, lvaddr_t binary,
                           size_t binary_size, enum cpu_type type,
                           const char *name, coreid_t coreid,
                           char *const argv[], char *const envp[],
-                          struct capref fdcap);
+                          struct capref inheritcn_cap, struct capref argcn_cap);
 errval_t spawn_run(struct spawninfo *si);
 errval_t spawn_free(struct spawninfo *si);
 
index 7fc9e30..f2ab35f 100644 (file)
@@ -734,7 +734,7 @@ errval_t idcap_create(struct capref dest)
  * \param cnoder Pointer to a cnoderef struct, fill-in by function.
  * \param capr   Capref to a CNode capability.
  */
-errval_t build_cnoderef_from_capref(struct cnoderef *cnoder, struct capref capr)
+errval_t cnode_build_cnoderef(struct cnoderef *cnoder, struct capref capr)
 {
     struct capability cap;
     errval_t err = debug_cap_identify(capr, &cap);
@@ -743,7 +743,7 @@ errval_t build_cnoderef_from_capref(struct cnoderef *cnoder, struct capref capr)
     }
 
     if (cap.type != ObjType_CNode) {
-        return LIB_ERR_NOT_A_CNODE;
+        return LIB_ERR_NOT_CNODE;
     }
 
     cnoder->address = get_cap_addr(capr);
index 582b0b5..fdd6cc6 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (c) 2010, 2011, ETH Zurich.
+ * Copyright (c) 2010, 2011, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -116,21 +116,25 @@ static errval_t bind_client(coreid_t coreid)
 /**
  * \brief Request the spawn daemon on a specific core to spawn a program
  *
- * \param coreid Core ID on which to spawn the program
- * \param path   Absolute path in the file system to an executable image
- *                        suitable for the given core
- * \param argv   Command-line arguments, NULL-terminated
- * \param envp   Optional environment, NULL-terminated (pass NULL to inherit)
- * \param fdcap  A cap to a file descriptor region to pass through
- * \param flags  Flags to spawn
- * \param ret_domainid If non-NULL, filled in with domain ID of program
+ * \param coreid        Core ID on which to spawn the program
+ * \param path          Absolute path in the file system to an executable image
+ *                      suitable for the given core
+ * \param argv          Command-line arguments, NULL-terminated
+ * \param envp          Optional environment, NULL-terminated
+ *                      (pass NULL to inherit)
+ * \param inheritcn_cap Cap to a CNode containing capabilities to be inherited
+ * \param argcn_cap     Cap to a CNode containing capabilities passed as
+ *                      arguments
+ * \param flags         Flags to spawn
+ * \param ret_domainid  If non-NULL, filled in with domain ID of program
  *
  * \bug flags are currently ignored
  */
-errval_t spawn_program_with_fdcap(coreid_t coreid, const char *path,
-                             char *const argv[], char *const envp[],
-                             struct capref fdcap,
-                             spawn_flags_t flags, domainid_t *ret_domainid)
+errval_t spawn_program_with_caps(coreid_t coreid, const char *path,
+                                 char *const argv[], char *const envp[],
+                                 struct capref inheritcn_cap,
+                                 struct capref argcn_cap, spawn_flags_t flags,
+                                 domainid_t *ret_domainid)
 {
     struct spawn_rpc_client *cl;
     errval_t err, msgerr;
@@ -234,15 +238,14 @@ errval_t spawn_program_with_fdcap(coreid_t coreid, const char *path,
         path = pathbuf;
     }
 
-    if (capref_is_null(fdcap)) {
-        err = cl->vtbl.spawn_domain(cl, path, argstr, argstrlen, 
+    if (capref_is_null(inheritcn_cap) && capref_is_null(argcn_cap)) {
+        err = cl->vtbl.spawn_domain(cl, path, argstr, argstrlen,
                                     envstr, envstrlen,
                                     &msgerr, &domain_id);
     } else {
-        err = cl->vtbl.spawn_domain_with_fdcap(cl, path, argstr, argstrlen, 
-                                               envstr, envstrlen,
-                                               fdcap, 
-                                               &msgerr, &domain_id);
+        err = cl->vtbl.spawn_domain_with_caps(cl, path, argstr, argstrlen,
+                                              envstr, envstrlen, inheritcn_cap,
+                                              argcn_cap, &msgerr, &domain_id);
     }
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "error sending spawn request");
@@ -257,6 +260,7 @@ errval_t spawn_program_with_fdcap(coreid_t coreid, const char *path,
     return msgerr;
 }
 
+
 /**
  * \brief Request the spawn daemon on a specific core to spawn a program
  *
@@ -274,8 +278,8 @@ errval_t spawn_program(coreid_t coreid, const char *path,
                              char *const argv[], char *const envp[],
                              spawn_flags_t flags, domainid_t *ret_domainid)
 {
-    return spawn_program_with_fdcap(coreid, path, argv, envp, NULL_CAP, 
-                                    flags, ret_domainid);
+    return spawn_program_with_caps(coreid, path, argv, envp, NULL_CAP,
+                                   NULL_CAP, flags, ret_domainid);
 }    
 
 
@@ -460,3 +464,76 @@ errval_t spawn_get_status(uint8_t domain, struct spawn_ps_entry *pse,
 
     return SYS_ERR_OK;
 }
+
+/**
+ * \brief Utility function to create an inherit cnode and copy fdcap into it.
+ *
+ * \param inheritcn_capp Pointer to capref, filled-in with location of inheritcn
+ *                       capability.
+ * \param fdcap          fdcap to copy into inherit cnode.
+ */
+errval_t alloc_inheritcn_with_fdcap(struct capref *inheritcn_capp,
+                                    struct capref fdcap)
+{
+    errval_t err;
+
+    // construct inherit CNode
+    struct cnoderef inheritcn;
+    err = cnode_create(inheritcn_capp, &inheritcn, DEFAULT_CNODE_SLOTS, NULL);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    if (capref_is_null(fdcap)) {
+        return SYS_ERR_OK;
+    }
+
+    // copy fdcap to inherit Cnode
+    struct capref dest = {
+        .cnode = inheritcn,
+        .slot  = INHERITCN_SLOT_FDSPAGE
+    };
+    err = cap_copy(dest, fdcap);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * \brief Utility function to create an inherit cnode and copy session
+ *        capability into it.
+ *
+ * \param inheritcn_capp Pointer to capref, filled-in with location of inheritcn
+ *                       capability.
+ * \param sidcap         sidcap to copy into inherit cnode.
+ */
+errval_t alloc_inheritcn_with_sidcap(struct capref *inheritcn_capp,
+                                    struct capref sidcap)
+{
+    errval_t err;
+
+    // construct inherit CNode
+    struct cnoderef inheritcn;
+    err = cnode_create(inheritcn_capp, &inheritcn, DEFAULT_CNODE_SLOTS, NULL);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    if (capref_is_null(sidcap)) {
+        return SYS_ERR_OK;
+    }
+
+    // copy fdcap to inherit Cnode
+    struct capref dest = {
+        .cnode = inheritcn,
+        .slot  = INHERITCN_SLOT_SESSIONID
+    };
+    err = cap_copy(dest, sidcap);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
index 0daef0a..46b7f2f 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011, ETH Zurich.
+ * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -18,6 +18,7 @@
 #include <barrelfish/barrelfish.h>
 #include <spawndomain/spawndomain.h>
 #include <barrelfish/dispatcher_arch.h>
+#include <barrelfish/spawn_client.h>
 #include <barrelfish_kpi/domain_params.h>
 #include <trace/trace.h>
 #include "spawn.h"
@@ -539,43 +540,129 @@ static errval_t spawn_setup_env(struct spawninfo *si,
     return SYS_ERR_OK;
 }
 
-static errval_t spawn_setup_fdcap(struct spawninfo *si, struct capref fdcap)
+static errval_t spawn_setup_fdcap(struct spawninfo *si,
+                                  struct cnoderef inheritcn)
 {
     errval_t err;
 
-    if (capref_is_null(fdcap)) {
+    struct capref src;
+    src.cnode = inheritcn;
+    src.slot  = INHERITCN_SLOT_FDSPAGE; 
+
+    // Create frame (actually multiple pages) for fds
+    struct capref dest;
+    dest.cnode = si->taskcn;
+    dest.slot  = TASKCN_SLOT_FDSPAGE;
+
+    err = cap_copy(dest, src);
+    if (err_no(err) == SYS_ERR_SOURCE_CAP_LOOKUP) {
+        // there was no fdcap to inherit, continue
         return SYS_ERR_OK;
+    } else if (err_is_fail(err)) {
+        return err_push(err, SPAWN_ERR_COPY_FDCAP);
     }
 
-    // Create frame (actually multiple pages) for fds
-    si->fdcap.cnode = si->taskcn;
-    si->fdcap.slot  = TASKCN_SLOT_FDSPAGE;
+    return SYS_ERR_OK;
+}
 
-    err = cap_copy(si->fdcap, fdcap);
+static errval_t spawn_setup_sidcap(struct spawninfo *si,
+                                   struct cnoderef inheritcn)
+{
+    errval_t err;
+
+    struct capref src;
+    src.cnode = inheritcn;
+    src.slot  = INHERITCN_SLOT_SESSIONID;
+
+    struct capref dest;
+    dest.cnode = si->taskcn;
+    dest.slot  = TASKCN_SLOT_SESSIONID;
+
+    err = cap_copy(dest, src);
+    if (err_no(err) == SYS_ERR_SOURCE_CAP_LOOKUP) {
+        // there was no sidcap to inherit, continue
+        return SYS_ERR_OK;
+    } else if (err_is_fail(err)) {
+        return err_push(err, SPAWN_ERR_COPY_SIDCAP);
+    }
+
+    return SYS_ERR_OK;
+}
+
+static errval_t spawn_setup_inherited_caps(struct spawninfo *si,
+                                           struct capref inheritcn_cap)
+{
+    errval_t err;
+    struct cnoderef inheritcn;
+
+    if (capref_is_null(inheritcn_cap)) {
+        return SYS_ERR_OK;
+    }
+
+    err = cnode_build_cnoderef(&inheritcn, inheritcn_cap);
     if (err_is_fail(err)) {
-        return err_push(err, SPAWN_ERR_COPY_FDCAP);
+        return err;
+    }
+
+    /* Copy the file descriptor frame cap over */
+    err = spawn_setup_fdcap(si, inheritcn);
+    if (err_is_fail(err)) {
+        return err_push(err, SPAWN_ERR_SETUP_FDCAP);
+    }
+
+    /* Copy the session capability over */
+    err = spawn_setup_sidcap(si, inheritcn);
+    if (err_is_fail(err)) {
+        return err_push(err, SPAWN_ERR_SETUP_SIDCAP);
     }
 
     return SYS_ERR_OK;
 }
 
+static errval_t spawn_setup_argcn(struct spawninfo *si,
+                                  struct capref argumentcn_cap)
+{
+    errval_t err;
+
+    if (capref_is_null(argumentcn_cap)) {
+        return SYS_ERR_OK;
+    }
+
+    struct capref dest = {
+        .cnode = si->rootcn,
+        .slot  = ROOTCN_SLOT_ARGCN
+    };
+
+    err = cap_copy(dest, argumentcn_cap);
+    if (err_is_fail(err)) {
+        return err_push(err, SPAWN_ERR_COPY_ARGCN);
+    }
+
+    return SYS_ERR_OK;
+}
+
+
 /**
  * \brief Load an image
  *
- * \param si     Struct used by the library
- * \param binary The image to load
- * \param type   The type of arch to load for
- * \param name   Name of the image required only to place it in disp struct
- * \param coreid Coreid to load for, required only to place it in disp struct
- * \param argv   Command-line arguments, NULL-terminated
- * \param envp   Environment, NULL-terminated
- * \param fdcap  Frame capability to file descriptor region
+ * \param si            Struct used by the library
+ * \param binary        The image to load
+ * \param type          The type of arch to load for
+ * \param name          Name of the image required only to place it in disp
+ *                      struct
+ * \param coreid        Coreid to load for, required only to place it in disp
+ *                      struct
+ * \param argv          Command-line arguments, NULL-terminated
+ * \param envp          Environment, NULL-terminated
+ * \param inheritcn_cap Cap to a CNode containing capabilities to be inherited
+ * \param argcn_cap     Cap to a CNode containing capabilities passed as
+ *                      arguments
  */
 errval_t spawn_load_image(struct spawninfo *si, lvaddr_t binary,
                           size_t binary_size, enum cpu_type type,
                           const char *name, coreid_t coreid,
                           char *const argv[], char *const envp[],
-                          struct capref fdcap)
+                          struct capref inheritcn_cap, struct capref argcn_cap)
 {
     errval_t err;
 
@@ -607,12 +694,18 @@ errval_t spawn_load_image(struct spawninfo *si, lvaddr_t binary,
         return err_push(err, SPAWN_ERR_SETUP_DISPATCHER);
     }
 
-    /* Copy the file descriptor frame cap over */
-    err = spawn_setup_fdcap(si, fdcap);
+    /* Setup inherited caps */
+    err = spawn_setup_inherited_caps(si, inheritcn_cap);
     if (err_is_fail(err)) {
-        return err_push(err, SPAWN_ERR_SETUP_FDCAP);
+        return err_push(err, SPAWN_ERR_SETUP_INHERITED_CAPS);
     }
 
+    /* Setup argument caps */
+    err = spawn_setup_argcn(si, argcn_cap);
+    if (err_is_fail(err)) {
+        return err_push(err, SPAWN_ERR_SETUP_ARGCN);
+    }
     /* Setup cmdline args */
     err = spawn_setup_env(si, argv, envp);
     if (err_is_fail(err)) {
index c29a359..499afbf 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011, ETH Zurich.
+ * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -147,7 +147,7 @@ static errval_t spawn_image_with_args(const char *name, void *image,
     printf("Spawning %s on core %d\n", name, my_core_id);
 
     err = spawn_load_image(&si, (lvaddr_t)image, imagelen, CURRENT_CPU_TYPE,
-                           name, my_core_id, argv, envp, NULL_CAP);
+                           name, my_core_id, argv, envp, NULL_CAP, NULL_CAP);
     if (err_is_fail(err)) {
         return err_push(err, SPAWN_ERR_LOAD);
     }
index 165dbcc..cbe40cd 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (c) 2010, ETH Zurich.
+ * Copyright (c) 2010, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -48,12 +48,18 @@ static errval_t spawn_child(int rfd)
     struct capref fdcap;
 
     err = spawn_setup_fds(&fdcap, rfd);
-    if(err_is_fail(err)) {
+    if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "spawn_setup_fds");
     }
 
-    err = spawn_program_with_fdcap(core, argv[0], argv, NULL, fdcap,
-                                   SPAWN_NEW_DOMAIN, &new_domain);
+    struct capref inheritcn_cap;
+    err = alloc_inheritcn_with_fdcap(&inheritcn_cap, fdcap);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "failed to setup inheritcn");
+    }
+
+    err = spawn_program_with_caps(core, argv[0], argv, NULL, inheritcn_cap,
+                                  NULL_CAP, SPAWN_NEW_DOMAIN, &new_domain);
 
     if (err_is_fail(err)) {
         DEBUG_ERR(err, "failed spawn on core %d", core);
index 33bf224..7dd1560 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (c) 2010-2011, ETH Zurich.
+ * Copyright (c) 2010, 2011, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -31,7 +31,8 @@
 
 static errval_t spawn(char *path, char *const argv[], char *argbuf,
                       size_t argbytes, char *const envp[], 
-                      struct capref fdcap, domainid_t *domainid)
+                      struct capref inheritcn_cap, struct capref argcn_cap,
+                      domainid_t *domainid)
 {
     errval_t err, msgerr;
 
@@ -88,7 +89,8 @@ static errval_t spawn(char *path, char *const argv[], char *argbuf,
     /* spawn the image */
     struct spawninfo si;
     err = spawn_load_image(&si, (lvaddr_t)image, info.size, CURRENT_CPU_TYPE,
-                           name, my_core_id, argv, envp, fdcap);
+                           name, my_core_id, argv, envp, inheritcn_cap,
+                           argcn_cap);
     if (err_is_fail(err)) {
         free(image);
         return err;
@@ -288,10 +290,11 @@ static errval_t spawn_reply(struct spawn_binding *b, errval_t rerr,
 }
 
 
-static void spawn_with_fdcap_handler(struct spawn_binding *b, char *path, 
-                                     char *argbuf, size_t argbytes, 
-                                     char *envbuf, size_t envbytes,
-                                     struct capref fdcap)
+static void spawn_with_caps_handler(struct spawn_binding *b, char *path,
+                                    char *argbuf, size_t argbytes,
+                                    char *envbuf, size_t envbytes,
+                                    struct capref inheritcn_cap,
+                                    struct capref argcn_cap)
 {
     errval_t err;
     domainid_t domainid = 0;
@@ -330,17 +333,23 @@ static void spawn_with_fdcap_handler(struct spawn_binding *b, char *path,
 
     vfs_path_normalise(path);
 
-    err = spawn(path, argv, argbuf, argbytes, envp, fdcap, &domainid);
-    if (!capref_is_null(fdcap)) {
+    err = spawn(path, argv, argbuf, argbytes, envp, inheritcn_cap, argcn_cap,
+                &domainid);
+    if (!capref_is_null(inheritcn_cap)) {
         errval_t err2;
-        err2 = cap_delete(fdcap);
+        err2 = cap_delete(inheritcn_cap);
+        assert(err_is_ok(err2));
+    }
+    if (!capref_is_null(argcn_cap)) {
+        errval_t err2;
+        err2 = cap_delete(argcn_cap);
         assert(err_is_ok(err2));
     }
 
  finish:
     if(err_is_fail(err)) {
         free(argbuf);
-       DEBUG_ERR(err, "spawn");
+        DEBUG_ERR(err, "spawn");
     }
 
     err = spawn_reply(b, err, domainid);
@@ -358,8 +367,8 @@ static void spawn_with_fdcap_handler(struct spawn_binding *b, char *path,
 static void spawn_handler(struct spawn_binding *b, char *path, char *argbuf,
                           size_t argbytes, char *envbuf, size_t envbytes)
 {
-    spawn_with_fdcap_handler(b, path, argbuf, argbytes, envbuf, envbytes,
-                             NULL_CAP);
+    spawn_with_caps_handler(b, path, argbuf, argbytes, envbuf, envbytes,
+                            NULL_CAP, NULL_CAP);
 }
 
 /**
@@ -544,7 +553,7 @@ static void status_handler(struct spawn_binding *b, domainid_t domainid)
 
 static struct spawn_rx_vtbl rx_vtbl = {
     .spawn_domain_call = spawn_handler,
-    .spawn_domain_with_fdcap_call = spawn_with_fdcap_handler,
+    .spawn_domain_with_caps_call = spawn_with_caps_handler,
     .use_local_memserv_call = use_local_memserv_handler,
     .kill_call = kill_handler,
     .exit_call = exit_handler,
index ed8acf0..87c5b20 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (c) 2010, ETH Zurich.
+ * Copyright (c) 2010, 2012, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -161,9 +161,13 @@ static errval_t spawn_child(struct capref fdcap)
     domainid_t new_domain = -1;
 
     coreid_t core = 0;
+
+    // allocate inheritcn
+    struct capref inheritcn_cap;
+    err = alloc_inheritcn_with_fdcap(&inheritcn_cap, fdcap);
     
-    err = spawn_program_with_fdcap(core, argv[0], argv, NULL, fdcap, 
-                                   SPAWN_NEW_DOMAIN, &new_domain);
+    err = spawn_program_with_caps(core, argv[0], argv, NULL, inheritcn_cap,
+                                  NULL_CAP, SPAWN_NEW_DOMAIN, &new_domain);
             
     if (err_is_fail(err)) {
         DEBUG_ERR(err, "failed spawn on core %d", core);