Add spawn, spawn_with_caps and span calls to the Process Manager API.
[barrelfish] / usr / proc_mgmt / spawn_client.c
1 /**
2  * \file
3  * \brief Spawn client for the process management service.
4  */
5
6 /*
7  * Copyright (c) 2017, ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 #include "spawn_client.h"
16 #include "spawnd_state.h"
17
18 /**
19  * \brief Request the spawn daemon on a specific core to spawn a program
20  *
21  * \param coreid          Core ID on which to spawn the program
22  * \param path            Absolute path in the file system to an executable
23  *                        image suitable for the given core
24  * \param argv            Command-line arguments, NULL-terminated
25  * \param envp            Optional environment, NULL-terminated
26  *                        (pass NULL to inherit)
27  * \param inheritcn_cap   Cap to a CNode containing capabilities to be inherited
28  * \param argcn_cap       Cap to a CNode containing capabilities passed as
29  *                        arguments
30  * \param flags           Flags to spawn
31  * \param ret_domain_cap  If non-NULL, filled in with domain cap of new domain
32  *
33  * \bug flags are currently ignored
34  */
35 errval_t spawn_with_caps(coreid_t core_id, const char *path,
36                          const char *argvbuf, size_t argvbytes,
37                          const char *envbuf, size_t envbytes,
38                          struct capref inheritcn_cap, struct capref argcn_cap,
39                          uint8_t flags, struct capref *ret_domain_cap)
40 {
41     errval_t err, msgerr;
42
43     if (!spawnd_state_exists(core_id)) {
44         USER_PANIC("not connected to spawnd on the requested core");
45     }
46     struct spawnd_state *state = spawnd_state_get(core_id);
47     assert(state != NULL);
48     struct spawn_binding *cl = state->b;
49     assert(cl != NULL);
50
51     struct capref domain_cap;
52     err = slot_alloc(&domain_cap);
53     if (err_is_fail(err)) {
54         USER_PANIC_ERR(err, "slot_alloc domain_cap");
55     }
56     err = cap_retype(domain_cap, cap_procmng, 0, ObjType_Domain, 0, 1);
57         if (err_is_fail(err)) {
58             USER_PANIC_ERR(err, "cap_retype domain_cap from cap_procmng");
59         }
60
61     if (capref_is_null(inheritcn_cap) && capref_is_null(argcn_cap)) {
62         err = cl->rpc_tx_vtbl.spawn_proc_mgmt_domain(cl, domain_cap,
63                         path, argvbuf, argvbytes, envbuf, envbytes, flags, &msgerr);
64     } else {
65         err = cl->rpc_tx_vtbl.spawn_proc_mgmt_domain_with_caps(cl, domain_cap,
66                         path, argvbuf, argvbytes, envbuf, envbytes, inheritcn_cap,
67                         argcn_cap, flags, &msgerr);
68     }
69     if (err_is_fail(err)) {
70         USER_PANIC_ERR(err, "error sending spawn request");
71     } else if (err_is_fail(msgerr)) {
72         goto out;
73     }
74
75     if (ret_domain_cap != NULL) {
76         *ret_domain_cap = domain_cap;
77     }
78
79 out:
80     return msgerr;
81 }
82
83 /**
84  * \brief Request the spawn daemon on a specific core to spawn a program
85  *
86  * \param coreid          Core ID on which to spawn the program
87  * \param path            Absolute path in the file system to an executable
88  *                        image suitable for the given core
89  * \param argv            Command-line arguments, NULL-terminated
90  * \param envp            Optional environment, NULL-terminated
91  *                        (pass NULL to inherit)
92  * \param inheritcn_cap   Cap to a CNode containing capabilities to be inherited
93  * \param argcn_cap       Cap to a CNode containing capabilities passed as
94  *                        arguments
95  * \param flags           Flags to spawn
96  * \param ret_domain_cap  If non-NULL, filled in with domain cap of new domain
97  *
98  * \bug flags are currently ignored
99  */
100 errval_t spawn(coreid_t core_id, const char *path, const char *argvbuf,
101                size_t argvbytes, const char *envbuf, size_t envbytes,
102                uint8_t flags, struct capref *ret_domain_cap)
103 {
104     return spawn_with_caps(core_id, path, argvbuf, argvbytes, envbuf, envbytes,
105                            NULL_CAP, NULL_CAP, flags, ret_domain_cap);
106 }
107
108 /**
109  * \brief Request the spawn daemon on a specific core to span an existing domain
110  *
111  * \param domain_cap Identifying capability for the domain to span
112  * \param core_id    Core ID on which to span
113  * \param vroot      Vspace root for the dispatcher to span
114  * \param dispframe  Frame for the dispatcher to span
115  */
116 errval_t span(struct capref domain_cap, coreid_t core_id, struct capref vroot,
117               struct capref dispframe)
118 {
119     errval_t err, msgerr;
120
121     if (!spawnd_state_exists(core_id)) {
122         USER_PANIC("not connected to spawnd on the requested core");
123     }
124     struct spawnd_state *state = spawnd_state_get(core_id);
125     assert(state != NULL);
126     struct spawn_binding *cl = state->b;
127     assert(cl != NULL);
128
129     err = cl->rpc_tx_vtbl.span(cl, domain_cap, vroot, dispframe, &msgerr);
130     if (err_is_fail(err)) {
131         USER_PANIC_ERR(err, "error sending span request");
132     }
133
134     return msgerr;
135 }