Blame 0004-hw-9pfs-use-migration-blockers-to-prevent-live-migra.patch

Justin M. Forbes 45e84a
From 77a02621812952acfde887244f6f480de1b51f95 Mon Sep 17 00:00:00 2001
Justin M. Forbes 45e84a
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Justin M. Forbes 45e84a
Date: Sun, 4 Dec 2011 22:35:28 +0530
Justin M. Forbes 45e84a
Subject: [PATCH 04/25] hw/9pfs: use migration blockers to prevent live
Justin M. Forbes 45e84a
 migration when virtfs export path is mounted
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Now when you try to migrate with VirtFS export path mounted, you get a proper QMP error:
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
(qemu) migrate tcp:localhost:4444
Justin M. Forbes 45e84a
Migration is disabled when VirtFS export path '/tmp/' is mounted in the guest using mount_tag 'v_tmp'
Justin M. Forbes 45e84a
(qemu)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Justin M. Forbes 45e84a
---
Justin M. Forbes 45e84a
 hw/9pfs/virtio-9p-device.c |   22 +++++++++++-----------
Justin M. Forbes 45e84a
 hw/9pfs/virtio-9p.c        |   19 +++++++++++++++++++
Justin M. Forbes 45e84a
 hw/9pfs/virtio-9p.h        |    5 +++--
Justin M. Forbes 45e84a
 qerror.c                   |    5 +++++
Justin M. Forbes 45e84a
 qerror.h                   |    3 +++
Justin M. Forbes 45e84a
 5 files changed, 41 insertions(+), 13 deletions(-)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
Justin M. Forbes 45e84a
index bba4c54..c9bca8b 100644
Justin M. Forbes 45e84a
--- a/hw/9pfs/virtio-9p-device.c
Justin M. Forbes 45e84a
+++ b/hw/9pfs/virtio-9p-device.c
Justin M. Forbes 45e84a
@@ -33,13 +33,15 @@ static V9fsState *to_virtio_9p(VirtIODevice *vdev)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
 static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
+    int len;
Justin M. Forbes 45e84a
     struct virtio_9p_config *cfg;
Justin M. Forbes 45e84a
     V9fsState *s = to_virtio_9p(vdev);
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-    cfg = g_malloc0(sizeof(struct virtio_9p_config) +
Justin M. Forbes 45e84a
-                        s->tag_len);
Justin M. Forbes 45e84a
-    stw_raw(&cfg->tag_len, s->tag_len);
Justin M. Forbes 45e84a
-    memcpy(cfg->tag, s->tag, s->tag_len);
Justin M. Forbes 45e84a
+    len = strlen(s->tag);
Justin M. Forbes 45e84a
+    cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
Justin M. Forbes 45e84a
+    stw_raw(&cfg->tag_len, len);
Justin M. Forbes 45e84a
+    /* We don't copy the terminating null to config space */
Justin M. Forbes 45e84a
+    memcpy(cfg->tag, s->tag, len);
Justin M. Forbes 45e84a
     memcpy(config, cfg, s->config_size);
Justin M. Forbes 45e84a
     g_free(cfg);
Justin M. Forbes 45e84a
 }
Justin M. Forbes 45e84a
@@ -96,20 +98,18 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
     len = strlen(conf->tag);
