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

[Xen-changelog] Add driver to use the kernel's xenbus connection from user-space.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 87ea297c1d3adeaa277cdef44bc03d399cf90a86
# Parent  c7e4e2fc4f4a8d68366fb153ed20d2edd7fd750b
Add driver to use the kernel's xenbus connection from user-space.
The driver exports xs_talkv to user-space, allowing programs running in
the domain to use the kernel's xenbus connection.  Intended use is driver
domain device configuration where the driver domain is not the domain
running xenstored.
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r c7e4e2fc4f4a -r 87ea297c1d3a 
linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile  Sat Sep  3 16:32:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile  Sat Sep  3 16:52:12 2005
@@ -4,3 +4,4 @@
 xenbus-objs += xenbus_comms.o
 xenbus-objs += xenbus_xs.o
 xenbus-objs += xenbus_probe.o 
+xenbus-objs += xenbus_dev.o 
diff -r c7e4e2fc4f4a -r 87ea297c1d3a 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sat Sep  3 
16:32:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sat Sep  3 
16:52:12 2005
@@ -106,10 +106,10 @@
 }
 
 /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
-static void *xs_talkv(enum xsd_sockmsg_type type,
-                     const struct kvec *iovec,
-                     unsigned int num_vecs,
-                     unsigned int *len)
+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;
@@ -557,7 +557,7 @@
                        BUG_ON(!w);
                        w->callback(w, node);
                        kfree(node);
-               } else
+               } else if (node)
                        printk(KERN_WARNING "XENBUS xs_read_watch: %li\n",
                               PTR_ERR(node));
                up(&xenbus_lock);
diff -r c7e4e2fc4f4a -r 87ea297c1d3a 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- /dev/null   Sat Sep  3 16:32:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Sat Sep  3 
16:52:12 2005
@@ -0,0 +1,186 @@
+/*
+ * xenbus_dev.c
+ * 
+ * Driver giving user-space access to the kernel's xenbus connection
+ * to xenstore.
+ * 
+ * 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.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/uio.h>
+#include <linux/notifier.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+
+#include "xenstored.h"
+#include "xenbus_comms.h"
+
+#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;
+};
+
+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);
+
+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;
+
+       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;
+               }
+       }
+
+       resp = xs_talkv(xt.type, iovec, xt.num_vecs, &len);
+       if (IS_ERR(resp)) {
+               ret = PTR_ERR(resp);
+               goto out;
+       }
+
+       switch (xt.type) {
+       case XS_TRANSACTION_START:
+               u->in_transaction = 1;
+               break;
+       case XS_TRANSACTION_END:
+               u->in_transaction = 0;
+               break;
+       default:
+               break;
+       }
+
+       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;
+}
+
+static int xenbus_dev_ioctl(struct inode *inode, struct file *filp,
+                           unsigned int cmd, unsigned long data)
+{
+       struct xenbus_dev_data *u = filp->private_data;
+       int ret = -ENOSYS;
+
+       switch (cmd) {
+       case IOCTL_XENBUS_DEV_TALKV:
+               ret = xenbus_dev_talkv(u, data);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int xenbus_dev_open(struct inode *inode, struct file *filp)
+{
+       struct xenbus_dev_data *u;
+
+       u = kmalloc(sizeof(*u), GFP_KERNEL);
+       if (u == NULL)
+               return -ENOMEM;
+
+       memset(u, 0, sizeof(*u));
+
+       filp->private_data = u;
+
+       down(&xenbus_lock);
+
+       return 0;
+}
+
+static int xenbus_dev_release(struct inode *inode, struct file *filp)
+{
+       struct xenbus_dev_data *u = filp->private_data;
+
+       if (u->in_transaction)
+               xenbus_transaction_end(1);
+
+       up(&xenbus_lock);
+
+       kfree(u);
+
+       return 0;
+}
+
+static struct file_operations xenbus_dev_file_ops = {
+       ioctl: xenbus_dev_ioctl,
+       open: xenbus_dev_open,
+       release: xenbus_dev_release
+};
+
+static int __init
+xenbus_dev_init(void)
+{
+       xenbus_dev_intf = create_xen_proc_entry("xenbus", 0400);
+       if (xenbus_dev_intf)
+               xenbus_dev_intf->proc_fops = &xenbus_dev_file_ops;
+
+       return 0;
+}
+
+__initcall(xenbus_dev_init);
diff -r c7e4e2fc4f4a -r 87ea297c1d3a 
linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h
--- /dev/null   Sat Sep  3 16:32:53 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h    Sat Sep 
 3 16:52:12 2005
@@ -0,0 +1,47 @@
+/*
+ * 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


 


Rackspace

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