1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

qemu: implement QEMU NBD source reconnect delay attribute

Currently it's only possible to set this parameter during domain
creation via QEMU commandline passthrough feature.
With the new delay attribute it's also possible to set this
parameter if you want to attach a new NBD disk
using "virsh attach-device domain device.xml" e.g.:

  <disk type='network' device='disk'>
    <driver name='qemu' type='raw'/>
    <source protocol='nbd' name='foo'>
      <host name='example.org' port='6000'/>
      <reconnect delay='10'/>
    </source>
    <target dev='vdb' bus='virtio'/>
  </disk>

Signed-off-by: Christian Nautze <christian.nautze@exoscale.ch>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Christian Nautze 2023-02-27 12:15:33 +01:00 committed by Michal Privoznik
parent 97dddef48c
commit a9a4421ba8
11 changed files with 84 additions and 19 deletions

View File

@ -2956,13 +2956,20 @@ paravirtualized driver is specified via the ``disk`` element.
are intended to be default, then the entire element may be omitted. are intended to be default, then the entire element may be omitted.
``reconnect`` ``reconnect``
For disk type ``vhostuser`` configures reconnect timeout if the connection For disk type ``vhostuser`` configures reconnect timeout if the connection
is lost. It has two mandatory attributes: is lost. This is set with the two mandatory attributes ``enabled`` and
``timeout``.
For disk type ``network`` and protocol ``nbd`` the QEMU NBD reconnect delay
can be set via attribute ``delay``:
``enabled`` ``enabled``
If the reconnect feature is enabled, accepts ``yes`` and ``no`` If the reconnect feature is enabled, accepts ``yes`` and ``no``
``timeout`` ``timeout``
The amount of seconds after which hypervisor tries to reconnect. The amount of seconds after which hypervisor tries to reconnect.
``delay``
Only for NBD hosts. The amount of seconds during which all requests are
paused and will be rerun after a successful reconnect. After that time, any
delayed requests and all future requests before a successful reconnect
will immediately fail. If not set the default QEMU value is 0.
For a "file" or "volume" disk type which represents a cdrom or floppy (the For a "file" or "volume" disk type which represents a cdrom or floppy (the
``device`` attribute), it is possible to define policy what to do with the ``device`` attribute), it is possible to define policy what to do with the

View File

