[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 3/3] qemu: Forbid migration with cache != none



On 2012-2-22 0:17, Jiri Denemark wrote:
Migrating domains with disks using cache != none is unsafe unless the
disk images are stored on coherent clustered filesystem. Thus we forbid
migrating such domains unless VIR_MIGRATE_UNSAFE flags is used.
---
  src/qemu/qemu_driver.c    |    3 ++-
  src/qemu/qemu_migration.c |   36 ++++++++++++++++++++++++++++++++----
  src/qemu/qemu_migration.h |    6 ++++--
  3 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 717bdf1..63a0703 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8767,7 +8767,8 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
          goto endjob;

      if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname,
-                                   cookieout, cookieoutlen)))
+                                   cookieout, cookieoutlen,
+                                   flags)))
          goto endjob;

      if ((flags&  VIR_MIGRATE_CHANGE_PROTECTION)) {
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index f0af494..127b35c 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -817,6 +817,27 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
      return true;
  }

+static bool
+qemuMigrationIsSafe(virDomainDefPtr def)
+{
+    int i;
+
+    for (i = 0 ; i<  def->ndisks ; i++) {
+        virDomainDiskDefPtr disk = def->disks[i];
+
+        /* shared&&  !readonly implies cache=none */
+        if (disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE&&

how about disk write through flag here? This flag should also imply cache=none.

i.e, VIR_DOMAIN_DISK_CACHE_WRITETHRU



+            (disk->cachemode || !disk->shared || disk->readonly)) {
+            qemuReportError(VIR_ERR_MIGRATE_UNSAFE, "%s",
+                            _("Migration may lead to data corruption if disks"
+                              " use cache != none"));
+            return false;
+        }
+    }
+
+    return true;
+}
+
  /** qemuMigrationSetOffline
   * Pause domain for non-live migration.
   */
@@ -1010,7 +1031,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
                           const char *xmlin,
                           const char *dname,
                           char **cookieout,
-                         int *cookieoutlen)
+                         int *cookieoutlen,
+                         unsigned long flags)
  {
      char *rv = NULL;
      qemuMigrationCookiePtr mig = NULL;
@@ -1018,9 +1040,9 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
      qemuDomainObjPrivatePtr priv = vm->privateData;

      VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s,"
-              " cookieout=%p, cookieoutlen=%p",
+              " cookieout=%p, cookieoutlen=%p, flags=%lx",
                driver, vm, NULLSTR(xmlin), NULLSTR(dname),
-              cookieout, cookieoutlen);
+              cookieout, cookieoutlen, flags);

      /* Only set the phase if we are inside QEMU_ASYNC_JOB_MIGRATION_OUT.
       * Otherwise we will start the async job later in the perform phase losing
@@ -1032,6 +1054,9 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
      if (!qemuMigrationIsAllowed(driver, vm, NULL))
          goto cleanup;

+    if (!(flags&  VIR_MIGRATE_UNSAFE)&&  !qemuMigrationIsSafe(vm->def))
+        goto cleanup;
+
      if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
          goto cleanup;

@@ -2070,7 +2095,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
       * a single job.  */

      dom_xml = qemuMigrationBegin(driver, vm, xmlin, dname,
-&cookieout,&cookieoutlen);
+&cookieout,&cookieoutlen, flags);
      if (!dom_xml)
          goto cleanup;

@@ -2354,6 +2379,9 @@ qemuMigrationPerformJob(struct qemud_driver *driver,
      if (!qemuMigrationIsAllowed(driver, vm, NULL))
          goto cleanup;

+    if (!(flags&  VIR_MIGRATE_UNSAFE)&&  !qemuMigrationIsSafe(vm->def))
+        goto cleanup;
+
      resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING;

      if ((flags&  (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index f806ca1..41e4eac 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -35,7 +35,8 @@
       VIR_MIGRATE_PAUSED |                       \
       VIR_MIGRATE_NON_SHARED_DISK |              \
       VIR_MIGRATE_NON_SHARED_INC |               \
-     VIR_MIGRATE_CHANGE_PROTECTION)
+     VIR_MIGRATE_CHANGE_PROTECTION |            \
+     VIR_MIGRATE_UNSAFE)

  enum qemuMigrationJobPhase {
      QEMU_MIGRATION_PHASE_NONE = 0,
@@ -81,7 +82,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
                           const char *xmlin,
                           const char *dname,
                           char **cookieout,
-                         int *cookieoutlen);
+                         int *cookieoutlen,
+                         unsigned long flags);

  int qemuMigrationPrepareTunnel(struct qemud_driver *driver,
                                 virConnectPtr dconn,


--
Shu Ming<shuming linux vnet ibm com>
IBM China Systems and Technology Laboratory



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]