File xs_weak_write.patch of Package xenstore-uvp
diff --git a/tools/xenstore/xenstore_client.c b/tools/xenstore/xenstore_client.c
index 94b82b9..0e03622 100644
--- a/tools/xenstore/xenstore_client.c
+++ b/tools/xenstore/xenstore_client.c
@@ -37,6 +37,7 @@ enum mode {
MODE_rm,
MODE_write,
MODE_watch,
+ MODE_weakwrite,
};
static char *output_buf = NULL;
@@ -99,6 +100,9 @@ usage(enum mode mode, int incl_mode, const char *progname)
case MODE_watch:
mstr = incl_mode ? "watch " : "";
errx(1, "Usage: %s %s[-h] [-n NR] key", progname, mstr);
+ case MODE_weakwrite:
+ mstr = incl_mode ? "weakwrite " : "";
+ errx(1, "Usage: %s %s[-h] [-s] key value [...]", progname, mstr);
}
}
@@ -335,6 +339,18 @@ perform(enum mode mode, int optind, int argc, char **argv, struct xs_handle *xsh
}
optind += 2;
} break;
+ case MODE_weakwrite: {
+ static struct expanding_buffer ebuf;
+ char *val_spec = argv[optind + 1];
+ unsigned len;
+ expanding_buffer_ensure(&ebuf, strlen(val_spec)+1);
+ unsanitise_value(ebuf.buf, &len, val_spec);
+ if (!xs_weak_write(xsh, xth, argv[optind], ebuf.buf, len)) {
+ warnx("could not write path %s", argv[optind]);
+ return 1;
+ }
+ optind += 2;
+ } break;
case MODE_rm: {
/* Remove the specified path. If the tidy flag is set, then also
remove any containing directories that are both empty and have no
@@ -486,6 +502,8 @@ static enum mode lookup_mode(const char *m)
return MODE_read;
else if (strcmp(m, "watch") == 0)
return MODE_watch;
+ else if (strcmp(m, "weakwrite") == 0)
+ return MODE_weakwrite;
errx(1, "unknown mode %s\n", m);
return 0;
@@ -618,6 +636,7 @@ main(int argc, char **argv)
break;
case MODE_ls:
case MODE_watch:
+ case MODE_weakwrite:
transaction = 0;
break;
default:
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 1749740..8de8e9c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -112,6 +112,8 @@ static char *sockmsg_string(enum xsd_sockmsg_type type)
case XS_RELEASE: return "RELEASE";
case XS_GET_DOMAIN_PATH: return "GET_DOMAIN_PATH";
case XS_WRITE: return "WRITE";
+ case XS_WEAK_WRITE: return "WEAK_WRITE";
+ case XS_LINUX_WEAK_WRITE: return "LINUX_WEAK_WRITE";
case XS_MKDIR: return "MKDIR";
case XS_RM: return "RM";
case XS_SET_PERMS: return "SET_PERMS";
@@ -901,9 +903,31 @@ static void do_write(struct connection *conn, struct buffered_data *in)
add_change_node(conn->transaction, name, false);
fire_watches(conn, name, false);
+ if (XS_WEAK_WRITE == in->hdr.msg.type)
+ send_ack(conn, XS_WEAK_WRITE);
+ else if (XS_LINUX_WEAK_WRITE == in->hdr.msg.type)
+ send_ack(conn, XS_LINUX_WEAK_WRITE);
+ else
send_ack(conn, XS_WRITE);
}
+static void do_weak_write(struct connection *conn, struct buffered_data *in)
+{
+ struct connection *connect, *next;
+ next = list_entry(connections.next, typeof(*conn), list);
+ while (&next->list != &connections) {
+ connect = next;
+ if (connect->transaction_started > 0)
+ {
+ send_error(conn, EAGAIN);
+ return;
+ } else {
+ next = list_entry(connect->list.next,
+ typeof(*connect), list);
+ }
+ }
+ do_write (conn, in);
+}
static void do_mkdir(struct connection *conn, const char *name)
{
struct node *node;
@@ -1181,7 +1205,10 @@ static void process_message(struct connection *conn, struct buffered_data *in)
case XS_WRITE:
do_write(conn, in);
break;
-
+ case XS_WEAK_WRITE:
+ case XS_LINUX_WEAK_WRITE:
+ do_weak_write(conn, in);
+ break;
case XS_MKDIR:
do_mkdir(conn, onearg(in));
break;
diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c
index c72ea83..089b543 100644
--- a/tools/xenstore/xs.c
+++ b/tools/xenstore/xs.c
@@ -560,6 +560,24 @@ bool xs_write(struct xs_handle *h, xs_transaction_t t,
ARRAY_SIZE(iovec), NULL));
}
+/* Write the value of a single file.
+ * Returns false on failure.
+ */
+bool xs_weak_write(struct xs_handle *h, xs_transaction_t t,
+ const char *path, const void *data, unsigned int len)
+{
+ struct iovec iovec[2];
+
+ iovec[0].iov_base = (void *)path;
+ iovec[0].iov_len = strlen(path) + 1;
+ iovec[1].iov_base = (void *)data;
+ iovec[1].iov_len = len;
+
+ return xs_bool(xs_talkv(h, t, XS_LINUX_WEAK_WRITE, iovec,
+ ARRAY_SIZE(iovec), NULL));
+}
+
+
/* Create a new directory.
* Returns false on failure, or success if it already exists.
*/
diff --git a/tools/xenstore/xs.h b/tools/xenstore/xs.h
index 1cbe255..888ff56 100644
--- a/tools/xenstore/xs.h
+++ b/tools/xenstore/xs.h
@@ -90,6 +90,12 @@ void *xs_read(struct xs_handle *h, xs_transaction_t t,
bool xs_write(struct xs_handle *h, xs_transaction_t t,
const char *path, const void *data, unsigned int len);
+/* Write the value of a single file.
+ * Returns false on failure.
+ */
+bool xs_weak_write(struct xs_handle *h, xs_transaction_t t,
+ const char *path, const void *data, unsigned int len);
+
/* Create a new directory.
* Returns false on failure, or success if it already exists.
*/
diff --git a/xen/include/public/io/xs_wire.h b/xen/include/public/io/xs_wire.h
index e1debce..8da5eee 100644
--- a/xen/include/public/io/xs_wire.h
+++ b/xen/include/public/io/xs_wire.h
@@ -48,7 +48,9 @@ enum xsd_sockmsg_type
XS_IS_DOMAIN_INTRODUCED,
XS_RESUME,
XS_SET_TARGET,
- XS_RESTRICT
+ XS_RESTRICT,
+ XS_WEAK_WRITE,
+ XS_LINUX_WEAK_WRITE = 128
};
#define XS_WRITE_NONE "NONE"