Re: [PATCH v2 1/2] migration: Introduce <migration> element for cdrom and floppy

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

 



On Mon, Oct 03, 2011 at 04:07:23PM +0200, Michal Privoznik wrote:
> This element says what to do with cdrom (or floppy) on migration.
> Currently, only one attribute is supported: 'optional'. It accepts
> 'require', 'optional' and 'drop' values. Setting a cdrom to be
> required means migration will fail if destination cannot access
> source under the same path. Setting to optional means, if destination
> cannot access disk source, it simply gets free()'d/ejected.
> Finally, setting to drop will simply cause cdrom to be dropped
> regardless of path being accessible or not.
> 
> This functionality is important for users, whose machines get buggy.
> So they decide to save as much as possible and migrate the machine
> even they won't be able to access (readonly) cdrom on destination.

Migration will also be disallowed when the vm uses host devices or has
snapshots (qemuMigrationIsAllowed)[1]. Would it make sense to introduce a
VIR_MIGRATE_FORCE similar to VIR_REVERT_FORCE here?  We could then
introduce error codes similar to the snapshot case
(VIR_ERR_MIGRATE_RISKY).

The attached patch shows how this could look like, it's not meant to be
applied yet.
Cheers,
 -- Guido (sorry for hijacking this thread a bit)

[1] Hopefully we can make migration with snapshots safe in the future by
transfering the metadata. A current hack around is to put this onto
shared storage and reread it on the destination side after migration.

