aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-01-23 13:22:13 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-01-23 13:22:13 +0000
commitf9f9329313866cffe0e00524592cf765734d3a41 (patch)
treebb835a42f05839df1244295194b58900637e19fb /tools/xenstore
parent47fcfcb75b5d5ece1bba1aeca8e2d99b0103d6c4 (diff)
downloadxen-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.c13
-rw-r--r--tools/xenstore/xenstored_core.h3
-rw-r--r--tools/xenstore/xenstored_domain.c45
-rw-r--r--tools/xenstore/xenstored_domain.h3
-rw-r--r--tools/xenstore/xs.c19
-rw-r--r--tools/xenstore/xs.h9
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.
*/