conf: Introduce <metadata_cache> subelement of <disk><driver>

In certain specific cases it might be beneficial to be able to control
the metadata caching of storage image format drivers of a hypervisor.

Introduce XML machinery to set the maximum size of the metadata cache
which will be used by qemu's qcow2 driver.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2021-01-06 18:20:22 +01:00
parent a01726e9cf
commit 154df5840d
8 changed files with 216 additions and 6 deletions

View File

@ -2755,6 +2755,11 @@ paravirtualized driver is specified via the ``disk`` element.
``format``
The ``format`` element contains ``type`` attribute which specifies the
internal format of the backing store, such as ``raw`` or ``qcow2``.
The ``format`` element can contain ``metadata_cache`` subelement, which
has identical semantics to the identically named subelement of ``driver``
of a ``disk``.
``source``
This element has the same structure as the ``source`` element in ``disk``.
It specifies which file, device, or network location contains the data of
@ -2967,6 +2972,44 @@ paravirtualized driver is specified via the ``disk`` element.
virtio-blk. ( :since:`Since 3.9.0` )
- For virtio disks, `Virtio-specific options <#elementsVirtio>`__ can also
be set. ( :since:`Since 3.5.0` )
- The optional ``metadata_cache`` subelement controls aspects related to the
format specific caching of storage image metadata. Note that this setting
applies only on the top level image; the identically named subelement of
``backingStore``'s ``format`` element can be used to specify cache
settings for the backing image.
:since:`Since 7.0.0` the maximum size of the metadata cache of ``qcow2``
format driver of the ``qemu`` hypervisor can be controlled via the
``max_size`` subelement (see example below).
In the majority of cases the default configuration used by the hypervisor
is sufficient so modifying this setting should not be necessary. For
specifics on how the metadata cache of ``qcow2`` in ``qemu`` behaves refer
to the ``qemu``
`qcow2 cache docs <https://git.qemu.org/?p=qemu.git;a=blob;f=docs/qcow2-cache.txt>`__
**Example:**
::
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'>
<metadata_cache>
<max_size unit='bytes'>1234</max_size>
</metadata_cache>
</driver>
<source file='/var/lib/libvirt/images/domain.qcow'/>
<backingStore type='file'>
<format type='qcow2'>
<metadata_cache>
<max_size unit='bytes'>1234</max_size>
</metadata_cache>
</format>
<source file='/var/lib/libvirt/images/snapshot.qcow'/>
<backingStore/>
</backingStore>
<target dev='vdd' bus='virtio'/>
</disk>
``backenddomain``
The optional ``backenddomain`` element allows specifying a backend domain

View File

@ -1590,7 +1590,15 @@
<attribute name="type">
<ref name="storageFormat"/>
</attribute>
<empty/>
<optional>
<element name="metadata_cache">
<optional>
<element name="max_size">
<ref name="scaledInteger"/>
</element>
</optional>
</element>
</optional>
</element>
</define>
@ -2267,7 +2275,15 @@
</attribute>
</optional>
<ref name="virtioOptions"/>
<empty/>
<optional>
<element name="metadata_cache">
<optional>
<element name="max_size">
<ref name="scaledInteger"/>
</element>
</optional>
</element>
</optional>
</element>
</define>
<define name="driverFormat">

View File