> ---
>  docs/formatdomain.html.in                          |   23 ++++++
>  docs/schemas/domaincommon.rng                      |   17 ++++
>  src/conf/domain_conf.c                             |   78 +++++++++++++++++++-
>  src/conf/domain_conf.h                             |   17 ++++
>  src/libvirt_private.syms                           |    2 +
>  .../domain-qemu-complex-migration.xml              |   68 +++++++++++++++++
>  6 files changed, 204 insertions(+), 1 deletions(-)
>  create mode 100644 tests/domainschemadata/domain-qemu-complex-migration.xml
> 
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index 593adcb..c72967f 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -917,6 +917,7 @@
>        &lt;driver name='qemu' type='raw'/&gt;
>        &lt;target def='hdc' bus='ide'/&gt;
>        &lt;readonly/&gt;
> +      &lt;migration optional='require'&gt;
>      &lt;/disk&gt;
>    &lt;/devices&gt;
>    ...</pre>
> @@ -1109,6 +1110,28 @@
>            </tr>
>          </table>
>        </dd>
> +      <dt><code>migration</code></dt>
> +      <dd>This element says what to do with disk during migration. Currently,
> +        only <code>optional</code> attribute is supported. This attribute
> +        specify policy for CD ROM and floppy in cases when source has or not
> +        access to source. Accepted values:
> +        <table class="top_table">
> +          <tr>
> +            <td> require </td>
> +            <td> destination must see the same medium as source </td>
> +          </tr>
> +          <tr>
> +            <td> optional </td>
> +            <td> if destination has same medium, use it. If not,
> +                eject medium regardless drive being locked or not.  </td>
> +          </tr>
> +          <tr>
> +            <td> drop </td>
> +            <td> on migration, destination will eject, even if it
> +                has same medium. Again, regardless drive lock status. </td>
> +          </tr>
> +        </table>
> +      </dd>
>        <dt><code>address</code></dt>
>        <dd>If present, the <code>address</code> element ties the disk
>          to a given slot of a controller (the
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index cffaac2..16a76e0 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -630,6 +630,9 @@
>        <ref name="encryption"/>
>      </optional>
>      <optional>
> +      <ref name="migration"/>
> +    </optional>
> +    <optional>
>        <ref name="address"/>
>      </optional>
>    </define>
> @@ -642,6 +645,20 @@
>        </choice>
>      </attribute>
>    </define>
> +  <define name="migration">
> +    <optional>
> +      <element name="migration">
> +        <attribute name="optional">
> +          <choice>
> +            <value>require</value>
> +            <value>optional</value>
> +            <value>drop</value>
> +          </choice>
> +        </attribute>
> +        <empty/>
> +      </element>
> +    </optional>
> +  </define>
>  
>    <define name="lease">
>      <element name="lease">
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 6fb1888..e1f43b6 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -572,6 +572,13 @@ VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
>                "preferred",
>                "interleave");
>  
> +VIR_ENUM_IMPL(virDomainDeviceMigrationOptional,
> +              VIR_DOMAIN_DEVICE_MIGRATION_OPT_LAST,
> +              "default",
> +              "require",
> +              "optional",
> +              "drop");
> +
>  #define virDomainReportError(code, ...)                              \
>      virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__,            \
>                           __FUNCTION__, __LINE__, __VA_ARGS__)
> @@ -2273,6 +2280,50 @@ cleanup:
>  }
>  
>  
> +static int
> +virDomainDeviceMigrationParseXML(xmlNodePtr node,
> +                                 virDomainDiskDefPtr def)
> +{
> +    int ret = -1;
> +    char *optional = NULL;
> +    int i;
> +
> +    if (!node || !def) {
> +        virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                             _("invalid argument supplied"));
> +        return -1;
> +    }
> +
> +    if ((optional = virXMLPropString(node, "optional")) != NULL) {
> +        i = virDomainDeviceMigrationOptionalTypeFromString(optional);
> +        if (i <= 0) {
> +            virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                                 _("unknown migration optional value '%s'"),
> +                                 optional);
> +            goto cleanup;
> +        }
> +
> +        if (i != VIR_DOMAIN_DEVICE_MIGRATION_OPT_REQ &&
> +            def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
> +            def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
> +            virDomainReportError(VIR_ERR_INVALID_ARG,
> +                                 _("Setting disk %s is allowed only for "
> +                                   "cdrom or floppy"),
> +                                 optional);
> +            goto cleanup;
> +        }
> +
> +        def->migration.optional = i;
> +    }
> +
> +    ret = 0;
> +
> +cleanup:
> +    VIR_FREE(optional);
> +    return ret;
> +}
> +
> +
>  /* Parse the XML definition for a disk
>   * @param node XML nodeset to parse for disk definition
>   */
> @@ -2283,7 +2334,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>                           unsigned int flags)
>  {
>      virDomainDiskDefPtr def;
> -    xmlNodePtr cur, host;
> +    xmlNodePtr cur, host, migration = NULL;
>      char *type = NULL;
>      char *device = NULL;
>      char *snapshot = NULL;
> @@ -2442,6 +2493,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>                  if (virDomainDeviceBootParseXML(cur, &def->bootIndex,
>                                                  bootMap))
>                      goto error;
> +            } else if (xmlStrEqual(cur->name, BAD_CAST "migration")) {
> +                migration = cur;
>              }
>          }
>          cur = cur->next;
> @@ -2605,6 +2658,11 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>          def->event_idx = idx;
>      }
>  
> +    if (migration) {
> +        if (virDomainDeviceMigrationParseXML(migration, def) < 0)
> +            goto error;
> +    }
> +
>      if (devaddr) {
>          if (virDomainParseLegacyDeviceAddress(devaddr,
>                                                &def->info.addr.pci) < 0) {
> @@ -9116,6 +9174,21 @@ virDomainLeaseDefFormat(virBufferPtr buf,
>  }
>  
>  static int
> +virDomainDeviceMigrationFormat(virBufferPtr buf,
> +                               virDomainDeviceMigrationInfoPtr mig)
> +{
> +    if (!buf || !mig)
> +        return -1;
> +
> +    if (mig->optional == VIR_DOMAIN_DEVICE_MIGRATION_OPT_DEFAULT)
> +        return 0;
> +
> +    virBufferAsprintf(buf, "      <migration optional='%s'/>\n",
> +                      virDomainDeviceMigrationOptionalTypeToString(mig->optional));
> +    return 0;
> +}
> +
> +static int
>  virDomainDiskDefFormat(virBufferPtr buf,
>                         virDomainDiskDefPtr def,
>                         unsigned int flags)
> @@ -9245,6 +9318,9 @@ virDomainDiskDefFormat(virBufferPtr buf,
>          virStorageEncryptionFormat(buf, def->encryption, 6) < 0)
>          return -1;
>  
> +    if (virDomainDeviceMigrationFormat(buf, &def->migration) < 0)
> +        return -1;
> +
>      if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
>          return -1;
>  
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index bc41d34..e0db892 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -268,6 +268,21 @@ enum virDomainSnapshotState {
>      VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST,
>  };
>  
> +enum virDomainDeviceMigrationOptional {
> +    VIR_DOMAIN_DEVICE_MIGRATION_OPT_DEFAULT = 0,
> +    VIR_DOMAIN_DEVICE_MIGRATION_OPT_REQ,
> +    VIR_DOMAIN_DEVICE_MIGRATION_OPT_OPT,
> +    VIR_DOMAIN_DEVICE_MIGRATION_OPT_DROP,
> +
> +    VIR_DOMAIN_DEVICE_MIGRATION_OPT_LAST
> +};
> +
> +typedef struct _virDomainDeviceMigrationInfo virDomainDeviceMigrationInfo;
> +typedef virDomainDeviceMigrationInfo *virDomainDeviceMigrationInfoPtr;
> +struct _virDomainDeviceMigrationInfo {
> +    int optional;
> +};
> +
>  /* Stores the virtual disk configuration */
>  typedef struct _virDomainDiskDef virDomainDiskDef;
>  typedef virDomainDiskDef *virDomainDiskDefPtr;
> @@ -295,6 +310,7 @@ struct _virDomainDiskDef {
>      unsigned int transient : 1;
>      virDomainDeviceInfo info;
>      virStorageEncryptionPtr encryption;
> +    virDomainDeviceMigrationInfo migration;
>  };
>  
>  
> @@ -1912,5 +1928,6 @@ VIR_ENUM_DECL(virDomainTimerName)
>  VIR_ENUM_DECL(virDomainTimerTrack)
>  VIR_ENUM_DECL(virDomainTimerTickpolicy)
>  VIR_ENUM_DECL(virDomainTimerMode)
> +VIR_ENUM_DECL(virDomainDeviceMigrationOptional)
>  
>  #endif /* __DOMAIN_CONF_H */
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 1ac486f..881d535 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -275,6 +275,8 @@ virDomainDeviceAddressTypeToString;
>  virDomainDeviceDefFree;
>  virDomainDeviceDefParse;
>  virDomainDeviceInfoIterate;
> +virDomainDeviceMigrationOptionalTypeFromString;
> +virDomainDeviceMigrationOptionalTypeToString;
>  virDomainDevicePCIAddressIsValid;
>  virDomainDeviceTypeToString;
>  virDomainDiskBusTypeToString;
> diff --git a/tests/domainschemadata/domain-qemu-complex-migration.xml b/tests/domainschemadata/domain-qemu-complex-migration.xml
> new file mode 100644
> index 0000000..7071b3d
> --- /dev/null
> +++ b/tests/domainschemadata/domain-qemu-complex-migration.xml
> @@ -0,0 +1,68 @@
> +<domain type='kvm'>
> +  <name>pxe</name>
> +  <uuid>ee74a5f1-71c1-4a46-84a9-05ac9199fe8f</uuid>
> +  <memory>1048576</memory>
> +  <currentMemory>1048576</currentMemory>
> +  <vcpu>4</vcpu>
> +  <os>
> +    <type arch='x86_64' machine='pc-0.14'>hvm</type>
> +    <boot dev='network'/>
> +  </os>
> +  <features>
> +    <acpi/>
> +    <apic/>
> +    <pae/>
> +  </features>
> +  <clock offset='utc'/>
> +  <on_poweroff>destroy</on_poweroff>
> +  <on_reboot>restart</on_reboot>
> +  <on_crash>restart</on_crash>
> +  <devices>
> +    <emulator>/usr/bin/qemu-kvm</emulator>
> +    <disk type='file' device='cdrom'>
> +      <driver name='qemu' type='raw'/>
> +      <source file='/tmp/cdrom.iso'/>
> +      <target dev='hdc' bus='ide'/>
> +      <readonly/>
> +      <migration optional='optional'/>
> +      <address type='drive' controller='0' bus='1' unit='0'/>
> +    </disk>
> +    <disk type='block' device='disk'>
> +      <driver name='qemu' type='raw'/>
> +      <source dev='/tmp/disk.img'/>
> +      <target dev='hdd' bus='ide'/>
> +      <migration optional='require'/>
> +      <address type='drive' controller='0' bus='1' unit='1'/>
> +    </disk>
> +    <controller type='virtio-serial' index='0'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
> +    </controller>
> +    <controller type='ide' index='0'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
> +    </controller>
> +    <interface type='network'>
> +      <mac address='52:54:00:75:71:fe'/>
> +      <source network='default'/>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
> +    </interface>
> +    <serial type='pty'>
> +      <target port='0'/>
> +    </serial>
> +    <console type='pty'>
> +      <target type='serial' port='0'/>
> +    </console>
> +    <channel type='spicevmc'>
> +      <target type='virtio' name='com.redhat.spice.0'/>
> +      <address type='virtio-serial' controller='0' bus='0' port='1'/>
> +    </channel>
> +    <input type='mouse' bus='ps2'/>
> +    <graphics type='spice' port='5999' autoport='no' keymap='en-us'/>
> +    <video>
> +      <model type='cirrus' vram='9216' heads='1'/>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
> +    </video>
> +    <memballoon model='virtio'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
> +    </memballoon>
> +  </devices>
> +</domain>
> -- 
> 1.7.3.4
> 
> --
> libvir-list mailing list
> libvir-list@xxxxxxxxxx
> https://www.redhat.com/mailman/listinfo/libvir-list
> 
>From 36bdfd44f099c1ce5e249581c9d1ebe974a5352b Mon Sep 17 00:00:00 2001
From: Guido Guenther <agx@xxxxxxxxxxx>
Date: Thu, 13 Oct 2011 12:05:08 +0200
Subject: [PATCH] Introducte VIR_MIGRATE_FORCE flag to allow for risky
 migrations

Change errors inidicating risky migration to VIR_ERR_MIGRATE_RISKY.
---
 include/libvirt/libvirt.h.in |    3 ++-
 include/libvirt/virterror.h  |    2 ++
 src/qemu/qemu_driver.c       |   10 +++++-----
 src/qemu/qemu_migration.c    |   38 ++++++++++++++++++++++++--------------
 src/qemu/qemu_migration.h    |   13 +++++++++----
 src/util/virterror.c         |    6 ++++++
 6 files changed, 48 insertions(+), 24 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index c991dfc..abf08a3 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -766,7 +766,8 @@ typedef enum {
     VIR_MIGRATE_CHANGE_PROTECTION = (1 << 8), /* protect for changing domain configuration through the
                                                * whole migration process; this will be used automatically
                                                * when supported */
-
+    VIR_MIGRATE_FORCE             = (1 << 9), /* Force migration even when we have host devices in use
+                                                 or have snapshotes */
 } virDomainMigrateFlags;
 
 /* Domain migration. */
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index dfbe2bc..17e8fdd 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -240,6 +240,8 @@ typedef enum {
     VIR_ERR_STORAGE_POOL_BUILT = 76,	/* storage pool already built */
     VIR_ERR_SNAPSHOT_REVERT_RISKY = 77,	/* force was not requested for a
                                            risky domain snapshot revert */
+    VIR_ERR_MIGRATE_RISKY = 78,         /* force was not requested for a
+                                           risky domain migration */
 } virErrorNumber;
 
 /**
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ec01cd5..95396e8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7838,7 +7838,7 @@ qemudDomainMigratePrepareTunnel(virConnectPtr dconn,
 
     ret = qemuMigrationPrepareTunnel(driver, dconn,
                                      NULL, 0, NULL, NULL, /* No cookies in v2 */
-                                     st, dname, dom_xml);
+                                     st, dname, dom_xml, flags);
 
 cleanup:
     qemuDriverUnlock(driver);
