aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore
diff options
context:
space:
mode:
Diffstat (limited to 'tools/xenstore')
-rw-r--r--tools/xenstore/Makefile3
-rw-r--r--tools/xenstore/fake_libxc.c2
-rw-r--r--tools/xenstore/xenstored_core.c34
-rw-r--r--tools/xenstore/xenstored_core.h3
-rw-r--r--tools/xenstore/xenstored_domain.c3
-rw-r--r--tools/xenstore/xenstored_test.h2
-rw-r--r--tools/xenstore/xs.c14
-rw-r--r--tools/xenstore/xs_lib.c8
-rw-r--r--tools/xenstore/xs_lib.h8
-rw-r--r--tools/xenstore/xs_random.c8
-rw-r--r--tools/xenstore/xs_test.c8
11 files changed, 55 insertions, 38 deletions
diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile
index b5511aea3c..408078efba 100644
--- a/tools/xenstore/Makefile
+++ b/tools/xenstore/Makefile
@@ -92,8 +92,11 @@ install: xenstored libxenstore.a
$(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored
$(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored
$(INSTALL_DIR) -p $(DESTDIR)/usr/sbin
+ $(INSTALL_DIR) -p $(DESTDIR)/usr/include
$(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin
$(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
$(INSTALL_DATA) libxenstore.a $(DESTDIR)/usr/$(LIBDIR)
+ $(INSTALL_DATA) xs.h $(DESTDIR)/usr/include
+ $(INSTALL_DATA) xs_lib.h $(DESTDIR)/usr/include
-include $(PROG_DEP)
diff --git a/tools/xenstore/fake_libxc.c b/tools/xenstore/fake_libxc.c
index decfb4001d..50e1db717c 100644
--- a/tools/xenstore/fake_libxc.c
+++ b/tools/xenstore/fake_libxc.c
@@ -71,7 +71,7 @@ int xc_interface_open(void)
return fd;
memset(page, 0, sizeof(page));
- if (!write_all(fd, page, sizeof(page)))
+ if (!xs_write_all(fd, page, sizeof(page)))
barf_perror("Failed to write /tmp/xcmap page");
return fd;
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 9d15848463..1df00f37b4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -81,7 +81,7 @@ bool test_write_all(int fd, void *contents, unsigned int len)
errno = ENOSPC;
return false;
}
- return write_all(fd, contents, len);
+ return xs_write_all(fd, contents, len);
}
int test_mkdir(const char *dir, int perms);
@@ -443,9 +443,9 @@ static struct xs_permissions *get_perms(struct transaction *transaction,
if (!strings)
return NULL;
- *num = count_strings(strings, size);
+ *num = xs_count_strings(strings, size);
ret = talloc_array(node, struct xs_permissions, *num);
- if (!strings_to_perms(ret, *num, strings))
+ if (!xs_strings_to_perms(ret, *num, strings))
corrupt(NULL, "Permissions corrupt for %s", node);
return ret;
@@ -460,7 +460,7 @@ static char *perms_to_strings(const char *node,
char buffer[MAX_STRLEN(domid_t) + 1];
for (*len = 0, i = 0; i < num; i++) {
- if (!perm_to_string(&perms[i], buffer))
+ if (!xs_perm_to_string(&perms[i], buffer))
return NULL;
strings = talloc_realloc(node, strings, char,
@@ -506,7 +506,7 @@ static char *tempfile(const char *path, void *contents, unsigned int len)
if (!fd)
return NULL;
talloc_set_destructor(tmppath, destroy_path);
- if (!write_all(*fd, contents, len))
+ if (!xs_write_all(*fd, contents, len))
return NULL;
return tmppath;
@@ -617,7 +617,7 @@ bool check_node_perms(struct connection *conn, const char *node,
return false;
}
- if (!conn->write && (perm & XS_PERM_WRITE)) {
+ if (!conn->can_write && (perm & XS_PERM_WRITE)) {
errno = EROFS;
return false;
}
@@ -721,14 +721,14 @@ static bool new_directory(struct connection *conn,
permstr = perms_to_strings(dir, &perms, 1, &len);
fd = talloc_open(node_permfile(conn->transaction, node),
O_WRONLY|O_CREAT|O_EXCL, 0640);
- if (!fd || !write_all(*fd, permstr, len))
+ if (!fd || !xs_write_all(*fd, permstr, len))
return false;
if (data) {
char *datapath = node_datafile(conn->transaction, node);
fd = talloc_open(datapath, O_WRONLY|O_CREAT|O_EXCL, 0640);
- if (!fd || !write_all(*fd, data, datalen))
+ if (!fd || !xs_write_all(*fd, data, datalen))
return false;
}
@@ -878,7 +878,7 @@ static bool do_set_perms(struct connection *conn, struct buffered_data *in)
char *node;
struct xs_permissions *perms;
- num = count_strings(in->buffer, in->used);
+ num = xs_count_strings(in->buffer, in->used);
if (num < 2)
return send_error(conn, EINVAL);
@@ -898,7 +898,7 @@ static bool do_set_perms(struct connection *conn, struct buffered_data *in)
return send_error(conn, errno);
perms = talloc_array(node, struct xs_permissions, num);
- if (!strings_to_perms(perms, num, in->buffer))
+ if (!xs_strings_to_perms(perms, num, in->buffer))
return send_error(conn, errno);
if (!set_perms(conn->transaction, node, perms, num))
@@ -938,6 +938,12 @@ static bool process_message(struct connection *conn, struct buffered_data *in)
return do_set_perms(conn, in);
case XS_SHUTDOWN:
+ /* FIXME: Implement gentle shutdown too. */
+ /* Only tools can do this. */
+ if (conn->id != 0)
+ return send_error(conn, EACCES);
+ if (!conn->can_write)
+ return send_error(conn, EROFS);
send_ack(conn, XS_SHUTDOWN);
/* Everything hangs off auto-free context, freed at exit. */
exit(0);
@@ -1137,6 +1143,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
new->transaction = NULL;
new->write = write;
new->read = read;
+ new->can_write = true;
talloc_set_fail_handler(out_of_mem, &talloc_fail);
if (setjmp(talloc_fail)) {
@@ -1170,10 +1177,11 @@ static void accept_connection(int sock, bool canwrite)
if (fd < 0)
return;
- conn = new_connection(canwrite ? writefd : NULL, readfd);
- if (conn)
+ conn = new_connection(writefd, readfd);
+ if (conn) {
conn->fd = fd;
- else
+ conn->can_write = canwrite;
+ } else
close(fd);
}
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index fe6eec8f72..0d0ebcaae0 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -56,6 +56,9 @@ struct connection
/* Are we blocked waiting for a transaction to end? Contains node. */
char *blocked;
+ /* Is this a read-only connection? */
+ bool can_write;
+
/* Our current event. If all used, we're waiting for ack. */
struct watch_event *event;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index bcc0a64967..a6f69ddf5b 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -268,6 +268,9 @@ bool do_introduce(struct connection *conn, struct buffered_data *in)
if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
return send_error(conn, EINVAL);
+ if (!conn->can_write)
+ return send_error(conn, EROFS);
+
/* Hang domain off "in" until we're finished. */
domain = talloc(in, struct domain);
domain->domid = atoi(vec[0]);
diff --git a/tools/xenstore/xenstored_test.h b/tools/xenstore/xenstored_test.h
index f173a5ca91..cf607cf2e0 100644
--- a/tools/xenstore/xenstored_test.h
+++ b/tools/xenstore/xenstored_test.h
@@ -21,7 +21,7 @@
#ifdef TESTING
bool test_write_all(int fd, void *contents, unsigned int len);
-#define write_all test_write_all
+#define xs_write_all test_write_all
int test_mkdir(const char *dir, int perms);
#define mkdir test_mkdir
diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c
index d5058abfb3..d6e41380f9 100644
--- a/tools/xenstore/xs.c
+++ b/tools/xenstore/xs.c
@@ -118,7 +118,7 @@ static bool read_all(int fd, void *data, unsigned int len)
#ifdef XSTEST
#define read_all read_all_choice
-#define write_all write_all_choice
+#define xs_write_all write_all_choice
#endif
static int get_error(const char *errorstring)
@@ -179,11 +179,11 @@ static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
ignorepipe.sa_flags = 0;
sigaction(SIGPIPE, &ignorepipe, &oldact);
- if (!write_all(h->fd, &msg, sizeof(msg)))
+ if (!xs_write_all(h->fd, &msg, sizeof(msg)))
goto fail;
for (i = 0; i < num_vecs; i++)
- if (!write_all(h->fd, iovec[i].iov_base, iovec[i].iov_len))
+ if (!xs_write_all(h->fd, iovec[i].iov_base, iovec[i].iov_len))
goto fail;
/* Watches can have fired before reply comes: daemon detects
@@ -253,7 +253,7 @@ char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num)
return NULL;
/* Count the strings. */
- *num = count_strings(strings, len);
+ *num = xs_count_strings(strings, len);
/* Transfer to one big alloc for easy freeing. */
ret = malloc(*num * sizeof(char *) + len);
@@ -342,7 +342,7 @@ struct xs_permissions *xs_get_permissions(struct xs_handle *h,
return NULL;
/* Count the strings: each one perms then domid. */
- *num = count_strings(strings, len);
+ *num = xs_count_strings(strings, len);
/* Transfer to one big alloc for easy freeing. */
ret = malloc(*num * sizeof(struct xs_permissions));
@@ -351,7 +351,7 @@ struct xs_permissions *xs_get_permissions(struct xs_handle *h,
return NULL;
}
- if (!strings_to_perms(ret, *num, strings)) {
+ if (!xs_strings_to_perms(ret, *num, strings)) {
free_no_errno(ret);
ret = NULL;
}
@@ -376,7 +376,7 @@ bool xs_set_permissions(struct xs_handle *h, const char *path,
for (i = 0; i < num_perms; i++) {
char buffer[MAX_STRLEN(domid_t)+1];
- if (!perm_to_string(&perms[i], buffer))
+ if (!xs_perm_to_string(&perms[i], buffer))
goto unwind;
iov[i+1].iov_base = strdup(buffer);
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 8630eaffce..3f4f4b0899 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -48,7 +48,7 @@ const char *xs_daemon_transactions(void)
}
/* Simple routines for writing to sockets, etc. */
-bool write_all(int fd, const void *data, unsigned int len)
+bool xs_write_all(int fd, const void *data, unsigned int len)
{
while (len) {
int done;
@@ -66,7 +66,7 @@ bool write_all(int fd, const void *data, unsigned int len)
}
/* Convert strings to permissions. False if a problem. */
-bool strings_to_perms(struct xs_permissions *perms, unsigned int num,
+bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
const char *strings)
{
const char *p;
@@ -104,7 +104,7 @@ bool strings_to_perms(struct xs_permissions *perms, unsigned int num,
}
/* Convert permissions to a string (up to len MAX_STRLEN(domid_t)+1). */
-bool perm_to_string(const struct xs_permissions *perm, char *buffer)
+bool xs_perm_to_string(const struct xs_permissions *perm, char *buffer)
{
switch (perm->perms) {
case XS_PERM_WRITE:
@@ -128,7 +128,7 @@ bool perm_to_string(const struct xs_permissions *perm, char *buffer)
}
/* Given a string and a length, count how many strings (nul terms). */
-unsigned int count_strings(const char *strings, unsigned int len)
+unsigned int xs_count_strings(const char *strings, unsigned int len)
{
unsigned int num;
const char *p;
diff --git a/tools/xenstore/xs_lib.h b/tools/xenstore/xs_lib.h
index a946ab0b19..76ea9b67fe 100644
--- a/tools/xenstore/xs_lib.h
+++ b/tools/xenstore/xs_lib.h
@@ -48,16 +48,16 @@ const char *xs_daemon_store(void);
const char *xs_daemon_transactions(void);
/* Simple write function: loops for you. */
-bool write_all(int fd, const void *data, unsigned int len);
+bool xs_write_all(int fd, const void *data, unsigned int len);
/* Convert strings to permissions. False if a problem. */
-bool strings_to_perms(struct xs_permissions *perms, unsigned int num,
+bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
const char *strings);
/* Convert permissions to a string (up to len MAX_STRLEN(domid_t)+1). */
-bool perm_to_string(const struct xs_permissions *perm, char *buffer);
+bool xs_perm_to_string(const struct xs_permissions *perm, char *buffer);
/* Given a string and a length, count how many strings (nul terms). */
-unsigned int count_strings(const char *strings, unsigned int len);
+unsigned int xs_count_strings(const char *strings, unsigned int len);
#endif /* _XS_LIB_H */
diff --git a/tools/xenstore/xs_random.c b/tools/xenstore/xs_random.c
index ef5d44d0b0..675cc89093 100644
--- a/tools/xenstore/xs_random.c
+++ b/tools/xenstore/xs_random.c
@@ -223,10 +223,10 @@ static struct xs_permissions *file_get_perms(struct file_ops_info *info,
release_file(perms, size);
return ret;
}
- *num = count_strings(perms, size);
+ *num = xs_count_strings(perms, size);
ret = new_array(struct xs_permissions, *num);
- if (!strings_to_perms(ret, *num, perms))
+ if (!xs_strings_to_perms(ret, *num, perms))
barf("Reading permissions from %s", permfile);
release_file(perms, size);
return ret;
@@ -267,7 +267,7 @@ static bool file_set_perms(struct file_ops_info *info,
for (i = 0; i < num; i++) {
char buffer[100];
- if (!perm_to_string(&perms[i], buffer)) {
+ if (!xs_perm_to_string(&perms[i], buffer)) {
int saved_errno = errno;
close(fd);
errno = saved_errno;
@@ -536,7 +536,7 @@ static char *dump_dir(struct ops *ops,
ret = talloc_asprintf_append(ret, "%s%s: ", spacing, dir[i]);
for (j = 0; j < numperms; j++) {
char buffer[100];
- if (!perm_to_string(&perms[j], buffer))
+ if (!xs_perm_to_string(&perms[j], buffer))
barf("perm to string");
ret = talloc_asprintf_append(ret, "%s ", buffer);
}
diff --git a/tools/xenstore/xs_test.c b/tools/xenstore/xs_test.c
index f1e66cbe28..4d769e220d 100644
--- a/tools/xenstore/xs_test.c
+++ b/tools/xenstore/xs_test.c
@@ -153,7 +153,7 @@ static bool write_all_choice(int fd, const void *data, unsigned int len)
{
if (fd == -2)
return write_all_shmem(fd, data, len);
- return write_all(fd, data, len);
+ return xs_write_all(fd, data, len);
}
/* We want access to internal functions. */
@@ -176,11 +176,11 @@ static void __attribute__((noreturn)) usage(void)
" watch <path> <prio>\n"
" waitwatch\n"
" ackwatch\n"
- " unwatch <path>\n"
+ " unwatch <path> <token>\n"
" close\n"
" start <node>\n"
" abort\n"
- " introduce <domid> <mfn> <eventchn>\n"
+ " introduce <domid> <mfn> <eventchn> <path>\n"
" commit\n"
" sleep <seconds>\n"
" dump\n");
@@ -491,7 +491,7 @@ static void dump_dir(unsigned int handle,
printf("%s%s: ", spacing, dir[i]);
for (j = 0; j < numperms; j++) {
char buffer[100];
- if (!perm_to_string(&perms[j], buffer))
+ if (!xs_perm_to_string(&perms[j], buffer))
barf("perm to string");
printf("%s ", buffer);
}