[libvirt] [PATCHv5 1/2] Support for Disk Geometry Override

Viktor Mihajlovski mihajlov at linux.vnet.ibm.com
Mon Aug 20 11:58:24 UTC 2012


From: J.B. Joret <jb at linux.vnet.ibm.com>

A hypervisor may allow to override the disk geometry of drives.
Qemu, as an example with cyls=,heads=,secs=[,trans=].
This patch extends the domain config to allow the specification of
disk geometry with libvirt.

V2 Changes: Split out qemu specific code, add documentation and schema.

V3 Changes: Moved geometry element to diskspec and use virReportError now.

Signed-off-by: J.B. Joret <jb at linux.vnet.ibm.com>
Signed-off-by: Viktor Mihajlovski <mihajlov at linux.vnet.ibm.com>
---
 docs/formatdomain.html.in     |   25 ++++++++++++++
 docs/schemas/domaincommon.rng |   25 ++++++++++++++
 src/conf/domain_conf.c        |   71 +++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h        |   17 ++++++++++
 src/libvirt_private.syms      |    2 +
 5 files changed, 140 insertions(+), 0 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 2c5c456..bbf69bb 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1224,6 +1224,12 @@
       <target dev='sda' bus='scsi'/>
       <address type='drive' controller='0' bus='0' target='3' unit='0'/>
     </disk>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/sda'/>
+      <geometry cyls='16383' heads='16' secs='63' trans='lba'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
   </devices>
   ...</pre>
 
@@ -1571,6 +1577,25 @@
         associated with the Ceph secret
         object.  <span class="since">libvirt 0.9.7</span>
       </dd>
+      <dt><code>geometry</code></dt>
+      <dd>The optional <code>geometry</code> element provides the
+        ability to override geometry settings. This mostly useful for
+        S390 DASD-disks or older DOS-disks
+        <dl>
+          <dt><code>cyls</code></dt>
+          <dd>The <code>cyls</code> element is the
+            number of cylinders. </dd>
+          <dt><code>heads</code></dt>
+          <dd>The <code>heads</code> element is the
+            number of heads. </dd>
+          <dt><code>secs</code></dt>
+          <dd>The <code>secs</code> element is the
+            number of sectors per track. </dd>
+          <dt><code>trans</code></dt>
+          <dd>The optional <code>trans</code> element is the
+            BIOS-Translation-Modus (none, lba or auto)</dd>
+        </dl>
+      </dd>
     </dl>
 
     <h4><a name="elementsFilesystems">Filesystems</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4903ca6..428df54 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -852,6 +852,9 @@
       <optional>
         <ref name="address"/>
       </optional>
+      <optional>
+        <ref name="geometry"/>
+      </optional>
     </interleave>
   </define>
   <define name="snapshot">
@@ -1054,6 +1057,28 @@
       </optional>
     </element>
   </define>
+  <define name="geometry">
+    <element name="geometry">
+      <attribute name="cyls">
+        <data type="integer"/>
+      </attribute>
+      <attribute name="heads">
+        <data type="integer"/>
+      </attribute>
+      <attribute name="secs">
+        <data type="integer"/>
+      </attribute>
+      <optional>
+        <attribute name="trans">
+          <choice>
+            <value>auto</value>
+            <value>none</value>
+            <value>lba</value>
+          </choice>
+        </attribute>
+      </optional>
+    </element>
+  </define>
   <!--
       Disk may use a special driver for access.
     -->
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a2e73c6..7662a6a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -171,6 +171,12 @@ VIR_ENUM_IMPL(virDomainDiskDevice, VIR_DOMAIN_DISK_DEVICE_LAST,
               "floppy",
               "lun")
 
