+ .. role:: since
+
Backup XML format
=================
necessary to set up an NBD server that exposes the content of each disk at
the time the backup is started.
+ In addition to the above the NBD server used for backups allows using
+ ``transport='fd' fdgroup='NAME'`` where ``NAME`` is the name used with
+ ``virDomainFDAssociate()`` to pass a pre-opened server socket file descriptor
+ to qemu. :since:`Since 11.3.0`
+
+ Example code to pass a socket with libvirt-python bindings::
+
+ import socket
+ import libvirt
+
+ s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ s.bind("/path/to/socket")
+
+ fdlist = [ s.fileno() ]
+
+ conn = libvirt.open()
+ dom = conn.lookupByName("VMNAME")
+ dom.FDAssociate("NAME", fdlist)
+
Note that for the QEMU hypervisor the TLS environment in controlled using
``backup_tls_x509_cert_dir``, ``backup_tls_x509_verify``, and
``backup_tls_x509_secret_uuid`` properties in ``/etc/libvirt/qemu.conf``.
def->server = g_new0(virStorageNetHostDef, 1);
- if (virDomainStorageNetworkParseHost(node, def->server, false) < 0)
+ if (virDomainStorageNetworkParseHost(node, def->server, true) < 0)
return NULL;
if (def->server->transport == VIR_STORAGE_NET_HOST_TRANS_RDMA) {
if (def->server->port)
virBufferAsprintf(&serverAttrBuf, " port='%u'", def->server->port);
virBufferEscapeString(&serverAttrBuf, " socket='%s'", def->server->socket);
+ virBufferEscapeString(&serverAttrBuf, " fdgroup='%s'", def->server->fdgroup);
}
virXMLFormatElement(&childBuf, "server", &serverAttrBuf, NULL);
<ref name="absFilePath"/>
</attribute>
</group>
+ <group>
+ <attribute name="transport">
+ <value>fd</value>
+ </attribute>
+ <attribute name="fdgroup"/>
+ </group>
</choice>
</element>
<ref name="backupDisksPull"/>
bool reuse = (flags & VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL);
int rc = 0;
int ret = -1;
+ g_autoptr(qemuFDPassDirect) fdpass = NULL;
virCheckFlags(VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL, -1);
priv->backup = g_steal_pointer(&def);
+ if (pull && priv->backup->server->fdgroup) {
+ virStorageSourceFDTuple *fdt = NULL;
+ VIR_AUTOCLOSE fdcopy = -1;
+
+ if (!(fdt = virHashLookup(priv->fds, priv->backup->server->fdgroup))) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("file descriptor group '%1$s' was not associated with the domain"),
+ priv->backup->server->fdgroup);
+ goto endjob;
+ }
+
+ if (fdt->nfds != 1) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("file descriptor group '%1$s' must contain only 1 file descriptor for NBD server"),
+ priv->backup->server->fdgroup);
+ goto endjob;
+ }
+
+ priv->backup->server->qemu_fdname = g_strdup("libvirt-backup-nbd");
+ fdcopy = dup(fdt->fds[0]);
+ fdpass = qemuFDPassDirectNew(priv->backup->server->qemu_fdname, &fdcopy);
+ }
+
if (qemuDomainObjEnterMonitorAsync(vm, VIR_ASYNC_JOB_BACKUP) < 0)
goto endjob;
if (rc == 0 && tlsProps)
rc = qemuMonitorAddObject(priv->mon, &tlsProps, &tlsAlias);
+ if (rc == 0 && fdpass)
+ rc = qemuFDPassDirectTransferMonitor(fdpass, priv->mon);
+
if (rc == 0) {
if ((rc = qemuMonitorNBDServerStart(priv->mon, priv->backup->server, tlsAlias)) == 0)
nbd_running = true;