Compare commits

...

3 Commits

Author SHA1 Message Date
Lennart Poettering 92608d4420
Merge 262d1b115d into 52b0351a15 2024-11-20 00:42:31 -08:00
Lennart Poettering 262d1b115d analyze: drop conditioning of --no-legend and --json= on specific verbs
First of all, the list of verbs was badly out of date, in particular for
--no-legend. But second if it, I think such minor switches that alter
some detail of the output should not result in failure when the specific
tweak does not apply on some command. It should be fine for scripts and
suchlike to dumbly always pass --no-legend to all invocations of our
tools without having to consider if a specific subtool of ours actually
supports it or not.
2024-11-15 11:58:59 +01:00
Lennart Poettering ad55979e88 analyze: add verb for showing system's CHIDs
We have the code already, expose it in systemd-analyze too.

This should make it easier to debug the CHID use in the UKIs with
onboard tooling.
2024-11-15 11:58:47 +01:00
6 changed files with 180 additions and 8 deletions

View File

@ -205,6 +205,11 @@
<arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">smbios11</arg> <arg choice="plain">smbios11</arg>
</cmdsynopsis> </cmdsynopsis>
<cmdsynopsis>
<command>systemd-analyze</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">chid</arg>
</cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
<refsect1> <refsect1>
@ -1084,6 +1089,34 @@ io.systemd.credential:vmm.notify_socket=vsock-stream:2:254570042
<xi:include href="version-info.xml" xpointer="v257"/> <xi:include href="version-info.xml" xpointer="v257"/>
</refsect2> </refsect2>
<refsect2>
<title><command>systemd-analyze chid</command></title>
<para>Shows a list of Computer Hardware IDs (CHIDs) of the local system. These IDs identify the
system's computer hardware, based on SMBIOS data. See <ulink
url="https://learn.microsoft.com/en-us/windows-hardware/drivers/dashboard/using-chids">Using Computer
Hardware IDs (CHIDs)</ulink> for details about CHIDs.</para>
<example>
<title>Example output</title>
<programlisting>$ systemd-analyze chid
TYPE CHID
3 520537c0-3b59-504f-b062-9682ea236b21
4 edf05dc8-a53d-5b2c-8023-630bca2a2463
5 ebc6a4d9-ec48-537a-916b-c69fa4fdd814
6 5ebe4bba-f598-5e90-9ff2-9fd0d3211465
7 1a3fb835-b42a-5f9c-a38c-eff5bfd5c41d
8 2a831dce-8163-5bad-8406-435b8c752dd8
9 7c21c878-4a75-50f7-9816-21e811588da0
10 9a003537-bcc5-500e-b10a-8d8892e4fc64
11 bb9122bb-8a5c-50d2-a742-a85beb719909
13 bfc36935-5032-5987-a0a3-6311f01de33a
</programlisting>
</example>
<xi:include href="version-info.xml" xpointer="v257"/>
</refsect2>
</refsect1> </refsect1>
<refsect1> <refsect1>

136
src/analyze/analyze-chid.c Normal file
View File

