# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1172583781 0
# Node ID b67c253d1cdb4f502dec2f2bcede135cf5f45a0b
# Parent 339e477d2548a0372a93a9d041dd7a087b14171e
linux: Don't allow partial message raeds from xenstore across
save/restore. This patch is an essential companion to
13519:b4a8000e76db6b4b27341.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c | 12 +++--
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h | 1
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 40 ++++++++---------
3 files changed, 29 insertions(+), 24 deletions(-)
diff -r 339e477d2548 -r b67c253d1cdb
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Tue Feb 27
11:19:25 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Tue Feb 27
13:43:01 2007 +0000
@@ -137,6 +137,14 @@ int xb_write(const void *data, unsigned
return 0;
}
+int xb_wait_for_data_to_read(void)
+{
+ struct xenstore_domain_interface *intf = xen_store_interface;
+ return wait_event_interruptible(
+ xb_waitq,
+ intf->rsp_cons != intf->rsp_prod);
+}
+
int xb_read(void *data, unsigned len)
{
struct xenstore_domain_interface *intf = xen_store_interface;
@@ -147,9 +155,7 @@ int xb_read(void *data, unsigned len)
unsigned int avail;
const char *src;
- rc = wait_event_interruptible(
- xb_waitq,
- intf->rsp_cons != intf->rsp_prod);
+ rc = xb_wait_for_data_to_read();
if (rc < 0)
return rc;
diff -r 339e477d2548 -r b67c253d1cdb
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Tue Feb 27
11:19:25 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Tue Feb 27
13:43:01 2007 +0000
@@ -37,6 +37,7 @@ int xb_init_comms(void);
/* Low level routines. */
int xb_write(const void *data, unsigned len);
int xb_read(void *data, unsigned len);
+int xb_wait_for_data_to_read(void);
int xs_input_avail(void);
extern struct xenstore_domain_interface *xen_store_interface;
extern int xen_store_evtchn;
diff -r 339e477d2548 -r b67c253d1cdb
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Feb 27
11:19:25 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Feb 27
13:43:01 2007 +0000
@@ -150,22 +150,6 @@ static void *read_reply(enum xsd_sockmsg
return body;
}
-/* Emergency write. */
-void xenbus_debug_write(const char *str, unsigned int count)
-{
- struct xsd_sockmsg msg = { 0 };
-
- msg.type = XS_DEBUG;
- msg.len = sizeof("print") + count + 1;
-
- mutex_lock(&xs_state.request_mutex);
- xb_write(&msg, sizeof(msg));
- xb_write("print", sizeof("print"));
- xb_write(str, count);
- xb_write("", 1);
- mutex_unlock(&xs_state.request_mutex);
-}
-
void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
{
void *ret;
@@ -753,27 +737,38 @@ static int process_msg(void)
char *body;
int err;
+ err = xb_wait_for_data_to_read();
+ if (err)
+ return err;
+
msg = kmalloc(sizeof(*msg), GFP_KERNEL);
if (msg == NULL)
return -ENOMEM;
+ /*
+ * We are now committed to reading an entire message. Partial reads
+ * across save/restore leave us out of sync with the xenstore daemon.
+ */
+ down_read(&xs_state.suspend_mutex);
+
err = xb_read(&msg->hdr, sizeof(msg->hdr));
if (err) {
kfree(msg);
- return err;
+ goto out;
}
body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
if (body == NULL) {
kfree(msg);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto out;
}
err = xb_read(body, msg->hdr.len);
if (err) {
kfree(body);
kfree(msg);
- return err;
+ goto out;
}
body[msg->hdr.len] = '\0';
@@ -782,7 +777,8 @@ static int process_msg(void)
&msg->u.watch.vec_size);
if (IS_ERR(msg->u.watch.vec)) {
kfree(msg);
- return PTR_ERR(msg->u.watch.vec);
+ err = PTR_ERR(msg->u.watch.vec);
+ goto out;
}
spin_lock(&watches_lock);
@@ -806,7 +802,9 @@ static int process_msg(void)
wake_up(&xs_state.reply_waitq);
}
- return 0;
+ out:
+ up_read(&xs_state.suspend_mutex);
+ return err;
}
static int xenbus_thread(void *unused)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|