This introduces the ability to set the discard granularity option for a disk. It defines the smallest amount of data that can be discarded in a single operation (useful for managing and optimizing storage). However, most hypervisors automatically set the proper discard granularity and users usually do not need to change the default setting. Signed-off-by: Kristina Hanicova <khanicov@xxxxxxxxxx> --- docs/formatdomain.rst | 6 +++++- src/conf/domain_conf.c | 19 ++++++++++++++++++- src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 3 ++- src/conf/schemas/domaincommon.rng | 5 +++++ src/qemu/qemu_domain.c | 2 ++ src/vz/vz_utils.c | 3 ++- 7 files changed, 35 insertions(+), 4 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index cd9cb02bf8..0d0812f08c 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2588,7 +2588,7 @@ paravirtualized driver is specified via the ``disk`` element. <driver name='qemu' type='raw'/> <source dev='/dev/sda'/> <geometry cyls='16383' heads='16' secs='63' trans='lba'/> - <blockio logical_block_size='512' physical_block_size='4096'/> + <blockio logical_block_size='512' physical_block_size='4096' discard_granularity='4096'/> <target dev='hdj' bus='ide'/> </disk> <disk type='volume' device='disk'> @@ -3435,6 +3435,10 @@ paravirtualized driver is specified via the ``disk`` element. 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. + ``discard_granularity`` + The smallest amount of data that can be discarded in a single operation. + It impacts the unmap operations and it must be a multiple of a + ``logical_block_size``. Filesystems ~~~~~~~~~~~ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 69934026ef..bb4f1fdb94 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8073,6 +8073,10 @@ virDomainDiskDefParseXML(virDomainXMLOption *xmlopt, if (virXMLPropUInt(blockioNode, "physical_block_size", 10, VIR_XML_PROP_NONE, &def->blockio.physical_block_size) < 0) return NULL; + + if (virXMLPropUInt(blockioNode, "discard_granularity", 10, VIR_XML_PROP_NONE, + &def->blockio.discard_granularity) < 0) + return NULL; } if ((driverNode = virXPathNode("./driver", ctxt))) { @@ -19836,6 +19840,13 @@ virDomainDiskBlockIoCheckABIStability(virDomainDiskDef *src, dst->blockio.physical_block_size, src->blockio.physical_block_size); return false; } + + if (src->blockio.discard_granularity != dst->blockio.discard_granularity) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target disk discard_granularity %1$u does not match source %2$u"), + dst->blockio.discard_granularity, src->blockio.discard_granularity); + return false; + } return true; } @@ -22132,7 +22143,8 @@ virDomainDiskBlockIoDefFormat(virBuffer *buf, virDomainDiskDef *def) { if (def->blockio.logical_block_size > 0 || - def->blockio.physical_block_size > 0) { + def->blockio.physical_block_size > 0 || + def->blockio.discard_granularity > 0) { virBufferAddLit(buf, "<blockio"); if (def->blockio.logical_block_size > 0) { virBufferAsprintf(buf, @@ -22144,6 +22156,11 @@ virDomainDiskBlockIoDefFormat(virBuffer *buf, " physical_block_size='%u'", def->blockio.physical_block_size); } + if (def->blockio.discard_granularity > 0) { + virBufferAsprintf(buf, + " discard_granularity='%u'", + def->blockio.discard_granularity); + } virBufferAddLit(buf, "/>\n"); } } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8bef097542..ca195a52d2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -579,6 +579,7 @@ struct _virDomainDiskDef { struct { unsigned int logical_block_size; unsigned int physical_block_size; + unsigned int discard_granularity; } blockio; virDomainBlockIoTuneInfo blkdeviotune; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index b286990b19..fd3eed3230 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -466,7 +466,8 @@ virDomainDiskVhostUserValidate(const virDomainDiskDef *disk) } if (disk->blockio.logical_block_size > 0 || - disk->blockio.physical_block_size > 0) { + disk->blockio.physical_block_size > 0 || + disk->blockio.discard_granularity > 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("blockio is not supported with vhostuser disk")); return -1; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 2556ac01ed..de3bd1c35c 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -2461,6 +2461,11 @@ <data type="integer"/> </attribute> </optional> + <optional> + <attribute name="discard_granularity"> + <data type="integer"/> + </attribute> + </optional> </element> </define> <!-- diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0b2b22a219..bfeddc7746 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8426,6 +8426,8 @@ qemuDomainDiskChangeSupported(virDomainDiskDef *disk, "blockio logical_block_size", false); CHECK_EQ(blockio.physical_block_size, "blockio physical_block_size", false); + CHECK_EQ(blockio.discard_granularity, + "blockio discard_granularity", false); CHECK_EQ(blkdeviotune.total_bytes_sec, "blkdeviotune total_bytes_sec", diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c index 7db7dbd419..de707df883 100644 --- a/src/vz/vz_utils.c +++ b/src/vz/vz_utils.c @@ -279,7 +279,8 @@ vzCheckDiskUnsupportedParams(virDomainDiskDef *disk) } if (disk->blockio.logical_block_size || - disk->blockio.physical_block_size) { + disk->blockio.physical_block_size || + disk->blockio.discard_granularity) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Setting disk block sizes is not " "supported by vz driver.")); -- 2.41.0