Skip to content

Commit

Permalink
Embed manpages into the binaries
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
haesbaert committed Oct 28, 2024
1 parent 51a3b02 commit e34ddae
Show file tree
Hide file tree
Showing 13 changed files with 225 additions and 23 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
52 changes: 39 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -336,6 +360,8 @@ clean:
$(Q)rm -f \
*.o \
*.a \
man-embedder \
manpages.h \
quark-mon \
quark-mon-static \
quark-btf \
Expand Down
33 changes: 33 additions & 0 deletions display_man.c
Original file line number Diff line number Diff line change
@@ -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);
}
18 changes: 14 additions & 4 deletions docs/quark-btf.8.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ <h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a><
</tr>
</table>
<br/>
<table class="Nm">
<tr>
<td><code class="Nm">quark-btf</code></td>
<td><code class="Fl">-h</code></td>
</tr>
</table>
<br/>
<table class="Nm">
<tr>
<td><code class="Nm">quark-btf <code class="Fl">-V</code></code></td>
Expand Down Expand Up @@ -80,9 +87,12 @@ <h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIP
<a class="permalink" href="#uname"><i class="Em">uname
-r</i></a>.</dd>
</dl>
This option only used to generate <span class="Pa">btfhub.c</span> via
<span class="Pa">genbtf.sh</span>, chances are you'll never need
this.</dd>
<p class="Pp">This option is only used to generate
<span class="Pa">btfhub.c</span> via <span class="Pa">genbtf.sh</span>,
chances are you'll never need this.</p>
</dd>
<dt id="h"><a class="permalink" href="#h"><code class="Fl">-h</code></a></dt>
<dd>Display this manpage.</dd>
<dt id="l"><a class="permalink" href="#l"><code class="Fl">-l</code></a>
<var class="Ar">version</var></dt>
<dd>Lookup the kernel
Expand Down Expand Up @@ -155,7 +165,7 @@ <h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
</div>
<table class="foot">
<tr>
<td class="foot-date">October 25, 2024</td>
<td class="foot-date">October 28, 2024</td>
<td class="foot-os">Linux</td>
</tr>
</table>
Expand Down
11 changes: 10 additions & 1 deletion docs/quark-mon.8.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ <h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a><
</tr>
</table>
<br/>
<table class="Nm">
<tr>
<td><code class="Nm">quark-mon</code></td>
<td><code class="Fl">-h</code></td>
</tr>
</table>
<br/>
<table class="Nm">
<tr>
<td><code class="Nm">quark-mon <code class="Fl">-V</code></code></td>
Expand Down Expand Up @@ -78,6 +85,8 @@ <h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIP
<dd>Use minimal aggregation, fork, exec and exit will
<a class="permalink" href="#not"><i class="Em" id="not">not</i></a> be
aggregated.</dd>
<dt id="h"><a class="permalink" href="#h"><code class="Fl">-h</code></a></dt>
<dd>Display this manpage.</dd>
<dt id="k"><a class="permalink" href="#k"><code class="Fl">-k</code></a></dt>
<dd>Attempt kprobe as the backend.</dd>
<dt id="l"><a class="permalink" href="#l"><code class="Fl">-l</code></a>
Expand Down Expand Up @@ -171,7 +180,7 @@ <h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
</div>
<table class="foot">
<tr>
<td class="foot-date">October 25, 2024</td>
<td class="foot-date">October 28, 2024</td>
<td class="foot-os">Linux</td>
</tr>
</table>
Expand Down
11 changes: 10 additions & 1 deletion docs/quark-test.8.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ <h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a><
</tr>
</table>
<br/>
<table class="Nm">
<tr>
<td><code class="Nm">quark-test</code></td>
<td><code class="Fl">-h</code></td>
</tr>
</table>
<br/>
<table class="Nm">
<tr>
<td><code class="Nm">quark-test <code class="Fl">-l</code></code></td>
Expand Down Expand Up @@ -64,6 +71,8 @@ <h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIP
<dl class="Bl-tag">
<dt id="b"><a class="permalink" href="#b"><code class="Fl">-b</code></a></dt>
<dd>Run only EBPF tests.</dd>
<dt id="h"><a class="permalink" href="#h"><code class="Fl">-h</code></a></dt>
<dd>Display this manpage.</dd>
<dt id="k"><a class="permalink" href="#k"><code class="Fl">-k</code></a></dt>
<dd>Run only KPROBE tests.</dd>
<dt id="l"><a class="permalink" href="#l"><code class="Fl">-l</code></a></dt>
Expand Down Expand Up @@ -120,7 +129,7 @@ <h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
</div>
<table class="foot">
<tr>
<td class="foot-date">October 25, 2024</td>
<td class="foot-date">October 28, 2024</td>
<td class="foot-os">Linux</td>
</tr>
</table>
Expand Down
63 changes: 63 additions & 0 deletions man-embedder.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: Apache-2.0
/* Copyright (c) 2024 Elastic NV */

