Index: xen-3.3.1-testing/tools/blktap/drivers/blktapctrl.c =================================================================== --- xen-3.3.1-testing.orig/tools/blktap/drivers/blktapctrl.c +++ xen-3.3.1-testing/tools/blktap/drivers/blktapctrl.c @@ -662,9 +662,6 @@ static int blktapctrl_new_blkif(blkif_t DPRINTF("Received a poll for a new vbd\n"); if ( ((blk=blkif->info) != NULL) && (blk->params != NULL) ) { - if (blktap_interface_create(ctlfd, &major, &minor, blkif) < 0) - return -1; - if (test_path(blk->params, &ptr, &type, &exist, &use_ioemu) != 0) { DPRINTF("Error in blktap device string(%s).\n", blk->params); @@ -693,10 +690,6 @@ static int blktapctrl_new_blkif(blkif_t blkif->fds[WRITE] = exist->fds[WRITE]; } - add_disktype(blkif, type); - blkif->major = major; - blkif->minor = minor; - image = (image_t *)malloc(sizeof(image_t)); blkif->prv = (void *)image; blkif->ops = &tapdisk_ops; @@ -720,11 +713,18 @@ static int blktapctrl_new_blkif(blkif_t goto fail; } + if (blktap_interface_create(ctlfd, &major, &minor, blkif) < 0) + return -1; + + blkif->major = major; + blkif->minor = minor; + + add_disktype(blkif, type); + } else return -1; return 0; fail: - ioctl(ctlfd, BLKTAP_IOCTL_FREEINTF, minor); return -EINVAL; } Index: xen-3.3.1-testing/tools/blktap/lib/xenbus.c =================================================================== --- xen-3.3.1-testing.orig/tools/blktap/lib/xenbus.c +++ xen-3.3.1-testing/tools/blktap/lib/xenbus.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "blktaplib.h" #include "list.h" #include "xs_api.h" @@ -149,6 +150,37 @@ static int backend_remove(struct xs_hand return 0; } +static int check_image(struct backend_info *be, const char** errmsg) +{ + const char *path; + int mode; + blkif_t *blkif = be->blkif; + blkif_info_t *info = blkif->info; + + /* Strip off the image type */ + path = strchr(info->params, ':'); + if (path == NULL) + path = info->params; + else + path++; + + /* Check if the image exists and access is permitted */ + mode = R_OK; + if (!be->readonly) + mode |= W_OK; + if (access(path, mode)) { + if (errno == ENOENT) + *errmsg = "File not found."; + else + *errmsg = "Insufficient file permissions."; + return -1; + } + + /* TODO Check that the image is not attached to a different VM */ + + return 0; +} + static void ueblktap_setup(struct xs_handle *h, char *bepath) { struct backend_info *be; @@ -156,6 +188,7 @@ static void ueblktap_setup(struct xs_han int len, er, deverr; long int pdev = 0, handle; blkif_info_t *blk; + const char* errmsg = NULL; be = be_lookup_be(bepath); if (be == NULL) @@ -211,6 +244,9 @@ static void ueblktap_setup(struct xs_han be->pdev = pdev; } + if (check_image(be, &errmsg)) + goto fail; + er = blkif_init(be->blkif, handle, be->pdev, be->readonly); if (er != 0) { DPRINTF("Unable to open device %s\n",blk->params); @@ -246,12 +282,21 @@ static void ueblktap_setup(struct xs_han } be->blkif->state = CONNECTED; + xs_printf(h, be->backpath, "hotplug-status", "connected"); + DPRINTF("[SETUP] Complete\n\n"); goto close; fail: - if ( (be != NULL) && (be->blkif != NULL) ) + if (be) { + if (errmsg == NULL) + errmsg = "Setting up the backend failed. See the log " + "files in /var/log/xen/ for details."; + xs_printf(h, be->backpath, "hotplug-error", errmsg); + xs_printf(h, be->backpath, "hotplug-status", "error"); + backend_remove(h, be); + } close: if (path) free(path); @@ -286,7 +331,8 @@ static void ueblktap_probe(struct xs_han len = strsep_len(bepath, '/', 7); if (len < 0) goto free_be; - bepath[len] = '\0'; + if (bepath[len] != '\0') + goto free_be; be = malloc(sizeof(*be)); if (!be) { Index: xen-3.3.1-testing/tools/examples/xen-backend.rules =================================================================== --- xen-3.3.1-testing.orig/tools/examples/xen-backend.rules +++ xen-3.3.1-testing/tools/examples/xen-backend.rules @@ -1,4 +1,3 @@ -SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACTION}" SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}" SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}" SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} online"