From: J.B. Joret <jb(a)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(a)linux.vnet.ibm.com>
Signed-off-by: Viktor Mihajlovski <mihajlov(a)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 b6e0d5d..7f42753 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1222,6 +1222,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>
@@ -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..dd6496e 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -851,6 +851,9 @@
<optional>
<ref name="address"/>
</optional>
+ <optional>
+ <ref name="geometry"/>
+ </optional>
</interleave>
</define>
<define name="snapshot">
@@ -1053,6 +1056,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 1b5dad9..0c4bdc9 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",
@@ -3343,6 +3349,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;
@@ -3371,6 +3378,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");
@@ -3480,6 +3492,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");
@@ -3958,6 +4004,7 @@ cleanup:
VIR_FREE(target);
VIR_FREE(source);
VIR_FREE(tray);
+ VIR_FREE(trans);
while (nhosts > 0) {
virDomainDiskHostDefFree(&hosts[nhosts - 1]);
nhosts--;
@@ -10976,6 +11023,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,
@@ -11097,6 +11166,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
} else {
virBufferAddLit(buf, "/>\n");
}
+ virDomainDiskGeometryDefFormat(buf, def);
break;
case VIR_DOMAIN_DISK_TYPE_BLOCK:
virBufferEscapeString(buf, " <source dev='%s'",
@@ -11110,6 +11180,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 6c777e7..ae5ae3c 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 734c881..d6dd166 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -307,6 +307,8 @@ virDomainDiskDefAssignAddress;
virDomainDiskDefForeachPath;
virDomainDiskDefFree;
virDomainDiskDeviceTypeToString;
+virDomainDiskGeometryTransTypeToString;
+virDomainDiskGeometryTransTypeFromString;
virDomainDiskErrorPolicyTypeFromString;
virDomainDiskErrorPolicyTypeToString;
virDomainDiskFindControllerModel;
--
1.7.0.4