WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Change xenbus_dev interface from ioctl to read/write.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Change xenbus_dev interface from ioctl to read/write.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 12 Sep 2005 21:12:11 +0000
Delivery-date: Mon, 12 Sep 2005 21:10:40 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 80afc502461b56539092dec5c1fa6df05df8baf2
# Parent  282d5698ea40f40dc09871f0c92dc691b10b7269
Change xenbus_dev interface from ioctl to read/write.
Check boundaries so we can recover if userspace dies.
Also simplifies libxenstore.
Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r 282d5698ea40 -r 80afc502461b .hgignore
--- a/.hgignore Mon Sep 12 20:46:37 2005
+++ b/.hgignore Mon Sep 12 21:12:16 2005
@@ -152,7 +152,6 @@
 ^tools/xenstat/xentop/xentop$
 ^tools/xenstore/testsuite/tmp/.*$
 ^tools/xenstore/xen$
-^tools/xenstore/xenbus_dev.h$
 ^tools/xenstore/xenstored$
 ^tools/xenstore/xenstored_test$
 ^tools/xenstore/xenstore-read$
diff -r 282d5698ea40 -r 80afc502461b 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Mon Sep 12 
20:46:37 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Mon Sep 12 
21:12:16 2005
@@ -5,6 +5,7 @@
  * to xenstore.
  * 
  * Copyright (c) 2005, Christian Limpach
+ * Copyright (c) 2005, Rusty Russell, IBM Corporation
  * 
  * This file may be distributed separately from the Linux kernel, or
  * incorporated into other software packages, subject to the following license:
@@ -41,104 +42,96 @@
 
 #include <asm/uaccess.h>
 #include <asm-xen/xenbus.h>
-#include <asm-xen/linux-public/xenbus_dev.h>
 #include <asm-xen/xen_proc.h>
 
 struct xenbus_dev_data {
-       int in_transaction;
+       /* Are there bytes left to be read in this message? */
+       int bytes_left;
+       /* Are we still waiting for the reply to a message we wrote? */
+       int awaiting_reply;
+       /* Buffer for outgoing messages. */
+       unsigned int len;
+       union {
+               struct xsd_sockmsg msg;
+               char buffer[PAGE_SIZE];
+       } u;
 };
 
 static struct proc_dir_entry *xenbus_dev_intf;
 
