1
0
mirror of https://github.com/systemd/systemd synced 2025-09-21 12:54:44 +02:00

Compare commits

..

No commits in common. "c6e6c85f83176fe6082c216aa2eb6621d9bc009d" and "85a725a9428d15548925ff482ec402f61cef812e" have entirely different histories.

96 changed files with 2444 additions and 2314 deletions

6
NEWS
View File

@ -1,11 +1,5 @@
systemd System and Service Manager systemd System and Service Manager
CHANGES WITH 259 in spe:
* homectl's --recovery-key= option may now be used with the "update"
command to add recovery keys to existing user accounts. Previously,
recovery keys could only be configured during initial user creation.
CHANGES WITH 258: CHANGES WITH 258:
Incompatible changes: Incompatible changes:

View File

@ -1584,13 +1584,6 @@ homectl update lafcadio --pkcs11-token-uri=auto</programlisting>
<programlisting># Allow a FIDO2 security token to unlock the account of user 'nihilbaxter'. <programlisting># Allow a FIDO2 security token to unlock the account of user 'nihilbaxter'.
homectl update nihilbaxter --fido2-device=auto</programlisting> homectl update nihilbaxter --fido2-device=auto</programlisting>
</example> </example>
<example>
<title>Add a recovery key to an existing user account:</title>
<programlisting># Generate and add a recovery key for user 'emily'.
homectl update emily --recovery-key=yes</programlisting>
</example>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@ -735,11 +735,10 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-W</option></term>
<term><option>--no-hostname</option></term> <term><option>--no-hostname</option></term>
<listitem><para>Do not show the hostname field of log messages. This switch has an effect only on the <listitem><para>Do not show the hostname field of log messages originating from the local host. This
<option>short</option> family of output modes (see above).</para> switch has an effect only on the <option>short</option> family of output modes (see above).</para>
<para>Note: this option does not remove occurrences of the hostname from log entries themselves, so <para>Note: this option does not remove occurrences of the hostname from log entries themselves, so
it does not prevent the hostname from being visible in the logs.</para> it does not prevent the hostname from being visible in the logs.</para>

View File

@ -729,14 +729,6 @@ SUBSYSTEM=="net", OPTIONS="log_level=debug"</programlisting></para>
<xi:include href="version-info.xml" xpointer="v258"/> <xi:include href="version-info.xml" xpointer="v258"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>dump-json</option></term>
<listitem>
<para>Similar to <option>dump</option>, but dump the status of the event in JSON format.</para>
<xi:include href="version-info.xml" xpointer="v259"/>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -2959,64 +2959,64 @@ alt_time_epoch = run_command('date', '-Is', '-u', '-d', '@@0@'.format(time_epoch
check : true).stdout().strip() check : true).stdout().strip()
summary({ summary({
'split bin-sbin' : split_bin, 'split bin-sbin' : split_bin,
'prefix directory' : prefixdir, 'prefix directory' : prefixdir,
'sysconf directory' : sysconfdir, 'sysconf directory' : sysconfdir,
'include directory' : includedir, 'include directory' : includedir,
'lib directory' : libdir, 'lib directory' : libdir,
'SysV init scripts' : sysvinit_path, 'SysV init scripts' : sysvinit_path,
'SysV rc?.d directories' : sysvrcnd_path, 'SysV rc?.d directories' : sysvrcnd_path,
'SysV rc.local script' : sysvrclocal_path, 'SysV rc.local script' : sysvrclocal_path,
'PAM modules directory' : pamlibdir, 'PAM modules directory' : pamlibdir,
'PAM configuration directory' : pamconfdir, 'PAM configuration directory' : pamconfdir,
'ssh server configuration directory' : sshdconfdir, 'ssh server configuration directory' : sshdconfdir,
'ssh server privilege separation directory' : sshdprivsepdir, 'ssh server privilege separation directory' : sshdprivsepdir,
'ssh client configuration directory' : sshconfdir, 'ssh client configuration directory' : sshconfdir,
'libcryptsetup plugins directory' : libcryptsetup_plugins_dir, 'libcryptsetup plugins directory' : libcryptsetup_plugins_dir,
'Shell profile directory' : shellprofiledir, 'Shell profile directory' : shellprofiledir,
'RPM macros directory' : rpmmacrosdir, 'RPM macros directory' : rpmmacrosdir,
'modprobe.d directory' : modprobedir, 'modprobe.d directory' : modprobedir,
'D-Bus policy directory' : dbuspolicydir, 'D-Bus policy directory' : dbuspolicydir,
'D-Bus session directory' : dbussessionservicedir, 'D-Bus session directory' : dbussessionservicedir,
'D-Bus system directory' : dbussystemservicedir, 'D-Bus system directory' : dbussystemservicedir,
'D-Bus interfaces directory' : dbus_interfaces_dir, 'D-Bus interfaces directory' : dbus_interfaces_dir,
'bash completions directory' : bashcompletiondir, 'bash completions directory' : bashcompletiondir,
'zsh completions directory' : zshcompletiondir, 'zsh completions directory' : zshcompletiondir,
'private shared lib version tag' : shared_lib_tag, 'private shared lib version tag' : shared_lib_tag,
'debug shell' : '@0@ @ @1@'.format(get_option('debug-shell'), 'debug shell' : '@0@ @ @1@'.format(get_option('debug-shell'),
get_option('debug-tty')), get_option('debug-tty')),
'system UIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'), 'system UIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'),
conf.get('SYSTEM_ALLOC_UID_MIN')), conf.get('SYSTEM_ALLOC_UID_MIN')),
'system GIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'), 'system GIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
conf.get('SYSTEM_ALLOC_GID_MIN')), conf.get('SYSTEM_ALLOC_GID_MIN')),
'greeter UIDs' : '@0@…@1@'.format(greeter_uid_min, greeter_uid_max), 'greeter UIDs' : '@0@…@1@'.format(greeter_uid_min, greeter_uid_max),
'dynamic UIDs' : '@0@…@1@'.format(dynamic_uid_min, dynamic_uid_max), 'dynamic UIDs' : '@0@…@1@'.format(dynamic_uid_min, dynamic_uid_max),
'container UID bases' : '@0@…@1@'.format(container_uid_base_min, container_uid_base_max), 'container UID bases' : '@0@…@1@'.format(container_uid_base_min, container_uid_base_max),
'foreign UID base' : '@0@'.format(foreign_uid_base), 'foreign UID base' : '@0@'.format(foreign_uid_base),
'static UID/GID allocations' : ' '.join(static_ugids), 'static UID/GID allocations' : ' '.join(static_ugids),
'/dev/kvm access mode' : get_option('dev-kvm-mode'), '/dev/kvm access mode' : get_option('dev-kvm-mode'),
'render group access mode' : get_option('group-render-mode'), 'render group access mode' : get_option('group-render-mode'),
'certificate root directory' : get_option('certificate-root'), 'certificate root directory' : get_option('certificate-root'),
'support URL' : support_url, 'support URL' : support_url,
'nobody user name' : nobody_user, 'nobody user name' : nobody_user,
'nobody group name' : nobody_group, 'nobody group name' : nobody_group,
'fallback hostname' : get_option('fallback-hostname'), 'fallback hostname' : get_option('fallback-hostname'),
'default compression method' : compression, 'default compression method' : compression,
'default DNSSEC mode' : default_dnssec, 'default DNSSEC mode' : default_dnssec,
'default DNS-over-TLS mode' : default_dns_over_tls, 'default DNS-over-TLS mode' : default_dns_over_tls,
'default mDNS mode' : default_mdns, 'default mDNS mode' : default_mdns,
'default LLMNR mode' : default_llmnr, 'default LLMNR mode' : default_llmnr,
'default DNS servers' : dns_servers.split(' '), 'default DNS servers' : dns_servers.split(' '),
'default NTP servers' : ntp_servers.split(' '), 'default NTP servers' : ntp_servers.split(' '),
'default net.naming_scheme= value' : default_net_naming_scheme, 'default net.naming_scheme= value': default_net_naming_scheme,
'default KillUserProcesses= value' : kill_user_processes, 'default KillUserProcesses= value': kill_user_processes,
'default locale' : default_locale, 'default locale' : default_locale,
'default nspawn locale' : nspawn_locale, 'default nspawn locale' : nspawn_locale,
'default status unit format' : status_unit_format_default, 'default status unit format' : status_unit_format_default,
'default user $PATH' : default_user_path != '' ? default_user_path : '(same as system services)', 'default user $PATH' :
'systemd service watchdog' : service_watchdog == '' ? 'disabled' : service_watchdog, default_user_path != '' ? default_user_path : '(same as system services)',
'time epoch' : '@0@ (@1@)'.format(time_epoch, alt_time_epoch) 'systemd service watchdog' : service_watchdog == '' ? 'disabled' : service_watchdog,
}) 'time epoch' : '@0@ (@1@)'.format(time_epoch, alt_time_epoch)})
# TODO: # TODO:
# CFLAGS: ${OUR_CFLAGS} ${CFLAGS} # CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
@ -3185,7 +3185,6 @@ else
endif endif
summary({ summary({
'enabled' : ', '.join(found), 'enabled' : ', '.join(found),
'disabled' : ', '.join(missing) 'disabled' : ', '.join(missing)},
},
section : 'Features') section : 'Features')

View File

@ -111,6 +111,7 @@ Packages=
llvm llvm
lsof lsof
lvm2 lvm2
man
mdadm mdadm
mtools mtools
nano nano

View File

@ -59,7 +59,6 @@ Packages=
libapparmor1 libapparmor1
libcap-progs libcap-progs
libtss2-tcti-device0 libtss2-tcti-device0
man
multipath-tools multipath-tools
ncat ncat
open-iscsi open-iscsi

View File

@ -3,8 +3,6 @@ set -e
# We don't use mkosi.extra because /usr/sbin could be a symlink and cp doesn't handle that properly until # We don't use mkosi.extra because /usr/sbin could be a symlink and cp doesn't handle that properly until
# coreutils 9.5 or newer. # coreutils 9.5 or newer.
mkdir -p "$BUILDROOT/sbin"
rm -f "$BUILDROOT/sbin/init"
cat >"$BUILDROOT/sbin/init" <<EOF cat >"$BUILDROOT/sbin/init" <<EOF
#!/bin/bash #!/bin/bash
echo "Hello from dummy init, beautiful day, innit?" echo "Hello from dummy init, beautiful day, innit?"

View File

@ -47,7 +47,7 @@ _journalctl() {
--show-cursor --dmesg -k --pager-end -e -r --reverse --show-cursor --dmesg -k --pager-end -e -r --reverse
--utc -x --catalog --no-full --force --dump-catalog --utc -x --catalog --no-full --force --dump-catalog
--flush --rotate --sync --relinquish-var --flush --rotate --sync --relinquish-var
--smart-relinquish-var --no-hostname -W -N --fields --smart-relinquish-var --no-hostname -N --fields
--list-namespaces --list-invocations -I -v --verbose' --list-namespaces --list-invocations -I -v --verbose'
[ARG]='-b --boot -D --directory -i --file -F --field -t --identifier [ARG]='-b --boot -D --directory -i --file -F --field -t --identifier
-T --exclude-identifier --facility -M --machine -o --output -T --exclude-identifier --facility -M --machine -o --output

View File

@ -99,7 +99,7 @@ _arguments -s \
'(- *)'{-h,--help}'[Show this help]' \ '(- *)'{-h,--help}'[Show this help]' \
'(- *)--version[Show package version]' \ '(- *)--version[Show package version]' \
'--no-pager[Do not pipe output into a pager]' \ '--no-pager[Do not pipe output into a pager]' \
'(-W --no-hostname)'{-W,--no-hostname}"[Don't show the hostname of log messages]" \ --no-hostname"[Don't show the hostname of local log messages]" \
'(-l --full)'{-l,--full}'[Show long fields in full]' \ '(-l --full)'{-l,--full}'[Show long fields in full]' \
'(-a --all)'{-a,--all}'[Show all fields, including long and unprintable]' \ '(-a --all)'{-a,--all}'[Show all fields, including long and unprintable]' \
'(-f --follow)'{-f,--follow}'[Follow journal]' \ '(-f --follow)'{-f,--follow}'[Follow journal]' \

View File

@ -144,8 +144,8 @@ bool compression_supported(Compression c) {
return BIT_SET(supported, c); return BIT_SET(supported, c);
} }
int dlopen_lzma(void) {
#if HAVE_XZ #if HAVE_XZ
int dlopen_lzma(void) {
ELF_NOTE_DLOPEN("lzma", ELF_NOTE_DLOPEN("lzma",
"Support lzma compression in journal and coredump files", "Support lzma compression in journal and coredump files",
COMPRESSION_PRIORITY_XZ, COMPRESSION_PRIORITY_XZ,
@ -160,10 +160,8 @@ int dlopen_lzma(void) {
DLSYM_ARG(lzma_stream_buffer_encode), DLSYM_ARG(lzma_stream_buffer_encode),
DLSYM_ARG(lzma_lzma_preset), DLSYM_ARG(lzma_lzma_preset),
DLSYM_ARG(lzma_stream_decoder)); DLSYM_ARG(lzma_stream_decoder));
#else
return -EOPNOTSUPP;
#endif
} }
#endif
int compress_blob_xz(const void *src, uint64_t src_size, int compress_blob_xz(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size, int level) { void *dst, size_t dst_alloc_size, size_t *dst_size, int level) {
@ -215,8 +213,8 @@ int compress_blob_xz(const void *src, uint64_t src_size,
#endif #endif
} }
int dlopen_lz4(void) {
#if HAVE_LZ4 #if HAVE_LZ4
int dlopen_lz4(void) {
ELF_NOTE_DLOPEN("lz4", ELF_NOTE_DLOPEN("lz4",
"Support lz4 compression in journal and coredump files", "Support lz4 compression in journal and coredump files",
COMPRESSION_PRIORITY_LZ4, COMPRESSION_PRIORITY_LZ4,
@ -240,10 +238,8 @@ int dlopen_lz4(void) {
DLSYM_ARG(LZ4_decompress_safe), DLSYM_ARG(LZ4_decompress_safe),
DLSYM_ARG(LZ4_decompress_safe_partial), DLSYM_ARG(LZ4_decompress_safe_partial),
DLSYM_ARG(LZ4_versionNumber)); DLSYM_ARG(LZ4_versionNumber));
#else
return -EOPNOTSUPP;
#endif
} }
#endif
int compress_blob_lz4(const void *src, uint64_t src_size, int compress_blob_lz4(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size, int level) { void *dst, size_t dst_alloc_size, size_t *dst_size, int level) {
@ -282,8 +278,8 @@ int compress_blob_lz4(const void *src, uint64_t src_size,
#endif #endif
} }
int dlopen_zstd(void) {
#if HAVE_ZSTD #if HAVE_ZSTD
int dlopen_zstd(void) {
ELF_NOTE_DLOPEN("zstd", ELF_NOTE_DLOPEN("zstd",
"Support zstd compression in journal and coredump files", "Support zstd compression in journal and coredump files",
COMPRESSION_PRIORITY_ZSTD, COMPRESSION_PRIORITY_ZSTD,
@ -308,10 +304,8 @@ int dlopen_zstd(void) {
DLSYM_ARG(ZSTD_isError), DLSYM_ARG(ZSTD_isError),
DLSYM_ARG(ZSTD_createDCtx), DLSYM_ARG(ZSTD_createDCtx),
DLSYM_ARG(ZSTD_createCCtx)); DLSYM_ARG(ZSTD_createCCtx));
#else
return -EOPNOTSUPP;
#endif
} }
#endif
int compress_blob_zstd( int compress_blob_zstd(
const void *src, uint64_t src_size, const void *src, uint64_t src_size,

View File

@ -62,9 +62,17 @@ int decompress_stream_xz(int fdf, int fdt, uint64_t max_size);
int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size); int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
int decompress_stream_zstd(int fdf, int fdt, uint64_t max_size); int decompress_stream_zstd(int fdf, int fdt, uint64_t max_size);
#if HAVE_LZ4
int dlopen_lz4(void); int dlopen_lz4(void);
#endif
#if HAVE_ZSTD
int dlopen_zstd(void); int dlopen_zstd(void);
#endif
#if HAVE_XZ
int dlopen_lzma(void); int dlopen_lzma(void);
#endif
static inline int compress_blob( static inline int compress_blob(
Compression compression, Compression compression,

View File

@ -650,16 +650,14 @@ int write_env_file(int dir_fd, const char *fname, char **headers, char **l, Writ
} }
r = fopen_tmpfile_linkable_at(dir_fd, fname, O_WRONLY|O_CLOEXEC, &p, &f); r = fopen_tmpfile_linkable_at(dir_fd, fname, O_WRONLY|O_CLOEXEC, &p, &f);
int k = call_label_ops_post ? label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fname, /* created= */ !!f) : 0; if (call_label_ops_post)
RET_GATHER(r, label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fname, /* created= */ !!f));
if (r < 0) if (r < 0)
return r; return r;
CLEANUP_TMPFILE_AT(dir_fd, p);
if (k < 0)
return k;
r = fchmod_umask(fileno(f), 0644); r = fchmod_umask(fileno(f), 0644);
if (r < 0) if (r < 0)
return r; goto fail;
STRV_FOREACH(i, headers) { STRV_FOREACH(i, headers) {
assert(isempty(*i) || startswith(*i, "#")); assert(isempty(*i) || startswith(*i, "#"));
@ -672,11 +670,15 @@ int write_env_file(int dir_fd, const char *fname, char **headers, char **l, Writ
r = flink_tmpfile_at(f, dir_fd, p, fname, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC); r = flink_tmpfile_at(f, dir_fd, p, fname, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC);
if (r < 0) if (r < 0)
return r; goto fail;
p = mfree(p); /* disarm CLEANUP_TMPFILE_AT() */
return 0; return 0;
fail:
if (p)
(void) unlinkat(dir_fd, p, 0);
return r;
} }
int write_vconsole_conf(int dir_fd, const char *fname, char **l) { int write_vconsole_conf(int dir_fd, const char *fname, char **l) {

View File

@ -240,28 +240,24 @@ static int write_string_file_atomic_at(
} }
r = fopen_temporary_at(dir_fd, fn, &f, &p); r = fopen_temporary_at(dir_fd, fn, &f, &p);
int k = call_label_ops_post ? label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f) : 0; if (call_label_ops_post)
/* If fopen_temporary_at() failed in the above, propagate the error code, and ignore failures in /* If fopen_temporary_at() failed in the above, propagate the error code, and ignore failures
* label_ops_post(). */ * in label_ops_post(). */
RET_GATHER(r, label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f));
if (r < 0) if (r < 0)
return r; goto fail;
CLEANUP_TMPFILE_AT(dir_fd, p);
if (k < 0)
return k;
r = write_string_stream_full(f, line, flags, ts); r = write_string_stream_full(f, line, flags, ts);
if (r < 0) if (r < 0)
return r; goto fail;
r = fchmod_umask(fileno(f), mode); r = fchmod_umask(fileno(f), mode);
if (r < 0) if (r < 0)
return r; goto fail;
r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn)); r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn));
if (r < 0) if (r < 0)
return r; goto fail;
p = mfree(p); /* disarm CLEANUP_TMPFILE_AT() */
if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) { if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
/* Sync the rename, too */ /* Sync the rename, too */
@ -271,6 +267,11 @@ static int write_string_file_atomic_at(
} }
return 0; return 0;
fail:
if (f)
(void) unlinkat(dir_fd, p, 0);
return r;
} }
int write_string_file_full( int write_string_file_full(

View File

@ -236,7 +236,7 @@ typedef struct sd_hwdb sd_hwdb;
/* shared/ forward declarations */ /* shared/ forward declarations */
typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, uint64_t bytes_per_second, void *userdata); typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata); typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata);
struct local_address; struct local_address;

View File

