[PATCH 0/9] qemu: fd: Address differences between FD passing types

Originally the intention was to have one set of helpers but it turned out to be too much hassle and too obscure semantics. This series adds a new helper qemuFDPassDirect and simplifies the internals greatly by using a distinct set of APIs. Peter Krempa (9): qemu: fd: Add a distinct set of APIs for 'direct' fd passing mode qemu: Convert passing of 'vhostfd' to 'qemuFDPassDirect' qemu: Convert passing of 'tapfds' to 'qemuFDPassDirect' qemu: Convert passing of 'slirpfd' to 'qemuFDPassDirect' qemu: Use 'qemuFDPassDirect' for 'unix' chardevs qemuFDPassValidate: Don't validate file descriptors qemu: fd: Remove support for 'direct' fd passing from 'qemuFDPass' qemuFDPassTransferCommand: Remove return value qemu: fd: Fix documentation for FD set related functions src/qemu/qemu_command.c | 55 +++----- src/qemu/qemu_domain.c | 7 +- src/qemu/qemu_domain.h | 7 +- src/qemu/qemu_fd.c | 265 ++++++++++++++++++++--------------- src/qemu/qemu_fd.h | 24 +++- src/qemu/qemu_hotplug.c | 15 +- src/qemu/qemu_interface.c | 8 +- src/qemu/qemu_monitor_json.c | 4 +- src/qemu/qemu_process.c | 5 +- src/qemu/qemu_slirp.c | 4 +- tests/qemuxml2argvmock.c | 10 +- tests/testutilsqemu.c | 26 ++-- 12 files changed, 232 insertions(+), 198 deletions(-) -- 2.35.3

Originally I envisioned a common set of APIs for both FD passing approaches but it turns out they are not really compatible enough for it to make sense to use one set of APIs. As of such introduce a distinct set of APIs for the 'direct' mode, which will later be used to convert all places that currently use 'qemuFDPassNewDirect' and later clean up the existing APIs. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_fd.c | 128 +++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_fd.h | 22 ++++++++ 2 files changed, 150 insertions(+) diff --git a/src/qemu/qemu_fd.c b/src/qemu/qemu_fd.c index 4641122d1f..442f92df2f 100644 --- a/src/qemu/qemu_fd.c +++ b/src/qemu/qemu_fd.c @@ -324,3 +324,131 @@ qemuFDPassGetPath(qemuFDPass *fdpass) return fdpass->path; } + + +struct _qemuFDPassDirect { + int fd; + char *path; + char *name; + + bool passed; /* passed to qemu via monitor */ +}; + + +void +qemuFDPassDirectFree(qemuFDPassDirect *fdpass) +{ + + if (!fdpass) + return; + + VIR_FORCE_CLOSE(fdpass->fd); + g_free(fdpass->path); + g_free(fdpass); +} + + +/** + * qemuFDPassDirectNew: + * @name: Name of the fd (for monitor passing use-case) + * @fd: The FD, cleared when passed. + * + * The qemuFDPassDirect helper returned by this helper is used to hold a FD + * passed to qemu either direcly via FD number when used on commandline or the + * 'getfd' QMP command. + */ +qemuFDPassDirect * +qemuFDPassDirectNew(const char *name, + int *fd) +{ + qemuFDPassDirect *fdpass = g_new0(qemuFDPassDirect, 1); + + fdpass->name = g_strdup(name); + fdpass->fd = *fd; + *fd = -1; + + return fdpass; +} + + +/** + * qemuFDPassDirectTransferCommand: + * @fdpass: The fd passing helper struct + * @cmd: Command to pass the filedescriptors to + * + * Pass the fds in @fdpass to a commandline object @cmd. @fdpass may be NULL + * in which case this is a no-op. + */ +void +qemuFDPassDirectTransferCommand(qemuFDPassDirect *fdpass, + virCommand *cmd) +{ + if (!fdpass) + return; + + virCommandPassFD(cmd, fdpass->fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); + fdpass->path = g_strdup_printf("%d", fdpass->fd); + fdpass->fd = -1; +} + + +/** + * qemuFDPassDirectTransferMonitor: + * @fdpass: The fd passing helper struct + * @mon: monitor object + * + * Pass the fds in @fdpass to qemu via the monitor. @fdpass may be NULL + * in which case this is a no-op. Caller needs to enter the monitor context. + */ +int +qemuFDPassDirectTransferMonitor(qemuFDPassDirect *fdpass, + qemuMonitor *mon) +{ + if (!fdpass) + return 0; + + if (qemuMonitorSendFileHandle(mon, fdpass->name, fdpass->fd) < 0) + return -1; + + fdpass->path = g_strdup(fdpass->name); + VIR_FORCE_CLOSE(fdpass->fd); + fdpass->passed = true; + + return 0; +} + + +/** + * qemuFDPassDirectTransferMonitorRollback: + * @fdpass: The fd passing helper struct + * @mon: monitor object + * + * Rolls back the addition of @fdpass to @mon if it was added originally. + */ +void +qemuFDPassDirectTransferMonitorRollback(qemuFDPassDirect *fdpass, + qemuMonitor *mon) +{ + if (!fdpass || !fdpass->passed) + return; + + ignore_value(qemuMonitorCloseFileHandle(mon, fdpass->name)); +} + + +/** + * qemuFDPassDirectGetPath: + * @fdpass: The fd passing helper struct + * + * Returns the path/fd name that is used in qemu to refer to the passed FD. + * Note that it's only valid to call this function after @fdpass was already + * transferred to the command or monitor. + */ +const char * +qemuFDPassDirectGetPath(qemuFDPassDirect *fdpass) +{ + if (!fdpass) + return NULL; + + return fdpass->path; +} diff --git a/src/qemu/qemu_fd.h b/src/qemu/qemu_fd.h index d078d4ce5d..dbb4ab0aa5 100644 --- a/src/qemu/qemu_fd.h +++ b/src/qemu/qemu_fd.h @@ -53,3 +53,25 @@ qemuFDPassTransferMonitorRollback(qemuFDPass *fdpass, const char * qemuFDPassGetPath(qemuFDPass *fdpass); + + +typedef struct _qemuFDPassDirect qemuFDPassDirect; + +void +qemuFDPassDirectFree(qemuFDPassDirect *fdpass); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuFDPassDirect, qemuFDPassDirectFree); + +qemuFDPassDirect * +qemuFDPassDirectNew(const char *name, + int *fd); +void +qemuFDPassDirectTransferCommand(qemuFDPassDirect *fdpass, + virCommand *cmd); +int +qemuFDPassDirectTransferMonitor(qemuFDPassDirect *fdpass, + qemuMonitor *mon); +void +qemuFDPassDirectTransferMonitorRollback(qemuFDPassDirect *fdpass, + qemuMonitor *mon); +const char * +qemuFDPassDirectGetPath(qemuFDPassDirect *fdpass); -- 2.35.3