@@ -7898,7 +7898,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
     ret = qemuMigrationPrepareDirect(driver, dconn,
                                      NULL, 0, NULL, NULL, /* No cookies */
                                      uri_in, uri_out,
-                                     dname, dom_xml);
+                                     dname, dom_xml, flags);
 
 cleanup:
     qemuDriverUnlock(driver);
@@ -8051,7 +8051,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
         goto endjob;
 
     if (!(xml = qemuMigrationBegin(driver, vm, xmlin,
-                                   cookieout, cookieoutlen)))
+                                   cookieout, cookieoutlen, flags)))
         goto endjob;
 
     if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
@@ -8128,7 +8128,7 @@ qemuDomainMigratePrepare3(virConnectPtr dconn,
                                      cookiein, cookieinlen,
                                      cookieout, cookieoutlen,
                                      uri_in, uri_out,
-                                     dname, dom_xml);
+                                     dname, dom_xml, flags);
 
 cleanup:
     qemuDriverUnlock(driver);
@@ -8173,7 +8173,7 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn,
     ret = qemuMigrationPrepareTunnel(driver, dconn,
                                      cookiein, cookieinlen,
                                      cookieout, cookieoutlen,
-                                     st, dname, dom_xml);
+                                     st, dname, dom_xml, flags);
     qemuDriverUnlock(driver);
 
 cleanup:
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 4516231..91000ad 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -780,18 +780,24 @@ error:
  * the fact that older servers did not do checks on the source. */
 static bool
 qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