@ -1,11 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#if HAVE_GCRYPT
#include <sys/syslog.h> #include <sys/syslog.h>
#include "gcrypt-util.h" #include "gcrypt-util.h"
#if HAVE_GCRYPT
static void *gcrypt_dl = NULL; static void *gcrypt_dl = NULL;
static DLSYM_PROTOTYPE(gcry_control) = NULL; static DLSYM_PROTOTYPE(gcry_control) = NULL;
@ -40,10 +40,8 @@ DLSYM_PROTOTYPE(gcry_mpi_sub_ui) = NULL;
DLSYM_PROTOTYPE(gcry_prime_check) = NULL; DLSYM_PROTOTYPE(gcry_prime_check) = NULL;
DLSYM_PROTOTYPE(gcry_randomize) = NULL; DLSYM_PROTOTYPE(gcry_randomize) = NULL;
DLSYM_PROTOTYPE(gcry_strerror) = NULL; DLSYM_PROTOTYPE(gcry_strerror) = NULL;
#endif
int dlopen_gcrypt(void) { static int dlopen_gcrypt(void) {
#if HAVE_GCRYPT
ELF_NOTE_DLOPEN("gcrypt", ELF_NOTE_DLOPEN("gcrypt",
"Support for journald forward-sealing", "Support for journald forward-sealing",
ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
@ -84,13 +82,9 @@ int dlopen_gcrypt(void) {
DLSYM_ARG(gcry_prime_check), DLSYM_ARG(gcry_prime_check),
DLSYM_ARG(gcry_randomize), DLSYM_ARG(gcry_randomize),
DLSYM_ARG(gcry_strerror)); DLSYM_ARG(gcry_strerror));
#else
return -EOPNOTSUPP;
#endif
} }
int initialize_libgcrypt(bool secmem) { int initialize_libgcrypt(bool secmem) {
#if HAVE_GCRYPT
int r; int r;
r = dlopen_gcrypt(); r = dlopen_gcrypt();
@ -111,7 +105,5 @@ int initialize_libgcrypt(bool secmem) {
sym_gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); sym_gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
return 0; return 0;
#else
return -EOPNOTSUPP;
#endif
} }
#endif

View File

@ -4,10 +4,6 @@
#include "forward.h" #include "forward.h"
int dlopen_gcrypt(void);
int initialize_libgcrypt(bool secmem);
#if HAVE_GCRYPT #if HAVE_GCRYPT
#include <gcrypt.h> /* IWYU pragma: export */ #include <gcrypt.h> /* IWYU pragma: export */
@ -44,6 +40,8 @@ extern DLSYM_PROTOTYPE(gcry_prime_check);
extern DLSYM_PROTOTYPE(gcry_randomize); extern DLSYM_PROTOTYPE(gcry_randomize);
extern DLSYM_PROTOTYPE(gcry_strerror); extern DLSYM_PROTOTYPE(gcry_strerror);
int initialize_libgcrypt(bool secmem);
/* Copied from gcry_md_putc from gcrypt.h due to the need to call the sym_ variant */ /* Copied from gcry_md_putc from gcrypt.h due to the need to call the sym_ variant */
#define sym_gcry_md_putc(h,c) \ #define sym_gcry_md_putc(h,c) \
do { \ do { \

View File

@ -436,17 +436,3 @@ int mkdtemp_open(const char *template, int flags, char **ret) {
return fd; return fd;
} }
void cleanup_tmpfile_data_done(struct cleanup_tmpfile_data *d) {
assert(d);
if (!d->dir_fd ||
*d->dir_fd < 0 ||
!d->filename ||
!*d->filename)
return;
(void) unlinkat(*d->dir_fd, *d->filename, 0);
d->dir_fd = NULL;
d->filename = NULL;
}

View File

@ -48,14 +48,3 @@ static inline int flink_tmpfile(FILE *f, const char *path, const char *target, L
int mkdtemp_malloc(const char *template, char **ret); int mkdtemp_malloc(const char *template, char **ret);
int mkdtemp_open(const char *template, int flags, char **ret); int mkdtemp_open(const char *template, int flags, char **ret);
/* A helper for removing link_tmpfile_at() via _cleanup_() */
struct cleanup_tmpfile_data {
int *dir_fd;
char **filename;
};
void cleanup_tmpfile_data_done(struct cleanup_tmpfile_data *d);
#define _CLEANUP_TMPFILE_AT(u, dir_fd, filename) \
_unused_ _cleanup_(cleanup_tmpfile_data_done) struct cleanup_tmpfile_data UNIQ_T(cta, u) = { &(dir_fd), &(filename) }
#define CLEANUP_TMPFILE_AT(dir_fd, filename) \
_CLEANUP_TMPFILE_AT(UNIQ, dir_fd, filename)

View File

@ -1165,10 +1165,6 @@ static void boot_entry_parse_tries(
if (!strcaseeq16(counter, suffix)) if (!strcaseeq16(counter, suffix))
return; return;
entry->id = xasprintf("%.*ls%ls",
(int) prefix_len - 1,
file,
suffix);
entry->tries_left = tries_left; entry->tries_left = tries_left;
entry->tries_done = tries_done; entry->tries_done = tries_done;
entry->directory = xstrdup16(directory); entry->directory = xstrdup16(directory);
@ -1399,16 +1395,13 @@ static void boot_entry_add_type1(
} }
entry->device = device; entry->device = device;
entry->id = xstrdup16(file);
if (path)
boot_entry_parse_tries(entry, path, file, u".conf");
if (!entry->id)
entry->id = xstrdup16(file);
strtolower16(entry->id); strtolower16(entry->id);
config_add_entry(config, entry); config_add_entry(config, entry);
if (path)
boot_entry_parse_tries(entry, path, file, u".conf");
TAKE_PTR(entry); TAKE_PTR(entry);
} }

View File

@ -132,19 +132,16 @@ elif get_option('sbat-distro') != ''
endif endif
endif endif
summary({ summary({'UEFI architectures' : efi_arch + (efi_arch_alt == '' ? '' : ', ' + efi_arch_alt)},
'UEFI architectures' : efi_arch + (efi_arch_alt == '' ? '' : ', ' + efi_arch_alt)
},
section : 'UEFI') section : 'UEFI')
if efi_conf.get('SBAT_DISTRO', '') != '' if efi_conf.get('SBAT_DISTRO', '') != ''
summary({ summary({
'SBAT distro' : efi_conf.get('SBAT_DISTRO'), 'SBAT distro': efi_conf.get('SBAT_DISTRO'),
'SBAT distro generation' : efi_conf.get('SBAT_DISTRO_GENERATION'), 'SBAT distro generation': efi_conf.get('SBAT_DISTRO_GENERATION'),
'SBAT distro version' : efi_conf.get('SBAT_DISTRO_VERSION'), 'SBAT distro version': efi_conf.get('SBAT_DISTRO_VERSION'),
'SBAT distro summary' : efi_conf.get('SBAT_DISTRO_SUMMARY'), 'SBAT distro summary': efi_conf.get('SBAT_DISTRO_SUMMARY'),
'SBAT distro URL' : efi_conf.get('SBAT_DISTRO_URL') 'SBAT distro URL': efi_conf.get('SBAT_DISTRO_URL')},
},
section : 'UEFI') section : 'UEFI')
endif endif

File diff suppressed because it is too large Load Diff

View File

@ -336,35 +336,40 @@ static int write_credential(
if (fd < 0) if (fd < 0)
return -errno; return -errno;
CLEANUP_TMPFILE_AT(dfd, tmp);
r = loop_write(fd, data, size); r = loop_write(fd, data, size);
if (r < 0) if (r < 0)
return r; goto fail;
r = RET_NERRNO(fchmod(fd, 0400)); /* Take away "w" bit */ r = RET_NERRNO(fchmod(fd, 0400)); /* Take away "w" bit */
if (r < 0) if (r < 0)
return r; goto fail;
if (uid_is_valid(uid) && uid != getuid()) { if (uid_is_valid(uid) && uid != getuid()) {
r = fd_add_uid_acl_permission(fd, uid, ACL_READ); r = fd_add_uid_acl_permission(fd, uid, ACL_READ);
/* Ideally we use ACLs, since we can neatly express what we want to express: if (r < 0) {
* the user gets read access and nothing else. But if the backing fs can't /* Ideally we use ACLs, since we can neatly express what we want to express:
* support that (e.g. ramfs), then we can use file ownership instead. But that's * the user gets read access and nothing else. But if the backing fs can't
* only safe if we can then re-mount the whole thing read-only, so that the user * support that (e.g. ramfs), then we can use file ownership instead. But that's
* can no longer chmod() the file to gain write access. */ * only safe if we can then re-mount the whole thing read-only, so that the user
if ((ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r)) && ownership_ok) * can no longer chmod() the file to gain write access. */
if (!ownership_ok || (!ERRNO_IS_NOT_SUPPORTED(r) && !ERRNO_IS_PRIVILEGE(r)))
goto fail;
r = RET_NERRNO(fchown(fd, uid, gid)); r = RET_NERRNO(fchown(fd, uid, gid));
if (r < 0) if (r < 0)
return r; goto fail;
}
} }
r = RET_NERRNO(renameat(dfd, tmp, dfd, id)); r = RET_NERRNO(renameat(dfd, tmp, dfd, id));
if (r < 0) if (r < 0)
return r; goto fail;
tmp = mfree(tmp); /* disarm CLEANUP_TMPFILE_AT() */
return 0; return 0;
fail:
(void) unlinkat(dfd, tmp, /* flags = */ 0);
return r;
} }
typedef enum CredentialSearchPath { typedef enum CredentialSearchPath {

View File

@ -22,7 +22,7 @@ static void transaction_delete_job(Transaction *tr, Job *j, bool delete_dependen
assert(tr); assert(tr);
assert(j); assert(j);
/* Deletes one job from the transaction. */ /* Deletes one job from the transaction */
transaction_unlink_job(tr, j, delete_dependencies); transaction_unlink_job(tr, j, delete_dependencies);
@ -32,7 +32,8 @@ static void transaction_delete_job(Transaction *tr, Job *j, bool delete_dependen
static void transaction_delete_unit(Transaction *tr, Unit *u) { static void transaction_delete_unit(Transaction *tr, Unit *u) {
Job *j; Job *j;
/* Deletes all jobs associated with a certain unit from the transaction. */ /* Deletes all jobs associated with a certain unit from the
* transaction */
while ((j = hashmap_get(tr->jobs, u))) while ((j = hashmap_get(tr->jobs, u)))
transaction_delete_job(tr, j, true); transaction_delete_job(tr, j, true);
@ -52,20 +53,21 @@ static void transaction_abort(Transaction *tr) {
static void transaction_find_jobs_that_matter_to_anchor(Job *j, unsigned generation) { static void transaction_find_jobs_that_matter_to_anchor(Job *j, unsigned generation) {
assert(j); assert(j);
/* A recursive sweep through the graph that marks all units that matter to the anchor job, i.e. are /* A recursive sweep through the graph that marks all units
* directly or indirectly a dependency of the anchor job via paths that are fully marked as * that matter to the anchor job, i.e. are directly or
* mattering. */ * indirectly a dependency of the anchor job via paths that
* are fully marked as mattering. */
j->matters_to_anchor = true; j->matters_to_anchor = true;
j->generation = generation; j->generation = generation;
LIST_FOREACH(subject, l, j->subject_list) { LIST_FOREACH(subject, l, j->subject_list) {
/* This link does not matter. */ /* This link does not matter */
if (!l->matters) if (!l->matters)
continue; continue;
/* This unit has already been marked. */ /* This unit has already been marked */
if (l->object->generation == generation) if (l->object->generation == generation)
continue; continue;
@ -88,7 +90,7 @@ static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other
j->irreversible = j->irreversible || other->irreversible; j->irreversible = j->irreversible || other->irreversible;
j->matters_to_anchor = j->matters_to_anchor || other->matters_to_anchor; j->matters_to_anchor = j->matters_to_anchor || other->matters_to_anchor;
/* Patch us in as new owner of the JobDependency objects. */ /* Patch us in as new owner of the JobDependency objects */
last = NULL; last = NULL;
LIST_FOREACH(subject, l, other->subject_list) { LIST_FOREACH(subject, l, other->subject_list) {
assert(l->subject == other); assert(l->subject == other);
@ -96,7 +98,7 @@ static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other
last = l; last = l;
} }
/* Merge both lists. */ /* Merge both lists */
if (last) { if (last) {
last->subject_next = j->subject_list; last->subject_next = j->subject_list;
if (j->subject_list) if (j->subject_list)
@ -104,7 +106,7 @@ static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other
j->subject_list = other->subject_list; j->subject_list = other->subject_list;
} }
/* Patch us in as new owner of the JobDependency objects. */ /* Patch us in as new owner of the JobDependency objects */
last = NULL; last = NULL;
LIST_FOREACH(object, l, other->object_list) { LIST_FOREACH(object, l, other->object_list) {
assert(l->object == other); assert(l->object == other);
@ -112,7 +114,7 @@ static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other
last = l; last = l;
} }
/* Merge both lists. */ /* Merge both lists */
if (last) { if (last) {
last->object_next = j->object_list; last->object_next = j->object_list;
if (j->object_list) if (j->object_list)
@ -120,7 +122,7 @@ static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other
j->object_list = other->object_list; j->object_list = other->object_list;
} }
/* Kill the other job. */ /* Kill the other job */
other->subject_list = NULL; other->subject_list = NULL;
other->object_list = NULL; other->object_list = NULL;
transaction_delete_job(tr, other, true); transaction_delete_job(tr, other, true);
@ -129,7 +131,8 @@ static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other
static bool job_is_conflicted_by(Job *j) { static bool job_is_conflicted_by(Job *j) {
assert(j); assert(j);
/* Returns true if this job is pulled in by a least one ConflictedBy= dependency. */ /* Returns true if this job is pulled in by a least one
* ConflictedBy dependency. */
LIST_FOREACH(object, l, j->object_list) LIST_FOREACH(object, l, j->object_list)
if (l->conflicts) if (l->conflicts)
@ -142,49 +145,57 @@ static int delete_one_unmergeable_job(Transaction *tr, Job *job) {
assert(job); assert(job);
/* Tries to delete one item in the linked list /* Tries to delete one item in the linked list
* j->transaction_next->transaction_next->... that conflicts with another one, in an attempt to make * j->transaction_next->transaction_next->... that conflicts
* an inconsistent transaction work. */ * with another one, in an attempt to make an inconsistent
* transaction work. */
/* We rely here on the fact that if a merged with b does not merge with c, either a or b merge with c /* We rely here on the fact that if a merged with b does not
* neither. */ * merge with c, either a or b merge with c neither */
LIST_FOREACH(transaction, j, job) LIST_FOREACH(transaction, j, job)
LIST_FOREACH(transaction, k, j->transaction_next) { LIST_FOREACH(transaction, k, j->transaction_next) {
Job *d; Job *d;
/* Is this one mergeable? Then skip it. */ /* Is this one mergeable? Then skip it */
if (job_type_is_mergeable(j->type, k->type)) if (job_type_is_mergeable(j->type, k->type))
continue; continue;
/* Ok, we found two that conflict, let's see if we can drop one of them. */ /* Ok, we found two that conflict, let's see if we can
* drop one of them */
if (!j->matters_to_anchor && !k->matters_to_anchor) { if (!j->matters_to_anchor && !k->matters_to_anchor) {
/* Both jobs don't matter, so let's find the one that is smarter to remove. /* Both jobs don't matter, so let's
* Let's think positive and rather remove stops than starts -- except if * find the one that is smarter to
* something is being stopped because it is conflicted by another unit in * remove. Let's think positive and
* which case we rather remove the start. */ * rather remove stops then starts --
* except if something is being
bool j_is_conflicted_by = job_is_conflicted_by(j), * stopped because it is conflicted by
k_is_conflicted_by = job_is_conflicted_by(k); * another unit in which case we
* rather remove the start. */
/* Update test/units/TEST-87-AUX-UTILS-VM.sh when logs below are changed. */ /* Update test/units/TEST-87-AUX-UTILS-VM.sh when logs below are changed. */
log_unit_debug(j->unit, log_unit_debug(j->unit,
"Looking at job %s/%s conflicted_by=%s", "Looking at job %s/%s conflicted_by=%s",
j->unit->id, job_type_to_string(j->type), j->unit->id, job_type_to_string(j->type),
yes_no(j->type == JOB_STOP && j_is_conflicted_by)); yes_no(j->type == JOB_STOP && job_is_conflicted_by(j)));
log_unit_debug(k->unit, log_unit_debug(k->unit,
"Looking at job %s/%s conflicted_by=%s", "Looking at job %s/%s conflicted_by=%s",
k->unit->id, job_type_to_string(k->type), k->unit->id, job_type_to_string(k->type),
yes_no(k->type == JOB_STOP && k_is_conflicted_by)); yes_no(k->type == JOB_STOP && job_is_conflicted_by(k)));
if (j->type == JOB_STOP && j_is_conflicted_by) if (j->type == JOB_STOP) {
d = k;
else if (k->type == JOB_STOP && k_is_conflicted_by) if (job_is_conflicted_by(j))
d = j; d = k;
else if (j->type == JOB_STOP) else
d = j; d = j;
else if (k->type == JOB_STOP)
d = k; } else if (k->type == JOB_STOP) {
else
if (job_is_conflicted_by(k))
d = j;
else
d = k;
} else
d = j; d = j;
} else if (!j->matters_to_anchor) } else if (!j->matters_to_anchor)
@ -224,16 +235,18 @@ static int transaction_ensure_mergeable(Transaction *tr, bool matters_to_anchor,
if (job_type_merge_and_collapse(&t, k->type, j->unit) >= 0) if (job_type_merge_and_collapse(&t, k->type, j->unit) >= 0)
continue; continue;
/* OK, we could not merge all jobs for this action. Let's see if we can get rid of /* OK, we could not merge all jobs for this
* one of them. */ * action. Let's see if we can get rid of one
* of them */
r = delete_one_unmergeable_job(tr, j); r = delete_one_unmergeable_job(tr, j);
if (r >= 0) if (r >= 0)
/* Ok, we managed to drop one, now let's ask our callers to call us again /* Ok, we managed to drop one, now
* after garbage collecting. */ * let's ask our callers to call us
* again after garbage collecting */
return -EAGAIN; return -EAGAIN;
/* We couldn't merge anything. Failure. */ /* We couldn't merge anything. Failure */
return sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, return sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING,
"Transaction contains conflicting jobs '%s' and '%s' for %s. " "Transaction contains conflicting jobs '%s' and '%s' for %s. "
"Probably contradicting requirement dependencies configured.", "Probably contradicting requirement dependencies configured.",
@ -266,7 +279,7 @@ static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
HASHMAP_FOREACH(j, tr->jobs) { HASHMAP_FOREACH(j, tr->jobs) {
JobType t = j->type; JobType t = j->type;
/* Merge all transaction jobs for j->unit. */ /* Merge all transaction jobs for j->unit */
LIST_FOREACH(transaction, k, j->transaction_next) LIST_FOREACH(transaction, k, j->transaction_next)
assert_se(job_type_merge_and_collapse(&t, k->type, j->unit) == 0); assert_se(job_type_merge_and_collapse(&t, k->type, j->unit) == 0);
@ -365,7 +378,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
* marker to find our way back, since smart how we are we stored our way back in there. */ * marker to find our way back, since smart how we are we stored our way back in there. */
for (Job *k = from; k; k = (k->generation == generation && k->marker != k) ? k->marker : NULL) { for (Job *k = from; k; k = (k->generation == generation && k->marker != k) ? k->marker : NULL) {
/* For logging below. */ /* For logging below */
if (strv_push_pair(&array, k->unit->id, (char*) job_type_to_string(k->type)) < 0) if (strv_push_pair(&array, k->unit->id, (char*) job_type_to_string(k->type)) < 0)
(void) log_oom_warning(); (void) log_oom_warning();
@ -373,7 +386,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
/* Ok, we can drop this one, so let's do so. */ /* Ok, we can drop this one, so let's do so. */
delete = k; delete = k;
/* Check if this in fact was the beginning of the cycle. */ /* Check if this in fact was the beginning of the cycle */
if (k == j) if (k == j)
break; break;
} }
@ -436,8 +449,10 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
"Transaction order is cyclic. See system logs for details."); "Transaction order is cyclic. See system logs for details.");
} }
/* Make the marker point to where we come from, so that we can find our way backwards if we want to /* Make the marker point to where we come from, so that we can
* break a cycle. We use a special marker for the beginning: we point to ourselves. */ * find our way backwards if we want to break a cycle. We use
* a special marker for the beginning: we point to
* ourselves. */
j->marker = from ?: j; j->marker = from ?: j;
j->generation = generation; j->generation = generation;
@ -471,7 +486,8 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
} }
} }
/* Ok, let's backtrack, and remember that this entry is not on our path anymore. */ /* Ok, let's backtrack, and remember that this entry is not on
* our path anymore. */
j->marker = NULL; j->marker = NULL;
return 0; return 0;
@ -485,7 +501,8 @@ static int transaction_verify_order(Transaction *tr, unsigned *generation, sd_bu
assert(tr); assert(tr);
assert(generation); assert(generation);
/* Check if the ordering graph is cyclic. If it is, try to fix that up by dropping one of the jobs. */ /* Check if the ordering graph is cyclic. If it is, try to fix
* that up by dropping one of the jobs. */
g = (*generation)++; g = (*generation)++;
@ -503,7 +520,7 @@ static void transaction_collect_garbage(Transaction *tr) {
assert(tr); assert(tr);
/* Drop jobs that are not required by any other job. */ /* Drop jobs that are not required by any other job */
do { do {
Job *j; Job *j;
@ -535,7 +552,8 @@ static int transaction_is_destructive(Transaction *tr, JobMode mode, sd_bus_erro
assert(tr); assert(tr);
/* Checks whether applying this transaction means that existing jobs would be replaced. */ /* Checks whether applying this transaction means that
* existing jobs would be replaced */
HASHMAP_FOREACH(j, tr->jobs) { HASHMAP_FOREACH(j, tr->jobs) {
@ -559,7 +577,8 @@ static int transaction_minimize_impact(Transaction *tr, JobMode mode, sd_bus_err
assert(tr); assert(tr);
/* Drops all unnecessary jobs that reverse already active jobs or that stop a running service. */ /* Drops all unnecessary jobs that reverse already active jobs
* or that stop a running service. */
if (!IN_SET(mode, JOB_FAIL, JOB_LENIENT)) if (!IN_SET(mode, JOB_FAIL, JOB_LENIENT))
return 0; return 0;
@ -569,12 +588,13 @@ rescan:
LIST_FOREACH(transaction, j, head) { LIST_FOREACH(transaction, j, head) {
bool stops_running_service, changes_existing_job; bool stops_running_service, changes_existing_job;
/* If it matters, we shouldn't drop it. */ /* If it matters, we shouldn't drop it */
if (j->matters_to_anchor && mode != JOB_LENIENT) if (j->matters_to_anchor && mode != JOB_LENIENT)
continue; continue;
/* Would this stop a running service? Would this change an existing job? If so, let's /* Would this stop a running service?
* drop this entry. */ * Would this change an existing job?
* If so, let's drop this entry */
stops_running_service = stops_running_service =
j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit)); j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit));
@ -603,7 +623,7 @@ rescan:
"%s/%s would change existing job.", "%s/%s would change existing job.",
j->unit->id, job_type_to_string(j->type)); j->unit->id, job_type_to_string(j->type));
/* Ok, let's get rid of this. */ /* Ok, let's get rid of this */
log_unit_debug(j->unit, log_unit_debug(j->unit,
"Deleting %s/%s to minimize impact.", "Deleting %s/%s to minimize impact.",
j->unit->id, job_type_to_string(j->type)); j->unit->id, job_type_to_string(j->type));
@ -628,11 +648,12 @@ static int transaction_apply(
assert(tr); assert(tr);
assert(m); assert(m);
/* Moves the transaction jobs to the set of active jobs. */ /* Moves the transaction jobs to the set of active jobs */
if (IN_SET(mode, JOB_ISOLATE, JOB_FLUSH)) { if (IN_SET(mode, JOB_ISOLATE, JOB_FLUSH)) {
/* When isolating first kill all installed jobs which aren't part of the new transaction. */ /* When isolating first kill all installed jobs which
* aren't part of the new transaction */
HASHMAP_FOREACH(j, m->jobs) { HASHMAP_FOREACH(j, m->jobs) {
assert(j->installed); assert(j->installed);
@ -642,14 +663,15 @@ static int transaction_apply(
if (hashmap_contains(tr->jobs, j->unit)) if (hashmap_contains(tr->jobs, j->unit))
continue; continue;
/* Not invalidating recursively. Avoids triggering OnFailure= actions of dependent /* Not invalidating recursively. Avoids triggering
* jobs. Also avoids invalidating our iterator. */ * OnFailure= actions of dependent jobs. Also avoids
* invalidating our iterator. */
job_finish_and_invalidate(j, JOB_CANCELED, false, false); job_finish_and_invalidate(j, JOB_CANCELED, false, false);
} }
} }
HASHMAP_FOREACH(j, tr->jobs) { HASHMAP_FOREACH(j, tr->jobs) {
/* Assume merged. */ /* Assume merged */
assert(!j->transaction_prev); assert(!j->transaction_prev);
assert(!j->transaction_next); assert(!j->transaction_next);
@ -661,12 +683,12 @@ static int transaction_apply(
while ((j = hashmap_steal_first(tr->jobs))) { while ((j = hashmap_steal_first(tr->jobs))) {
Job *installed_job; Job *installed_job;
/* Clean the job dependencies. */ /* Clean the job dependencies */
transaction_unlink_job(tr, j, false); transaction_unlink_job(tr, j, false);
installed_job = job_install(j); installed_job = job_install(j);
if (installed_job != j) { if (installed_job != j) {
/* j has been merged into a previously installed job. */ /* j has been merged into a previously installed job */
if (tr->anchor_job == j) if (tr->anchor_job == j)
tr->anchor_job = installed_job; tr->anchor_job = installed_job;
@ -711,69 +733,71 @@ int transaction_activate(
assert(tr); assert(tr);
assert(m); assert(m);
/* Reset the generation counter of all installed jobs. The detection of cycles looks at installed /* Reset the generation counter of all installed jobs. The detection of cycles
* jobs. If they had a non-zero generation from some previous walk of the graph, the algorithm would * looks at installed jobs. If they had a non-zero generation from some previous
* break. */ * walk of the graph, the algorithm would break. */
HASHMAP_FOREACH(j, m->jobs) HASHMAP_FOREACH(j, m->jobs)
j->generation = 0; j->generation = 0;
/* First step: figure out which jobs matter. */ /* First step: figure out which jobs matter */
transaction_find_jobs_that_matter_to_anchor(tr->anchor_job, generation++); transaction_find_jobs_that_matter_to_anchor(tr->anchor_job, generation++);
/* Second step: Try not to stop any running services if we don't have to. Don't try to reverse /* Second step: Try not to stop any running services if we don't have to. Don't try to reverse
* running jobs if we don't have to. */ * running jobs if we don't have to. */
r = transaction_minimize_impact(tr, mode, e); r = transaction_minimize_impact(tr, mode, e);
if (r < 0) if (r < 0)
return r; /* Note that we don't log here, because for JOB_LENIENT conflicts are very much return r; /* Note that we don't log here, because for JOB_LENIENT conflicts are very much expected
* expected and shouldn't appear to be fatal for the unit. Only inform the caller and shouldn't appear to be fatal for the unit. Only inform the caller via bus error. */
* via bus error. */
/* Third step: Drop redundant jobs. */ /* Third step: Drop redundant jobs */
transaction_drop_redundant(tr); transaction_drop_redundant(tr);
for (;;) { for (;;) {
/* Fourth step: Let's remove unneeded jobs that might be lurking. */ /* Fourth step: Let's remove unneeded jobs that might
* be lurking. */
if (mode != JOB_ISOLATE) if (mode != JOB_ISOLATE)
transaction_collect_garbage(tr); transaction_collect_garbage(tr);
/* Fifth step: verify order makes sense and correct cycles if necessary and possible. */ /* Fifth step: verify order makes sense and correct
* cycles if necessary and possible */
r = transaction_verify_order(tr, &generation, e); r = transaction_verify_order(tr, &generation, e);
if (r >= 0) if (r >= 0)
break; break;
if (r != -EAGAIN) if (r != -EAGAIN)
return log_warning_errno(r, "Requested transaction contains an unfixable cyclic ordering dependency: %s", return log_warning_errno(r, "Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error_message(e, r));
bus_error_message(e, r));
/* Let's see if the resulting transaction ordering graph is still cyclic... */ /* Let's see if the resulting transaction ordering
* graph is still cyclic... */
} }
for (;;) { for (;;) {
/* Sixth step: let's drop unmergeable entries if necessary and possible, merge entries we can /* Sixth step: let's drop unmergeable entries if
* merge. */ * necessary and possible, merge entries we can
* merge */
r = transaction_merge_jobs(tr, e); r = transaction_merge_jobs(tr, e);
if (r >= 0) if (r >= 0)
break; break;
if (r != -EAGAIN) if (r != -EAGAIN)
return log_warning_errno(r, "Requested transaction contains unmergeable jobs: %s", return log_warning_errno(r, "Requested transaction contains unmergeable jobs: %s", bus_error_message(e, r));
bus_error_message(e, r));
/* Seventh step: an entry got dropped, let's garbage collect its dependencies. */ /* Seventh step: an entry got dropped, let's garbage
* collect its dependencies. */
if (mode != JOB_ISOLATE) if (mode != JOB_ISOLATE)
transaction_collect_garbage(tr); transaction_collect_garbage(tr);
/* Let's see if the resulting transaction still has unmergeable entries... */ /* Let's see if the resulting transaction still has
* unmergeable entries ... */
} }
/* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */ /* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */
transaction_drop_redundant(tr); transaction_drop_redundant(tr);
/* Ninth step: check whether we can actually apply this. */ /* Ninth step: check whether we can actually apply this */
r = transaction_is_destructive(tr, mode, e); r = transaction_is_destructive(tr, mode, e);
if (r < 0) if (r < 0)
return log_notice_errno(r, "Requested transaction contradicts existing jobs: %s", return log_notice_errno(r, "Requested transaction contradicts existing jobs: %s", bus_error_message(e, r));
bus_error_message(e, r));
/* Tenth step: apply changes. */ /* Tenth step: apply changes */
r = transaction_apply(tr, m, mode, affected_jobs); r = transaction_apply(tr, m, mode, affected_jobs);
if (r < 0) if (r < 0)
return log_warning_errno(r, "Failed to apply transaction: %m"); return log_warning_errno(r, "Failed to apply transaction: %m");
@ -795,8 +819,9 @@ static Job* transaction_add_one_job(Transaction *tr, JobType type, Unit *unit, b
assert(tr); assert(tr);
assert(unit); assert(unit);
/* Looks for an existing prospective job and returns that. If it doesn't exist it is created and /* Looks for an existing prospective job and returns that. If
* added to the prospective jobs list. */ * it doesn't exist it is created and added to the prospective
* jobs list. */
f = hashmap_get(tr->jobs, unit); f = hashmap_get(tr->jobs, unit);
@ -907,7 +932,7 @@ static JobType job_type_propagate_stop_graceful(Job *j) {
case JOB_STOP: case JOB_STOP:
case JOB_RESTART: case JOB_RESTART:
/* Nothing to worry about, an appropriate job is in-place. */ /* Nothing to worry about, an appropriate job is in-place */
return JOB_NOP; return JOB_NOP;
case JOB_START: case JOB_START:
@ -917,7 +942,7 @@ static JobType job_type_propagate_stop_graceful(Job *j) {
type = JOB_RESTART; type = JOB_RESTART;
break; break;
default: /* We don't care about others. */ default: /* We don't care about others */
; ;
} }
@ -945,17 +970,16 @@ int transaction_add_job_and_dependencies(
/* Before adding jobs for this unit, let's ensure that its state has been loaded. This matters when /* Before adding jobs for this unit, let's ensure that its state has been loaded. This matters when
* jobs are spawned as part of coldplugging itself (see e. g. path_coldplug()). This way, we * jobs are spawned as part of coldplugging itself (see e. g. path_coldplug()). This way, we
* "recursively" coldplug units, ensuring that we do not look at state of not-yet-coldplugged units. */ * "recursively" coldplug units, ensuring that we do not look at state of not-yet-coldplugged
* units. */
if (MANAGER_IS_RELOADING(unit->manager)) if (MANAGER_IS_RELOADING(unit->manager))
unit_coldplug(unit); unit_coldplug(unit);
if (by) if (by)
log_trace("Pulling in %s/%s from %s/%s", log_trace("Pulling in %s/%s from %s/%s", unit->id, job_type_to_string(type), by->unit->id, job_type_to_string(by->type));
unit->id, job_type_to_string(type),
by->unit->id, job_type_to_string(by->type));
/* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should /* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set
* only be set temporarily. */ * temporarily. */
if (!UNIT_IS_LOAD_COMPLETE(unit->load_state)) if (!UNIT_IS_LOAD_COMPLETE(unit->load_state))
return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
@ -968,8 +992,8 @@ int transaction_add_job_and_dependencies(
* again even if the cache is current, it might have been updated in a different context * again even if the cache is current, it might have been updated in a different context
* before we had a chance to retry loading this particular unit. * before we had a chance to retry loading this particular unit.
* *
* Given building up the transaction is a synchronous operation, attempt to load the unit * Given building up the transaction is a synchronous operation, attempt
* immediately. */ * to load the unit immediately. */
if (manager_unit_cache_should_retry_load(unit)) { if (manager_unit_cache_should_retry_load(unit)) {
assert(unit->load_state == UNIT_NOT_FOUND); assert(unit->load_state == UNIT_NOT_FOUND);
unit->load_state = UNIT_STUB; unit->load_state = UNIT_STUB;
@ -989,7 +1013,7 @@ int transaction_add_job_and_dependencies(
job_type_to_string(type), unit->id); job_type_to_string(type), unit->id);
if (type == JOB_START) { if (type == JOB_START) {
/* The hard concurrency limit for slice units we already enforce when a job is enqueued. */ /* The hard concurrency limit for slice units we already enforce when a job is enqueued */
Slice *slice = SLICE(UNIT_GET_SLICE(unit)); Slice *slice = SLICE(UNIT_GET_SLICE(unit));
if (slice && slice_concurrency_hard_max_reached(slice, unit)) if (slice && slice_concurrency_hard_max_reached(slice, unit))
return sd_bus_error_setf( return sd_bus_error_setf(
@ -1115,8 +1139,8 @@ int transaction_add_job_and_dependencies(
} }
/* Process UNIT_ATOM_PROPAGATE_STOP_GRACEFUL (PropagatesStopTo=) units. We need to wait until /* Process UNIT_ATOM_PROPAGATE_STOP_GRACEFUL (PropagatesStopTo=) units. We need to wait until
* all other dependencies are processed, i.e. we're the anchor job or already in the * all other dependencies are processed, i.e. we're the anchor job or already in the recursion
* recursion that handles it. */ * that handles it. */
if (!by || FLAGS_SET(flags, TRANSACTION_PROCESS_PROPAGATE_STOP_GRACEFUL)) if (!by || FLAGS_SET(flags, TRANSACTION_PROCESS_PROPAGATE_STOP_GRACEFUL))
UNIT_FOREACH_DEPENDENCY_SAFE(dep, job->unit, UNIT_ATOM_PROPAGATE_STOP_GRACEFUL) { UNIT_FOREACH_DEPENDENCY_SAFE(dep, job->unit, UNIT_ATOM_PROPAGATE_STOP_GRACEFUL) {
JobType nt; JobType nt;
@ -1141,7 +1165,7 @@ int transaction_add_job_and_dependencies(
if (type == JOB_RELOAD) if (type == JOB_RELOAD)
transaction_add_propagate_reload_jobs(tr, job->unit, job, flags & TRANSACTION_IGNORE_ORDER); transaction_add_propagate_reload_jobs(tr, job->unit, job, flags & TRANSACTION_IGNORE_ORDER);
/* JOB_VERIFY_ACTIVE requires no dependency handling. */ /* JOB_VERIFY_ACTIVE requires no dependency handling */
return 0; return 0;
@ -1180,11 +1204,11 @@ int transaction_add_isolate_jobs(Transaction *tr, Manager *m) {
_cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
Unit *o; Unit *o;
/* Ignore aliases. */ /* Ignore aliases */
if (u->id != k) if (u->id != k)
continue; continue;
/* No need to stop inactive units. */ /* No need to stop inactive units */
if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)) && !u->job) if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)) && !u->job)
continue; continue;
@ -1219,7 +1243,7 @@ int transaction_add_triggering_jobs(Transaction *tr, Unit *u) {
UNIT_FOREACH_DEPENDENCY_SAFE(trigger, u, UNIT_ATOM_TRIGGERED_BY) { UNIT_FOREACH_DEPENDENCY_SAFE(trigger, u, UNIT_ATOM_TRIGGERED_BY) {
_cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
/* No need to stop inactive jobs. */ /* No need to stop inactive jobs */
if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(trigger)) && !trigger->job) if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(trigger)) && !trigger->job)
continue; continue;
@ -1235,7 +1259,7 @@ int transaction_add_triggering_jobs(Transaction *tr, Unit *u) {
return 0; return 0;
} }
Transaction* transaction_new(bool irreversible) { Transaction *transaction_new(bool irreversible) {
Transaction *tr; Transaction *tr;
tr = new0(Transaction, 1); tr = new0(Transaction, 1);
@ -1251,7 +1275,7 @@ Transaction* transaction_new(bool irreversible) {
return tr; return tr;
} }
Transaction* transaction_free(Transaction *tr) { Transaction *transaction_free(Transaction *tr) {
if (!tr) if (!tr)
return NULL; return NULL;
@ -1261,7 +1285,7 @@ Transaction* transaction_free(Transaction *tr) {
return mfree(tr); return mfree(tr);
} }
Transaction* transaction_abort_and_free(Transaction *tr) { Transaction *transaction_abort_and_free(Transaction *tr) {
if (!tr) if (!tr)
return NULL; return NULL;

View File

@ -144,15 +144,15 @@
#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq)) #define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
#define UNIQ __COUNTER__ #define UNIQ __COUNTER__
/* The macro is true when the code block is called first time, and is false for the second and later times. /* Note that this works differently from pthread_once(): this macro does
* Note that this works differently from pthread_once(): this macro does not synchronize code execution, i.e. * not synchronize code execution, i.e. code that is run conditionalized
* code that is run conditionalized on this macro will run concurrently to all other code conditionalized the * on this macro will run concurrently to all other code conditionalized
* same way, there's no ordering or completion enforced. */ * the same way, there's no ordering or completion enforced. */
#define ONCE __ONCE(UNIQ_T(_once_, UNIQ)) #define ONCE __ONCE(UNIQ_T(_once_, UNIQ))
#define __ONCE(o) \ #define __ONCE(o) \
({ \ ({ \
static bool (o) = false; \ static bool (o) = false; \
!__atomic_exchange_n(&(o), true, __ATOMIC_SEQ_CST); \ __atomic_exchange_n(&(o), true, __ATOMIC_SEQ_CST); \
}) })
#define U64_KB UINT64_C(1024) #define U64_KB UINT64_C(1024)

View File

@ -1829,15 +1829,9 @@ static int acquire_updated_home_record(
return r; return r;
} }
if (arg_recovery_key) {
r = identity_add_recovery_key(&json);
if (r < 0)
return r;
}
/* If the user supplied a full record, then add in lastChange, but do not override. Otherwise always /* If the user supplied a full record, then add in lastChange, but do not override. Otherwise always
* override. */ * override. */
r = update_last_change(&json, arg_pkcs11_token_uri || arg_fido2_device || arg_recovery_key, !arg_identity); r = update_last_change(&json, arg_pkcs11_token_uri || arg_fido2_device, !arg_identity);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -45,7 +45,6 @@ typedef struct ProgressInfo {
uint64_t size; uint64_t size;
bool started; bool started;
bool logged_incomplete; bool logged_incomplete;
uint64_t bps;
} ProgressInfo; } ProgressInfo;
static void progress_info_free(ProgressInfo *p) { static void progress_info_free(ProgressInfo *p) {
@ -73,10 +72,8 @@ static void progress_show(ProgressInfo *p) {
if (p->size == 0) if (p->size == 0)
log_info("Copying tree, currently at '%s'...", p->path); log_info("Copying tree, currently at '%s'...", p->path);
else if (p->bps == UINT64_MAX)
log_info("Copying tree, currently at '%s' (@%s)...", p->path, FORMAT_BYTES(p->size));
else else
log_info("Copying tree, currently at '%s' (@%s, %s/s)...", p->path, FORMAT_BYTES(p->size), FORMAT_BYTES(p->bps)); log_info("Copying tree, currently at '%s' (@%s)...", p->path, FORMAT_BYTES(p->size));
} }
static int progress_path(const char *path, const struct stat *st, void *userdata) { static int progress_path(const char *path, const struct stat *st, void *userdata) {
@ -93,13 +90,12 @@ static int progress_path(const char *path, const struct stat *st, void *userdata
return 0; return 0;
} }
static int progress_bytes(uint64_t nbytes, uint64_t bps, void *userdata) { static int progress_bytes(uint64_t nbytes, void *userdata) {
ProgressInfo *p = ASSERT_PTR(userdata); ProgressInfo *p = ASSERT_PTR(userdata);
assert(p->size != UINT64_MAX); assert(p->size != UINT64_MAX);
p->size += nbytes; p->size += nbytes;
p->bps = bps;
progress_show(p); progress_show(p);
return 0; return 0;
@ -107,7 +103,7 @@ static int progress_bytes(uint64_t nbytes, uint64_t bps, void *userdata) {
static int import_fs(int argc, char *argv[], void *userdata) { static int import_fs(int argc, char *argv[], void *userdata) {
_cleanup_(rm_rf_subvolume_and_freep) char *temp_path = NULL; _cleanup_(rm_rf_subvolume_and_freep) char *temp_path = NULL;
_cleanup_(progress_info_free) ProgressInfo progress = { .bps = UINT64_MAX }; _cleanup_(progress_info_free) ProgressInfo progress = {};
_cleanup_free_ char *l = NULL, *final_path = NULL; _cleanup_free_ char *l = NULL, *final_path = NULL;
const char *path = NULL, *local = NULL, *dest = NULL; const char *path = NULL, *local = NULL, *dest = NULL;
_cleanup_close_ int open_fd = -EBADF; _cleanup_close_ int open_fd = -EBADF;

View File

@ -274,7 +274,7 @@ static int help(void) {
" --show-cursor Print the cursor after all the entries\n" " --show-cursor Print the cursor after all the entries\n"
" --utc Express time in Coordinated Universal Time (UTC)\n" " --utc Express time in Coordinated Universal Time (UTC)\n"
" -x --catalog Add message explanations where available\n" " -x --catalog Add message explanations where available\n"
" -W --no-hostname Suppress output of hostname field\n" " --no-hostname Suppress output of hostname field\n"
" --no-full Ellipsize fields\n" " --no-full Ellipsize fields\n"
" -a --all Show all fields, including long and unprintable\n" " -a --all Show all fields, including long and unprintable\n"
" -f --follow Follow the journal\n" " -f --follow Follow the journal\n"
@ -367,6 +367,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VACUUM_SIZE, ARG_VACUUM_SIZE,
ARG_VACUUM_FILES, ARG_VACUUM_FILES,
ARG_VACUUM_TIME, ARG_VACUUM_TIME,
ARG_NO_HOSTNAME,
ARG_OUTPUT_FIELDS, ARG_OUTPUT_FIELDS,
ARG_NAMESPACE, ARG_NAMESPACE,
ARG_LIST_NAMESPACES, ARG_LIST_NAMESPACES,
@ -440,7 +441,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE }, { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE },
{ "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES }, { "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES },
{ "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME }, { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME },
{ "no-hostname", no_argument, NULL, 'W' }, { "no-hostname", no_argument, NULL, ARG_NO_HOSTNAME },
{ "output-fields", required_argument, NULL, ARG_OUTPUT_FIELDS }, { "output-fields", required_argument, NULL, ARG_OUTPUT_FIELDS },
{ "namespace", required_argument, NULL, ARG_NAMESPACE }, { "namespace", required_argument, NULL, ARG_NAMESPACE },
{ "list-namespaces", no_argument, NULL, ARG_LIST_NAMESPACES }, { "list-namespaces", no_argument, NULL, ARG_LIST_NAMESPACES },
@ -453,7 +454,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0); assert(argc >= 0);
assert(argv); assert(argv);
while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:g:c:S:U:t:T:u:INF:xrM:i:W", options, NULL)) >= 0) while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:g:c:S:U:t:T:u:INF:xrM:i:", options, NULL)) >= 0)
switch (c) { switch (c) {
@ -906,7 +907,7 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_LIST_FIELD_NAMES; arg_action = ACTION_LIST_FIELD_NAMES;
break; break;
case 'W': case ARG_NO_HOSTNAME:
arg_no_hostname = true; arg_no_hostname = true;
break; break;

View File

@ -5,7 +5,6 @@
#include "sd-event.h" #include "sd-event.h"
#include "capability-util.h"
#include "device-internal.h" #include "device-internal.h"
#include "device-private.h" #include "device-private.h"
#include "device-util.h" #include "device-util.h"
@ -26,17 +25,14 @@
#include "tests.h" #include "tests.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
#include "udev-util.h" #include "udev-util.h"
#include "virt.h"
TEST(mdio_bus) { TEST(mdio_bus) {
int r; int r;
/* For issue #37711 */ /* For issue #37711 */
if (getuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) if (getuid() != 0)
return (void) log_tests_skipped("Not privileged"); return (void) log_tests_skipped("not running as root");
if (running_in_chroot() > 0)
return (void) log_tests_skipped("Running in chroot");
ASSERT_OK(r = safe_fork("(mdio_bus)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL)); ASSERT_OK(r = safe_fork("(mdio_bus)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL));
if (r == 0) { if (r == 0) {

View File

@ -1968,19 +1968,27 @@ _public_ int sd_event_add_memory_pressure(
/* By default we want to watch memory pressure on the local cgroup, but we'll fall back on /* By default we want to watch memory pressure on the local cgroup, but we'll fall back on
* the system wide pressure if for some reason we cannot (which could be: memory controller * the system wide pressure if for some reason we cannot (which could be: memory controller
* not delegated to us, or PSI simply not available in the kernel). */ * not delegated to us, or PSI simply not available in the kernel). On legacy cgroupv1 we'll
* only use the system-wide logic. */
_cleanup_free_ char *cg = NULL; r = cg_all_unified();
r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cg);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0)
watch = "/proc/pressure/memory";
else {
_cleanup_free_ char *cg = NULL;
w = path_join("/sys/fs/cgroup", cg, "memory.pressure"); r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cg);
if (!w) if (r < 0)
return -ENOMEM; return r;
watch = w; w = path_join("/sys/fs/cgroup", cg, "memory.pressure");
watch_fallback = "/proc/pressure/memory"; if (!w)
return -ENOMEM;
watch = w;
watch_fallback = "/proc/pressure/memory";
}
/* Android uses three levels in its userspace low memory killer logic: /* Android uses three levels in its userspace low memory killer logic:
* some 70000 1000000 * some 70000 1000000

View File

@ -4,42 +4,31 @@
static SD_VARLINK_DEFINE_METHOD( static SD_VARLINK_DEFINE_METHOD(
GetInfo, GetInfo,
SD_VARLINK_FIELD_COMMENT("String identifying the vendor of this service"),
SD_VARLINK_DEFINE_OUTPUT(vendor, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_OUTPUT(vendor, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("String identifying the product implementing this service"),
SD_VARLINK_DEFINE_OUTPUT(product, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_OUTPUT(product, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Version string of this product"),
SD_VARLINK_DEFINE_OUTPUT(version, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_OUTPUT(version, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Web URL pointing to additional information about this service"),
SD_VARLINK_DEFINE_OUTPUT(url, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_OUTPUT(url, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("List of interfaces implemented by this service"),
SD_VARLINK_DEFINE_OUTPUT(interfaces, SD_VARLINK_STRING, SD_VARLINK_ARRAY)); SD_VARLINK_DEFINE_OUTPUT(interfaces, SD_VARLINK_STRING, SD_VARLINK_ARRAY));
static SD_VARLINK_DEFINE_METHOD( static SD_VARLINK_DEFINE_METHOD(
GetInterfaceDescription, GetInterfaceDescription,
SD_VARLINK_FIELD_COMMENT("Name of interface to query interface description of"),
SD_VARLINK_DEFINE_INPUT(interface, SD_VARLINK_STRING, 0), SD_VARLINK_DEFINE_INPUT(interface, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Interface description in Varlink IDL format"),
SD_VARLINK_DEFINE_OUTPUT(description, SD_VARLINK_STRING, 0)); SD_VARLINK_DEFINE_OUTPUT(description, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_ERROR( static SD_VARLINK_DEFINE_ERROR(
InterfaceNotFound, InterfaceNotFound,
SD_VARLINK_FIELD_COMMENT("Name of interface that was called but does not exist"),
SD_VARLINK_DEFINE_FIELD(interface, SD_VARLINK_STRING, 0)); SD_VARLINK_DEFINE_FIELD(interface, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_ERROR( static SD_VARLINK_DEFINE_ERROR(
MethodNotFound, MethodNotFound,
SD_VARLINK_FIELD_COMMENT("Name of method that was called but does not exist"),
SD_VARLINK_DEFINE_FIELD(method, SD_VARLINK_STRING, 0)); SD_VARLINK_DEFINE_FIELD(method, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_ERROR( static SD_VARLINK_DEFINE_ERROR(
MethodNotImplemented, MethodNotImplemented,
SD_VARLINK_FIELD_COMMENT("Name of method that was called but is not implemented."),
SD_VARLINK_DEFINE_FIELD(method, SD_VARLINK_STRING, 0)); SD_VARLINK_DEFINE_FIELD(method, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_ERROR( static SD_VARLINK_DEFINE_ERROR(
InvalidParameter, InvalidParameter,
SD_VARLINK_FIELD_COMMENT("Name of the invalid parameter"),
SD_VARLINK_DEFINE_FIELD(parameter, SD_VARLINK_STRING, 0)); SD_VARLINK_DEFINE_FIELD(parameter, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_ERROR(PermissionDenied); static SD_VARLINK_DEFINE_ERROR(PermissionDenied);
@ -50,20 +39,11 @@ static SD_VARLINK_DEFINE_ERROR(ExpectedMore);
SD_VARLINK_DEFINE_INTERFACE( SD_VARLINK_DEFINE_INTERFACE(
org_varlink_service, org_varlink_service,
"org.varlink.service", "org.varlink.service",
SD_VARLINK_INTERFACE_COMMENT("General Varlink service interface"),
SD_VARLINK_SYMBOL_COMMENT("Get service meta information"),
&vl_method_GetInfo, &vl_method_GetInfo,
SD_VARLINK_SYMBOL_COMMENT("Get description of an implemented interface in Varlink IDL format"),
&vl_method_GetInterfaceDescription, &vl_method_GetInterfaceDescription,
SD_VARLINK_SYMBOL_COMMENT("Error returned if a method is called on an unknown interface"),
&vl_error_InterfaceNotFound, &vl_error_InterfaceNotFound,
SD_VARLINK_SYMBOL_COMMENT("Error returned if an unknown method is called on an known interface"),
&vl_error_MethodNotFound, &vl_error_MethodNotFound,
SD_VARLINK_SYMBOL_COMMENT("Error returned if an method is called that is known but not implemented"),
&vl_error_MethodNotImplemented, &vl_error_MethodNotImplemented,
SD_VARLINK_SYMBOL_COMMENT("Error returned if a method is called with an invalid parameter"),
&vl_error_InvalidParameter, &vl_error_InvalidParameter,
SD_VARLINK_SYMBOL_COMMENT("General permission error"),
&vl_error_PermissionDenied, &vl_error_PermissionDenied,
SD_VARLINK_SYMBOL_COMMENT("A method was called with the 'more' flag off, but it may only be called with the flag turned on"),
&vl_error_ExpectedMore); &vl_error_ExpectedMore);

View File

@ -44,248 +44,248 @@ struct ConfigPerfItem;
%struct-type %struct-type
%includes %includes
%% %%
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, conditions) Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, conditions) Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, conditions)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, conditions) Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, conditions)
Match.KernelVersion, config_parse_net_condition, CONDITION_VERSION, offsetof(NetDev, conditions) Match.KernelVersion, config_parse_net_condition, CONDITION_VERSION, offsetof(NetDev, conditions)
Match.Version, config_parse_net_condition, CONDITION_VERSION, offsetof(NetDev, conditions) Match.Version, config_parse_net_condition, CONDITION_VERSION, offsetof(NetDev, conditions)
Match.Credential, config_parse_net_condition, CONDITION_CREDENTIAL, offsetof(NetDev, conditions) Match.Credential, config_parse_net_condition, CONDITION_CREDENTIAL, offsetof(NetDev, conditions)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, conditions) Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, conditions)
Match.Firmware, config_parse_net_condition, CONDITION_FIRMWARE, offsetof(NetDev, conditions) Match.Firmware, config_parse_net_condition, CONDITION_FIRMWARE, offsetof(NetDev, conditions)
NetDev.Description, config_parse_string, 0, offsetof(NetDev, description) NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname) NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind) NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
NetDev.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(NetDev, mtu) NetDev.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(NetDev, mtu)
NetDev.MACAddress, config_parse_netdev_hw_addr, ETH_ALEN, offsetof(NetDev, hw_addr) NetDev.MACAddress, config_parse_netdev_hw_addr, ETH_ALEN, offsetof(NetDev, hw_addr)
VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id) VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id)
VLAN.Protocol, config_parse_vlanprotocol, 0, offsetof(VLan, protocol) VLAN.Protocol, config_parse_vlanprotocol, 0, offsetof(VLan, protocol)
VLAN.GVRP, config_parse_tristate, 0, offsetof(VLan, gvrp) VLAN.GVRP, config_parse_tristate, 0, offsetof(VLan, gvrp)
VLAN.MVRP, config_parse_tristate, 0, offsetof(VLan, mvrp) VLAN.MVRP, config_parse_tristate, 0, offsetof(VLan, mvrp)
VLAN.LooseBinding, config_parse_tristate, 0, offsetof(VLan, loose_binding) VLAN.LooseBinding, config_parse_tristate, 0, offsetof(VLan, loose_binding)
VLAN.ReorderHeader, config_parse_tristate, 0, offsetof(VLan, reorder_hdr) VLAN.ReorderHeader, config_parse_tristate, 0, offsetof(VLan, reorder_hdr)
VLAN.EgressQOSMaps, config_parse_vlan_qos_maps, 0, offsetof(VLan, egress_qos_maps) VLAN.EgressQOSMaps, config_parse_vlan_qos_maps, 0, offsetof(VLan, egress_qos_maps)
VLAN.IngressQOSMaps, config_parse_vlan_qos_maps, 0, offsetof(VLan, ingress_qos_maps) VLAN.IngressQOSMaps, config_parse_vlan_qos_maps, 0, offsetof(VLan, ingress_qos_maps)
MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
MACVLAN.SourceMACAddress, config_parse_ether_addrs, 0, offsetof(MacVlan, match_source_mac) MACVLAN.SourceMACAddress, config_parse_ether_addrs, 0, offsetof(MacVlan, match_source_mac)
MACVLAN.BroadcastMulticastQueueLength, config_parse_macvlan_broadcast_queue_size, 0, offsetof(MacVlan, bc_queue_length) MACVLAN.BroadcastMulticastQueueLength, config_parse_macvlan_broadcast_queue_size, 0, offsetof(MacVlan, bc_queue_length)
MACVLAN.BroadcastQueueThreshold, config_parse_macvlan_broadcast_queue_threshold, 0, offsetof(MacVlan, bc_queue_threshold) MACVLAN.BroadcastQueueThreshold, config_parse_macvlan_broadcast_queue_threshold, 0, offsetof(MacVlan, bc_queue_threshold)
MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
MACVTAP.SourceMACAddress, config_parse_ether_addrs, 0, offsetof(MacVlan, match_source_mac) MACVTAP.SourceMACAddress, config_parse_ether_addrs, 0, offsetof(MacVlan, match_source_mac)
IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode) IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
IPVLAN.Flags, config_parse_ipvlan_flags, 0, offsetof(IPVlan, flags) IPVLAN.Flags, config_parse_ipvlan_flags, 0, offsetof(IPVlan, flags)
IPVTAP.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode) IPVTAP.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
IPVTAP.Flags, config_parse_ipvlan_flags, 0, offsetof(IPVlan, flags) IPVTAP.Flags, config_parse_ipvlan_flags, 0, offsetof(IPVlan, flags)
Tunnel.Local, config_parse_tunnel_local_address, 0, 0 Tunnel.Local, config_parse_tunnel_local_address, 0, 0
Tunnel.Remote, config_parse_tunnel_remote_address, 0, 0 Tunnel.Remote, config_parse_tunnel_remote_address, 0, 0
Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos) Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl) Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key) Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key)
Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey) Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey)
Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey) Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey)
Tunnel.DiscoverPathMTU, config_parse_tristate, 0, offsetof(Tunnel, pmtudisc) Tunnel.DiscoverPathMTU, config_parse_tristate, 0, offsetof(Tunnel, pmtudisc)
Tunnel.IgnoreDontFragment, config_parse_bool, 0, offsetof(Tunnel, ignore_df) Tunnel.IgnoreDontFragment, config_parse_bool, 0, offsetof(Tunnel, ignore_df)
Tunnel.Mode, config_parse_tunnel_mode, 0, offsetof(Tunnel, mode) Tunnel.Mode, config_parse_tunnel_mode, 0, offsetof(Tunnel, mode)
Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, 0 Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, 0
Tunnel.CopyDSCP, config_parse_bool, 0, offsetof(Tunnel, copy_dscp) Tunnel.CopyDSCP, config_parse_bool, 0, offsetof(Tunnel, copy_dscp)
Tunnel.EncapsulationLimit, config_parse_encap_limit, 0, 0 Tunnel.EncapsulationLimit, config_parse_encap_limit, 0, 0
Tunnel.Independent, config_parse_bool, 0, offsetof(Tunnel, independent) Tunnel.Independent, config_parse_bool, 0, offsetof(Tunnel, independent)
Tunnel.AssignToLoopback, config_parse_bool, 0, offsetof(Tunnel, assign_to_loopback) Tunnel.AssignToLoopback, config_parse_bool, 0, offsetof(Tunnel, assign_to_loopback)
Tunnel.AllowLocalRemote, config_parse_tristate, 0, offsetof(Tunnel, allow_localremote) Tunnel.AllowLocalRemote, config_parse_tristate, 0, offsetof(Tunnel, allow_localremote)
Tunnel.FooOverUDP, config_parse_bool, 0, offsetof(Tunnel, fou_tunnel) Tunnel.FooOverUDP, config_parse_bool, 0, offsetof(Tunnel, fou_tunnel)
Tunnel.FOUDestinationPort, config_parse_ip_port, 0, offsetof(Tunnel, fou_destination_port) Tunnel.FOUDestinationPort, config_parse_ip_port, 0, offsetof(Tunnel, fou_destination_port)
Tunnel.FOUSourcePort, config_parse_ip_port, 0, offsetof(Tunnel, encap_src_port) Tunnel.FOUSourcePort, config_parse_ip_port, 0, offsetof(Tunnel, encap_src_port)
Tunnel.Encapsulation, config_parse_fou_encap_type, 0, offsetof(Tunnel, fou_encap_type) Tunnel.Encapsulation, config_parse_fou_encap_type, 0, offsetof(Tunnel, fou_encap_type)
Tunnel.IPv6RapidDeploymentPrefix, config_parse_6rd_prefix, 0, 0 Tunnel.IPv6RapidDeploymentPrefix, config_parse_6rd_prefix, 0, 0
Tunnel.ERSPANVersion, config_parse_erspan_version, 0, offsetof(Tunnel, erspan_version) Tunnel.ERSPANVersion, config_parse_erspan_version, 0, offsetof(Tunnel, erspan_version)
Tunnel.ERSPANIndex, config_parse_erspan_index, 0, offsetof(Tunnel, erspan_index) Tunnel.ERSPANIndex, config_parse_erspan_index, 0, offsetof(Tunnel, erspan_index)
Tunnel.ERSPANDirection, config_parse_erspan_direction, 0, offsetof(Tunnel, erspan_direction) Tunnel.ERSPANDirection, config_parse_erspan_direction, 0, offsetof(Tunnel, erspan_direction)
Tunnel.ERSPANHardwareId, config_parse_erspan_hwid, 0, offsetof(Tunnel, erspan_hwid) Tunnel.ERSPANHardwareId, config_parse_erspan_hwid, 0, offsetof(Tunnel, erspan_hwid)
Tunnel.SerializeTunneledPackets, config_parse_tristate, 0, offsetof(Tunnel, gre_erspan_sequence) Tunnel.SerializeTunneledPackets, config_parse_tristate, 0, offsetof(Tunnel, gre_erspan_sequence)
Tunnel.ISATAP, config_parse_tristate, 0, offsetof(Tunnel, isatap) Tunnel.ISATAP, config_parse_tristate, 0, offsetof(Tunnel, isatap)
Tunnel.External, config_parse_bool, 0, offsetof(Tunnel, external) Tunnel.External, config_parse_bool, 0, offsetof(Tunnel, external)
FooOverUDP.Protocol, config_parse_ip_protocol, /* relax = */ true, offsetof(FouTunnel, fou_protocol) FooOverUDP.Protocol, config_parse_ip_protocol, /* relax = */ true, offsetof(FouTunnel, fou_protocol)
FooOverUDP.Encapsulation, config_parse_fou_encap_type, 0, offsetof(FouTunnel, fou_encap_type) FooOverUDP.Encapsulation, config_parse_fou_encap_type, 0, offsetof(FouTunnel, fou_encap_type)
FooOverUDP.Port, config_parse_ip_port, 0, offsetof(FouTunnel, port) FooOverUDP.Port, config_parse_ip_port, 0, offsetof(FouTunnel, port)
FooOverUDP.PeerPort, config_parse_ip_port, 0, offsetof(FouTunnel, peer_port) FooOverUDP.PeerPort, config_parse_ip_port, 0, offsetof(FouTunnel, peer_port)
FooOverUDP.Local, config_parse_fou_tunnel_address, 0, offsetof(FouTunnel, local) FooOverUDP.Local, config_parse_fou_tunnel_address, 0, offsetof(FouTunnel, local)
FooOverUDP.Peer, config_parse_fou_tunnel_address, 0, offsetof(FouTunnel, peer) FooOverUDP.Peer, config_parse_fou_tunnel_address, 0, offsetof(FouTunnel, peer)
L2TP.TunnelId, config_parse_l2tp_tunnel_id, 0, offsetof(L2tpTunnel, tunnel_id) L2TP.TunnelId, config_parse_l2tp_tunnel_id, 0, offsetof(L2tpTunnel, tunnel_id)
L2TP.PeerTunnelId, config_parse_l2tp_tunnel_id, 0, offsetof(L2tpTunnel, peer_tunnel_id) L2TP.PeerTunnelId, config_parse_l2tp_tunnel_id, 0, offsetof(L2tpTunnel, peer_tunnel_id)
L2TP.UDPSourcePort, config_parse_ip_port, 0, offsetof(L2tpTunnel, l2tp_udp_sport) L2TP.UDPSourcePort, config_parse_ip_port, 0, offsetof(L2tpTunnel, l2tp_udp_sport)
L2TP.UDPDestinationPort, config_parse_ip_port, 0, offsetof(L2tpTunnel, l2tp_udp_dport) L2TP.UDPDestinationPort, config_parse_ip_port, 0, offsetof(L2tpTunnel, l2tp_udp_dport)
L2TP.Local, config_parse_l2tp_tunnel_local_address, 0, 0 L2TP.Local, config_parse_l2tp_tunnel_local_address, 0, 0
L2TP.Remote, config_parse_l2tp_tunnel_remote_address, 0, 0 L2TP.Remote, config_parse_l2tp_tunnel_remote_address, 0, 0
L2TP.EncapsulationType, config_parse_l2tp_encap_type, 0, offsetof(L2tpTunnel, l2tp_encap_type) L2TP.EncapsulationType, config_parse_l2tp_encap_type, 0, offsetof(L2tpTunnel, l2tp_encap_type)
L2TP.UDPChecksum, config_parse_bool, 0, offsetof(L2tpTunnel, udp_csum) L2TP.UDPChecksum, config_parse_bool, 0, offsetof(L2tpTunnel, udp_csum)
L2TP.UDPCheckSum, config_parse_bool, 0, offsetof(L2tpTunnel, udp_csum) /* deprecated */ L2TP.UDPCheckSum, config_parse_bool, 0, offsetof(L2tpTunnel, udp_csum) /* deprecated */
L2TP.UDP6ChecksumRx, config_parse_bool, 0, offsetof(L2tpTunnel, udp6_csum_rx) L2TP.UDP6ChecksumRx, config_parse_bool, 0, offsetof(L2tpTunnel, udp6_csum_rx)
L2TP.UDP6CheckSumRx, config_parse_bool, 0, offsetof(L2tpTunnel, udp6_csum_rx) /* deprecated */ L2TP.UDP6CheckSumRx, config_parse_bool, 0, offsetof(L2tpTunnel, udp6_csum_rx) /* deprecated */
L2TP.UDP6ChecksumTx, config_parse_bool, 0, offsetof(L2tpTunnel, udp6_csum_tx) L2TP.UDP6ChecksumTx, config_parse_bool, 0, offsetof(L2tpTunnel, udp6_csum_tx)
L2TP.UDP6CheckSumTx, config_parse_bool, 0, offsetof(L2tpTunnel, udp6_csum_tx) /* deprecated */ L2TP.UDP6CheckSumTx, config_parse_bool, 0, offsetof(L2tpTunnel, udp6_csum_tx) /* deprecated */
L2TPSession.SessionId, config_parse_l2tp_session_id, 0, 0 L2TPSession.SessionId, config_parse_l2tp_session_id, 0, 0
L2TPSession.PeerSessionId, config_parse_l2tp_session_id, 0, 0 L2TPSession.PeerSessionId, config_parse_l2tp_session_id, 0, 0
L2TPSession.Layer2SpecificHeader, config_parse_l2tp_session_l2spec, 0, 0 L2TPSession.Layer2SpecificHeader, config_parse_l2tp_session_l2spec, 0, 0
L2TPSession.Name, config_parse_l2tp_session_name, 0, 0 L2TPSession.Name, config_parse_l2tp_session_name, 0, 0
Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer) Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
Peer.MACAddress, config_parse_netdev_hw_addr, ETH_ALEN, offsetof(Veth, hw_addr_peer) Peer.MACAddress, config_parse_netdev_hw_addr, ETH_ALEN, offsetof(Veth, hw_addr_peer)
VXCAN.Peer, config_parse_ifname, 0, offsetof(VxCan, ifname_peer) VXCAN.Peer, config_parse_ifname, 0, offsetof(VxCan, ifname_peer)
VXLAN.VNI, config_parse_uint32, 0, offsetof(VxLan, vni) VXLAN.VNI, config_parse_uint32, 0, offsetof(VxLan, vni)
VXLAN.Id, config_parse_uint32, 0, offsetof(VxLan, vni) /* deprecated */ VXLAN.Id, config_parse_uint32, 0, offsetof(VxLan, vni) /* deprecated */
VXLAN.Group, config_parse_vxlan_address, 0, offsetof(VxLan, group) VXLAN.Group, config_parse_vxlan_address, 0, offsetof(VxLan, group)
VXLAN.Local, config_parse_vxlan_address, 0, offsetof(VxLan, local) VXLAN.Local, config_parse_vxlan_address, 0, offsetof(VxLan, local)
VXLAN.Remote, config_parse_vxlan_address, 0, offsetof(VxLan, remote) VXLAN.Remote, config_parse_vxlan_address, 0, offsetof(VxLan, remote)
VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos) VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos)
VXLAN.TTL, config_parse_vxlan_ttl, 0, offsetof(VxLan, ttl) VXLAN.TTL, config_parse_vxlan_ttl, 0, offsetof(VxLan, ttl)
VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning) VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning)
VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy)
VXLAN.ReduceARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) VXLAN.ReduceARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy)
VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss) VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss)
VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss) VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss)
VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit) VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit)
VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum) VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum)
VXLAN.UDPChecksum, config_parse_bool, 0, offsetof(VxLan, udpcsum) VXLAN.UDPChecksum, config_parse_bool, 0, offsetof(VxLan, udpcsum)
VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx)
VXLAN.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) VXLAN.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx)
VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx)
VXLAN.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) VXLAN.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx)
VXLAN.RemoteChecksumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx) VXLAN.RemoteChecksumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx)
VXLAN.RemoteChecksumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx) VXLAN.RemoteChecksumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx)
VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing) VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing)
VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy) VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy)
VXLAN.GenericProtocolExtension, config_parse_bool, 0, offsetof(VxLan, generic_protocol_extension) VXLAN.GenericProtocolExtension, config_parse_bool, 0, offsetof(VxLan, generic_protocol_extension)
VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb) VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb)
VXLAN.PortRange, config_parse_port_range, 0, 0 VXLAN.PortRange, config_parse_port_range, 0, 0
VXLAN.DestinationPort, config_parse_ip_port, 0, offsetof(VxLan, dest_port) VXLAN.DestinationPort, config_parse_ip_port, 0, offsetof(VxLan, dest_port)
VXLAN.FlowLabel, config_parse_flow_label, 0, 0 VXLAN.FlowLabel, config_parse_flow_label, 0, 0
VXLAN.IPDoNotFragment, config_parse_df, 0, offsetof(VxLan, df) VXLAN.IPDoNotFragment, config_parse_df, 0, offsetof(VxLan, df)
VXLAN.Independent, config_parse_bool, 0, offsetof(VxLan, independent) VXLAN.Independent, config_parse_bool, 0, offsetof(VxLan, independent)
VXLAN.External, config_parse_bool, 0, offsetof(VxLan, external) VXLAN.External, config_parse_bool, 0, offsetof(VxLan, external)
VXLAN.VNIFilter, config_parse_bool, 0, offsetof(VxLan, vnifilter) VXLAN.VNIFilter, config_parse_bool, 0, offsetof(VxLan, vnifilter)
GENEVE.Id, config_parse_geneve_vni, 0, offsetof(Geneve, id) GENEVE.Id, config_parse_geneve_vni, 0, offsetof(Geneve, id)
GENEVE.Remote, config_parse_geneve_address, 0, offsetof(Geneve, remote) GENEVE.Remote, config_parse_geneve_address, 0, offsetof(Geneve, remote)
GENEVE.TOS, config_parse_uint8, 0, offsetof(Geneve, tos) GENEVE.TOS, config_parse_uint8, 0, offsetof(Geneve, tos)
GENEVE.TTL, config_parse_geneve_ttl, 0, offsetof(Geneve, ttl) GENEVE.TTL, config_parse_geneve_ttl, 0, offsetof(Geneve, ttl)
GENEVE.UDPChecksum, config_parse_bool, 0, offsetof(Geneve, udpcsum) GENEVE.UDPChecksum, config_parse_bool, 0, offsetof(Geneve, udpcsum)
GENEVE.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumrx) GENEVE.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumrx)
GENEVE.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumrx) GENEVE.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumrx)
GENEVE.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumtx) GENEVE.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumtx)
GENEVE.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumtx) GENEVE.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumtx)
GENEVE.DestinationPort, config_parse_ip_port, 0, offsetof(Geneve, dest_port) GENEVE.DestinationPort, config_parse_ip_port, 0, offsetof(Geneve, dest_port)
GENEVE.IPDoNotFragment, config_parse_geneve_df, 0, offsetof(Geneve, geneve_df) GENEVE.IPDoNotFragment, config_parse_geneve_df, 0, offsetof(Geneve, geneve_df)
GENEVE.FlowLabel, config_parse_geneve_flow_label, 0, 0 GENEVE.FlowLabel, config_parse_geneve_flow_label, 0, 0
GENEVE.InheritInnerProtocol, config_parse_bool, 0, offsetof(Geneve, inherit_inner_protocol) GENEVE.InheritInnerProtocol, config_parse_bool, 0, offsetof(Geneve, inherit_inner_protocol)
HSR.Ports, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(Hsr, ports) HSR.Ports, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(Hsr, ports)
HSR.Protocol, config_parse_hsr_protocol, 0, offsetof(Hsr, protocol) HSR.Protocol, config_parse_hsr_protocol, 0, offsetof(Hsr, protocol)
HSR.Supervision, config_parse_uint8, 0, offsetof(Hsr, supervision) HSR.Supervision, config_parse_uint8, 0, offsetof(Hsr, supervision)
MACsec.Port, config_parse_macsec_port, 0, 0 MACsec.Port, config_parse_macsec_port, 0, 0
MACsec.Encrypt, config_parse_tristate, 0, offsetof(MACsec, encrypt) MACsec.Encrypt, config_parse_tristate, 0, offsetof(MACsec, encrypt)
MACsecReceiveChannel.Port, config_parse_macsec_port, 0, 0 MACsecReceiveChannel.Port, config_parse_macsec_port, 0, 0
MACsecReceiveChannel.MACAddress, config_parse_macsec_hw_address, 0, 0 MACsecReceiveChannel.MACAddress, config_parse_macsec_hw_address, 0, 0
MACsecTransmitAssociation.PacketNumber, config_parse_macsec_packet_number, 0, 0 MACsecTransmitAssociation.PacketNumber, config_parse_macsec_packet_number, 0, 0
MACsecTransmitAssociation.KeyId, config_parse_macsec_key_id, 0, 0 MACsecTransmitAssociation.KeyId, config_parse_macsec_key_id, 0, 0
MACsecTransmitAssociation.Key, config_parse_macsec_key, 0, 0 MACsecTransmitAssociation.Key, config_parse_macsec_key, 0, 0
MACsecTransmitAssociation.KeyFile, config_parse_macsec_key_file, 0, 0 MACsecTransmitAssociation.KeyFile, config_parse_macsec_key_file, 0, 0
MACsecTransmitAssociation.Activate, config_parse_macsec_sa_activate, 0, 0 MACsecTransmitAssociation.Activate, config_parse_macsec_sa_activate, 0, 0
MACsecTransmitAssociation.UseForEncoding, config_parse_macsec_use_for_encoding, 0, 0 MACsecTransmitAssociation.UseForEncoding, config_parse_macsec_use_for_encoding, 0, 0
MACsecReceiveAssociation.Port, config_parse_macsec_port, 0, 0 MACsecReceiveAssociation.Port, config_parse_macsec_port, 0, 0
MACsecReceiveAssociation.MACAddress, config_parse_macsec_hw_address, 0, 0 MACsecReceiveAssociation.MACAddress, config_parse_macsec_hw_address, 0, 0
MACsecReceiveAssociation.PacketNumber, config_parse_macsec_packet_number, 0, 0 MACsecReceiveAssociation.PacketNumber, config_parse_macsec_packet_number, 0, 0
MACsecReceiveAssociation.KeyId, config_parse_macsec_key_id, 0, 0 MACsecReceiveAssociation.KeyId, config_parse_macsec_key_id, 0, 0
MACsecReceiveAssociation.Key, config_parse_macsec_key, 0, 0 MACsecReceiveAssociation.Key, config_parse_macsec_key, 0, 0
MACsecReceiveAssociation.KeyFile, config_parse_macsec_key_file, 0, 0 MACsecReceiveAssociation.KeyFile, config_parse_macsec_key_file, 0, 0
MACsecReceiveAssociation.Activate, config_parse_macsec_sa_activate, 0, 0 MACsecReceiveAssociation.Activate, config_parse_macsec_sa_activate, 0, 0
Tun.OneQueue, config_parse_warn_compat, DISABLED_LEGACY, 0 Tun.OneQueue, config_parse_warn_compat, DISABLED_LEGACY, 0
Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue) Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info) Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
Tun.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr) Tun.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr)
Tun.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, user_name) Tun.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, user_name)
Tun.Group, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, group_name) Tun.Group, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, group_name)
Tun.KeepCarrier, config_parse_bool, 0, offsetof(TunTap, keep_fd) Tun.KeepCarrier, config_parse_bool, 0, offsetof(TunTap, keep_fd)
Tap.OneQueue, config_parse_warn_compat, DISABLED_LEGACY, 0 Tap.OneQueue, config_parse_warn_compat, DISABLED_LEGACY, 0
Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue) Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info) Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
Tap.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr) Tap.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr)
Tap.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, user_name) Tap.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, user_name)
Tap.Group, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, group_name) Tap.Group, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, group_name)
Tap.KeepCarrier, config_parse_bool, 0, offsetof(TunTap, keep_fd) Tap.KeepCarrier, config_parse_bool, 0, offsetof(TunTap, keep_fd)
Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode) Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)
Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy) Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy)
Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate) Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate)
Bond.AdSelect, config_parse_bond_ad_select, 0, offsetof(Bond, ad_select) Bond.AdSelect, config_parse_bond_ad_select, 0, offsetof(Bond, ad_select)
Bond.FailOverMACPolicy, config_parse_bond_fail_over_mac, 0, offsetof(Bond, fail_over_mac) Bond.FailOverMACPolicy, config_parse_bond_fail_over_mac, 0, offsetof(Bond, fail_over_mac)
Bond.ARPIPTargets, config_parse_arp_ip_target_address, 0, 0 Bond.ARPIPTargets, config_parse_arp_ip_target_address, 0, 0
Bond.ARPValidate, config_parse_bond_arp_validate, 0, offsetof(Bond, arp_validate) Bond.ARPValidate, config_parse_bond_arp_validate, 0, offsetof(Bond, arp_validate)
Bond.ARPAllTargets, config_parse_bond_arp_all_targets, 0, offsetof(Bond, arp_all_targets) Bond.ARPAllTargets, config_parse_bond_arp_all_targets, 0, offsetof(Bond, arp_all_targets)
Bond.PrimaryReselectPolicy, config_parse_bond_primary_reselect, 0, offsetof(Bond, primary_reselect) Bond.PrimaryReselectPolicy, config_parse_bond_primary_reselect, 0, offsetof(Bond, primary_reselect)
Bond.ResendIGMP, config_parse_unsigned, 0, offsetof(Bond, resend_igmp) Bond.ResendIGMP, config_parse_unsigned, 0, offsetof(Bond, resend_igmp)
Bond.PacketsPerSlave, config_parse_unsigned, 0, offsetof(Bond, packets_per_slave) Bond.PacketsPerSlave, config_parse_unsigned, 0, offsetof(Bond, packets_per_slave)
Bond.GratuitousARP, config_parse_unsigned, 0, offsetof(Bond, num_grat_arp) Bond.GratuitousARP, config_parse_unsigned, 0, offsetof(Bond, num_grat_arp)
Bond.AllSlavesActive, config_parse_bool, 0, offsetof(Bond, all_slaves_active) Bond.AllSlavesActive, config_parse_bool, 0, offsetof(Bond, all_slaves_active)
Bond.DynamicTransmitLoadBalancing, config_parse_tristate, 0, offsetof(Bond, tlb_dynamic_lb) Bond.DynamicTransmitLoadBalancing, config_parse_tristate, 0, offsetof(Bond, tlb_dynamic_lb)
Bond.MinLinks, config_parse_unsigned, 0, offsetof(Bond, min_links) Bond.MinLinks, config_parse_unsigned, 0, offsetof(Bond, min_links)
Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon) Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon)
Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay) Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay)
Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay) Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay)
Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval) Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval)
Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval) Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval)
Bond.PeerNotifyDelaySec, config_parse_sec, 0, offsetof(Bond, peer_notify_delay) Bond.PeerNotifyDelaySec, config_parse_sec, 0, offsetof(Bond, peer_notify_delay)
Bond.AdActorSystemPriority, config_parse_ad_actor_sys_prio, 0, offsetof(Bond, ad_actor_sys_prio) Bond.AdActorSystemPriority, config_parse_ad_actor_sys_prio, 0, offsetof(Bond, ad_actor_sys_prio)
Bond.AdUserPortKey, config_parse_ad_user_port_key, 0, offsetof(Bond, ad_user_port_key) Bond.AdUserPortKey, config_parse_ad_user_port_key, 0, offsetof(Bond, ad_user_port_key)
Bond.AdActorSystem, config_parse_ad_actor_system, 0, offsetof(Bond, ad_actor_system) Bond.AdActorSystem, config_parse_ad_actor_system, 0, offsetof(Bond, ad_actor_system)
Bond.ARPMissedMax, config_parse_uint8, 0, offsetof(Bond, arp_missed_max) Bond.ARPMissedMax, config_parse_uint8, 0, offsetof(Bond, arp_missed_max)
Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time) Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time)
Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age) Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age)
Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time) Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time)
Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay) Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay)
Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority) Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority)
Bridge.GroupForwardMask, config_parse_uint16, 0, offsetof(Bridge, group_fwd_mask) Bridge.GroupForwardMask, config_parse_uint16, 0, offsetof(Bridge, group_fwd_mask)
Bridge.DefaultPVID, config_parse_default_port_vlanid, 0, offsetof(Bridge, default_pvid) Bridge.DefaultPVID, config_parse_default_port_vlanid, 0, offsetof(Bridge, default_pvid)
Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier) Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier)
Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping) Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping)
Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering) Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering)
Bridge.VLANProtocol, config_parse_vlanprotocol, 0, offsetof(Bridge, vlan_protocol) Bridge.VLANProtocol, config_parse_vlanprotocol, 0, offsetof(Bridge, vlan_protocol)
Bridge.STP, config_parse_tristate, 0, offsetof(Bridge, stp) Bridge.STP, config_parse_tristate, 0, offsetof(Bridge, stp)
Bridge.MulticastIGMPVersion, config_parse_bridge_igmp_version, 0, offsetof(Bridge, igmp_version) Bridge.MulticastIGMPVersion, config_parse_bridge_igmp_version, 0, offsetof(Bridge, igmp_version)
Bridge.FDBMaxLearned, config_parse_bridge_fdb_max_learned, 0, offsetof(Bridge, fdb_max_learned) Bridge.FDBMaxLearned, config_parse_bridge_fdb_max_learned, 0, offsetof(Bridge, fdb_max_learned)
Bridge.LinkLocalLearning, config_parse_tristate, 0, offsetof(Bridge, linklocal_learn) Bridge.LinkLocalLearning, config_parse_tristate, 0, offsetof(Bridge, linklocal_learn)
VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table) /* deprecated */ VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table) /* deprecated */
VRF.Table, config_parse_uint32, 0, offsetof(Vrf, table) VRF.Table, config_parse_uint32, 0, offsetof(Vrf, table)
BareUDP.DestinationPort, config_parse_ip_port, 0, offsetof(BareUDP, dest_port) BareUDP.DestinationPort, config_parse_ip_port, 0, offsetof(BareUDP, dest_port)
BareUDP.MinSourcePort, config_parse_ip_port, 0, offsetof(BareUDP, min_port) BareUDP.MinSourcePort, config_parse_ip_port, 0, offsetof(BareUDP, min_port)
BareUDP.EtherType, config_parse_bare_udp_iftype, 0, offsetof(BareUDP, iftype) BareUDP.EtherType, config_parse_bare_udp_iftype, 0, offsetof(BareUDP, iftype)
WireGuard.FirewallMark, config_parse_unsigned, 0, offsetof(Wireguard, fwmark) WireGuard.FirewallMark, config_parse_unsigned, 0, offsetof(Wireguard, fwmark)
WireGuard.FwMark, config_parse_unsigned, 0, offsetof(Wireguard, fwmark) /* deprecated */ WireGuard.FwMark, config_parse_unsigned, 0, offsetof(Wireguard, fwmark) /* deprecated */
WireGuard.ListenPort, config_parse_wireguard_listen_port, 0, offsetof(Wireguard, port) WireGuard.ListenPort, config_parse_wireguard_listen_port, 0, offsetof(Wireguard, port)
WireGuard.PrivateKey, config_parse_wireguard_private_key, 0, 0 WireGuard.PrivateKey, config_parse_wireguard_private_key, 0, 0
WireGuard.PrivateKeyFile, config_parse_wireguard_private_key_file, 0, 0 WireGuard.PrivateKeyFile, config_parse_wireguard_private_key_file, 0, 0
WireGuard.RouteTable, config_parse_wireguard_route_table, 0, offsetof(Wireguard, route_table) WireGuard.RouteTable, config_parse_wireguard_route_table, 0, offsetof(Wireguard, route_table)
WireGuard.RouteMetric, config_parse_wireguard_route_priority, 0, offsetof(Wireguard, route_priority) WireGuard.RouteMetric, config_parse_wireguard_route_priority, 0, offsetof(Wireguard, route_priority)
WireGuardPeer.AllowedIPs, config_parse_wireguard_allowed_ips, 0, 0 WireGuardPeer.AllowedIPs, config_parse_wireguard_allowed_ips, 0, 0
WireGuardPeer.Endpoint, config_parse_wireguard_endpoint, 0, 0 WireGuardPeer.Endpoint, config_parse_wireguard_endpoint, 0, 0
WireGuardPeer.PublicKey, config_parse_wireguard_peer_key, 0, 0 WireGuardPeer.PublicKey, config_parse_wireguard_peer_key, 0, 0
WireGuardPeer.PublicKeyFile, config_parse_wireguard_peer_key_file, 0, 0 WireGuardPeer.PublicKeyFile, config_parse_wireguard_peer_key_file, 0, 0
WireGuardPeer.PresharedKey, config_parse_wireguard_peer_key, 0, 0 WireGuardPeer.PresharedKey, config_parse_wireguard_peer_key, 0, 0
WireGuardPeer.PresharedKeyFile, config_parse_wireguard_peer_key_file, 0, 0 WireGuardPeer.PresharedKeyFile, config_parse_wireguard_peer_key_file, 0, 0
WireGuardPeer.PersistentKeepalive, config_parse_wireguard_keepalive, 0, 0 WireGuardPeer.PersistentKeepalive, config_parse_wireguard_keepalive, 0, 0
WireGuardPeer.RouteTable, config_parse_wireguard_peer_route_table, 0, 0 WireGuardPeer.RouteTable, config_parse_wireguard_peer_route_table, 0, 0
WireGuardPeer.RouteMetric, config_parse_wireguard_peer_route_priority, 0, 0 WireGuardPeer.RouteMetric, config_parse_wireguard_peer_route_priority,0, 0
Xfrm.InterfaceId, config_parse_uint32, 0, offsetof(Xfrm, if_id) Xfrm.InterfaceId, config_parse_uint32, 0, offsetof(Xfrm, if_id)
Xfrm.Independent, config_parse_bool, 0, offsetof(Xfrm, independent) Xfrm.Independent, config_parse_bool, 0, offsetof(Xfrm, independent)
BatmanAdvanced.Aggregation, config_parse_bool, 0, offsetof(BatmanAdvanced, aggregation) BatmanAdvanced.Aggregation, config_parse_bool, 0, offsetof(BatmanAdvanced, aggregation)
BatmanAdvanced.BridgeLoopAvoidance, config_parse_bool, 0, offsetof(BatmanAdvanced, bridge_loop_avoidance) BatmanAdvanced.BridgeLoopAvoidance, config_parse_bool, 0, offsetof(BatmanAdvanced, bridge_loop_avoidance)
BatmanAdvanced.DistributedArpTable, config_parse_bool, 0, offsetof(BatmanAdvanced, distributed_arp_table) BatmanAdvanced.DistributedArpTable, config_parse_bool, 0, offsetof(BatmanAdvanced, distributed_arp_table)
BatmanAdvanced.Fragmentation, config_parse_bool, 0, offsetof(BatmanAdvanced, fragmentation) BatmanAdvanced.Fragmentation, config_parse_bool, 0, offsetof(BatmanAdvanced, fragmentation)
BatmanAdvanced.GatewayMode, config_parse_batadv_gateway_mode, 0, offsetof(BatmanAdvanced, gateway_mode) BatmanAdvanced.GatewayMode, config_parse_batadv_gateway_mode, 0, offsetof(BatmanAdvanced, gateway_mode)
BatmanAdvanced.GatewayBandwithDown, config_parse_badadv_bandwidth, 0, offsetof(BatmanAdvanced, gateway_bandwidth_down) BatmanAdvanced.GatewayBandwithDown, config_parse_badadv_bandwidth, 0, offsetof(BatmanAdvanced, gateway_bandwidth_down)
BatmanAdvanced.GatewayBandwithUp, config_parse_badadv_bandwidth, 0, offsetof(BatmanAdvanced, gateway_bandwidth_up) BatmanAdvanced.GatewayBandwithUp, config_parse_badadv_bandwidth, 0, offsetof(BatmanAdvanced, gateway_bandwidth_up)
BatmanAdvanced.GatewayBandwidthDown, config_parse_badadv_bandwidth, 0, offsetof(BatmanAdvanced, gateway_bandwidth_down) BatmanAdvanced.GatewayBandwidthDown, config_parse_badadv_bandwidth, 0, offsetof(BatmanAdvanced, gateway_bandwidth_down)
BatmanAdvanced.GatewayBandwidthUp, config_parse_badadv_bandwidth, 0, offsetof(BatmanAdvanced, gateway_bandwidth_up) BatmanAdvanced.GatewayBandwidthUp, config_parse_badadv_bandwidth, 0, offsetof(BatmanAdvanced, gateway_bandwidth_up)
BatmanAdvanced.HopPenalty, config_parse_uint8, 0, offsetof(BatmanAdvanced, hop_penalty) BatmanAdvanced.HopPenalty, config_parse_uint8, 0, offsetof(BatmanAdvanced, hop_penalty)
BatmanAdvanced.OriginatorIntervalSec, config_parse_sec, 0, offsetof(BatmanAdvanced, originator_interval) BatmanAdvanced.OriginatorIntervalSec, config_parse_sec, 0, offsetof(BatmanAdvanced, originator_interval)
BatmanAdvanced.RoutingAlgorithm, config_parse_batadv_routing_algorithm, 0, offsetof(BatmanAdvanced, routing_algorithm) BatmanAdvanced.RoutingAlgorithm, config_parse_batadv_routing_algorithm, 0, offsetof(BatmanAdvanced, routing_algorithm)
IPoIB.PartitionKey, config_parse_ipoib_pkey, 0, offsetof(IPoIB, pkey) IPoIB.PartitionKey, config_parse_ipoib_pkey, 0, offsetof(IPoIB, pkey)
IPoIB.Mode, config_parse_ipoib_mode, 0, offsetof(IPoIB, mode) IPoIB.Mode, config_parse_ipoib_mode, 0, offsetof(IPoIB, mode)
IPoIB.IgnoreUserspaceMulticastGroups, config_parse_tristate, 0, offsetof(IPoIB, umcast) IPoIB.IgnoreUserspaceMulticastGroups, config_parse_tristate, 0, offsetof(IPoIB, umcast)
WLAN.PhysicalDevice, config_parse_wiphy, 0, 0 WLAN.PhysicalDevice, config_parse_wiphy, 0, 0
WLAN.Type, config_parse_wlan_iftype, 0, offsetof(WLan, iftype) WLAN.Type, config_parse_wlan_iftype, 0, offsetof(WLan, iftype)
WLAN.WDS, config_parse_tristate, 0, offsetof(WLan, wds) WLAN.WDS, config_parse_tristate, 0, offsetof(WLan, wds)

