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

[Xen-changelog] [xen-unstable] [BLKTAP] have udev create the device for blktap



# HG changeset patch
# User Andrew Warfield <andy@xxxxxxxxxxxxx>
# Node ID d90be316e5f5852da5626d1b1a72d890a5c18000
# Parent  500043f8ccff0338363da8b08e39827b522f7b6a
[BLKTAP] have udev create the device for blktap
This patch makes blktap Do The Right Thing(TM).  It allows udev to
create the /dev/xen/blktap[0-9] devices.

It creates a sysfs class called "xen".  This part may later be placed
someplace else, but currently blktap is the only user so it is placed in
the blktap code.

When blktap is initialized, a blktap0 sysfs class device is made.  The
other devices blktapX (X > 0) are made when the BLKTAP_IOCTL_NEWINTF
ioctl is called.  This way we don't flood the sysfs and /dev/xen with
unnecessary devices.

I added a rule in the xen-backend.rules to allow for udev to create the
blktap devices.

With this, we can really remove the code to search and create the
/dev/xen/blktap[0-9]*, but I'll leave it in for now. With the use of
udev, we really should remove that code as well as the code for creating
the evtchn device.  udev works for both of these now.  But that removal
will have to be in another patch.

Signed-off-by: Steven Rostedt <srostedt@xxxxxxxxxx>
---
 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c |   68 ++++++++++++++++++++---
 tools/examples/xen-backend.rules                 |    1 
 2 files changed, 63 insertions(+), 6 deletions(-)

diff -r 500043f8ccff -r d90be316e5f5 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Thu Sep 28 12:47:45 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Thu Sep 28 13:44:00 
2006 -0700
@@ -44,7 +44,6 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/miscdevice.h>
 #include <linux/errno.h>
 #include <linux/major.h>
 #include <linux/gfp.h>
@@ -54,6 +53,30 @@
 
 #define MAX_TAP_DEV 100     /*the maximum number of tapdisk ring devices    */
 #define MAX_DEV_NAME 100    /*the max tapdisk ring device name e.g. blktap0 */
+
+
+struct class *xen_class;
+EXPORT_SYMBOL_GPL(xen_class);
+
+/*
+ * Setup the xen class.  This should probably go in another file, but
+ * since blktap is the only user of it so far, it gets to keep it.
+ */
+int setup_xen_class(void)
+{
+       int ret;
+
+       if (xen_class)
+               return 0;
+
+       xen_class = class_create(THIS_MODULE, "xen");
+       if ((ret = IS_ERR(xen_class))) {
+               xen_class = NULL;
+               return ret;
+       }
+
+       return 0;
+}
 
 /*
  * The maximum number of requests that can be outstanding at any time
@@ -100,6 +123,7 @@ typedef struct tap_blkif {
        unsigned long *idx_map;       /*Record the user ring id to kern 
                                        [req id, idx] tuple                  */
        blkif_t *blkif;               /*Associate blkif with tapdev          */
+       int sysfs_set;                /*Set if it has a class device.        */
 } tap_blkif_t;
 
 /*Data struct handed back to userspace for tapdisk device to VBD mapping*/
@@ -304,8 +328,6 @@ static int blktap_ioctl(struct inode *in
                         unsigned int cmd, unsigned long arg);
 static unsigned int blktap_poll(struct file *file, poll_table *wait);
 
-struct miscdevice *set_misc(int minor, char *name, int dev);
-
 static struct file_operations blktap_fops = {
        .owner   = THIS_MODULE,
        .poll    = blktap_poll,
@@ -337,6 +359,16 @@ static int get_next_free_dev(void)
        
 done:
        spin_unlock_irqrestore(&pending_free_lock, flags);
+
+       /*
+        * We are protected by having the dev_pending set.
+        */
+       if (!tapfds[i]->sysfs_set && xen_class) {
+               class_device_create(xen_class, NULL,
+                                   MKDEV(blktap_major, ret), NULL,
+                                   "blktap%d", ret);
+               tapfds[i]->sysfs_set = 1;
+       }
        return ret;
 }
 
@@ -428,7 +460,7 @@ static int blktap_release(struct inode *
        if (!info) {
                WPRINTK("Trying to free device that doesn't exist "
                       "[/dev/xen/blktap%d]\n",iminor(inode) - BLKTAP_MINOR);
-               return -1;
+               return -EBADF;
        }
        info->dev_inuse = 0;
        DPRINTK("Freeing device [/dev/xen/blktap%d]\n",info->minor);
@@ -602,6 +634,7 @@ static int blktap_ioctl(struct inode *in
        case BLKTAP_IOCTL_FREEINTF:
        {
                unsigned long dev = arg;
+               unsigned long flags;
 
                /* Looking at another device */
                info = NULL;
@@ -609,8 +642,11 @@ static int blktap_ioctl(struct inode *in
                if ( (dev > 0) && (dev < MAX_TAP_DEV) )
                        info = tapfds[dev];
 
+               spin_lock_irqsave(&pending_free_lock, flags);
                if ( (info != NULL) && (info->dev_pending) )
                        info->dev_pending = 0;
+               spin_unlock_irqrestore(&pending_free_lock, flags);
+
                return 0;
        }
        case BLKTAP_IOCTL_MINOR:
@@ -1371,7 +1407,8 @@ static int __init blkif_init(void)
 
        for(i = 0; i < MAX_TAP_DEV; i++ ) {
                info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL);
-               if(tapfds[i] == NULL) return -ENOMEM;
+               if(tapfds[i] == NULL)
+                       return -ENOMEM;
                info->minor = i;
                info->pid = 0;
                info->blkif = NULL;
@@ -1379,12 +1416,31 @@ static int __init blkif_init(void)
                ret = devfs_mk_cdev(MKDEV(blktap_major, i),
                        S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", i);
 
-               if(ret != 0) return -ENOMEM;
+               if(ret != 0)
+                       return -ENOMEM;
                info->dev_pending = info->dev_inuse = 0;
 
                DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i);
        }
        
+       /* Make sure the xen class exists */
+       if (!setup_xen_class()) {
+               /*
+                * This will allow udev to create the blktap ctrl device.
+                * We only want to create blktap0 first.  We don't want
+                * to flood the sysfs system with needless blktap devices.
+                * We only create the device when a request of a new device is
+                * made.
+                */
+               class_device_create(xen_class, NULL,
+                                   MKDEV(blktap_major, 0), NULL,
+                                   "blktap0");
+               tapfds[0]->sysfs_set = 1;
+       } else {
+               /* this is bad, but not fatal */
+               WPRINTK("blktap: sysfs xen_class not created\n");
+       }
+
        DPRINTK("Blktap device successfully created\n");
 
        return 0;
diff -r 500043f8ccff -r d90be316e5f5 tools/examples/xen-backend.rules
--- a/tools/examples/xen-backend.rules  Thu Sep 28 12:47:45 2006 -0700
+++ b/tools/examples/xen-backend.rules  Thu Sep 28 13:44:00 2006 -0700
@@ -5,3 +5,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vif*"
 SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", 
RUN+="$env{script} offline"
 SUBSYSTEM=="xen-backend", ACTION=="remove", 
RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
 KERNEL=="evtchn", NAME="xen/%k"
+KERNEL=="blktap[0-9]*", NAME="xen/%k"

_______________________________________________
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®.