+VIR_ENUM_IMPL(virDomainDiskGeometryTrans, VIR_DOMAIN_DISK_TRANS_LAST,
+              "default",
+              "none",
+              "auto",
+              "lba")
+
 VIR_ENUM_IMPL(virDomainDiskBus, VIR_DOMAIN_DISK_BUS_LAST,
               "ide",
               "fdc",
@@ -3336,6 +3342,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
     char *source = NULL;
     char *target = NULL;
     char *protocol = NULL;
+    char *trans = NULL;
     virDomainDiskHostDefPtr hosts = NULL;
     int nhosts = 0;
     char *bus = NULL;
@@ -3364,6 +3371,11 @@ virDomainDiskDefParseXML(virCapsPtr caps,
         return NULL;
     }
 
+    def->geometry.cylinders = 0;
+    def->geometry.heads = 0;
+    def->geometry.sectors = 0;
+    def->geometry.trans = VIR_DOMAIN_DISK_TRANS_DEFAULT;
+
     ctxt->node = node;
 
     type = virXMLPropString(node, "type");
@@ -3473,6 +3485,40 @@ virDomainDiskDefParseXML(virCapsPtr caps,
                 if (target &&
                     STRPREFIX(target, "ioemu:"))
                     memmove(target, target+6, strlen(target)-5);
+            } else if (xmlStrEqual(cur->name, BAD_CAST "geometry")) {
+                if (virXPathUInt("string(./geometry/@cyls)",
+                                 ctxt, &def->geometry.cylinders) < 0) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("invalid geometry settings (cyls)"));
+                    goto error;
+                }
+                if (virXPathUInt("string(./geometry/@heads)",
+                                 ctxt, &def->geometry.heads) < 0) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("invalid geometry settings (heads)"));
+                    goto error;
+                }
+                if (virXPathUInt("string(./geometry/@secs)",
+                                 ctxt, &def->geometry.sectors) < 0) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("invalid geometry settings (secs)"));
+                    goto error;
+                }
+                trans = virXMLPropString(cur, "trans");
+                if (trans != NULL) {
+                    if (STREQ(trans, "none"))
+                        def->geometry.trans = VIR_DOMAIN_DISK_TRANS_NONE;
+                    else if (STREQ(trans, "auto"))
+                        def->geometry.trans = VIR_DOMAIN_DISK_TRANS_AUTO;
+                    else if (STREQ(trans, "lba"))
+                        def->geometry.trans = VIR_DOMAIN_DISK_TRANS_LBA;
+                    else {
+                        virReportError(VIR_ERR_INTERNAL_ERROR,
+                                       _("invalid translation value '%s'"),
+                                       trans);
+                        goto error;
+                    }
+                }
             } else if (!driverName &&
                        xmlStrEqual(cur->name, BAD_CAST "driver")) {
                 driverName = virXMLPropString(cur, "name");
@@ -3951,6 +3997,7 @@ cleanup:
     VIR_FREE(target);
     VIR_FREE(source);
     VIR_FREE(tray);
+    VIR_FREE(trans);
     while (nhosts > 0) {
         virDomainDiskHostDefFree(&hosts[nhosts - 1]);
         nhosts--;
@@ -11081,6 +11128,28 @@ virDomainLeaseDefFormat(virBufferPtr buf,
     return 0;
 }
 
+static void virDomainDiskGeometryDefFormat(virBufferPtr buf,
+                                           virDomainDiskDefPtr def)
+{
+    const char *trans =
+        virDomainDiskGeometryTransTypeToString(def->geometry.trans);
+
+    if (def->geometry.cylinders > 0 &&
+        def->geometry.heads > 0 &&
+        def->geometry.sectors > 0) {
+        virBufferAsprintf(buf,
+                          "      <geometry cyls='%u' heads='%u' secs='%u'",
+                          def->geometry.cylinders,
+                          def->geometry.heads,
+                          def->geometry.sectors);
+
+        if (def->geometry.trans != VIR_DOMAIN_DISK_TRANS_DEFAULT)
+            virBufferEscapeString(buf, " trans='%s'", trans);
+
+        virBufferAddLit(buf, "/>\n");
+    }
+}
+
 static int
 virDomainDiskDefFormat(virBufferPtr buf,
                        virDomainDiskDefPtr def,
@@ -11202,6 +11271,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
             } else {
                 virBufferAddLit(buf, "/>\n");
             }
+            virDomainDiskGeometryDefFormat(buf, def);
             break;
         case VIR_DOMAIN_DISK_TYPE_BLOCK:
             virBufferEscapeString(buf, "      <source dev='%s'",
@@ -11215,6 +11285,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
             } else {
                 virBufferAddLit(buf, "/>\n");
             }
+            virDomainDiskGeometryDefFormat(buf, def);
             break;
         case VIR_DOMAIN_DISK_TYPE_DIR:
             virBufferEscapeString(buf, "      <source dir='%s'/>\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index fae7792..3b62e4c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -469,6 +469,15 @@ enum virDomainDiskTray {
     VIR_DOMAIN_DISK_TRAY_LAST
 };
 
+enum  virDomainDiskGeometryTrans {
+    VIR_DOMAIN_DISK_TRANS_DEFAULT = 0,
+    VIR_DOMAIN_DISK_TRANS_NONE,
+    VIR_DOMAIN_DISK_TRANS_AUTO,
+    VIR_DOMAIN_DISK_TRANS_LBA,
+
+    VIR_DOMAIN_DISK_TRANS_LAST
+};
+
 typedef struct _virDomainDiskHostDef virDomainDiskHostDef;
 typedef virDomainDiskHostDef *virDomainDiskHostDefPtr;
 struct _virDomainDiskHostDef {
@@ -578,6 +587,13 @@ struct _virDomainDiskDef {
     char *mirrorFormat;
     bool mirroring;
 
+    struct {
+        unsigned int cylinders;
+        unsigned int heads;
+        unsigned int sectors;
+        int trans;
+    } geometry;
+
     virDomainBlockIoTuneInfo blkdeviotune;
 
     char *serial;
@@ -2171,6 +2187,7 @@ VIR_ENUM_DECL(virDomainDeviceAddress)
 VIR_ENUM_DECL(virDomainDeviceAddressPciMulti)
 VIR_ENUM_DECL(virDomainDisk)
 VIR_ENUM_DECL(virDomainDiskDevice)
+VIR_ENUM_DECL(virDomainDiskGeometryTrans)
 VIR_ENUM_DECL(virDomainDiskBus)
 VIR_ENUM_DECL(virDomainDiskCache)
 VIR_ENUM_DECL(virDomainDiskErrorPolicy)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e91540d..7f4c1c6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -315,6 +315,8 @@ virDomainDiskDefAssignAddress;
 virDomainDiskDefForeachPath;
 virDomainDiskDefFree;
 virDomainDiskDeviceTypeToString;
+virDomainDiskGeometryTransTypeToString;
+virDomainDiskGeometryTransTypeFromString;
 virDomainDiskErrorPolicyTypeFromString;
 virDomainDiskErrorPolicyTypeToString;
 virDomainDiskFindControllerModel;
-- 
1.7.0.4




More information about the libvir-list mailing list