File diff suppressed because it is too large Load Diff

View File

@ -74,7 +74,7 @@ static int controlled_delay_fill_message(Link *link, QDisc *qdisc, sd_netlink_me
return 0; return 0;
} }
int config_parse_codel_u32( int config_parse_controlled_delay_u32(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -126,7 +126,7 @@ int config_parse_codel_u32(
return 0; return 0;
} }
int config_parse_codel_usec( int config_parse_controlled_delay_usec(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -191,7 +191,7 @@ int config_parse_codel_usec(
return 0; return 0;
} }
int config_parse_codel_bool( int config_parse_controlled_delay_bool(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -17,6 +17,6 @@ typedef struct ControlledDelay {
DEFINE_QDISC_CAST(CODEL, ControlledDelay); DEFINE_QDISC_CAST(CODEL, ControlledDelay);
extern const QDiscVTable codel_vtable; extern const QDiscVTable codel_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_codel_u32); CONFIG_PARSER_PROTOTYPE(config_parse_controlled_delay_u32);
CONFIG_PARSER_PROTOTYPE(config_parse_codel_usec); CONFIG_PARSER_PROTOTYPE(config_parse_controlled_delay_usec);
CONFIG_PARSER_PROTOTYPE(config_parse_codel_bool); CONFIG_PARSER_PROTOTYPE(config_parse_controlled_delay_bool);

View File

@ -94,7 +94,7 @@ static int fair_queueing_controlled_delay_fill_message(Link *link, QDisc *qdisc,
return 0; return 0;
} }
int config_parse_fq_codel_u32( int config_parse_fair_queueing_controlled_delay_u32(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -154,7 +154,7 @@ int config_parse_fq_codel_u32(
return 0; return 0;
} }
int config_parse_fq_codel_usec( int config_parse_fair_queueing_controlled_delay_usec(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -219,7 +219,7 @@ int config_parse_fq_codel_usec(
return 0; return 0;
} }
int config_parse_fq_codel_bool( int config_parse_fair_queueing_controlled_delay_bool(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -264,7 +264,7 @@ int config_parse_fq_codel_bool(
return 0; return 0;
} }
int config_parse_fq_codel_size( int config_parse_fair_queueing_controlled_delay_size(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -21,7 +21,7 @@ typedef struct FairQueueingControlledDelay {
DEFINE_QDISC_CAST(FQ_CODEL, FairQueueingControlledDelay); DEFINE_QDISC_CAST(FQ_CODEL, FairQueueingControlledDelay);
extern const QDiscVTable fq_codel_vtable; extern const QDiscVTable fq_codel_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_fq_codel_u32); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_controlled_delay_u32);
CONFIG_PARSER_PROTOTYPE(config_parse_fq_codel_usec); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_controlled_delay_usec);
CONFIG_PARSER_PROTOTYPE(config_parse_fq_codel_bool); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_controlled_delay_bool);
CONFIG_PARSER_PROTOTYPE(config_parse_fq_codel_size); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_controlled_delay_size);

View File

@ -103,7 +103,7 @@ static int fair_queueing_fill_message(Link *link, QDisc *qdisc, sd_netlink_messa
return 0; return 0;
} }
int config_parse_fq_u32( int config_parse_fair_queueing_u32(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -167,7 +167,7 @@ int config_parse_fq_u32(
return 0; return 0;
} }
int config_parse_fq_size( int config_parse_fair_queueing_size(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -235,7 +235,7 @@ int config_parse_fq_size(
return 0; return 0;
} }
int config_parse_fq_bool( int config_parse_fair_queueing_bool(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -281,7 +281,7 @@ int config_parse_fq_bool(
return 0; return 0;
} }
int config_parse_fq_usec( int config_parse_fair_queueing_usec(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -341,7 +341,7 @@ int config_parse_fq_usec(
return 0; return 0;
} }
int config_parse_fq_max_rate( int config_parse_fair_queueing_max_rate(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -22,8 +22,8 @@ typedef struct FairQueueing {
DEFINE_QDISC_CAST(FQ, FairQueueing); DEFINE_QDISC_CAST(FQ, FairQueueing);
extern const QDiscVTable fq_vtable; extern const QDiscVTable fq_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_fq_u32); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_u32);
CONFIG_PARSER_PROTOTYPE(config_parse_fq_size); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_size);
CONFIG_PARSER_PROTOTYPE(config_parse_fq_bool); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_bool);
CONFIG_PARSER_PROTOTYPE(config_parse_fq_usec); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_usec);
CONFIG_PARSER_PROTOTYPE(config_parse_fq_max_rate); CONFIG_PARSER_PROTOTYPE(config_parse_fair_queueing_max_rate);

View File

@ -65,7 +65,7 @@ static int generic_random_early_detection_verify(QDisc *qdisc) {
return 0; return 0;
} }
int config_parse_gred_u32( int config_parse_generic_random_early_detection_u32(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -131,7 +131,7 @@ int config_parse_gred_u32(
return 0; return 0;
} }
int config_parse_gred_bool( int config_parse_generic_random_early_detection_bool(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -16,5 +16,5 @@ typedef struct GenericRandomEarlyDetection {
DEFINE_QDISC_CAST(GRED, GenericRandomEarlyDetection); DEFINE_QDISC_CAST(GRED, GenericRandomEarlyDetection);
extern const QDiscVTable gred_vtable; extern const QDiscVTable gred_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_gred_u32); CONFIG_PARSER_PROTOTYPE(config_parse_generic_random_early_detection_u32);
CONFIG_PARSER_PROTOTYPE(config_parse_gred_bool); CONFIG_PARSER_PROTOTYPE(config_parse_generic_random_early_detection_bool);

View File

@ -37,7 +37,7 @@ static int heavy_hitter_filter_fill_message(Link *link, QDisc *qdisc, sd_netlink
return 0; return 0;
} }
int config_parse_hhf_packet_limit( int config_parse_heavy_hitter_filter_packet_limit(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -14,4 +14,4 @@ typedef struct HeavyHitterFilter {
DEFINE_QDISC_CAST(HHF, HeavyHitterFilter); DEFINE_QDISC_CAST(HHF, HeavyHitterFilter);
extern const QDiscVTable hhf_vtable; extern const QDiscVTable hhf_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_hhf_packet_limit); CONFIG_PARSER_PROTOTYPE(config_parse_heavy_hitter_filter_packet_limit);

View File

@ -45,7 +45,7 @@ static int hierarchy_token_bucket_fill_message(Link *link, QDisc *qdisc, sd_netl
return 0; return 0;
} }
int config_parse_htb_default_class( int config_parse_hierarchy_token_bucket_default_class(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -97,7 +97,7 @@ int config_parse_htb_default_class(
return 0; return 0;
} }
int config_parse_htb_u32( int config_parse_hierarchy_token_bucket_u32(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -239,7 +239,7 @@ static int hierarchy_token_bucket_class_fill_message(Link *link, TClass *tclass,
return 0; return 0;
} }
int config_parse_htb_class_u32( int config_parse_hierarchy_token_bucket_class_u32(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -292,7 +292,7 @@ int config_parse_htb_class_u32(
return 0; return 0;
} }
int config_parse_htb_class_size( int config_parse_hierarchy_token_bucket_class_size(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -375,7 +375,7 @@ int config_parse_htb_class_size(
return 0; return 0;
} }
int config_parse_htb_class_rate( int config_parse_hierarchy_token_bucket_class_rate(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -15,8 +15,8 @@ typedef struct HierarchyTokenBucket {
DEFINE_QDISC_CAST(HTB, HierarchyTokenBucket); DEFINE_QDISC_CAST(HTB, HierarchyTokenBucket);
extern const QDiscVTable htb_vtable; extern const QDiscVTable htb_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_htb_default_class); CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_default_class);
CONFIG_PARSER_PROTOTYPE(config_parse_htb_u32); CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_u32);
typedef struct HierarchyTokenBucketClass { typedef struct HierarchyTokenBucketClass {
TClass meta; TClass meta;
@ -34,6 +34,6 @@ typedef struct HierarchyTokenBucketClass {
DEFINE_TCLASS_CAST(HTB, HierarchyTokenBucketClass); DEFINE_TCLASS_CAST(HTB, HierarchyTokenBucketClass);
extern const TClassVTable htb_tclass_vtable; extern const TClassVTable htb_tclass_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_htb_class_u32); CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_class_u32);
CONFIG_PARSER_PROTOTYPE(config_parse_htb_class_size); CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_class_size);
CONFIG_PARSER_PROTOTYPE(config_parse_htb_class_rate); CONFIG_PARSER_PROTOTYPE(config_parse_hierarchy_token_bucket_class_rate);

View File

@ -48,7 +48,7 @@ static int network_emulator_fill_message(Link *link, QDisc *qdisc, sd_netlink_me
return 0; return 0;
} }
int config_parse_netem_delay( int config_parse_network_emulator_delay(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -109,7 +109,7 @@ int config_parse_netem_delay(
return 0; return 0;
} }
int config_parse_netem_rate( int config_parse_network_emulator_rate(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -169,7 +169,7 @@ int config_parse_netem_rate(
return 0; return 0;
} }
int config_parse_netem_packet_limit( int config_parse_network_emulator_packet_limit(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -19,6 +19,6 @@ typedef struct NetworkEmulator {
DEFINE_QDISC_CAST(NETEM, NetworkEmulator); DEFINE_QDISC_CAST(NETEM, NetworkEmulator);
extern const QDiscVTable netem_vtable; extern const QDiscVTable netem_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_netem_delay); CONFIG_PARSER_PROTOTYPE(config_parse_network_emulator_delay);
CONFIG_PARSER_PROTOTYPE(config_parse_netem_rate); CONFIG_PARSER_PROTOTYPE(config_parse_network_emulator_rate);
CONFIG_PARSER_PROTOTYPE(config_parse_netem_packet_limit); CONFIG_PARSER_PROTOTYPE(config_parse_network_emulator_packet_limit);

View File

@ -52,7 +52,7 @@ static int quick_fair_queueing_class_fill_message(Link *link, TClass *tclass, sd
return 0; return 0;
} }
int config_parse_qfq_weight( int config_parse_quick_fair_queueing_weight(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -112,7 +112,7 @@ int config_parse_qfq_weight(
return 0; return 0;
} }
int config_parse_qfq_max_packet( int config_parse_quick_fair_queueing_max_packet(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -23,5 +23,5 @@ typedef struct QuickFairQueueingClass {
DEFINE_TCLASS_CAST(QFQ, QuickFairQueueingClass); DEFINE_TCLASS_CAST(QFQ, QuickFairQueueingClass);
extern const TClassVTable qfq_tclass_vtable; extern const TClassVTable qfq_tclass_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_qfq_weight); CONFIG_PARSER_PROTOTYPE(config_parse_quick_fair_queueing_weight);
CONFIG_PARSER_PROTOTYPE(config_parse_qfq_max_packet); CONFIG_PARSER_PROTOTYPE(config_parse_quick_fair_queueing_max_packet);

View File

@ -47,7 +47,7 @@ static int stochastic_fair_blue_fill_message(Link *link, QDisc *qdisc, sd_netlin
return 0; return 0;
} }
int config_parse_sfb_u32( int config_parse_stochastic_fair_blue_u32(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -14,4 +14,4 @@ typedef struct StochasticFairBlue {
DEFINE_QDISC_CAST(SFB, StochasticFairBlue); DEFINE_QDISC_CAST(SFB, StochasticFairBlue);
extern const QDiscVTable sfb_vtable; extern const QDiscVTable sfb_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_sfb_u32); CONFIG_PARSER_PROTOTYPE(config_parse_stochastic_fair_blue_u32);

View File

@ -30,7 +30,7 @@ static int stochastic_fairness_queueing_fill_message(Link *link, QDisc *qdisc, s
return 0; return 0;
} }
int config_parse_sfq_perturb_period( int config_parse_stochastic_fairness_queueing_perturb_period(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -14,4 +14,4 @@ typedef struct StochasticFairnessQueueing {
DEFINE_QDISC_CAST(SFQ, StochasticFairnessQueueing); DEFINE_QDISC_CAST(SFQ, StochasticFairnessQueueing);
extern const QDiscVTable sfq_vtable; extern const QDiscVTable sfq_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_sfq_perturb_period); CONFIG_PARSER_PROTOTYPE(config_parse_stochastic_fairness_queueing_perturb_period);

View File

@ -108,7 +108,7 @@ static int token_bucket_filter_fill_message(Link *link, QDisc *qdisc, sd_netlink
return 0; return 0;
} }
int config_parse_tbf_size( int config_parse_token_bucket_filter_size(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -181,7 +181,7 @@ int config_parse_tbf_size(
return 0; return 0;
} }
int config_parse_tbf_rate( int config_parse_token_bucket_filter_rate(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -242,7 +242,7 @@ int config_parse_tbf_rate(
return 0; return 0;
} }
int config_parse_tbf_latency( int config_parse_token_bucket_filter_latency(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -20,6 +20,6 @@ typedef struct TokenBucketFilter {
DEFINE_QDISC_CAST(TBF, TokenBucketFilter); DEFINE_QDISC_CAST(TBF, TokenBucketFilter);
extern const QDiscVTable tbf_vtable; extern const QDiscVTable tbf_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_tbf_latency); CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_latency);
CONFIG_PARSER_PROTOTYPE(config_parse_tbf_size); CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_size);
CONFIG_PARSER_PROTOTYPE(config_parse_tbf_rate); CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_rate);

View File

@ -41,7 +41,7 @@ const QDiscVTable teql_vtable = {
.is_ready = trivial_link_equalizer_is_ready, .is_ready = trivial_link_equalizer_is_ready,
}; };
int config_parse_teql_id( int config_parse_trivial_link_equalizer_id(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -13,4 +13,4 @@ typedef struct TrivialLinkEqualizer {
DEFINE_QDISC_CAST(TEQL, TrivialLinkEqualizer); DEFINE_QDISC_CAST(TEQL, TrivialLinkEqualizer);
extern const QDiscVTable teql_vtable; extern const QDiscVTable teql_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_teql_id); CONFIG_PARSER_PROTOTYPE(config_parse_trivial_link_equalizer_id);

View File

@ -19,66 +19,66 @@ struct ConfigPerfItem;
%struct-type %struct-type
%includes %includes
%% %%
Exec.Boot, config_parse_boot, 0, 0 Exec.Boot, config_parse_boot, 0, 0
Exec.Ephemeral, config_parse_tristate, 0, offsetof(Settings, ephemeral) Exec.Ephemeral, config_parse_tristate, 0, offsetof(Settings, ephemeral)
Exec.ProcessTwo, config_parse_pid2, 0, 0 Exec.ProcessTwo, config_parse_pid2, 0, 0
Exec.Parameters, config_parse_strv, 0, offsetof(Settings, parameters) Exec.Parameters, config_parse_strv, 0, offsetof(Settings, parameters)
Exec.Environment, config_parse_strv, 0, offsetof(Settings, environment) Exec.Environment, config_parse_strv, 0, offsetof(Settings, environment)
Exec.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Settings, user) Exec.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Settings, user)
Exec.Capability, config_parse_capability, 0, offsetof(Settings, capability) Exec.Capability, config_parse_capability, 0, offsetof(Settings, capability)
Exec.AmbientCapability, config_parse_capability, 0, offsetof(Settings, ambient_capability) Exec.AmbientCapability, config_parse_capability, 0, offsetof(Settings, ambient_capability)
Exec.DropCapability, config_parse_capability, 0, offsetof(Settings, drop_capability) Exec.DropCapability, config_parse_capability, 0, offsetof(Settings, drop_capability)
Exec.KillSignal, config_parse_signal, 0, offsetof(Settings, kill_signal) Exec.KillSignal, config_parse_signal, 0, offsetof(Settings, kill_signal)
Exec.Personality, config_parse_personality, 0, offsetof(Settings, personality) Exec.Personality, config_parse_personality, 0, offsetof(Settings, personality)
Exec.MachineID, config_parse_id128, 0, offsetof(Settings, machine_id) Exec.MachineID, config_parse_id128, 0, offsetof(Settings, machine_id)
Exec.WorkingDirectory, config_parse_path, 0, offsetof(Settings, working_directory) Exec.WorkingDirectory, config_parse_path, 0, offsetof(Settings, working_directory)
Exec.PivotRoot, config_parse_pivot_root, 0, 0 Exec.PivotRoot, config_parse_pivot_root, 0, 0
Exec.PrivateUsers, config_parse_private_users, 0, 0 Exec.PrivateUsers, config_parse_private_users, 0, 0
Exec.NotifyReady, config_parse_tristate, 0, offsetof(Settings, notify_ready) Exec.NotifyReady, config_parse_tristate, 0, offsetof(Settings, notify_ready)
Exec.SystemCallFilter, config_parse_syscall_filter, 0, 0 Exec.SystemCallFilter, config_parse_syscall_filter, 0, 0
Exec.LimitCPU, config_parse_rlimit, RLIMIT_CPU, offsetof(Settings, rlimit) Exec.LimitCPU, config_parse_rlimit, RLIMIT_CPU, offsetof(Settings, rlimit)
Exec.LimitFSIZE, config_parse_rlimit, RLIMIT_FSIZE, offsetof(Settings, rlimit) Exec.LimitFSIZE, config_parse_rlimit, RLIMIT_FSIZE, offsetof(Settings, rlimit)
Exec.LimitDATA, config_parse_rlimit, RLIMIT_DATA, offsetof(Settings, rlimit) Exec.LimitDATA, config_parse_rlimit, RLIMIT_DATA, offsetof(Settings, rlimit)
Exec.LimitSTACK, config_parse_rlimit, RLIMIT_STACK, offsetof(Settings, rlimit) Exec.LimitSTACK, config_parse_rlimit, RLIMIT_STACK, offsetof(Settings, rlimit)
Exec.LimitCORE, config_parse_rlimit, RLIMIT_CORE, offsetof(Settings, rlimit) Exec.LimitCORE, config_parse_rlimit, RLIMIT_CORE, offsetof(Settings, rlimit)
Exec.LimitRSS, config_parse_rlimit, RLIMIT_RSS, offsetof(Settings, rlimit) Exec.LimitRSS, config_parse_rlimit, RLIMIT_RSS, offsetof(Settings, rlimit)
Exec.LimitNOFILE, config_parse_rlimit, RLIMIT_NOFILE, offsetof(Settings, rlimit) Exec.LimitNOFILE, config_parse_rlimit, RLIMIT_NOFILE, offsetof(Settings, rlimit)
Exec.LimitAS, config_parse_rlimit, RLIMIT_AS, offsetof(Settings, rlimit) Exec.LimitAS, config_parse_rlimit, RLIMIT_AS, offsetof(Settings, rlimit)
Exec.LimitNPROC, config_parse_rlimit, RLIMIT_NPROC, offsetof(Settings, rlimit) Exec.LimitNPROC, config_parse_rlimit, RLIMIT_NPROC, offsetof(Settings, rlimit)
Exec.LimitMEMLOCK, config_parse_rlimit, RLIMIT_MEMLOCK, offsetof(Settings, rlimit) Exec.LimitMEMLOCK, config_parse_rlimit, RLIMIT_MEMLOCK, offsetof(Settings, rlimit)
Exec.LimitLOCKS, config_parse_rlimit, RLIMIT_LOCKS, offsetof(Settings, rlimit) Exec.LimitLOCKS, config_parse_rlimit, RLIMIT_LOCKS, offsetof(Settings, rlimit)
Exec.LimitSIGPENDING, config_parse_rlimit, RLIMIT_SIGPENDING, offsetof(Settings, rlimit) Exec.LimitSIGPENDING, config_parse_rlimit, RLIMIT_SIGPENDING, offsetof(Settings, rlimit)
Exec.LimitMSGQUEUE, config_parse_rlimit, RLIMIT_MSGQUEUE, offsetof(Settings, rlimit) Exec.LimitMSGQUEUE, config_parse_rlimit, RLIMIT_MSGQUEUE, offsetof(Settings, rlimit)
Exec.LimitNICE, config_parse_rlimit, RLIMIT_NICE, offsetof(Settings, rlimit) Exec.LimitNICE, config_parse_rlimit, RLIMIT_NICE, offsetof(Settings, rlimit)
Exec.LimitRTPRIO, config_parse_rlimit, RLIMIT_RTPRIO, offsetof(Settings, rlimit) Exec.LimitRTPRIO, config_parse_rlimit, RLIMIT_RTPRIO, offsetof(Settings, rlimit)
Exec.LimitRTTIME, config_parse_rlimit, RLIMIT_RTTIME, offsetof(Settings, rlimit) Exec.LimitRTTIME, config_parse_rlimit, RLIMIT_RTTIME, offsetof(Settings, rlimit)
Exec.Hostname, config_parse_hostname, 0, offsetof(Settings, hostname) Exec.Hostname, config_parse_hostname, 0, offsetof(Settings, hostname)
Exec.NoNewPrivileges, config_parse_tristate, 0, offsetof(Settings, no_new_privileges) Exec.NoNewPrivileges, config_parse_tristate, 0, offsetof(Settings, no_new_privileges)
Exec.OOMScoreAdjust, config_parse_oom_score_adjust, 0, 0 Exec.OOMScoreAdjust, config_parse_oom_score_adjust, 0, 0
Exec.CPUAffinity, config_parse_cpu_set, 0, offsetof(Settings, cpu_set) Exec.CPUAffinity, config_parse_cpu_set, 0, offsetof(Settings, cpu_set)
Exec.ResolvConf, config_parse_resolv_conf, 0, offsetof(Settings, resolv_conf) Exec.ResolvConf, config_parse_resolv_conf, 0, offsetof(Settings, resolv_conf)
Exec.LinkJournal, config_parse_link_journal, 0, 0 Exec.LinkJournal, config_parse_link_journal, 0, 0
Exec.Timezone, config_parse_timezone_mode, 0, offsetof(Settings, timezone) Exec.Timezone, config_parse_timezone_mode, 0, offsetof(Settings, timezone)
Exec.SuppressSync, config_parse_tristate, 0, offsetof(Settings, suppress_sync) Exec.SuppressSync, config_parse_tristate, 0, offsetof(Settings, suppress_sync)
Files.ReadOnly, config_parse_tristate, 0, offsetof(Settings, read_only) Files.ReadOnly, config_parse_tristate, 0, offsetof(Settings, read_only)
Files.Volatile, config_parse_volatile_mode, 0, offsetof(Settings, volatile_mode) Files.Volatile, config_parse_volatile_mode, 0, offsetof(Settings, volatile_mode)
Files.Bind, config_parse_bind, 0, 0 Files.Bind, config_parse_bind, 0, 0
Files.BindReadOnly, config_parse_bind, 1, 0 Files.BindReadOnly, config_parse_bind, 1, 0
Files.TemporaryFileSystem, config_parse_tmpfs, 0, 0 Files.TemporaryFileSystem, config_parse_tmpfs, 0, 0
Files.Inaccessible, config_parse_inaccessible, 0, 0 Files.Inaccessible, config_parse_inaccessible, 0, 0
Files.Overlay, config_parse_overlay, 0, 0 Files.Overlay, config_parse_overlay, 0, 0
Files.OverlayReadOnly, config_parse_overlay, 1, 0 Files.OverlayReadOnly, config_parse_overlay, 1, 0
Files.PrivateUsersChown, config_parse_userns_chown, 0, offsetof(Settings, userns_ownership) Files.PrivateUsersChown, config_parse_userns_chown, 0, offsetof(Settings, userns_ownership)
Files.PrivateUsersOwnership, config_parse_userns_ownership, 0, offsetof(Settings, userns_ownership) Files.PrivateUsersOwnership, config_parse_userns_ownership, 0, offsetof(Settings, userns_ownership)
Files.BindUser, config_parse_bind_user, 0, offsetof(Settings, bind_user) Files.BindUser, config_parse_bind_user, 0, offsetof(Settings, bind_user)
Files.BindUserShell, config_parse_bind_user_shell, 0, 0 Files.BindUserShell, config_parse_bind_user_shell, 0, 0
Network.Private, config_parse_tristate, 0, offsetof(Settings, private_network) Network.Private, config_parse_tristate, 0, offsetof(Settings, private_network)
Network.NamespacePath, config_parse_path, 0, offsetof(Settings, network_namespace_path) Network.NamespacePath, config_parse_path, 0, offsetof(Settings, network_namespace_path)
Network.Interface, config_parse_network_iface_pair, 0, offsetof(Settings, network_interfaces) Network.Interface, config_parse_network_iface_pair, 0, offsetof(Settings, network_interfaces)
Network.MACVLAN, config_parse_macvlan_iface_pair, 0, offsetof(Settings, network_macvlan) Network.MACVLAN, config_parse_macvlan_iface_pair, 0, offsetof(Settings, network_macvlan)
Network.IPVLAN, config_parse_ipvlan_iface_pair, 0, offsetof(Settings, network_ipvlan) Network.IPVLAN, config_parse_ipvlan_iface_pair, 0, offsetof(Settings, network_ipvlan)
Network.VirtualEthernet, config_parse_tristate, 0, offsetof(Settings, network_veth) Network.VirtualEthernet, config_parse_tristate, 0, offsetof(Settings, network_veth)
Network.VirtualEthernetExtra, config_parse_veth_extra, 0, 0 Network.VirtualEthernetExtra, config_parse_veth_extra, 0, 0
Network.Bridge, config_parse_ifname, 0, offsetof(Settings, network_bridge) Network.Bridge, config_parse_ifname, 0, offsetof(Settings, network_bridge)
Network.Zone, config_parse_network_zone, 0, 0 Network.Zone, config_parse_network_zone, 0, 0
Network.Port, config_parse_expose_port, 0, 0 Network.Port, config_parse_expose_port, 0, 0

View File

@ -5377,7 +5377,7 @@ static int partition_format_verity_sig(Context *context, Partition *p) {
return 0; return 0;
} }
static int progress_bytes(uint64_t n_bytes, uint64_t bps, void *userdata) { static int progress_bytes(uint64_t n_bytes, void *userdata) {
Partition *p = ASSERT_PTR(userdata); Partition *p = ASSERT_PTR(userdata);
unsigned percent; unsigned percent;
@ -5395,25 +5395,14 @@ static int progress_bytes(uint64_t n_bytes, uint64_t bps, void *userdata) {
if (!ratelimit_below(&p->progress_ratelimit)) if (!ratelimit_below(&p->progress_ratelimit))
return 0; return 0;
if (bps != UINT64_MAX) (void) draw_progress_barf(
(void) draw_progress_barf( percent,
percent, "%s %s %s %s/%s",
"%s %s %s %s/%s %s/s", strna(p->copy_blocks_path),
strna(p->copy_blocks_path), glyph(GLYPH_ARROW_RIGHT),
glyph(GLYPH_ARROW_RIGHT), strna(p->definition_path),
strna(p->definition_path), FORMAT_BYTES(p->copy_blocks_done),
FORMAT_BYTES(p->copy_blocks_done), FORMAT_BYTES(p->copy_blocks_size));
FORMAT_BYTES(p->copy_blocks_size),
FORMAT_BYTES(bps));
else
(void) draw_progress_barf(
percent,
"%s %s %s %s/%s",
strna(p->copy_blocks_path),
glyph(GLYPH_ARROW_RIGHT),
strna(p->definition_path),
FORMAT_BYTES(p->copy_blocks_done),
FORMAT_BYTES(p->copy_blocks_size));
p->last_percent = percent; p->last_percent = percent;

View File

@ -18,11 +18,11 @@ struct ConfigPerfItem;
%struct-type %struct-type
%includes %includes
%% %%
Service.Name, config_parse_dnssd_name, 0, 0 Service.Name, config_parse_dnssd_registered_service_name, 0, 0
Service.Type, config_parse_dnssd_type, 0, 0 Service.Type, config_parse_dnssd_registered_service_type, 0, 0
Service.SubType, config_parse_dnssd_subtype, 0, 0 Service.SubType, config_parse_dnssd_registered_service_subtype, 0, 0
Service.Port, config_parse_ip_port, 0, offsetof(DnssdRegisteredService, port) Service.Port, config_parse_ip_port, 0, offsetof(DnssdRegisteredService, port)
Service.Priority, config_parse_uint16, 0, offsetof(DnssdRegisteredService, priority) Service.Priority, config_parse_uint16, 0, offsetof(DnssdRegisteredService, priority)
Service.Weight, config_parse_uint16, 0, offsetof(DnssdRegisteredService, weight) Service.Weight, config_parse_uint16, 0, offsetof(DnssdRegisteredService, weight)
Service.TxtText, config_parse_dnssd_txt, DNS_TXT_ITEM_TEXT, 0 Service.TxtText, config_parse_dnssd_txt, DNS_TXT_ITEM_TEXT, 0
Service.TxtData, config_parse_dnssd_txt, DNS_TXT_ITEM_DATA, 0 Service.TxtData, config_parse_dnssd_txt, DNS_TXT_ITEM_DATA, 0

View File

@ -413,7 +413,7 @@ int dnssd_signal_conflict(Manager *manager, const char *name) {
return 0; return 0;
} }
int config_parse_dnssd_name( int config_parse_dnssd_registered_service_name(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -467,7 +467,7 @@ int config_parse_dnssd_name(
return free_and_strdup_warn(&s->name_template, rvalue); return free_and_strdup_warn(&s->name_template, rvalue);
} }
int config_parse_dnssd_type( int config_parse_dnssd_registered_service_type(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -503,7 +503,7 @@ int config_parse_dnssd_type(
return 0; return 0;
} }
int config_parse_dnssd_subtype( int config_parse_dnssd_registered_service_subtype(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -63,7 +63,7 @@ int dnssd_signal_conflict(Manager *manager, const char *name);
const struct ConfigPerfItem* resolved_dnssd_gperf_lookup(const char *key, GPERF_LEN_TYPE length); const struct ConfigPerfItem* resolved_dnssd_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_name); CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_registered_service_name);
CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_subtype); CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_registered_service_subtype);
CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_type); CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_registered_service_type);
CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_txt); CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_txt);

View File

@ -26,13 +26,12 @@
#include "path-util.h" #include "path-util.h"
#include "rm-rf.h" #include "rm-rf.h"
#include "selinux-util.h" #include "selinux-util.h"
#include "set.h"
#include "signal-util.h" #include "signal-util.h"
#include "stat-util.h" #include "stat-util.h"
#include "set.h"
#include "stdio-util.h" #include "stdio-util.h"
#include "string-util.h" #include "string-util.h"
#include "sync-util.h" #include "sync-util.h"
#include "time-util.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
#include "umask-util.h" #include "umask-util.h"
#include "user-util.h" #include "user-util.h"
@ -264,10 +263,6 @@ int copy_bytes_full(
} }
} }
usec_t start_timestamp = USEC_INFINITY;
if (progress)
start_timestamp = now(CLOCK_MONOTONIC);
for (;;) { for (;;) {
ssize_t n; ssize_t n;
size_t m; size_t m;
@ -516,13 +511,7 @@ int copy_bytes_full(
try_sendfile = false; try_sendfile = false;
if (progress) { if (progress) {
usec_t t = now(CLOCK_MONOTONIC); r = progress(n, userdata);
usec_t d = usec_sub_unsigned(t, start_timestamp);
uint64_t bps = UINT64_MAX;
if (d > USEC_PER_SEC * 3U)
bps = (uint64_t) (copied_total / ((double) d / USEC_PER_SEC));
r = progress(n, bps, userdata);
if (r < 0) if (r < 0)
return r; return r;
} }

View File

@ -43,7 +43,7 @@ typedef enum DenyType {
_DENY_TYPE_INVALID = -EINVAL, _DENY_TYPE_INVALID = -EINVAL,
} DenyType; } DenyType;
typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, uint64_t bytes_per_second, void *userdata); typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata); typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata);
int copy_file_fd_at_full(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata); int copy_file_fd_at_full(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);

View File

@ -393,8 +393,6 @@ static int make_credential_host_secret(
if (fd < 0) if (fd < 0)
return log_debug_errno(fd, "Failed to create temporary file for credential host secret: %m"); return log_debug_errno(fd, "Failed to create temporary file for credential host secret: %m");
CLEANUP_TMPFILE_AT(dfd, t);
r = chattr_secret(fd, 0); r = chattr_secret(fd, 0);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to set file attributes for secrets file, ignoring: %m"); log_debug_errno(r, "Failed to set file attributes for secrets file, ignoring: %m");
@ -407,22 +405,29 @@ static int make_credential_host_secret(
r = crypto_random_bytes(buf.data, sizeof(buf.data)); r = crypto_random_bytes(buf.data, sizeof(buf.data));
if (r < 0) if (r < 0)
return r; goto fail;
r = loop_write(fd, &buf, sizeof(buf)); r = loop_write(fd, &buf, sizeof(buf));
if (r < 0) if (r < 0)
return r; goto fail;
if (fchmod(fd, 0400) < 0) if (fchmod(fd, 0400) < 0) {
return -errno; r = -errno;
goto fail;
}
if (fsync(fd) < 0) {
r = -errno;
goto fail;
}
warn_not_encrypted(fd, flags, dirname, fn); warn_not_encrypted(fd, flags, dirname, fn);
r = link_tmpfile_at(fd, dfd, t, fn, LINK_TMPFILE_SYNC); r = link_tmpfile_at(fd, dfd, t, fn, LINK_TMPFILE_SYNC);
if (r < 0) if (r < 0) {
return log_debug_errno(r, "Failed to link host key into place: %m"); log_debug_errno(r, "Failed to link host key into place: %m");
goto fail;
t = mfree(t); /* disarm CLEANUP_TMPFILE_AT() */ }
if (ret) { if (ret) {
void *copy; void *copy;
@ -435,6 +440,12 @@ static int make_credential_host_secret(
} }
return 0; return 0;
fail:
if (t && unlinkat(dfd, t, 0) < 0)
log_debug_errno(errno, "Failed to remove temporary credential key: %m");
return r;
} }
int get_credential_host_secret(CredentialSecretFlags flags, struct iovec *ret) { int get_credential_host_secret(CredentialSecretFlags flags, struct iovec *ret) {

View File

@ -89,10 +89,7 @@ static DLSYM_PROTOTYPE(elf_version) = NULL;
static DLSYM_PROTOTYPE(gelf_getphdr) = NULL; static DLSYM_PROTOTYPE(gelf_getphdr) = NULL;
static DLSYM_PROTOTYPE(gelf_getnote) = NULL; static DLSYM_PROTOTYPE(gelf_getnote) = NULL;
#endif
int dlopen_dw(void) { int dlopen_dw(void) {
#if HAVE_ELFUTILS
int r; int r;
ELF_NOTE_DLOPEN("dw", ELF_NOTE_DLOPEN("dw",
@ -141,13 +138,9 @@ int dlopen_dw(void) {
return r; return r;
return 1; return 1;
#else
return -EOPNOTSUPP;
#endif
} }
int dlopen_elf(void) { int dlopen_elf(void) {
#if HAVE_ELFUTILS
int r; int r;
ELF_NOTE_DLOPEN("elf", ELF_NOTE_DLOPEN("elf",
@ -172,13 +165,8 @@ int dlopen_elf(void) {
return r; return r;
return 1; return 1;
#else
return -EOPNOTSUPP;
#endif
} }
#if HAVE_ELFUTILS
typedef struct StackContext { typedef struct StackContext {
MemStream m; MemStream m;
Dwfl *dwfl; Dwfl *dwfl;

View File

@ -3,8 +3,10 @@
#include "forward.h" #include "forward.h"
#if HAVE_ELFUTILS
int dlopen_dw(void); int dlopen_dw(void);
int dlopen_elf(void); int dlopen_elf(void);
#endif
/* Parse an ELF object in a forked process, so that errors while iterating over /* Parse an ELF object in a forked process, so that errors while iterating over
* untrusted and potentially malicious data do not propagate to the main caller's process. * untrusted and potentially malicious data do not propagate to the main caller's process.

View File

@ -71,10 +71,7 @@ static void fido_log_propagate_handler(const char *s) {
log_debug("libfido2: %s", strempty(s)); log_debug("libfido2: %s", strempty(s));
} }
#endif
int dlopen_libfido2(void) { int dlopen_libfido2(void) {
#if HAVE_LIBFIDO2
int r; int r;
ELF_NOTE_DLOPEN("fido2", ELF_NOTE_DLOPEN("fido2",
@ -139,13 +136,8 @@ int dlopen_libfido2(void) {
sym_fido_set_log_handler(fido_log_propagate_handler); sym_fido_set_log_handler(fido_log_propagate_handler);
return 0; return 0;
#else
return -EOPNOTSUPP;
#endif
} }
#if HAVE_LIBFIDO2
static int verify_features( static int verify_features(
fido_dev_t *d, fido_dev_t *d,
const char *path, const char *path,

View File

@ -16,8 +16,6 @@ typedef enum Fido2EnrollFlags {
_FIDO2ENROLL_TYPE_INVALID = -EINVAL, _FIDO2ENROLL_TYPE_INVALID = -EINVAL,
} Fido2EnrollFlags; } Fido2EnrollFlags;
int dlopen_libfido2(void);
#if HAVE_LIBFIDO2 #if HAVE_LIBFIDO2
#include <fido.h> #include <fido.h>
@ -72,6 +70,8 @@ extern DLSYM_PROTOTYPE(fido_init);
extern DLSYM_PROTOTYPE(fido_set_log_handler); extern DLSYM_PROTOTYPE(fido_set_log_handler);
extern DLSYM_PROTOTYPE(fido_strerr); extern DLSYM_PROTOTYPE(fido_strerr);
int dlopen_libfido2(void);
static inline void fido_cbor_info_free_wrapper(fido_cbor_info_t **p) { static inline void fido_cbor_info_free_wrapper(fido_cbor_info_t **p) {
if (*p) if (*p)
sym_fido_cbor_info_free(p); sym_fido_cbor_info_free(p);

View File

@ -4,7 +4,7 @@
#include "errno-util.h" #include "errno-util.h"
#include "log.h" #include "log.h"
#include "memory-util.h" #include "memory-util.h"
#include "password-quality-util-passwdqc.h" #include "password-quality-util.h"
#include "strv.h" #include "strv.h"
#if HAVE_PASSWDQC #if HAVE_PASSWDQC
@ -18,6 +18,22 @@ DLSYM_PROTOTYPE(passwdqc_params_free) = NULL;
DLSYM_PROTOTYPE(passwdqc_check) = NULL; DLSYM_PROTOTYPE(passwdqc_check) = NULL;
DLSYM_PROTOTYPE(passwdqc_random) = NULL; DLSYM_PROTOTYPE(passwdqc_random) = NULL;
int dlopen_passwdqc(void) {
ELF_NOTE_DLOPEN("passwdqc",
"Support for password quality checks",
ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
"libpasswdqc.so.1");
return dlopen_many_sym_or_warn(
&passwdqc_dl, "libpasswdqc.so.1", LOG_DEBUG,
DLSYM_ARG(passwdqc_params_reset),
DLSYM_ARG(passwdqc_params_load),
DLSYM_ARG(passwdqc_params_parse),
DLSYM_ARG(passwdqc_params_free),
DLSYM_ARG(passwdqc_check),
DLSYM_ARG(passwdqc_random));
}
static int pwqc_allocate_context(passwdqc_params_t **ret) { static int pwqc_allocate_context(passwdqc_params_t **ret) {
_cleanup_(sym_passwdqc_params_freep) passwdqc_params_t *params = NULL; _cleanup_(sym_passwdqc_params_freep) passwdqc_params_t *params = NULL;
@ -128,23 +144,3 @@ int check_password_quality(
} }
#endif #endif
int dlopen_passwdqc(void) {
#if HAVE_PASSWDQC
ELF_NOTE_DLOPEN("passwdqc",
"Support for password quality checks",
ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
"libpasswdqc.so.1");
return dlopen_many_sym_or_warn(
&passwdqc_dl, "libpasswdqc.so.1", LOG_DEBUG,
DLSYM_ARG(passwdqc_params_reset),
DLSYM_ARG(passwdqc_params_load),
DLSYM_ARG(passwdqc_params_parse),
DLSYM_ARG(passwdqc_params_free),
DLSYM_ARG(passwdqc_check),
DLSYM_ARG(passwdqc_random));
#else
return -EOPNOTSUPP;
#endif
}

View File

@ -15,11 +15,11 @@ extern DLSYM_PROTOTYPE(passwdqc_params_free);
extern DLSYM_PROTOTYPE(passwdqc_check); extern DLSYM_PROTOTYPE(passwdqc_check);
extern DLSYM_PROTOTYPE(passwdqc_random); extern DLSYM_PROTOTYPE(passwdqc_random);
int dlopen_passwdqc(void);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(passwdqc_params_t*, sym_passwdqc_params_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(passwdqc_params_t*, sym_passwdqc_params_free, NULL);
int suggest_passwords(void); int suggest_passwords(void);
int check_password_quality(const char *password, const char *old, const char *username, char **ret_error); int check_password_quality(const char *password, const char *old, const char *username, char **ret_error);
#endif #endif
int dlopen_passwdqc(void);

View File

@ -8,7 +8,6 @@
#include "errno-util.h" #include "errno-util.h"
#include "log.h" #include "log.h"
#include "password-quality-util.h" #include "password-quality-util.h"
#include "password-quality-util-pwquality.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
@ -25,6 +24,24 @@ DLSYM_PROTOTYPE(pwquality_read_config) = NULL;
DLSYM_PROTOTYPE(pwquality_set_int_value) = NULL; DLSYM_PROTOTYPE(pwquality_set_int_value) = NULL;
DLSYM_PROTOTYPE(pwquality_strerror) = NULL; DLSYM_PROTOTYPE(pwquality_strerror) = NULL;
int dlopen_pwquality(void) {
ELF_NOTE_DLOPEN("pwquality",
"Support for password quality checks",
ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
"libpwquality.so.1");
return dlopen_many_sym_or_warn(
&pwquality_dl, "libpwquality.so.1", LOG_DEBUG,
DLSYM_ARG(pwquality_check),
DLSYM_ARG(pwquality_default_settings),
DLSYM_ARG(pwquality_free_settings),
DLSYM_ARG(pwquality_generate),
DLSYM_ARG(pwquality_get_str_value),
DLSYM_ARG(pwquality_read_config),
DLSYM_ARG(pwquality_set_int_value),
DLSYM_ARG(pwquality_strerror));
}
static void pwq_maybe_disable_dictionary(pwquality_settings_t *pwq) { static void pwq_maybe_disable_dictionary(pwquality_settings_t *pwq) {
char buf[PWQ_MAX_ERROR_MESSAGE_LEN]; char buf[PWQ_MAX_ERROR_MESSAGE_LEN];
const char *path; const char *path;
@ -146,25 +163,3 @@ int check_password_quality(const char *password, const char *old, const char *us
} }
#endif #endif
int dlopen_pwquality(void) {
#if HAVE_PWQUALITY
ELF_NOTE_DLOPEN("pwquality",
"Support for password quality checks",
ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
"libpwquality.so.1");
return dlopen_many_sym_or_warn(
&pwquality_dl, "libpwquality.so.1", LOG_DEBUG,
DLSYM_ARG(pwquality_check),
DLSYM_ARG(pwquality_default_settings),
DLSYM_ARG(pwquality_free_settings),
DLSYM_ARG(pwquality_generate),
DLSYM_ARG(pwquality_get_str_value),
DLSYM_ARG(pwquality_read_config),
DLSYM_ARG(pwquality_set_int_value),
DLSYM_ARG(pwquality_strerror));
#else
return -EOPNOTSUPP;
#endif
}

View File

@ -17,11 +17,11 @@ extern DLSYM_PROTOTYPE(pwquality_read_config);
extern DLSYM_PROTOTYPE(pwquality_set_int_value); extern DLSYM_PROTOTYPE(pwquality_set_int_value);
extern DLSYM_PROTOTYPE(pwquality_strerror); extern DLSYM_PROTOTYPE(pwquality_strerror);
int dlopen_pwquality(void);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(pwquality_settings_t*, sym_pwquality_free_settings, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(pwquality_settings_t*, sym_pwquality_free_settings, NULL);
int suggest_passwords(void); int suggest_passwords(void);
int check_password_quality(const char *password, const char *old, const char *username, char **ret_error); int check_password_quality(const char *password, const char *old, const char *username, char **ret_error);
#endif #endif
int dlopen_pwquality(void);

View File

@ -4,7 +4,6 @@
#if HAVE_QRENCODE #if HAVE_QRENCODE
#include <qrencode.h> #include <qrencode.h>
#endif
#include <stdio.h> #include <stdio.h>
#include "ansi-color.h" #include "ansi-color.h"
@ -19,15 +18,12 @@
#define UNICODE_LOWER_HALF_BLOCK UTF8("▄") #define UNICODE_LOWER_HALF_BLOCK UTF8("▄")
#define UNICODE_UPPER_HALF_BLOCK UTF8("▀") #define UNICODE_UPPER_HALF_BLOCK UTF8("▀")
#if HAVE_QRENCODE
static void *qrcode_dl = NULL; static void *qrcode_dl = NULL;
static DLSYM_PROTOTYPE(QRcode_encodeString) = NULL; static DLSYM_PROTOTYPE(QRcode_encodeString) = NULL;
static DLSYM_PROTOTYPE(QRcode_free) = NULL; static DLSYM_PROTOTYPE(QRcode_free) = NULL;
#endif
int dlopen_qrencode(void) { int dlopen_qrencode(void) {
#if HAVE_QRENCODE
int r; int r;
ELF_NOTE_DLOPEN("qrencode", ELF_NOTE_DLOPEN("qrencode",
@ -45,13 +41,8 @@ int dlopen_qrencode(void) {
} }
return r; return r;
#else
return -EOPNOTSUPP;
#endif
} }
#if HAVE_QRENCODE
static void print_border(FILE *output, unsigned width, unsigned row, unsigned column) { static void print_border(FILE *output, unsigned width, unsigned row, unsigned column) {
assert(output); assert(output);
assert(width); assert(width);
@ -185,8 +176,6 @@ static void write_qrcode(FILE *output, QRcode *qr, unsigned row, unsigned column
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(QRcode*, sym_QRcode_free, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(QRcode*, sym_QRcode_free, NULL);
#endif
int print_qrcode_full( int print_qrcode_full(
FILE *out, FILE *out,
const char *header, const char *header,
@ -197,7 +186,6 @@ int print_qrcode_full(
unsigned tty_height, unsigned tty_height,
bool check_tty) { bool check_tty) {
#if HAVE_QRENCODE
int r; int r;
/* If this is not a UTF-8 system or ANSI colors aren't supported/disabled don't print any QR /* If this is not a UTF-8 system or ANSI colors aren't supported/disabled don't print any QR
@ -247,7 +235,5 @@ int print_qrcode_full(
fputc('\n', out); fputc('\n', out);
return 0; return 0;
#else
return -EOPNOTSUPP;
#endif
} }
#endif

View File

@ -3,6 +3,9 @@
#include "forward.h" #include "forward.h"
#if HAVE_QRENCODE
int dlopen_qrencode(void);
int print_qrcode_full( int print_qrcode_full(
FILE *out, FILE *out,
const char *header, const char *header,
@ -12,8 +15,19 @@ int print_qrcode_full(
unsigned tty_width, unsigned tty_width,
unsigned tty_height, unsigned tty_height,
bool check_tty); bool check_tty);
#else
int dlopen_qrencode(void); static inline int print_qrcode_full(
FILE *out,
const char *header,
const char *string,
unsigned row,
unsigned column,
unsigned tty_width,
unsigned tty_height,
bool check_tty) {
return -EOPNOTSUPP;
}
#endif
static inline int print_qrcode(FILE *out, const char *header, const char *string) { static inline int print_qrcode(FILE *out, const char *header, const char *string) {
return print_qrcode_full(out, header, string, UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX, true); return print_qrcode_full(out, header, string, UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX, true);

View File

@ -217,10 +217,7 @@ static int dlopen_tpm2_mu(void) {
DLSYM_ARG(Tss2_MU_UINT32_Marshal)); DLSYM_ARG(Tss2_MU_UINT32_Marshal));
} }
#endif
int dlopen_tpm2(void) { int dlopen_tpm2(void) {
#if HAVE_TPM2
int r; int r;
r = dlopen_tpm2_esys(); r = dlopen_tpm2_esys();
@ -236,13 +233,8 @@ int dlopen_tpm2(void) {
return r; return r;
return 0; return 0;
#else
return -EOPNOTSUPP;
#endif
} }
#if HAVE_TPM2
void Esys_Freep(void *p) { void Esys_Freep(void *p) {
assert(p); assert(p);

View File

@ -39,14 +39,14 @@ static inline bool TPM2_PCR_MASK_VALID(uint32_t pcr_mask) {
#define TPM2_N_HASH_ALGORITHMS 4U #define TPM2_N_HASH_ALGORITHMS 4U
int dlopen_tpm2(void);
#if HAVE_TPM2 #if HAVE_TPM2
#include <tss2/tss2_esys.h> /* IWYU pragma: export */ #include <tss2/tss2_esys.h> /* IWYU pragma: export */
#include <tss2/tss2_mu.h> /* IWYU pragma: export */ #include <tss2/tss2_mu.h> /* IWYU pragma: export */
#include <tss2/tss2_rc.h> /* IWYU pragma: export */ #include <tss2/tss2_rc.h> /* IWYU pragma: export */
int dlopen_tpm2(void);
typedef struct Tpm2Context { typedef struct Tpm2Context {
unsigned n_ref; unsigned n_ref;

View File

@ -127,12 +127,11 @@ static int read_definitions(
const char *suffix, const char *suffix,
const char *node) { const char *node) {
ConfFile **files = NULL; _cleanup_strv_free_ char **files = NULL;
Transfer **transfers = NULL, **disabled = NULL; Transfer **transfers = NULL, **disabled = NULL;
size_t n_files = 0, n_transfers = 0, n_disabled = 0; size_t n_transfers = 0, n_disabled = 0;
int r; int r;
CLEANUP_ARRAY(files, n_files, conf_file_free_many);
CLEANUP_ARRAY(transfers, n_transfers, free_transfers); CLEANUP_ARRAY(transfers, n_transfers, free_transfers);
CLEANUP_ARRAY(disabled, n_disabled, free_transfers); CLEANUP_ARRAY(disabled, n_disabled, free_transfers);
@ -140,20 +139,19 @@ static int read_definitions(
assert(dirs); assert(dirs);
assert(suffix); assert(suffix);
r = conf_files_list_strv_full(suffix, arg_root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, dirs, &files, &n_files); r = conf_files_list_strv(&files, suffix, arg_root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, dirs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enumerate sysupdate.d/*%s definitions: %m", suffix); return log_error_errno(r, "Failed to enumerate sysupdate.d/*%s definitions: %m", suffix);
FOREACH_ARRAY(i, files, n_files) { STRV_FOREACH(p, files) {
_cleanup_(transfer_freep) Transfer *t = NULL; _cleanup_(transfer_freep) Transfer *t = NULL;
Transfer **appended; Transfer **appended;
ConfFile *e = *i;
t = transfer_new(c); t = transfer_new(c);
if (!t) if (!t)
return log_oom(); return log_oom();
r = transfer_read_definition(t, e->result, dirs, c->features); r = transfer_read_definition(t, *p, dirs, c->features);
if (r < 0) if (r < 0)
return r; return r;
@ -178,7 +176,7 @@ static int read_definitions(
} }
static int context_read_definitions(Context *c, const char* node, bool requires_enabled_transfers) { static int context_read_definitions(Context *c, const char* node, bool requires_enabled_transfers) {
_cleanup_strv_free_ char **dirs = NULL; _cleanup_strv_free_ char **dirs = NULL, **files = NULL;
int r; int r;
assert(c); assert(c);
@ -207,26 +205,22 @@ static int context_read_definitions(Context *c, const char* node, bool requires_
if (!dirs) if (!dirs)
return log_oom(); return log_oom();
ConfFile **files = NULL; r = conf_files_list_strv(&files,
size_t n_files = 0; ".feature",
arg_root,
CLEANUP_ARRAY(files, n_files, conf_file_free_many); CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
(const char**) dirs);
r = conf_files_list_strv_full(".feature", arg_root,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
(const char**) dirs, &files, &n_files);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enumerate sysupdate.d/*.feature definitions: %m"); return log_error_errno(r, "Failed to enumerate sysupdate.d/*.feature definitions: %m");
FOREACH_ARRAY(i, files, n_files) { STRV_FOREACH(p, files) {
_cleanup_(feature_unrefp) Feature *f = NULL; _cleanup_(feature_unrefp) Feature *f = NULL;
ConfFile *e = *i;
f = feature_new(); f = feature_new();
if (!f) if (!f)
return log_oom(); return log_oom();
r = feature_read_definition(f, e->result, (const char**) dirs); r = feature_read_definition(f, *p, (const char**) dirs);
if (r < 0) if (r < 0)
return r; return r;
@ -1548,6 +1542,8 @@ static int verb_components(int argc, char **argv, void *userdata) {
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL; _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
_cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL; _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
_cleanup_set_free_ Set *names = NULL; _cleanup_set_free_ Set *names = NULL;
_cleanup_free_ char **z = NULL; /* We use simple free() rather than strv_free() here, since set_free() will free the strings for us */
char **l = CONF_PATHS_STRV("");
bool has_default_component = false; bool has_default_component = false;
int r; int r;
@ -1557,49 +1553,65 @@ static int verb_components(int argc, char **argv, void *userdata) {
if (r < 0) if (r < 0)
return r; return r;
ConfFile **directories = NULL; STRV_FOREACH(i, l) {
size_t n_directories = 0; _cleanup_closedir_ DIR *d = NULL;
_cleanup_free_ char *p = NULL;
CLEANUP_ARRAY(directories, n_directories, conf_file_free_many); r = chase_and_opendir(*i, arg_root, CHASE_PREFIX_ROOT, &p, &d);
if (r == -ENOENT)
r = conf_files_list_strv_full(".d", arg_root, CONF_FILES_DIRECTORY, (const char * const *) CONF_PATHS_STRV(""), &directories, &n_directories);
if (r < 0)
return log_error_errno(r, "Failed to enumerate directories: %m");
FOREACH_ARRAY(i, directories, n_directories) {
ConfFile *e = *i;
if (streq(e->name, "sysupdate.d")) {
has_default_component = true;
continue; continue;
}
const char *s = startswith(e->name, "sysupdate.");
if (!s)
continue;
const char *a = endswith(s, ".d");
if (!a)
continue;
_cleanup_free_ char *n = strndup(s, a - s);
if (!n)
return log_oom();
r = component_name_valid(n);
if (r < 0) if (r < 0)
return log_error_errno(r, "Unable to validate component name '%s': %m", n); return log_error_errno(r, "Failed to open directory '%s': %m", *i);
if (r == 0)
continue;
r = set_ensure_put(&names, &string_hash_ops_free, n); for (;;) {
if (r < 0 && r != -EEXIST) _cleanup_free_ char *n = NULL;
return log_error_errno(r, "Failed to add component '%s' to set: %m", n); struct dirent *de;
TAKE_PTR(n); const char *e, *a;
de = readdir_ensure_type(d);
if (!de) {
if (errno != 0)
return log_error_errno(errno, "Failed to enumerate directory '%s': %m", p);
break;
}
if (de->d_type != DT_DIR)
continue;
if (dot_or_dot_dot(de->d_name))
continue;
if (streq(de->d_name, "sysupdate.d")) {
has_default_component = true;
continue;
}
e = startswith(de->d_name, "sysupdate.");
if (!e)
continue;
a = endswith(e, ".d");
if (!a)
continue;
n = strndup(e, a - e);
if (!n)
return log_oom();
r = component_name_valid(n);
if (r < 0)
return log_error_errno(r, "Unable to validate component name: %m");
if (r == 0)
continue;
r = set_ensure_consume(&names, &string_hash_ops_free, TAKE_PTR(n));
if (r < 0 && r != -EEXIST)
return log_error_errno(r, "Failed to add component to set: %m");
}
} }
/* We use simple free() rather than strv_free() here, since set_free() will free the strings for us */ z = set_get_strv(names);
_cleanup_free_ char **z = set_get_strv(names);
if (!z) if (!z)
return log_oom(); return log_oom();

View File

@ -68,8 +68,8 @@ simple_tests += files(
'test-bus-unit-util.c', 'test-bus-unit-util.c',
'test-bus-util.c', 'test-bus-util.c',
'test-calendarspec.c', 'test-calendarspec.c',
'test-cgroup-setup.c',
'test-cgroup-util.c', 'test-cgroup-util.c',
'test-cgroup.c',
'test-chase.c', 'test-chase.c',
'test-chid.c', 'test-chid.c',
'test-clock.c', 'test-clock.c',

View File

@ -11,7 +11,6 @@
#include "pidref.h" #include "pidref.h"
#include "process-util.h" #include "process-util.h"
#include "special.h" #include "special.h"
#include "stat-util.h"
#include "string-util.h" #include "string-util.h"
#include "tests.h" #include "tests.h"
@ -335,36 +334,6 @@ TEST(controller_is_valid) {
assert_se(!cg_controller_is_valid("tatü")); assert_se(!cg_controller_is_valid("tatü"));
} }
TEST(cg_split_spec) {
char *c, *p;
ASSERT_OK_ZERO(cg_split_spec("foobar:/", &c, &p));
ASSERT_STREQ(c, "foobar");
ASSERT_STREQ(p, "/");
c = mfree(c);
p = mfree(p);
ASSERT_OK_ZERO(cg_split_spec("foobar:", &c, &p));
c = mfree(c);
p = mfree(p);
ASSERT_FAIL(cg_split_spec("foobar:asdfd", &c, &p));
ASSERT_FAIL(cg_split_spec(":///", &c, &p));
ASSERT_FAIL(cg_split_spec(":", &c, &p));
ASSERT_FAIL(cg_split_spec("", &c, &p));
ASSERT_FAIL(cg_split_spec("fo/obar:/", &c, &p));
ASSERT_OK(cg_split_spec("/", &c, &p));
ASSERT_NULL(c);
ASSERT_STREQ(p, "/");
p = mfree(p);
ASSERT_OK(cg_split_spec("foo", &c, &p));
ASSERT_STREQ(c, "foo");
ASSERT_NULL(p);
c = mfree(c);
}
static void test_slice_to_path_one(const char *unit, const char *path, int error) { static void test_slice_to_path_one(const char *unit, const char *path, int error) {
_cleanup_free_ char *ret = NULL; _cleanup_free_ char *ret = NULL;
int r; int r;
@ -463,7 +432,7 @@ TEST(cg_get_keyed_attribute) {
int r; int r;
r = cg_get_keyed_attribute("cpu", "/init.scope", "no_such_file", STRV_MAKE("no_such_attr"), &val); r = cg_get_keyed_attribute("cpu", "/init.scope", "no_such_file", STRV_MAKE("no_such_attr"), &val);
if (r == -ENOMEDIUM || ERRNO_IS_PRIVILEGE(r)) { if (IN_SET(r, -ENOMEDIUM, -ENOENT) || ERRNO_IS_PRIVILEGE(r)) {
log_info_errno(r, "Skipping most of %s, /sys/fs/cgroup not accessible: %m", __func__); log_info_errno(r, "Skipping most of %s, /sys/fs/cgroup not accessible: %m", __func__);
return; return;
} }
@ -504,45 +473,4 @@ TEST(bfq_weight_conversion) {
assert_se(BFQ_WEIGHT(10000) == 1000); assert_se(BFQ_WEIGHT(10000) == 1000);
} }
TEST(cgroupid) {
_cleanup_free_ char *p = NULL, *p2 = NULL;
_cleanup_close_ int fd = -EBADF, fd2 = -EBADF;
uint64_t id, id2;
int r;
r = cg_all_unified();
if (IN_SET(r, -ENOMEDIUM, -ENOENT))
return (void) log_tests_skipped("cgroupfs is not mounted");
if (r == 0)
return (void) log_tests_skipped("skipping cgroupid test, not running in unified mode");
ASSERT_OK_POSITIVE(r);
fd = cg_path_open(SYSTEMD_CGROUP_CONTROLLER, "/");
ASSERT_OK(fd);
ASSERT_OK(fd_get_path(fd, &p));
ASSERT_TRUE(path_equal(p, "/sys/fs/cgroup"));
ASSERT_OK(cg_fd_get_cgroupid(fd, &id));
fd2 = cg_cgroupid_open(fd, id);
if (ERRNO_IS_NEG_PRIVILEGE(fd2))
log_notice("Skipping open-by-cgroup-id test because lacking privs.");
else if (ERRNO_IS_NEG_NOT_SUPPORTED(fd2))
log_notice("Skipping open-by-cgroup-id test because syscall is missing or blocked.");
else {
ASSERT_OK(fd2);
ASSERT_OK(fd_get_path(fd2, &p2));
ASSERT_TRUE(path_equal(p2, "/sys/fs/cgroup"));
ASSERT_OK(cg_fd_get_cgroupid(fd2, &id2));
ASSERT_EQ(id, id2);
ASSERT_OK_EQ(inode_same_at(fd, NULL, fd2, NULL, AT_EMPTY_PATH), true);
}
}
DEFINE_TEST_MAIN(LOG_DEBUG); DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -3,11 +3,43 @@
#include "cgroup-setup.h" #include "cgroup-setup.h"
#include "cgroup-util.h" #include "cgroup-util.h"
#include "errno-util.h" #include "errno-util.h"
#include "fd-util.h"
#include "path-util.h" #include "path-util.h"
#include "process-util.h" #include "process-util.h"
#include "stat-util.h"
#include "string-util.h" #include "string-util.h"
#include "tests.h" #include "tests.h"
TEST(cg_split_spec) {
char *c, *p;
ASSERT_OK_ZERO(cg_split_spec("foobar:/", &c, &p));
ASSERT_STREQ(c, "foobar");
ASSERT_STREQ(p, "/");
c = mfree(c);
p = mfree(p);
ASSERT_OK_ZERO(cg_split_spec("foobar:", &c, &p));
c = mfree(c);
p = mfree(p);
ASSERT_FAIL(cg_split_spec("foobar:asdfd", &c, &p));
ASSERT_FAIL(cg_split_spec(":///", &c, &p));
ASSERT_FAIL(cg_split_spec(":", &c, &p));
ASSERT_FAIL(cg_split_spec("", &c, &p));
ASSERT_FAIL(cg_split_spec("fo/obar:/", &c, &p));
ASSERT_OK(cg_split_spec("/", &c, &p));
ASSERT_NULL(c);
ASSERT_STREQ(p, "/");
p = mfree(p);
ASSERT_OK(cg_split_spec("foo", &c, &p));
ASSERT_STREQ(c, "foo");
ASSERT_NULL(p);
c = mfree(c);
}
TEST(cg_create) { TEST(cg_create) {
int r; int r;
@ -86,4 +118,45 @@ TEST(cg_create) {
ASSERT_OK(cg_trim(test_b, true)); ASSERT_OK(cg_trim(test_b, true));
} }
TEST(id) {
_cleanup_free_ char *p = NULL, *p2 = NULL;
_cleanup_close_ int fd = -EBADF, fd2 = -EBADF;
uint64_t id, id2;
int r;
r = cg_all_unified();
if (IN_SET(r, -ENOMEDIUM, -ENOENT))
return (void) log_tests_skipped("cgroupfs is not mounted");
if (r == 0)
return (void) log_tests_skipped("skipping cgroupid test, not running in unified mode");
ASSERT_OK_POSITIVE(r);
fd = cg_path_open(SYSTEMD_CGROUP_CONTROLLER, "/");
ASSERT_OK(fd);
ASSERT_OK(fd_get_path(fd, &p));
ASSERT_TRUE(path_equal(p, "/sys/fs/cgroup"));
ASSERT_OK(cg_fd_get_cgroupid(fd, &id));
fd2 = cg_cgroupid_open(fd, id);
if (ERRNO_IS_NEG_PRIVILEGE(fd2))
log_notice("Skipping open-by-cgroup-id test because lacking privs.");
else if (ERRNO_IS_NEG_NOT_SUPPORTED(fd2))
log_notice("Skipping open-by-cgroup-id test because syscall is missing or blocked.");
else {
ASSERT_OK(fd2);
ASSERT_OK(fd_get_path(fd2, &p2));
ASSERT_TRUE(path_equal(p2, "/sys/fs/cgroup"));
ASSERT_OK(cg_fd_get_cgroupid(fd2, &id2));
ASSERT_EQ(id, id2);
ASSERT_OK_EQ(inode_same_at(fd, NULL, fd2, NULL, AT_EMPTY_PATH), true);
}
}
DEFINE_TEST_MAIN(LOG_DEBUG); DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -19,9 +19,6 @@
#include "tests.h" #include "tests.h"
#include "tpm2-util.h" #include "tpm2-util.h"
#define ASSERT_DLOPEN(func, cond) \
cond ? ASSERT_OK(func()) : ASSERT_ERROR(func(), EOPNOTSUPP)
static int run(int argc, char **argv) { static int run(int argc, char **argv) {
test_setup_logging(LOG_DEBUG); test_setup_logging(LOG_DEBUG);
@ -29,25 +26,78 @@ static int run(int argc, char **argv) {
* where .so versions change and distributions update, but systemd doesn't have the new so names * where .so versions change and distributions update, but systemd doesn't have the new so names
* around yet. */ * around yet. */
ASSERT_DLOPEN(dlopen_idn, HAVE_LIBIDN2 || HAVE_LIBIDN); #if HAVE_LIBIDN2 || HAVE_LIBIDN
ASSERT_DLOPEN(dlopen_cryptsetup, HAVE_LIBCRYPTSETUP); assert_se(dlopen_idn() >= 0);
ASSERT_DLOPEN(dlopen_passwdqc, HAVE_PASSWDQC); #endif
ASSERT_DLOPEN(dlopen_pwquality, HAVE_PWQUALITY);
ASSERT_DLOPEN(dlopen_qrencode, HAVE_QRENCODE); #if HAVE_LIBCRYPTSETUP
ASSERT_DLOPEN(dlopen_tpm2, HAVE_TPM2); assert_se(dlopen_cryptsetup() >= 0);
ASSERT_DLOPEN(dlopen_libfido2, HAVE_LIBFIDO2); #endif
ASSERT_DLOPEN(dlopen_bpf, HAVE_LIBBPF);
ASSERT_DLOPEN(dlopen_dw, HAVE_ELFUTILS); #if HAVE_PASSWDQC
ASSERT_DLOPEN(dlopen_elf, HAVE_ELFUTILS); assert_se(dlopen_passwdqc() >= 0);
ASSERT_DLOPEN(dlopen_pcre2, HAVE_PCRE2); #endif
ASSERT_DLOPEN(dlopen_p11kit, HAVE_P11KIT);
ASSERT_DLOPEN(dlopen_libarchive, HAVE_LIBARCHIVE); #if HAVE_PWQUALITY
ASSERT_DLOPEN(dlopen_lz4, HAVE_LZ4); assert_se(dlopen_pwquality() >= 0);
ASSERT_DLOPEN(dlopen_zstd, HAVE_ZSTD); #endif
ASSERT_DLOPEN(dlopen_lzma, HAVE_XZ);
ASSERT_DLOPEN(dlopen_gcrypt, HAVE_GCRYPT); #if HAVE_QRENCODE
ASSERT_DLOPEN(dlopen_libkmod, HAVE_KMOD); assert_se(dlopen_qrencode() >= 0);
ASSERT_DLOPEN(dlopen_libapparmor, HAVE_APPARMOR); #endif
#if HAVE_TPM2
assert_se(dlopen_tpm2() >= 0);
#endif
#if HAVE_LIBFIDO2
assert_se(dlopen_libfido2() >= 0);
#endif
#if HAVE_LIBBPF
assert_se(dlopen_bpf() >= 0);
#endif
#if HAVE_ELFUTILS
assert_se(dlopen_dw() >= 0);
assert_se(dlopen_elf() >= 0);
#endif
#if HAVE_PCRE2
assert_se(dlopen_pcre2() >= 0);
#endif
#if HAVE_P11KIT
assert_se(dlopen_p11kit() >= 0);
#endif
#if HAVE_LIBARCHIVE
assert_se(dlopen_libarchive() >= 0);
#endif
#if HAVE_LZ4
assert_se(dlopen_lz4() >= 0);
#endif
#if HAVE_ZSTD
assert_se(dlopen_zstd() >= 0);
#endif
#if HAVE_XZ
assert_se(dlopen_lzma() >= 0);
#endif
#if HAVE_GCRYPT
assert_se(initialize_libgcrypt(/* secmem= */ false) >= 0);
#endif
#if HAVE_KMOD
assert_se(dlopen_libkmod() >= 0);
#endif
#if HAVE_APPARMOR
assert_se(dlopen_libapparmor() >= 0);
#endif
return 0; return 0;
} }

View File

@ -1613,9 +1613,6 @@ static int intro(void) {
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0)
return log_tests_skipped("not privileged"); return log_tests_skipped("not privileged");
if (running_in_chroot() > 0)
return log_tests_skipped("running in chroot");
if (enter_cgroup_subroot(NULL) == -ENOMEDIUM) if (enter_cgroup_subroot(NULL) == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");

View File

@ -42,22 +42,6 @@ static void test_file(void) {
assert_se(startswith(__FILE__, RELATIVE_SOURCE_PATH "/")); assert_se(startswith(__FILE__, RELATIVE_SOURCE_PATH "/"));
} }
static void test_log_once_impl(void) {
log_once(LOG_INFO, "This should be logged in LOG_INFO at first, then in LOG_DEBUG later.");
log_once(LOG_DEBUG, "This should be logged only once in LOG_DEBUG.");
ASSERT_ERROR(log_once_errno(LOG_INFO, SYNTHETIC_ERRNO(ENOANO),
"This should be logged with errno in LOG_INFO at first, then in LOG_DEBUG later: %m"),
ENOANO);
ASSERT_ERROR(log_once_errno(LOG_DEBUG, SYNTHETIC_ERRNO(EBADMSG),
"This should be logged only once with errno in LOG_DEBUG: %m"),
EBADMSG);
}
static void test_log_once(void) {
for (unsigned i = 0; i < 4; i++)
test_log_once_impl();
}
static void test_log_struct(void) { static void test_log_struct(void) {
log_struct(LOG_INFO, log_struct(LOG_INFO,
"MESSAGE=Waldo PID="PID_FMT" (no errno)", getpid_cached(), "MESSAGE=Waldo PID="PID_FMT" (no errno)", getpid_cached(),
@ -249,8 +233,6 @@ int main(int argc, char* argv[]) {
assert_se(log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), "foo") == -EUCLEAN); assert_se(log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), "foo") == -EUCLEAN);
test_log_once();
for (int target = 0; target < _LOG_TARGET_MAX; target++) { for (int target = 0; target < _LOG_TARGET_MAX; target++) {
log_set_target(target); log_set_target(target);
log_open(); log_open();

View File

@ -1102,20 +1102,4 @@ TEST(u64_multiply_safe) {
assert_se(u64_multiply_safe(UINT64_MAX, UINT64_MAX) == 0); assert_se(u64_multiply_safe(UINT64_MAX, UINT64_MAX) == 0);
} }
static void test_once_impl(void) {
static unsigned count = 0;
if (ONCE) {
log_info("This should be logged only once.");
count++;
}
ASSERT_EQ(count, 1u);
}
TEST(once) {
for (unsigned i = 0; i < 20; i++)
test_once_impl();
}
DEFINE_TEST_MAIN(LOG_INFO); DEFINE_TEST_MAIN(LOG_INFO);

View File

@ -23,23 +23,6 @@
#include "strv.h" #include "strv.h"
#include "tests.h" #include "tests.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
#include "virt.h"
#define FORK_COMMON_FLAGS \
(FORK_CLOSE_ALL_FDS | \
FORK_RESET_SIGNALS | \
FORK_DEATHSIG_SIGTERM | \
FORK_LOG | \
FORK_REOPEN_LOG | \
FORK_WAIT | \
FORK_NEW_MOUNTNS | \
FORK_MOUNTNS_SLAVE)
#define CHECK_PRIV \
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) \
return (void) log_tests_skipped("Not privileged"); \
if (running_in_chroot() > 0) \
return (void) log_tests_skipped("running in chroot");
TEST(mount_option_mangle) { TEST(mount_option_mangle) {
char *opts = NULL; char *opts = NULL;
@ -149,9 +132,11 @@ TEST(mount_flags_to_string) {
TEST(bind_remount_recursive) { TEST(bind_remount_recursive) {
_cleanup_(rm_rf_physical_and_freep) char *tmp = NULL; _cleanup_(rm_rf_physical_and_freep) char *tmp = NULL;
_cleanup_free_ char *subdir = NULL; _cleanup_free_ char *subdir = NULL;
int r;
CHECK_PRIV; if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
(void) log_tests_skipped("not running privileged");
return;
}
assert_se(mkdtemp_malloc("/tmp/XXXXXX", &tmp) >= 0); assert_se(mkdtemp_malloc("/tmp/XXXXXX", &tmp) >= 0);
subdir = path_join(tmp, "subdir"); subdir = path_join(tmp, "subdir");
@ -159,9 +144,15 @@ TEST(bind_remount_recursive) {
assert_se(mkdir(subdir, 0755) >= 0); assert_se(mkdir(subdir, 0755) >= 0);
FOREACH_STRING(p, "/usr", "/sys", "/", tmp) { FOREACH_STRING(p, "/usr", "/sys", "/", tmp) {
ASSERT_OK(r = safe_fork("(bind-remount-recursive)", FORK_COMMON_FLAGS, NULL)); pid_t pid;
if (r == 0) { /* child */
pid = fork();
assert_se(pid >= 0);
if (pid == 0) {
struct statvfs svfs; struct statvfs svfs;
/* child */
assert_se(detach_mount_namespace() >= 0);
/* Check that the subdir is writable (it must be because it's in /tmp) */ /* Check that the subdir is writable (it must be because it's in /tmp) */
assert_se(statvfs(subdir, &svfs) >= 0); assert_se(statvfs(subdir, &svfs) >= 0);
@ -187,18 +178,29 @@ TEST(bind_remount_recursive) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("test-remount-rec", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
} }
TEST(bind_remount_one) { TEST(bind_remount_one) {
int r; pid_t pid;
CHECK_PRIV; if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
(void) log_tests_skipped("not running privileged");
return;
}
pid = fork();
assert_se(pid >= 0);
if (pid == 0) {
/* child */
ASSERT_OK(r = safe_fork("(remount-one-with-mountinfo)", FORK_COMMON_FLAGS, NULL));
if (r == 0) { /* child */
_cleanup_fclose_ FILE *proc_self_mountinfo = NULL; _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
assert_se(detach_mount_namespace() >= 0);
assert_se(fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo) >= 0); assert_se(fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo) >= 0);
assert_se(bind_remount_one_with_mountinfo("/run", MS_RDONLY, MS_RDONLY, proc_self_mountinfo) >= 0); assert_se(bind_remount_one_with_mountinfo("/run", MS_RDONLY, MS_RDONLY, proc_self_mountinfo) >= 0);
@ -210,8 +212,16 @@ TEST(bind_remount_one) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
ASSERT_OK(r = safe_fork("(remount-one)", FORK_COMMON_FLAGS, NULL)); assert_se(wait_for_terminate_and_check("test-remount-one-with-mountinfo", pid, WAIT_LOG) == EXIT_SUCCESS);
if (r == 0) { /* child */
pid = fork();
assert_se(pid >= 0);
if (pid == 0) {
/* child */
assert_se(detach_mount_namespace() >= 0);
assert_se(bind_remount_one("/run", MS_RDONLY, MS_RDONLY) >= 0); assert_se(bind_remount_one("/run", MS_RDONLY, MS_RDONLY) >= 0);
assert_se(bind_remount_one("/run", MS_NOEXEC, MS_RDONLY|MS_NOEXEC) >= 0); assert_se(bind_remount_one("/run", MS_NOEXEC, MS_RDONLY|MS_NOEXEC) >= 0);
assert_se(bind_remount_one("/proc/idontexist", MS_RDONLY, MS_RDONLY) == -ENOENT); assert_se(bind_remount_one("/proc/idontexist", MS_RDONLY, MS_RDONLY) == -ENOENT);
@ -220,6 +230,8 @@ TEST(bind_remount_one) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("test-remount-one", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(make_mount_point_inode) { TEST(make_mount_point_inode) {
@ -271,7 +283,10 @@ TEST(make_mount_switch_root) {
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;
int r; int r;
CHECK_PRIV; if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
(void) log_tests_skipped("not running privileged");
return;
}
assert_se(mkdtemp_malloc(NULL, &t) >= 0); assert_se(mkdtemp_malloc(NULL, &t) >= 0);
@ -290,7 +305,18 @@ TEST(make_mount_switch_root) {
}; };
FOREACH_ELEMENT(i, table) { FOREACH_ELEMENT(i, table) {
ASSERT_OK(r = safe_fork("(switch-root)", FORK_COMMON_FLAGS, NULL)); r = safe_fork("(switch-root)",
FORK_RESET_SIGNALS |
FORK_CLOSE_ALL_FDS |
FORK_DEATHSIG_SIGTERM |
FORK_WAIT |
FORK_REOPEN_LOG |
FORK_LOG |
FORK_NEW_MOUNTNS |
FORK_MOUNTNS_SLAVE,
NULL);
assert_se(r >= 0);
if (r == 0) { if (r == 0) {
assert_se(make_mount_point(i->path) >= 0); assert_se(make_mount_point(i->path) >= 0);
assert_se(mount_switch_root_full(i->path, /* mount_propagation_flag= */ 0, i->force_ms_move) >= 0); assert_se(mount_switch_root_full(i->path, /* mount_propagation_flag= */ 0, i->force_ms_move) >= 0);
@ -331,10 +357,23 @@ TEST(umount_recursive) {
int r; int r;
CHECK_PRIV;
FOREACH_ELEMENT(t, test_table) { FOREACH_ELEMENT(t, test_table) {
ASSERT_OK(r = safe_fork("(umount-rec)", FORK_COMMON_FLAGS, NULL));
r = safe_fork("(umount-rec)",
FORK_RESET_SIGNALS |
FORK_CLOSE_ALL_FDS |
FORK_DEATHSIG_SIGTERM |
FORK_WAIT |
FORK_REOPEN_LOG |
FORK_LOG |
FORK_NEW_MOUNTNS |
FORK_MOUNTNS_SLAVE,
NULL);
if (ERRNO_IS_NEG_PRIVILEGE(r))
return (void) log_notice("Skipping umount_recursive() test, lacking privileges");
assert_se(r >= 0);
if (r == 0) { /* child */ if (r == 0) { /* child */
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
@ -383,7 +422,10 @@ TEST(fd_make_mount_point) {
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;
int r; int r;
CHECK_PRIV; if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
(void) log_tests_skipped("not running privileged");
return;
}
assert_se(mkdtemp_malloc(NULL, &t) >= 0); assert_se(mkdtemp_malloc(NULL, &t) >= 0);
@ -391,7 +433,18 @@ TEST(fd_make_mount_point) {
assert_se(s); assert_se(s);
assert_se(mkdir(s, 0700) >= 0); assert_se(mkdir(s, 0700) >= 0);
ASSERT_OK(r = safe_fork("(make-mount-point)", FORK_COMMON_FLAGS, NULL)); r = safe_fork("(make_mount-point)",
FORK_RESET_SIGNALS |
FORK_CLOSE_ALL_FDS |
FORK_DEATHSIG_SIGTERM |
FORK_WAIT |
FORK_REOPEN_LOG |
FORK_LOG |
FORK_NEW_MOUNTNS |
FORK_MOUNTNS_SLAVE,
NULL);
assert_se(r >= 0);
if (r == 0) { if (r == 0) {
_cleanup_close_ int fd = -EBADF, fd2 = -EBADF; _cleanup_close_ int fd = -EBADF, fd2 = -EBADF;
@ -415,78 +468,72 @@ TEST(fd_make_mount_point) {
TEST(bind_mount_submounts) { TEST(bind_mount_submounts) {
_cleanup_(rmdir_and_freep) char *a = NULL, *b = NULL; _cleanup_(rmdir_and_freep) char *a = NULL, *b = NULL;
_cleanup_free_ char *x = NULL;
int r; int r;
CHECK_PRIV;
assert_se(mkdtemp_malloc(NULL, &a) >= 0); assert_se(mkdtemp_malloc(NULL, &a) >= 0);
r = mount_nofollow_verbose(LOG_INFO, "tmpfs", a, "tmpfs", 0, NULL);
if (ERRNO_IS_NEG_PRIVILEGE(r))
return (void) log_tests_skipped("Skipping bind_mount_submounts() test, lacking privileges");
assert_se(r >= 0);
assert_se(x = path_join(a, "foo"));
assert_se(touch(x) >= 0);
free(x);
assert_se(x = path_join(a, "x"));
assert_se(mkdir(x, 0755) >= 0);
assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", x, "tmpfs", 0, NULL) >= 0);
free(x);
assert_se(x = path_join(a, "x/xx"));
assert_se(touch(x) >= 0);
free(x);
assert_se(x = path_join(a, "y"));
assert_se(mkdir(x, 0755) >= 0);
assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", x, "tmpfs", 0, NULL) >= 0);
free(x);
assert_se(x = path_join(a, "y/yy"));
assert_se(touch(x) >= 0);
free(x);
assert_se(mkdtemp_malloc(NULL, &b) >= 0); assert_se(mkdtemp_malloc(NULL, &b) >= 0);
assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", b, "tmpfs", 0, NULL) >= 0);
ASSERT_OK(r = safe_fork("(bind-mount-submounts)", FORK_COMMON_FLAGS, NULL)); assert_se(x = path_join(b, "x"));
if (r == 0) { assert_se(mkdir(x, 0755) >= 0);
char *x; free(x);
ASSERT_OK(mount_nofollow_verbose(LOG_INFO, "tmpfs", a, "tmpfs", 0, NULL)); assert_se(x = path_join(b, "y"));
assert_se(mkdir(x, 0755) >= 0);
free(x);
assert_se(x = path_join(a, "foo")); assert_se(bind_mount_submounts(a, b) >= 0);
assert_se(touch(x) >= 0);
free(x);
assert_se(x = path_join(a, "x")); assert_se(x = path_join(b, "foo"));
assert_se(mkdir(x, 0755) >= 0); assert_se(access(x, F_OK) < 0 && errno == ENOENT);
assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", x, "tmpfs", 0, NULL) >= 0); free(x);
free(x);
assert_se(x = path_join(a, "x/xx")); assert_se(x = path_join(b, "x/xx"));
assert_se(touch(x) >= 0); assert_se(access(x, F_OK) >= 0);
free(x); free(x);
assert_se(x = path_join(a, "y")); assert_se(x = path_join(b, "y/yy"));
assert_se(mkdir(x, 0755) >= 0); assert_se(access(x, F_OK) >= 0);
assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", x, "tmpfs", 0, NULL) >= 0); free(x);
free(x);
assert_se(x = path_join(a, "y/yy")); assert_se(x = path_join(b, "x"));
assert_se(touch(x) >= 0); assert_se(path_is_mount_point(x) > 0);
free(x); free(x);
assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", b, "tmpfs", 0, NULL) >= 0); assert_se(x = path_join(b, "y"));
assert_se(path_is_mount_point(x) > 0);
assert_se(x = path_join(b, "x")); assert_se(umount_recursive(a, 0) >= 0);
assert_se(mkdir(x, 0755) >= 0); assert_se(umount_recursive(b, 0) >= 0);
free(x);
assert_se(x = path_join(b, "y"));
assert_se(mkdir(x, 0755) >= 0);
free(x);
assert_se(bind_mount_submounts(a, b) >= 0);
assert_se(x = path_join(b, "foo"));
assert_se(access(x, F_OK) < 0 && errno == ENOENT);
free(x);
assert_se(x = path_join(b, "x/xx"));
assert_se(access(x, F_OK) >= 0);
free(x);
assert_se(x = path_join(b, "y/yy"));
assert_se(access(x, F_OK) >= 0);
free(x);
assert_se(x = path_join(b, "x"));
assert_se(path_is_mount_point(x) > 0);
free(x);
assert_se(x = path_join(b, "y"));
assert_se(path_is_mount_point(x) > 0);
free(x);
assert_se(umount_recursive(a, 0) >= 0);
assert_se(umount_recursive(b, 0) >= 0);
_exit(EXIT_SUCCESS);
}
} }
TEST(path_is_network_fs_harder) { TEST(path_is_network_fs_harder) {
@ -506,12 +553,26 @@ TEST(path_is_network_fs_harder) {
log_debug("path_is_network_fs_harder_at(root, %s) → %i: %s", q, r, r < 0 ? STRERROR(r) : yes_no(r)); log_debug("path_is_network_fs_harder_at(root, %s) → %i: %s", q, r, r < 0 ? STRERROR(r) : yes_no(r));
} }
CHECK_PRIV; if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
(void) log_tests_skipped("not running privileged");
return;
}
_cleanup_(rm_rf_physical_and_freep) char *t = NULL; _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
assert_se(mkdtemp_malloc("/tmp/test-mount-util.path_is_network_fs_harder.XXXXXXX", &t) >= 0); assert_se(mkdtemp_malloc("/tmp/test-mount-util.path_is_network_fs_harder.XXXXXXX", &t) >= 0);
ASSERT_OK(r = safe_fork("(path-is-network-fs-harder)", FORK_COMMON_FLAGS, NULL)); r = safe_fork("(make_mount-point)",
FORK_RESET_SIGNALS |
FORK_CLOSE_ALL_FDS |
FORK_DEATHSIG_SIGTERM |
FORK_WAIT |
FORK_REOPEN_LOG |
FORK_LOG |
FORK_NEW_MOUNTNS |
FORK_MOUNTNS_SLAVE,
NULL);
ASSERT_OK(r);
if (r == 0) { if (r == 0) {
ASSERT_OK(mount_nofollow_verbose(LOG_INFO, "tmpfs", t, "tmpfs", 0, NULL)); ASSERT_OK(mount_nofollow_verbose(LOG_INFO, "tmpfs", t, "tmpfs", 0, NULL));
ASSERT_OK_ZERO(path_is_network_fs_harder(t)); ASSERT_OK_ZERO(path_is_network_fs_harder(t));
@ -526,7 +587,7 @@ TEST(path_is_network_fs_harder) {
} }
TEST(umountat) { TEST(umountat) {
CHECK_PRIV; int r;
_cleanup_(rm_rf_physical_and_freep) char *p = NULL; _cleanup_(rm_rf_physical_and_freep) char *p = NULL;
_cleanup_close_ int dfd = mkdtemp_open(NULL, O_CLOEXEC, &p); _cleanup_close_ int dfd = mkdtemp_open(NULL, O_CLOEXEC, &p);
@ -536,7 +597,11 @@ TEST(umountat) {
_cleanup_free_ char *q = ASSERT_PTR(path_join(p, "foo")); _cleanup_free_ char *q = ASSERT_PTR(path_join(p, "foo"));
ASSERT_OK(mount_nofollow_verbose(LOG_ERR, "tmpfs", q, "tmpfs", 0, NULL)); r = mount_nofollow_verbose(LOG_ERR, "tmpfs", q, "tmpfs", 0, NULL);
if (ERRNO_IS_NEG_PRIVILEGE(r))
return (void) log_tests_skipped("not running privileged");
ASSERT_OK(r);
ASSERT_OK(umountat_detach_verbose(LOG_ERR, dfd, "foo")); ASSERT_OK(umountat_detach_verbose(LOG_ERR, dfd, "foo"));
ASSERT_ERROR(umountat_detach_verbose(LOG_ERR, dfd, "foo"), EINVAL); ASSERT_ERROR(umountat_detach_verbose(LOG_ERR, dfd, "foo"), EINVAL);
} }

View File

@ -18,7 +18,6 @@
#include "string-util.h" #include "string-util.h"
#include "tests.h" #include "tests.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
#include "virt.h"
static void test_mount_propagation_flag_one(const char *name, int ret, unsigned long expected) { static void test_mount_propagation_flag_one(const char *name, int ret, unsigned long expected) {
unsigned long flags; unsigned long flags;
@ -456,12 +455,6 @@ static int intro(void) {
/* let's move into our own mount namespace with all propagation from the host turned off, so /* let's move into our own mount namespace with all propagation from the host turned off, so
* that /proc/self/mountinfo is static and constant for the whole time our test runs. */ * that /proc/self/mountinfo is static and constant for the whole time our test runs. */
if (running_in_chroot() > 0) {
/* We cannot remount file system with MS_PRIVATE when running in chroot. */
log_notice("Running in chroot, proceeding in originating mount namespace.");
return EXIT_SUCCESS;
}
if (unshare(CLONE_NEWNS) < 0) { if (unshare(CLONE_NEWNS) < 0) {
if (!ERRNO_IS_PRIVILEGE(errno)) if (!ERRNO_IS_PRIVILEGE(errno))
return log_error_errno(errno, "Failed to detach mount namespace: %m"); return log_error_errno(errno, "Failed to detach mount namespace: %m");

View File

@ -6,7 +6,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/socket.h> #include <sys/socket.h>
#include "locale-util.h"
#include "parse-util.h" #include "parse-util.h"
#include "tests.h" #include "tests.h"
@ -656,6 +655,7 @@ TEST(safe_atoux64) {
TEST(safe_atod) { TEST(safe_atod) {
double d; double d;
char *e;
ASSERT_ERROR(safe_atod("junk", &d), EINVAL); ASSERT_ERROR(safe_atod("junk", &d), EINVAL);
@ -663,18 +663,39 @@ TEST(safe_atod) {
assert_se(fabs(d - 0.2244) < 0.000001); assert_se(fabs(d - 0.2244) < 0.000001);
ASSERT_ERROR(safe_atod("0,5", &d), EINVAL); ASSERT_ERROR(safe_atod("0,5", &d), EINVAL);
errno = 0;
strtod("0,5", &e);
assert_se(*e == ',');
ASSERT_ERROR(safe_atod("", &d), EINVAL); ASSERT_ERROR(safe_atod("", &d), EINVAL);
/* Check if this really is locale independent */ /* Check if this really is locale independent */
_cleanup_(freelocalep) locale_t loc = if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
newlocale(LC_NUMERIC_MASK, "de_DE.utf8", (locale_t) 0);
if (!loc) ASSERT_OK_ZERO(safe_atod("0.2244", &d));
return (void) log_tests_skipped_errno(errno, "locale de_DE.utf8 not found"); assert_se(fabs(d - 0.2244) < 0.000001);
ASSERT_ERROR(safe_atod("0,5", &d), EINVAL);
errno = 0;
assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
ASSERT_ERROR(safe_atod("", &d), EINVAL);
}
/* And check again, reset */
ASSERT_NOT_NULL(setlocale(LC_NUMERIC, "C"));
ASSERT_OK_ZERO(safe_atod("0.2244", &d)); ASSERT_OK_ZERO(safe_atod("0.2244", &d));
assert_se(fabs(d - 0.2244) < 0.000001); assert_se(fabs(d - 0.2244) < 0.000001);
ASSERT_ERROR(safe_atod("0,5", &d), EINVAL); ASSERT_ERROR(safe_atod("0,5", &d), EINVAL);
errno = 0;
strtod("0,5", &e);
assert_se(*e == ',');
ASSERT_ERROR(safe_atod("", &d), EINVAL); ASSERT_ERROR(safe_atod("", &d), EINVAL);
} }

View File

@ -42,13 +42,9 @@
# define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0 # define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0
#endif #endif
#define CHECK_SECCOMP(refuse_container) \ static bool have_seccomp_privs(void) {
if (!is_seccomp_available()) \ return geteuid() == 0 && have_effective_cap(CAP_SYS_ADMIN) > 0; /* If we are root but CAP_SYS_ADMIN we can't do caps (unless we also do NNP) */
return (void) log_tests_skipped("Seccomp not available"); \ }
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) \
return (void) log_tests_skipped("Not privileged"); \
if (refuse_container && detect_container() > 0) \
return (void) log_tests_skipped("Running in container");
TEST(parse_syscall_and_errno) { TEST(parse_syscall_and_errno) {
_cleanup_free_ char *n = NULL; _cleanup_free_ char *n = NULL;
@ -170,11 +166,17 @@ TEST(syscall_filter_set_find) {
} }
TEST(filter_sets) { TEST(filter_sets) {
int r; if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
CHECK_SECCOMP(/* skip_container = */ false); return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
for (unsigned i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) { for (unsigned i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
pid_t pid;
#if HAVE_VALGRIND_VALGRIND_H #if HAVE_VALGRIND_VALGRIND_H
if (RUNNING_ON_VALGRIND && IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_BASIC_IO, SYSCALL_FILTER_SET_SIGNAL)) { if (RUNNING_ON_VALGRIND && IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_BASIC_IO, SYSCALL_FILTER_SET_SIGNAL)) {
@ -193,9 +195,11 @@ TEST(filter_sets) {
log_info("Testing %s", syscall_filter_sets[i].name); log_info("Testing %s", syscall_filter_sets[i].name);
ASSERT_OK(r = safe_fork("(filter_sets)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
int fd;
if (pid == 0) { /* Child? */
int fd, r;
/* If we look at the default set (or one that includes it), allow-list instead of deny-list */ /* If we look at the default set (or one that includes it), allow-list instead of deny-list */
if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT,
@ -218,6 +222,8 @@ TEST(filter_sets) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check(syscall_filter_sets[i].name, pid, WAIT_LOG) == EXIT_SUCCESS);
} }
} }
@ -257,10 +263,12 @@ TEST(filter_sets_ordered) {
TEST(restrict_namespace) { TEST(restrict_namespace) {
char *s = NULL; char *s = NULL;
unsigned long ul; unsigned long ul;
int r; pid_t pid;
if (!have_namespaces()) if (!have_namespaces()) {
return (void) log_tests_skipped("Testing without namespaces"); log_notice("Testing without namespaces, skipping %s", __func__);
return;
}
assert_se(namespace_flags_to_string(0, &s) == 0 && isempty(s)); assert_se(namespace_flags_to_string(0, &s) == 0 && isempty(s));
s = mfree(s); s = mfree(s);
@ -289,10 +297,19 @@ TEST(restrict_namespace) {
assert_se(namespace_flags_from_string(s, &ul) == 0 && ul == NAMESPACE_FLAGS_ALL); assert_se(namespace_flags_from_string(s, &ul) == 0 && ul == NAMESPACE_FLAGS_ALL);
s = mfree(s); s = mfree(s);
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping remaining tests in %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping remaining tests in %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(restrict-namespace)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
assert_se(seccomp_restrict_namespaces(CLONE_NEWNS|CLONE_NEWNET) >= 0); assert_se(seccomp_restrict_namespaces(CLONE_NEWNS|CLONE_NEWNET) >= 0);
@ -320,7 +337,7 @@ TEST(restrict_namespace) {
assert_se(setns(0, 0) == -1); assert_se(setns(0, 0) == -1);
assert_se(errno == EPERM); assert_se(errno == EPERM);
pid_t pid = raw_clone(CLONE_NEWNS); pid = raw_clone(CLONE_NEWNS);
assert_se(pid >= 0); assert_se(pid >= 0);
if (pid == 0) if (pid == 0)
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
@ -340,21 +357,37 @@ TEST(restrict_namespace) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("nsseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(protect_sysctl) { TEST(protect_sysctl) {
int r; pid_t pid;
_cleanup_free_ char *seccomp = NULL;
if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
/* in containers _sysctl() is likely missing anyway */ /* in containers _sysctl() is likely missing anyway */
CHECK_SECCOMP(/* skip_container = */ true); if (detect_container() > 0) {
log_notice("Testing in container, skipping %s", __func__);
return;
}
_cleanup_free_ char *seccomp = NULL;
assert_se(get_proc_field("/proc/self/status", "Seccomp", &seccomp) == 0); assert_se(get_proc_field("/proc/self/status", "Seccomp", &seccomp) == 0);
if (!streq(seccomp, "0")) if (!streq(seccomp, "0"))
log_warning("Warning: seccomp filter detected, results may be unreliable for %s", __func__); log_warning("Warning: seccomp filter detected, results may be unreliable for %s", __func__);
ASSERT_OK(r = safe_fork("(protect-sysctl)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
#if defined __NR__sysctl && __NR__sysctl >= 0 #if defined __NR__sysctl && __NR__sysctl >= 0
assert_se(syscall(__NR__sysctl, NULL) < 0); assert_se(syscall(__NR__sysctl, NULL) < 0);
assert_se(IN_SET(errno, EFAULT, ENOSYS)); assert_se(IN_SET(errno, EFAULT, ENOSYS));
@ -376,16 +409,32 @@ TEST(protect_sysctl) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("sysctlseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(protect_syslog) { TEST(protect_syslog) {
int r; pid_t pid;
if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
/* in containers syslog() is likely missing anyway */ /* in containers syslog() is likely missing anyway */
CHECK_SECCOMP(/* skip_container = */ true); if (detect_container() > 0) {
log_notice("Testing in container, skipping %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(protect-syslog)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
#if defined __NR_syslog && __NR_syslog >= 0 #if defined __NR_syslog && __NR_syslog >= 0
assert_se(syscall(__NR_syslog, -1, NULL, 0) < 0); assert_se(syscall(__NR_syslog, -1, NULL, 0) < 0);
assert_se(errno == EINVAL); assert_se(errno == EINVAL);
@ -400,15 +449,26 @@ TEST(protect_syslog) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("syslogseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(restrict_address_families) { TEST(restrict_address_families) {
int r; pid_t pid;
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(restrict-address-families)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
int fd; int fd;
Set *s; Set *s;
@ -476,23 +536,34 @@ TEST(restrict_address_families) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("socketseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(restrict_realtime) { TEST(restrict_realtime) {
int r; pid_t pid;
if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
/* in containers RT privs are likely missing anyway */ /* in containers RT privs are likely missing anyway */
CHECK_SECCOMP(/* skip_container = */ true); if (detect_container() > 0) {
log_notice("Testing in container, skipping %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(restrict-realtime)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
/* On some CI environments, the restriction may be already enabled. */ /* On some CI environments, the restriction may be already enabled. */
if (sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) < 0) { if (sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) < 0) {
if (errno == ENOSYS) {
log_tests_skipped("sched_setscheduler() is not available or already filtered");
_exit(EXIT_SUCCESS);
}
log_full_errno(errno == EPERM ? LOG_DEBUG : LOG_WARNING, errno, log_full_errno(errno == EPERM ? LOG_DEBUG : LOG_WARNING, errno,
"Failed to set scheduler parameter for FIFO: %m"); "Failed to set scheduler parameter for FIFO: %m");
assert(errno == EPERM); assert(errno == EPERM);
@ -520,13 +591,21 @@ TEST(restrict_realtime) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("realtimeseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(memory_deny_write_execute_mmap) { TEST(memory_deny_write_execute_mmap) {
int r; pid_t pid;
CHECK_SECCOMP(/* skip_container = */ false);
if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
#if HAVE_VALGRIND_VALGRIND_H #if HAVE_VALGRIND_VALGRIND_H
if (RUNNING_ON_VALGRIND) { if (RUNNING_ON_VALGRIND) {
log_notice("Running on valgrind, skipping %s", __func__); log_notice("Running on valgrind, skipping %s", __func__);
@ -538,8 +617,10 @@ TEST(memory_deny_write_execute_mmap) {
return; return;
#endif #endif
ASSERT_OK(r = safe_fork("(memory_deny_write_execute_mmap)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
void *p; void *p;
p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
@ -568,11 +649,14 @@ TEST(memory_deny_write_execute_mmap) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("memoryseccomp-mmap", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(memory_deny_write_execute_shmat) { TEST(memory_deny_write_execute_shmat) {
int shmid;
pid_t pid;
uint32_t arch; uint32_t arch;
int r, shmid;
SECCOMP_FOREACH_LOCAL_ARCH(arch) { SECCOMP_FOREACH_LOCAL_ARCH(arch) {
log_debug("arch %s: SCMP_SYS(mmap) = %d", seccomp_arch_to_string(arch), SCMP_SYS(mmap)); log_debug("arch %s: SCMP_SYS(mmap) = %d", seccomp_arch_to_string(arch), SCMP_SYS(mmap));
@ -582,8 +666,14 @@ TEST(memory_deny_write_execute_shmat) {
log_debug("arch %s: SCMP_SYS(shmdt) = %d", seccomp_arch_to_string(arch), SCMP_SYS(shmdt)); log_debug("arch %s: SCMP_SYS(shmdt) = %d", seccomp_arch_to_string(arch), SCMP_SYS(shmdt));
} }
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs() || have_effective_cap(CAP_IPC_OWNER) <= 0) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
#if HAVE_VALGRIND_VALGRIND_H #if HAVE_VALGRIND_VALGRIND_H
if (RUNNING_ON_VALGRIND) { if (RUNNING_ON_VALGRIND) {
log_notice("Running on valgrind, skipping %s", __func__); log_notice("Running on valgrind, skipping %s", __func__);
@ -598,8 +688,10 @@ TEST(memory_deny_write_execute_shmat) {
shmid = shmget(IPC_PRIVATE, page_size(), 0); shmid = shmget(IPC_PRIVATE, page_size(), 0);
assert_se(shmid >= 0); assert_se(shmid >= 0);
ASSERT_OK(r = safe_fork("(memory-deny-write-execute)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
void *p; void *p;
p = shmat(shmid, NULL, 0); p = shmat(shmid, NULL, 0);
@ -630,15 +722,26 @@ TEST(memory_deny_write_execute_shmat) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("memoryseccomp-shmat", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(restrict_archs) { TEST(restrict_archs) {
int r; pid_t pid;
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(restrict-archs)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
_cleanup_set_free_ Set *s = NULL; _cleanup_set_free_ Set *s = NULL;
assert_se(access("/", F_OK) >= 0); assert_se(access("/", F_OK) >= 0);
@ -657,15 +760,26 @@ TEST(restrict_archs) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("archseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(load_syscall_filter_set_raw) { TEST(load_syscall_filter_set_raw) {
int r; pid_t pid;
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(load-filter)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
_cleanup_hashmap_free_ Hashmap *s = NULL; _cleanup_hashmap_free_ Hashmap *s = NULL;
assert_se(access("/", F_OK) >= 0); assert_se(access("/", F_OK) >= 0);
@ -759,15 +873,26 @@ TEST(load_syscall_filter_set_raw) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("syscallrawseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(native_syscalls_filtered) { TEST(native_syscalls_filtered) {
int r; pid_t pid;
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(native-syscalls)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
_cleanup_set_free_ Set *arch_s = NULL; _cleanup_set_free_ Set *arch_s = NULL;
_cleanup_hashmap_free_ Hashmap *s = NULL; _cleanup_hashmap_free_ Hashmap *s = NULL;
@ -806,21 +931,32 @@ TEST(native_syscalls_filtered) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("nativeseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
TEST(lock_personality) { TEST(lock_personality) {
unsigned long current_opinionated; unsigned long current_opinionated;
int r; pid_t pid;
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
assert_se(opinionated_personality(&current_opinionated) >= 0); assert_se(opinionated_personality(&current_opinionated) >= 0);
log_info("current personality=0x%lX", (unsigned long) safe_personality(PERSONALITY_INVALID)); log_info("current personality=0x%lX", (unsigned long) safe_personality(PERSONALITY_INVALID));
log_info("current opinionated personality=0x%lX", current_opinionated); log_info("current opinionated personality=0x%lX", current_opinionated);
ASSERT_OK(r = safe_fork("(lock-personality)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
unsigned long current; unsigned long current;
assert_se(seccomp_lock_personality(current_opinionated) >= 0); assert_se(seccomp_lock_personality(current_opinionated) >= 0);
@ -852,6 +988,8 @@ TEST(lock_personality) {
assert_se((current & OPINIONATED_PERSONALITY_MASK) == current_opinionated); assert_se((current & OPINIONATED_PERSONALITY_MASK) == current_opinionated);
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("lockpersonalityseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
static int real_open(const char *path, int flags, mode_t mode) { static int real_open(const char *path, int flags, mode_t mode) {
@ -885,12 +1023,21 @@ static int try_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) {
} }
TEST(restrict_suid_sgid) { TEST(restrict_suid_sgid) {
int r; pid_t pid;
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(suid-sgid)", FORK_LOG | FORK_WAIT, NULL)); pid = fork();
if (r == 0) { assert_se(pid >= 0);
if (pid == 0) {
char path[] = "/tmp/suidsgidXXXXXX", dir[] = "/tmp/suidsgiddirXXXXXX"; char path[] = "/tmp/suidsgidXXXXXX", dir[] = "/tmp/suidsgiddirXXXXXX";
int fd = -EBADF, k = -EBADF; int fd = -EBADF, k = -EBADF;
const char *z; const char *z;
@ -1077,6 +1224,8 @@ TEST(restrict_suid_sgid) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
assert_se(wait_for_terminate_and_check("suidsgidseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
} }
static void test_seccomp_suppress_sync_child(void) { static void test_seccomp_suppress_sync_child(void) {
@ -1109,15 +1258,25 @@ static void test_seccomp_suppress_sync_child(void) {
} }
TEST(seccomp_suppress_sync) { TEST(seccomp_suppress_sync) {
int r; pid_t pid;
CHECK_SECCOMP(/* skip_container = */ false); if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
ASSERT_OK(r = safe_fork("(suppress-sync)", FORK_LOG | FORK_WAIT, NULL)); ASSERT_OK_ERRNO(pid = fork());
if (r == 0) {
if (pid == 0) {
test_seccomp_suppress_sync_child(); test_seccomp_suppress_sync_child();
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
ASSERT_EQ(wait_for_terminate_and_check("seccomp_suppress_sync", pid, WAIT_LOG), EXIT_SUCCESS);
} }
DEFINE_TEST_MAIN(LOG_DEBUG); DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -151,7 +151,6 @@ udev_binaries_dict = [
include_directories('.', 'net'), include_directories('.', 'net'),
], ],
'dependencies' : udev_dependencies, 'dependencies' : udev_dependencies,
'link_with' : udev_link_with,
'install_rpath' : udev_rpath, 'install_rpath' : udev_rpath,
'install_tag' : 'udev', 'install_tag' : 'udev',
'extract' : udevadm_extract_sources, 'extract' : udevadm_extract_sources,

View File

@ -638,7 +638,7 @@ static usec_t extra_timeout_usec(void) {
parsed = true; parsed = true;
e = secure_getenv("SYSTEMD_UDEV_EXTRA_TIMEOUT_SEC"); e = getenv("SYSTEMD_UDEV_EXTRA_TIMEOUT_SEC");
if (!e) if (!e)
return saved; return saved;

View File

@ -1011,9 +1011,7 @@ static int parse_token(
op = OP_ASSIGN; op = OP_ASSIGN;
if (streq(value, "dump")) if (streq(value, "dump"))
r = rule_line_add_token(rule_line, TK_A_OPTIONS_DUMP, op, NULL, UINT_TO_PTR(SD_JSON_FORMAT_OFF), /* is_case_insensitive = */ false, token_str); r = rule_line_add_token(rule_line, TK_A_OPTIONS_DUMP, op, NULL, NULL, /* is_case_insensitive = */ false, token_str);
else if (streq(value, "dump-json"))
r = rule_line_add_token(rule_line, TK_A_OPTIONS_DUMP, op, NULL, UINT_TO_PTR(SD_JSON_FORMAT_NEWLINE), /* is_case_insensitive = */ false, token_str);
else if (streq(value, "string_escape=none")) else if (streq(value, "string_escape=none"))
r = rule_line_add_token(rule_line, TK_A_OPTIONS_STRING_ESCAPE_NONE, op, NULL, NULL, /* is_case_insensitive = */ false, token_str); r = rule_line_add_token(rule_line, TK_A_OPTIONS_STRING_ESCAPE_NONE, op, NULL, NULL, /* is_case_insensitive = */ false, token_str);
else if (streq(value, "string_escape=replace")) else if (streq(value, "string_escape=replace"))
@ -2595,8 +2593,6 @@ static int udev_rule_apply_token_to_event(
return token_match_string(event, token, event->program_result, /* log_result = */ true); return token_match_string(event, token, event->program_result, /* log_result = */ true);
case TK_A_OPTIONS_DUMP: { case TK_A_OPTIONS_DUMP: {
sd_json_format_flags_t flags = PTR_TO_UINT(token->data);
log_event_info(event, token, "Dumping current state:"); log_event_info(event, token, "Dumping current state:");
_cleanup_(memstream_done) MemStream m = {}; _cleanup_(memstream_done) MemStream m = {};
@ -2604,7 +2600,7 @@ static int udev_rule_apply_token_to_event(
if (!f) if (!f)
return log_oom(); return log_oom();
(void) dump_event(event, flags, f); (void) dump_event(event, SD_JSON_FORMAT_OFF, f);
_cleanup_free_ char *buf = NULL; _cleanup_free_ char *buf = NULL;
r = memstream_finalize(&m, &buf, NULL); r = memstream_finalize(&m, &buf, NULL);

View File

@ -628,7 +628,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_TPM_STATE: case ARG_TPM_STATE:
if (path_is_valid(optarg) && (path_is_absolute(optarg) || path_startswith(optarg, "./"))) { if (path_is_absolute(optarg) && path_is_valid(optarg)) {
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_tpm_state_path); r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_tpm_state_path);
if (r < 0) if (r < 0)
return r; return r;
@ -2094,30 +2094,24 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
} }
if (arg_image) { if (arg_image) {
_cleanup_free_ char *escaped_image = NULL;
assert(!arg_directory); assert(!arg_directory);
if (strv_extend(&cmdline, "-drive") < 0) r = strv_extend(&cmdline, "-drive");
if (r < 0)
return log_oom(); return log_oom();
_cleanup_free_ char *escaped_image = escape_qemu_value(arg_image); escaped_image = escape_qemu_value(arg_image);
if (!escaped_image) if (!escaped_image)
return log_oom(); return log_oom();
if (strv_extendf(&cmdline, "if=none,id=vmspawn,file=%s,format=raw,discard=%s", escaped_image, on_off(arg_discard_disk)) < 0) r = strv_extendf(&cmdline, "if=none,id=vmspawn,file=%s,format=raw,discard=%s", escaped_image, on_off(arg_discard_disk));
if (r < 0)
return log_oom(); return log_oom();
_cleanup_free_ char *image_fn = NULL; r = strv_extend_many(&cmdline, "-device", "virtio-blk-pci,drive=vmspawn,bootindex=1");
if (path_extract_filename(arg_image, &image_fn) < 0) if (r < 0)
return log_error_errno(r, "Failed to extract filename from path '%s': %m", image_fn);
_cleanup_free_ char *escaped_image_fn = escape_qemu_value(image_fn);
if (!escaped_image_fn)
return log_oom();
if (strv_extend(&cmdline, "-device") < 0)
return log_oom();
if (strv_extendf(&cmdline, "virtio-blk-pci,drive=vmspawn,bootindex=1,serial=%s", escaped_image_fn) < 0)
return log_oom(); return log_oom();
r = grow_image(arg_image, arg_grow_image); r = grow_image(arg_image, arg_grow_image);
@ -2192,18 +2186,21 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
size_t i = 0; size_t i = 0;
STRV_FOREACH(drive, arg_extra_drives) { STRV_FOREACH(drive, arg_extra_drives) {
if (strv_extend(&cmdline, "-blockdev") < 0) _cleanup_free_ char *escaped_drive = NULL;
const char *driver = NULL;
struct stat st;
r = strv_extend(&cmdline, "-blockdev");
if (r < 0)
return log_oom(); return log_oom();
_cleanup_free_ char *escaped_drive = escape_qemu_value(*drive); escaped_drive = escape_qemu_value(*drive);
if (!escaped_drive) if (!escaped_drive)
return log_oom(); return log_oom();
struct stat st;
if (stat(*drive, &st) < 0) if (stat(*drive, &st) < 0)
return log_error_errno(errno, "Failed to stat '%s': %m", *drive); return log_error_errno(errno, "Failed to stat '%s': %m", *drive);
const char *driver = NULL;
if (S_ISREG(st.st_mode)) if (S_ISREG(st.st_mode))
driver = "file"; driver = "file";
else if (S_ISBLK(st.st_mode)) else if (S_ISBLK(st.st_mode))
@ -2211,22 +2208,16 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
else else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected regular file or block device, not '%s'.", *drive); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected regular file or block device, not '%s'.", *drive);
if (strv_extendf(&cmdline, "driver=raw,cache.direct=off,cache.no-flush=on,file.driver=%s,file.filename=%s,node-name=vmspawn_extra_%zu", driver, escaped_drive, i) < 0) r = strv_extendf(&cmdline, "driver=raw,cache.direct=off,cache.no-flush=on,file.driver=%s,file.filename=%s,node-name=vmspawn_extra_%zu", driver, escaped_drive, i);
return log_oom();
_cleanup_free_ char *drive_fn = NULL;
r = path_extract_filename(*drive, &drive_fn);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to extract filename from path '%s': %m", *drive);
_cleanup_free_ char *escaped_drive_fn = escape_qemu_value(drive_fn);
if (!escaped_drive_fn)
return log_oom(); return log_oom();
if (strv_extend(&cmdline, "-device") < 0) r = strv_extend(&cmdline, "-device");
if (r < 0)
return log_oom(); return log_oom();
if (strv_extendf(&cmdline, "scsi-hd,drive=vmspawn_extra_%zu,serial=%s", i++, escaped_drive_fn) < 0) r = strv_extendf(&cmdline, "scsi-hd,drive=vmspawn_extra_%zu", i++);
if (r < 0)
return log_oom(); return log_oom();
} }

View File

@ -192,7 +192,7 @@ if want_tests != 'false'
test('test-udev', test('test-udev',
test_udev_py, test_udev_py,
args : ['-v'], args : ['-v'],
env : test_env + { 'UDEV_RULE_RUNNER' : exe.full_path() }, env : ['UDEV_RULE_RUNNER=' + exe.full_path()],
depends : exe, depends : exe,
timeout : 180, timeout : 180,
suite : 'udev') suite : 'udev')

View File

@ -35,12 +35,12 @@ preprocess() {
} }
compare() { compare() {
if ! diff -u "$TESTDIR/etc/passwd" <(preprocess "$1.expected-passwd" "$3") >&2; then if ! diff -u "$TESTDIR/etc/passwd" <(preprocess "$1.expected-passwd" "$3"); then
echo >&2 "**** Unexpected output for $f $2" echo >&2 "**** Unexpected output for $f $2"
exit 1 exit 1
fi fi
if ! diff -u "$TESTDIR/etc/group" <(preprocess "$1.expected-group" "$3") >&2; then if ! diff -u "$TESTDIR/etc/group" <(preprocess "$1.expected-group" "$3"); then
echo >&2 "**** Unexpected output for $f $2" echo >&2 "**** Unexpected output for $f $2"
exit 1 exit 1
fi fi
@ -167,7 +167,7 @@ for f in $(find "$SOURCE"/unhappy-*.input | sort -V); do
prepare_testdir "${f%.input}" prepare_testdir "${f%.input}"
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf" cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
SYSTEMD_LOG_LEVEL=info "$SYSUSERS" --root="$TESTDIR" 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >"$TESTDIR/err" SYSTEMD_LOG_LEVEL=info "$SYSUSERS" --root="$TESTDIR" 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >"$TESTDIR/err"
if ! diff -u "$TESTDIR/err" "${f%.*}.expected-err" >&2; then if ! diff -u "$TESTDIR/err" "${f%.*}.expected-err"; then
echo >&2 "**** Unexpected error output for $f" echo >&2 "**** Unexpected error output for $f"
cat >&2 "$TESTDIR/err" cat >&2 "$TESTDIR/err"
exit 1 exit 1

View File

@ -20,7 +20,8 @@ ConditionDirectoryNotEmpty=|/sysusr/usr/lib/repart.d
ConditionDirectoryNotEmpty=|/sysusr/usr/local/lib/repart.d ConditionDirectoryNotEmpty=|/sysusr/usr/local/lib/repart.d
DefaultDependencies=no DefaultDependencies=no
After=initrd-usr-fs.target systemd-tpm2-setup-early.service systemd-tmpfiles-setup-dev.service Wants=modprobe@loop.service modprobe@dm_mod.service
After=initrd-usr-fs.target modprobe@loop.service modprobe@dm_mod.service systemd-tpm2-setup-early.service
Before=initrd-root-fs.target factory-reset-now.target Before=initrd-root-fs.target factory-reset-now.target
Conflicts=shutdown.target initrd-switch-root.target Conflicts=shutdown.target initrd-switch-root.target
Before=shutdown.target initrd-switch-root.target Before=shutdown.target initrd-switch-root.target