-                       virDomainDefPtr def)
+                       virDomainDefPtr def, int flags)
 {
     int nsnapshots;
 
+    /* FIXME: there are different kinds of risk (a missing host device
+       might break the vm entirely while missing snapshots will not */
+    if (flags & VIR_MIGRATE_FORCE) {
+        return true;
+    }
+
     if (vm) {
         if (qemuProcessAutoDestroyActive(driver, vm)) {
-            qemuReportError(VIR_ERR_OPERATION_INVALID,
+            qemuReportError(VIR_ERR_MIGRATE_RISKY,
                             "%s", _("domain is marked for auto destroy"));
             return false;
         }
         if ((nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) {
-            qemuReportError(VIR_ERR_OPERATION_INVALID,
+            qemuReportError(VIR_ERR_MIGRATE_RISKY,
                             _("cannot migrate domain with %d snapshots"),
                             nsnapshots);
             return false;
@@ -800,7 +806,7 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
         def = vm->def;
     }
     if (def->nhostdevs > 0) {
-        qemuReportError(VIR_ERR_OPERATION_INVALID,
+        qemuReportError(VIR_ERR_MIGRATE_RISKY,
             "%s", _("Domain with assigned host devices cannot be migrated"));
         return false;
     }
@@ -993,7 +999,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
                          virDomainObjPtr vm,
                          const char *xmlin,
                          char **cookieout,
-                         int *cookieoutlen)
+                         int *cookieoutlen,
+                         unsigned long flags)
 {
     char *rv = NULL;
     qemuMigrationCookiePtr mig = NULL;
@@ -1010,7 +1017,7 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
     if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT)
         qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_BEGIN3);
 
-    if (!qemuMigrationIsAllowed(driver, vm, NULL))
+    if (!qemuMigrationIsAllowed(driver, vm, NULL, flags))
         goto cleanup;
 
     if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
@@ -1059,7 +1066,8 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
                         const char *dname,
                         const char *dom_xml,
                         const char *migrateFrom,
-                        virStreamPtr st)
+                        virStreamPtr st,
+                        int flags)
 {
     virDomainDefPtr def = NULL;
     virDomainObjPtr vm = NULL;
@@ -1080,7 +1088,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    if (!qemuMigrationIsAllowed(driver, NULL, def))
+    if (!qemuMigrationIsAllowed(driver, NULL, def, flags))
         goto cleanup;
 
     /* Target domain name, maybe renamed. */
@@ -1220,7 +1228,8 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver,
                            int *cookieoutlen,
                            virStreamPtr st,
                            const char *dname,
-                           const char *dom_xml)
+                           const char *dom_xml,
+                           unsigned long flags)
 {
     int ret;
 
@@ -1234,7 +1243,7 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver,
      */
     ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
                                   cookieout, cookieoutlen, dname, dom_xml,
-                                  "stdio", st);
+                                  "stdio", st, flags);
     return ret;
 }
 
