diff --git a/Dockerfile b/Dockerfile index 3720e7a..2b7809e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -200,8 +200,21 @@ RUN set -x && \ # mlat-client: simple test /usr/local/share/radarbox-mlat-client/venv/bin/python3 -c 'import mlat.client' +FROM debian:bullseye as rbfeeder_fixcputemp +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +ADD rbfeeder_fixcputemp ./ +RUN set -x && \ + apt-get update && \ + apt-get install -y --no-install-suggests --no-install-recommends \ + build-essential +ARG TARGETARCH +RUN if [ $TARGETARCH != "arm" ]; then \ + apt-get install -y crossbuild-essential-armhf \ + ; fi +RUN make CC=arm-linux-gnueabihf-gcc + # THTTPD -FROM alpine:3.13.2 AS thttpd +FROM alpine:3.19.1 AS thttpd ENV THTTPD_VERSION=2.29 @@ -244,6 +257,7 @@ COPY --from=confd /opt/confd/bin/confd /copy_root/opt/confd/bin/ COPY --from=radarbox /usr/bin/rbfeeder /copy_root/usr/bin/rbfeeder_armhf COPY --from=radarbox /usr/bin/dump1090-rb /copy_root/usr/bin/dump1090-rbs COPY --from=radarbox /usr/local/share/radarbox-mlat-client /copy_root/usr/local/share/radarbox-mlat-client +COPY --from=rbfeeder_fixcputemp ./librbfeeder_fixcputemp.so /copy_root/usr/lib/arm-linux-gnueabihf/librbfeeder_fixcputemp.so ADD build /copy_root/build FROM debian:bullseye-slim as serve diff --git a/build/rbfeeder_wrapper.sh b/build/rbfeeder_wrapper.sh index 0290fc7..d5cd66c 100755 --- a/build/rbfeeder_wrapper.sh +++ b/build/rbfeeder_wrapper.sh @@ -5,9 +5,10 @@ # attempt to run natively if /usr/bin/rbfeeder_armhf --no-start --version >/dev/null 2>&1; then + export LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/librbfeeder_fixcputemp.so /usr/bin/rbfeeder_armhf "$@" elif qemu-arm-static /usr/bin/rbfeeder_armhf --no-start --version >/dev/null 2>&1; then - qemu-arm-static /usr/bin/rbfeeder_armhf "$@" + qemu-arm-static -E LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/librbfeeder_fixcputemp.so /usr/bin/rbfeeder_armhf "$@" else for i in {1..5}; do echo "FATAL: Could not run rbfeeder natively or via qemu!" | mawk -W interactive '{printf "%c[34m[radarbox-feeder]%c[0m %s\n", 27, 27, $0}' diff --git a/rbfeeder_fixcputemp/.gitignore b/rbfeeder_fixcputemp/.gitignore new file mode 100644 index 0000000..9d22eb4 --- /dev/null +++ b/rbfeeder_fixcputemp/.gitignore @@ -0,0 +1,2 @@ +*.o +*.so diff --git a/rbfeeder_fixcputemp/Makefile b/rbfeeder_fixcputemp/Makefile new file mode 100644 index 0000000..c4414ec --- /dev/null +++ b/rbfeeder_fixcputemp/Makefile @@ -0,0 +1,11 @@ +CFLAGS := $(CFLAGS) -fPIC -Wall + +TARGET = librbfeeder_fixcputemp + +all: $(TARGET).so + +$(TARGET).so: $(TARGET).o + $(CC) $^ -shared -o $@ + +clean: + rm *.so *.o diff --git a/rbfeeder_fixcputemp/README.md b/rbfeeder_fixcputemp/README.md new file mode 100644 index 0000000..056d2ec --- /dev/null +++ b/rbfeeder_fixcputemp/README.md @@ -0,0 +1,24 @@ +# Fixup CPU Teampeature for RBFeeder + +This is a simple hook library for RBFeeder to fixup the CPU temperature measurement function on non-Raspberry Pi devices. + +## Implementation +When running on a Raspberry Pi, the CPU temperature is read from the `/sys/class/thermal/thermal_zone0/temp` file. However this file does not exist on some other devices, and RBFeeder will crash because the file is not found. + +This library hooked `fopen` function to intercept the file open request for `/sys/class/thermal/thermal_zone0/temp` and return a fake file handle with a fixed temperature value if we are unable to open that file. + +## Usage +1. Build the library by running `make` with cross compiler or on the target device. +``` +$ make CC=arm-linux-gnueabihf-gcc +``` + +2. LD_PRELOAD the library when running RBFeeder. +``` +$ LD_PRELOAD=./libfixcputemp.so ./rbfeeder +``` + +or if you are using qemu +``` +$ qemu-arm -E LD_PRELOAD=./librbfeeder_fixcputemp.so ./rbfeeder +``` diff --git a/rbfeeder_fixcputemp/librbfeeder_fixcputemp.c b/rbfeeder_fixcputemp/librbfeeder_fixcputemp.c new file mode 100644 index 0000000..fe126fd --- /dev/null +++ b/rbfeeder_fixcputemp/librbfeeder_fixcputemp.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include +#include +#include +#include + +#undef fopen + +ssize_t cputemp_read(void *cookie, char *buf, size_t size) +{ + const char temp[] = "0"; + size_t len = sizeof(temp); + if (size < len) + { + return -1; + } + memcpy(buf, temp, len); + return len; +} + +cookie_io_functions_t cputemp_funcs = { + .read = cputemp_read, +}; + +FILE *fopen(const char *path, const char *mode) +{ + FILE *orig_file = NULL; + static FILE *(*real_fopen)(const char *, const char *) = NULL; + if (real_fopen == NULL) + { + real_fopen = dlsym(RTLD_NEXT, "fopen"); + if (real_fopen == NULL) + { + fprintf(stderr, "fixcputemp: Error in `dlsym`: %s\n", dlerror()); + return NULL; + } + } + + orig_file = real_fopen(path, mode); + if (orig_file) + { + return orig_file; + } + + if (strcmp(path, "/sys/class/thermal/thermal_zone0/temp") == 0) + { + if (strcmp(mode, "r") != 0) + { + fprintf(stderr, "fixcputemp: fopen() called with mode other than 'r'\n"); + return NULL; + } + return fopencookie(NULL, "r", cputemp_funcs); + } + return NULL; +}