On Tue, May 17, 2022 at 11:07:18 +0200, Peter Krempa wrote:
Originally I envisioned a common set of APIs for both FD passing approaches but it turns out they are not really compatible enough for it to make sense to use one set of APIs.
As of such introduce a distinct set of APIs for the 'direct' mode, which will later be used to convert all places that currently use 'qemuFDPassNewDirect' and later clean up the existing APIs.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_fd.c | 128 +++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_fd.h | 22 ++++++++ 2 files changed, 150 insertions(+)
diff --git a/src/qemu/qemu_fd.c b/src/qemu/qemu_fd.c index 4641122d1f..442f92df2f 100644 --- a/src/qemu/qemu_fd.c +++ b/src/qemu/qemu_fd.c @@ -324,3 +324,131 @@ qemuFDPassGetPath(qemuFDPass *fdpass)
return fdpass->path; } + + +struct _qemuFDPassDirect { + int fd; + char *path; + char *name; + + bool passed; /* passed to qemu via monitor */ +}; + + +void +qemuFDPassDirectFree(qemuFDPassDirect *fdpass) +{ + + if (!fdpass) + return; + + VIR_FORCE_CLOSE(fdpass->fd); + g_free(fdpass->path); + g_free(fdpass); +}
Consider the following squashed in: diff --git a/src/qemu/qemu_fd.c b/src/qemu/qemu_fd.c index 442f92df2f..baa16fd669 100644 --- a/src/qemu/qemu_fd.c +++ b/src/qemu/qemu_fd.c @@ -343,6 +343,7 @@ qemuFDPassDirectFree(qemuFDPassDirect *fdpass) return; VIR_FORCE_CLOSE(fdpass->fd); + g_free(fdpass->name); g_free(fdpass->path); g_free(fdpass);

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 8 +++----- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_domain.h | 2 +- src/qemu/qemu_hotplug.c | 4 ++-- src/qemu/qemu_interface.c | 8 ++------ tests/qemuxml2argvmock.c | 10 +++------- 6 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a52ba70066..ed7f0eafd2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4260,7 +4260,7 @@ qemuBuildHostNetProps(virDomainNetDef *net) nfds = 0; for (n = netpriv->vhostfds; n; n = n->next) { - virBufferAsprintf(&buf, "%s:", qemuFDPassGetPath(n->data)); + virBufferAsprintf(&buf, "%s:", qemuFDPassDirectGetPath(n->data)); nfds++; } @@ -8916,10 +8916,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, return -1; } - for (n = netpriv->vhostfds; n; n = n->next) { - if (qemuFDPassTransferCommand(n->data, cmd) < 0) - return -1; - } + for (n = netpriv->vhostfds; n; n = n->next) + qemuFDPassDirectTransferCommand(n->data, cmd); if (qemuFDPassTransferCommand(netpriv->slirpfd, cmd) < 0 || qemuFDPassTransferCommand(netpriv->vdpafd, cmd) < 0) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4305d5db06..eba556a6e7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1053,7 +1053,7 @@ qemuDomainNetworkPrivateClearFDs(qemuDomainNetworkPrivate *priv) g_clear_pointer(&priv->slirpfd, qemuFDPassFree); g_clear_pointer(&priv->vdpafd, qemuFDPassFree); - g_slist_free_full(g_steal_pointer(&priv->vhostfds), (GDestroyNotify) qemuFDPassFree); + g_slist_free_full(g_steal_pointer(&priv->vhostfds), (GDestroyNotify) qemuFDPassDirectFree); g_slist_free_full(g_steal_pointer(&priv->tapfds), (GDestroyNotify) qemuFDPassFree); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index e9eda8903e..9475c30e0c 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -405,7 +405,7 @@ struct _qemuDomainNetworkPrivate { /* file descriptor transfer helpers */ qemuFDPass *slirpfd; GSList *tapfds; - GSList *vhostfds; + GSList *vhostfds; /* qemuFDPassDirect */ qemuFDPass *vdpafd; }; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index cae7b0dd3b..da0896a671 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1380,7 +1380,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, } for (n = netpriv->vhostfds; n; n = n->next) { - if (qemuFDPassTransferMonitor(n->data, priv->mon) < 0) { + if (qemuFDPassDirectTransferMonitor(n->data, priv->mon) < 0) { qemuDomainObjExitMonitor(vm); goto cleanup; } @@ -1528,7 +1528,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, qemuFDPassTransferMonitorRollback(n->data, priv->mon); for (n = netpriv->vhostfds; n; n = n->next) - qemuFDPassTransferMonitorRollback(n->data, priv->mon); + qemuFDPassDirectTransferMonitorRollback(n->data, priv->mon); qemuDomainObjExitMonitor(vm); virErrorRestore(&originalError); diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c index bda96808eb..ba03277025 100644 --- a/src/qemu/qemu_interface.c +++ b/src/qemu/qemu_interface.c @@ -700,12 +700,10 @@ int qemuInterfaceOpenVhostNet(virDomainObj *vm, virDomainNetDef *net) { - qemuDomainObjPrivate *priv = vm->privateData; qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net); size_t i; const char *vhostnet_path = net->backend.vhost; size_t vhostfdSize = net->driver.virtio.queues; - g_autofree char *prefix = g_strdup_printf("vhostfd-%s", net->info.alias); if (!vhostfdSize) vhostfdSize = 1; @@ -743,8 +741,7 @@ qemuInterfaceOpenVhostNet(virDomainObj *vm, for (i = 0; i < vhostfdSize; i++) { VIR_AUTOCLOSE fd = open(vhostnet_path, O_RDWR); - g_autoptr(qemuFDPass) pass = qemuFDPassNewDirect(prefix, priv); - g_autofree char *suffix = g_strdup_printf("%zu", i); + g_autofree char *name = g_strdup_printf("vhostfd-%s%zu", net->info.alias, i); /* If the config says explicitly to use vhost and we couldn't open it, * report an error. @@ -761,8 +758,7 @@ qemuInterfaceOpenVhostNet(virDomainObj *vm, break; } - qemuFDPassAddFD(pass, &fd, suffix); - netpriv->vhostfds = g_slist_prepend(netpriv->vhostfds, g_steal_pointer(&pass)); + netpriv->vhostfds = g_slist_prepend(netpriv->vhostfds, qemuFDPassDirectNew(name, &fd)); } netpriv->vhostfds = g_slist_reverse(netpriv->vhostfds); diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c index aa82ffa2d6..bb14f775f3 100644 --- a/tests/qemuxml2argvmock.c +++ b/tests/qemuxml2argvmock.c @@ -226,12 +226,10 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path G_GNUC_UNUSED, } int -qemuInterfaceOpenVhostNet(virDomainObj *vm, +qemuInterfaceOpenVhostNet(virDomainObj *vm G_GNUC_UNUSED, virDomainNetDef *net) { - qemuDomainObjPrivate *priv = vm->privateData; qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net); - g_autofree char *prefix = g_strdup_printf("vhostfd-%s", net->info.alias); size_t vhostfdSize = net->driver.virtio.queues; size_t i; @@ -242,12 +240,10 @@ qemuInterfaceOpenVhostNet(virDomainObj *vm, return 0; for (i = 0; i < vhostfdSize; i++) { - g_autoptr(qemuFDPass) pass = qemuFDPassNewDirect(prefix, priv); - g_autofree char *suffix = g_strdup_printf("%zu", i); + g_autofree char *name = g_strdup_printf("vhostfd-%s%zu", net->info.alias, i); int fd = STDERR_FILENO + 42 + i; - qemuFDPassAddFD(pass, &fd, suffix); - netpriv->vhostfds = g_slist_prepend(netpriv->vhostfds, g_steal_pointer(&pass)); + netpriv->vhostfds = g_slist_prepend(netpriv->vhostfds, qemuFDPassDirectNew(name, &fd)); } netpriv->vhostfds = g_slist_reverse(netpriv->vhostfds); -- 2.35.3

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 15 +++++---------- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_domain.h | 2 +- src/qemu/qemu_hotplug.c | 4 ++-- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ed7f0eafd2..bab2b0a99b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4244,7 +4244,7 @@ qemuBuildHostNetProps(virDomainNetDef *net) if (netpriv->tapfds) { nfds = 0; for (n = netpriv->tapfds; n; n = n->next) { - virBufferAsprintf(&buf, "%s:", qemuFDPassGetPath(n->data)); + virBufferAsprintf(&buf, "%s:", qemuFDPassDirectGetPath(n->data)); nfds++; } @@ -8738,16 +8738,13 @@ qemuBuildInterfaceConnect(virDomainObj *vm, /* 'vhostfd' is set to true in all cases when we need to process tapfds */ if (vhostfd) { - g_autofree char *prefix = g_strdup_printf("tapfd-%s", net->info.alias); size_t i; for (i = 0; i < tapfdSize; i++) { - g_autoptr(qemuFDPass) pass = qemuFDPassNewDirect(prefix, priv); - g_autofree char *suffix = g_strdup_printf("%zu", i); + g_autofree char *name = g_strdup_printf("tapfd-%s%zu", net->info.alias, i); int fd = tapfd[i]; /* we want to keep the array intact for security labeling*/ - qemuFDPassAddFD(pass, &fd, suffix); - netpriv->tapfds = g_slist_prepend(netpriv->tapfds, g_steal_pointer(&pass)); + netpriv->tapfds = g_slist_prepend(netpriv->tapfds, qemuFDPassDirectNew(name, &fd)); } netpriv->tapfds = g_slist_reverse(netpriv->tapfds); @@ -8911,10 +8908,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, virNetDevSetMTU(net->ifname, net->mtu) < 0) goto cleanup; - for (n = netpriv->tapfds; n; n = n->next) { - if (qemuFDPassTransferCommand(n->data, cmd) < 0) - return -1; - } + for (n = netpriv->tapfds; n; n = n->next) + qemuFDPassDirectTransferCommand(n->data, cmd); for (n = netpriv->vhostfds; n; n = n->next) qemuFDPassDirectTransferCommand(n->data, cmd); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index eba556a6e7..f83ee55246 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1054,7 +1054,7 @@ qemuDomainNetworkPrivateClearFDs(qemuDomainNetworkPrivate *priv) g_clear_pointer(&priv->slirpfd, qemuFDPassFree); g_clear_pointer(&priv->vdpafd, qemuFDPassFree); g_slist_free_full(g_steal_pointer(&priv->vhostfds), (GDestroyNotify) qemuFDPassDirectFree); - g_slist_free_full(g_steal_pointer(&priv->tapfds), (GDestroyNotify) qemuFDPassFree); + g_slist_free_full(g_steal_pointer(&priv->tapfds), (GDestroyNotify) qemuFDPassDirectFree); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 9475c30e0c..521df8ca01 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -404,7 +404,7 @@ struct _qemuDomainNetworkPrivate { /* file descriptor transfer helpers */ qemuFDPass *slirpfd; - GSList *tapfds; + GSList *tapfds; /* qemuFDPassDirect */ GSList *vhostfds; /* qemuFDPassDirect */ qemuFDPass *vdpafd; }; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index da0896a671..4ebb3c5818 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1373,7 +1373,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, qemuDomainObjEnterMonitor(driver, vm); for (n = netpriv->tapfds; n; n = n->next) { - if (qemuFDPassTransferMonitor(n->data, priv->mon) < 0) { + if (qemuFDPassDirectTransferMonitor(n->data, priv->mon) < 0) { qemuDomainObjExitMonitor(vm); goto cleanup; } @@ -1525,7 +1525,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, netdev_name); for (n = netpriv->tapfds; n; n = n->next) - qemuFDPassTransferMonitorRollback(n->data, priv->mon); + qemuFDPassDirectTransferMonitorRollback(n->data, priv->mon); for (n = netpriv->vhostfds; n; n = n->next) qemuFDPassDirectTransferMonitorRollback(n->data, priv->mon); -- 2.35.3

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 7 ++++--- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_domain.h | 2 +- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_slirp.c | 4 +--- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index bab2b0a99b..90a4b98e1e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4325,7 +4325,7 @@ qemuBuildHostNetProps(virDomainNetDef *net) if (netpriv->slirpfd) { if (virJSONValueObjectAdd(&netprops, "s:type", "socket", - "s:fd", qemuFDPassGetPath(netpriv->slirpfd), + "s:fd", qemuFDPassDirectGetPath(netpriv->slirpfd), NULL) < 0) return NULL; } else { @@ -8914,8 +8914,9 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, for (n = netpriv->vhostfds; n; n = n->next) qemuFDPassDirectTransferCommand(n->data, cmd); - if (qemuFDPassTransferCommand(netpriv->slirpfd, cmd) < 0 || - qemuFDPassTransferCommand(netpriv->vdpafd, cmd) < 0) + qemuFDPassDirectTransferCommand(netpriv->slirpfd, cmd); + + if (qemuFDPassTransferCommand(netpriv->vdpafd, cmd) < 0) return -1; if (!(hostnetprops = qemuBuildHostNetProps(net))) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index f83ee55246..c957b5296a 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1051,7 +1051,7 @@ qemuDomainNetworkPrivateClearFDs(qemuDomainNetworkPrivate *priv) if (!priv) return; - g_clear_pointer(&priv->slirpfd, qemuFDPassFree); + g_clear_pointer(&priv->slirpfd, qemuFDPassDirectFree); g_clear_pointer(&priv->vdpafd, qemuFDPassFree); g_slist_free_full(g_steal_pointer(&priv->vhostfds), (GDestroyNotify) qemuFDPassDirectFree); g_slist_free_full(g_steal_pointer(&priv->tapfds), (GDestroyNotify) qemuFDPassDirectFree); diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 521df8ca01..1547dec668 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -403,7 +403,7 @@ struct _qemuDomainNetworkPrivate { qemuSlirp *slirp; /* file descriptor transfer helpers */ - qemuFDPass *slirpfd; + qemuFDPassDirect *slirpfd; GSList *tapfds; /* qemuFDPassDirect */ GSList *vhostfds; /* qemuFDPassDirect */ qemuFDPass *vdpafd; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 4ebb3c5818..3504cd21ff 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1386,7 +1386,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, } } - if (qemuFDPassTransferMonitor(netpriv->slirpfd, priv->mon) < 0 || + if (qemuFDPassDirectTransferMonitor(netpriv->slirpfd, priv->mon) < 0 || qemuFDPassTransferMonitor(netpriv->vdpafd, priv->mon) < 0) { qemuDomainObjExitMonitor(vm); goto cleanup; diff --git a/src/qemu/qemu_slirp.c b/src/qemu/qemu_slirp.c index 618947b6c1..772ea582c5 100644 --- a/src/qemu/qemu_slirp.c +++ b/src/qemu/qemu_slirp.c @@ -352,9 +352,7 @@ qemuSlirpStart(virDomainObj *vm, slirp->pid = pid; - netpriv->slirpfd = qemuFDPassNewDirect(fdname, priv); - - qemuFDPassAddFD(netpriv->slirpfd, &slirp->fd[0], NULL); + netpriv->slirpfd = qemuFDPassDirectNew(fdname, &slirp->fd[0]); return 0; -- 2.35.3

Unix socket chardevs with FD passing need to use the direct mode so we need to convert it to use qemuFDPassDirect. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 15 +++++++++------ src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_hotplug.c | 5 +++-- src/qemu/qemu_monitor_json.c | 4 ++-- src/qemu/qemu_process.c | 5 ++--- tests/testutilsqemu.c | 26 +++++++++++--------------- 7 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 90a4b98e1e..828c7c38f5 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1396,8 +1396,8 @@ qemuBuildChardevStr(const virDomainChrSourceDef *dev, case VIR_DOMAIN_CHR_TYPE_UNIX: virBufferAsprintf(&buf, "socket,id=%s", charAlias); - if (chrSourcePriv->sourcefd) { - virBufferAsprintf(&buf, ",fd=%s", qemuFDPassGetPath(chrSourcePriv->sourcefd)); + if (chrSourcePriv->directfd) { + virBufferAsprintf(&buf, ",fd=%s", qemuFDPassDirectGetPath(chrSourcePriv->directfd)); } else { virBufferAddLit(&buf, ",path="); virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path); @@ -1513,9 +1513,13 @@ qemuBuildChardevCommand(virCommand *cmd, break; case VIR_DOMAIN_CHR_TYPE_FILE: - case VIR_DOMAIN_CHR_TYPE_UNIX: if (qemuFDPassTransferCommand(chrSourcePriv->sourcefd, cmd) < 0) return -1; + + break; + + case VIR_DOMAIN_CHR_TYPE_UNIX: + qemuFDPassDirectTransferCommand(chrSourcePriv->directfd, cmd); break; case VIR_DOMAIN_CHR_TYPE_NULL: @@ -4943,12 +4947,11 @@ qemuBuildVideoCommandLine(virCommand *cmd, qemuDomainVideoPrivate *videopriv = QEMU_DOMAIN_VIDEO_PRIVATE(video); g_autoptr(virDomainChrSourceDef) chrsrc = virDomainChrSourceDefNew(priv->driver->xmlopt); g_autofree char *chrAlias = qemuDomainGetVhostUserChrAlias(video->info.alias); + g_autofree char *name = g_strdup_printf("%s-vhost-user", video->info.alias); qemuDomainChrSourcePrivate *chrsrcpriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(chrsrc); chrsrc->type = VIR_DOMAIN_CHR_TYPE_UNIX; - chrsrcpriv->sourcefd = qemuFDPassNewDirect(video->info.alias, priv); - - qemuFDPassAddFD(chrsrcpriv->sourcefd, &videopriv->vhost_user_fd, "-vhost-user"); + chrsrcpriv->directfd = qemuFDPassDirectNew(name, &videopriv->vhost_user_fd); if (qemuBuildChardevCommand(cmd, chrsrc, chrAlias, priv->qemuCaps) < 0) return -1; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index c957b5296a..29a09bb7f7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -916,6 +916,7 @@ qemuDomainChrSourcePrivateClearFDPass(qemuDomainChrSourcePrivate *priv) g_clear_pointer(&priv->sourcefd, qemuFDPassFree); g_clear_pointer(&priv->logfd, qemuFDPassFree); + g_clear_pointer(&priv->directfd, qemuFDPassDirectFree); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 1547dec668..547d85b5f9 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -350,6 +350,7 @@ struct _qemuDomainChrSourcePrivate { qemuFDPass *sourcefd; qemuFDPass *logfd; + qemuFDPassDirect *directfd; bool wait; /* wait for incoming connections on chardev */ char *tlsCertPath; /* path to certificates if TLS is requested */ diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 3504cd21ff..15ffcdc6ce 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2133,11 +2133,12 @@ qemuDomainAttachChrDevice(virQEMUDriver *driver, if (qemuProcessPrepareHostBackendChardevHotplug(vm, dev) < 0) goto cleanup; - if (charpriv->sourcefd || charpriv->logfd) { + if (charpriv->sourcefd || charpriv->logfd || charpriv->directfd) { qemuDomainObjEnterMonitor(driver, vm); if (qemuFDPassTransferMonitor(charpriv->sourcefd, priv->mon) < 0 || - qemuFDPassTransferMonitor(charpriv->logfd, priv->mon) < 0) + qemuFDPassTransferMonitor(charpriv->logfd, priv->mon) < 0 || + qemuFDPassDirectTransferMonitor(charpriv->directfd, priv->mon) < 0) goto exit_monitor; qemuDomainObjExitMonitor(vm); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index a092bf420f..523a4326da 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6724,8 +6724,8 @@ qemuMonitorJSONAttachCharDevGetProps(const char *chrID, waitval = VIR_TRISTATE_BOOL_NO; } - if (chrSourcePriv->sourcefd) { - if (!(addr = qemuMonitorJSONBuildFDSocketAddress(qemuFDPassGetPath(chrSourcePriv->sourcefd)))) + if (chrSourcePriv->directfd) { + if (!(addr = qemuMonitorJSONBuildFDSocketAddress(qemuFDPassDirectGetPath(chrSourcePriv->directfd)))) return NULL; } else { if (!(addr = qemuMonitorJSONBuildUnixSocketAddress(chr->data.nix.path))) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 07e467d01e..e83d1fff27 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6876,6 +6876,7 @@ qemuProcessPrepareHostBackendChardevOne(virDomainDeviceDef *dev, case VIR_DOMAIN_CHR_TYPE_UNIX: if (chardev->data.nix.listen) { + g_autofree char *name = g_strdup_printf("%s-source", devalias); VIR_AUTOCLOSE sourcefd = -1; if (qemuSecuritySetSocketLabel(data->priv->driver->securityManager, data->def) < 0) @@ -6887,9 +6888,7 @@ qemuProcessPrepareHostBackendChardevOne(virDomainDeviceDef *dev, sourcefd < 0) return -1; - charpriv->sourcefd = qemuFDPassNewDirect(devalias, data->priv); - - qemuFDPassAddFD(charpriv->sourcefd, &sourcefd, "-source"); + charpriv->directfd = qemuFDPassDirectNew(name, &sourcefd); } break; diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index 89fdf1d6fe..7ae88c9b8d 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -1019,7 +1019,6 @@ testQemuPrepareHostBackendChardevOne(virDomainDeviceDef *dev, qemuDomainChrSourcePrivate *charpriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(chardev); int fakesourcefd = -1; const char *devalias = NULL; - bool usefdset = true; if (vm) priv = vm->privateData; @@ -1061,13 +1060,22 @@ testQemuPrepareHostBackendChardevOne(virDomainDeviceDef *dev, case VIR_DOMAIN_CHR_TYPE_FILE: fakesourcefd = 1750; + + if (fcntl(fakesourcefd, F_GETFD) != -1) + abort(); + + charpriv->sourcefd = qemuFDPassNew(devalias, priv); + qemuFDPassAddFD(charpriv->sourcefd, &fakesourcefd, "-source"); break; case VIR_DOMAIN_CHR_TYPE_UNIX: - if (chardev->data.nix.listen) + if (chardev->data.nix.listen) { + g_autofree char *name = g_strdup_printf("%s-source", devalias); fakesourcefd = 1729; - usefdset = false; + charpriv->directfd = qemuFDPassDirectNew(name, &fakesourcefd); + } + break; case VIR_DOMAIN_CHR_TYPE_NMDM: @@ -1075,18 +1083,6 @@ testQemuPrepareHostBackendChardevOne(virDomainDeviceDef *dev, break; } - if (fakesourcefd != -1) { - if (fcntl(fakesourcefd, F_GETFD) != -1) - abort(); - - if (usefdset) - charpriv->sourcefd = qemuFDPassNew(devalias, priv); - else - charpriv->sourcefd = qemuFDPassNewDirect(devalias, priv); - - qemuFDPassAddFD(charpriv->sourcefd, &fakesourcefd, "-source"); - } - if (chardev->logfile) { int fd = 1751; -- 2.35.3

The callers adding the FDs are validating them regardless so this check was redundant. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_fd.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/qemu/qemu_fd.c b/src/qemu/qemu_fd.c index 442f92df2f..fc9fecbb0e 100644 --- a/src/qemu/qemu_fd.c +++ b/src/qemu/qemu_fd.c @@ -68,8 +68,6 @@ qemuFDPassFree(qemuFDPass *fdpass) static int qemuFDPassValidate(qemuFDPass *fdpass) { - size_t i; - if (!fdpass->useFDSet && fdpass->nfds > 1) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -77,14 +75,6 @@ qemuFDPassValidate(qemuFDPass *fdpass) return -1; } - for (i = 0; i < fdpass->nfds; i++) { - if (fdpass->fds[i].fd < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("invalid file descriptor")); - return -1; - } - } - return 0; } -- 2.35.3

This finishes the separation of the fdset and direct helpers. Remove 'qemuFDPassNewDirect' and all internals which were applicable only in direct mode. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_fd.c | 116 ++++++++------------------------------------- 1 file changed, 19 insertions(+), 97 deletions(-) diff --git a/src/qemu/qemu_fd.c b/src/qemu/qemu_fd.c index fc9fecbb0e..cff2428727 100644 --- a/src/qemu/qemu_fd.c +++ b/src/qemu/qemu_fd.c @@ -34,7 +34,6 @@ struct qemuFDPassFD { }; struct _qemuFDPass { - bool useFDSet; unsigned int fdSetID; size_t nfds; struct qemuFDPassFD *fds; @@ -65,20 +64,6 @@ qemuFDPassFree(qemuFDPass *fdpass) } -static int -qemuFDPassValidate(qemuFDPass *fdpass) -{ - if (!fdpass->useFDSet && - fdpass->nfds > 1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("direct FD passing supports only 1 file descriptor")); - return -1; - } - - return 0; -} - - /** * qemuFDPassNew: * @prefix: prefix used for naming the passed FDs @@ -99,7 +84,6 @@ qemuFDPassNew(const char *prefix, qemuFDPass *fdpass = g_new0(qemuFDPass, 1); fdpass->prefix = g_strdup(prefix); - fdpass->useFDSet = true; if (priv) { fdpass->fdSetID = qemuDomainFDSetIDNew(priv); @@ -112,34 +96,6 @@ qemuFDPassNew(const char *prefix, } -/** - * qemuFDPassNewDirect: - * @prefix: prefix used for naming the passed FDs - * @dompriv: qemu domain private data - * - * Create a new helper object for passing FDs to QEMU. - * - * The instance created via 'qemuFDPassNewDirect' will result in the older - * approach of directly using FD number on the commandline and 'getfd' - * QMP command. - * - * Non-test uses must pass a valid @dompriv. - * - * @prefix is used for naming the FD if needed and is later referenced when - * removing the FDSet via monitor. - */ -qemuFDPass * -qemuFDPassNewDirect(const char *prefix, - void *dompriv G_GNUC_UNUSED) -{ - qemuFDPass *fdpass = g_new0(qemuFDPass, 1); - - fdpass->prefix = g_strdup(prefix); - - return fdpass; -} - - /** * qemuFDPassAddFD: * @fdpass: The fd passing helper struct @@ -165,11 +121,6 @@ qemuFDPassAddFD(qemuFDPass *fdpass, newfd.opaque = g_strdup_printf("%s%s", fdpass->prefix, NULLSTR_EMPTY(suffix)); - if (!fdpass->useFDSet) { - g_free(fdpass->path); - fdpass->path = g_strdup(newfd.opaque); - } - VIR_APPEND_ELEMENT(fdpass->fds, fdpass->nfds, newfd); } @@ -191,28 +142,15 @@ qemuFDPassTransferCommand(qemuFDPass *fdpass, if (!fdpass) return 0; - if (qemuFDPassValidate(fdpass) < 0) - return -1; - for (i = 0; i < fdpass->nfds; i++) { - virCommandPassFD(cmd, fdpass->fds[i].fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); - - if (fdpass->useFDSet) { - g_autofree char *arg = NULL; - - arg = g_strdup_printf("set=%u,fd=%d,opaque=%s", - fdpass->fdSetID, - fdpass->fds[i].fd, - fdpass->fds[i].opaque); - - virCommandAddArgList(cmd, "-add-fd", arg, NULL); - } else { - /* for monitor use the older FD passing needs the FD number */ - g_free(fdpass->path); - fdpass->path = g_strdup_printf("%d", fdpass->fds[i].fd); - } + g_autofree char *arg = g_strdup_printf("set=%u,fd=%d,opaque=%s", + fdpass->fdSetID, + fdpass->fds[i].fd, + fdpass->fds[i].opaque); + virCommandPassFD(cmd, fdpass->fds[i].fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); fdpass->fds[i].fd = -1; + virCommandAddArgList(cmd, "-add-fd", arg, NULL); } return 0; @@ -231,42 +169,30 @@ int qemuFDPassTransferMonitor(qemuFDPass *fdpass, qemuMonitor *mon) { + g_autoptr(qemuMonitorFdsets) fdsets = NULL; size_t i; if (!fdpass) return 0; - if (qemuFDPassValidate(fdpass) < 0) + if (qemuMonitorQueryFdsets(mon, &fdsets) < 0) return -1; - if (fdpass->useFDSet) { - g_autoptr(qemuMonitorFdsets) fdsets = NULL; - if (qemuMonitorQueryFdsets(mon, &fdsets) < 0) + for (i = 0; i < fdsets->nfdsets; i++) { + if (fdsets->fdsets[i].id == fdpass->fdSetID) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("fdset '%u' is already in use by qemu"), + fdpass->fdSetID); return -1; - - for (i = 0; i < fdsets->nfdsets; i++) { - if (fdsets->fdsets[i].id == fdpass->fdSetID) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("fdset '%u' is already in use by qemu"), - fdpass->fdSetID); - return -1; - } } } for (i = 0; i < fdpass->nfds; i++) { - if (fdpass->useFDSet) { - if (qemuMonitorAddFileHandleToSet(mon, - fdpass->fds[i].fd, - fdpass->fdSetID, - fdpass->fds[i].opaque) < 0) - return -1; - } else { - if (qemuMonitorSendFileHandle(mon, - fdpass->fds[i].opaque, - fdpass->fds[i].fd) < 0) - return -1; - } + if (qemuMonitorAddFileHandleToSet(mon, + fdpass->fds[i].fd, + fdpass->fdSetID, + fdpass->fds[i].opaque) < 0) + return -1; VIR_FORCE_CLOSE(fdpass->fds[i].fd); fdpass->passed = true; @@ -290,11 +216,7 @@ qemuFDPassTransferMonitorRollback(qemuFDPass *fdpass, if (!fdpass || !fdpass->passed) return; - if (fdpass->useFDSet) { - ignore_value(qemuMonitorRemoveFdset(mon, fdpass->fdSetID)); - } else { - ignore_value(qemuMonitorCloseFileHandle(mon, fdpass->fds[0].opaque)); - } + ignore_value(qemuMonitorRemoveFdset(mon, fdpass->fdSetID)); } -- 2.35.3

Now that the 'direct' mode was separated and thus we don't have any possible error case we can stop returning any values and simplify callers. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 18 +++++------------- src/qemu/qemu_fd.c | 6 ++---- src/qemu/qemu_fd.h | 2 +- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 828c7c38f5..114c737b3d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1513,9 +1513,7 @@ qemuBuildChardevCommand(virCommand *cmd, break; case VIR_DOMAIN_CHR_TYPE_FILE: - if (qemuFDPassTransferCommand(chrSourcePriv->sourcefd, cmd) < 0) - return -1; - + qemuFDPassTransferCommand(chrSourcePriv->sourcefd, cmd); break; case VIR_DOMAIN_CHR_TYPE_UNIX: @@ -1543,8 +1541,7 @@ qemuBuildChardevCommand(virCommand *cmd, return -1; } - if (qemuFDPassTransferCommand(chrSourcePriv->logfd, cmd) < 0) - return -1; + qemuFDPassTransferCommand(chrSourcePriv->logfd, cmd); if (!(charstr = qemuBuildChardevStr(dev, charAlias))) return -1; @@ -8918,9 +8915,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, qemuFDPassDirectTransferCommand(n->data, cmd); qemuFDPassDirectTransferCommand(netpriv->slirpfd, cmd); - - if (qemuFDPassTransferCommand(netpriv->vdpafd, cmd) < 0) - return -1; + qemuFDPassTransferCommand(netpriv->vdpafd, cmd); if (!(hostnetprops = qemuBuildHostNetProps(net))) goto cleanup; @@ -9810,11 +9805,8 @@ qemuBuildTPMCommandLine(virCommand *cmd, return -1; } - if (qemuFDPassTransferCommand(passtpm, cmd) < 0) - return -1; - - if (qemuFDPassTransferCommand(passcancel, cmd) < 0) - return -1; + qemuFDPassTransferCommand(passtpm, cmd); + qemuFDPassTransferCommand(passcancel, cmd); if (!(tpmdevstr = qemuBuildTPMBackendStr(tpm, passtpm, passcancel))) return -1; diff --git a/src/qemu/qemu_fd.c b/src/qemu/qemu_fd.c index cff2428727..b7dd66bdc7 100644 --- a/src/qemu/qemu_fd.c +++ b/src/qemu/qemu_fd.c @@ -133,14 +133,14 @@ qemuFDPassAddFD(qemuFDPass *fdpass, * Pass the fds in @fdpass to a commandline object @cmd. @fdpass may be NULL * in which case this is a no-op. */ -int +void qemuFDPassTransferCommand(qemuFDPass *fdpass, virCommand *cmd) { size_t i; if (!fdpass) - return 0; + return; for (i = 0; i < fdpass->nfds; i++) { g_autofree char *arg = g_strdup_printf("set=%u,fd=%d,opaque=%s", @@ -152,8 +152,6 @@ qemuFDPassTransferCommand(qemuFDPass *fdpass, fdpass->fds[i].fd = -1; virCommandAddArgList(cmd, "-add-fd", arg, NULL); } - - return 0; } diff --git a/src/qemu/qemu_fd.h b/src/qemu/qemu_fd.h index dbb4ab0aa5..6f165b6be9 100644 --- a/src/qemu/qemu_fd.h +++ b/src/qemu/qemu_fd.h @@ -39,7 +39,7 @@ qemuFDPassAddFD(qemuFDPass *fdpass, int *fd, const char *suffix); -int +void qemuFDPassTransferCommand(qemuFDPass *fdpass, virCommand *cmd); -- 2.35.3

When dealing with fdsets only we don't need to pass the FD first as we now generate fdset name directly. Also there are no more caveats in passing multiple FDs. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_fd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_fd.c b/src/qemu/qemu_fd.c index b7dd66bdc7..266177b496 100644 --- a/src/qemu/qemu_fd.c +++ b/src/qemu/qemu_fd.c @@ -102,9 +102,8 @@ qemuFDPassNew(const char *prefix, * @fd: File descriptor to pass * @suffix: Name suffix for the file descriptor name * - * Adds @fd to be passed to qemu when transferring @fdpass to qemu. When @fdpass - * is configured to use FD set mode, multiple file descriptors can be passed by - * calling this function repeatedly. + * Adds @fd to be passed to qemu when transferring @fdpass to qemu. + * Multiple file descriptors can be passed by calling this function repeatedly. * * @suffix is used to build the name of the file descriptor by concatenating * it with @prefix passed to qemuFDPassNew. @suffix may be NULL, in which case @@ -223,8 +222,6 @@ qemuFDPassTransferMonitorRollback(qemuFDPass *fdpass, * @fdpass: The fd passing helper struct * * Returns the path/fd name that is used in qemu to refer to the passed FD. - * Note that it's only valid to call this function after @fdpass was already - * transferred to the command or monitor. */ const char * qemuFDPassGetPath(qemuFDPass *fdpass) -- 2.35.3

On a Tuesday in 2022, Peter Krempa wrote:
Originally the intention was to have one set of helpers but it turned out to be too much hassle and too obscure semantics.
This series adds a new helper qemuFDPassDirect and simplifies the internals greatly by using a distinct set of APIs.
Peter Krempa (9): qemu: fd: Add a distinct set of APIs for 'direct' fd passing mode qemu: Convert passing of 'vhostfd' to 'qemuFDPassDirect' qemu: Convert passing of 'tapfds' to 'qemuFDPassDirect' qemu: Convert passing of 'slirpfd' to 'qemuFDPassDirect' qemu: Use 'qemuFDPassDirect' for 'unix' chardevs qemuFDPassValidate: Don't validate file descriptors qemu: fd: Remove support for 'direct' fd passing from 'qemuFDPass' qemuFDPassTransferCommand: Remove return value qemu: fd: Fix documentation for FD set related functions
src/qemu/qemu_command.c | 55 +++----- src/qemu/qemu_domain.c | 7 +- src/qemu/qemu_domain.h | 7 +- src/qemu/qemu_fd.c | 265 ++++++++++++++++++++--------------- src/qemu/qemu_fd.h | 24 +++- src/qemu/qemu_hotplug.c | 15 +- src/qemu/qemu_interface.c | 8 +- src/qemu/qemu_monitor_json.c | 4 +- src/qemu/qemu_process.c | 5 +- src/qemu/qemu_slirp.c | 4 +- tests/qemuxml2argvmock.c | 10 +- tests/testutilsqemu.c | 26 ++-- 12 files changed, 232 insertions(+), 198 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Peter Krempa