@@ -1249,7 +1258,8 @@ qemuMigrationPrepareDirect(struct qemud_driver *driver,
                            const char *uri_in,
                            char **uri_out,
                            const char *dname,
-                           const char *dom_xml)
+                           const char *dom_xml,
+                           unsigned long flags)
 {
     static int port = 0;
     int this_port;
@@ -1345,7 +1355,7 @@ qemuMigrationPrepareDirect(struct qemud_driver *driver,
 
     ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
                                   cookieout, cookieoutlen, dname, dom_xml,
-                                  migrateFrom, NULL);
+                                  migrateFrom, NULL, flags);
 cleanup:
     VIR_FREE(hostname);
     if (ret != 0)
@@ -2012,7 +2022,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
      * a single job.  */
 
     dom_xml = qemuMigrationBegin(driver, vm, xmlin,
-                                 &cookieout, &cookieoutlen);
+                                 &cookieout, &cookieoutlen, flags);
     if (!dom_xml)
         goto cleanup;
 
@@ -2289,7 +2299,7 @@ qemuMigrationPerformJob(struct qemud_driver *driver,
         goto endjob;
     }
 
-    if (!qemuMigrationIsAllowed(driver, vm, NULL))
+    if (!qemuMigrationIsAllowed(driver, vm, NULL, flags))
         goto cleanup;
 
     resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING;
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index ec70422..5adc1cf 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -35,7 +35,9 @@
      VIR_MIGRATE_PAUSED |                       \
      VIR_MIGRATE_NON_SHARED_DISK |              \
      VIR_MIGRATE_NON_SHARED_INC |               \
