On Wed, 11 Jun 2025 at 15:38, Thomas Weißschuh <thomas.weisssc...@linutronix.de> wrote: > > UAPI selftests may expect a "normal" userspace environment. > For example the normal kernel API pseudo-filesystems should be mounted. > This could be done from kernel code but it is non-idiomatic. > > Add a preinit userspace executable which performs these setup steps > before running the final test executable. > This preinit executable is only ever run from the kernel. > Give it access to autoconf.h and kconfig.h to adapt itself to the > tested kernel. > > Signed-off-by: Thomas Weißschuh <thomas.weisssc...@linutronix.de> > ---
Looks good and works here. Reviewed-by: David Gow <david...@google.com> (Although, personally, _I wish_ it were more idiomatic to mount things from kernelspace.) Cheers, -- David > lib/kunit/Makefile | 9 ++++++- > lib/kunit/uapi-preinit.c | 63 > ++++++++++++++++++++++++++++++++++++++++++++++++ > lib/kunit/uapi.c | 11 +++++++-- > 3 files changed, 80 insertions(+), 3 deletions(-) > > diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile > index > e406a31df1df834a87961663de0b7921b59481c2..19493ec320c61e2ccbb58e8b2e943e9a4ec447e2 > 100644 > --- a/lib/kunit/Makefile > +++ b/lib/kunit/Makefile > @@ -12,7 +12,14 @@ kunit-objs += test.o \ > device.o \ > platform.o > > -kunit-$(CONFIG_KUNIT_UAPI) += uapi.o > +userprogs += uapi-preinit > +uapi-preinit-nolibc := $(CONFIG_ARCH_HAS_NOLIBC) > +uapi-preinit-userccflags += -static \ > + -include include/generated/autoconf.h > \ > + -include > $(srctree)/tools/include/linux/kconfig.h > +blobs += uapi-preinit.blob.o > +uapi-preinit.blob-symbol := kunit_uapi_preinit > +kunit-$(CONFIG_KUNIT_UAPI) += uapi.o uapi-preinit.blob.o > > ifeq ($(CONFIG_KUNIT_DEBUGFS),y) > kunit-objs += debugfs.o > diff --git a/lib/kunit/uapi-preinit.c b/lib/kunit/uapi-preinit.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..81182039965a8c93aebb2d5d76f4113bfef277a6 > --- /dev/null > +++ b/lib/kunit/uapi-preinit.c > @@ -0,0 +1,63 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * KUnit Userspace environment setup. > + * > + * Copyright (C) 2025, Linutronix GmbH. > + * Author: Thomas Weißschuh <thomas.weisssc...@linutronix.de> > + * > + * This is *userspace* code. > + */ > + > +#include <sys/mount.h> > +#include <sys/stat.h> > + > +#include "../../tools/testing/selftests/kselftest.h" > + > +static int setup_api_mount(const char *target, const char *fstype) > +{ > + int ret; > + > + ret = mkdir(target, 0755); > + if (ret && errno != EEXIST) > + return -errno; > + > + ret = mount("none", target, fstype, 0, NULL); > + if (ret && errno != EBUSY) > + return -errno; > + > + return 0; > +} > + > +static void exit_failure(const char *stage, int err) > +{ > + /* If preinit fails synthesize a failed test report. */ > + ksft_print_header(); > + ksft_set_plan(1); > + ksft_test_result_fail("Failed during test setup: %s: %s\n", stage, > strerror(-err)); > + ksft_finished(); > +} > + > +int main(int argc, char **argv, char **envp) > +{ > + int ret; > + > + ret = setup_api_mount("/proc", "proc"); > + if (ret) > + exit_failure("mount /proc", ret); > + > + ret = setup_api_mount("/sys", "sysfs"); > + if (ret) > + exit_failure("mount /sys", ret); > + > + if (IS_ENABLED(CONFIG_DEVTMPFS)) { > + ret = setup_api_mount("/dev", "devtmpfs"); > + if (ret) > + exit_failure("mount /dev", ret); > + } > + > + ret = execve(argv[0], argv, envp); > + if (ret) > + exit_failure("execve", ret); > + > + return 0; > +} > diff --git a/lib/kunit/uapi.c b/lib/kunit/uapi.c > index > 121146dda533b3f90aca37c20bd0e7a1d20cb3b5..bccc081a6538507724c1ef340203cfd147170dc4 > 100644 > --- a/lib/kunit/uapi.c > +++ b/lib/kunit/uapi.c > @@ -139,7 +139,7 @@ static int kunit_uapi_user_mode_thread_init(void *data) > kernel_sigaction(SIGABRT, SIG_DFL); > > complete(&ctx->setup_done); > - ctx->exec_err = kernel_execve(ctx->executable, argv, NULL); > + ctx->exec_err = > kernel_execve(kbasename(BLOB(kunit_uapi_preinit)->path), argv, NULL); > if (!ctx->exec_err) > return 0; > do_exit(0); > @@ -239,6 +239,7 @@ static int kunit_uapi_run_executable_in_mount(struct > kunit *test, const char *ex > > static int kunit_uapi_run_executable(struct kunit *test, const struct blob > *executable) > { > + const struct blob *preinit = BLOB(kunit_uapi_preinit); > const char *exe_name = kbasename(executable->path); > struct vfsmount *mnt; > int err; > @@ -247,7 +248,13 @@ static int kunit_uapi_run_executable(struct kunit *test, > const struct blob *exec > if (IS_ERR(mnt)) > return PTR_ERR(mnt); > > - err = kunit_uapi_write_file(mnt, exe_name, 0755, executable->data, > blob_size(executable)); > + err = kunit_uapi_write_file(mnt, kbasename(preinit->path), 0755, > + preinit->data, > + blob_size(preinit)); > + > + if (!err) > + err = kunit_uapi_write_file(mnt, exe_name, 0755, > + executable->data, > blob_size(executable)); > > if (!err) > err = kunit_uapi_run_executable_in_mount(test, exe_name, mnt); > > -- > 2.49.0 >
smime.p7s
Description: S/MIME Cryptographic Signature