@ -0,0 +1,136 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "analyze.h"
#include "analyze-chid.h"
#include "chid-fundamental.h"
#include "efi-api.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-table.h"
#include "parse-util.h"
#include "strv.h"
#include "utf8.h"
#include "virt.h"
static int parse_chid_type(const char *s, size_t *ret) {
unsigned u;
int r;
assert(s);
r = safe_atou(s, &u);
if (r < 0)
return r;
if (u >= CHID_TYPES_MAX)
return -ERANGE;
if (ret)
*ret = u;
return 0;
}
static int add_chid(Table *table, const EFI_GUID guids[static CHID_TYPES_MAX], size_t t) {
int r;
assert(table);
assert(guids);
assert(t < CHID_TYPES_MAX);
sd_id128_t id = efi_guid_to_id128(guids + t);
if (sd_id128_is_null(id))
return 0;
r = table_add_many(table,
TABLE_UINT, (unsigned) t,
TABLE_UUID, id);
if (r < 0)
return table_log_add_error(r);
return 0;
}
static void smbios_fields_free(char16_t *(*fields)[_CHID_SMBIOS_FIELDS_MAX]) {
assert(fields);
for (size_t t = 0; t < _CHID_SMBIOS_FIELDS_MAX; t++)
free((*fields)[t]);
}
int verb_chid(int argc, char *argv[], void *userdata) {
static const char *const smbios_files[_CHID_SMBIOS_FIELDS_MAX] = {
[CHID_SMBIOS_MANUFACTURER] = "sys_vendor",
[CHID_SMBIOS_FAMILY] = "product_family",
[CHID_SMBIOS_PRODUCT_NAME] = "product_name",
[CHID_SMBIOS_PRODUCT_SKU] = "product_sku",
[CHID_SMBIOS_BASEBOARD_MANUFACTURER] = "board_vendor",
[CHID_SMBIOS_BASEBOARD_PRODUCT] = "board_name",
};
_cleanup_(table_unrefp) Table *table = NULL;
int r;
if (detect_container() > 0)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Container environments do not have SMBIOS.");
table = table_new("type", "chid");
if (!table)
return log_oom();
(void) table_set_align_percent(table, table_get_cell(table, 0, 0), 100);
(void) table_set_align_percent(table, table_get_cell(table, 0, 1), 50);
_cleanup_close_ int smbios_fd = open("/sys/class/dmi/id", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (smbios_fd < 0)
return log_error_errno(errno, "Failed to open SMBIOS sysfs object: %m");
_cleanup_(smbios_fields_free) char16_t* smbios_fields[_CHID_SMBIOS_FIELDS_MAX] = {};
for (ChidSmbiosFields f = 0; f < _CHID_SMBIOS_FIELDS_MAX; f++) {
_cleanup_free_ char *buf = NULL;
size_t size;
r = read_virtual_file_at(smbios_fd, smbios_files[f], SIZE_MAX, &buf, &size);
if (r < 0)
return log_error_errno(r, "Failed to read SMBIOS field '%s': %m", smbios_files[f]);
if (size < 1 || buf[size-1] != '\n')
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected SMBIOS field '%s' to end in newline, but it doesn't, refusing.", smbios_files[f]);
size--;
smbios_fields[f] = utf8_to_utf16(buf, size);
if (!smbios_fields[f])
return log_oom();
}
EFI_GUID chids[CHID_TYPES_MAX] = {};
chid_calculate((const char16_t* const*) smbios_fields, chids);
if (strv_isempty(strv_skip(argv, 1)))
for (size_t t = 0; t < CHID_TYPES_MAX; t++) {
r = add_chid(table, chids, t);
if (r < 0)
return r;
}
else {
STRV_FOREACH(as, strv_skip(argv, 1)) {
size_t t;
r = parse_chid_type(*as, &t);
if (r < 0)
return log_error_errno(r, "Failed to pare CHID type: %s", *as);
r = add_chid(table, chids, t);
if (r < 0)
return r;
}
(void) table_set_sort(table, (size_t) 0);
}
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
if (r < 0)
return log_error_errno(r, "Failed to output table: %m");
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,4 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
int verb_chid(int argc, char *argv[], void *userdata);

View File

@ -18,6 +18,7 @@
#include "analyze-calendar.h" #include "analyze-calendar.h"
#include "analyze-capability.h" #include "analyze-capability.h"
#include "analyze-cat-config.h" #include "analyze-cat-config.h"
#include "analyze-chid.h"
#include "analyze-compare-versions.h" #include "analyze-compare-versions.h"
#include "analyze-condition.h" #include "analyze-condition.h"
#include "analyze-critical-chain.h" #include "analyze-critical-chain.h"
@ -219,6 +220,7 @@ static int help(int argc, char *argv[], void *userdata) {
" filesystems [NAME...] List known filesystems\n" " filesystems [NAME...] List known filesystems\n"
" architectures [NAME...] List known architectures\n" " architectures [NAME...] List known architectures\n"
" smbios11 List strings passed via SMBIOS Type #11\n" " smbios11 List strings passed via SMBIOS Type #11\n"
" chid List local CHIDs\n"
"\n%3$sExpression Evaluation:%4$s\n" "\n%3$sExpression Evaluation:%4$s\n"
" condition CONDITION... Evaluate conditions and asserts\n" " condition CONDITION... Evaluate conditions and asserts\n"
" compare-versions VERSION1 [OP] VERSION2\n" " compare-versions VERSION1 [OP] VERSION2\n"
@ -592,10 +594,6 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --offline= requires one or more units to perform a security review."); "Option --offline= requires one or more units to perform a security review.");
if (sd_json_format_enabled(arg_json_format_flags) && !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.");
if (arg_threshold != 100 && !streq_ptr(argv[optind], "security")) if (arg_threshold != 100 && !streq_ptr(argv[optind], "security"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --threshold= is only supported for security right now."); "Option --threshold= is only supported for security right now.");
@ -630,10 +628,6 @@ static int parse_argv(int argc, char *argv[]) {
if (streq_ptr(argv[optind], "condition") && arg_unit && optind < argc - 1) if (streq_ptr(argv[optind], "condition") && arg_unit && optind < argc - 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No conditions can be passed if --unit= is used."); 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 && !sd_json_format_enabled(arg_json_format_flags)))
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")) if (arg_table && !streq_ptr(argv[optind], "plot"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --table is only supported for plot right now."); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --table is only supported for plot right now.");
@ -690,6 +684,7 @@ static int run(int argc, char *argv[]) {
{ "srk", VERB_ANY, 1, 0, verb_srk }, { "srk", VERB_ANY, 1, 0, verb_srk },
{ "architectures", VERB_ANY, VERB_ANY, 0, verb_architectures }, { "architectures", VERB_ANY, VERB_ANY, 0, verb_architectures },
{ "smbios11", VERB_ANY, 1, 0, verb_smbios11 }, { "smbios11", VERB_ANY, 1, 0, verb_smbios11 },
{ "chid", VERB_ANY, VERB_ANY, 0, verb_chid },
{} {}
}; };

View File

@ -6,6 +6,7 @@ systemd_analyze_sources = files(
'analyze-calendar.c', 'analyze-calendar.c',
'analyze-capability.c', 'analyze-capability.c',
'analyze-cat-config.c', 'analyze-cat-config.c',
'analyze-chid.c',
'analyze-compare-versions.c', 'analyze-compare-versions.c',
'analyze-condition.c', 'analyze-condition.c',
'analyze-critical-chain.c', 'analyze-critical-chain.c',

View File

@ -990,6 +990,9 @@ systemd-analyze architectures uname
systemd-analyze smbios11 systemd-analyze smbios11
systemd-analyze smbios11 -q systemd-analyze smbios11 -q
systemd-analyze chid ||:
systemd-analyze chid --json=pretty ||:
systemd-analyze condition --instance=tmp --unit=systemd-growfs@.service systemd-analyze condition --instance=tmp --unit=systemd-growfs@.service
systemd-analyze verify --instance=tmp --man=no systemd-growfs@.service systemd-analyze verify --instance=tmp --man=no systemd-growfs@.service
systemd-analyze security --instance=tmp systemd-growfs@.service systemd-analyze security --instance=tmp systemd-growfs@.service