-     VIR_MIGRATE_CHANGE_PROTECTION)
+     VIR_MIGRATE_CHANGE_PROTECTION |            \
+     VIR_MIGRATE_FORCE)
+
 
 enum qemuMigrationJobPhase {
     QEMU_MIGRATION_PHASE_NONE = 0,
@@ -80,7 +82,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
                          virDomainObjPtr vm,
                          const char *xmlin,
                          char **cookieout,
-                         int *cookieoutlen);
+                         int *cookieoutlen,
+                         unsigned long flags);
 
 int qemuMigrationPrepareTunnel(struct qemud_driver *driver,
                                virConnectPtr dconn,
@@ -90,7 +93,8 @@ int qemuMigrationPrepareTunnel(struct qemud_driver *driver,
                                int *cookieoutlen,
                                virStreamPtr st,
                                const char *dname,
-                               const char *dom_xml);
+                               const char *dom_xml,
+                               unsigned long flags);
 
 int qemuMigrationPrepareDirect(struct qemud_driver *driver,
                                virConnectPtr dconn,
@@ -101,7 +105,8 @@ int qemuMigrationPrepareDirect(struct qemud_driver *driver,
                                const char *uri_in,
                                char **uri_out,
                                const char *dname,
-                               const char *dom_xml);
+                               const char *dom_xml,
+                               unsigned long flags);
 
 int qemuMigrationPerform(struct qemud_driver *driver,
                          virConnectPtr conn,
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 5006fa2..3544208 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1210,6 +1210,12 @@ virErrorMsg(virErrorNumber error, const char *info)
             else
                 errmsg = _("revert requires force: %s");
             break;
+        case VIR_ERR_MIGRATE_RISKY:
+            if (info == NULL)
+                errmsg = _("migration requires force");
+            else
+                errmsg = _("migration requires force: %s");
+            break;
     }
     return (errmsg);
 }
-- 
1.7.6.3

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]