conf: Support for Block Device IO Limits

Introducing a new iolimits element allowing to override certain
properties of a guest block device like the physical and logical
block size.
This can be useful for platforms with 'non-standard' disk formats
like S390 DASD with its 4K block size.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
This commit is contained in:
Viktor Mihajlovski 2012-08-29 17:48:30 +02:00 committed by Eric Blake
parent 54e99644bf
commit 5cc50ad7a4
4 changed files with 89 additions and 0 deletions

View File

@ -1264,6 +1264,7 @@
&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;iolimits logical_block_size='512' physical_block_size='4096'/&gt;
&lt;target dev='hda' bus='ide'/&gt;
&lt;/disk&gt;
&lt;/devices&gt;
@ -1632,6 +1633,23 @@
BIOS-Translation-Modus (none, lba or auto)</dd>
</dl>
</dd>
<dt><code>iolimits</code></dt>
<dd>If present, the <code>iolimits</code> element allows
to override any of the block device properties listed below.
<span class="since">Since 0.10.2 (QEMU and KVM)</span>
<dl>
<dt><code>logical_block_size</code></dt>
<dd>The logical block size the disk will report to the guest
OS. For Linux this would be the value returned by the
BLKSSZGET ioctl and describes the smallest units for disk
I/O.
<dt><code>physical_block_size</code></dt>
<dd>The physical block size the disk will report to the guest
OS. For Linux this would be the value returned by the
BLKPBSZGET ioctl and describes the disk's hardware sector
size which can be relevant for the alignment of disk data.
</dl>
</dd>
</dl>
<h4><a name="elementsFilesystems">Filesystems</a></h4>

View File

@ -886,6 +886,9 @@
<optional>
<ref name="geometry"/>
</optional>
<optional>
<ref name="diskIoLimits"/>
</optional>
</interleave>
</define>
<define name="snapshot">
@ -1110,6 +1113,20 @@
</optional>
</element>
</define>
<define name="diskIoLimits">
<element name="iolimits">
<optional>
<attribute name="logical_block_size">
<data type="integer"/>
</attribute>
</optional>
<optional>
<attribute name="physical_block_size">
<data type="integer"/>
</attribute>
</optional>
</element>
</define>
<!--
Disk may use a special driver for access.
-->

View File

@ -3421,6 +3421,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
char *authUUID = NULL;
char *usageType = NULL;
char *tray = NULL;
char *logical_block_size = NULL;
char *physical_block_size = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@ -3432,6 +3434,9 @@ virDomainDiskDefParseXML(virCapsPtr caps,
def->geometry.sectors = 0;
def->geometry.trans = VIR_DOMAIN_DISK_TRANS_DEFAULT;
def->iolimits.logical_block_size = 0;
def->iolimits.physical_block_size = 0;
ctxt->node = node;
type = virXMLPropString(node, "type");
@ -3570,6 +3575,27 @@ virDomainDiskDefParseXML(virCapsPtr caps,
goto error;
}
}
} else if (xmlStrEqual(cur->name, BAD_CAST "iolimits")) {
logical_block_size =
virXMLPropString(cur, "logical_block_size");
if (logical_block_size &&
virStrToLong_ui(logical_block_size, NULL, 0,
&def->iolimits.logical_block_size) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("invalid logical block size '%s'"),
logical_block_size);
goto error;
}
physical_block_size =
virXMLPropString(cur, "physical_block_size");
if (physical_block_size &&
virStrToLong_ui(physical_block_size, NULL, 0,
&def->iolimits.physical_block_size) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("invalid physical block size '%s'"),
physical_block_size);
goto error;
}
} else if (!driverName &&
xmlStrEqual(cur->name, BAD_CAST "driver")) {
driverName = virXMLPropString(cur, "name");
@ -4075,6 +4101,8 @@ cleanup:
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
VIR_FREE(startupPolicy);
VIR_FREE(logical_block_size);
VIR_FREE(physical_block_size);
ctxt->node = save_ctxt;
return def;
@ -11341,6 +11369,26 @@ static void virDomainDiskGeometryDefFormat(virBufferPtr buf,
virBufferAddLit(buf, "/>\n");
}
}
static void virDomainDiskIolimitsDefFormat(virBufferPtr buf,
virDomainDiskDefPtr def)
{
if (def->iolimits.logical_block_size > 0 ||
def->iolimits.physical_block_size > 0) {
virBufferAddLit(buf," <iolimits");
if (def->iolimits.logical_block_size > 0) {
virBufferAsprintf(buf,
" logical_block_size='%u'",
def->iolimits.logical_block_size);
}
if (def->iolimits.physical_block_size > 0) {
virBufferAsprintf(buf,
" physical_block_size='%u'",
def->iolimits.physical_block_size);
}
virBufferAddLit(buf, "/>\n");
}
}
static int
virDomainDiskDefFormat(virBufferPtr buf,
@ -11514,6 +11562,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
}
virDomainDiskGeometryDefFormat(buf, def);
virDomainDiskIolimitsDefFormat(buf, def);
/* For now, mirroring is currently output-only: we only output it
* for live domains, therefore we ignore it on input except for

View File

@ -569,6 +569,11 @@ struct _virDomainDiskDef {
int trans;
} geometry;
struct {
unsigned int logical_block_size;
unsigned int physical_block_size;
} iolimits;
virDomainBlockIoTuneInfo blkdeviotune;
char *serial;