SHA256
1
0
forked from pool/xen
xen/snapshot-without-pv-fix.patch
Charles Arnold 5a49a4e63b - Upstream patch for python 2.7 compatibility
22045-python27-compat.patch 

Thu Nov  11 18:44:48 CST 2010 - cyliu@novell.com
- bnc#641144 - FV Xen VM running windows or linux cannot write to
  virtual floppy drive
  bdrv_default_rwflag.patch

- fate#310510 - fix xenpaging
  xenpaging.optimize_p2m_mem_paging_populate.patch
  xenpaging.HVMCOPY_gfn_paged_out.patch

- bnc#649864 - automatic numa cpu placement of xen conflicts with
  cpupools
  22326-cpu-pools-numa-placement.patch

- fate#310510 - fix xenpaging
  xenpaging.populate_only_if_paged.patch
  - revert logic, populate needs to happen unconditionally
  xenpaging.p2m_mem_paging_populate_if_p2m_ram_paged.patch
  - invalidate current mfn only if gfn is not in flight or done
  xenpaging.mem_event_check_ring-free_requests.patch
  - print info only if 1 instead of 2 slots are free
  xenpaging.guest_remove_page.patch
  - check mfn before usage in resume function
  xenpaging.machine_to_phys_mapping.patch
  - check mfn before usage in resume function

- bnc#552115 - Remove target discovery in block-iscsi

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=82
2010-11-12 17:55:23 +00:00

380 lines
10 KiB
Diff

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[].
Signed-off-by: Li Dongyang <lidongyang@novell.com>
---
tools/blktap/drivers/blktapctrl.c | 81 +++++++++++++++++++++++++++++++++-
tools/blktap/lib/blkif.c | 23 ++++++++++
tools/blktap/lib/blktaplib.h | 5 ++
tools/blktap/lib/xenbus.c | 69 +++++++++++++++++++++++++++++
tools/ioemu-qemu-xen/hw/xen_blktap.c | 49 +++++++++++++++-----
5 files changed, 213 insertions(+), 14 deletions(-)
diff --git a/tools/blktap/drivers/blktapctrl.c b/tools/blktap/drivers/blktapctrl.c
index bcc3152..8b58e3e 100644
--- a/tools/blktap/drivers/blktapctrl.c
+++ b/tools/blktap/drivers/blktapctrl.c
@@ -381,7 +381,22 @@ static int write_msg(int fd, int msgtype, void *ptr, void *ptr2)
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;
}
@@ -476,6 +491,12 @@ static int read_msg(int fd, int msgtype, void *ptr)
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;
@@ -758,6 +779,63 @@ static int unmap_blktapctrl(blkif_t *blkif)
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;
@@ -854,6 +932,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) {
diff --git a/tools/blktap/lib/blkif.c b/tools/blktap/lib/blkif.c
index 9a19596..11b63dc 100644
--- a/tools/blktap/lib/blkif.c
+++ b/tools/blktap/lib/blkif.c
@@ -89,6 +89,11 @@ void register_new_blkif_hook(int (*fn)(blkif_t *blkif))
{
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));
diff --git a/tools/blktap/lib/blktaplib.h b/tools/blktap/lib/blktaplib.h
index 733b924..2a6a078 100644
--- a/tools/blktap/lib/blktaplib.h
+++ b/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
diff --git a/tools/blktap/lib/xenbus.c b/tools/blktap/lib/xenbus.c
index 53db3c8..96f75a5 100644
--- a/tools/blktap/lib/xenbus.c
+++ b/tools/blktap/lib/xenbus.c
@@ -318,6 +318,72 @@ static int check_image(struct xs_handle *h, struct backend_info *be,
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_handle *h, struct xenbus_watch *w,
be->backpath = bepath;
be->frontpath = frontend;
+
+ if (add_blockdevice_state_watch(h, frontend) != 0)
+ goto free_be;
list_add(&be->list, &belist);
diff --git a/tools/ioemu-qemu-xen/hw/xen_blktap.c b/tools/ioemu-qemu-xen/hw/xen_blktap.c
index c2236fd..c925283 100644
--- a/tools/ioemu-qemu-xen/hw/xen_blktap.c
+++ b/tools/ioemu-qemu-xen/hw/xen_blktap.c
@@ -83,8 +83,18 @@ static void unmap_disk(struct td_state *s)
{
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);
@@ -244,18 +254,6 @@ static int open_disk(struct td_state *s, char *path, int readonly)
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;
}
@@ -496,7 +494,7 @@ static void handle_blktap_ctrlmsg(void* private)
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;
@@ -622,6 +620,31 @@ static void handle_blktap_ctrlmsg(void* private)
len = write(write_fd, buf, msglen);
break;
+ case CTLMSG_ADDDEV:
+ s = get_state(msg->cookie);
+ if (s) {
+#ifndef QEMU_TOOL
+ 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++;
+ 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;
}