@ -7166,6 +7166,15 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
src->tlsFromConfig = !!value; src->tlsFromConfig = !!value;
} }
if (src->protocol == VIR_STORAGE_NET_PROTOCOL_NBD) {
xmlNodePtr cur;
if ((cur = virXPathNode("./reconnect", ctxt))) {
if (virXMLPropUInt(cur, "delay", 10, VIR_XML_PROP_NONE,
&src->reconnectDelay) < 0)
return -1;
}
}
/* for historical reasons we store the volume and image name in one XML /* for historical reasons we store the volume and image name in one XML
* element although it complicates thing when attempting to access them. */ * element although it complicates thing when attempting to access them. */
if (src->path && if (src->path &&
@ -22146,6 +22155,9 @@ virDomainDiskSourceFormatNetwork(virBuffer *attrBuf,
virBufferAddLit(childBuf, "/>\n"); virBufferAddLit(childBuf, "/>\n");
} }
if (src->reconnectDelay) {
virBufferAsprintf(childBuf, "<reconnect delay='%u'/>\n", src->reconnectDelay);
}
virBufferEscapeString(childBuf, "<snapshot name='%s'/>\n", src->snapshot); virBufferEscapeString(childBuf, "<snapshot name='%s'/>\n", src->snapshot);
virBufferEscapeString(childBuf, "<config file='%s'/>\n", src->configFile); virBufferEscapeString(childBuf, "<config file='%s'/>\n", src->configFile);

View File

@ -2205,6 +2205,9 @@
</optional> </optional>
<ref name="diskSourceCommon"/> <ref name="diskSourceCommon"/>
<ref name="diskSourceNetworkHost"/> <ref name="diskSourceNetworkHost"/>
<optional>
<ref name="reconnect"/>
</optional>
<optional> <optional>
<ref name="encryption"/> <ref name="encryption"/>
</optional> </optional>

View File

@ -55,6 +55,8 @@
<define name="reconnect"> <define name="reconnect">
<element name="reconnect"> <element name="reconnect">
<choice>
<group>
<attribute name="enabled"> <attribute name="enabled">
<ref name="virYesNo"/> <ref name="virYesNo"/>
</attribute> </attribute>
@ -63,6 +65,11 @@
<ref name="unsignedInt"/> <ref name="unsignedInt"/>
</attribute> </attribute>
</optional> </optional>
</group>
<attribute name="delay">
<ref name="unsignedInt"/>
</attribute>
</choice>
</element> </element>
</define> </define>

View File

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

View File

@ -312,6 +312,10 @@ struct _virStorageSource {
unsigned long long readahead; /* size of the readahead buffer in bytes */ unsigned long long readahead; /* size of the readahead buffer in bytes */
unsigned long long timeout; /* connection timeout in seconds */ unsigned long long timeout; /* connection timeout in seconds */
/* NBD QEMU reconnect-delay option,
* 0 as default value */
unsigned int reconnectDelay;
virStorageSourceNVMeDef *nvme; /* type == VIR_STORAGE_TYPE_NVME */ virStorageSourceNVMeDef *nvme; /* type == VIR_STORAGE_TYPE_NVME */
virDomainChrSourceDef *vhostuser; /* type == VIR_STORAGE_TYPE_VHOST_USER */ virDomainChrSourceDef *vhostuser; /* type == VIR_STORAGE_TYPE_VHOST_USER */

View File

@ -529,6 +529,7 @@ qemuBlockStorageSourceGetNBDProps(virStorageSource *src,
"S:export", src->path, "S:export", src->path,
"S:tls-creds", tlsAlias, "S:tls-creds", tlsAlias,
"S:tls-hostname", tlsHostname, "S:tls-hostname", tlsHostname,
"p:reconnect-delay", src->reconnectDelay,
NULL) < 0) NULL) < 0)
return NULL; return NULL;
@ -1848,7 +1849,8 @@ qemuBlockGetBackingStoreString(virStorageSource *src,
src->ncookies == 0 && src->ncookies == 0 &&
src->sslverify == VIR_TRISTATE_BOOL_ABSENT && src->sslverify == VIR_TRISTATE_BOOL_ABSENT &&
src->timeout == 0 && src->timeout == 0 &&
src->readahead == 0) { src->readahead == 0 &&
src->reconnectDelay == 0) {
switch ((virStorageNetProtocol) src->protocol) { switch ((virStorageNetProtocol) src->protocol) {
case VIR_STORAGE_NET_PROTOCOL_NBD: case VIR_STORAGE_NET_PROTOCOL_NBD:

View File

@ -5063,6 +5063,15 @@ qemuDomainValidateStorageSource(virStorageSource *src,
} }
} }
if (src->reconnectDelay > 0) {
if (actualType != VIR_STORAGE_TYPE_NETWORK ||
src->protocol != VIR_STORAGE_NET_PROTOCOL_NBD) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("reconnect delay is supported only with NBD protocol"));
return -1;
}
}
if (src->query && if (src->query &&
(actualType != VIR_STORAGE_TYPE_NETWORK || (actualType != VIR_STORAGE_TYPE_NETWORK ||
(src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS && (src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS &&

View File

@ -27,21 +27,24 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-no-shutdown \ -no-shutdown \
-boot strict=on \ -boot strict=on \
-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
-blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.org","port":"6000"},"node-name":"libvirt-5-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.org","port":"6000"},"node-name":"libvirt-6-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-6-format","read-only":false,"driver":"raw","file":"libvirt-6-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x2","drive":"libvirt-6-format","id":"virtio-disk0","bootindex":1}' \
-blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.org","port":"6000"},"export":"bar","node-name":"libvirt-5-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-5-format","read-only":false,"driver":"raw","file":"libvirt-5-storage"}' \ -blockdev '{"node-name":"libvirt-5-format","read-only":false,"driver":"raw","file":"libvirt-5-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x2","drive":"libvirt-5-format","id":"virtio-disk0","bootindex":1}' \ -device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x3","drive":"libvirt-5-format","id":"virtio-disk1"}' \
-blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.org","port":"6000"},"export":"bar","node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"driver":"nbd","server":{"type":"inet","host":"::1","port":"6000"},"node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-4-format","read-only":false,"driver":"raw","file":"libvirt-4-storage"}' \ -blockdev '{"node-name":"libvirt-4-format","read-only":false,"driver":"raw","file":"libvirt-4-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x3","drive":"libvirt-4-format","id":"virtio-disk1"}' \ -device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x4","drive":"libvirt-4-format","id":"virtio-disk2"}' \
-blockdev '{"driver":"nbd","server":{"type":"inet","host":"::1","port":"6000"},"node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"driver":"nbd","server":{"type":"inet","host":"::1","port":"6000"},"export":"bar","node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"raw","file":"libvirt-3-storage"}' \ -blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"raw","file":"libvirt-3-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x4","drive":"libvirt-3-format","id":"virtio-disk2"}' \ -device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x5","drive":"libvirt-3-format","id":"virtio-disk3"}' \
-blockdev '{"driver":"nbd","server":{"type":"inet","host":"::1","port":"6000"},"export":"bar","node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"driver":"nbd","server":{"type":"unix","path":"/var/run/nbdsock"},"export":"bar","node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw","file":"libvirt-2-storage"}' \ -blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw","file":"libvirt-2-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x5","drive":"libvirt-2-format","id":"virtio-disk3"}' \ -device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x6","drive":"libvirt-2-format","id":"virtio-disk4"}' \
-blockdev '{"driver":"nbd","server":{"type":"unix","path":"/var/run/nbdsock"},"export":"bar","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.org","port":"6000"},"export":"foo","reconnect-delay":10,"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x6","drive":"libvirt-1-format","id":"virtio-disk4"}' \ -device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x7","drive":"libvirt-1-format","id":"virtio-disk5"}' \
-audiodev '{"id":"audio1","driver":"none"}' \ -audiodev '{"id":"audio1","driver":"none"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on -msg timestamp=on

View File

@ -49,6 +49,14 @@
</source> </source>
<target dev='vde' bus='virtio'/> <target dev='vde' bus='virtio'/>
</disk> </disk>
<disk type='network' device='disk'>
<driver name='qemu' type='raw'/>
<source protocol='nbd' name='foo'>
<host name='example.org' port='6000'/>
<reconnect delay='10'/>
</source>
<target dev='vdf' bus='virtio'/>
</disk>
<controller type='usb' index='0'/> <controller type='usb' index='0'/>
<controller type='ide' index='0'/> <controller type='ide' index='0'/>
<controller type='pci' index='0' model='pci-root'/> <controller type='pci' index='0' model='pci-root'/>

View File

@ -54,6 +54,15 @@
<target dev='vde' bus='virtio'/> <target dev='vde' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</disk> </disk>
<disk type='network' device='disk'>
<driver name='qemu' type='raw'/>
<source protocol='nbd' name='foo'>
<host name='example.org' port='6000'/>
<reconnect delay='10'/>
</source>
<target dev='vdf' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</disk>
<controller type='usb' index='0'> <controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller> </controller>