mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
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:
parent
54e99644bf
commit
5cc50ad7a4
@ -1264,6 +1264,7 @@
|
|||||||
<driver name='qemu' type='raw'/>
|
<driver name='qemu' type='raw'/>
|
||||||
<source dev='/dev/sda'/>
|
<source dev='/dev/sda'/>
|
||||||
<geometry cyls='16383' heads='16' secs='63' trans='lba'/>
|
<geometry cyls='16383' heads='16' secs='63' trans='lba'/>
|
||||||
|
<iolimits logical_block_size='512' physical_block_size='4096'/>
|
||||||
<target dev='hda' bus='ide'/>
|
<target dev='hda' bus='ide'/>
|
||||||
</disk>
|
</disk>
|
||||||
</devices>
|
</devices>
|
||||||
@ -1632,6 +1633,23 @@
|
|||||||
BIOS-Translation-Modus (none, lba or auto)</dd>
|
BIOS-Translation-Modus (none, lba or auto)</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</dd>
|
</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>
|
</dl>
|
||||||
|
|
||||||
<h4><a name="elementsFilesystems">Filesystems</a></h4>
|
<h4><a name="elementsFilesystems">Filesystems</a></h4>
|
||||||
|
@ -886,6 +886,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="geometry"/>
|
<ref name="geometry"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name="diskIoLimits"/>
|
||||||
|
</optional>
|
||||||
</interleave>
|
</interleave>
|
||||||
</define>
|
</define>
|
||||||
<define name="snapshot">
|
<define name="snapshot">
|
||||||
@ -1110,6 +1113,20 @@
|
|||||||
</optional>
|
</optional>
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</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.
|
Disk may use a special driver for access.
|
||||||
-->
|
-->
|
||||||
|
@ -3421,6 +3421,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
char *authUUID = NULL;
|
char *authUUID = NULL;
|
||||||
char *usageType = NULL;
|
char *usageType = NULL;
|
||||||
char *tray = NULL;
|
char *tray = NULL;
|
||||||
|
char *logical_block_size = NULL;
|
||||||
|
char *physical_block_size = NULL;
|
||||||
|
|
||||||
if (VIR_ALLOC(def) < 0) {
|
if (VIR_ALLOC(def) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
@ -3432,6 +3434,9 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
def->geometry.sectors = 0;
|
def->geometry.sectors = 0;
|
||||||
def->geometry.trans = VIR_DOMAIN_DISK_TRANS_DEFAULT;
|
def->geometry.trans = VIR_DOMAIN_DISK_TRANS_DEFAULT;
|
||||||
|
|
||||||
|
def->iolimits.logical_block_size = 0;
|
||||||
|
def->iolimits.physical_block_size = 0;
|
||||||
|
|
||||||
ctxt->node = node;
|
ctxt->node = node;
|
||||||
|
|
||||||
type = virXMLPropString(node, "type");
|
type = virXMLPropString(node, "type");
|
||||||
@ -3570,6 +3575,27 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
goto error;
|
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 &&
|
} else if (!driverName &&
|
||||||
xmlStrEqual(cur->name, BAD_CAST "driver")) {
|
xmlStrEqual(cur->name, BAD_CAST "driver")) {
|
||||||
driverName = virXMLPropString(cur, "name");
|
driverName = virXMLPropString(cur, "name");
|
||||||
@ -4075,6 +4101,8 @@ cleanup:
|
|||||||
VIR_FREE(serial);
|
VIR_FREE(serial);
|
||||||
virStorageEncryptionFree(encryption);
|
virStorageEncryptionFree(encryption);
|
||||||
VIR_FREE(startupPolicy);
|
VIR_FREE(startupPolicy);
|
||||||
|
VIR_FREE(logical_block_size);
|
||||||
|
VIR_FREE(physical_block_size);
|
||||||
|
|
||||||
ctxt->node = save_ctxt;
|
ctxt->node = save_ctxt;
|
||||||
return def;
|
return def;
|
||||||
@ -11341,6 +11369,26 @@ static void virDomainDiskGeometryDefFormat(virBufferPtr buf,
|
|||||||
virBufferAddLit(buf, "/>\n");
|
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
|
static int
|
||||||
virDomainDiskDefFormat(virBufferPtr buf,
|
virDomainDiskDefFormat(virBufferPtr buf,
|
||||||
@ -11514,6 +11562,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
virDomainDiskGeometryDefFormat(buf, def);
|
virDomainDiskGeometryDefFormat(buf, def);
|
||||||
|
virDomainDiskIolimitsDefFormat(buf, def);
|
||||||
|
|
||||||
/* For now, mirroring is currently output-only: we only output it
|
/* For now, mirroring is currently output-only: we only output it
|
||||||
* for live domains, therefore we ignore it on input except for
|
* for live domains, therefore we ignore it on input except for
|
||||||
|
@ -569,6 +569,11 @@ struct _virDomainDiskDef {
|
|||||||
int trans;
|
int trans;
|
||||||
} geometry;
|
} geometry;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned int logical_block_size;
|
||||||
|
unsigned int physical_block_size;
|
||||||
|
} iolimits;
|
||||||
|
|
||||||
virDomainBlockIoTuneInfo blkdeviotune;
|
virDomainBlockIoTuneInfo blkdeviotune;
|
||||||
|
|
||||||
char *serial;
|
char *serial;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user