qemu: add automatic port allocation for pull-mode backup NBD servers

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>
This commit is contained in:
Lucas Amaral authored and Peter Krempa committed 2026-03-20 14:32:34 +01:00
1 parent 36cf50f85b
commit a561883abf
3 files changed
+23 -11

No files matched your search

+2 -1
View File
@@ -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
+20 -10
View File
@@ -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;
}
}
+1
View File
@@ -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