[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] linux: Don't allow partial message raeds from xenstore across



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.