From 2f0733b819a4d5d8d50a269502f84a497e1c59df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9tur=20Ingi=20Egilsson?= Date: Wed, 28 Oct 2026 16:14:34 +0100 Subject: [PATCH] analyze: hint when man is not installed When "systemd-analyze verify" checks Documentation=man: entries it runs man(1). If man is not installed, the failure is reported as if the man page itself could not be shown: '(man)' failed with exit status 1. foo.service: Can't show systemd(1): Protocol error This is common on minimal images and containers that leave out man-db, and the message points at the documentation rather than at the missing tool. When showing the page fails, check whether man can be found and, if not, append a hint to the existing message: foo.service: Can't show systemd(1), man may not be installed, pass --man=no to skip: Protocol error The lookup happens only in the error path, so the successful case is untouched and execvp(3) still locates man, including through a relative PATH entry. verify still fails in this case, since the man pages were not checked. (cherry picked from commit 5ef99260c081010d62d95f215d6459e431d51cc0) (cherry picked from commit 7fcc2cc67b52f412d97890ef3c5add12724637d8) --- src/analyze/analyze-verify-util.c | 10 +++++++--- test/units/TEST-65-ANALYZE.sh | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/analyze/analyze-verify-util.c b/src/analyze/analyze-verify-util.c index d3951fff0d7..0af4ad33b9e 100644 --- a/src/analyze/analyze-verify-util.c +++ b/src/analyze/analyze-verify-util.c @@ -232,9 +232,13 @@ static int verify_documentation(Unit *u, bool check_man) { if (check_man && startswith(*p, "man:")) { k = show_man_page(*p + 4, true); if (k != 0) { - if (k < 0) - log_unit_error_errno(u, k, "Can't show %s: %m", *p + 4); - else { + if (k < 0) { + const char *hint = ""; + + if (find_executable("man", /* ret_filename= */ NULL) == -ENOENT) + hint = ", man may not be installed, pass --man=no to skip"; + log_unit_error_errno(u, k, "Can't show %s%s: %m", *p + 4, hint); + } else { log_unit_error(u, "Command 'man %s' failed with code %d", *p + 4, k); k = -ENOEXEC; } diff --git a/test/units/TEST-65-ANALYZE.sh b/test/units/TEST-65-ANALYZE.sh index 05a7b7f0c16..2cf0cb750f5 100755 --- a/test/units/TEST-65-ANALYZE.sh +++ b/test/units/TEST-65-ANALYZE.sh @@ -491,6 +491,19 @@ systemd-analyze verify /tmp/multi-exec-start.service echo 'ExecStart=command-should-not-exist' >>/tmp/multi-exec-start.service (! systemd-analyze verify /tmp/multi-exec-start.service) +# test that a missing man binary is reported as such, and that --man=no skips the check. +cat </tmp/man-documentation.service +[Unit] +Documentation=man:systemd(1) + +[Service] +Type=oneshot +ExecStart=/usr/bin/true +EOF +(! env PATH=/nonexistent "$(command -v systemd-analyze)" verify /tmp/man-documentation.service 2>/tmp/man-documentation.log) +grep "man may not be installed" /tmp/man-documentation.log >/dev/null +env PATH=/nonexistent "$(command -v systemd-analyze)" verify --man=no /tmp/man-documentation.service + # Prevent regression from #20233 where systemd-analyze will return nonzero exit codes on warnings # Unit file with warning "Unknown key name 'foo' in section 'Unit', ignoring"