#include "analyze-exit-status.h"
#include "analyze-fdstore.h"
#include "analyze-filesystems.h"
+#include "analyze-has-tpm2.h"
#include "analyze-image-policy.h"
#include "analyze-inspect-elf.h"
#include "analyze-log-control.h"
#include "analyze-plot.h"
#include "analyze-security.h"
#include "analyze-service-watchdogs.h"
+#include "analyze-smbios11.h"
#include "analyze-srk.h"
#include "analyze-syscall-filter.h"
#include "analyze-time.h"
#include "verbs.h"
DotMode arg_dot = DEP_ALL;
+CapabilityMode arg_capability = CAPABILITY_LITERAL;
char **arg_dot_from_patterns = NULL, **arg_dot_to_patterns = NULL;
usec_t arg_fuzz = 0;
PagerFlags arg_pager_flags = 0;
RecursiveErrors arg_recursive_errors = _RECURSIVE_ERRORS_INVALID;
bool arg_man = true;
bool arg_generators = false;
+const char *arg_instance = "test_instance";
+double arg_svg_timescale = 1.0;
+bool arg_detailed_svg = false;
char *arg_root = NULL;
static char *arg_image = NULL;
char *arg_security_policy = NULL;
unsigned arg_iterations = 1;
usec_t arg_base_time = USEC_INFINITY;
char *arg_unit = NULL;
-JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
+sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF;
bool arg_quiet = false;
char *arg_profile = NULL;
bool arg_legend = true;
if (r < 0)
return log_oom();
- printf("%s [OPTIONS...] COMMAND ...\n\n"
- "%sProfile systemd, show unit dependencies, check unit files.%s\n"
- "\nCommands:\n"
+ printf("%1$s [OPTIONS...] COMMAND ...\n\n"
+ "%5$sProfile systemd, show unit dependencies, check unit files.%6$s\n"
+ "\n%3$sBoot Analysis:%4$s\n"
" [time] Print time required to boot the machine\n"
" blame Print list of running units ordered by\n"
" time to init\n"
" critical-chain [UNIT...] Print a tree of the time critical chain\n"
" of units\n"
+ "\n%3$sDependency Analysis:%4$s\n"
" plot Output SVG graphic showing service\n"
" initialization\n"
- " dot [UNIT...] Output dependency graph in %s format\n"
+ " dot [UNIT...] Output dependency graph in %7$s format\n"
" dump [PATTERN...] Output state serialization of service\n"
" manager\n"
+ "\n%3$sConfiguration Files and Search Paths:%4$s\n"
" cat-config NAME|PATH... Show configuration file and drop-ins\n"
" unit-files List files and symlinks for units\n"
" unit-paths List load directories for units\n"
+ "\n%3$sEnumerate OS Concepts:%4$s\n"
" exit-status [STATUS...] List exit status definitions\n"
" capability [CAP...] List capability definitions\n"
" syscall-filter [NAME...] List syscalls in seccomp filters\n"
" filesystems [NAME...] List known filesystems\n"
" architectures [NAME...] List known architectures\n"
+ " smbios11 List strings passed via SMBIOS Type #11\n"
+ "\n%3$sExpression Evaluation:%4$s\n"
" condition CONDITION... Evaluate conditions and asserts\n"
" compare-versions VERSION1 [OP] VERSION2\n"
" Compare two version strings\n"
- " verify FILE... Check unit files for correctness\n"
+ " image-policy POLICY... Analyze image policy string\n"
+ "\n%3$sClock & Time:%4$s\n"
" calendar SPEC... Validate repetitive calendar time\n"
" events\n"
" timestamp TIMESTAMP... Validate a timestamp\n"
" timespan SPAN... Validate a time span\n"
+ "\n%3$sUnit & Service Analysis:%4$s\n"
+ " verify FILE... Check unit files for correctness\n"
" security [UNIT...] Analyze security of unit\n"
- " inspect-elf FILE... Parse and print ELF package metadata\n"
- " malloc [D-BUS SERVICE...] Dump malloc stats of a D-Bus service\n"
" fdstore SERVICE... Show file descriptor store contents of service\n"
- " image-policy POLICY... Analyze image policy string\n"
+ " malloc [D-BUS SERVICE...] Dump malloc stats of a D-Bus service\n"
+ "\n%3$sExecutable Analysis:%4$s\n"
+ " inspect-elf FILE... Parse and print ELF package metadata\n"
+ "\n%3$sTPM Operations:%4$s\n"
+ " has-tpm2 Report whether TPM2 support is available\n"
" pcrs [PCR...] Show TPM2 PCRs and their names\n"
" srk [>FILE] Write TPM2 SRK (to FILE)\n"
- "\nOptions:\n"
+ "\n%3$sOptions:%4$s\n"
" --recursive-errors=MODE Control which units are verified\n"
" --offline=BOOL Perform a security review on unit file(s)\n"
" --threshold=N Exit with a non-zero status when overall\n"
" --man[=BOOL] Do [not] check for existence of man pages\n"
" --generators[=BOOL] Do [not] run unit generators\n"
" (requires privileges)\n"
+ " --instance=NAME Specify fallback instance name for template units\n"
" --iterations=N Show the specified number of iterations\n"
" --base-time=TIMESTAMP Calculate calendar times relative to\n"
" specified time\n"
" security review of the unit(s)\n"
" --unit=UNIT Evaluate conditions and asserts of unit\n"
" --table Output plot's raw time data as a table\n"
+ " --scale-svg=FACTOR Stretch x-axis of plot by FACTOR (default: 1.0)\n"
+ " --detailed Add more details to SVG plot,\n"
+ " e.g. show activation timestamps\n"
" -h --help Show this help\n"
" --version Show package version\n"
" -q --quiet Do not emit hints\n"
" --root=PATH Operate on an alternate filesystem root\n"
" --image=PATH Operate on disk image as filesystem root\n"
" --image-policy=POLICY Specify disk image dissection policy\n"
- "\nSee the %s for details.\n",
+ "\nSee the %2$s for details.\n",
program_invocation_short_name,
+ link,
+ ansi_underline(),
+ ansi_normal(),
ansi_highlight(),
ansi_normal(),
- dot_link,
- link);
+ dot_link);
/* When updating this list, including descriptions, apply changes to
* shell-completion/bash/systemd-analyze and shell-completion/zsh/_systemd-analyze too. */
ARG_NO_PAGER,
ARG_MAN,
ARG_GENERATORS,
+ ARG_INSTANCE,
ARG_ITERATIONS,
ARG_BASE_TIME,
ARG_RECURSIVE_ERRORS,
ARG_TABLE,
ARG_NO_LEGEND,
ARG_TLDR,
+ ARG_SCALE_FACTOR_SVG,
+ ARG_DETAILED_SVG,
};
static const struct option options[] = {
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "man", optional_argument, NULL, ARG_MAN },
{ "generators", optional_argument, NULL, ARG_GENERATORS },
+ { "instance", required_argument, NULL, ARG_INSTANCE },
{ "host", required_argument, NULL, 'H' },
{ "machine", required_argument, NULL, 'M' },
{ "iterations", required_argument, NULL, ARG_ITERATIONS },
{ "table", optional_argument, NULL, ARG_TABLE },
{ "no-legend", optional_argument, NULL, ARG_NO_LEGEND },
{ "tldr", no_argument, NULL, ARG_TLDR },
+ { "mask", no_argument, NULL, 'm' },
+ { "scale-svg", required_argument, NULL, ARG_SCALE_FACTOR_SVG },
+ { "detailed", no_argument, NULL, ARG_DETAILED_SVG },
{}
};
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "hH:M:U:q", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "hqH:M:U:m", options, NULL)) >= 0)
switch (c) {
case 'h':
return r;
break;
+ case ARG_INSTANCE:
+ arg_instance = optarg;
+ break;
+
case ARG_OFFLINE:
r = parse_boolean_argument("--offline", optarg, &arg_offline);
if (r < 0)
arg_cat_flags = CAT_TLDR;
break;
+ case 'm':
+ arg_capability = CAPABILITY_MASK;
+ break;
+
+ case ARG_SCALE_FACTOR_SVG:
+ arg_svg_timescale = strtod(optarg, NULL);
+ break;
+
+ case ARG_DETAILED_SVG:
+ arg_detailed_svg = true;
+ break;
+
case '?':
return -EINVAL;
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --offline= requires one or more units to perform a security review.");
- if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot", "fdstore", "pcrs", "architectures", "capability", "exit-status"))
+ if (arg_json_format_flags != SD_JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot", "fdstore", "pcrs", "architectures", "capability", "exit-status"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --json= is only supported for security, inspect-elf, plot, fdstore, pcrs, architectures, capability, exit-status right now.");
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --threshold= is only supported for security right now.");
- if (arg_runtime_scope == RUNTIME_SCOPE_GLOBAL &&
- !STR_IN_SET(argv[optind] ?: "time", "dot", "unit-paths", "verify"))
+ if (arg_runtime_scope == RUNTIME_SCOPE_GLOBAL && !streq_ptr(argv[optind], "unit-paths"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Option --global only makes sense with verbs dot, unit-paths, verify.");
+ "Option --global only makes sense with verb unit-paths.");
if (streq_ptr(argv[optind], "cat-config") && arg_runtime_scope == RUNTIME_SCOPE_USER)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --security-policy= is only supported for security.");
- if ((arg_root || arg_image) && (!STRPTR_IN_SET(argv[optind], "cat-config", "verify", "condition")) &&
+ if ((arg_root || arg_image) && (!STRPTR_IN_SET(argv[optind], "cat-config", "verify", "condition", "inspect-elf")) &&
(!(streq_ptr(argv[optind], "security") && arg_offline)))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Options --root= and --image= are only supported for cat-config, verify, condition and security when used with --offline= right now.");
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No conditions can be passed if --unit= is used.");
if ((!arg_legend && !STRPTR_IN_SET(argv[optind], "plot", "architectures")) ||
- (streq_ptr(argv[optind], "plot") && !arg_legend && !arg_table && FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF)))
+ (streq_ptr(argv[optind], "plot") && !arg_legend && !arg_table && FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF)))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --no-legend is only supported for plot with either --table or --json=.");
if (arg_table && !streq_ptr(argv[optind], "plot"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --table is only supported for plot right now.");
- if (arg_table && !FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF))
+ if (arg_table && !FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--table and --json= are mutually exclusive.");
+ if (arg_capability != CAPABILITY_LITERAL && !streq_ptr(argv[optind], "capability"))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --mask is only supported for capability.");
+
return 1; /* work to do */
}
{ "malloc", VERB_ANY, VERB_ANY, 0, verb_malloc },
{ "fdstore", 2, VERB_ANY, 0, verb_fdstore },
{ "image-policy", 2, 2, 0, verb_image_policy },
+ { "has-tpm2", VERB_ANY, 1, 0, verb_has_tpm2 },
{ "pcrs", VERB_ANY, VERB_ANY, 0, verb_pcrs },
{ "srk", VERB_ANY, 1, 0, verb_srk },
{ "architectures", VERB_ANY, VERB_ANY, 0, verb_architectures },
+ { "smbios11", VERB_ANY, 1, 0, verb_smbios11 },
{}
};
arg_image_policy,
DISSECT_IMAGE_GENERIC_ROOT |
DISSECT_IMAGE_RELAX_VAR_CHECK |
- DISSECT_IMAGE_READ_ONLY,
+ DISSECT_IMAGE_READ_ONLY |
+ DISSECT_IMAGE_ALLOW_USERSPACE_VERITY,
&mounted_dir,
/* ret_dir_fd= */ NULL,
&loop_device);