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

Michal Privoznik mprivozn at redhat.com
Tue Sep 27 14:39:50 UTC 2011


This element says what to do with cdrom (or floppy) on migration.
Currently, only one attribute is supported: 'optional'. It accepts
'yes' and 'no' values. Setting a cdrom to be optional means, if
destination cannot access disk source, it simply gets free()'d/ejected.

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.
---
 docs/schemas/domaincommon.rng |   16 ++++++++
 src/conf/domain_conf.c        |   85 ++++++++++++++++++++++++++++++++++++++++-
 src/conf/domain_conf.h        |   16 ++++++++
 src/libvirt_private.syms      |    2 +
 4 files changed, 118 insertions(+), 1 deletions(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index be98be0..1150297 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,19 @@
       </choice>
     </attribute>
   </define>
+  <define name="migration">
+    <optional>
+      <element name="migration">
+        <attribute name="optional">
+          <choice>
+            <value>yes</value>
+            <value>no</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 a918679..9296ff0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -560,6 +560,12 @@ VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
               "preferred",
               "interleave");
 
+VIR_ENUM_IMPL(virDomainDeviceMigrationOptional,
+              VIR_DOMAIN_DEVICE_MIGRATION_OPT_LAST,
+              "default",
+              "yes",
+              "no");
+
 #define virDomainReportError(code, ...)                              \
     virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__,            \
                          __FUNCTION__, __LINE__, __VA_ARGS__)
@@ -764,6 +770,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
     VIR_FREE(def->dst);
     VIR_FREE(def->driverName);
     VIR_FREE(def->driverType);
+    VIR_FREE(def->migration);
     virStorageEncryptionFree(def->encryption);
     virDomainDeviceInfoClear(&def->info);
 
@@ -2247,6 +2254,56 @@ 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 (VIR_ALLOC(def->migration) < 0) {
+        virReportOOMError();
+        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_YES &&
+            def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
+            def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
+            virDomainReportError(VIR_ERR_INVALID_ARG, "%s",
+                                 _("Setting disk optional is allowed only for "
+                                   "cdrom or floppy"));
+            goto cleanup;
+        }
+
+        def->migration->optional = i;
+    }
+
+    ret = 0;
+
+cleanup:
+    if (ret < 0)
+        VIR_FREE(def->migration);
+    VIR_FREE(optional);
+    return ret;
+}
+
+
 /* Parse the XML definition for a disk
  * @param node XML nodeset to parse for disk definition
  */
@@ -2257,7 +2314,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;
@@ -2416,6 +2473,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;
@@ -2579,6 +2638,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) {
@@ -9076,6 +9140,21 @@ virDomainLeaseDefFormat(virBufferPtr buf,
 }
 
 static int
+virDomainDeviceMigrationFormat(virBufferPtr buf,
+                               virDomainDeviceMigrationInfoPtr mig)
+{
+    if (!buf)
+        return -1;
+
+    if (!mig)
+        return 0;
+
+    virBufferAsprintf(buf, "      <migration optional='%s'/>\n",
+                      virDomainDeviceMigrationOptionalTypeToString(mig->optional));
+    return 0;
+}
+
+static int
 virDomainDiskDefFormat(virBufferPtr buf,
                        virDomainDiskDefPtr def,
                        unsigned int flags)
@@ -9205,6 +9284,10 @@ virDomainDiskDefFormat(virBufferPtr buf,
         virStorageEncryptionFormat(buf, def->encryption, 6) < 0)
         return -1;
 
+    if (def->migration &&
+        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 86b4c79..4dcf511 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -259,6 +259,20 @@ enum virDomainSnapshotState {
     VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST,
 };
 
+enum virDomainDeviceMigrationOptional {
+    VIR_DOMAIN_DEVICE_MIGRATION_OPT_DEFAULT = 0,
+    VIR_DOMAIN_DEVICE_MIGRATION_OPT_YES,
+    VIR_DOMAIN_DEVICE_MIGRATION_OPT_NO,
+
+    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;
@@ -286,6 +300,7 @@ struct _virDomainDiskDef {
     unsigned int transient : 1;
     virDomainDeviceInfo info;
     virStorageEncryptionPtr encryption;
+    virDomainDeviceMigrationInfoPtr migration;
 };
 
 
@@ -1893,5 +1908,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 8235ea1..bb6ee87 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -273,6 +273,8 @@ virDomainDeviceAddressTypeToString;
 virDomainDeviceDefFree;
 virDomainDeviceDefParse;
 virDomainDeviceInfoIterate;
+virDomainDeviceMigrationOptionalTypeFromString;
+virDomainDeviceMigrationOptionalTypeToString;
 virDomainDevicePCIAddressIsValid;
 virDomainDeviceTypeToString;
 virDomainDiskBusTypeToString;
-- 
1.7.3.4




More information about the libvir-list mailing list