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

[Xen-devel] [PATCH][Linux-2.6.18-xen.hg] Ad I/O suspend/resume to blktap



This patch adds I/O suspend / resume functionality to blktap.

When suspending ...

        I/O requests and ignored
        inflight I/Os are completed (up to the 5 min timeout)
        the suspend() call is synchronous (with a 5 min timeout)

        tapdisk associated with the vdisk is shot down (SIGHUP)

        internal I/O "scheduler" thread is cancelled

When resuming ...

        blktap is directed to process I/O requests once again.

        tapdisk is resurected via blktapcntrl and a xenstore watch

        internal I/O "scheduler" thread is created

Signed-off-by: Ben Guthro
Signed-off-by: Josh Nicholas <jnicholas@xxxxxxxxxxxxxxx>

diff -r 8341d8acbd7c drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c       Thu Aug 02 10:38:33 2007 -0400
+++ b/drivers/xen/blktap/blktap.c       Thu Aug 02 10:38:33 2007 -0400
@@ -52,6 +52,7 @@
 #include <linux/major.h>
 #include <linux/gfp.h>
 #include <linux/poll.h>
+#include <linux/delay.h>
 #include <asm/tlbflush.h>
 
 #define MAX_TAP_DEV 256     /*the maximum number of tapdisk ring devices    */
@@ -550,6 +551,63 @@ void signal_tapdisk(int idx)
        info->blkif = NULL;
 
        return;
+}
+
+int ensure_tapdisk_shutdown(blkif_t *blkif)
+{
+       int err;
+       tap_blkif_t *info;
+       unsigned int cntr;
+
+       info = tapfds[blkif->dev_num];
+       if (info == NULL) {
+               WPRINTK("%s() tapdisk info is missing for %d\n",  __FUNCTION__, 
(int)blkif->domid);
+               return -EINVAL;
+       }
+
+       if (info->pid < 1)
+               return 0;
+
+#define        kTAPDISK_SIGHUP_TIMEOUT_IN_SECS         10
+#define        kTAPDISK_SIGKILL_TIMEOUT_IN_SECS        8
+
+       err = kill_proc(info->pid, SIGHUP, 1);
+       if (err && (err != -ESRCH) && find_task_by_pid(info->pid)) {
+               WPRINTK("%s() SIGHUP to %u failed (%d) - attempting SIGKILL\n", 
__FUNCTION__, (unsigned int)info->pid, err);
+               err = kill_proc(info->pid, SIGKILL, 1);
+               if (err && find_task_by_pid(info->pid)) {
+                       WPRINTK("%s() SIGKILL to %u failed (%d) - abandoning 
!?!\n", __FUNCTION__, (unsigned int)info->pid, err);
+                       return err;
+               }
+       }
+
+       DPRINTK("tapdisk %u signaled for %d - now waiting\n", (unsigned 
int)info->pid, (int)blkif->domid);
+
+       for (cntr=0;cntr<kTAPDISK_SIGHUP_TIMEOUT_IN_SECS;++cntr) {
+               msleep(1000);
+               if (!find_task_by_pid(info->pid)) {
+                       DPRINTK("tapdisk %u for %d done [h:%u]\n", (unsigned 
int)info->pid, (int)blkif->domid, cntr);
+                       return 0;
+               }
+       }
+
+       DPRINTK("tapdisk %u SIGHUP failed for %d - now SIGKILLing\n", (unsigned 
int)info->pid, (int)blkif->domid);
+
+       for (cntr=0;cntr<kTAPDISK_SIGKILL_TIMEOUT_IN_SECS;++cntr) {
+               err = kill_proc(info->pid, SIGKILL, 1);
+               msleep(1000);
+               if (!find_task_by_pid(info->pid)) {
+                       DPRINTK("tapdisk %u for %d done [k:%u]\n", (unsigned 
int)info->pid, (int)blkif->domid, cntr);
+                       return 0;
+               }
+               if (err) {
+                       WPRINTK("%s() SIGKILL to %u failed (%d) - abandoning 
!?!\n", __FUNCTION__, (unsigned int)info->pid, err);
+                       return err;
+               }
+       }
+
+       WPRINTK("%s() tapdisk %u SIGKILLing failed for %d - abandoning !?!\n", 
__FUNCTION__, (unsigned int)info->pid, (int)blkif->domid);
+       return -EAGAIN;
 }
 
 static int blktap_open(struct inode *inode, struct file *filp)
diff -r 8341d8acbd7c drivers/xen/blktap/common.h
--- a/drivers/xen/blktap/common.h       Thu Aug 02 10:38:33 2007 -0400
+++ b/drivers/xen/blktap/common.h       Thu Aug 02 10:38:33 2007 -0400
@@ -117,5 +117,6 @@ int tap_blkif_schedule(void *arg);
 
 int dom_to_devid(domid_t domid, int xenbus_id, blkif_t *blkif);
 void signal_tapdisk(int idx);
+int ensure_tapdisk_shutdown(blkif_t *blkif);
 
 #endif /* __BLKIF__BACKEND__COMMON_H__ */
diff -r 8341d8acbd7c drivers/xen/blktap/xenbus.c
--- a/drivers/xen/blktap/xenbus.c       Thu Aug 02 10:38:33 2007 -0400
+++ b/drivers/xen/blktap/xenbus.c       Thu Aug 02 10:38:33 2007 -0400
@@ -178,9 +178,12 @@ static int blktap_remove(struct xenbus_d
                be->backend_watch.node = NULL;
        }
        if (be->blkif) {
-               if (be->blkif->xenblkd)
+               if (be->blkif->xenblkd) {
                        kthread_stop(be->blkif->xenblkd);
+                       be->blkif->xenblkd = NULL;
+               }
                signal_tapdisk(be->blkif->dev_num);
+               ensure_tapdisk_shutdown(be->blkif);
                tap_blkif_free(be->blkif);
                be->blkif = NULL;
        }
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

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