Index: xen-4.0.0-testing/tools/blktap/drivers/blktapctrl.c =================================================================== --- xen-4.0.0-testing.orig/tools/blktap/drivers/blktapctrl.c +++ xen-4.0.0-testing/tools/blktap/drivers/blktapctrl.c @@ -347,6 +347,7 @@ static int write_msg(int fd, int msgtype msg_dev = (msg_newdev_t *)(buf + sizeof(msg_hdr_t)); msg_dev->devnum = blkif->minor; msg_dev->domid = blkif->domid; + msg_dev->be_id = blkif->be_id; break; Index: xen-4.0.0-testing/tools/blktap/lib/blktaplib.h =================================================================== --- xen-4.0.0-testing.orig/tools/blktap/lib/blktaplib.h +++ xen-4.0.0-testing/tools/blktap/lib/blktaplib.h @@ -189,6 +189,7 @@ typedef struct msg_hdr { typedef struct msg_newdev { uint8_t devnum; uint16_t domid; + uint32_t be_id; } msg_newdev_t; typedef struct msg_pid { Index: xen-4.0.0-testing/tools/ioemu-remote/hw/xen_blktap.c =================================================================== --- xen-4.0.0-testing.orig/tools/ioemu-remote/hw/xen_blktap.c +++ xen-4.0.0-testing/tools/ioemu-remote/hw/xen_blktap.c @@ -67,6 +67,8 @@ int write_fd; static pid_t process; fd_list_entry_t *fd_start = NULL; +extern char* get_snapshot_name(int devid); + static void handle_blktap_iomsg(void* private); struct aiocb_info { @@ -500,6 +502,10 @@ static void handle_blktap_ctrlmsg(void* char buf[MSG_SIZE]; +#ifndef QEMU_TOOL + char *snapshot; +#endif + length = read(read_fd, buf, MSG_SIZE); if (length > 0 && length >= sizeof(msg_hdr_t)) @@ -555,7 +561,39 @@ static void handle_blktap_ctrlmsg(void* if (s != NULL) { ret = ((map_new_dev(s, msg_dev->devnum) == msg_dev->devnum ? 0: -1)); - } + } + +#ifndef QEMU_TOOL + fprintf(stderr, "Reading snapshot name for %d\n", msg_dev->be_id); + snapshot = get_snapshot_name(msg_dev->be_id); + if (snapshot) { + fprintf(stderr, "Using snapshot %s\n", snapshot); + ret = bdrv_snapshot_goto(s->bs, snapshot); + switch (ret) { + case 0: + /* Success */ + break; + case -ENOTSUP: + if (s->flags & TD_RDONLY) { + fprintf(stderr, "Snapshots not supported for " + "image format of a read-only image\n"); + } else { + fprintf(stderr, "Snapshots not supported " + "for this image format"); + ret = -1; + } + break; + case -ENOENT: + fprintf(stderr, "No such snapshot"); + ret = -1; + break; + default: + fprintf(stderr, "Could not load snapshot"); + ret = -1; + break; + } + } +#endif memset(buf, 0x00, MSG_SIZE); msglen = sizeof(msg_hdr_t); Index: xen-4.0.0-testing/tools/ioemu-remote/xenstore.c =================================================================== --- xen-4.0.0-testing.orig/tools/ioemu-remote/xenstore.c +++ xen-4.0.0-testing/tools/ioemu-remote/xenstore.c @@ -103,6 +103,8 @@ int xenstore_watch_new_callback(const ch } +char* get_snapshot_name(int devid); + static int pasprintf(char **buf, const char *fmt, ...) { va_list ap; @@ -644,8 +646,33 @@ void xenstore_parse_domain_config(int hv } } pstrcpy(bs->filename, sizeof(bs->filename), params); - if (bdrv_open2(bs, params, BDRV_O_CACHE_WB /* snapshot and write-back */, format) < 0) + if (bdrv_open2(bs, params, BDRV_O_CACHE_WB /* snapshot and write-back */, format) < 0) { fprintf(stderr, "qemu: could not open vbd '%s' or hard disk image '%s' (drv '%s' format '%s')\n", buf, params, drv ? drv : "?", format ? format->format_name : "0"); + } else { + char* snapshot = get_snapshot_name(atoi(e_danger[i])); + if (snapshot) { + fprintf(stderr, "Using snapshot %s\n", snapshot); + ret = bdrv_snapshot_goto(bs, snapshot); + switch (ret) { + case 0: + /* Success */ + break; + case -ENOTSUP: + /* Don't abort here (could be read-only ISO) */ + fprintf(stderr, "Snapshots are not supported for " + "this image file format\n"); + break; + case -ENOENT: + fprintf(stderr, "No such snapshot, skipping this " + "image file\n"); + continue; + default: + fprintf(stderr, "Could not load snapshot, skipping" + " this image file\n"); + continue; + } + } + } } #endif @@ -779,6 +806,23 @@ int xenstore_parse_disable_pf_config () return disable_pf; } + +char* get_snapshot_name(int devid) +{ + char* path = NULL; + char* name = NULL; + unsigned int len; + + if (pasprintf(&path, + "/local/domain/0/backend/tap/%u/%u/snapshot", domid, devid) == -1) + return NULL; + name = xs_read(xsh, XBT_NULL, path, &len); + + free(path); + return name; +} + + int xenstore_fd(void) { if (xsh)