From e34ddae5a4d01e62001c8334ed63d53df528b978 Mon Sep 17 00:00:00 2001 From: Christiano Haesbaert Date: Mon, 28 Oct 2024 10:53:32 +0100 Subject: [PATCH] Embed manpages into the binaries With this invoking one of the utilities with `-h` will display the manpage. Since quark is not a "system utility", we can't expect people to go to the trouble of installing manpages, and typing `man ./quark-mon.8` is a pain. It's also likely that the binary is sent somewhere and thus the man relationship was lost. I had to write a mini-utility to embed the manpage, it's a bit sad that there isn't a `mandoc -T c` to export the manpage as a C struct. Arm64 cross compilation gets a little bit trickier: In order to build quark-mon, quark-btf and quark-test, it needs to build manpage.h, and to build manpage.h it needs to build man-embedder. But it can't build man-embedder for arm64, since we must be able to execute it! We fix it by cheating the order build, we force manpages.h to be evaluated before `all` in the host system. Which pulls man-embedder for the host and generates manpage.h. The only drawback is that man-embedder will stay built for the host system, which is fine since it's a build-system executable. --- .gitignore | 3 ++ Makefile | 52 +++++++++++++++++++++++++--------- display_man.c | 33 ++++++++++++++++++++++ docs/quark-btf.8.html | 18 +++++++++--- docs/quark-mon.8.html | 11 +++++++- docs/quark-test.8.html | 11 +++++++- man-embedder.c | 63 ++++++++++++++++++++++++++++++++++++++++++ quark-btf.8 | 7 ++++- quark-btf.c | 15 +++++++++- quark-mon.8 | 4 +++ quark-mon.c | 14 +++++++++- quark-test.8 | 4 +++ quark-test.c | 13 ++++++++- 13 files changed, 225 insertions(+), 23 deletions(-) create mode 100644 display_man.c create mode 100644 man-embedder.c diff --git a/.gitignore b/.gitignore index 1ce14a3..ec3000c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ init libquark.a libquark_big.a bpf_prog_skel.h +# manpages.h is autogenerated +manpages.h +man-embedder manhtml/*.html elftoolchain/libelf/libelf_pic.a initramfs/ diff --git a/Makefile b/Makefile index 4ce3254..763954e 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,7 @@ EEBPF_INCLUDES:= -Ielastic-ebpf/GPL/Events -Ielastic-ebpf/contrib/vmlinux/$(ARCH # LIBQUARK LIBQUARK_DEPS:= $(wildcard *.h) bpf_prog_skel.h $(EEBPF_FILES) include +LIBQUARK_DEPS:= $(filter-out manpages.h, $(LIBQUARK_DEPS)) LIBQUARK_SRCS:= \ bpf_queue.c \ btf.c \ @@ -198,7 +199,7 @@ docker: docker-image clean-all $(call msg,DOCKER-RUN,Dockerfile) $(Q)$(DOCKER) run $(DOCKER_RUN_ARGS) /bin/bash -c "make -C $(PWD)" -docker-cross-arm64: clean-all docker-image +docker-cross-arm64: clean-all docker-image manpages.h $(call msg,DOCKER-RUN,Dockerfile) $(Q)$(DOCKER) run \ -e ARCH=arm64 \ @@ -278,29 +279,52 @@ init: init.c $(call msg,CC,$@) $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) -static -o $@ $^ -quark-mon: quark-mon.c $(LIBQUARK_STATIC_BIG) +quark-mon: quark-mon.c manpages.h $(LIBQUARK_STATIC_BIG) $(call msg,CC,$@) - $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) -o $@ $^ + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) \ + -o $@ $< $(LIBQUARK_STATIC_BIG) -quark-btf: quark-btf.c $(LIBQUARK_STATIC_BIG) +quark-btf: quark-btf.c manpages.h $(LIBQUARK_STATIC_BIG) $(call msg,CC,$@) - $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) -o $@ $^ + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) \ + -o $@ $< $(LIBQUARK_STATIC_BIG) -quark-test: quark-test.c $(LIBQUARK_STATIC_BIG) +quark-test: quark-test.c manpages.h $(LIBQUARK_STATIC_BIG) $(call msg,CC,$@) - $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) -o $@ $^ + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) \ + -o $@ $< $(LIBQUARK_STATIC_BIG) -quark-mon-static: quark-mon.c $(LIBQUARK_STATIC_BIG) +quark-mon-static: quark-mon.c manpages.h $(LIBQUARK_STATIC_BIG) $(call msg,CC,$@) - $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) -DNO_PRIVDROP $(CDIAGFLAGS) -static -o $@ $^ + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) -DNO_PRIVDROP $(CDIAGFLAGS) \ + -static -o $@ $< $(LIBQUARK_STATIC_BIG) -quark-btf-static: quark-btf.c $(LIBQUARK_STATIC_BIG) +quark-btf-static: quark-btf.c manpages.h $(LIBQUARK_STATIC_BIG) $(call msg,CC,$@) - $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) -static -o $@ $^ + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) \ + -static -o $@ $< $(LIBQUARK_STATIC_BIG) -quark-test-static: quark-test.c $(LIBQUARK_STATIC_BIG) +quark-test-static: quark-test.c manpages.h $(LIBQUARK_STATIC_BIG) $(call msg,CC,$@) - $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) -static -o $@ $^ + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) \ + -static -o $@ $< $(LIBQUARK_STATIC_BIG) + +man-embedder: man-embedder.c + $(call msg,CC,$@) + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(CDIAGFLAGS) -o $@ $^ + +manpages.h: man-embedder display_man.c quark-btf.8 quark-mon.8 quark-test.8 + $(Q)echo '// SPDX-License-Identifier: Apache-2.0' > $@ + $(Q)echo '/* Copyright (c) 2024 Elastic NV */' >> $@ + $(Q)echo '' >> $@ + $(call msg,MAN-EMB,quark-btf.8) + $(Q)./man-embedder quark-btf.8 MAN_QUARK_BTF >> $@ + $(call msg,MAN-EMB,quark-mon.8) + $(Q)./man-embedder quark-mon.8 MAN_QUARK_MON >> $@ + $(call msg,MAN-EMB,quark-test.8) + $(Q)./man-embedder quark-test.8 MAN_QUARK_TEST >> $@ + $(call msg,MAN-EMB,display_man.c) + $(Q)cat display_man.c >> $@ docs/index.html: docs/quark.7.html $(call msg,CP,index.html) @@ -336,6 +360,8 @@ clean: $(Q)rm -f \ *.o \ *.a \ + man-embedder \ + manpages.h \ quark-mon \ quark-mon-static \ quark-btf \ diff --git a/display_man.c b/display_man.c new file mode 100644 index 0000000..b78cd37 --- /dev/null +++ b/display_man.c @@ -0,0 +1,33 @@ +/* + * This code is stashed in the end of manpage.h + */ +static void +display_man(void) +{ + int fd, status; + char template[] = "/tmp/quark-man-display.XXXXXX"; + pid_t pid; + + fd = mkstemp(template); + if (fd == -1) + err(1, "mkstemp"); + if (qwrite(fd, manpage_bin, sizeof(manpage_bin)) != 0) + err(1, "qwrite"); + close(fd); + + if ((pid = fork()) == -1) + err(1, "fork"); + + /* child */ + if (pid == 0) + exit(execlp("man", "man", template, NULL)); + /* parent */ + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid"); + if (unlink(template) != 0) + warn("unlink"); + if (WIFEXITED(status)) + exit(WEXITSTATUS(status)); + + exit(1); +} diff --git a/docs/quark-btf.8.html b/docs/quark-btf.8.html index 4763501..05c6a8e 100644 --- a/docs/quark-btf.8.html +++ b/docs/quark-btf.8.html @@ -46,6 +46,13 @@

<
+ + + + + +
quark-btf-h
+
@@ -80,9 +87,12 @@

. - This option only used to generate btfhub.c via - genbtf.sh, chances are you'll never need - this. +

This option is only used to generate + btfhub.c via genbtf.sh, + chances are you'll never need this.

+ +
+
Display this manpage.
version
Lookup the kernel @@ -155,7 +165,7 @@

quark-btf -V
October 25, 2024October 28, 2024 Linux

<
+ + + + + +
quark-mon-h
+
@@ -78,6 +85,8 @@

be aggregated.
+
+
Display this manpage.
Attempt kprobe as the backend.
@@ -171,7 +180,7 @@

quark-mon -V
October 25, 2024October 28, 2024 Linux

<
+ + + + + +
quark-test-h
+
@@ -64,6 +71,8 @@

Run only EBPF tests.
+
+
Display this manpage.
Run only KPROBE tests.
@@ -120,7 +129,7 @@

quark-test -l
October 25, 2024October 28, 2024 Linux