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 #include #include +#include #include #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;cntrpid)) { + 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;cntrpid, 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; }