From: Lucas Amaral <lucaaamaral@gmail.com>
Previously, users had to manually specify a TCP port when starting
a pull-mode backup with an NBD server. A TODO comment in
qemuBackupPrepare() noted this limitation and pointed toward using
virPortAllocator, as done for migration, VNC, and SPICE ports.
When a pull-mode backup is started without specifying a TCP port,
a port is now acquired automatically from the configured range via
virPortAllocatorAcquire(). The port is released when the backup
ends or if startup fails.
Signed-off-by: Lucas Amaral <lucaaamaral@gmail.com>
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
---
docs/formatbackup.rst | 3 ++-
src/qemu/qemu_backup.c | 30 ++++++++++++++++++++----------
src/qemu/qemu_domain.h | 1 +
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/docs/formatbackup.rst b/docs/formatbackup.rst
index df6392e3bd..24857eaf72 100644
--- a/docs/formatbackup.rst
+++ b/docs/formatbackup.rst
@@ -42,7 +42,8 @@ were supplied). The following child elements and attributes are supported:
```protocol`` element of a disk <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ attached
via NBD in the domain (such as transport, socket, name, port, or tls),
necessary to set up an NBD server that exposes the content of each disk at
- the time the backup is started.
+ the time the backup is started. For TCP transport, if ``port`` is omitted, a
+ port is allocated automatically from the range configured in ``/etc/libvirt/qemu.conf``.
In addition to the above the NBD server used for backups allows using
``transport='fd' fdgroup='NAME'`` where ``NAME`` is the name used with
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index d380dd3a63..ddab4be34b 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -32,6 +32,7 @@
#include "storage_source.h"
#include "storage_source_conf.h"
#include "virerror.h"
+#include "virportallocator.h"
#include "virlog.h"
#include "virbuffer.h"
#include "backup_conf.h"
@@ -58,7 +59,8 @@ qemuDomainGetBackup(virDomainObj *vm)
static int
-qemuBackupPrepare(virDomainBackupDef *def)
+qemuBackupPrepare(qemuDomainObjPrivate *priv,
+ virDomainBackupDef *def)
{
if (def->type == VIR_DOMAIN_BACKUP_TYPE_PULL) {
@@ -71,15 +73,12 @@ qemuBackupPrepare(virDomainBackupDef *def)
switch (def->server->transport) {
case VIR_STORAGE_NET_HOST_TRANS_TCP:
- /* TODO: Update qemu.conf to provide a port range,
- * probably starting at 10809, for obtaining automatic
- * port via virPortAllocatorAcquire, as well as store
- * somewhere if we need to call virPortAllocatorRelease
- * during BackupEnd. Until then, user must provide port */
if (!def->server->port) {
- virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
- _("<domainbackup> must specify TCP port for now"));
- return -1;
+ if (virPortAllocatorAcquire(priv->driver->backupPorts,
+ &priv->backupNBDPort) < 0)
+ return -1;
+
+ def->server->port = priv->backupNBDPort;
}
break;
@@ -838,7 +837,7 @@ qemuBackupBegin(virDomainObj *vm,
goto endjob;
}
- if (qemuBackupPrepare(def) < 0)
+ if (qemuBackupPrepare(priv, def) < 0)
goto endjob;
if (qemuBackupBeginPrepareTLS(vm, cfg, def, &tlsProps, &tlsSecretProps) < 0)
@@ -969,6 +968,11 @@ qemuBackupBegin(virDomainObj *vm,
qemuDomainObjExitMonitor(vm);
}
+ if (ret < 0 && priv->backupNBDPort) {
+ virPortAllocatorRelease(priv->backupNBDPort);
+ priv->backupNBDPort = 0;
+ }
+
if (ret < 0 && !job_started && priv->backup)
def = g_steal_pointer(&priv->backup);
@@ -1026,6 +1030,12 @@ qemuBackupNotifyBlockjobEndStopNBD(virDomainObj *vm,
qemuDomainObjExitMonitor(vm);
backup->nbdStopped = true;
+
+ if (priv->backupNBDPort) {
+ virPortAllocatorRelease(priv->backupNBDPort);
+ priv->backupNBDPort = 0;
+ backup->server->port = 0;
+ }
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index f797542a87..b321a64e96 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -147,6 +147,7 @@ struct _qemuDomainObjPrivate {
char *origname;
int nbdPort; /* Port used for migration with NBD */
unsigned short migrationPort;
+ unsigned short backupNBDPort;
int preMigrationState;
unsigned long long preMigrationMemlock; /* Original RLIMIT_MEMLOCK in case
it was changed for the current
--
2.53.0
© 2016 - 2026 Red Hat, Inc.