#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

static void
usage(void)
{
fprintf(stderr, "usage: %s input_file ifdef_name\n",
program_invocation_short_name);

exit(1);
}

static int
embed(const char *input_path, const char *ifdef_name)
{
FILE *input;
int ch, line_wrap;

if ((input = fopen(input_path, "r")) == NULL)
err(1, "fopen");

if (ifdef_name != NULL)
printf("#ifdef %s\n", ifdef_name);
printf("const char manpage_bin[] = {\n");

line_wrap = 0;
while ((ch = fgetc(input)) != EOF) {
if (line_wrap == 0)
putchar('\t');
printf("0x%02x, ", ch);
if (++line_wrap == 10) {
putchar('\n');
line_wrap = 0;
}
}
if (ferror(input))
errx(1, "input error");
fclose(input);

printf("\n};\n");
if (ifdef_name != NULL)
printf("#endif /* %s */", ifdef_name);
putchar('\n');

return (0);
}

int
main(int argc, char *argv[])
{
if (argc != 3)
usage();

return (embed(argv[1], argv[2]));
}
7 changes: 6 additions & 1 deletion quark-btf.8
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
.Nm quark-btf
.Op Fl v
.Fl g Ar btf_file name version
.Nm quark-btf
.Fl h
.Nm quark-btf Fl V
.Sh DESCRIPTION
The
Expand Down Expand Up @@ -45,11 +47,14 @@ is a human identifier, like ubuntu-22.
is the kernel version as returned by
.Em uname -r .
.El
This option only used to generate
.Pp
This option is only used to generate
.Pa btfhub.c
via
.Pa genbtf.sh ,
chances are you'll never need this.
.It Fl h
Display this manpage.
.It Fl l Ar version
Lookup the kernel
.Em version
Expand Down
15 changes: 14 additions & 1 deletion quark-btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
#include <strings.h>
#include <unistd.h>

#include <sys/wait.h>

#include "quark.h"

#define MAN_QUARK_BTF
#include "manpages.h"

static int bflag;
static int fflag;
static int gflag;
Expand All @@ -29,6 +34,8 @@ disply_version(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s -h\n",
program_invocation_short_name);
fprintf(stderr, "usage: %s [-bv] [targets...]\n",
program_invocation_short_name);
fprintf(stderr, "usage: %s [-bv] [-f btf_file]\n",
Expand Down Expand Up @@ -229,14 +236,20 @@ main(int argc, char *argv[])
int ch;
const char *path = NULL;

while ((ch = getopt(argc, argv, "bf:glvV")) != -1) {
while ((ch = getopt(argc, argv, "bf:ghlvV")) != -1) {
switch (ch) {
case 'b':
bflag = 1;
break;
case 'g':
gflag = 1;
break;
case 'h':
if (isatty(STDOUT_FILENO))
display_man();
else
usage();
break; /* NOTREACHED */
case 'l':
lflag = 1;
break;
Expand Down
4 changes: 4 additions & 0 deletions quark-mon.8
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
.Op Fl C Ar filename
.Op Fl l Ar maxlength
.Op Fl m Ar maxnodes
.Nm quark-mon
.Fl h
.Nm quark-mon Fl V
.Sh DESCRIPTION
The
Expand Down Expand Up @@ -56,6 +58,8 @@ it is Elastic/ECS specific.
Use minimal aggregation, fork, exec and exit will
.Em not
be aggregated.
.It Fl h
Display this manpage.
.It Fl k
Attempt kprobe as the backend.
.It Fl l Ar maxlength
Expand Down
Loading

0 comments on commit e34ddae

Please sign in to comment.