Justin M. Forbes 45e84a
-    if (len > MAX_TAG_LEN) {
Justin M. Forbes 45e84a
+    if (len > MAX_TAG_LEN - 1) {
Justin M. Forbes 45e84a
         fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
Justin M. Forbes 45e84a
-                "maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN);
Justin M. Forbes 45e84a
+                "maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN - 1);
Justin M. Forbes 45e84a
         exit(1);
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
-    /* s->tag is non-NULL terminated string */
Justin M. Forbes 45e84a
-    s->tag = g_malloc(len);
Justin M. Forbes 45e84a
-    memcpy(s->tag, conf->tag, len);
Justin M. Forbes 45e84a
-    s->tag_len = len;
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+    s->tag = strdup(conf->tag);
Justin M. Forbes 45e84a
     s->ctx.uid = -1;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
     s->ops = fse->ops;
Justin M. Forbes 45e84a
     s->vdev.get_features = virtio_9p_get_features;
Justin M. Forbes 45e84a
-    s->config_size = sizeof(struct virtio_9p_config) + s->tag_len;
Justin M. Forbes 45e84a
+    s->config_size = sizeof(struct virtio_9p_config) + len;
Justin M. Forbes 45e84a
     s->vdev.get_config = virtio_9p_get_config;
Justin M. Forbes 45e84a
     s->fid_list = NULL;
Justin M. Forbes 45e84a
     qemu_co_rwlock_init(&s->rename_lock);
Justin M. Forbes 45e84a
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
Justin M. Forbes 45e84a
index 1b2fc5d..32b98dd 100644
Justin M. Forbes 45e84a
--- a/hw/9pfs/virtio-9p.c
Justin M. Forbes 45e84a
+++ b/hw/9pfs/virtio-9p.c
Justin M. Forbes 45e84a
@@ -23,6 +23,7 @@
Justin M. Forbes 45e84a
 #include "virtio-9p-xattr.h"
Justin M. Forbes 45e84a
 #include "virtio-9p-coth.h"
Justin M. Forbes 45e84a
 #include "trace.h"
Justin M. Forbes 45e84a
+#include "migration.h"
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
 int open_fd_hw;
Justin M. Forbes 45e84a
 int total_open_fd;
Justin M. Forbes 45e84a
@@ -373,6 +374,19 @@ static void put_fid(V9fsPDU *pdu, V9fsFidState *fidp)
Justin M. Forbes 45e84a
      * Don't free the fid if it is in reclaim list
Justin M. Forbes 45e84a
      */
Justin M. Forbes 45e84a
     if (!fidp->ref && fidp->clunked) {
Justin M. Forbes 45e84a
+        if (fidp->fid == pdu->s->root_fid) {
Justin M. Forbes 45e84a
+            /*
Justin M. Forbes 45e84a
+             * if the clunked fid is root fid then we
Justin M. Forbes 45e84a
+             * have unmounted the fs on the client side.
Justin M. Forbes 45e84a
+             * delete the migration blocker. Ideally, this
Justin M. Forbes 45e84a
+             * should be hooked to transport close notification
Justin M. Forbes 45e84a
+             */
Justin M. Forbes 45e84a
+            if (pdu->s->migration_blocker) {
Justin M. Forbes 45e84a
+                migrate_del_blocker(pdu->s->migration_blocker);
Justin M. Forbes 45e84a
+                error_free(pdu->s->migration_blocker);
Justin M. Forbes 45e84a
+                pdu->s->migration_blocker = NULL;
Justin M. Forbes 45e84a
+            }
Justin M. Forbes 45e84a
+        }
Justin M. Forbes 45e84a
         free_fid(pdu, fidp);
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
 }
Justin M. Forbes 45e84a
@@ -1235,6 +1249,11 @@ static void v9fs_attach(void *opaque)
Justin M. Forbes 45e84a
     err = offset;
Justin M. Forbes 45e84a
     trace_v9fs_attach_return(pdu->tag, pdu->id,
Justin M. Forbes 45e84a
                              qid.type, qid.version, qid.path);
Justin M. Forbes 45e84a
+    s->root_fid = fid;
Justin M. Forbes 45e84a
+    /* disable migration */
Justin M. Forbes 45e84a
+    error_set(&s->migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
Justin M. Forbes 45e84a
+              s->ctx.fs_root, s->tag);
Justin M. Forbes 45e84a
+    migrate_add_blocker(s->migration_blocker);
Justin M. Forbes 45e84a
 out:
Justin M. Forbes 45e84a
     put_fid(pdu, fidp);
Justin M. Forbes 45e84a
 out_nofid:
Justin M. Forbes 45e84a
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
Justin M. Forbes 45e84a
index 7f88356..8b612da 100644
Justin M. Forbes 45e84a
--- a/hw/9pfs/virtio-9p.h
Justin M. Forbes 45e84a
+++ b/hw/9pfs/virtio-9p.h
Justin M. Forbes 45e84a
@@ -246,8 +246,7 @@ typedef struct V9fsState
Justin M. Forbes 45e84a
     V9fsFidState *fid_list;
Justin M. Forbes 45e84a
     FileOperations *ops;
Justin M. Forbes 45e84a
     FsContext ctx;
Justin M. Forbes 45e84a
-    uint16_t tag_len;
Justin M. Forbes 45e84a
-    uint8_t *tag;
Justin M. Forbes 45e84a
+    char *tag;
Justin M. Forbes 45e84a
     size_t config_size;
Justin M. Forbes 45e84a
     enum p9_proto_version proto_version;
Justin M. Forbes 45e84a
     int32_t msize;
Justin M. Forbes 45e84a
@@ -256,6 +255,8 @@ typedef struct V9fsState
Justin M. Forbes 45e84a
      * on rename.
Justin M. Forbes 45e84a
      */
Justin M. Forbes 45e84a
     CoRwlock rename_lock;
Justin M. Forbes 45e84a
+    int32_t root_fid;
Justin M. Forbes 45e84a
+    Error *migration_blocker;
Justin M. Forbes 45e84a
 } V9fsState;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
 typedef struct V9fsStatState {
Justin M. Forbes 45e84a
diff --git a/qerror.c b/qerror.c
Justin M. Forbes 45e84a
index fdf62b9..25bc91e 100644
Justin M. Forbes 45e84a
--- a/qerror.c
Justin M. Forbes 45e84a
+++ b/qerror.c
Justin M. Forbes 45e84a
@@ -235,6 +235,11 @@ static const QErrorStringTable qerror_table[] = {
Justin M. Forbes 45e84a
                      "supported by this qemu version: %(feature)",
Justin M. Forbes 45e84a
     },
Justin M. Forbes 45e84a
     {
Justin M. Forbes 45e84a
+        .error_fmt = QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
Justin M. Forbes 45e84a
+        .desc      = "Migration is disabled when VirtFS export path '%(path)' "
Justin M. Forbes 45e84a
+                     "is mounted in the guest using mount_tag '%(tag)'",
Justin M. Forbes 45e84a
+    },
Justin M. Forbes 45e84a
+    {
Justin M. Forbes 45e84a
         .error_fmt = QERR_VNC_SERVER_FAILED,
Justin M. Forbes 45e84a
         .desc      = "Could not start VNC server on %(target)",
Justin M. Forbes 45e84a
     },
Justin M. Forbes 45e84a
diff --git a/qerror.h b/qerror.h
Justin M. Forbes 45e84a
index 2d3d43b..6414cd9 100644
Justin M. Forbes 45e84a
--- a/qerror.h
Justin M. Forbes 45e84a
+++ b/qerror.h
Justin M. Forbes 45e84a
@@ -192,6 +192,9 @@ QError *qobject_to_qerror(const QObject *obj);
Justin M. Forbes 45e84a
 #define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
Justin M. Forbes 45e84a
     "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }"
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
+#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
Justin M. Forbes 45e84a
+    "{ 'class': 'VirtFSFeatureBlocksMigration', 'data': { 'path': %s, 'tag': %s } }"
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
 #define QERR_VNC_SERVER_FAILED \
Justin M. Forbes 45e84a
     "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-- 
Justin M. Forbes 45e84a
1.7.7.5
Justin M. Forbes 45e84a