-void *xs_talkv(enum xsd_sockmsg_type type, const struct kvec *iovec,
-              unsigned int num_vecs, unsigned int *len);
+/* Reply can be long (dir, getperm): don't buffer, just examine
+ * headers so we can discard rest if they die. */
+static ssize_t xenbus_dev_read(struct file *filp,
+                              char __user *ubuf,
+                              size_t len, loff_t *ppos)
+{
+       struct xenbus_dev_data *data = filp->private_data;
+       struct xsd_sockmsg msg;
+       int err;
 
-static int xenbus_dev_talkv(struct xenbus_dev_data *u, unsigned long data)
-{
-       struct xenbus_dev_talkv xt;
-       unsigned int len;
-       void *resp, *base;
-       struct kvec *iovec;
-       int ret = -EFAULT, v = 0;
+       /* Refill empty buffer? */
+       if (data->bytes_left == 0) {
+               if (len < sizeof(msg))
+                       return -EINVAL;
 
-       if (copy_from_user(&xt, (void *)data, sizeof(xt)))
-               return -EFAULT;
-
-       iovec = kmalloc(xt.num_vecs * sizeof(struct kvec), GFP_KERNEL);
-       if (iovec == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(iovec, xt.iovec,
-                          xt.num_vecs * sizeof(struct kvec)))
-               goto out;
-
-       for (v = 0; v < xt.num_vecs; v++) {
-               base = iovec[v].iov_base;
-               iovec[v].iov_base = kmalloc(iovec[v].iov_len, GFP_KERNEL);
-               if (iovec[v].iov_base == NULL ||
-                   copy_from_user(iovec[v].iov_base, base, iovec[v].iov_len))
-               {
-                       if (iovec[v].iov_base)
-                               kfree(iovec[v].iov_base);
-                       else
-                               ret = -ENOMEM;
-                       v--;
-                       goto out;
-               }
+               err = xb_read(&msg, sizeof(msg));
+               if (err)
+                       return err;
+               data->bytes_left = msg.len;
+               if (ubuf && copy_to_user(ubuf, &msg, sizeof(msg)) != 0)
+                       return -EFAULT;
+               /* We can receive spurious XS_WATCH_EVENT messages. */
+               if (msg.type != XS_WATCH_EVENT)
+                       data->awaiting_reply = 0;
+               return sizeof(msg);
        }
 
-       resp = xs_talkv(xt.type, iovec, xt.num_vecs, &len);
-       if (IS_ERR(resp)) {
-               ret = PTR_ERR(resp);
-               goto out;
-       }
+       /* Don't read over next header, or over temporary buffer. */
+       if (len > sizeof(data->u.buffer))
+               len = sizeof(data->u.buffer);
+       if (len > data->bytes_left)
+               len = data->bytes_left;
 
-       switch (xt.type) {
-       case XS_TRANSACTION_START:
-               u->in_transaction = 1;
-               break;
-       case XS_TRANSACTION_END:
-               u->in_transaction = 0;
-               break;
-       default:
-               break;
-       }
+       err = xb_read(data->u.buffer, len);
+       if (err)
+               return err;
 
-       ret = len;
-       if (len > xt.len)
-               len = xt.len;
-
-       if (copy_to_user(xt.buf, resp, len))
-               ret = -EFAULT;
-
-       kfree(resp);
- out:
-       while (v-- > 0)
-               kfree(iovec[v].iov_base);
-       kfree(iovec);
-       return ret;
+       data->bytes_left -= len;
+       if (ubuf && copy_to_user(ubuf, data->u.buffer, len) != 0)
+               return -EFAULT;
+       return len;
 }
 
-static int xenbus_dev_ioctl(struct inode *inode, struct file *filp,
-                           unsigned int cmd, unsigned long data)
+/* We do v. basic sanity checking so they don't screw up kernel later. */
+static ssize_t xenbus_dev_write(struct file *filp,
+                               const char __user *ubuf,
+                               size_t len, loff_t *ppos)
 {
-       struct xenbus_dev_data *u = filp->private_data;
-       int ret = -ENOSYS;
+       struct xenbus_dev_data *data = filp->private_data;
+       int err;
 
-       switch (cmd) {
-       case IOCTL_XENBUS_DEV_TALKV:
-               ret = xenbus_dev_talkv(u, data);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
+       /* We gather data in buffer until we're ready to send it. */
+       if (len > data->len + sizeof(data->u))
+               return -EINVAL;
+       if (copy_from_user(data->u.buffer + data->len, ubuf, len) != 0)
+               return -EFAULT;
+       data->len += len;
+       if (data->len >= sizeof(data->u.msg) + data->u.msg.len) {
+               err = xb_write(data->u.buffer, data->len);
+               if (err)
+                       return err;
+               data->len = 0;
+               data->awaiting_reply = 1;
        }
-       return ret;
+       return len;
 }
 
 static int xenbus_dev_open(struct inode *inode, struct file *filp)
 {
        struct xenbus_dev_data *u;
+
+       /* Don't try seeking. */
+       nonseekable_open(inode, filp);
 
        u = kmalloc(sizeof(*u), GFP_KERNEL);
        if (u == NULL)
@@ -155,20 +148,25 @@
 
 static int xenbus_dev_release(struct inode *inode, struct file *filp)
 {
-       struct xenbus_dev_data *u = filp->private_data;
+       struct xenbus_dev_data *data = filp->private_data;
 
-       if (u->in_transaction)
-               xenbus_transaction_end(1);
+       /* Discard any unread replies. */
+       while (data->bytes_left || data->awaiting_reply)
+               xenbus_dev_read(filp, NULL, sizeof(data->u.buffer), NULL);
+
+       /* Harmless if no transaction in progress. */
+       xenbus_transaction_end(1);
 
        up(&xenbus_lock);
 
-       kfree(u);
+       kfree(data);
 
        return 0;
 }
 
 static struct file_operations xenbus_dev_file_ops = {
-       .ioctl = xenbus_dev_ioctl,
+       .read = xenbus_dev_read,
+       .write = xenbus_dev_write,
        .open = xenbus_dev_open,
        .release = xenbus_dev_release,
 };
diff -r 282d5698ea40 -r 80afc502461b 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Mon Sep 12 
20:46:37 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Mon Sep 12 
21:12:16 2005
@@ -106,10 +106,10 @@
 }
 
 /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
-void *xs_talkv(enum xsd_sockmsg_type type,
-              const struct kvec *iovec,
-              unsigned int num_vecs,
-              unsigned int *len)
+static void *xs_talkv(enum xsd_sockmsg_type type,
+                     const struct kvec *iovec,
+                     unsigned int num_vecs,
+                     unsigned int *len)
 {
        struct xsd_sockmsg msg;
        void *ret = NULL;
diff -r 282d5698ea40 -r 80afc502461b tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Mon Sep 12 20:46:37 2005
+++ b/tools/xenstore/Makefile   Mon Sep 12 21:12:16 2005
@@ -17,7 +17,6 @@
 BASECFLAGS+= -I$(XEN_ROOT)/tools/libxc
 BASECFLAGS+= -I$(XEN_ROOT)/xen/include/public
 BASECFLAGS+= -I.
-BASECFLAGS+= -I$(XEN_ROOT)/linux-2.6-xen-sparse/include/asm-xen/linux-public
 
 CFLAGS  += $(BASECFLAGS)
 LDFLAGS += $(PROFILE) -L$(XEN_LIBXC)
diff -r 282d5698ea40 -r 80afc502461b tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Mon Sep 12 20:46:37 2005
+++ b/tools/xenstore/xs.c       Mon Sep 12 21:12:16 2005
@@ -36,12 +36,10 @@
 #include "xenstored.h"
 #include "xs_lib.h"
 #include "utils.h"
-#include "xenbus_dev.h"
 
 struct xs_handle
 {
        int fd;
-       enum { SOCK, DEV } type;
 };
 
 /* Get the socket from the store daemon handle.
@@ -68,7 +66,6 @@
                h = malloc(sizeof(*h));
                if (h) {
                        h->fd = sock;
-                       h->type = SOCK;
                        return h;
                }
        }
@@ -82,16 +79,15 @@
 static struct xs_handle *get_dev(const char *connect_to)
 {
        int fd, saved_errno;
-       struct xs_handle *h = NULL;
-
-       fd = open(connect_to, O_RDONLY);
+       struct xs_handle *h;
+
+       fd = open(connect_to, O_RDWR);
        if (fd < 0)
                return NULL;
 
        h = malloc(sizeof(*h));
        if (h) {
                h->fd = fd;
-               h->type = DEV;
                return h;
        }
 
@@ -190,9 +186,9 @@
 }
 
 /* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
-static void *xs_talkv_sock(struct xs_handle *h, enum xsd_sockmsg_type type,
-                          const struct iovec *iovec, unsigned int num_vecs,
-                          unsigned int *len)
+static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
+                     const struct iovec *iovec, unsigned int num_vecs,
+                     unsigned int *len)
 {
        struct xsd_sockmsg msg;
        void *ret = NULL;
@@ -250,54 +246,6 @@
        close(h->fd);
        h->fd = -1;
        errno = saved_errno;
-       return NULL;
-}
-
-/* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
-static void *xs_talkv_dev(struct xs_handle *h, enum xsd_sockmsg_type type,
-                         const struct iovec *iovec, unsigned int num_vecs,
-                         unsigned int *len)
-{
-       struct xenbus_dev_talkv dt;
-       char *buf;
-       int err, buflen = 1024;
-
- again:
-       buf = malloc(buflen);
-       if (buf == NULL) {
-               errno = ENOMEM;
-               return NULL;
-       }
-       dt.type = type;
-       dt.iovec = (struct kvec *)iovec;
-       dt.num_vecs = num_vecs;
-       dt.buf = buf;
-       dt.len = buflen;
-       err = ioctl(h->fd, IOCTL_XENBUS_DEV_TALKV, &dt);
-       if (err < 0) {
-               free(buf);
-               errno = err;
-               return NULL;
-       }
-       if (err > buflen) {
-               free(buf);
-               buflen = err;
-               goto again;
-       }
-       if (len)
-               *len = err;
-       return buf;
-}
-
-/* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
-static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
-                     const struct iovec *iovec, unsigned int num_vecs,
-                     unsigned int *len)
-{
-       if (h->type == SOCK)
-               return xs_talkv_sock(h, type, iovec, num_vecs, len);
-       if (h->type == DEV)
-               return xs_talkv_dev(h, type, iovec, num_vecs, len);
        return NULL;
 }
 
diff -r 282d5698ea40 -r 80afc502461b 
linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h
--- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h    Mon Sep 
12 20:46:37 2005
+++ /dev/null   Mon Sep 12 21:12:16 2005
@@ -1,47 +0,0 @@
-/*
- * xenbus_dev.h
- * 
- * Copyright (c) 2005, Christian Limpach
- * 
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef _XENBUS_DEV_H_
-#define _XENBUS_DEV_H_
-
-struct xenbus_dev_talkv {
-       enum xsd_sockmsg_type type;
-       const struct kvec *iovec;
-       unsigned int num_vecs;
-       char *buf;
-       unsigned int len;
-};
-
-/*
- * @cmd: IOCTL_XENBUS_DEV_TALKV
- * @arg: struct xenbus_dev_talkv
- * Return: 0 on success, error code on failure.
- */
-#define        IOCTL_XENBUS_DEV_TALKV \
-       _IOC(_IOC_NONE, 'X', 0, sizeof(struct xenbus_dev_talkv))
-
-#endif /* _XENBUS_DEV_H_ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Change xenbus_dev interface from ioctl to read/write., Xen patchbot -unstable <=