From 4914fce77be7764332ca2b56a3496ea73ad2f042 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 6 Apr 2023 13:28:06 +1000 Subject: nstool: Rename nsholder to nstool In preparation for extending what it does. Signed-off-by: David Gibson Signed-off-by: Stefano Brivio --- test/.gitignore | 2 +- test/Makefile | 4 +- test/lib/setup | 30 ++++++------ test/nsholder.c | 139 -------------------------------------------------------- test/nstool.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+), 157 deletions(-) delete mode 100644 test/nsholder.c create mode 100644 test/nstool.c diff --git a/test/.gitignore b/test/.gitignore index fbee491..4837402 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -6,6 +6,6 @@ QEMU_EFI.fd *.raw *.raw.xz *.bin -nsholder +nstool guest-key guest-key.pub diff --git a/test/Makefile b/test/Makefile index 8d9be0b..7b00bef 100644 --- a/test/Makefile +++ b/test/Makefile @@ -58,7 +58,7 @@ TESTDATA_ASSETS = small.bin big.bin medium.bin LOCAL_ASSETS = mbuto.img mbuto.mem.img QEMU_EFI.fd \ $(DEBIAN_IMGS:%=prepared-%) $(FEDORA_IMGS:%=prepared-%) \ $(UBUNTU_NEW_IMGS:%=prepared-%) \ - nsholder guest-key guest-key.pub \ + nstool guest-key guest-key.pub \ $(TESTDATA_ASSETS) ASSETS = $(DOWNLOAD_ASSETS) $(LOCAL_ASSETS) @@ -79,7 +79,7 @@ mbuto.img: passt.mbuto mbuto guest-key.pub $(TESTDATA_ASSETS) mbuto.mem.img: passt.mem.mbuto mbuto ../passt.avx2 ./mbuto/mbuto -p ./$< -c lz4 -f $@ -nsholder: nsholder.c +nstool: nstool.c $(CC) $(CFLAGS) -o $@ $^ QEMU_EFI.fd: diff --git a/test/lib/setup b/test/lib/setup index 4311af9..2640203 100755 --- a/test/lib/setup +++ b/test/lib/setup @@ -17,7 +17,7 @@ INITRAMFS="${BASEPATH}/mbuto.img" VCPUS="$( [ $(nproc) -ge 8 ] && echo 6 || echo $(( $(nproc) / 2 + 1 )) )" __mem_kib="$(sed -n 's/MemTotal:[ ]*\([0-9]*\) kB/\1/p' /proc/meminfo)" VMEM="$((${__mem_kib} / 1024 / 4))" -NSHOLDER="${BASEPATH}/nsholder" +NSTOOL="${BASEPATH}/nstool" # setup_build() - Set up pane layout for build tests setup_build() { @@ -77,8 +77,8 @@ setup_pasta() { layout_pasta - context_run_bg unshare "unshare -rUnpf ${NSHOLDER} ${STATESETUP}/ns.hold hold" - __target_pid=$(${NSHOLDER} ${STATESETUP}/ns.hold pid) + context_run_bg unshare "unshare -rUnpf ${NSTOOL} ${STATESETUP}/ns.hold hold" + __target_pid=$(${NSTOOL} ${STATESETUP}/ns.hold pid) context_setup_nsenter ns -U -n -p --preserve-credentials -t ${__target_pid} @@ -126,9 +126,9 @@ setup_passt_in_ns() { [ ${DEBUG} -eq 1 ] && __opts="${__opts} -d" [ ${TRACE} -eq 1 ] && __opts="${__opts} --trace" - context_run_bg pasta "./pasta ${__opts} -t 10001,10002,10011,10012 -T 10003,10013 -u 10001,10002,10011,10012 -U 10003,10013 -P ${STATESETUP}/pasta.pid --config-net ${NSHOLDER} ${STATESETUP}/ns.hold hold" + context_run_bg pasta "./pasta ${__opts} -t 10001,10002,10011,10012 -T 10003,10013 -u 10001,10002,10011,10012 -U 10003,10013 -P ${STATESETUP}/pasta.pid --config-net ${NSTOOL} ${STATESETUP}/ns.hold hold" wait_for [ -f "${STATESETUP}/pasta.pid" ] - __ns_pid=$(${NSHOLDER} ${STATESETUP}/ns.hold pid) + __ns_pid=$(${NSTOOL} ${STATESETUP}/ns.hold pid) context_setup_nsenter qemu "-t ${__ns_pid} -U -n -p --preserve-credentials" context_setup_nsenter ns "-t ${__ns_pid} -U -n -p --preserve-credentials" @@ -189,16 +189,16 @@ setup_two_guests() { [ ${PCAP} -eq 1 ] && __opts="${__opts} -p ${LOGDIR}/pasta_1.pcap" [ ${DEBUG} -eq 1 ] && __opts="${__opts} -d" [ ${TRACE} -eq 1 ] && __opts="${__opts} --trace" - context_run_bg pasta_1 "./pasta ${__opts} --trace -l /tmp/pasta1.log -P ${STATESETUP}/pasta_1.pid -t 10001,10002 -T 10003,10004 -u 10001,10002 -U 10003,10004 --config-net ${NSHOLDER} ${STATESETUP}/ns1.hold hold" - __ns1_pid=$(${NSHOLDER} ${STATESETUP}/ns1.hold pid) + context_run_bg pasta_1 "./pasta ${__opts} --trace -l /tmp/pasta1.log -P ${STATESETUP}/pasta_1.pid -t 10001,10002 -T 10003,10004 -u 10001,10002 -U 10003,10004 --config-net ${NSTOOL} ${STATESETUP}/ns1.hold hold" + __ns1_pid=$(${NSTOOL} ${STATESETUP}/ns1.hold pid) context_setup_nsenter passt_1 -U -n -p --preserve-credentials -t ${__ns1_pid} __opts= [ ${PCAP} -eq 1 ] && __opts="${__opts} -p ${LOGDIR}/pasta_2.pcap" [ ${DEBUG} -eq 1 ] && __opts="${__opts} -d" [ ${TRACE} -eq 1 ] && __opts="${__opts} --trace" - context_run_bg pasta_2 "./pasta ${__opts} --trace -l /tmp/pasta2.log -P ${STATESETUP}/pasta_2.pid -t 10004,10005 -T 10003,10001 -u 10004,10005 -U 10003,10001 --config-net ${NSHOLDER} ${STATESETUP}/ns2.hold hold" - __ns2_pid=$(${NSHOLDER} ${STATESETUP}/ns2.hold pid) + context_run_bg pasta_2 "./pasta ${__opts} --trace -l /tmp/pasta2.log -P ${STATESETUP}/pasta_2.pid -t 10004,10005 -T 10003,10001 -u 10004,10005 -U 10003,10001 --config-net ${NSTOOL} ${STATESETUP}/ns2.hold hold" + __ns2_pid=$(${NSTOOL} ${STATESETUP}/ns2.hold pid) context_setup_nsenter passt_2 -U -n -p --preserve-credentials -t ${__ns2_pid} context_setup_nsenter qemu_1 -U -n -p --preserve-credentials -t ${__ns1_pid} @@ -284,7 +284,7 @@ teardown_passt() { # teardown_pasta() - Exit namespace, kill pasta process teardown_pasta() { - ${NSHOLDER} "${STATESETUP}/ns.hold" stop + ${NSTOOL} "${STATESETUP}/ns.hold" stop context_wait unshare teardown_context_watch ${PANE_HOST} host @@ -297,7 +297,7 @@ teardown_passt_in_ns() { context_run ns kill $(cat "${STATESETUP}/qemu.pid") context_wait qemu - ${NSHOLDER} "${STATESETUP}/ns.hold" stop + ${NSTOOL} "${STATESETUP}/ns.hold" stop context_wait pasta rm "${STATESETUP}/passt.pid" "${STATESETUP}/pasta.pid" @@ -310,8 +310,8 @@ teardown_passt_in_ns() { # teardown_two_guests() - Exit namespaces, kill qemu processes, passt and pasta teardown_two_guests() { - __ns1_pid=$(${NSHOLDER} "${STATESETUP}/ns1.hold" pid) - __ns2_pid=$(${NSHOLDER} "${STATESETUP}/ns2.hold" pid) + __ns1_pid=$(${NSTOOL} "${STATESETUP}/ns1.hold" pid) + __ns2_pid=$(${NSTOOL} "${STATESETUP}/ns2.hold" pid) nsenter -U -p --preserve-credentials -t ${__ns1_pid} kill $(cat "${STATESETUP}/qemu_1.pid") nsenter -U -p --preserve-credentials -t ${__ns2_pid} kill $(cat "${STATESETUP}/qemu_2.pid") context_wait qemu_1 @@ -321,8 +321,8 @@ teardown_two_guests() { nsenter -U -p --preserve-credentials -t ${__ns2_pid} kill $(cat "${STATESETUP}/passt_2.pid") context_wait passt_1 context_wait passt_2 - ${NSHOLDER} "${STATESETUP}/ns1.hold" stop - ${NSHOLDER} "${STATESETUP}/ns2.hold" stop + ${NSTOOL} "${STATESETUP}/ns1.hold" stop + ${NSTOOL} "${STATESETUP}/ns2.hold" stop context_wait pasta_1 context_wait pasta_2 diff --git a/test/nsholder.c b/test/nsholder.c deleted file mode 100644 index 03cf7a2..0000000 --- a/test/nsholder.c +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/* nsholder - maintain a namespace to be entered by other processes - * - * Copyright Red Hat - * Author: David Gibson - * - * Can run in 3 modes: - * - * nsholder hold - * Designed to be run inside a namespace, opens a Unix domain - * control socket at and waits until instructed to stop - * with "nsholder stop" - * nsholder pid - * Prints the PID of the nsholder hold process with control - * socket . This is given in the PID namespace where - * nsholder pid is executed, not the one where nsholder hold is - * running - * nsholder stop - * Instruct the nsholder hold with control socket at to exit. - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include - -#define die(...) \ - do { \ - fprintf(stderr, __VA_ARGS__); \ - exit(1); \ - } while (0) - -static void usage(void) -{ - die("Usage: holder hold|pid\n"); -} - -static void hold(int fd, const struct sockaddr_un *addr) -{ - int rc; - - rc = bind(fd, (struct sockaddr *)addr, sizeof(*addr)); - if (rc < 0) - die("bind(): %s\n", strerror(errno)); - - rc = listen(fd, 0); - if (rc < 0) - die("listen(): %s\n", strerror(errno)); - - printf("nsholder: local PID=%d local UID=%u local GID=%u\n", - getpid(), getuid(), getgid()); - do { - int afd = accept(fd, NULL, NULL); - char buf; - - if (afd < 0) - die("accept(): %s\n", strerror(errno)); - - rc = read(afd, &buf, sizeof(buf)); - if (rc < 0) - die("read(): %s\n", strerror(errno)); - } while (rc == 0); - - unlink(addr->sun_path); -} - -static void pid(int fd, const struct sockaddr_un *addr) -{ - int rc; - struct ucred peercred; - socklen_t optlen = sizeof(peercred); - - do { - rc = connect(fd, (struct sockaddr *)addr, sizeof(*addr)); - if (rc < 0 && errno != ENOENT && errno != ECONNREFUSED) - die("connect(): %s\n", strerror(errno)); - } while (rc < 0); - - rc = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, - &peercred, &optlen); - if (rc < 0) - die("getsockopet(SO_PEERCRED): %s\n", strerror(errno)); - - close(fd); - - printf("%d\n", peercred.pid); -} - -static void stop(int fd, const struct sockaddr_un *addr) -{ - int rc; - char buf = 'Q'; - - rc = connect(fd, (struct sockaddr *)addr, sizeof(*addr)); - if (rc < 0) - die("connect(): %s\n", strerror(errno)); - - rc = write(fd, &buf, sizeof(buf)); - if (rc < 0) - die("write(): %s\n", strerror(errno)); - - close(fd); -} - -int main(int argc, char *argv[]) -{ - int fd; - const char *sockname; - struct sockaddr_un sockaddr = { - .sun_family = AF_UNIX, - }; - - if (argc != 3) - usage(); - - sockname = argv[1]; - strncpy(sockaddr.sun_path, sockname, UNIX_PATH_MAX); - - fd = socket(AF_UNIX, SOCK_STREAM, PF_UNIX); - if (fd < 0) - die("socket(): %s\n", strerror(errno)); - - if (strcmp(argv[2], "hold") == 0) - hold(fd, &sockaddr); - else if (strcmp(argv[2], "pid") == 0) - pid(fd, &sockaddr); - else if (strcmp(argv[2], "stop") == 0) - stop(fd, &sockaddr); - else - usage(); - - exit(0); -} diff --git a/test/nstool.c b/test/nstool.c new file mode 100644 index 0000000..9d6ee0c --- /dev/null +++ b/test/nstool.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* nstool - maintain a namespace to be entered by other processes + * + * Copyright Red Hat + * Author: David Gibson + * + * Can run in 3 modes: + * + * nstool hold + * Designed to be run inside a namespace, opens a Unix domain + * control socket at and waits until instructed to stop + * with "nstool stop" + * nstool pid + * Prints the PID of the nstool hold process with control + * socket . This is given in the PID namespace where + * nstool pid is executed, not the one where nstool hold is + * running + * nstool stop + * Instruct the nstool hold with control socket at to exit. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#define die(...) \ + do { \ + fprintf(stderr, __VA_ARGS__); \ + exit(1); \ + } while (0) + +static void usage(void) +{ + die("Usage: nstool hold|pid\n"); +} + +static void hold(int fd, const struct sockaddr_un *addr) +{ + int rc; + + rc = bind(fd, (struct sockaddr *)addr, sizeof(*addr)); + if (rc < 0) + die("bind(): %s\n", strerror(errno)); + + rc = listen(fd, 0); + if (rc < 0) + die("listen(): %s\n", strerror(errno)); + + printf("nstool: local PID=%d local UID=%u local GID=%u\n", + getpid(), getuid(), getgid()); + do { + int afd = accept(fd, NULL, NULL); + char buf; + + if (afd < 0) + die("accept(): %s\n", strerror(errno)); + + rc = read(afd, &buf, sizeof(buf)); + if (rc < 0) + die("read(): %s\n", strerror(errno)); + } while (rc == 0); + + unlink(addr->sun_path); +} + +static void pid(int fd, const struct sockaddr_un *addr) +{ + int rc; + struct ucred peercred; + socklen_t optlen = sizeof(peercred); + + do { + rc = connect(fd, (struct sockaddr *)addr, sizeof(*addr)); + if (rc < 0 && errno != ENOENT && errno != ECONNREFUSED) + die("connect(): %s\n", strerror(errno)); + } while (rc < 0); + + rc = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, + &peercred, &optlen); + if (rc < 0) + die("getsockopet(SO_PEERCRED): %s\n", strerror(errno)); + + close(fd); + + printf("%d\n", peercred.pid); +} + +static void stop(int fd, const struct sockaddr_un *addr) +{ + int rc; + char buf = 'Q'; + + rc = connect(fd, (struct sockaddr *)addr, sizeof(*addr)); + if (rc < 0) + die("connect(): %s\n", strerror(errno)); + + rc = write(fd, &buf, sizeof(buf)); + if (rc < 0) + die("write(): %s\n", strerror(errno)); + + close(fd); +} + +int main(int argc, char *argv[]) +{ + int fd; + const char *sockname; + struct sockaddr_un sockaddr = { + .sun_family = AF_UNIX, + }; + + if (argc != 3) + usage(); + + sockname = argv[1]; + strncpy(sockaddr.sun_path, sockname, UNIX_PATH_MAX); + + fd = socket(AF_UNIX, SOCK_STREAM, PF_UNIX); + if (fd < 0) + die("socket(): %s\n", strerror(errno)); + + if (strcmp(argv[2], "hold") == 0) + hold(fd, &sockaddr); + else if (strcmp(argv[2], "pid") == 0) + pid(fd, &sockaddr); + else if (strcmp(argv[2], "stop") == 0) + stop(fd, &sockaddr); + else + usage(); + + exit(0); +} -- cgit v1.2.3