Compare commits
15 Commits
80b9e60022
...
ff1ef4757e
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | ff1ef4757e | |
Daan De Meyer | 4a346b779a | |
Yu Watanabe | 0e42004f3e | |
Luca Boccassi | 6fd3496cfd | |
Daan De Meyer | bb486fe9df | |
Zbigniew Jędrzejewski-Szmek | 8da8996181 | |
Zbigniew Jędrzejewski-Szmek | fb1ad8c2df | |
Zbigniew Jędrzejewski-Szmek | 7a5997bad1 | |
Zbigniew Jędrzejewski-Szmek | 64e225d4c3 | |
Zbigniew Jędrzejewski-Szmek | d9cb7338f9 | |
Zbigniew Jędrzejewski-Szmek | 654fa34796 | |
Zbigniew Jędrzejewski-Szmek | 0638a45ec9 | |
Zbigniew Jędrzejewski-Szmek | e97f1ad4c9 | |
Zbigniew Jędrzejewski-Szmek | 48e5aec4a3 | |
Zbigniew Jędrzejewski-Szmek | 907a3b128c |
|
@ -38,9 +38,8 @@ SignExpectedPcr=yes
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
ExtraTrees=
|
ExtraTrees=
|
||||||
|
mkosi.extra.common
|
||||||
mkosi.crt:/usr/lib/verity.d/mkosi.crt # sysext verification key
|
mkosi.crt:/usr/lib/verity.d/mkosi.crt # sysext verification key
|
||||||
mkosi.leak-sanitizer-suppressions:/usr/lib/systemd/leak-sanitizer-suppressions
|
|
||||||
mkosi.coredump-journal-storage.conf:/usr/lib/systemd/coredump.conf.d/10-coredump-journal-storage.conf
|
|
||||||
%O/minimal-0.root-%a.raw:/usr/share/minimal_0.raw
|
%O/minimal-0.root-%a.raw:/usr/share/minimal_0.raw
|
||||||
%O/minimal-0.root-%a-verity.raw:/usr/share/minimal_0.verity
|
%O/minimal-0.root-%a-verity.raw:/usr/share/minimal_0.verity
|
||||||
%O/minimal-0.root-%a-verity-sig.raw:/usr/share/minimal_0.verity.sig
|
%O/minimal-0.root-%a-verity-sig.raw:/usr/share/minimal_0.verity.sig
|
||||||
|
|
|
@ -6,9 +6,7 @@ Include=
|
||||||
%D/mkosi.sanitizers
|
%D/mkosi.sanitizers
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
ExtraTrees=
|
ExtraTrees=%D/mkosi.extra.common
|
||||||
%D/mkosi.leak-sanitizer-suppressions:/usr/lib/systemd/leak-sanitizer-suppressions
|
|
||||||
%D/mkosi.coredump-journal-storage.conf:/usr/lib/systemd/coredump.conf.d/10-coredump-journal-storage.conf
|
|
||||||
|
|
||||||
Packages=
|
Packages=
|
||||||
findutils
|
findutils
|
||||||
|
|
|
@ -47,30 +47,25 @@ int verb_architectures(int argc, char *argv[], void *userdata) {
|
||||||
|
|
||||||
(void) table_hide_column_from_display(table, (size_t) 0);
|
(void) table_hide_column_from_display(table, (size_t) 0);
|
||||||
|
|
||||||
if (strv_isempty(strv_skip(argv, 1)))
|
char **args = strv_skip(argv, 1);
|
||||||
for (Architecture a = 0; a < _ARCHITECTURE_MAX; a++) {
|
if (args) {
|
||||||
r = add_arch(table, a);
|
STRV_FOREACH(arg, args) {
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
STRV_FOREACH(as, strv_skip(argv, 1)) {
|
|
||||||
Architecture a;
|
Architecture a;
|
||||||
|
|
||||||
if (streq(*as, "native"))
|
if (streq(*arg, "native"))
|
||||||
a = native_architecture();
|
a = native_architecture();
|
||||||
else if (streq(*as, "uname"))
|
else if (streq(*arg, "uname"))
|
||||||
a = uname_architecture();
|
a = uname_architecture();
|
||||||
else if (streq(*as, "secondary")) {
|
else if (streq(*arg, "secondary")) {
|
||||||
#ifdef ARCHITECTURE_SECONDARY
|
#ifdef ARCHITECTURE_SECONDARY
|
||||||
a = ARCHITECTURE_SECONDARY;
|
a = ARCHITECTURE_SECONDARY;
|
||||||
#else
|
#else
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No secondary architecture.");
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No secondary architecture.");
|
||||||
#endif
|
#endif
|
||||||
} else
|
} else
|
||||||
a = architecture_from_string(*as);
|
a = architecture_from_string(*arg);
|
||||||
if (a < 0)
|
if (a < 0)
|
||||||
return log_error_errno(a, "Architecture \"%s\" not known.", *as);
|
return log_error_errno(a, "Architecture \"%s\" not known.", *arg);
|
||||||
|
|
||||||
r = add_arch(table, a);
|
r = add_arch(table, a);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -78,7 +73,12 @@ int verb_architectures(int argc, char *argv[], void *userdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) table_set_sort(table, (size_t) 0);
|
(void) table_set_sort(table, (size_t) 0);
|
||||||
}
|
} else
|
||||||
|
for (Architecture a = 0; a < _ARCHITECTURE_MAX; a++) {
|
||||||
|
r = add_arch(table, a);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
|
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -9,12 +9,11 @@
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
|
||||||
int verb_cat_config(int argc, char *argv[], void *userdata) {
|
int verb_cat_config(int argc, char *argv[], void *userdata) {
|
||||||
char **list;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
pager_open(arg_pager_flags);
|
pager_open(arg_pager_flags);
|
||||||
|
|
||||||
list = strv_skip(argv, 1);
|
char **list = strv_skip(argv, 1);
|
||||||
STRV_FOREACH(arg, list) {
|
STRV_FOREACH(arg, list) {
|
||||||
const char *t = NULL;
|
const char *t = NULL;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,24 @@ int verb_exit_status(int argc, char *argv[], void *userdata) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to right-align status: %m");
|
return log_error_errno(r, "Failed to right-align status: %m");
|
||||||
|
|
||||||
if (strv_isempty(strv_skip(argv, 1)))
|
char **args = strv_skip(argv, 1);
|
||||||
|
if (args)
|
||||||
|
STRV_FOREACH(arg, args) {
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = exit_status_from_string(*arg);
|
||||||
|
if (status < 0)
|
||||||
|
return log_error_errno(status, "Invalid exit status \"%s\".", *arg);
|
||||||
|
|
||||||
|
assert(status >= 0 && (size_t) status < ELEMENTSOF(exit_status_mappings));
|
||||||
|
r = table_add_many(table,
|
||||||
|
TABLE_STRING, exit_status_mappings[status].name ?: "-",
|
||||||
|
TABLE_INT, status,
|
||||||
|
TABLE_STRING, exit_status_class(status) ?: "-");
|
||||||
|
if (r < 0)
|
||||||
|
return table_log_add_error(r);
|
||||||
|
}
|
||||||
|
else
|
||||||
for (size_t i = 0; i < ELEMENTSOF(exit_status_mappings); i++) {
|
for (size_t i = 0; i < ELEMENTSOF(exit_status_mappings); i++) {
|
||||||
if (!exit_status_mappings[i].name)
|
if (!exit_status_mappings[i].name)
|
||||||
continue;
|
continue;
|
||||||
|
@ -29,22 +46,6 @@ int verb_exit_status(int argc, char *argv[], void *userdata) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return table_log_add_error(r);
|
return table_log_add_error(r);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = exit_status_from_string(argv[i]);
|
|
||||||
if (status < 0)
|
|
||||||
return log_error_errno(status, "Invalid exit status \"%s\".", argv[i]);
|
|
||||||
|
|
||||||
assert(status >= 0 && (size_t) status < ELEMENTSOF(exit_status_mappings));
|
|
||||||
r = table_add_many(table,
|
|
||||||
TABLE_STRING, exit_status_mappings[status].name ?: "-",
|
|
||||||
TABLE_INT, status,
|
|
||||||
TABLE_STRING, exit_status_class(status) ?: "-");
|
|
||||||
if (r < 0)
|
|
||||||
return table_log_add_error(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
|
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -106,15 +106,30 @@ static void dump_filesystem_set(const FilesystemSet *set) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int verb_filesystems(int argc, char *argv[], void *userdata) {
|
int verb_filesystems(int argc, char *argv[], void *userdata) {
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
#if ! HAVE_LIBBPF
|
#if ! HAVE_LIBBPF
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Not compiled with libbpf support, sorry.");
|
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Not compiled with libbpf support, sorry.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pager_open(arg_pager_flags);
|
pager_open(arg_pager_flags);
|
||||||
|
|
||||||
if (strv_isempty(strv_skip(argv, 1))) {
|
char **args = strv_skip(argv, 1);
|
||||||
|
if (args)
|
||||||
|
STRV_FOREACH(name, args) {
|
||||||
|
if (name != args)
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
const FilesystemSet *set = filesystem_set_find(*name);
|
||||||
|
if (!set) {
|
||||||
|
/* make sure the error appears below normal output */
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||||
|
"Filesystem set \"%s\" not found.", *name);
|
||||||
|
}
|
||||||
|
|
||||||
|
dump_filesystem_set(set);
|
||||||
|
}
|
||||||
|
else {
|
||||||
_cleanup_set_free_ Set *kernel = NULL, *known = NULL;
|
_cleanup_set_free_ Set *kernel = NULL, *known = NULL;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
|
@ -126,27 +141,24 @@ int verb_filesystems(int argc, char *argv[], void *userdata) {
|
||||||
|
|
||||||
for (FilesystemGroups i = 0; i < _FILESYSTEM_SET_MAX; i++) {
|
for (FilesystemGroups i = 0; i < _FILESYSTEM_SET_MAX; i++) {
|
||||||
const FilesystemSet *set = filesystem_sets + i;
|
const FilesystemSet *set = filesystem_sets + i;
|
||||||
if (!first)
|
if (i > 0)
|
||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
dump_filesystem_set(set);
|
dump_filesystem_set(set);
|
||||||
filesystem_set_remove(kernel, set);
|
filesystem_set_remove(kernel, set);
|
||||||
if (i != FILESYSTEM_SET_KNOWN)
|
if (i != FILESYSTEM_SET_KNOWN)
|
||||||
filesystem_set_remove(known, set);
|
filesystem_set_remove(known, set);
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg_quiet) /* Let's not show the extra stuff in quiet mode */
|
if (arg_quiet) /* Let's not show the extra stuff in quiet mode */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!set_isempty(known)) {
|
if (!set_isempty(known)) {
|
||||||
_cleanup_free_ char **l = NULL;
|
|
||||||
|
|
||||||
printf("\n"
|
printf("\n"
|
||||||
"# %sUngrouped filesystems%s (known but not included in any of the groups except @known):\n",
|
"# %sUngrouped filesystems%s (known but not included in any of the groups except @known):\n",
|
||||||
ansi_highlight(), ansi_normal());
|
ansi_highlight(), ansi_normal());
|
||||||
|
|
||||||
l = set_get_strv(known);
|
_cleanup_free_ char **l = set_get_strv(known);
|
||||||
if (!l)
|
if (!l)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
@ -197,25 +209,7 @@ int verb_filesystems(int argc, char *argv[], void *userdata) {
|
||||||
STRV_FOREACH(filesystem, l)
|
STRV_FOREACH(filesystem, l)
|
||||||
printf("# %s\n", *filesystem);
|
printf("# %s\n", *filesystem);
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
STRV_FOREACH(name, strv_skip(argv, 1)) {
|
|
||||||
const FilesystemSet *set;
|
|
||||||
|
|
||||||
if (!first)
|
|
||||||
puts("");
|
|
||||||
|
|
||||||
set = filesystem_set_find(*name);
|
|
||||||
if (!set) {
|
|
||||||
/* make sure the error appears below normal output */
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
|
||||||
"Filesystem set \"%s\" not found.", *name);
|
|
||||||
}
|
|
||||||
|
|
||||||
dump_filesystem_set(set);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,12 @@ int verb_malloc(int argc, char *argv[], void *userdata) {
|
||||||
char **services = STRV_MAKE("org.freedesktop.systemd1");
|
char **services = STRV_MAKE("org.freedesktop.systemd1");
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!strv_isempty(strv_skip(argv, 1))) {
|
char **args = strv_skip(argv, 1);
|
||||||
services = strv_skip(argv, 1);
|
if (args) {
|
||||||
STRV_FOREACH(service, services)
|
STRV_FOREACH(service, args)
|
||||||
if (!service_name_is_valid(*service))
|
if (!service_name_is_valid(*service))
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "D-Bus service name '%s' is not valid.", *service);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "D-Bus service name '%s' is not valid.", *service);
|
||||||
|
services = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = acquire_bus(&bus, NULL);
|
r = acquire_bus(&bus, NULL);
|
||||||
|
|
|
@ -114,19 +114,14 @@ int verb_pcrs(int argc, char *argv[], void *userdata) {
|
||||||
if (!alg) /* hide hash column if we couldn't acquire it */
|
if (!alg) /* hide hash column if we couldn't acquire it */
|
||||||
(void) table_set_display(table, 0, 1);
|
(void) table_set_display(table, 0, 1);
|
||||||
|
|
||||||
if (strv_isempty(strv_skip(argv, 1)))
|
char **args = strv_skip(argv, 1);
|
||||||
for (uint32_t pi = 0; pi < _TPM2_PCR_INDEX_MAX_DEFINED; pi++) {
|
if (args) {
|
||||||
r = add_pcr_to_table(table, alg, pi);
|
STRV_FOREACH(arg, args) {
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
int pi;
|
int pi;
|
||||||
|
|
||||||
pi = tpm2_pcr_index_from_string(argv[i]);
|
pi = tpm2_pcr_index_from_string(*arg);
|
||||||
if (pi < 0)
|
if (pi < 0)
|
||||||
return log_error_errno(pi, "PCR index \"%s\" not known.", argv[i]);
|
return log_error_errno(pi, "PCR index \"%s\" not known.", *arg);
|
||||||
|
|
||||||
r = add_pcr_to_table(table, alg, pi);
|
r = add_pcr_to_table(table, alg, pi);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -134,7 +129,12 @@ int verb_pcrs(int argc, char *argv[], void *userdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) table_set_sort(table, (size_t) 0);
|
(void) table_set_sort(table, (size_t) 0);
|
||||||
}
|
} else
|
||||||
|
for (uint32_t pi = 0; pi < _TPM2_PCR_INDEX_MAX_DEFINED; pi++) {
|
||||||
|
r = add_pcr_to_table(table, alg, pi);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, /* show_header= */true);
|
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, /* show_header= */true);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -103,12 +103,30 @@ static void dump_syscall_filter(const SyscallFilterSet *set) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int verb_syscall_filters(int argc, char *argv[], void *userdata) {
|
int verb_syscall_filters(int argc, char *argv[], void *userdata) {
|
||||||
bool first = true;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
pager_open(arg_pager_flags);
|
pager_open(arg_pager_flags);
|
||||||
|
|
||||||
if (strv_isempty(strv_skip(argv, 1))) {
|
char **args = strv_skip(argv, 1);
|
||||||
|
if (args)
|
||||||
|
STRV_FOREACH(name, args) {
|
||||||
|
const SyscallFilterSet *set;
|
||||||
|
|
||||||
|
if (name != args)
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
set = syscall_filter_set_find(*name);
|
||||||
|
if (!set) {
|
||||||
|
/* make sure the error appears below normal output */
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||||
|
"Filter set \"%s\" not found.", *name);
|
||||||
|
}
|
||||||
|
|
||||||
|
dump_syscall_filter(set);
|
||||||
|
}
|
||||||
|
else {
|
||||||
_cleanup_set_free_ Set *kernel = NULL, *known = NULL;
|
_cleanup_set_free_ Set *kernel = NULL, *known = NULL;
|
||||||
int k = 0; /* explicit initialization to appease gcc */
|
int k = 0; /* explicit initialization to appease gcc */
|
||||||
|
|
||||||
|
@ -121,27 +139,24 @@ int verb_syscall_filters(int argc, char *argv[], void *userdata) {
|
||||||
|
|
||||||
for (int i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
|
for (int i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
|
||||||
const SyscallFilterSet *set = syscall_filter_sets + i;
|
const SyscallFilterSet *set = syscall_filter_sets + i;
|
||||||
if (!first)
|
if (i > 0)
|
||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
dump_syscall_filter(set);
|
dump_syscall_filter(set);
|
||||||
syscall_set_remove(kernel, set);
|
syscall_set_remove(kernel, set);
|
||||||
if (i != SYSCALL_FILTER_SET_KNOWN)
|
if (i != SYSCALL_FILTER_SET_KNOWN)
|
||||||
syscall_set_remove(known, set);
|
syscall_set_remove(known, set);
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg_quiet) /* Let's not show the extra stuff in quiet mode */
|
if (arg_quiet) /* Let's not show the extra stuff in quiet mode */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!set_isempty(known)) {
|
if (!set_isempty(known)) {
|
||||||
_cleanup_free_ char **l = NULL;
|
|
||||||
|
|
||||||
printf("\n"
|
printf("\n"
|
||||||
"# %sUngrouped System Calls%s (known but not included in any of the groups except @known):\n",
|
"# %sUngrouped System Calls%s (known but not included in any of the groups except @known):\n",
|
||||||
ansi_highlight(), ansi_normal());
|
ansi_highlight(), ansi_normal());
|
||||||
|
|
||||||
l = set_get_strv(known);
|
_cleanup_free_ char **l = set_get_strv(known);
|
||||||
if (!l)
|
if (!l)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
@ -157,13 +172,11 @@ int verb_syscall_filters(int argc, char *argv[], void *userdata) {
|
||||||
if (!arg_quiet)
|
if (!arg_quiet)
|
||||||
log_notice_errno(k, "# Not showing unlisted system calls, couldn't retrieve kernel system call list: %m");
|
log_notice_errno(k, "# Not showing unlisted system calls, couldn't retrieve kernel system call list: %m");
|
||||||
} else if (!set_isempty(kernel)) {
|
} else if (!set_isempty(kernel)) {
|
||||||
_cleanup_free_ char **l = NULL;
|
|
||||||
|
|
||||||
printf("\n"
|
printf("\n"
|
||||||
"# %sUnlisted System Calls%s (supported by the local kernel, but not included in any of the groups listed above):\n",
|
"# %sUnlisted System Calls%s (supported by the local kernel, but not included in any of the groups listed above):\n",
|
||||||
ansi_highlight(), ansi_normal());
|
ansi_highlight(), ansi_normal());
|
||||||
|
|
||||||
l = set_get_strv(kernel);
|
_cleanup_free_ char **l = set_get_strv(kernel);
|
||||||
if (!l)
|
if (!l)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
@ -172,25 +185,7 @@ int verb_syscall_filters(int argc, char *argv[], void *userdata) {
|
||||||
STRV_FOREACH(syscall, l)
|
STRV_FOREACH(syscall, l)
|
||||||
printf("# %s\n", *syscall);
|
printf("# %s\n", *syscall);
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
STRV_FOREACH(name, strv_skip(argv, 1)) {
|
|
||||||
const SyscallFilterSet *set;
|
|
||||||
|
|
||||||
if (!first)
|
|
||||||
puts("");
|
|
||||||
|
|
||||||
set = syscall_filter_set_find(*name);
|
|
||||||
if (!set) {
|
|
||||||
/* make sure the error appears below normal output */
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
|
||||||
"Filter set \"%s\" not found.", *name);
|
|
||||||
}
|
|
||||||
|
|
||||||
dump_syscall_filter(set);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,11 +75,12 @@ static int test_timestamp_one(const char *p) {
|
||||||
int verb_timestamp(int argc, char *argv[], void *userdata) {
|
int verb_timestamp(int argc, char *argv[], void *userdata) {
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
STRV_FOREACH(p, strv_skip(argv, 1)) {
|
char **args = strv_skip(argv, 1);
|
||||||
RET_GATHER(r, test_timestamp_one(*p));
|
STRV_FOREACH(arg, args) {
|
||||||
|
if (arg != args)
|
||||||
|
puts("");
|
||||||
|
|
||||||
if (p[1])
|
RET_GATHER(r, test_timestamp_one(*arg));
|
||||||
putchar('\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -956,14 +956,16 @@ bool strv_fnmatch_full(
|
||||||
}
|
}
|
||||||
|
|
||||||
char** strv_skip(char **l, size_t n) {
|
char** strv_skip(char **l, size_t n) {
|
||||||
|
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
if (strv_isempty(l))
|
if (strv_isempty(l))
|
||||||
return l;
|
return NULL;
|
||||||
|
|
||||||
l++, n--;
|
l++, n--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* To simplify callers, always return NULL instead of a zero-item array. */
|
||||||
|
if (strv_isempty(l))
|
||||||
|
return NULL;
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,9 +547,21 @@ static int tree(int argc, char **argv, void *userdata) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (argc <= 1) {
|
char **args = strv_skip(argv, 1);
|
||||||
|
if (args)
|
||||||
|
STRV_FOREACH(arg, args) {
|
||||||
|
if (arg != args)
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
if (args[1]) {
|
||||||
|
pager_open(arg_pager_flags);
|
||||||
|
printf("Service %s%s%s:\n", ansi_highlight(), *arg, ansi_normal());
|
||||||
|
}
|
||||||
|
|
||||||
|
RET_GATHER(r, tree_one(bus, *arg));
|
||||||
|
}
|
||||||
|
else {
|
||||||
_cleanup_strv_free_ char **names = NULL;
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
bool not_first = false;
|
|
||||||
|
|
||||||
r = sd_bus_list_names(bus, &names, NULL);
|
r = sd_bus_list_names(bus, &names, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -557,42 +569,21 @@ static int tree(int argc, char **argv, void *userdata) {
|
||||||
|
|
||||||
pager_open(arg_pager_flags);
|
pager_open(arg_pager_flags);
|
||||||
|
|
||||||
STRV_FOREACH(i, names) {
|
STRV_FOREACH(name, names) {
|
||||||
int q;
|
if (!arg_unique && (*name)[0] == ':')
|
||||||
|
|
||||||
if (!arg_unique && (*i)[0] == ':')
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!arg_acquired && (*i)[0] == ':')
|
if (!arg_acquired && (*name)[0] == ':')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (not_first)
|
if (name != names)
|
||||||
printf("\n");
|
puts("");
|
||||||
|
|
||||||
printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
|
printf("Service %s%s%s:\n", ansi_highlight(), *name, ansi_normal());
|
||||||
|
|
||||||
q = tree_one(bus, *i);
|
RET_GATHER(r, tree_one(bus, *name));
|
||||||
if (q < 0 && r >= 0)
|
|
||||||
r = q;
|
|
||||||
|
|
||||||
not_first = true;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
STRV_FOREACH(i, strv_skip(argv, 1)) {
|
|
||||||
int q;
|
|
||||||
|
|
||||||
if (i > argv+1)
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (argv[2]) {
|
|
||||||
pager_open(arg_pager_flags);
|
|
||||||
printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
|
|
||||||
}
|
|
||||||
|
|
||||||
q = tree_one(bus, *i);
|
|
||||||
if (q < 0 && r >= 0)
|
|
||||||
r = q;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -663,8 +663,9 @@ static int add_root_mount(void) {
|
||||||
|
|
||||||
r = efi_loader_get_device_part_uuid(NULL);
|
r = efi_loader_get_device_part_uuid(NULL);
|
||||||
if (r == -ENOENT) {
|
if (r == -ENOENT) {
|
||||||
log_notice("EFI loader partition unknown, exiting.\n"
|
log_notice("EFI loader partition unknown, not processing %s.\n"
|
||||||
"(The boot loader did not set EFI variable LoaderDevicePartUUID.)");
|
"(The boot loader did not set EFI variable LoaderDevicePartUUID.)",
|
||||||
|
in_initrd() ? "/sysroot" : "/");
|
||||||
return 0;
|
return 0;
|
||||||
} else if (r < 0)
|
} else if (r < 0)
|
||||||
return log_error_errno(r, "Failed to read loader partition UUID: %m");
|
return log_error_errno(r, "Failed to read loader partition UUID: %m");
|
||||||
|
|
|
@ -691,122 +691,110 @@ static void dump_home_record(UserRecord *hr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **mangle_user_list(char **list, char ***ret_allocated) {
|
static int inspect_home(sd_bus *bus, const char *name) {
|
||||||
_cleanup_free_ char *myself = NULL;
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
char **l;
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||||
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||||
|
_cleanup_(user_record_unrefp) UserRecord *hr = NULL;
|
||||||
|
const char *json;
|
||||||
|
int incomplete;
|
||||||
|
uid_t uid;
|
||||||
|
int r;
|
||||||
|
|
||||||
if (!strv_isempty(list)) {
|
r = parse_uid(name, &uid);
|
||||||
*ret_allocated = NULL;
|
if (r < 0) {
|
||||||
return list;
|
if (!valid_user_group_name(name, 0))
|
||||||
}
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid user name '%s'.", name);
|
||||||
|
|
||||||
myself = getusername_malloc();
|
r = bus_call_method(bus, bus_mgr, "GetUserRecordByName", &error, &reply, "s", name);
|
||||||
if (!myself)
|
} else
|
||||||
return NULL;
|
r = bus_call_method(bus, bus_mgr, "GetUserRecordByUID", &error, &reply, "u", (uint32_t) uid);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to inspect home: %s", bus_error_message(&error, r));
|
||||||
|
|
||||||
l = new(char*, 2);
|
r = sd_bus_message_read(reply, "sbo", &json, &incomplete, NULL);
|
||||||
if (!l)
|
if (r < 0)
|
||||||
return NULL;
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
l[0] = TAKE_PTR(myself);
|
r = sd_json_parse(json, SD_JSON_PARSE_SENSITIVE, &v, NULL, NULL);
|
||||||
l[1] = NULL;
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse JSON identity: %m");
|
||||||
|
|
||||||
*ret_allocated = l;
|
hr = user_record_new();
|
||||||
return l;
|
if (!hr)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
hr->incomplete = incomplete;
|
||||||
|
dump_home_record(hr);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int inspect_home(int argc, char *argv[], void *userdata) {
|
static int inspect_homes(int argc, char *argv[], void *userdata) {
|
||||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||||
_cleanup_strv_free_ char **mangled_list = NULL;
|
int r;
|
||||||
int r, ret = 0;
|
|
||||||
char **items;
|
|
||||||
|
|
||||||
pager_open(arg_pager_flags);
|
|
||||||
|
|
||||||
r = acquire_bus(&bus);
|
r = acquire_bus(&bus);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
items = mangle_user_list(strv_skip(argv, 1), &mangled_list);
|
pager_open(arg_pager_flags);
|
||||||
if (!items)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
STRV_FOREACH(i, items) {
|
char **args = strv_skip(argv, 1);
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
if (args) {
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
_cleanup_free_ char *myself = getusername_malloc();
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
if (!myself)
|
||||||
_cleanup_(user_record_unrefp) UserRecord *hr = NULL;
|
|
||||||
const char *json;
|
|
||||||
int incomplete;
|
|
||||||
uid_t uid;
|
|
||||||
|
|
||||||
r = parse_uid(*i, &uid);
|
|
||||||
if (r < 0) {
|
|
||||||
if (!valid_user_group_name(*i, 0)) {
|
|
||||||
log_error("Invalid user name '%s'.", *i);
|
|
||||||
if (ret == 0)
|
|
||||||
ret = -EINVAL;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = bus_call_method(bus, bus_mgr, "GetUserRecordByName", &error, &reply, "s", *i);
|
|
||||||
} else
|
|
||||||
r = bus_call_method(bus, bus_mgr, "GetUserRecordByUID", &error, &reply, "u", (uint32_t) uid);
|
|
||||||
if (r < 0) {
|
|
||||||
log_error_errno(r, "Failed to inspect home: %s", bus_error_message(&error, r));
|
|
||||||
if (ret == 0)
|
|
||||||
ret = r;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_bus_message_read(reply, "sbo", &json, &incomplete, NULL);
|
|
||||||
if (r < 0) {
|
|
||||||
bus_log_parse_error(r);
|
|
||||||
if (ret == 0)
|
|
||||||
ret = r;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_json_parse(json, SD_JSON_PARSE_SENSITIVE, &v, NULL, NULL);
|
|
||||||
if (r < 0) {
|
|
||||||
log_error_errno(r, "Failed to parse JSON identity: %m");
|
|
||||||
if (ret == 0)
|
|
||||||
ret = r;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = user_record_new();
|
|
||||||
if (!hr)
|
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
|
return inspect_home(bus, myself);
|
||||||
if (r < 0) {
|
} else {
|
||||||
if (ret == 0)
|
STRV_FOREACH(arg, args)
|
||||||
ret = r;
|
RET_GATHER(r, inspect_home(bus, *arg));
|
||||||
|
|
||||||
continue;
|
return r;
|
||||||
}
|
|
||||||
|
|
||||||
hr->incomplete = incomplete;
|
|
||||||
dump_home_record(hr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int authenticate_home(int argc, char *argv[], void *userdata) {
|
static int authenticate_home(sd_bus *bus, const char *name) {
|
||||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
_cleanup_(user_record_unrefp) UserRecord *secret = NULL;
|
||||||
_cleanup_strv_free_ char **mangled_list = NULL;
|
int r;
|
||||||
int r, ret = 0;
|
|
||||||
char **items;
|
|
||||||
|
|
||||||
items = mangle_user_list(strv_skip(argv, 1), &mangled_list);
|
r = acquire_passed_secrets(name, &secret);
|
||||||
if (!items)
|
if (r < 0)
|
||||||
return log_oom();
|
return r;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||||
|
|
||||||
|
r = bus_message_new_method_call(bus, &m, bus_mgr, "AuthenticateHome");
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_append(m, "s", name);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
|
r = bus_message_append_secret(m, secret);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, NULL);
|
||||||
|
if (r < 0) {
|
||||||
|
r = handle_generic_user_record_error(name, secret, &error, r, false);
|
||||||
|
if (r >= 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int authenticate_homes(int argc, char *argv[], void *userdata) {
|
||||||
|
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
r = acquire_bus(&bus);
|
r = acquire_bus(&bus);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -814,44 +802,19 @@ static int authenticate_home(int argc, char *argv[], void *userdata) {
|
||||||
|
|
||||||
(void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
|
(void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
|
||||||
|
|
||||||
STRV_FOREACH(i, items) {
|
char **args = strv_skip(argv, 1);
|
||||||
_cleanup_(user_record_unrefp) UserRecord *secret = NULL;
|
if (args) {
|
||||||
|
_cleanup_free_ char *myself = getusername_malloc();
|
||||||
|
if (!myself)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
r = acquire_passed_secrets(*i, &secret);
|
return authenticate_home(bus, myself);
|
||||||
if (r < 0)
|
} else {
|
||||||
return r;
|
STRV_FOREACH(arg, args)
|
||||||
|
RET_GATHER(r, authenticate_home(bus, *arg));
|
||||||
|
|
||||||
for (;;) {
|
return r;
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
|
||||||
|
|
||||||
r = bus_message_new_method_call(bus, &m, bus_mgr, "AuthenticateHome");
|
|
||||||
if (r < 0)
|
|
||||||
return bus_log_create_error(r);
|
|
||||||
|
|
||||||
r = sd_bus_message_append(m, "s", *i);
|
|
||||||
if (r < 0)
|
|
||||||
return bus_log_create_error(r);
|
|
||||||
|
|
||||||
r = bus_message_append_secret(m, secret);
|
|
||||||
if (r < 0)
|
|
||||||
return bus_log_create_error(r);
|
|
||||||
|
|
||||||
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, NULL);
|
|
||||||
if (r < 0) {
|
|
||||||
r = handle_generic_user_record_error(*i, secret, &error, r, false);
|
|
||||||
if (r < 0) {
|
|
||||||
if (ret == 0)
|
|
||||||
ret = r;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_last_change(sd_json_variant **v, bool with_password, bool override) {
|
static int update_last_change(sd_json_variant **v, bool with_password, bool override) {
|
||||||
|
@ -4727,8 +4690,8 @@ static int run(int argc, char *argv[]) {
|
||||||
{ "list", VERB_ANY, 1, VERB_DEFAULT, list_homes },
|
{ "list", VERB_ANY, 1, VERB_DEFAULT, list_homes },
|
||||||
{ "activate", 2, VERB_ANY, 0, activate_home },
|
{ "activate", 2, VERB_ANY, 0, activate_home },
|
||||||
{ "deactivate", 2, VERB_ANY, 0, deactivate_home },
|
{ "deactivate", 2, VERB_ANY, 0, deactivate_home },
|
||||||
{ "inspect", VERB_ANY, VERB_ANY, 0, inspect_home },
|
{ "inspect", VERB_ANY, VERB_ANY, 0, inspect_homes },
|
||||||
{ "authenticate", VERB_ANY, VERB_ANY, 0, authenticate_home },
|
{ "authenticate", VERB_ANY, VERB_ANY, 0, authenticate_homes },
|
||||||
{ "create", VERB_ANY, 2, 0, create_home },
|
{ "create", VERB_ANY, 2, 0, create_home },
|
||||||
{ "remove", 2, VERB_ANY, 0, remove_home },
|
{ "remove", 2, VERB_ANY, 0, remove_home },
|
||||||
{ "update", VERB_ANY, 2, 0, update_home },
|
{ "update", VERB_ANY, 2, 0, update_home },
|
||||||
|
|
|
@ -133,17 +133,7 @@ static int verb_show(int argc, char **argv, void *userdata) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
argv = strv_skip(argv, 1);
|
argv = strv_skip(argv, 1);
|
||||||
if (strv_isempty(argv)) {
|
if (argv)
|
||||||
if (!sd_id128_is_null(arg_app))
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"'show --app-specific=' can only be used with explicit UUID input.");
|
|
||||||
|
|
||||||
for (const GptPartitionType *e = gpt_partition_type_table; e->name; e++) {
|
|
||||||
r = show_one(&table, e->name, e->uuid, e == gpt_partition_type_table);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
STRV_FOREACH(p, argv) {
|
STRV_FOREACH(p, argv) {
|
||||||
sd_id128_t uuid;
|
sd_id128_t uuid;
|
||||||
const char *id = NULL;
|
const char *id = NULL;
|
||||||
|
@ -171,6 +161,17 @@ static int verb_show(int argc, char **argv, void *userdata) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (!sd_id128_is_null(arg_app))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"'show --app-specific=' can only be used with explicit UUID input.");
|
||||||
|
|
||||||
|
for (const GptPartitionType *e = gpt_partition_type_table; e->name; e++) {
|
||||||
|
r = show_one(&table, e->name, e->uuid, e == gpt_partition_type_table);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (table) {
|
if (table) {
|
||||||
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
|
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
|
||||||
|
|
|
@ -152,11 +152,13 @@ static int do_execute(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEBUG_LOGGING) {
|
if (DEBUG_LOGGING) {
|
||||||
_cleanup_free_ char *args = NULL;
|
_cleanup_free_ char *s = NULL;
|
||||||
if (argv)
|
|
||||||
args = quote_command_line(strv_skip(argv, 1), SHELL_ESCAPE_EMPTY);
|
|
||||||
|
|
||||||
log_debug("About to execute %s%s%s", t, argv ? " " : "", argv ? strnull(args) : "");
|
char **args = strv_skip(argv, 1);
|
||||||
|
if (args)
|
||||||
|
s = quote_command_line(args, SHELL_ESCAPE_EMPTY);
|
||||||
|
|
||||||
|
log_debug("About to execute %s%s%s", t, args ? " " : "", args ? strnull(s) : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_SET(flags, EXEC_DIR_WARN_WORLD_WRITABLE)) {
|
if (FLAGS_SET(flags, EXEC_DIR_WARN_WORLD_WRITABLE)) {
|
||||||
|
|
|
@ -172,14 +172,14 @@ int verb_list_dependencies(int argc, char *argv[], void *userdata) {
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
patterns = strv_skip(argv, 1);
|
patterns = strv_skip(argv, 1);
|
||||||
if (strv_isempty(patterns)) {
|
if (patterns) {
|
||||||
units = strv_new(SPECIAL_DEFAULT_TARGET);
|
|
||||||
if (!units)
|
|
||||||
return log_oom();
|
|
||||||
} else {
|
|
||||||
r = expand_unit_names(bus, patterns, NULL, &units, NULL);
|
r = expand_unit_names(bus, patterns, NULL, &units, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to expand names: %m");
|
return log_error_errno(r, "Failed to expand names: %m");
|
||||||
|
} else {
|
||||||
|
units = strv_new(SPECIAL_DEFAULT_TARGET);
|
||||||
|
if (!units)
|
||||||
|
return log_oom();
|
||||||
}
|
}
|
||||||
|
|
||||||
pager_open(arg_pager_flags);
|
pager_open(arg_pager_flags);
|
||||||
|
|
|
@ -20,15 +20,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int run(int argc, char **argv) {
|
static int run(int argc, char **argv) {
|
||||||
_cleanup_close_ int fd = -EBADF;
|
|
||||||
char **args = strv_skip(argv, 1);
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
test_setup_logging(LOG_DEBUG);
|
test_setup_logging(LOG_DEBUG);
|
||||||
|
|
||||||
args = !strv_isempty(args) ? args : STRV_MAKE("/bin/true");
|
char **args = strv_skip(argv, 1) ?: STRV_MAKE("/bin/true");
|
||||||
|
|
||||||
fd = open(args[0], O_RDONLY | O_CLOEXEC);
|
_cleanup_close_ int fd = open(args[0], O_RDONLY | O_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return log_error_errno(errno, "open(%s) failed: %m", args[0]);
|
return log_error_errno(errno, "open(%s) failed: %m", args[0]);
|
||||||
|
|
||||||
|
|
|
@ -1004,17 +1004,21 @@ TEST(strv_skip) {
|
||||||
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
|
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
|
||||||
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
|
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
|
||||||
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
|
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
|
||||||
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL));
|
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, NULL);
|
||||||
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL));
|
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, NULL);
|
||||||
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL));
|
test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, NULL);
|
||||||
|
|
||||||
test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
|
test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
|
||||||
test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL));
|
test_strv_skip_one(STRV_MAKE("quux"), 1, NULL);
|
||||||
test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL));
|
test_strv_skip_one(STRV_MAKE("quux"), 55, NULL);
|
||||||
|
|
||||||
test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL));
|
test_strv_skip_one(STRV_MAKE(NULL), 0, NULL);
|
||||||
test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL));
|
test_strv_skip_one(STRV_MAKE(NULL), 1, NULL);
|
||||||
test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL));
|
test_strv_skip_one(STRV_MAKE(NULL), 55, NULL);
|
||||||
|
|
||||||
|
test_strv_skip_one(NULL, 0, NULL);
|
||||||
|
test_strv_skip_one(NULL, 1, NULL);
|
||||||
|
test_strv_skip_one(NULL, 55, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(strv_extend_n) {
|
TEST(strv_extend_n) {
|
||||||
|
|
|
@ -35,7 +35,10 @@ static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) {
|
||||||
"%s: expected: load [module…]", argv[0]);
|
"%s: expected: load [module…]", argv[0]);
|
||||||
|
|
||||||
char **modules = strv_skip(argv, 2);
|
char **modules = strv_skip(argv, 2);
|
||||||
if (strv_isempty(modules)) {
|
if (modules)
|
||||||
|
STRV_FOREACH(module, modules)
|
||||||
|
(void) module_load_and_warn(ctx, *module, /* verbose = */ false);
|
||||||
|
else {
|
||||||
const char *modalias;
|
const char *modalias;
|
||||||
|
|
||||||
r = sd_device_get_property_value(dev, "MODALIAS", &modalias);
|
r = sd_device_get_property_value(dev, "MODALIAS", &modalias);
|
||||||
|
@ -43,9 +46,7 @@ static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) {
|
||||||
return log_device_warning_errno(dev, r, "Failed to read property \"MODALIAS\": %m");
|
return log_device_warning_errno(dev, r, "Failed to read property \"MODALIAS\": %m");
|
||||||
|
|
||||||
(void) module_load_and_warn(ctx, modalias, /* verbose = */ false);
|
(void) module_load_and_warn(ctx, modalias, /* verbose = */ false);
|
||||||
} else
|
}
|
||||||
STRV_FOREACH(module, modules)
|
|
||||||
(void) module_load_and_warn(ctx, *module, /* verbose = */ false);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -630,7 +630,7 @@ static int run(int argc, char **argv) {
|
||||||
} else {
|
} else {
|
||||||
fd = find_source_vc(&vc, &idx);
|
fd = find_source_vc(&vc, &idx);
|
||||||
if (fd < 0 && fd != -EBUSY)
|
if (fd < 0 && fd != -EBUSY)
|
||||||
return log_error_errno(fd, "No usable source console found: %m");
|
return log_error_errno(fd, "No virtual console that can be configured found: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
utf8 = is_locale_utf8();
|
utf8 = is_locale_utf8();
|
||||||
|
@ -640,7 +640,7 @@ static int run(int argc, char **argv) {
|
||||||
/* We found only busy VCs, which might happen during the boot process when the boot splash is
|
/* We found only busy VCs, which might happen during the boot process when the boot splash is
|
||||||
* displayed on the only allocated VC. In this case we don't interfere and avoid initializing
|
* displayed on the only allocated VC. In this case we don't interfere and avoid initializing
|
||||||
* the VC partially as some operations are likely to fail. */
|
* the VC partially as some operations are likely to fail. */
|
||||||
log_notice("All allocated VCs are currently busy, skipping initialization of font and keyboard settings.");
|
log_notice("All allocated virtual consoles are busy, will not configure key mapping and font.");
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,7 +664,7 @@ static int run(int argc, char **argv) {
|
||||||
setup_remaining_vcs(fd, idx, utf8);
|
setup_remaining_vcs(fd, idx, utf8);
|
||||||
else
|
else
|
||||||
log_full(r == EX_OSERR ? LOG_NOTICE : LOG_WARNING,
|
log_full(r == EX_OSERR ? LOG_NOTICE : LOG_WARNING,
|
||||||
"Setting source virtual console failed, ignoring remaining ones.");
|
"Configuration of first virtual console failed, ignoring remaining ones.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return IN_SET(r, 0, EX_OSERR) && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
return IN_SET(r, 0, EX_OSERR) && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
integration_tests += [
|
integration_tests += [
|
||||||
integration_test_template + {
|
integration_test_template + {
|
||||||
'name' : fs.name(meson.current_source_dir()),
|
'name' : fs.name(meson.current_source_dir()),
|
||||||
|
'coredump-exclude-regex' : '/(bash|python3.[0-9]+|systemd-executor)$',
|
||||||
'cmdline' : integration_test_template['cmdline'] + [
|
'cmdline' : integration_test_template['cmdline'] + [
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ integration_tests += [
|
||||||
integration_test_template + {
|
integration_test_template + {
|
||||||
'name' : fs.name(meson.current_source_dir()),
|
'name' : fs.name(meson.current_source_dir()),
|
||||||
'unit' : files('TEST-16-EXTEND-TIMEOUT.service'),
|
'unit' : files('TEST-16-EXTEND-TIMEOUT.service'),
|
||||||
|
'coredump-exclude-regex' : '/(bash|sleep)$',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -4,5 +4,6 @@ integration_tests += [
|
||||||
integration_test_template + {
|
integration_test_template + {
|
||||||
'name' : fs.name(meson.current_source_dir()),
|
'name' : fs.name(meson.current_source_dir()),
|
||||||
'vm' : true,
|
'vm' : true,
|
||||||
|
'coredump-exclude-regex' : '/(sleep|udevadm)$',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,5 +3,6 @@
|
||||||
integration_tests += [
|
integration_tests += [
|
||||||
integration_test_template + {
|
integration_test_template + {
|
||||||
'name' : fs.name(meson.current_source_dir()),
|
'name' : fs.name(meson.current_source_dir()),
|
||||||
|
'coredump-exclude-regex' : '/(sleep|bash|systemd-notify)$',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,5 +4,7 @@ integration_tests += [
|
||||||
integration_test_template + {
|
integration_test_template + {
|
||||||
'name' : fs.name(meson.current_source_dir()),
|
'name' : fs.name(meson.current_source_dir()),
|
||||||
'priority' : 10,
|
'priority' : 10,
|
||||||
|
# TODO: Remove when https://github.com/systemd/systemd/issues/35335 is fixed.
|
||||||
|
'coredump-exclude-regex' : '/systemd-localed',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,6 +5,7 @@ integration_tests += [
|
||||||
'name' : fs.name(meson.current_source_dir()),
|
'name' : fs.name(meson.current_source_dir()),
|
||||||
'storage': 'persistent',
|
'storage': 'persistent',
|
||||||
'vm' : true,
|
'vm' : true,
|
||||||
|
'coredump-exclude-regex' : '/(test-usr-dump|test-dump|bash)$',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
@ -32,6 +33,59 @@ ExecStart=false
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def process_coredumps(args: argparse.Namespace, journal_file: Path) -> bool:
|
||||||
|
# Collect executable paths of all coredumps and filter out the expected ones.
|
||||||
|
|
||||||
|
if args.coredump_exclude_regex:
|
||||||
|
exclude_regex = re.compile(args.coredump_exclude_regex)
|
||||||
|
else:
|
||||||
|
exclude_regex = None
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
[
|
||||||
|
args.mkosi,
|
||||||
|
'--directory', os.fspath(args.meson_source_dir),
|
||||||
|
'--extra-search-path', os.fspath(args.meson_build_dir),
|
||||||
|
'sandbox',
|
||||||
|
'coredumpctl',
|
||||||
|
'--file', journal_file,
|
||||||
|
'--json=short',
|
||||||
|
],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
text=True,
|
||||||
|
) # fmt: skip
|
||||||
|
|
||||||
|
# coredumpctl returns a non-zero exit status if there are no coredumps.
|
||||||
|
if result.returncode != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
coredumps = json.loads(result.stdout)
|
||||||
|
|
||||||
|
coredumps = [
|
||||||
|
coredump for coredump in coredumps if not exclude_regex or not exclude_regex.search(coredump['exe'])
|
||||||
|
]
|
||||||
|
|
||||||
|
if not coredumps:
|
||||||
|
return False
|
||||||
|
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
args.mkosi,
|
||||||
|
'--directory', os.fspath(args.meson_source_dir),
|
||||||
|
'--extra-search-path', os.fspath(args.meson_build_dir),
|
||||||
|
'sandbox',
|
||||||
|
'coredumpctl',
|
||||||
|
'--file', journal_file,
|
||||||
|
'--no-pager',
|
||||||
|
'info',
|
||||||
|
*(coredump['exe'] for coredump in coredumps),
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
) # fmt: skip
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument('--mkosi', required=True)
|
parser.add_argument('--mkosi', required=True)
|
||||||
|
@ -44,6 +98,7 @@ def main() -> None:
|
||||||
parser.add_argument('--slow', action=argparse.BooleanOptionalAction)
|
parser.add_argument('--slow', action=argparse.BooleanOptionalAction)
|
||||||
parser.add_argument('--vm', action=argparse.BooleanOptionalAction)
|
parser.add_argument('--vm', action=argparse.BooleanOptionalAction)
|
||||||
parser.add_argument('--exit-code', required=True, type=int)
|
parser.add_argument('--exit-code', required=True, type=int)
|
||||||
|
parser.add_argument('--coredump-exclude-regex', required=True)
|
||||||
parser.add_argument('mkosi_args', nargs='*')
|
parser.add_argument('mkosi_args', nargs='*')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -114,7 +169,9 @@ def main() -> None:
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
journal_file = None
|
journal_file = (args.meson_build_dir / (f'test/journal/{name}.journal')).absolute()
|
||||||
|
journal_file.unlink(missing_ok=True)
|
||||||
|
|
||||||
if not sys.stderr.isatty():
|
if not sys.stderr.isatty():
|
||||||
dropin += textwrap.dedent(
|
dropin += textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
|
@ -122,9 +179,6 @@ def main() -> None:
|
||||||
FailureAction=exit
|
FailureAction=exit
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
journal_file = (args.meson_build_dir / (f'test/journal/{name}.journal')).absolute()
|
|
||||||
journal_file.unlink(missing_ok=True)
|
|
||||||
elif not shell:
|
elif not shell:
|
||||||
dropin += textwrap.dedent(
|
dropin += textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
|
@ -194,44 +248,42 @@ def main() -> None:
|
||||||
)
|
)
|
||||||
exit(77)
|
exit(77)
|
||||||
|
|
||||||
if journal_file and (
|
coredumps = process_coredumps(args, journal_file)
|
||||||
keep_journal == '0' or (result.returncode in (args.exit_code, 77) and keep_journal == 'fail')
|
|
||||||
|
if keep_journal == '0' or (
|
||||||
|
keep_journal == 'fail' and result.returncode in (args.exit_code, 77) and not coredumps
|
||||||
):
|
):
|
||||||
journal_file.unlink(missing_ok=True)
|
journal_file.unlink(missing_ok=True)
|
||||||
|
|
||||||
if shell or result.returncode in (args.exit_code, 77):
|
if shell or (result.returncode in (args.exit_code, 77) and not coredumps):
|
||||||
exit(0 if shell or result.returncode == args.exit_code else 77)
|
exit(0 if shell or result.returncode == args.exit_code else 77)
|
||||||
|
|
||||||
if journal_file:
|
ops = []
|
||||||
ops = []
|
|
||||||
|
|
||||||
if os.getenv('GITHUB_ACTIONS'):
|
if os.getenv('GITHUB_ACTIONS'):
|
||||||
id = os.environ['GITHUB_RUN_ID']
|
id = os.environ['GITHUB_RUN_ID']
|
||||||
iteration = os.environ['GITHUB_RUN_ATTEMPT']
|
iteration = os.environ['GITHUB_RUN_ATTEMPT']
|
||||||
j = json.loads(
|
j = json.loads(
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[
|
[
|
||||||
args.mkosi,
|
args.mkosi,
|
||||||
'--directory', os.fspath(args.meson_source_dir),
|
'--directory', os.fspath(args.meson_source_dir),
|
||||||
'--json',
|
'--json',
|
||||||
'summary',
|
'summary',
|
||||||
],
|
],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
text=True,
|
text=True,
|
||||||
).stdout
|
).stdout
|
||||||
) # fmt: skip
|
) # fmt: skip
|
||||||
distribution = j['Images'][-1]['Distribution']
|
distribution = j['Images'][-1]['Distribution']
|
||||||
release = j['Images'][-1]['Release']
|
release = j['Images'][-1]['Release']
|
||||||
artifact = f'ci-mkosi-{id}-{iteration}-{distribution}-{release}-failed-test-journals'
|
artifact = f'ci-mkosi-{id}-{iteration}-{distribution}-{release}-failed-test-journals'
|
||||||
ops += [f'gh run download {id} --name {artifact} -D ci/{artifact}']
|
ops += [f'gh run download {id} --name {artifact} -D ci/{artifact}']
|
||||||
journal_file = Path(f'ci/{artifact}/test/journal/{name}.journal')
|
journal_file = Path(f'ci/{artifact}/test/journal/{name}.journal')
|
||||||
|
|
||||||
ops += [f'journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info']
|
ops += [f'journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info']
|
||||||
|
|
||||||
print(
|
print("Test failed, relevant logs can be viewed with: \n\n" f"{(' && '.join(ops))}\n", file=sys.stderr)
|
||||||
"Test failed, relevant logs can be viewed with: \n\n" f"{(' && '.join(ops))}\n",
|
|
||||||
file=sys.stderr,
|
|
||||||
)
|
|
||||||
|
|
||||||
# 0 also means we failed so translate that to a non-zero exit code to mark the test as failed.
|
# 0 also means we failed so translate that to a non-zero exit code to mark the test as failed.
|
||||||
exit(result.returncode or 1)
|
exit(result.returncode or 1)
|
||||||
|
|
|
@ -297,6 +297,7 @@ integration_test_template = {
|
||||||
'qemu-args' : [],
|
'qemu-args' : [],
|
||||||
'exit-code' : 123,
|
'exit-code' : 123,
|
||||||
'vm' : false,
|
'vm' : false,
|
||||||
|
'coredump-exclude-regex' : '',
|
||||||
}
|
}
|
||||||
testdata_subdirs = [
|
testdata_subdirs = [
|
||||||
'auxv',
|
'auxv',
|
||||||
|
@ -391,6 +392,7 @@ foreach integration_test : integration_tests
|
||||||
'--storage', integration_test['storage'],
|
'--storage', integration_test['storage'],
|
||||||
'--firmware', integration_test['firmware'],
|
'--firmware', integration_test['firmware'],
|
||||||
'--exit-code', integration_test['exit-code'].to_string(),
|
'--exit-code', integration_test['exit-code'].to_string(),
|
||||||
|
'--coredump-exclude-regex', integration_test['coredump-exclude-regex'],
|
||||||
]
|
]
|
||||||
|
|
||||||
if 'unit' in integration_test
|
if 'unit' in integration_test
|
||||||
|
|
|
@ -248,6 +248,7 @@ Bridge=mybridge
|
||||||
[Match]
|
[Match]
|
||||||
Name=mybridge
|
Name=mybridge
|
||||||
[Network]
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
DNS=192.168.250.1
|
DNS=192.168.250.1
|
||||||
Address=192.168.250.33/24
|
Address=192.168.250.33/24
|
||||||
Gateway=192.168.250.1
|
Gateway=192.168.250.1
|
||||||
|
@ -540,6 +541,7 @@ MACAddress=12:34:56:78:9a:bc
|
||||||
[Match]
|
[Match]
|
||||||
Name=dummy0
|
Name=dummy0
|
||||||
[Network]
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
Address=192.168.42.100/24
|
Address=192.168.42.100/24
|
||||||
DNS=192.168.42.1
|
DNS=192.168.42.1
|
||||||
Domains= ~company
|
Domains= ~company
|
||||||
|
@ -573,6 +575,7 @@ MACAddress=12:34:56:78:9a:bc
|
||||||
self.write_network('50-myvpn.network', '''[Match]
|
self.write_network('50-myvpn.network', '''[Match]
|
||||||
Name=dummy0
|
Name=dummy0
|
||||||
[Network]
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
Address=192.168.42.100/24
|
Address=192.168.42.100/24
|
||||||
DNS=192.168.42.1
|
DNS=192.168.42.1
|
||||||
Domains= ~company ~.
|
Domains= ~company ~.
|
||||||
|
@ -927,6 +930,7 @@ cat <<EOF >/run/systemd/network/50-test.network
|
||||||
Name={ifr}
|
Name={ifr}
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
Address=192.168.5.1/24
|
Address=192.168.5.1/24
|
||||||
{addr6}
|
{addr6}
|
||||||
DHCPServer=yes
|
DHCPServer=yes
|
||||||
|
@ -1006,6 +1010,7 @@ MACAddress=12:34:56:78:9a:bc
|
||||||
[Match]
|
[Match]
|
||||||
Name=dummy0
|
Name=dummy0
|
||||||
[Network]
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
Address=192.168.42.100/24
|
Address=192.168.42.100/24
|
||||||
DNS=192.168.42.1
|
DNS=192.168.42.1
|
||||||
Domains= one two three four five six seven eight nine ten
|
Domains= one two three four five six seven eight nine ten
|
||||||
|
@ -1035,6 +1040,7 @@ MACAddress=12:34:56:78:9a:bc
|
||||||
[Match]
|
[Match]
|
||||||
Name=dummy0
|
Name=dummy0
|
||||||
[Network]
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
Address=192.168.42.100/24
|
Address=192.168.42.100/24
|
||||||
DNS=192.168.42.1
|
DNS=192.168.42.1
|
||||||
''')
|
''')
|
||||||
|
@ -1107,7 +1113,12 @@ class MatchClientTest(unittest.TestCase, NetworkdTestingUtilities):
|
||||||
def test_basic_matching(self):
|
def test_basic_matching(self):
|
||||||
"""Verify the Name= line works throughout this class."""
|
"""Verify the Name= line works throughout this class."""
|
||||||
self.add_veth_pair('test_if1', 'fake_if2')
|
self.add_veth_pair('test_if1', 'fake_if2')
|
||||||
self.write_network('50-test.network', "[Match]\nName=test_*\n[Network]")
|
self.write_network('50-test.network', '''\
|
||||||
|
[Match]
|
||||||
|
Name=test_*
|
||||||
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
''')
|
||||||
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||||
self.assert_link_states(test_if1='managed', fake_if2='unmanaged')
|
self.assert_link_states(test_if1='managed', fake_if2='unmanaged')
|
||||||
|
|
||||||
|
@ -1118,11 +1129,13 @@ class MatchClientTest(unittest.TestCase, NetworkdTestingUtilities):
|
||||||
mac = '00:01:02:03:98:99'
|
mac = '00:01:02:03:98:99'
|
||||||
self.add_veth_pair('test_veth', 'test_peer',
|
self.add_veth_pair('test_veth', 'test_peer',
|
||||||
['addr', mac], ['addr', mac])
|
['addr', mac], ['addr', mac])
|
||||||
self.write_network('50-no-veth.network', """\
|
self.write_network('50-no-veth.network', '''\
|
||||||
[Match]
|
[Match]
|
||||||
MACAddress={}
|
MACAddress={}
|
||||||
Name=!nonexistent *peer*
|
Name=!nonexistent *peer*
|
||||||
[Network]""".format(mac))
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
'''.format(mac))
|
||||||
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||||
self.assert_link_states(test_veth='managed', test_peer='unmanaged')
|
self.assert_link_states(test_veth='managed', test_peer='unmanaged')
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,14 @@ set -o pipefail
|
||||||
# shellcheck source=test/units/test-control.sh
|
# shellcheck source=test/units/test-control.sh
|
||||||
. "$(dirname "$0")"/test-control.sh
|
. "$(dirname "$0")"/test-control.sh
|
||||||
|
|
||||||
|
if systemd-detect-virt --quiet --container; then
|
||||||
|
# This comes from the selinux package and tries to write
|
||||||
|
# some files under sysfs, which will be read-only in a container,
|
||||||
|
# so mask it. It's not our tmpfiles.d file anyway.
|
||||||
|
mkdir -p /run/tmpfiles.d/
|
||||||
|
ln -s /dev/null /run/tmpfiles.d/selinux-policy.conf
|
||||||
|
fi
|
||||||
|
|
||||||
run_subtests
|
run_subtests
|
||||||
|
|
||||||
touch /testok
|
touch /testok
|
||||||
|
|
Loading…
Reference in New Issue