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",
/*
- * 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.
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);
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
/*
- * 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.
#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);
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
*/
/*
- * 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.
#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
*/
/*
- * 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.
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;
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);
* \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);
}
if (cap.type != ObjType_CNode) {
- return LIB_ERR_NOT_A_CNODE;
+ return LIB_ERR_NOT_CNODE;
}
cnoder->address = get_cap_addr(capr);
*/
/*
- * 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.
/**
* \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;
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");
return msgerr;
}
+
/**
* \brief Request the spawn daemon on a specific core to spawn a program
*
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);
}
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;
+}
*/
/*
- * 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.
#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"
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;
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)) {
*/
/*
- * 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.
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);
}
*/
/*
- * 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.
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);
*/
/*
- * 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.
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;
/* 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;
}
-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;
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);
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);
}
/**
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,
*/
/*
- * 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.
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);