@ -8609,6 +8609,12 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
if (!(backingStore = virDomainStorageSourceParseBase(type, format, idx)))
return -1;
if (virParseScaledValue("./format/metadata_cache/max_size", NULL,
ctxt,
&backingStore->metadataCacheMaxSize,
1, ULLONG_MAX, false) < 0)
return -1;
/* backing store is always read-only */
backingStore->readonly = true;
@ -8959,9 +8965,13 @@ virDomainDiskDefParseValidate(const virDomainDiskDef *def)
static int
virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def,
xmlNodePtr cur)
xmlNodePtr cur,
xmlXPathContextPtr ctxt)
{
g_autofree char *tmp = NULL;
VIR_XPATH_NODE_AUTORESTORE(ctxt)
ctxt->node = cur;
def->driverName = virXMLPropString(cur, "name");
@ -9071,6 +9081,12 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def,
return -1;
}
if (virParseScaledValue("./metadata_cache/max_size", NULL,
ctxt,
&def->src->metadataCacheMaxSize,
1, ULLONG_MAX, false) < 0)
return -1;
return 0;
}
@ -9227,7 +9243,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
if (virDomainVirtioOptionsParseXML(cur, &def->virtio) < 0)
return NULL;
if (virDomainDiskDefDriverParseXML(def, cur) < 0)
if (virDomainDiskDefDriverParseXML(def, cur, ctxt) < 0)
return NULL;
} else if (!def->mirror &&
virXMLNodeNameEqual(cur, "mirror") &&
@ -24081,6 +24097,8 @@ virDomainDiskBackingStoreFormat(virBufferPtr buf,
{
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
g_auto(virBuffer) formatAttrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) formatChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
bool inactive = flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE;
virStorageSourcePtr backingStore = src->backingStore;
@ -24108,8 +24126,22 @@ virDomainDiskBackingStoreFormat(virBufferPtr buf,
if (backingStore->id != 0)
virBufferAsprintf(&attrBuf, " index='%u'", backingStore->id);
virBufferAsprintf(&childBuf, "<format type='%s'/>\n",
virBufferAsprintf(&formatAttrBuf, " type='%s'",
virStorageFileFormatTypeToString(backingStore->format));
if (backingStore->metadataCacheMaxSize > 0) {
g_auto(virBuffer) metadataCacheChildBuf = VIR_BUFFER_INIT_CHILD(&formatChildBuf);
virBufferAsprintf(&metadataCacheChildBuf,
"<max_size unit='bytes'>%llu</max_size>\n",
backingStore->metadataCacheMaxSize);
virXMLFormatElement(&formatChildBuf, "metadata_cache", NULL, &metadataCacheChildBuf);
}
virXMLFormatElement(&childBuf, "format", &formatAttrBuf, &formatChildBuf);
if (virDomainDiskSourceFormat(&childBuf, backingStore, "source", 0, false,
flags, false, false, xmlopt) < 0)
return -1;
@ -24177,6 +24209,7 @@ virDomainDiskDefFormatDriver(virBufferPtr buf,
virDomainDiskDefPtr disk)
{
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
virBufferEscapeString(&attrBuf, " name='%s'", virDomainDiskGetDriver(disk));
@ -24228,7 +24261,17 @@ virDomainDiskDefFormatDriver(virBufferPtr buf,
virDomainVirtioOptionsFormat(&attrBuf, disk->virtio);
virXMLFormatElement(buf, "driver", &attrBuf, NULL);
if (disk->src->metadataCacheMaxSize > 0) {
g_auto(virBuffer) metadataCacheChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
virBufferAsprintf(&metadataCacheChildBuf,
"<max_size unit='bytes'>%llu</max_size>\n",
disk->src->metadataCacheMaxSize);
virXMLFormatElement(&childBuf, "metadata_cache", NULL, &metadataCacheChildBuf);
}
virXMLFormatElement(buf, "driver", &attrBuf, &childBuf);
}

View File

@ -2217,6 +2217,7 @@ virStorageSourceCopy(const virStorageSource *src,
def->sslverify = src->sslverify;
def->readahead = src->readahead;
def->timeout = src->timeout;
def->metadataCacheMaxSize = src->metadataCacheMaxSize;
/* storage driver metadata are not copied */
def->drv = NULL;

View File

@ -322,6 +322,8 @@ struct _virStorageSource {
unsigned long long clusterSize; /* in bytes, 0 if unknown */
bool has_allocation; /* Set to true when provided in XML */
unsigned long long metadataCacheMaxSize; /* size of the metadata cache in bytes */
size_t nseclabels;
virSecurityDeviceLabelDefPtr *seclabels;

View File

@ -0,0 +1,46 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-i386</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'>
<metadata_cache>
<max_size>12345</max_size>
</metadata_cache>
</driver>
<source file='/tmp/QEMUGuest1.img'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'/>
<source file='/tmp/QEMUGuest2.img'/>
<backingStore type='file'>
<format type='qcow2'>
<metadata_cache>
<max_size unit='kiB'>1024</max_size>
</metadata_cache>
</format>
<source file='/tmp/backing-store.qcow'/>
<backingStore/>
</backingStore>
<target dev='hdb' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<controller type='usb' index='0'/>
<controller type='ide' index='0'/>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -0,0 +1,58 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-i386</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'>
<metadata_cache>
<max_size unit='bytes'>12345</max_size>
</metadata_cache>
</driver>
<source file='/tmp/QEMUGuest1.img'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'/>
<source file='/tmp/QEMUGuest2.img'/>
<backingStore type='file'>
<format type='qcow2'>
<metadata_cache>
<max_size unit='bytes'>1048576</max_size>
</metadata_cache>
</format>
<source file='/tmp/backing-store.qcow'/>
<backingStore/>
</backingStore>
<target dev='hdb' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<controller type='usb' index='0' model='piix3-uhci'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</memballoon>
</devices>
</domain>

View File

@ -294,6 +294,7 @@ mymain(void)
DO_TEST_CAPS_VER("disk-cache", "2.7.0");
DO_TEST_CAPS_VER("disk-cache", "2.12.0");
DO_TEST_CAPS_LATEST("disk-cache");
DO_TEST_CAPS_LATEST("disk-metadata-cache");
DO_TEST("disk-network-nbd", NONE);
DO_TEST("disk-network-iscsi", QEMU_CAPS_VIRTIO_SCSI,
QEMU_CAPS_SCSI_BLOCK);