Ad I/O suspend/resume to blktap
PATCH 1/1 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 <[email protected]>
drivers/xen/blktap/blktap.c +58 -0
@@ -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)
drivers/xen/blktap/common.h +1 -0
@@ -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__ */
drivers/xen/blktap/xenbus.c +4 -1
@@ -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
[email protected]
http://lists.xensource.com/xen-devel