diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-01-23 13:22:13 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-01-23 13:22:13 +0000 |
commit | f9f9329313866cffe0e00524592cf765734d3a41 (patch) | |
tree | bb835a42f05839df1244295194b58900637e19fb /tools/xenstore | |
parent | 47fcfcb75b5d5ece1bba1aeca8e2d99b0103d6c4 (diff) | |
download | xen-f9f9329313866cffe0e00524592cf765734d3a41.tar.gz xen-f9f9329313866cffe0e00524592cf765734d3a41.tar.bz2 xen-f9f9329313866cffe0e00524592cf765734d3a41.zip |
New XS_SET_TARGET
Stubdomains (and probably other domain disagregation elements too)
need to be able to tinker with another domain. This adds
XS_SET_TARGET so that XenStore allows domains to have permissions on
files on which the "target" has permissions. This also adds
xs_set_target, called by the domain builder when the 'target' option
is used in the configuration.
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'tools/xenstore')
-rw-r--r-- | tools/xenstore/xenstored_core.c | 13 | ||||
-rw-r--r-- | tools/xenstore/xenstored_core.h | 3 | ||||
-rw-r--r-- | tools/xenstore/xenstored_domain.c | 45 | ||||
-rw-r--r-- | tools/xenstore/xenstored_domain.h | 3 | ||||
-rw-r--r-- | tools/xenstore/xs.c | 19 | ||||
-rw-r--r-- | tools/xenstore/xs.h | 9 |
6 files changed, 90 insertions, 2 deletions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index acf6dd3918..7f20e30ca0 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -119,6 +119,7 @@ static char *sockmsg_string(enum xsd_sockmsg_type type) case XS_ERROR: return "ERROR"; case XS_IS_DOMAIN_INTRODUCED: return "XS_IS_DOMAIN_INTRODUCED"; case XS_RESUME: return "RESUME"; + case XS_SET_TARGET: return "SET_TARGET"; default: return "**UNKNOWN**"; } @@ -283,6 +284,8 @@ static int destroy_conn(void *_conn) break; close(conn->fd); } + if (conn->target) + talloc_unlink(conn, conn->target); list_del(&conn->list); trace_destroy(conn, "connection"); return 0; @@ -472,11 +475,13 @@ static enum xs_perm_type perm_for_conn(struct connection *conn, mask &= ~XS_PERM_WRITE; /* Owners and tools get it all... */ - if (!conn->id || perms[0].id == conn->id) + if (!conn->id || perms[0].id == conn->id + || (conn->target && perms[0].id == conn->target->id)) return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask; for (i = 1; i < num; i++) - if (perms[i].id == conn->id) + if (perms[i].id == conn->id + || (conn->target && perms[i].id == conn->target->id)) return perms[i].perms & mask; return perms[0].perms & mask; @@ -1245,6 +1250,10 @@ static void process_message(struct connection *conn, struct buffered_data *in) do_resume(conn, onearg(in)); break; + case XS_SET_TARGET: + do_set_target(conn, in); + break; + default: eprintf("Client unknown operation %i", in->hdr.msg.type); send_error(conn, ENOSYS); diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index d46d77f026..975a97226f 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -84,6 +84,9 @@ struct connection /* The domain I'm associated with, if any. */ struct domain *domain; + /* The target of the domain I'm associated with. */ + struct connection *target; + /* My watches. */ struct list_head watches; diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index ed422a52aa..2cc9881eb4 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -381,6 +381,51 @@ void do_introduce(struct connection *conn, struct buffered_data *in) send_ack(conn, XS_INTRODUCE); } +void do_set_target(struct connection *conn, struct buffered_data *in) +{ + char *vec[2]; + unsigned int domid, tdomid; + struct domain *domain, *tdomain; + if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { + send_error(conn, EINVAL); + return; + } + + if (conn->id != 0 || !conn->can_write) { + send_error(conn, EACCES); + return; + } + + domid = atoi(vec[0]); + tdomid = atoi(vec[1]); + + domain = find_domain_by_domid(domid); + if (!domain) { + send_error(conn, ENOENT); + return; + } + if (!domain->conn) { + send_error(conn, EINVAL); + return; + } + + tdomain = find_domain_by_domid(tdomid); + if (!tdomain) { + send_error(conn, ENOENT); + return; + } + + if (!tdomain->conn) { + send_error(conn, EINVAL); + return; + } + + talloc_reference(domain->conn, tdomain->conn); + domain->conn->target = tdomain->conn; + + send_ack(conn, XS_SET_TARGET); +} + /* domid */ void do_release(struct connection *conn, const char *domid_str) { diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 69fdb77c1a..f42a9f50ad 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -34,6 +34,9 @@ void do_release(struct connection *conn, const char *domid_str); /* domid */ void do_resume(struct connection *conn, const char *domid_str); +/* domid, target */ +void do_set_target(struct connection *conn, struct buffered_data *in); + /* domid */ void do_get_domain_path(struct connection *conn, const char *domid_str); diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c index a815257798..dbbf8ef394 100644 --- a/tools/xenstore/xs.c +++ b/tools/xenstore/xs.c @@ -708,6 +708,25 @@ bool xs_introduce_domain(struct xs_handle *h, ARRAY_SIZE(iov), NULL)); } +bool xs_set_target(struct xs_handle *h, + unsigned int domid, unsigned int target) +{ + char domid_str[MAX_STRLEN(domid)]; + char target_str[MAX_STRLEN(target)]; + struct iovec iov[2]; + + snprintf(domid_str, sizeof(domid_str), "%u", domid); + snprintf(target_str, sizeof(target_str), "%u", target); + + iov[0].iov_base = domid_str; + iov[0].iov_len = strlen(domid_str) + 1; + iov[1].iov_base = target_str; + iov[1].iov_len = strlen(target_str) + 1; + + return xs_bool(xs_talkv(h, XBT_NULL, XS_SET_TARGET, iov, + ARRAY_SIZE(iov), NULL)); +} + static void * single_with_domid(struct xs_handle *h, enum xsd_sockmsg_type type, unsigned int domid) diff --git a/tools/xenstore/xs.h b/tools/xenstore/xs.h index c855614675..dd8cbf8c95 100644 --- a/tools/xenstore/xs.h +++ b/tools/xenstore/xs.h @@ -132,6 +132,15 @@ bool xs_introduce_domain(struct xs_handle *h, unsigned int domid, unsigned long mfn, unsigned int eventchn); + +/* Set the target of a domain + * This tells the store daemon that a domain is targetting another one, so + * it should let it tinker with it. + */ +bool xs_set_target(struct xs_handle *h, + unsigned int domid, + unsigned int target); + /* Resume a domain. * Clear the shutdown flag for this domain in the store. */ |