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

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



From: J.B. Joret <jb 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.

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

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b6e0d5d..7f42753 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1222,6 +1222,12 @@
       &lt;target dev='sda' bus='scsi'/&gt;
       &lt;address type='drive' controller='0' bus='0' target='3' unit='0'/&gt;
     &lt;/disk&gt;
+    &lt;disk type='block' device='disk'&gt;
+      &lt;driver name='qemu' type='raw'/&gt;
+      &lt;source dev='/dev/sda'/&gt;
+      &lt;geometry cyls='16383' heads='16' secs='63' trans='lba'/&gt;
+      &lt;target dev='hda' bus='ide'/&gt;
+    &lt;/disk&gt;
   &lt;/devices&gt;
   ...</pre>
 
@@ -1569,6 +1575,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 b7562ad..b6970d9 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -945,6 +945,9 @@
                 </optional>
               </element>
             </optional>
+            <optional>
+              <ref name="geometry"/>
+            </optional>
             <ref name="diskspec"/>
           </interleave>
         </group>
@@ -963,6 +966,9 @@
                 </optional>
               </element>
             </optional>
+            <optional>
+              <ref name="geometry"/>
+            </optional>
             <ref name="diskspec"/>
           </interleave>
         </group>
@@ -1053,6 +1059,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 4f8c57a..4b208fc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -170,6 +170,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",
@@ -3347,6 +3353,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;
@@ -3375,6 +3382,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");
@@ -3484,6 +3496,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) {
+                    virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                                         _("invalid geometry settings (cyls)"));
+                    goto error;
+                }
+                if (virXPathUInt("string(./geometry/@heads)",
+                                 ctxt, &def->geometry.heads) < 0) {
+                    virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                                         _("invalid geometry settings (heads)"));
+                    goto error;
+                }
+                if (virXPathUInt("string(./geometry/@secs)",
+                                 ctxt, &def->geometry.sectors) < 0) {
+                    virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                                         _("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 {
+                        virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                                             _("invalid translation value '%s'"),
+                                             trans);
+                        goto error;
+                    }
+                }
             } else if (!driverName &&
                        xmlStrEqual(cur->name, BAD_CAST "driver")) {
                 driverName = virXMLPropString(cur, "name");
@@ -3962,6 +4008,7 @@ cleanup:
     VIR_FREE(target);
     VIR_FREE(source);
     VIR_FREE(tray);
+    VIR_FREE(trans);
     while (nhosts > 0) {
         virDomainDiskHostDefFree(&hosts[nhosts - 1]);
         nhosts--;
@@ -10973,6 +11020,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,
@@ -11094,6 +11163,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
             } else {
                 virBufferAddLit(buf, "/>\n");
             }
+            virDomainDiskGeometryDefFormat(buf, def);
             break;
         case VIR_DOMAIN_DISK_TYPE_BLOCK:
             virBufferEscapeString(buf, "      <source dev='%s'",
@@ -11107,6 +11177,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 5e5374a..018a1f1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -466,6 +466,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 {
@@ -575,6 +584,13 @@ struct _virDomainDiskDef {
     char *mirrorFormat;
     bool mirroring;
 
+    struct {
+        unsigned int cylinders;
+        unsigned int heads;
+        unsigned int sectors;
+        int trans;
+    } geometry;
+
     virDomainBlockIoTuneInfo blkdeviotune;
 
     char *serial;
@@ -2165,6 +2181,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 b173590..6b2064e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -304,6 +304,8 @@ virDomainDiskDefAssignAddress;
 virDomainDiskDefForeachPath;
 virDomainDiskDefFree;
 virDomainDiskDeviceTypeToString;
+virDomainDiskGeometryTransTypeToString;
+virDomainDiskGeometryTransTypeFromString;
 virDomainDiskErrorPolicyTypeFromString;
 virDomainDiskErrorPolicyTypeToString;
 virDomainDiskFindControllerModel;
-- 
1.7.0.4


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