analyze: allow --json= for the chid, blame and identify-tpm2 verbs (#43366)

verb_chid(), verb_blame() and verb_identify_tpm2() all render their
output via table_print_with_pager() with arg_json_format_flags, so JSON
output has been implemented for them since each verb was introduced.
None of them was ever added to the verb allowlist
that gates --json=, so e.g. systemd-analyze chid --json=pretty failed
with:

Option --json= is only supported for security, inspect-elf,
dlopen-metadata, ...

This adds them to the allowlist and the error message. After a sweep of
src/analyze/ for arg_json_format_flags, these are the only remaining
verbs that render through it but were not allowlisted.

has-tpm2 is deliberately not included: verb_has_tpm2() defers to
verb_has_tpm2_generic(), which writes plain text via printf() and has no
JSON support, so accepting --json= there would silently ignore it. The
table_print_with_pager() call in analyze-has-tpm2.c
belongs to verb_identify_tpm2(), which is what got allowlisted instead.

The chid gap went unnoticed because its TEST-65-ANALYZE coverage is
guarded behind a check for SMBIOS board_vendor and a non-container
environment, so it only runs on bare-metal/VM runners.
This commit is contained in:
Yu Watanabe
2026-08-13 00:06:07 +09:00
committed by GitHub
3 changed files with 12 additions and 3 deletions
+7 -1
View File
@@ -77,7 +77,8 @@ _systemd_analyze() {
)
local -A VERBS=(
[STANDALONE]='time blame unit-files unit-paths exit-status compare-versions timestamp timespan pcrs nvpcrs srk has-tpm2 identify-tpm2 smbios11 chid image-policy'
[STANDALONE]='time unit-files unit-paths compare-versions timestamp timespan srk has-tpm2 smbios11 image-policy'
[STANDALONE_JSON]='blame exit-status pcrs nvpcrs identify-tpm2 chid'
[CRITICAL_CHAIN]='critical-chain'
[DOT]='dot'
[DUMP]='dump'
@@ -153,6 +154,11 @@ _systemd_analyze() {
comps='--help --version --system --user --global --no-pager'
fi
elif __contains_word "$verb" ${VERBS[STANDALONE_JSON]}; then
if [[ $cur = -* ]]; then
comps='--help --version --system --user --global --no-pager --json=off --json=pretty --json=short'
fi
elif __contains_word "$verb" ${VERBS[CRITICAL_CHAIN]}; then
if [[ $cur = -* ]]; then
comps='--help --version --system --user --fuzz --no-pager'
+2 -2
View File
@@ -625,9 +625,9 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
"Option --offline= requires one or more units to perform a security review.");
if (arg_json_format_flags != SD_JSON_FORMAT_OFF &&
!STRPTR_IN_SET(verb, "security", "inspect-elf", "dlopen-metadata", "plot", "fdstore", "pcrs", "nvpcrs", "architectures", "capability", "exit-status"))
!STRPTR_IN_SET(verb, "security", "inspect-elf", "dlopen-metadata", "plot", "fdstore", "pcrs", "nvpcrs", "architectures", "capability", "exit-status", "chid", "blame", "identify-tpm2"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --json= is only supported for security, inspect-elf, dlopen-metadata, plot, fdstore, pcrs, nvpcrs, architectures, capability, exit-status right now.");
"Option --json= is only supported for security, inspect-elf, dlopen-metadata, plot, fdstore, pcrs, nvpcrs, architectures, capability, exit-status, chid, blame, identify-tpm2 right now.");
if (arg_threshold != 100 && !streq_ptr(verb, "security"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+3
View File
@@ -18,6 +18,7 @@ systemd-analyze time || :
systemd-analyze critical-chain || :
# blame
systemd-analyze blame
systemd-analyze blame --json=pretty
systemd-run --wait --user --pipe -M testuser@.host systemd-analyze blame --no-pager
(! systemd-analyze blame --global)
# plot
@@ -1139,6 +1140,8 @@ systemd-analyze security --instance=tmp systemd-growfs@.service
systemd-analyze has-tpm2 ||:
if systemd-analyze has-tpm2 -q ; then
echo "have tpm2"
systemd-analyze identify-tpm2
systemd-analyze identify-tpm2 --json=pretty
else
echo "have no tpm2"
fi