New function to call "qemu-ebpf-rss-helper".
The helper passes few fds through unix socket.
Technically libvirt should not be aware how many and what those fds.
The helper should return fds that should be passed to the qemu as is and in same order.
Signed-off-by: Andrew Melnychenko <andrew(a)daynix.com>
---
src/qemu/qemu_interface.c | 54 +++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_interface.h | 2 ++
2 files changed, 56 insertions(+)
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index ac0168c80d..76435af94e 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -777,3 +777,57 @@ qemuInterfaceOpenVhostNet(virDomainDef *def,
return -1;
}
+
+
+int qemuEbpfRssHelper(const char *helper, int *fds, int nfds)
+{
+ int ret = 0;
+ int err = 0;
+ int unix_fds[2] = { -1, -1 };
+ virCommand *cmd = NULL;
+
+ if (!helper || !fds || !nfds) {
+ return -1;
+ }
+
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, unix_fds);
+ if (ret) {
+ virReportSystemError(errno, "%s", _("failed to create
socket"));
+ return -1;
+ }
+
+ cmd = virCommandNew(helper);
+ if (cmd == NULL) {
+ VIR_FORCE_CLOSE(unix_fds[1]);
+ ret = -1;
+ goto cleanup;
+ }
+ virCommandAddArgFormat(cmd, "--fd=%d", unix_fds[1]);
+ virCommandPassFD(cmd, unix_fds[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+ virCommandDoAsyncIO(cmd);
+
+ if (virCommandRunAsync(cmd, NULL) < 0) {
+ VIR_FORCE_CLOSE(unix_fds[1]);
+ ret = -1;
+ goto cleanup;
+ }
+
+ memset(fds, 0, sizeof(*fds) * nfds);
+
+ ret = virSocketRecvMultipleFDs(unix_fds[0], fds, nfds, 0);
+
+ if (virCommandWait(cmd, &err) < 0) {
+ int i = 0;
+ for (; i < ret; ++i) {
+ if (fds[i]) {
+ VIR_FORCE_CLOSE(fds[i]);
+ }
+ }
+ ret = -1;
+ }
+
+cleanup:
+ VIR_FORCE_CLOSE(unix_fds[0]);
+ virCommandFree(cmd);
+ return ret;
+}
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index 438d548065..63d7590035 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -61,3 +61,5 @@ int qemuInterfacePrepareSlirp(virQEMUDriver *driver,
qemuSlirp **slirp);
int qemuInterfaceVDPAConnect(virDomainNetDef *net) G_GNUC_NO_INLINE;
+
+int qemuEbpfRssHelper(const char *helper, int *fds, int nfds);
--
2.31.1