diff mbox series

[langdale,24/37] qemu-helper-native: Re-write bridge helper as C program

Message ID adabfbd9245553d1fb6abb050856e3da89f7a3d5.1669471990.git.steve@sakoman.com
State New
Headers show
Series [langdale,01/37] ffmpeg: upgrade 5.1.1 -> 5.1.2 | expand

Commit Message

Steve Sakoman Nov. 26, 2022, 2:14 p.m. UTC
From: Joshua Watt <JPEWhacker@gmail.com>

The bridge helper program is invoked directly from QEMU when it needs to
attach to a network bridge. As such, it is subject to the environment of
QEMU itself. Specifically, if bridging is enabled with direct rendering
acceleration, QEMU is run with an LD_PRELOAD that attempts to preload
several uninative libraries; however /bin/sh doesn't use the uninative
loader which means it can fail to start with an error like:

 /bin/sh: symbol lookup error: sysroots-uninative/x86_64-linux/lib/librt.so.1: undefined symbol: __libc_unwind_link_get, version GLIBC_PRIVATE

Converting the helper program to a C program resolves this problem
because it will now use the uninative loader so the preload doesn't
cause errors.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
(cherry picked from commit f698e98f2f09952b34488b8cf9e73e82bd7aea07)
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
 .../qemu/qemu-helper-native_1.0.bb            |  6 +--
 .../qemu/qemu-helper/qemu-oe-bridge-helper    | 25 -----------
 .../qemu/qemu-helper/qemu-oe-bridge-helper.c  | 41 +++++++++++++++++++
 3 files changed, 44 insertions(+), 28 deletions(-)
 delete mode 100755 meta/recipes-devtools/qemu/qemu-helper/qemu-oe-bridge-helper
 create mode 100644 meta/recipes-devtools/qemu/qemu-helper/qemu-oe-bridge-helper.c
diff mbox series

Patch

diff --git a/meta/recipes-devtools/qemu/qemu-helper-native_1.0.bb b/meta/recipes-devtools/qemu/qemu-helper-native_1.0.bb
index aa9e499c77..e297586bbb 100644
--- a/meta/recipes-devtools/qemu/qemu-helper-native_1.0.bb
+++ b/meta/recipes-devtools/qemu/qemu-helper-native_1.0.bb
@@ -7,7 +7,7 @@  LIC_FILES_CHKSUM = "file://${WORKDIR}/tunctl.c;endline=4;md5=ff3a09996bc5fff6bc5
 
 SRC_URI = "\
     file://tunctl.c \
-    file://qemu-oe-bridge-helper \
+    file://qemu-oe-bridge-helper.c \
     "
 
 S = "${WORKDIR}"
@@ -16,13 +16,13 @@  inherit native
 
 do_compile() {
 	${CC} ${CFLAGS} ${LDFLAGS} -Wall tunctl.c -o tunctl
+	${CC} ${CFLAGS} ${LDFLAGS} -Wall qemu-oe-bridge-helper.c -o qemu-oe-bridge-helper
 }
 
 do_install() {
 	install -d ${D}${bindir}
 	install tunctl ${D}${bindir}/
-
-    install -m 755 ${WORKDIR}/qemu-oe-bridge-helper ${D}${bindir}/
+	install qemu-oe-bridge-helper ${D}${bindir}/
 }
 
 DEPENDS += "qemu-system-native"
diff --git a/meta/recipes-devtools/qemu/qemu-helper/qemu-oe-bridge-helper b/meta/recipes-devtools/qemu/qemu-helper/qemu-oe-bridge-helper
deleted file mode 100755
index f057d4eef0..0000000000
--- a/meta/recipes-devtools/qemu/qemu-helper/qemu-oe-bridge-helper
+++ /dev/null
@@ -1,25 +0,0 @@ 
-#! /bin/sh
-# Copyright 2020 Garmin Ltd. or its subsidiaries
-#
-# SPDX-License-Identifier: GPL-2.0
-#
-# Attempts to find and exec the host qemu-bridge-helper program
-
-# If the QEMU_BRIDGE_HELPER variable is set by the user, exec it.
-if [ -n "$QEMU_BRIDGE_HELPER" ]; then
-    exec "$QEMU_BRIDGE_HELPER" "$@"
-fi
-
-# Search common paths for the helper program
-BN="qemu-bridge-helper"
-PATHS="/usr/libexec/ /usr/lib/qemu/"
-
-for p in $PATHS; do
-    if [ -e "$p/$BN" ]; then
-        exec "$p/$BN" "$@"
-    fi
-done
-
-echo "$BN not found!" > /dev/stderr
-exit 1
-
diff --git a/meta/recipes-devtools/qemu/qemu-helper/qemu-oe-bridge-helper.c b/meta/recipes-devtools/qemu/qemu-helper/qemu-oe-bridge-helper.c
new file mode 100644
index 0000000000..cadf2a012a
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu-helper/qemu-oe-bridge-helper.c
@@ -0,0 +1,41 @@ 
+/*
+ * Copyright 2022 Garmin Ltd. or its subsidiaries
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Attempts to find and exec the host qemu-bridge-helper program
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+void try_program(char const* path, char** args) {
+    if (access(path, X_OK) == 0) {
+        execv(path, args);
+    }
+}
+
+int main(int argc, char** argv) {
+    char* var;
+
+    /* Copy arguments so that they are a NULL terminated list, skipping argv[0]
+     * since it is this program name */
+    char** args = malloc(argc * sizeof(char*));
+    for (int i = 0; i < argc - 1; i++) {
+        args[i] = argv[i + 1];
+    }
+    args[argc - 1] = NULL;
+
+    var = getenv("QEMU_BRIDGE_HELPER");
+    if (var && var[0] != '\0') {
+        execvp(var, args);
+        return 1;
+    }
+
+    try_program("/usr/libexec/qemu-bridge-helper", args);
+    try_program("/usr/lib/qemu/qemu-bridge-helper", args);
+
+    fprintf(stderr, "No bridge helper found\n");
+    return 1;
+}
+