Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2
xen
snapshot-without-pv-fix.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File snapshot-without-pv-fix.patch of Package xen
Subject: add the drive into drives_table[] only if guest is using PV driver now when blktapctrl asks qemu to add a device, it also set a watch on the xenstore backend state path of the device, e.g. /local/domain/<domian-id>/device/vbd/<device-id>/state and when the state changed to 4, that means guest is using the PV driver and it's ready, so the watch will tell qemu to add the disk entry to drives_table[], otherwise the disk in qemu will just stay opened,not showing up in drives_table[]. Index: xen-4.1.2-testing/tools/blktap/drivers/blktapctrl.c =================================================================== --- xen-4.1.2-testing.orig/tools/blktap/drivers/blktapctrl.c +++ xen-4.1.2-testing/tools/blktap/drivers/blktapctrl.c @@ -380,7 +380,22 @@ static int write_msg(int fd, int msgtype msg->cookie = blkif->cookie; break; - + + case CTLMSG_ADDDEV: + DPRINTF("Write_msg called: CTLMSG_ADDDEV\n"); + + msglen = sizeof(msg_hdr_t); + buf = malloc(msglen); + + /*Assign header fields*/ + msg = (msg_hdr_t *)buf; + msg->type = CTLMSG_ADDDEV; + msg->len = msglen; + msg->drivertype = blkif->drivertype; + msg->cookie = blkif->cookie; + + break; + default: return -1; } @@ -475,6 +490,12 @@ static int read_msg(int fd, int msgtype, DPRINTF("\tPID: [%d]\n",blkif->tappid); } break; + + case CTLMSG_ADDDEV_RSP: + DPRINTF("Received CTLMSG_ADDDEV_RSP\n"); + if (msgtype != CTLMSG_ADDDEV_RSP) ret = 0; + break; + default: DPRINTF("UNKNOWN MESSAGE TYPE RECEIVED\n"); ret = 0; @@ -757,6 +778,63 @@ static int unmap_blktapctrl(blkif_t *blk return 0; } +static int blktapctrl_blkif_state(blkif_t *blkif, XenbusState state) +{ + struct disk_info *drivertype = NULL; + + if (!blkif) + return -EINVAL; + + switch (state) + { + case XenbusStateUnknown: + break; + + case XenbusStateInitialising: + break; + + case XenbusStateInitWait: + break; + + case XenbusStateInitialised: + break; + + case XenbusStateConnected: + drivertype = dtypes[blkif->drivertype]; + if (drivertype->use_ioemu && blkif->state == CONNECTED) { + if (write_msg(blkif->fds[WRITE], CTLMSG_ADDDEV, blkif, NULL) + <=0) { + DPRINTF("Write_msg failed - CTLMSG_ADDDEV\n"); + return -1; + } + if (read_msg(blkif->fds[READ], CTLMSG_ADDDEV_RSP, blkif) <= 0) { + DPRINTF("Read_msg failure - CTLMSG_ADDDEV\n"); + return -1; + } + } + + break; + + case XenbusStateClosing: + break; + + case XenbusStateClosed: + break; + + case XenbusStateReconfiguring: + break; + + case XenbusStateReconfigured: + break; + + default: + DPRINTF("Unrecognized XenbusState %d\n", state); + return -1; + } + + return 0; +} + int open_ctrl_socket(char *devname) { int ret; @@ -853,6 +931,7 @@ int main(int argc, char *argv[]) register_new_blkif_hook(blktapctrl_new_blkif); register_new_devmap_hook(map_new_blktapctrl); register_new_unmap_hook(unmap_blktapctrl); + register_blkif_state_hook(blktapctrl_blkif_state); ctlfd = blktap_interface_open(); if (ctlfd < 0) { Index: xen-4.1.2-testing/tools/blktap/lib/blkif.c =================================================================== --- xen-4.1.2-testing.orig/tools/blktap/lib/blkif.c +++ xen-4.1.2-testing/tools/blktap/lib/blkif.c @@ -89,6 +89,11 @@ void register_new_blkif_hook(int (*fn)(b { new_blkif_hook = fn; } +static int (*blkif_state_hook)(blkif_t *blkif, XenbusState state) = NULL; +void register_blkif_state_hook(int (*fn)(blkif_t *blkif, XenbusState state)) +{ + blkif_state_hook = fn; +} int blkif_init(blkif_t *blkif, long int handle, long int pdev, long int readonly) @@ -179,6 +184,24 @@ void free_blkif(blkif_t *blkif) } } +int blkif_handle_state(blkif_t *blkif, XenbusState state) +{ + if (blkif == NULL) + return -EINVAL; + + if (blkif_state_hook == NULL) + { + DPRINTF("Probe handling blkif state, but no blkif_state_hook!\n"); + return -1; + } + if (blkif_state_hook(blkif, state)!=0) { + DPRINTF("BLKIF: blkif_state_hook failed!\n"); + return -1; + } + + return 0; +} + void __init_blkif(void) { memset(blkif_hash, 0, sizeof(blkif_hash)); Index: xen-4.1.2-testing/tools/blktap/lib/blktaplib.h =================================================================== --- xen-4.1.2-testing.orig/tools/blktap/lib/blktaplib.h +++ xen-4.1.2-testing/tools/blktap/lib/blktaplib.h @@ -38,6 +38,7 @@ #include <xen/xen.h> #include <xen/io/blkif.h> #include <xen/io/ring.h> +#include <xen/io/xenbus.h> #include <xs.h> #include <sys/types.h> #include <unistd.h> @@ -138,11 +139,13 @@ typedef struct blkif_info { void register_new_devmap_hook(int (*fn)(blkif_t *blkif)); void register_new_unmap_hook(int (*fn)(blkif_t *blkif)); void register_new_blkif_hook(int (*fn)(blkif_t *blkif)); +void register_blkif_state_hook(int (*fn)(blkif_t *blkif, XenbusState state)); blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle); blkif_t *alloc_blkif(domid_t domid); int blkif_init(blkif_t *blkif, long int handle, long int pdev, long int readonly); void free_blkif(blkif_t *blkif); +int blkif_handle_state(blkif_t *blkif, XenbusState state); void __init_blkif(void); typedef struct busy_state { @@ -210,6 +213,8 @@ typedef struct msg_pid { #define CTLMSG_CLOSE_RSP 8 #define CTLMSG_PID 9 #define CTLMSG_PID_RSP 10 +#define CTLMSG_ADDDEV 11 +#define CTLMSG_ADDDEV_RSP 12 /* disk driver types */ #define MAX_DISK_TYPES 20 Index: xen-4.1.2-testing/tools/blktap/lib/xenbus.c =================================================================== --- xen-4.1.2-testing.orig/tools/blktap/lib/xenbus.c +++ xen-4.1.2-testing/tools/blktap/lib/xenbus.c @@ -318,6 +318,72 @@ static int check_image(struct xs_handle return 0; } +static void check_frontend_state(struct xs_handle *h, struct xenbus_watch *w, + const char *state_path_im) +{ + struct backend_info *be = NULL; + struct blkif *blkif = NULL; + char *fepath = NULL, *bepath = NULL; + XenbusState state; + int er, len; + + len = strsep_len(state_path_im, '/', 6); + if (len < 0) + return; + if (!(fepath = malloc(len + 1))) + return; + memset(fepath, 0, len + 1); + strncpy(fepath, state_path_im, len); + + er = xs_gather(h, fepath, "state", "%d", &state, + "backend", NULL, &bepath, + NULL); + + if (er) { + DPRINTF("Error getting state [%s]\n", fepath); + goto free_fe; + } + + be = be_lookup_be(bepath); + if (!be || !be->blkif) + goto free_fe; + + blkif = be->blkif; + blkif_handle_state(blkif, state); + +free_fe: + if (fepath) + free(fepath); + if (bepath) + free(bepath); + return; +} + +static int add_blockdevice_state_watch(struct xs_handle *h, const char *frontend) +{ + char *path = NULL; + struct xenbus_watch *vbd_watch; + + if (asprintf(&path, frontend) == -1) + return -ENOMEM; + if (!(path = realloc(path, strlen(path) + strlen("/state") + 1))) + return -ENOMEM; + strcpy(path + strlen(path), "/state"); + + vbd_watch = (struct xenbus_watch *)malloc(sizeof(struct xenbus_watch)); + if (!vbd_watch) { + DPRINTF("ERROR: unable to malloc vbd_watch [%s]\n", path); + return -EINVAL; + } + vbd_watch->node = path; + vbd_watch->callback = check_frontend_state; + if (register_xenbus_watch(h, vbd_watch) != 0) { + DPRINTF("ERROR: adding vbd probe watch %s\n", path); + return -EINVAL; + } + return 0; +} + static void ueblktap_setup(struct xs_handle *h, char *bepath) { struct backend_info *be; @@ -512,6 +578,9 @@ static void ueblktap_probe(struct xs_han be->backpath = bepath; be->frontpath = frontend; + + if (add_blockdevice_state_watch(h, frontend) != 0) + goto free_be; list_add(&be->list, &belist); Index: xen-4.1.2-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c =================================================================== --- xen-4.1.2-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.c +++ xen-4.1.2-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c @@ -35,6 +35,8 @@ #ifndef QEMU_TOOL #include "qemu-common.h" #include "sysemu.h" +#include "irq.h" +#include "hw.h" #endif #include "xen_blktap.h" @@ -81,8 +83,18 @@ static void unmap_disk(struct td_state * { tapdev_info_t *info = s->ring_info; fd_list_entry_t *entry; + int i; bdrv_close(s->bs); +#ifndef QEMU_TOOL + for (i = 0; i < MAX_DRIVES + 1; i++) { + if (drives_table[i].bdrv == s->bs) { + drives_table[i].bdrv = NULL; + nb_drives--; + break; + } + } +#endif if (info != NULL && info->mem > 0) munmap(info->mem, getpagesize() * BLKTAP_MMAP_REGION_SIZE); @@ -242,18 +254,6 @@ static int open_disk(struct td_state *s, s->info = ((s->flags & TD_RDONLY) ? VDISK_READONLY : 0); -#ifndef QEMU_TOOL - for (i = 0; i < MAX_DRIVES + 1; i++) { - if (drives_table[i].bdrv == NULL) { - drives_table[i].bdrv = bs; - drives_table[i].type = IF_BLKTAP; - drives_table[i].bus = 0; - drives_table[i].unit = 0; - break; - } - } -#endif - return 0; } @@ -494,7 +494,7 @@ static void handle_blktap_ctrlmsg(void* msg_hdr_t *msg; msg_newdev_t *msg_dev; msg_pid_t *msg_pid; - int ret = -1; + int ret = -1, i; struct td_state *s = NULL; fd_list_entry_t *entry; @@ -584,6 +584,33 @@ static void handle_blktap_ctrlmsg(void* len = write(write_fd, buf, msglen); break; + case CTLMSG_ADDDEV: + s = get_state(msg->cookie); + if (s && !s->added) { +#ifndef QEMU_TOOL + ide_unplug_harddisks(); + for (i = 0; i < MAX_DRIVES + 1; i++) { + if (drives_table[i].bdrv == NULL) { + drives_table[i].bdrv = s->bs; + drives_table[i].type = IF_BLKTAP; + drives_table[i].bus = 0; + drives_table[i].unit = 0; + drives_table[i].used = 1; + nb_drives++; + s->added = 1; + break; + } + } +#endif + } + + memset(buf, 0x00, MSG_SIZE); + msglen = sizeof(msg_hdr_t); + msg->type = CTLMSG_ADDDEV_RSP; + msg->len = msglen; + len = write(write_fd, buf, msglen); + break; + default: break; } Index: xen-4.1.2-testing/tools/ioemu-qemu-xen/hw/xen_blktap.h =================================================================== --- xen-4.1.2-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.h +++ xen-4.1.2-testing/tools/ioemu-qemu-xen/hw/xen_blktap.h @@ -40,7 +40,8 @@ struct td_state { void *fd_entry; uint64_t sector_size; uint64_t size; - unsigned int info; + unsigned int info; + int added; }; typedef struct fd_list_entry {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor