Support for Disk Geometry Override

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.

Signed-off-by: J.B. Joret <jb@linux.vnet.ibm.com>
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
This commit is contained in:
J.B. Joret 2012-08-20 15:58:50 +02:00 committed by Eric Blake
parent 4fce1c43ca
commit 5d4f8d9746
6 changed files with 137 additions and 0 deletions

View File

@ -258,6 +258,8 @@ Patches have also been contributed by:
Asad Saeed <asad.saeed@acidseed.com>
Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Thomas Woerner <twoerner@redhat.com>
J.B. Joret <jb@linux.vnet.ibm.com>
[....send patches to get your name here....]
The libvirt Logo was designed by Diana Fong

View File

@ -1224,6 +1224,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>
@ -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. <span class="since">0.10.0</span>
<dl>
<dt><code>cyls</code></dt>
<dd>The <code>cyls</code> attribute is the
number of cylinders. </dd>
<dt><code>heads</code></dt>
<dd>The <code>heads</code> attribute is the
number of heads. </dd>
<dt><code>secs</code></dt>
<dd>The <code>secs</code> attribute is the
number of sectors per track. </dd>
<dt><code>trans</code></dt>
<dd>The optional <code>trans</code> attribute is the
BIOS-Translation-Modus (none, lba or auto)</dd>
</dl>
</dd>
</dl>
<h4><a name="elementsFilesystems">Filesystems</a></h4>

View File

@ -866,6 +866,9 @@
<optional>
<ref name="address"/>
</optional>
<optional>
<ref name="geometry"/>
</optional>
</interleave>
</define>
<define name="snapshot">
@ -1068,6 +1071,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.
-->

View File

@ -166,6 +166,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",
@ -3351,6 +3357,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;
@ -3379,6 +3386,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");
@ -3488,6 +3500,35 @@ 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) {
def->geometry.trans = virDomainDiskGeometryTransTypeFromString(trans);
if (def->geometry.trans <= 0) {
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");
@ -3966,6 +4007,7 @@ cleanup:
VIR_FREE(target);
VIR_FREE(source);
VIR_FREE(tray);
VIR_FREE(trans);
while (nhosts > 0) {
virDomainDiskHostDefFree(&hosts[nhosts - 1]);
nhosts--;
@ -11109,6 +11151,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,
@ -11280,6 +11344,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
}
}
virDomainDiskGeometryDefFormat(buf, def);
/* For now, mirroring is currently output-only: we only output it
* for live domains, therefore we ignore it on input except for
* the internal parse on libvirtd restart. */

View File

@ -453,6 +453,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 {
@ -561,6 +570,13 @@ struct _virDomainDiskDef {
char *mirrorFormat;
bool mirroring;
struct {
unsigned int cylinders;
unsigned int heads;
unsigned int sectors;
int trans;
} geometry;
virDomainBlockIoTuneInfo blkdeviotune;
char *serial;
@ -2166,6 +2182,7 @@ VIR_ENUM_DECL(virDomainDevice)
VIR_ENUM_DECL(virDomainDeviceAddress)
VIR_ENUM_DECL(virDomainDisk)
VIR_ENUM_DECL(virDomainDiskDevice)
VIR_ENUM_DECL(virDomainDiskGeometryTrans)
VIR_ENUM_DECL(virDomainDiskBus)
VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainDiskErrorPolicy)

View File

@ -326,6 +326,8 @@ virDomainDiskDeviceTypeToString;
virDomainDiskErrorPolicyTypeFromString;
virDomainDiskErrorPolicyTypeToString;
virDomainDiskFindControllerModel;
virDomainDiskGeometryTransTypeFromString;
virDomainDiskGeometryTransTypeToString;
virDomainDiskIndexByName;
virDomainDiskInsert;
virDomainDiskInsertPreAlloced;