Compare commits
40 Commits
b047bfe825
...
ece1840885
Author | SHA1 | Date |
---|---|---|
![]() |
ece1840885 | |
![]() |
edc49209f1 | |
![]() |
2791b2bc3d | |
![]() |
7baf24c949 | |
![]() |
ce921df8d1 | |
![]() |
c96a5d9912 | |
![]() |
6858c1fd8b | |
![]() |
b1236ce38b | |
![]() |
710653d3bc | |
![]() |
d9826d303b | |
![]() |
10ed8cda58 | |
![]() |
a035eaa227 | |
![]() |
e8881f09c5 | |
![]() |
60bcd98228 | |
![]() |
90755dac69 | |
![]() |
6d88e4a4b4 | |
![]() |
52278e0634 | |
![]() |
4cf443e644 | |
![]() |
a85f73fa55 | |
![]() |
09ddaf2af3 | |
![]() |
919aeb666a | |
![]() |
1b25b88f82 | |
![]() |
5c6e6f5ad1 | |
![]() |
10d786458c | |
![]() |
d3af116afd | |
![]() |
32b5deb1b2 | |
![]() |
6d1a69d0f0 | |
![]() |
25a9bd72ef | |
![]() |
4100e0f207 | |
![]() |
765ffa12ee | |
![]() |
5f43554f90 | |
![]() |
70669fa2fe | |
![]() |
f92fac7e9b | |
![]() |
855800aaec | |
![]() |
f8b0277101 | |
![]() |
9ee08c8dce | |
![]() |
19aa8c0f0e | |
![]() |
3e8a4defa8 | |
![]() |
76a8f5ae4b | |
![]() |
c9110dd8c5 |
|
@ -25,7 +25,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
- uses: systemd/mkosi@7e4ec15aee6b98300b2ee14265bc647a716a9f8a
|
||||
- uses: systemd/mkosi@dbb4020beee2cdf250f93a425794f1cf8b0fe693
|
||||
|
||||
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
|
||||
# immediately, we remove the files in the background. However, we first move them to a different location
|
||||
|
@ -90,7 +90,6 @@ jobs:
|
|||
sudo mkosi sandbox -- \
|
||||
meson setup \
|
||||
--buildtype=debugoptimized \
|
||||
-Dintegration-tests=true \
|
||||
build
|
||||
|
||||
- name: Build image
|
||||
|
@ -120,7 +119,8 @@ jobs:
|
|||
meson test \
|
||||
-C build \
|
||||
--no-rebuild \
|
||||
--suite integration-tests \
|
||||
--setup=integration \
|
||||
--suite=integration-tests \
|
||||
--print-errorlogs \
|
||||
--no-stdsplit \
|
||||
--num-processes "$(($(nproc) - 1))" \
|
||||
|
|
|
@ -120,7 +120,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
- uses: systemd/mkosi@7e4ec15aee6b98300b2ee14265bc647a716a9f8a
|
||||
- uses: systemd/mkosi@dbb4020beee2cdf250f93a425794f1cf8b0fe693
|
||||
|
||||
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
|
||||
# immediately, we remove the files in the background. However, we first move them to a different location
|
||||
|
@ -197,7 +197,6 @@ jobs:
|
|||
sudo mkosi sandbox -- \
|
||||
meson setup \
|
||||
--buildtype=debugoptimized \
|
||||
-Dintegration-tests=true \
|
||||
-Dbpf-framework=disabled \
|
||||
build
|
||||
|
||||
|
@ -233,7 +232,8 @@ jobs:
|
|||
meson test \
|
||||
-C build \
|
||||
--no-rebuild \
|
||||
--suite integration-tests \
|
||||
--setup=integration \
|
||||
--suite=integration-tests \
|
||||
--print-errorlogs \
|
||||
--no-stdsplit \
|
||||
--num-processes "$(($(nproc) - 1))" \
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
<refsynopsisdiv>
|
||||
<programlisting>
|
||||
Host unix/* vsock/* vsock-mux/*
|
||||
Host unix/* unix,* vsock/* vsock,* vsock-mux/* vsock-mux,*
|
||||
ProxyCommand /usr/lib/systemd/systemd-ssh-proxy %h %p
|
||||
ProxyUseFdpass yes
|
||||
</programlisting>
|
||||
|
@ -46,7 +46,7 @@ Host unix/* vsock/* vsock-mux/*
|
|||
configuration fragment like the following:</para>
|
||||
|
||||
<programlisting>
|
||||
Host unix/* vsock/* vsock-mux/*
|
||||
Host unix/* unix,* vsock/* vsock,* vsock-mux/* vsock-mux,*
|
||||
ProxyCommand /usr/lib/systemd/systemd-ssh-proxy %h %p
|
||||
ProxyUseFdpass yes
|
||||
CheckHostIP no
|
||||
|
@ -69,7 +69,9 @@ Host .host
|
|||
direct <constant>AF_VSOCK</constant> communication between the host and guests, and provide their own
|
||||
multiplexer over <constant>AF_UNIX</constant> sockets. See
|
||||
<ulink url="https://github.com/cloud-hypervisor/cloud-hypervisor/blob/main/docs/vsock.md">cloud-hypervisor VSOCK support</ulink>
|
||||
and <ulink url="https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md">Using the Firecracker Virtio-vsock Device</ulink>.</para>
|
||||
and <ulink url="https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md">Using the Firecracker Virtio-vsock Device</ulink>.
|
||||
Note that <literal>,</literal> can be used as a separator instead of <literal>/</literal> to be
|
||||
compatible with tools like <literal>scp</literal> and <literal>rsync</literal>.</para>
|
||||
|
||||
<para>Moreover, connecting to <literal>.host</literal> will connect to the local host via SSH, without
|
||||
involving networking.</para>
|
||||
|
@ -113,6 +115,12 @@ Host .host
|
|||
|
||||
<programlisting>ssh unix/run/ssh-unix-local/socket</programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Copy local 'foo' file to a local VM with CID 1348</title>
|
||||
|
||||
<programlisting>scp foo vsock,1348:</programlisting>
|
||||
</example>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
|
11
meson.build
11
meson.build
|
@ -13,6 +13,12 @@ project('systemd', 'c',
|
|||
meson_version : '>= 0.62.0',
|
||||
)
|
||||
|
||||
add_test_setup(
|
||||
'default',
|
||||
exclude_suites : ['integration-tests'],
|
||||
is_default : true,
|
||||
)
|
||||
|
||||
project_major_version = meson.project_version().split('.')[0].split('~')[0]
|
||||
if meson.project_version().contains('.')
|
||||
project_minor_version = meson.project_version().split('.')[-1].split('~')[0]
|
||||
|
@ -339,7 +345,6 @@ meson_build_sh = find_program('tools/meson-build.sh')
|
|||
want_tests = get_option('tests')
|
||||
want_slow_tests = want_tests != 'false' and get_option('slow-tests')
|
||||
want_fuzz_tests = want_tests != 'false' and get_option('fuzz-tests')
|
||||
want_integration_tests = want_tests != 'false' and get_option('integration-tests')
|
||||
install_tests = want_tests != 'false' and get_option('install-tests')
|
||||
|
||||
if add_languages('cpp', native : false, required : fuzzer_build)
|
||||
|
@ -2661,10 +2666,6 @@ endif
|
|||
#####################################################################
|
||||
|
||||
mkosi = find_program('mkosi', required : false)
|
||||
if want_integration_tests and not mkosi.found()
|
||||
error('Could not find mkosi which is required to run the integration tests')
|
||||
endif
|
||||
|
||||
mkosi_depends = public_programs
|
||||
|
||||
foreach executable : ['systemd-journal-remote', 'systemd-sbsign', 'systemd-keyutil']
|
||||
|
|
|
@ -509,7 +509,7 @@ option('install-tests', type : 'boolean', value : false,
|
|||
description : 'install test executables')
|
||||
option('log-message-verification', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' },
|
||||
description : 'do fake printf() calls to verify format strings')
|
||||
option('integration-tests', type : 'boolean', value : false,
|
||||
option('integration-tests', type : 'boolean', value : false, deprecated : true,
|
||||
description : 'run the integration tests')
|
||||
|
||||
option('ok-color', type : 'combo',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
[Config]
|
||||
MinimumVersion=commit:7e4ec15aee6b98300b2ee14265bc647a716a9f8a
|
||||
MinimumVersion=commit:dbb4020beee2cdf250f93a425794f1cf8b0fe693
|
||||
Dependencies=
|
||||
exitrd
|
||||
initrd
|
||||
|
@ -78,8 +78,7 @@ KernelCommandLine=
|
|||
oops=panic
|
||||
panic=-1
|
||||
softlockup_panic=1
|
||||
# Disabled due to BTRFS issue, waiting for the fix to become available
|
||||
panic_on_warn=0
|
||||
panic_on_warn=1
|
||||
psi=1
|
||||
mitigations=off
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Distribution=arch
|
||||
|
||||
[Content]
|
||||
PrepareScripts=systemd.prepare
|
||||
VolatilePackages=
|
||||
systemd
|
||||
systemd-libs
|
||||
|
|
|
@ -5,6 +5,7 @@ Distribution=|centos
|
|||
Distribution=|fedora
|
||||
|
||||
[Content]
|
||||
PrepareScripts=systemd.prepare
|
||||
VolatilePackages=
|
||||
systemd
|
||||
systemd-boot
|
||||
|
|
|
@ -5,6 +5,7 @@ Distribution=|debian
|
|||
Distribution=|ubuntu
|
||||
|
||||
[Content]
|
||||
PrepareScripts=systemd.prepare
|
||||
VolatilePackages=
|
||||
libnss-myhostname
|
||||
libnss-mymachines
|
||||
|
|
|
@ -11,6 +11,7 @@ Repositories=non-oss
|
|||
SandboxTrees=macros.db_backend:/etc/rpm/macros.db_backend
|
||||
|
||||
[Content]
|
||||
PrepareScripts=systemd.prepare
|
||||
VolatilePackages=
|
||||
libsystemd0
|
||||
libudev1
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Distribution=arch
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/systemd.prepare
|
||||
VolatilePackages=
|
||||
systemd
|
||||
systemd-libs
|
||||
|
|
|
@ -5,6 +5,6 @@ Distribution=|centos
|
|||
Distribution=|fedora
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/systemd.prepare
|
||||
VolatilePackages=
|
||||
systemd-standalone-shutdown
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
Distribution=debian
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/systemd.prepare
|
||||
VolatilePackages=
|
||||
systemd-standalone-shutdown
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Distribution=opensuse
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/systemd.prepare
|
||||
Packages=
|
||||
diffutils
|
||||
grep
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Distribution=ubuntu
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/systemd.prepare
|
||||
VolatilePackages=
|
||||
libsystemd-shared
|
||||
libsystemd0
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Distribution=arch
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/systemd.prepare
|
||||
Packages=
|
||||
btrfs-progs
|
||||
tpm2-tools
|
||||
|
|
|
@ -5,7 +5,7 @@ Distribution=|centos
|
|||
Distribution=|fedora
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/systemd.prepare
|
||||
Packages=
|
||||
tpm2-tools
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ Distribution=|debian
|
|||
Distribution=|ubuntu
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/systemd.prepare
|
||||
Packages=
|
||||
btrfs-progs
|
||||
tpm2-tools
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Distribution=opensuse
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/systemd.prepare
|
||||
Packages=
|
||||
btrfs-progs
|
||||
kmod
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Distribution=arch
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/systemd.prepare
|
||||
Packages=
|
||||
inetutils
|
||||
iproute
|
||||
|
|
|
@ -5,7 +5,7 @@ Distribution=|centos
|
|||
Distribution=|fedora
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/systemd.prepare
|
||||
Packages=
|
||||
hostname
|
||||
iproute
|
||||
|
|
|
@ -5,7 +5,7 @@ Distribution=|debian
|
|||
Distribution=|ubuntu
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/systemd.prepare
|
||||
Packages=
|
||||
hostname
|
||||
iproute2
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Distribution=opensuse
|
||||
|
||||
[Content]
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/mkosi.prepare
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/systemd.prepare
|
||||
Packages=
|
||||
diffutils
|
||||
grep
|
||||
|
|
|
@ -77,6 +77,20 @@ ENV{DDC_DEVICE}=="?*", TAG+="uaccess"
|
|||
# media player raw devices (for user-mode drivers, Android SDK, etc.)
|
||||
SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess"
|
||||
|
||||
# Android devices (ADB DbC, ADB, Fastboot)
|
||||
# Used to interact with devices over Android Debug Bridge and Fastboot protocols, see:
|
||||
# * https://developer.android.com/tools/adb
|
||||
# * https://source.android.com/docs/setup/test/running
|
||||
# * https://source.android.com/docs/setup/test/flash
|
||||
#
|
||||
# The bInterfaceClass and bInterfaceSubClass used are documented in source code here:
|
||||
# * https://android.googlesource.com/platform/packages/modules/adb/+/d0db47dcdf941673f405e1095e6ffb5e565902e5/adb.h#199
|
||||
# * https://android.googlesource.com/platform/system/core/+/7199051aaf0ddfa2849650933119307327d8669c/fastboot/fastboot.cpp#244
|
||||
#
|
||||
# Since it's using a generic vendor specific interface class, this can potentially result
|
||||
# in a rare case where non-ADB/Fastboot device ends up with an ID_DEBUG_APPLIANCE="android".
|
||||
SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:dc0201:*|*:ff4201:*|*:ff4203:*", ENV{ID_DEBUG_APPLIANCE}="android"
|
||||
|
||||
# software-defined radio communication devices
|
||||
ENV{ID_SOFTWARE_RADIO}=="?*", TAG+="uaccess"
|
||||
|
||||
|
@ -111,4 +125,7 @@ SUBSYSTEM=="hidraw", ENV{ID_HARDWARE_WALLET}=="1", TAG+="uaccess"
|
|||
# As defined in https://en.wikipedia.org/wiki/3Dconnexion
|
||||
SUBSYSTEM=="hidraw", ENV{ID_INPUT_3D_MOUSE}=="1", TAG+="uaccess"
|
||||
|
||||
# Debug interfaces (e.g. Android Debug Bridge)
|
||||
ENV{ID_DEBUG_APPLIANCE}=="?*", TAG+="uaccess"
|
||||
|
||||
LABEL="uaccess_end"
|
||||
|
|
|
@ -31,7 +31,7 @@ static void log_syntax_callback(const char *unit, int level, void *userdata) {
|
|||
|
||||
r = set_put_strdup(s, unit);
|
||||
if (r < 0) {
|
||||
set_free_free(*s);
|
||||
set_free(*s);
|
||||
*s = POINTER_MAX;
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ static int verify_unit(Unit *u, bool check_man, const char *root) {
|
|||
static void set_destroy_ignore_pointer_max(Set **s) {
|
||||
if (*s == POINTER_MAX)
|
||||
return;
|
||||
set_free_free(*s);
|
||||
set_free(*s);
|
||||
}
|
||||
|
||||
int verify_units(
|
||||
|
|
|
@ -1001,13 +1001,13 @@ int fd_verify_safe_flags_full(int fd, int extra_flags) {
|
|||
if (flags < 0)
|
||||
return -errno;
|
||||
|
||||
unexpected_flags = flags & ~(O_ACCMODE|O_NOFOLLOW|RAW_O_LARGEFILE|extra_flags);
|
||||
unexpected_flags = flags & ~(O_ACCMODE_STRICT|O_NOFOLLOW|RAW_O_LARGEFILE|extra_flags);
|
||||
if (unexpected_flags != 0)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EREMOTEIO),
|
||||
"Unexpected flags set for extrinsic fd: 0%o",
|
||||
(unsigned) unexpected_flags);
|
||||
|
||||
return flags & (O_ACCMODE | extra_flags); /* return the flags variable, but remove the noise */
|
||||
return flags & (O_ACCMODE_STRICT | extra_flags); /* return the flags variable, but remove the noise */
|
||||
}
|
||||
|
||||
int read_nr_open(void) {
|
||||
|
@ -1132,7 +1132,7 @@ int fds_are_same_mount(int fd1, int fd2) {
|
|||
}
|
||||
|
||||
const char* accmode_to_string(int flags) {
|
||||
switch (flags & O_ACCMODE) {
|
||||
switch (flags & O_ACCMODE_STRICT) {
|
||||
case O_RDONLY:
|
||||
return "ro";
|
||||
case O_WRONLY:
|
||||
|
|
|
@ -1036,7 +1036,7 @@ int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_
|
|||
|
||||
if (flags & ~(O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_EXCL|O_NOATIME|O_NOFOLLOW|O_PATH))
|
||||
return -EINVAL;
|
||||
if ((flags & O_ACCMODE) != O_RDONLY)
|
||||
if ((flags & O_ACCMODE_STRICT) != O_RDONLY)
|
||||
return -EINVAL;
|
||||
|
||||
/* Note that O_DIRECTORY|O_NOFOLLOW is implied, but we allow specifying it anyway. The following
|
||||
|
|
|
@ -90,6 +90,8 @@ OrderedHashmap* _ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DE
|
|||
|
||||
#define hashmap_free_and_replace(a, b) \
|
||||
free_and_replace_full(a, b, hashmap_free)
|
||||
#define ordered_hashmap_free_and_replace(a, b) \
|
||||
free_and_replace_full(a, b, ordered_hashmap_free)
|
||||
|
||||
HashmapBase* _hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
|
||||
static inline Hashmap* hashmap_free(Hashmap *h) {
|
||||
|
|
|
@ -43,3 +43,9 @@
|
|||
#ifndef AT_HANDLE_FID
|
||||
#define AT_HANDLE_FID AT_REMOVEDIR
|
||||
#endif
|
||||
|
||||
/* On musl, O_ACCMODE is defined as (03|O_SEARCH), unlike glibc which defines it as
|
||||
* (O_RDONLY|O_WRONLY|O_RDWR). Additionally, O_SEARCH is simply defined as O_PATH. This changes the behaviour
|
||||
* of O_ACCMODE in certain situations, which we don't want. This definition is copied from glibc and works
|
||||
* around the problems with musl's definition. */
|
||||
#define O_ACCMODE_STRICT (O_RDONLY|O_WRONLY|O_RDWR)
|
||||
|
|
|
@ -267,7 +267,7 @@ static int acquire_path(const char *path, int flags, mode_t mode) {
|
|||
|
||||
assert(path);
|
||||
|
||||
if (IN_SET(flags & O_ACCMODE, O_WRONLY, O_RDWR))
|
||||
if (IN_SET(flags & O_ACCMODE_STRICT, O_WRONLY, O_RDWR))
|
||||
flags |= O_CREAT;
|
||||
|
||||
fd = open(path, flags|O_NOCTTY, mode);
|
||||
|
@ -291,9 +291,9 @@ static int acquire_path(const char *path, int flags, mode_t mode) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if ((flags & O_ACCMODE) == O_RDONLY)
|
||||
if ((flags & O_ACCMODE_STRICT) == O_RDONLY)
|
||||
r = shutdown(fd, SHUT_WR);
|
||||
else if ((flags & O_ACCMODE) == O_WRONLY)
|
||||
else if ((flags & O_ACCMODE_STRICT) == O_WRONLY)
|
||||
r = shutdown(fd, SHUT_RD);
|
||||
else
|
||||
r = 0;
|
||||
|
|
|
@ -38,11 +38,10 @@ static VacuumCandidate* vacuum_candidate_free(VacuumCandidate *c) {
|
|||
}
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(VacuumCandidate*, vacuum_candidate_free);
|
||||
|
||||
static Hashmap* vacuum_candidate_hashmap_free(Hashmap *h) {
|
||||
return hashmap_free_with_destructor(h, vacuum_candidate_free);
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, vacuum_candidate_hashmap_free);
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
vacuum_candidate_hash_ops,
|
||||
void, trivial_hash_func, trivial_compare_func,
|
||||
VacuumCandidate, vacuum_candidate_free);
|
||||
|
||||
static int uid_from_file_name(const char *filename, uid_t *uid) {
|
||||
const char *p, *e, *u;
|
||||
|
@ -141,7 +140,7 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
_cleanup_(vacuum_candidate_hashmap_freep) Hashmap *h = NULL;
|
||||
_cleanup_hashmap_free_ Hashmap *h = NULL;
|
||||
VacuumCandidate *worst = NULL;
|
||||
uint64_t sum = 0;
|
||||
|
||||
|
@ -171,10 +170,6 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
|
|||
if (exclude_fd >= 0 && stat_inode_same(&exclude_st, &st))
|
||||
continue;
|
||||
|
||||
r = hashmap_ensure_allocated(&h, NULL);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
t = timespec_load(&st.st_mtim);
|
||||
|
||||
c = hashmap_get(h, UID_TO_PTR(uid));
|
||||
|
@ -197,7 +192,7 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
|
|||
return r;
|
||||
n->oldest_mtime = t;
|
||||
|
||||
r = hashmap_put(h, UID_TO_PTR(uid), n);
|
||||
r = hashmap_ensure_put(&h, &vacuum_candidate_hash_ops, UID_TO_PTR(uid), n);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ static void device_unref_many(sd_device **devices, size_t n) {
|
|||
static void device_enumerator_unref_devices(sd_device_enumerator *enumerator) {
|
||||
assert(enumerator);
|
||||
|
||||
hashmap_clear_with_destructor(enumerator->devices_by_syspath, sd_device_unref);
|
||||
hashmap_clear(enumerator->devices_by_syspath);
|
||||
device_unref_many(enumerator->devices, enumerator->n_devices);
|
||||
enumerator->devices = mfree(enumerator->devices);
|
||||
enumerator->n_devices = 0;
|
||||
|
@ -471,6 +471,11 @@ failed:
|
|||
return r;
|
||||
}
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
device_hash_ops_by_syspath,
|
||||
char, path_hash_func, path_compare,
|
||||
sd_device, sd_device_unref);
|
||||
|
||||
int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device) {
|
||||
const char *syspath;
|
||||
int r;
|
||||
|
@ -482,7 +487,7 @@ int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *de
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_ensure_put(&enumerator->devices_by_syspath, &string_hash_ops, syspath, device);
|
||||
r = hashmap_ensure_put(&enumerator->devices_by_syspath, &device_hash_ops_by_syspath, syspath, device);
|
||||
if (IN_SET(r, -EEXIST, 0))
|
||||
return 0;
|
||||
if (r < 0)
|
||||
|
|
|
@ -692,8 +692,8 @@ int device_clone_with_db(sd_device *device, sd_device **ret) {
|
|||
void device_cleanup_tags(sd_device *device) {
|
||||
assert(device);
|
||||
|
||||
device->all_tags = set_free_free(device->all_tags);
|
||||
device->current_tags = set_free_free(device->current_tags);
|
||||
device->all_tags = set_free(device->all_tags);
|
||||
device->current_tags = set_free(device->current_tags);
|
||||
device->property_tags_outdated = true;
|
||||
device->tags_generation++;
|
||||
}
|
||||
|
@ -701,7 +701,7 @@ void device_cleanup_tags(sd_device *device) {
|
|||
void device_cleanup_devlinks(sd_device *device) {
|
||||
assert(device);
|
||||
|
||||
set_free_free(device->devlinks);
|
||||
set_free(device->devlinks);
|
||||
device->devlinks = NULL;
|
||||
device->property_devlinks_outdated = true;
|
||||
device->devlinks_generation++;
|
||||
|
|
|
@ -98,7 +98,7 @@ DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
|||
JournalFile, journal_file_close);
|
||||
|
||||
static int mmap_prot_from_open_flags(int flags) {
|
||||
switch (flags & O_ACCMODE) {
|
||||
switch (flags & O_ACCMODE_STRICT) {
|
||||
case O_RDONLY:
|
||||
return PROT_READ;
|
||||
case O_WRONLY:
|
||||
|
@ -4075,10 +4075,10 @@ int journal_file_open(
|
|||
assert(mmap_cache);
|
||||
assert(ret);
|
||||
|
||||
if (!IN_SET((open_flags & O_ACCMODE), O_RDONLY, O_RDWR))
|
||||
if (!IN_SET((open_flags & O_ACCMODE_STRICT), O_RDONLY, O_RDWR))
|
||||
return -EINVAL;
|
||||
|
||||
if ((open_flags & O_ACCMODE) == O_RDONLY && FLAGS_SET(open_flags, O_CREAT))
|
||||
if ((open_flags & O_ACCMODE_STRICT) == O_RDONLY && FLAGS_SET(open_flags, O_CREAT))
|
||||
return -EINVAL;
|
||||
|
||||
if (fname && (open_flags & O_CREAT) && !endswith(fname, ".journal"))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
|
@ -15,6 +14,7 @@
|
|||
#include "compress.h"
|
||||
#include "hashmap.h"
|
||||
#include "journal-def.h"
|
||||
#include "missing_fcntl.h"
|
||||
#include "mmap-cache.h"
|
||||
#include "sparse-endian.h"
|
||||
#include "time-util.h"
|
||||
|
@ -391,5 +391,5 @@ static inline uint32_t COMPRESSION_TO_HEADER_INCOMPATIBLE_FLAG(Compression c) {
|
|||
|
||||
static inline bool journal_file_writable(JournalFile *f) {
|
||||
assert(f);
|
||||
return (f->open_flags & O_ACCMODE) != O_RDONLY;
|
||||
return (f->open_flags & O_ACCMODE_STRICT) != O_RDONLY;
|
||||
}
|
||||
|
|
|
@ -46,11 +46,21 @@ static GenericNetlinkFamily *genl_family_free(GenericNetlinkFamily *f) {
|
|||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(GenericNetlinkFamily*, genl_family_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
genl_family_hash_ops_by_name,
|
||||
char, string_hash_func, string_compare_func,
|
||||
GenericNetlinkFamily, genl_family_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
genl_family_hash_ops_by_id,
|
||||
void, trivial_hash_func, trivial_compare_func,
|
||||
GenericNetlinkFamily, genl_family_free);
|
||||
|
||||
void genl_clear_family(sd_netlink *nl) {
|
||||
assert(nl);
|
||||
|
||||
nl->genl_family_by_name = hashmap_free_with_destructor(nl->genl_family_by_name, genl_family_free);
|
||||
nl->genl_family_by_id = hashmap_free_with_destructor(nl->genl_family_by_id, genl_family_free);
|
||||
nl->genl_family_by_name = hashmap_free(nl->genl_family_by_name);
|
||||
nl->genl_family_by_id = hashmap_free(nl->genl_family_by_id);
|
||||
}
|
||||
|
||||
static int genl_family_new_unsupported(
|
||||
|
@ -80,7 +90,7 @@ static int genl_family_new_unsupported(
|
|||
if (!f->name)
|
||||
return -ENOMEM;
|
||||
|
||||
r = hashmap_ensure_put(&nl->genl_family_by_name, &string_hash_ops, f->name, f);
|
||||
r = hashmap_ensure_put(&nl->genl_family_by_name, &genl_family_hash_ops_by_name, f->name, f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -190,11 +200,11 @@ static int genl_family_new(
|
|||
return r;
|
||||
}
|
||||
|
||||
r = hashmap_ensure_put(&nl->genl_family_by_id, NULL, UINT_TO_PTR(f->id), f);
|
||||
r = hashmap_ensure_put(&nl->genl_family_by_id, &genl_family_hash_ops_by_id, UINT_TO_PTR(f->id), f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_ensure_put(&nl->genl_family_by_name, &string_hash_ops, f->name, f);
|
||||
r = hashmap_ensure_put(&nl->genl_family_by_name, &genl_family_hash_ops_by_name, f->name, f);
|
||||
if (r < 0) {
|
||||
hashmap_remove(nl->genl_family_by_id, UINT_TO_PTR(f->id));
|
||||
return r;
|
||||
|
|
|
@ -161,12 +161,13 @@ static int socket_recv_message(int fd, void *buf, size_t buf_size, uint32_t *ret
|
|||
assert(fd >= 0);
|
||||
assert(peek || (buf && buf_size > 0));
|
||||
|
||||
/* Note: this might return successfully, but with a zero size under some transient conditions, such
|
||||
* as the reception of a non-kernel message. In such a case the passed buffer might or might not be
|
||||
* modified. Caller must treat a zero return as "no message, but also not an error". */
|
||||
|
||||
n = recvmsg_safe(fd, &msg, peek ? (MSG_PEEK|MSG_TRUNC) : 0);
|
||||
if (ERRNO_IS_NEG_TRANSIENT(n)) {
|
||||
if (ret_mcast_group)
|
||||
*ret_mcast_group = 0;
|
||||
return 0;
|
||||
}
|
||||
if (ERRNO_IS_NEG_TRANSIENT(n))
|
||||
goto transient;
|
||||
if (n == -ENOBUFS)
|
||||
return log_debug_errno(n, "sd-netlink: kernel receive buffer overrun");
|
||||
if (n == -ECHRNG)
|
||||
|
@ -181,21 +182,16 @@ static int socket_recv_message(int fd, void *buf, size_t buf_size, uint32_t *ret
|
|||
log_debug("sd-netlink: ignoring message from PID %"PRIu32, sender.nl.nl_pid);
|
||||
|
||||
if (peek) {
|
||||
_cleanup_free_ uint8_t *b = new(uint8_t, n);
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
|
||||
iov = IOVEC_MAKE(b, n);
|
||||
|
||||
/* drop the message */
|
||||
/* Drop the message. Note that we ignore ECHRNG/EXFULL errors here, which
|
||||
* recvmsg_safe() returns in case the payload or cdata is truncated. Given we just
|
||||
* want to drop the message we also don't care if its payload or cdata was
|
||||
* truncated. */
|
||||
n = recvmsg_safe(fd, &msg, 0);
|
||||
if (n < 0)
|
||||
if (n < 0 && !IN_SET(n, -ECHRNG, -EXFULL))
|
||||
return (int) n;
|
||||
}
|
||||
|
||||
if (ret_mcast_group)
|
||||
*ret_mcast_group = 0;
|
||||
return 0;
|
||||
goto transient;
|
||||
}
|
||||
|
||||
if (ret_mcast_group) {
|
||||
|
@ -209,6 +205,12 @@ static int socket_recv_message(int fd, void *buf, size_t buf_size, uint32_t *ret
|
|||
}
|
||||
|
||||
return (int) n;
|
||||
|
||||
transient:
|
||||
if (ret_mcast_group)
|
||||
*ret_mcast_group = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
|
|
|
@ -436,7 +436,11 @@ _public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_dev
|
|||
*
|
||||
* Returns: a new udev device, or #NULL if no matching parent exists.
|
||||
**/
|
||||
_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) {
|
||||
_public_ struct udev_device* udev_device_get_parent_with_subsystem_devtype(
|
||||
struct udev_device *udev_device,
|
||||
const char *subsystem,
|
||||
const char *devtype) {
|
||||
|
||||
sd_device *parent;
|
||||
int r;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "hashmap.h"
|
||||
#include "libudev-list-internal.h"
|
||||
#include "list.h"
|
||||
#include "sort-util.h"
|
||||
|
||||
/**
|
||||
* SECTION:libudev-list
|
||||
|
@ -54,6 +53,11 @@ static struct udev_list_entry *udev_list_entry_free(struct udev_list_entry *entr
|
|||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_list_entry*, udev_list_entry_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
udev_list_entry_hash_ops,
|
||||
char, string_hash_func, string_compare_func,
|
||||
struct udev_list_entry, udev_list_entry_free);
|
||||
|
||||
struct udev_list* udev_list_new(bool unique) {
|
||||
struct udev_list *list;
|
||||
|
||||
|
@ -68,36 +72,26 @@ struct udev_list *udev_list_new(bool unique) {
|
|||
return list;
|
||||
}
|
||||
|
||||
struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char *_name, const char *_value) {
|
||||
struct udev_list_entry* udev_list_entry_add(struct udev_list *list, const char *name, const char *value) {
|
||||
_cleanup_(udev_list_entry_freep) struct udev_list_entry *entry = NULL;
|
||||
_cleanup_free_ char *name = NULL, *value = NULL;
|
||||
|
||||
assert(list);
|
||||
assert(_name);
|
||||
assert(name);
|
||||
|
||||
name = strdup(_name);
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
if (_value) {
|
||||
value = strdup(_value);
|
||||
if (!value)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry = new(struct udev_list_entry, 1);
|
||||
entry = new0(struct udev_list_entry, 1);
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
*entry = (struct udev_list_entry) {
|
||||
.name = TAKE_PTR(name),
|
||||
.value = TAKE_PTR(value),
|
||||
};
|
||||
if (strdup_to(&entry->name, name) < 0)
|
||||
return NULL;
|
||||
|
||||
if (strdup_to(&entry->value, value) < 0)
|
||||
return NULL;
|
||||
|
||||
if (list->unique) {
|
||||
udev_list_entry_free(hashmap_get(list->unique_entries, entry->name));
|
||||
|
||||
if (hashmap_ensure_put(&list->unique_entries, &string_hash_ops, entry->name, entry) < 0)
|
||||
if (hashmap_ensure_put(&list->unique_entries, &udev_list_entry_hash_ops, entry->name, entry) < 0)
|
||||
return NULL;
|
||||
|
||||
list->uptodate = false;
|
||||
|
@ -115,7 +109,7 @@ void udev_list_cleanup(struct udev_list *list) {
|
|||
|
||||
if (list->unique) {
|
||||
list->uptodate = false;
|
||||
hashmap_clear_with_destructor(list->unique_entries, udev_list_entry_free);
|
||||
hashmap_clear(list->unique_entries);
|
||||
} else
|
||||
LIST_FOREACH(entries, i, list->entries)
|
||||
udev_list_entry_free(i);
|
||||
|
@ -131,10 +125,6 @@ struct udev_list *udev_list_free(struct udev_list *list) {
|
|||
return mfree(list);
|
||||
}
|
||||
|
||||
static int udev_list_entry_compare_func(struct udev_list_entry * const *a, struct udev_list_entry * const *b) {
|
||||
return strcmp((*a)->name, (*b)->name);
|
||||
}
|
||||
|
||||
struct udev_list_entry* udev_list_get_entry(struct udev_list *list) {
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
@ -151,18 +141,10 @@ struct udev_list_entry *udev_list_get_entry(struct udev_list *list) {
|
|||
LIST_PREPEND(entries, list->entries, hashmap_first(list->unique_entries));
|
||||
else {
|
||||
_cleanup_free_ struct udev_list_entry **buf = NULL;
|
||||
struct udev_list_entry *entry, **p;
|
||||
|
||||
buf = new(struct udev_list_entry *, n);
|
||||
if (!buf)
|
||||
if (hashmap_dump_sorted(list->unique_entries, (void***) &buf, /* ret_n = */ NULL) < 0)
|
||||
return NULL;
|
||||
|
||||
p = buf;
|
||||
HASHMAP_FOREACH(entry, list->unique_entries)
|
||||
*p++ = entry;
|
||||
|
||||
typesafe_qsort(buf, n, udev_list_entry_compare_func);
|
||||
|
||||
for (size_t j = n; j > 0; j--)
|
||||
LIST_PREPEND(entries, list->entries, buf[j-1]);
|
||||
}
|
||||
|
|
|
@ -155,8 +155,11 @@ _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) {
|
|||
*
|
||||
* Returns: a flag indicating if udev is currently handling events.
|
||||
**/
|
||||
_public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
|
||||
unsigned long long int start, unsigned long long int end) {
|
||||
_public_ int udev_queue_get_seqnum_sequence_is_finished(
|
||||
struct udev_queue *udev_queue,
|
||||
unsigned long long int start,
|
||||
unsigned long long int end) {
|
||||
|
||||
return udev_queue_is_empty() > 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,8 +125,12 @@ _public_ struct udev *udev_unref(struct udev *udev) {
|
|||
_public_ void udev_set_log_fn(
|
||||
struct udev *udev,
|
||||
void (*log_fn)(struct udev *udev,
|
||||
int priority, const char *file, int line, const char *fn,
|
||||
const char *format, va_list args)) {
|
||||
int priority,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *fn,
|
||||
const char *format,
|
||||
va_list args)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,15 @@ struct udev;
|
|||
struct udev* udev_ref(struct udev *udev);
|
||||
struct udev* udev_unref(struct udev *udev);
|
||||
struct udev* udev_new(void);
|
||||
void udev_set_log_fn(struct udev *udev,
|
||||
void udev_set_log_fn(
|
||||
struct udev *udev,
|
||||
void (*log_fn)(struct udev *udev,
|
||||
int priority, const char *file, int line, const char *fn,
|
||||
const char *format, va_list args)) __attribute__((__deprecated__));
|
||||
int priority,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *fn,
|
||||
const char *format,
|
||||
va_list args)) __attribute__((__deprecated__));
|
||||
int udev_get_log_priority(struct udev *udev) __attribute__((__deprecated__));
|
||||
void udev_set_log_priority(struct udev *udev, int priority) __attribute__((__deprecated__));
|
||||
void* udev_get_userdata(struct udev *udev);
|
||||
|
@ -68,8 +73,10 @@ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char
|
|||
struct udev_device* udev_device_new_from_environment(struct udev *udev);
|
||||
/* udev_device_get_parent_*() does not take a reference on the returned device, it is automatically unref'd with the parent */
|
||||
struct udev_device* udev_device_get_parent(struct udev_device *udev_device);
|
||||
struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device,
|
||||
const char *subsystem, const char *devtype);
|
||||
struct udev_device* udev_device_get_parent_with_subsystem_devtype(
|
||||
struct udev_device *udev_device,
|
||||
const char *subsystem,
|
||||
const char *devtype);
|
||||
/* retrieve device properties */
|
||||
const char* udev_device_get_devpath(struct udev_device *udev_device);
|
||||
const char* udev_device_get_subsystem(struct udev_device *udev_device);
|
||||
|
@ -112,8 +119,10 @@ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int
|
|||
int udev_monitor_get_fd(struct udev_monitor *udev_monitor);
|
||||
struct udev_device* udev_monitor_receive_device(struct udev_monitor *udev_monitor);
|
||||
/* in-kernel socket filters to select messages that get delivered to a listener */
|
||||
int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor,
|
||||
const char *subsystem, const char *devtype);
|
||||
int udev_monitor_filter_add_match_subsystem_devtype(
|
||||
struct udev_monitor *udev_monitor,
|
||||
const char *subsystem,
|
||||
const char *devtype);
|
||||
int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag);
|
||||
int udev_monitor_filter_update(struct udev_monitor *udev_monitor);
|
||||
int udev_monitor_filter_remove(struct udev_monitor *udev_monitor);
|
||||
|
@ -160,8 +169,10 @@ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue)
|
|||
int udev_queue_get_udev_is_active(struct udev_queue *udev_queue);
|
||||
int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue);
|
||||
int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) __attribute__((__deprecated__));
|
||||
int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
|
||||
unsigned long long int start, unsigned long long int end) __attribute__((__deprecated__));
|
||||
int udev_queue_get_seqnum_sequence_is_finished(
|
||||
struct udev_queue *udev_queue,
|
||||
unsigned long long int start,
|
||||
unsigned long long int end) __attribute__((__deprecated__));
|
||||
int udev_queue_get_fd(struct udev_queue *udev_queue);
|
||||
int udev_queue_flush(struct udev_queue *udev_queue);
|
||||
struct udev_list_entry* udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) __attribute__((__deprecated__));
|
||||
|
|
|
@ -536,7 +536,7 @@ static int method_set_tty(sd_bus_message *message, void *userdata, sd_bus_error
|
|||
flags = fcntl(fd, F_GETFL, 0);
|
||||
if (flags < 0)
|
||||
return -errno;
|
||||
if ((flags & O_ACCMODE) != O_RDWR)
|
||||
if ((flags & O_ACCMODE_STRICT) != O_RDWR)
|
||||
return -EACCES;
|
||||
if (FLAGS_SET(flags, O_PATH))
|
||||
return -ENOTTY;
|
||||
|
|
|
@ -99,7 +99,7 @@ static int validate_image_fd(int fd, MountImageParameters *p) {
|
|||
if (fl < 0)
|
||||
return log_debug_errno(fl, "Image file descriptor has unsafe flags set: %m");
|
||||
|
||||
switch (fl & O_ACCMODE) {
|
||||
switch (fl & O_ACCMODE_STRICT) {
|
||||
|
||||
case O_RDONLY:
|
||||
p->read_only = true;
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
|
||||
#define STATIC_BRIDGE_FDB_ENTRIES_PER_NETWORK_MAX 1024U
|
||||
|
||||
/* remove and FDB entry. */
|
||||
BridgeFDB *bridge_fdb_free(BridgeFDB *fdb) {
|
||||
static BridgeFDB* bridge_fdb_free(BridgeFDB *fdb) {
|
||||
if (!fdb)
|
||||
return NULL;
|
||||
|
||||
|
@ -40,7 +39,11 @@ BridgeFDB *bridge_fdb_free(BridgeFDB *fdb) {
|
|||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(BridgeFDB, bridge_fdb_free);
|
||||
|
||||
/* create a new FDB entry or get an existing one. */
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
bridge_fdb_hash_ops_by_section,
|
||||
ConfigSection, config_section_hash_func, config_section_compare_func,
|
||||
BridgeFDB, bridge_fdb_free);
|
||||
|
||||
static int bridge_fdb_new_static(
|
||||
Network *network,
|
||||
const char *filename,
|
||||
|
@ -83,13 +86,12 @@ static int bridge_fdb_new_static(
|
|||
.ntf_flags = NEIGHBOR_CACHE_ENTRY_FLAGS_SELF,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_put(&network->bridge_fdb_entries_by_section, &config_section_hash_ops, fdb->section, fdb);
|
||||
r = hashmap_ensure_put(&network->bridge_fdb_entries_by_section, &bridge_fdb_hash_ops_by_section, fdb->section, fdb);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* return allocated FDB structure. */
|
||||
*ret = TAKE_PTR(fdb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,6 @@ typedef struct BridgeFDB {
|
|||
int outgoing_ifindex;
|
||||
} BridgeFDB;
|
||||
|
||||
BridgeFDB *bridge_fdb_free(BridgeFDB *fdb);
|
||||
|
||||
void network_drop_invalid_bridge_fdb_entries(Network *network);
|
||||
|
||||
int link_request_static_bridge_fdb(Link *link);
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
#include "networkd-manager.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-util.h"
|
||||
#include "string-util.h"
|
||||
#include "vlan-util.h"
|
||||
|
||||
#define STATIC_BRIDGE_MDB_ENTRIES_PER_NETWORK_MAX 1024U
|
||||
|
||||
/* remove MDB entry. */
|
||||
BridgeMDB *bridge_mdb_free(BridgeMDB *mdb) {
|
||||
static BridgeMDB* bridge_mdb_free(BridgeMDB *mdb) {
|
||||
if (!mdb)
|
||||
return NULL;
|
||||
|
||||
|
@ -32,7 +32,11 @@ BridgeMDB *bridge_mdb_free(BridgeMDB *mdb) {
|
|||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(BridgeMDB, bridge_mdb_free);
|
||||
|
||||
/* create a new MDB entry or get an existing one. */
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
bridge_mdb_hash_ops_by_section,
|
||||
ConfigSection, config_section_hash_func, config_section_compare_func,
|
||||
BridgeMDB, bridge_mdb_free);
|
||||
|
||||
static int bridge_mdb_new_static(
|
||||
Network *network,
|
||||
const char *filename,
|
||||
|
@ -74,7 +78,7 @@ static int bridge_mdb_new_static(
|
|||
.type = _BRIDGE_MDB_ENTRY_TYPE_INVALID,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_put(&network->bridge_mdb_entries_by_section, &config_section_hash_ops, mdb->section, mdb);
|
||||
r = hashmap_ensure_put(&network->bridge_mdb_entries_by_section, &bridge_mdb_hash_ops_by_section, mdb->section, mdb);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "conf-parser.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "networkd-util.h"
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Network Network;
|
||||
|
@ -30,8 +29,6 @@ typedef struct BridgeMDB {
|
|||
uint16_t vlan_id;
|
||||
} BridgeMDB;
|
||||
|
||||
BridgeMDB *bridge_mdb_free(BridgeMDB *mdb);
|
||||
|
||||
void network_drop_invalid_bridge_mdb_entries(Network *network);
|
||||
|
||||
int link_request_static_bridge_mdb(Link *link);
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
#include "networkd-network.h"
|
||||
#include "networkd-util.h"
|
||||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(DHCPStaticLease, dhcp_static_lease_free);
|
||||
|
||||
DHCPStaticLease *dhcp_static_lease_free(DHCPStaticLease *static_lease) {
|
||||
static DHCPStaticLease* dhcp_static_lease_free(DHCPStaticLease *static_lease) {
|
||||
if (!static_lease)
|
||||
return NULL;
|
||||
|
||||
|
@ -21,6 +19,13 @@ DHCPStaticLease *dhcp_static_lease_free(DHCPStaticLease *static_lease) {
|
|||
return mfree(static_lease);
|
||||
}
|
||||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(DHCPStaticLease, dhcp_static_lease_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
static_lease_hash_ops_by_section,
|
||||
ConfigSection, config_section_hash_func, config_section_compare_func,
|
||||
DHCPStaticLease, dhcp_static_lease_free);
|
||||
|
||||
static int dhcp_static_lease_new(DHCPStaticLease **ret) {
|
||||
DHCPStaticLease *p;
|
||||
|
||||
|
@ -60,7 +65,8 @@ static int lease_new_static(Network *network, const char *filename, unsigned sec
|
|||
|
||||
static_lease->network = network;
|
||||
static_lease->section = TAKE_PTR(n);
|
||||
r = hashmap_ensure_put(&network->dhcp_static_leases_by_section, &config_section_hash_ops, static_lease->section, static_lease);
|
||||
|
||||
r = hashmap_ensure_put(&network->dhcp_static_leases_by_section, &static_lease_hash_ops_by_section, static_lease->section, static_lease);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ typedef struct DHCPStaticLease {
|
|||
size_t client_id_size;
|
||||
} DHCPStaticLease;
|
||||
|
||||
DHCPStaticLease *dhcp_static_lease_free(DHCPStaticLease *lease);
|
||||
void network_drop_invalid_static_leases(Network *network);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_static_lease_address);
|
||||
|
|
|
@ -281,7 +281,7 @@ int config_parse_dnssec_negative_trust_anchors(
|
|||
assert(rvalue);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
*nta = set_free_free(*nta);
|
||||
*nta = set_free(*nta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -306,7 +306,7 @@ int config_parse_dnssec_negative_trust_anchors(
|
|||
continue;
|
||||
}
|
||||
|
||||
r = set_ensure_consume(nta, &dns_name_hash_ops, TAKE_PTR(w));
|
||||
r = set_ensure_consume(nta, &dns_name_hash_ops_free, TAKE_PTR(w));
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,13 @@ void network_adjust_ipv6_proxy_ndp(Network *network) {
|
|||
log_once(LOG_WARNING,
|
||||
"%s: IPv6 proxy NDP addresses are set, but IPv6 is not supported by kernel, "
|
||||
"Ignoring IPv6 proxy NDP addresses.", network->filename);
|
||||
network->ipv6_proxy_ndp_addresses = set_free_free(network->ipv6_proxy_ndp_addresses);
|
||||
network->ipv6_proxy_ndp_addresses = set_free(network->ipv6_proxy_ndp_addresses);
|
||||
return;
|
||||
}
|
||||
|
||||
if (network->ipv6_proxy_ndp == 0) {
|
||||
log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network->filename);
|
||||
network->ipv6_proxy_ndp_addresses = set_free(network->ipv6_proxy_ndp_addresses);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +155,7 @@ int config_parse_ipv6_proxy_ndp_address(
|
|||
assert(rvalue);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
network->ipv6_proxy_ndp_addresses = set_free_free(network->ipv6_proxy_ndp_addresses);
|
||||
network->ipv6_proxy_ndp_addresses = set_free(network->ipv6_proxy_ndp_addresses);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -170,11 +176,9 @@ int config_parse_ipv6_proxy_ndp_address(
|
|||
if (!address)
|
||||
return log_oom();
|
||||
|
||||
r = set_ensure_put(&network->ipv6_proxy_ndp_addresses, &in6_addr_hash_ops, address);
|
||||
r = set_ensure_consume(&network->ipv6_proxy_ndp_addresses, &in6_addr_hash_ops_free, TAKE_PTR(address));
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
if (r > 0)
|
||||
TAKE_PTR(address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -479,7 +479,7 @@ int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_e
|
|||
}
|
||||
|
||||
int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_set_free_free_ Set *ns = NULL;
|
||||
_cleanup_set_free_ Set *ns = NULL;
|
||||
_cleanup_strv_free_ char **ntas = NULL;
|
||||
Link *l = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
@ -502,7 +502,7 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
|
|||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid negative trust anchor domain: %s", *i);
|
||||
}
|
||||
|
||||
ns = set_new(&dns_name_hash_ops);
|
||||
ns = set_new(&dns_name_hash_ops_free);
|
||||
if (!ns)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -523,8 +523,7 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
|
|||
if (r == 0)
|
||||
return 1; /* Polkit will call us back */
|
||||
|
||||
set_free_free(l->dnssec_negative_trust_anchors);
|
||||
l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
|
||||
set_free_and_replace(l->dnssec_negative_trust_anchors, ns);
|
||||
|
||||
r = link_save_and_clean_full(l, /* also_save_manager = */ true);
|
||||
if (r < 0)
|
||||
|
|
|
@ -231,7 +231,7 @@ void link_dns_settings_clear(Link *link) {
|
|||
link->dnssec_mode = _DNSSEC_MODE_INVALID;
|
||||
link->dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID;
|
||||
|
||||
link->dnssec_negative_trust_anchors = set_free_free(link->dnssec_negative_trust_anchors);
|
||||
link->dnssec_negative_trust_anchors = set_free(link->dnssec_negative_trust_anchors);
|
||||
}
|
||||
|
||||
static void link_free_engines(Link *link) {
|
||||
|
@ -295,7 +295,7 @@ static Link *link_free(Link *link) {
|
|||
hashmap_free(link->bound_to_links);
|
||||
hashmap_free(link->bound_by_links);
|
||||
|
||||
set_free_with_destructor(link->slaves, link_unref);
|
||||
set_free(link->slaves);
|
||||
|
||||
network_unref(link->network);
|
||||
|
||||
|
@ -307,6 +307,11 @@ static Link *link_free(Link *link) {
|
|||
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(Link, link, link_free);
|
||||
|
||||
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
link_hash_ops,
|
||||
void, trivial_hash_func, trivial_compare_func,
|
||||
Link, link_unref);
|
||||
|
||||
int link_get_by_index(Manager *m, int ifindex, Link **ret) {
|
||||
Link *link;
|
||||
|
||||
|
@ -985,7 +990,7 @@ static int link_append_to_master(Link *link) {
|
|||
if (link_get_master(link, &master) < 0)
|
||||
return 0;
|
||||
|
||||
r = set_ensure_put(&master->slaves, NULL, link);
|
||||
r = set_ensure_put(&master->slaves, &link_hash_ops, link);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
|
@ -2746,7 +2751,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
|
|||
.dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_put(&manager->links_by_index, NULL, INT_TO_PTR(link->ifindex), link);
|
||||
r = hashmap_ensure_put(&manager->links_by_index, &link_hash_ops, INT_TO_PTR(link->ifindex), link);
|
||||
if (r < 0)
|
||||
return log_link_debug_errno(link, r, "Failed to store link into manager: %m");
|
||||
|
||||
|
|
|
@ -222,6 +222,8 @@ typedef struct Link {
|
|||
char **ntp;
|
||||
} Link;
|
||||
|
||||
extern const struct hash_ops link_hash_ops;
|
||||
|
||||
typedef int (*link_netlink_message_handler_t)(sd_netlink*, sd_netlink_message*, Link*);
|
||||
|
||||
bool link_is_ready_to_configure(Link *link, bool allow_unmanaged);
|
||||
|
|
|
@ -672,15 +672,16 @@ Manager* manager_free(Manager *m) {
|
|||
m->request_queue = ordered_set_free(m->request_queue);
|
||||
m->remove_request_queue = ordered_set_free(m->remove_request_queue);
|
||||
|
||||
m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
|
||||
m->new_wlan_ifindices = set_free(m->new_wlan_ifindices);
|
||||
|
||||
m->dirty_links = set_free(m->dirty_links);
|
||||
m->links_by_name = hashmap_free(m->links_by_name);
|
||||
m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr);
|
||||
m->links_by_dhcp_pd_subnet_prefix = hashmap_free(m->links_by_dhcp_pd_subnet_prefix);
|
||||
m->links_by_index = hashmap_free_with_destructor(m->links_by_index, link_unref);
|
||||
m->links_by_index = hashmap_free(m->links_by_index);
|
||||
|
||||
m->dhcp_pd_subnet_ids = set_free(m->dhcp_pd_subnet_ids);
|
||||
m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
|
||||
m->networks = ordered_hashmap_free(m->networks);
|
||||
|
||||
/* The same object may be registered with multiple names, and netdev_detach() may drop multiple
|
||||
* entries. Hence, hashmap_free_with_destructor() cannot be used. */
|
||||
|
@ -691,7 +692,7 @@ Manager* manager_free(Manager *m) {
|
|||
m->tuntap_fds_by_name = hashmap_free(m->tuntap_fds_by_name);
|
||||
|
||||
m->wiphy_by_name = hashmap_free(m->wiphy_by_name);
|
||||
m->wiphy_by_index = hashmap_free_with_destructor(m->wiphy_by_index, wiphy_free);
|
||||
m->wiphy_by_index = hashmap_free(m->wiphy_by_index);
|
||||
|
||||
ordered_set_free(m->address_pools);
|
||||
|
||||
|
|
|
@ -89,11 +89,11 @@ void network_adjust_ndisc(Network *network) {
|
|||
/* When RouterAllowList=, PrefixAllowList= or RouteAllowList= are specified, then
|
||||
* RouterDenyList=, PrefixDenyList= or RouteDenyList= are ignored, respectively. */
|
||||
if (!set_isempty(network->ndisc_allow_listed_router))
|
||||
network->ndisc_deny_listed_router = set_free_free(network->ndisc_deny_listed_router);
|
||||
network->ndisc_deny_listed_router = set_free(network->ndisc_deny_listed_router);
|
||||
if (!set_isempty(network->ndisc_allow_listed_prefix))
|
||||
network->ndisc_deny_listed_prefix = set_free_free(network->ndisc_deny_listed_prefix);
|
||||
network->ndisc_deny_listed_prefix = set_free(network->ndisc_deny_listed_prefix);
|
||||
if (!set_isempty(network->ndisc_allow_listed_route_prefix))
|
||||
network->ndisc_deny_listed_route_prefix = set_free_free(network->ndisc_deny_listed_route_prefix);
|
||||
network->ndisc_deny_listed_route_prefix = set_free(network->ndisc_deny_listed_route_prefix);
|
||||
}
|
||||
|
||||
static int ndisc_check_ready(Link *link);
|
||||
|
|
|
@ -44,6 +44,16 @@
|
|||
#include "strv.h"
|
||||
#include "tclass.h"
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
network_hash_ops,
|
||||
char, string_hash_func, string_compare_func,
|
||||
Network, network_unref);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
stacked_netdevs_hash_ops,
|
||||
char, string_hash_func, string_compare_func,
|
||||
NetDev, netdev_unref);
|
||||
|
||||
static int network_resolve_netdev_one(Network *network, const char *name, NetDevKind kind, NetDev **ret) {
|
||||
const char *kind_string;
|
||||
NetDev *netdev;
|
||||
|
@ -105,14 +115,14 @@ static int network_resolve_stacked_netdevs(Network *network) {
|
|||
if (network_resolve_netdev_one(network, name, PTR_TO_INT(kind), &netdev) <= 0)
|
||||
continue;
|
||||
|
||||
r = hashmap_ensure_put(&network->stacked_netdevs, &string_hash_ops, netdev->ifname, netdev);
|
||||
r = hashmap_ensure_put(&network->stacked_netdevs, &stacked_netdevs_hash_ops, netdev->ifname, netdev);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "%s: Failed to add NetDev '%s' to network, ignoring: %m",
|
||||
network->filename, (const char *) name);
|
||||
|
||||
netdev = NULL;
|
||||
TAKE_PTR(netdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -291,11 +301,6 @@ int network_verify(Network *network) {
|
|||
if (network->keep_configuration < 0)
|
||||
network->keep_configuration = KEEP_CONFIGURATION_NO;
|
||||
|
||||
if (network->ipv6_proxy_ndp == 0 && !set_isempty(network->ipv6_proxy_ndp_addresses)) {
|
||||
log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network->filename);
|
||||
network->ipv6_proxy_ndp_addresses = set_free_free(network->ipv6_proxy_ndp_addresses);
|
||||
}
|
||||
|
||||
r = network_drop_invalid_addresses(network);
|
||||
if (r < 0)
|
||||
return r; /* network_drop_invalid_addresses() logs internally. */
|
||||
|
@ -594,7 +599,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
|||
if (r < 0)
|
||||
return r; /* network_verify() logs internally. */
|
||||
|
||||
r = ordered_hashmap_ensure_put(networks, &string_hash_ops, network->name, network);
|
||||
r = ordered_hashmap_ensure_put(networks, &network_hash_ops, network->name, network);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "%s: Failed to store configuration into hashmap: %m", filename);
|
||||
|
||||
|
@ -645,7 +650,7 @@ static bool network_netdev_equal(Network *a, Network *b) {
|
|||
}
|
||||
|
||||
int network_reload(Manager *manager) {
|
||||
OrderedHashmap *new_networks = NULL;
|
||||
_cleanup_ordered_hashmap_free_ OrderedHashmap *new_networks = NULL;
|
||||
Network *n, *old;
|
||||
int r;
|
||||
|
||||
|
@ -653,7 +658,7 @@ int network_reload(Manager *manager) {
|
|||
|
||||
r = network_load(manager, &new_networks);
|
||||
if (r < 0)
|
||||
goto failure;
|
||||
return r;
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(n, new_networks) {
|
||||
r = network_get_by_name(manager, n->name, &old);
|
||||
|
@ -675,14 +680,13 @@ int network_reload(Manager *manager) {
|
|||
/* Nothing updated, use the existing Network object, and drop the new one. */
|
||||
r = ordered_hashmap_replace(new_networks, old->name, old);
|
||||
if (r < 0)
|
||||
goto failure;
|
||||
return r;
|
||||
|
||||
network_ref(old);
|
||||
network_unref(n);
|
||||
}
|
||||
|
||||
ordered_hashmap_free_with_destructor(manager->networks, network_unref);
|
||||
manager->networks = new_networks;
|
||||
ordered_hashmap_free_and_replace(manager->networks, new_networks);
|
||||
|
||||
r = manager_build_dhcp_pd_subnet_ids(manager);
|
||||
if (r < 0)
|
||||
|
@ -693,11 +697,6 @@ int network_reload(Manager *manager) {
|
|||
return r;
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
ordered_hashmap_free_with_destructor(new_networks, network_unref);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int manager_build_dhcp_pd_subnet_ids(Manager *manager) {
|
||||
|
@ -752,7 +751,7 @@ static Network *network_free(Network *network) {
|
|||
free(network->dns);
|
||||
ordered_set_free(network->search_domains);
|
||||
ordered_set_free(network->route_domains);
|
||||
set_free_free(network->dnssec_negative_trust_anchors);
|
||||
set_free(network->dnssec_negative_trust_anchors);
|
||||
|
||||
/* DHCP server */
|
||||
free(network->dhcp_server_relay_agent_circuit_id);
|
||||
|
@ -825,23 +824,23 @@ static Network *network_free(Network *network) {
|
|||
netdev_unref(network->bridge);
|
||||
netdev_unref(network->bond);
|
||||
netdev_unref(network->vrf);
|
||||
hashmap_free_with_destructor(network->stacked_netdevs, netdev_unref);
|
||||
hashmap_free(network->stacked_netdevs);
|
||||
|
||||
/* static configs */
|
||||
set_free_free(network->ipv6_proxy_ndp_addresses);
|
||||
set_free(network->ipv6_proxy_ndp_addresses);
|
||||
ordered_hashmap_free(network->addresses_by_section);
|
||||
hashmap_free(network->routes_by_section);
|
||||
ordered_hashmap_free(network->nexthops_by_section);
|
||||
hashmap_free_with_destructor(network->bridge_fdb_entries_by_section, bridge_fdb_free);
|
||||
hashmap_free_with_destructor(network->bridge_mdb_entries_by_section, bridge_mdb_free);
|
||||
hashmap_free(network->bridge_fdb_entries_by_section);
|
||||
hashmap_free(network->bridge_mdb_entries_by_section);
|
||||
ordered_hashmap_free(network->neighbors_by_section);
|
||||
hashmap_free(network->address_labels_by_section);
|
||||
hashmap_free_with_destructor(network->prefixes_by_section, prefix_free);
|
||||
hashmap_free_with_destructor(network->route_prefixes_by_section, route_prefix_free);
|
||||
hashmap_free_with_destructor(network->pref64_prefixes_by_section, prefix64_free);
|
||||
hashmap_free(network->prefixes_by_section);
|
||||
hashmap_free(network->route_prefixes_by_section);
|
||||
hashmap_free(network->pref64_prefixes_by_section);
|
||||
hashmap_free(network->rules_by_section);
|
||||
hashmap_free_with_destructor(network->dhcp_static_leases_by_section, dhcp_static_lease_free);
|
||||
ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free);
|
||||
hashmap_free(network->dhcp_static_leases_by_section);
|
||||
ordered_hashmap_free(network->sr_iov_by_section);
|
||||
hashmap_free(network->qdiscs_by_section);
|
||||
hashmap_free(network->tclasses_by_section);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ bool link_radv_enabled(Link *link) {
|
|||
return link->network->router_prefix_delegation;
|
||||
}
|
||||
|
||||
Prefix* prefix_free(Prefix *prefix) {
|
||||
static Prefix* prefix_free(Prefix *prefix) {
|
||||
if (!prefix)
|
||||
return NULL;
|
||||
|
||||
|
@ -52,6 +52,11 @@ Prefix* prefix_free(Prefix *prefix) {
|
|||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(Prefix, prefix_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
prefix_hash_ops_by_section,
|
||||
ConfigSection, config_section_hash_func, config_section_compare_func,
|
||||
Prefix, prefix_free);
|
||||
|
||||
static int prefix_new_static(Network *network, const char *filename, unsigned section_line, Prefix **ret) {
|
||||
_cleanup_(config_section_freep) ConfigSection *n = NULL;
|
||||
_cleanup_(prefix_freep) Prefix *prefix = NULL;
|
||||
|
@ -87,7 +92,7 @@ static int prefix_new_static(Network *network, const char *filename, unsigned se
|
|||
.prefix.preferred_until = USEC_INFINITY,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_put(&network->prefixes_by_section, &config_section_hash_ops, prefix->section, prefix);
|
||||
r = hashmap_ensure_put(&network->prefixes_by_section, &prefix_hash_ops_by_section, prefix->section, prefix);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -95,7 +100,7 @@ static int prefix_new_static(Network *network, const char *filename, unsigned se
|
|||
return 0;
|
||||
}
|
||||
|
||||
RoutePrefix* route_prefix_free(RoutePrefix *prefix) {
|
||||
static RoutePrefix* route_prefix_free(RoutePrefix *prefix) {
|
||||
if (!prefix)
|
||||
return NULL;
|
||||
|
||||
|
@ -111,6 +116,11 @@ RoutePrefix* route_prefix_free(RoutePrefix *prefix) {
|
|||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(RoutePrefix, route_prefix_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
route_prefix_hash_ops_by_section,
|
||||
ConfigSection, config_section_hash_func, config_section_compare_func,
|
||||
RoutePrefix, route_prefix_free);
|
||||
|
||||
static int route_prefix_new_static(Network *network, const char *filename, unsigned section_line, RoutePrefix **ret) {
|
||||
_cleanup_(config_section_freep) ConfigSection *n = NULL;
|
||||
_cleanup_(route_prefix_freep) RoutePrefix *prefix = NULL;
|
||||
|
@ -143,7 +153,7 @@ static int route_prefix_new_static(Network *network, const char *filename, unsig
|
|||
.route.valid_until = USEC_INFINITY,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_put(&network->route_prefixes_by_section, &config_section_hash_ops, prefix->section, prefix);
|
||||
r = hashmap_ensure_put(&network->route_prefixes_by_section, &route_prefix_hash_ops_by_section, prefix->section, prefix);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -151,7 +161,7 @@ static int route_prefix_new_static(Network *network, const char *filename, unsig
|
|||
return 0;
|
||||
}
|
||||
|
||||
Prefix64* prefix64_free(Prefix64 *prefix) {
|
||||
static Prefix64* prefix64_free(Prefix64 *prefix) {
|
||||
if (!prefix)
|
||||
return NULL;
|
||||
|
||||
|
@ -167,6 +177,11 @@ Prefix64* prefix64_free(Prefix64 *prefix) {
|
|||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(Prefix64, prefix64_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
prefix64_hash_ops_by_section,
|
||||
ConfigSection, config_section_hash_func, config_section_compare_func,
|
||||
Prefix64, prefix64_free);
|
||||
|
||||
static int prefix64_new_static(Network *network, const char *filename, unsigned section_line, Prefix64 **ret) {
|
||||
_cleanup_(config_section_freep) ConfigSection *n = NULL;
|
||||
_cleanup_(prefix64_freep) Prefix64 *prefix = NULL;
|
||||
|
@ -199,7 +214,7 @@ static int prefix64_new_static(Network *network, const char *filename, unsigned
|
|||
.prefix64.valid_until = USEC_INFINITY,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_put(&network->pref64_prefixes_by_section, &config_section_hash_ops, prefix->section, prefix);
|
||||
r = hashmap_ensure_put(&network->pref64_prefixes_by_section, &prefix64_hash_ops_by_section, prefix->section, prefix);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -809,9 +824,9 @@ void network_adjust_radv(Network *network) {
|
|||
}
|
||||
|
||||
if (!FLAGS_SET(network->router_prefix_delegation, RADV_PREFIX_DELEGATION_STATIC)) {
|
||||
network->prefixes_by_section = hashmap_free_with_destructor(network->prefixes_by_section, prefix_free);
|
||||
network->route_prefixes_by_section = hashmap_free_with_destructor(network->route_prefixes_by_section, route_prefix_free);
|
||||
network->pref64_prefixes_by_section = hashmap_free_with_destructor(network->pref64_prefixes_by_section, prefix64_free);
|
||||
network->prefixes_by_section = hashmap_free(network->prefixes_by_section);
|
||||
network->route_prefixes_by_section = hashmap_free(network->route_prefixes_by_section);
|
||||
network->pref64_prefixes_by_section = hashmap_free(network->pref64_prefixes_by_section);
|
||||
}
|
||||
|
||||
if (!network->router_prefix_delegation)
|
||||
|
|
|
@ -52,10 +52,6 @@ typedef struct Prefix64 {
|
|||
sd_ndisc_prefix64 prefix64;
|
||||
} Prefix64;
|
||||
|
||||
Prefix* prefix_free(Prefix *prefix);
|
||||
RoutePrefix* route_prefix_free(RoutePrefix *prefix);
|
||||
Prefix64* prefix64_free(Prefix64 *prefix);
|
||||
|
||||
void network_adjust_radv(Network *network);
|
||||
|
||||
int link_request_radv_addresses(Link *link);
|
||||
|
|
|
@ -947,8 +947,6 @@ static int link_save(Link *link) {
|
|||
}
|
||||
|
||||
void link_dirty(Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
|
@ -962,10 +960,9 @@ void link_dirty(Link *link) {
|
|||
/* Also mark manager dirty as link is dirty */
|
||||
link->manager->dirty = true;
|
||||
|
||||
r = set_ensure_put(&link->manager->dirty_links, NULL, link);
|
||||
if (r <= 0)
|
||||
/* Ignore allocation errors and don't take another ref if the link was already dirty */
|
||||
return;
|
||||
if (set_ensure_put(&link->manager->dirty_links, &link_hash_ops, link) <= 0)
|
||||
return; /* Ignore allocation errors and don't take another ref if the link was already dirty */
|
||||
|
||||
link_ref(link);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "udev-util.h"
|
||||
#include "wifi-util.h"
|
||||
|
||||
Wiphy *wiphy_free(Wiphy *w) {
|
||||
static Wiphy* wiphy_free(Wiphy *w) {
|
||||
if (!w)
|
||||
return NULL;
|
||||
|
||||
|
@ -29,6 +29,13 @@ Wiphy *wiphy_free(Wiphy *w) {
|
|||
return mfree(w);
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Wiphy*, wiphy_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
wiphy_hash_ops,
|
||||
void, trivial_hash_func, trivial_compare_func,
|
||||
Wiphy, wiphy_free);
|
||||
|
||||
static int wiphy_new(Manager *manager, sd_netlink_message *message, Wiphy **ret) {
|
||||
_cleanup_(wiphy_freep) Wiphy *w = NULL;
|
||||
_cleanup_free_ char *name = NULL;
|
||||
|
@ -56,7 +63,7 @@ static int wiphy_new(Manager *manager, sd_netlink_message *message, Wiphy **ret)
|
|||
.name = TAKE_PTR(name),
|
||||
};
|
||||
|
||||
r = hashmap_ensure_put(&manager->wiphy_by_index, NULL, UINT32_TO_PTR(w->index), w);
|
||||
r = hashmap_ensure_put(&manager->wiphy_by_index, &wiphy_hash_ops, UINT32_TO_PTR(w->index), w);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -31,9 +31,6 @@ typedef struct Wiphy {
|
|||
RFKillState rfkill_state;
|
||||
} Wiphy;
|
||||
|
||||
Wiphy *wiphy_free(Wiphy *w);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Wiphy*, wiphy_free);
|
||||
|
||||
int wiphy_get_by_index(Manager *manager, uint32_t index, Wiphy **ret);
|
||||
int wiphy_get_by_name(Manager *manager, const char *name, Wiphy **ret);
|
||||
|
||||
|
|
|
@ -146,13 +146,13 @@ int memfd_clone_fd(int fd, const char *name, int mode) {
|
|||
|
||||
assert(fd >= 0);
|
||||
assert(name);
|
||||
assert(IN_SET(mode & O_ACCMODE, O_RDONLY, O_RDWR));
|
||||
assert(IN_SET(mode & O_ACCMODE_STRICT, O_RDONLY, O_RDWR));
|
||||
assert((mode & ~(O_RDONLY|O_RDWR|O_CLOEXEC)) == 0);
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
ro = (mode & O_ACCMODE) == O_RDONLY;
|
||||
ro = (mode & O_ACCMODE_STRICT) == O_RDONLY;
|
||||
exec = st.st_mode & 0111;
|
||||
|
||||
mfd = memfd_create_wrapper(name,
|
||||
|
|
|
@ -504,7 +504,7 @@ int journal_file_open_reliably(
|
|||
-EIDRM)) /* File has been deleted */
|
||||
return r;
|
||||
|
||||
if ((open_flags & O_ACCMODE) == O_RDONLY)
|
||||
if ((open_flags & O_ACCMODE_STRICT) == O_RDONLY)
|
||||
return r;
|
||||
|
||||
if (!(open_flags & O_CREAT))
|
||||
|
@ -519,7 +519,7 @@ int journal_file_open_reliably(
|
|||
/* The file is corrupted. Try opening it read-only as the template before rotating to inherit its
|
||||
* sequence number and ID. */
|
||||
r = journal_file_open(-EBADF, fname,
|
||||
(open_flags & ~(O_ACCMODE|O_CREAT|O_EXCL)) | O_RDONLY,
|
||||
(open_flags & ~(O_ACCMODE_STRICT|O_CREAT|O_EXCL)) | O_RDONLY,
|
||||
file_flags, 0, compress_threshold_bytes, NULL,
|
||||
mmap_cache, /* template = */ NULL, &old_file);
|
||||
if (r < 0)
|
||||
|
|
|
@ -500,7 +500,7 @@ static int loop_device_make_internal(
|
|||
.block_size = sector_size,
|
||||
.info = {
|
||||
/* Use the specified flags, but configure the read-only flag from the open flags, and force autoclear */
|
||||
.lo_flags = (loop_flags & ~LO_FLAGS_READ_ONLY) | ((open_flags & O_ACCMODE) == O_RDONLY ? LO_FLAGS_READ_ONLY : 0) | LO_FLAGS_AUTOCLEAR,
|
||||
.lo_flags = (loop_flags & ~LO_FLAGS_READ_ONLY) | ((open_flags & O_ACCMODE_STRICT) == O_RDONLY ? LO_FLAGS_READ_ONLY : 0) | LO_FLAGS_AUTOCLEAR,
|
||||
.lo_offset = offset,
|
||||
.lo_sizelimit = size == UINT64_MAX ? 0 : size,
|
||||
},
|
||||
|
|
|
@ -9,6 +9,25 @@
|
|||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
static SRIOV* sr_iov_free(SRIOV *sr_iov) {
|
||||
if (!sr_iov)
|
||||
return NULL;
|
||||
|
||||
if (sr_iov->sr_iov_by_section && sr_iov->section)
|
||||
ordered_hashmap_remove(sr_iov->sr_iov_by_section, sr_iov->section);
|
||||
|
||||
config_section_free(sr_iov->section);
|
||||
|
||||
return mfree(sr_iov);
|
||||
}
|
||||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(SRIOV, sr_iov_free);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
sr_iov_hash_ops_by_section,
|
||||
ConfigSection, config_section_hash_func, config_section_compare_func,
|
||||
SRIOV, sr_iov_free);
|
||||
|
||||
static int sr_iov_new(SRIOV **ret) {
|
||||
SRIOV *sr_iov;
|
||||
|
||||
|
@ -57,7 +76,7 @@ static int sr_iov_new_static(OrderedHashmap **sr_iov_by_section, const char *fil
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_hashmap_ensure_put(sr_iov_by_section, &config_section_hash_ops, n, sr_iov);
|
||||
r = ordered_hashmap_ensure_put(sr_iov_by_section, &sr_iov_hash_ops_by_section, n, sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -68,18 +87,6 @@ static int sr_iov_new_static(OrderedHashmap **sr_iov_by_section, const char *fil
|
|||
return 0;
|
||||
}
|
||||
|
||||
SRIOV *sr_iov_free(SRIOV *sr_iov) {
|
||||
if (!sr_iov)
|
||||
return NULL;
|
||||
|
||||
if (sr_iov->sr_iov_by_section && sr_iov->section)
|
||||
ordered_hashmap_remove(sr_iov->sr_iov_by_section, sr_iov->section);
|
||||
|
||||
config_section_free(sr_iov->section);
|
||||
|
||||
return mfree(sr_iov);
|
||||
}
|
||||
|
||||
void sr_iov_hash_func(const SRIOV *sr_iov, struct siphash *state) {
|
||||
assert(sr_iov);
|
||||
assert(state);
|
||||
|
|
|
@ -32,7 +32,6 @@ typedef struct SRIOV {
|
|||
struct ether_addr mac;
|
||||
} SRIOV;
|
||||
|
||||
SRIOV *sr_iov_free(SRIOV *sr_iov);
|
||||
void sr_iov_hash_func(const SRIOV *sr_iov, struct siphash *state);
|
||||
int sr_iov_compare_func(const SRIOV *s1, const SRIOV *s2);
|
||||
int sr_iov_set_netlink_message(SRIOV *sr_iov, sd_netlink_message *req);
|
||||
|
@ -40,8 +39,6 @@ int sr_iov_get_num_vfs(sd_device *device, uint32_t *ret);
|
|||
int sr_iov_set_num_vfs(sd_device *device, uint32_t num_vfs, OrderedHashmap *sr_iov_by_section);
|
||||
int sr_iov_drop_invalid_sections(uint32_t num_vfs, OrderedHashmap *sr_iov_by_section);
|
||||
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(SRIOV, sr_iov_free);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_uint32);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_boolean);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_link_state);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "blockdev-util.h"
|
||||
#include "detach-loopback.h"
|
||||
#include "device-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "shutdown.h"
|
||||
|
||||
|
@ -106,8 +107,12 @@ static int delete_loopback(const char *device) {
|
|||
|
||||
fd = open(device, O_RDONLY|O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
log_debug_errno(errno, "Failed to open loopback device %s: %m", device);
|
||||
return errno == ENOENT ? 0 : -errno;
|
||||
if (ERRNO_IS_DEVICE_ABSENT(errno)) {
|
||||
log_debug_errno(errno, "Tried to open loopback device '%s', but device disappeared by now, ignoring: %m", device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return log_debug_errno(errno, "Failed to open loopback device '%s': %m", device);
|
||||
}
|
||||
|
||||
/* Loopback block devices don't sync in-flight blocks when we clear the fd, hence sync explicitly
|
||||
|
|
|
@ -131,12 +131,21 @@ static int delete_md(RaidDevice *m) {
|
|||
assert(m->path);
|
||||
|
||||
fd = open(m->path, O_RDONLY|O_CLOEXEC|O_EXCL);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
if (fd < 0) {
|
||||
if (ERRNO_IS_DEVICE_ABSENT(errno)) {
|
||||
log_debug_errno(errno, "Tried to open MD device '%s', but device disappeared by now, ignoring: %m", m->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return log_debug_errno(errno, "Failed to open MD device '%s': %m", m->path);
|
||||
}
|
||||
|
||||
(void) sync_with_progress(fd);
|
||||
|
||||
return RET_NERRNO(ioctl(fd, STOP_ARRAY, NULL));
|
||||
if (ioctl(fd, STOP_ARRAY, NULL) < 0)
|
||||
return log_debug_errno(errno, "Failed to issue STOP_ARRAY on MD device '%s': %m", m->path);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int md_points_list_detach(RaidDevice **head, bool *changed, bool last_try) {
|
||||
|
@ -164,8 +173,9 @@ static int md_points_list_detach(RaidDevice **head, bool *changed, bool last_try
|
|||
n_failed++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (r > 0)
|
||||
*changed = true;
|
||||
|
||||
raid_device_free(head, m);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "alloc-util.h"
|
||||
#include "detach-swap.h"
|
||||
#include "errno-util.h"
|
||||
#include "libmount-util.h"
|
||||
|
||||
static void swap_device_free(SwapDevice **head, SwapDevice *m) {
|
||||
|
@ -74,20 +75,23 @@ int swap_list_get(const char *swaps, SwapDevice **head) {
|
|||
}
|
||||
|
||||
static int swap_points_list_off(SwapDevice **head, bool *changed) {
|
||||
int n_failed = 0;
|
||||
int n_failed = 0, r;
|
||||
|
||||
assert(head);
|
||||
assert(changed);
|
||||
|
||||
LIST_FOREACH(swap_device, m, *head) {
|
||||
log_info("Deactivating swap %s.", m->path);
|
||||
if (swapoff(m->path) < 0) {
|
||||
log_warning_errno(errno, "Could not deactivate swap %s: %m", m->path);
|
||||
r = RET_NERRNO(swapoff(m->path));
|
||||
if (ERRNO_IS_NEG_DEVICE_ABSENT(r))
|
||||
log_debug_errno(r, "Tried to deactivate swap '%s', but swap disappeared by now, ignoring: %m", m->path);
|
||||
else if (r < 0) {
|
||||
log_warning_errno(r, "Could not deactivate swap %s: %m", m->path);
|
||||
n_failed++;
|
||||
continue;
|
||||
}
|
||||
|
||||
} else
|
||||
*changed = true;
|
||||
|
||||
swap_device_free(head, m);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ Host .host machine/.host
|
|||
# Make sure unix/* and vsock/* can be used to connect to AF_UNIX and AF_VSOCK paths.
|
||||
# Make sure machine/* can be used to connect to local machines registered in machined.
|
||||
#
|
||||
Host unix/* vsock/* vsock-mux/* machine/*
|
||||
Host unix/* unix,* vsock/* vsock,* vsock-mux/* vsock-mux,* machine/* machine,*
|
||||
ProxyCommand {{LIBEXECDIR}}/systemd-ssh-proxy %h %p
|
||||
ProxyUseFdpass yes
|
||||
CheckHostIP no
|
||||
|
|
|
@ -175,6 +175,15 @@ static int process_machine(const char *machine, const char *port) {
|
|||
return process_vsock_cid(cid, port);
|
||||
}
|
||||
|
||||
static char *startswith_sep(const char *s, const char *prefix) {
|
||||
const char *p = startswith(s, prefix);
|
||||
|
||||
if (p && IN_SET(*p, '/', ','))
|
||||
return (char*) p + 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int run(int argc, char* argv[]) {
|
||||
|
||||
log_setup();
|
||||
|
@ -184,19 +193,19 @@ static int run(int argc, char* argv[]) {
|
|||
|
||||
const char *host = argv[1], *port = argv[2];
|
||||
|
||||
const char *p = startswith(host, "vsock/");
|
||||
const char *p = startswith_sep(host, "vsock");
|
||||
if (p)
|
||||
return process_vsock_string(p, port);
|
||||
|
||||
p = startswith(host, "unix/");
|
||||
p = startswith_sep(host, "unix");
|
||||
if (p)
|
||||
return process_unix(p);
|
||||
|
||||
p = startswith(host, "vsock-mux/");
|
||||
p = startswith_sep(host, "vsock-mux");
|
||||
if (p)
|
||||
return process_vsock_mux(p, port);
|
||||
|
||||
p = startswith(host, "machine/");
|
||||
p = startswith_sep(host, "machine");
|
||||
if (p)
|
||||
return process_machine(p, port);
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ static void context_done(Context *c) {
|
|||
hashmap_free(c->database_by_gid);
|
||||
hashmap_free(c->database_by_groupname);
|
||||
|
||||
set_free_free(c->names);
|
||||
set_free(c->names);
|
||||
uid_range_free(c->uid_range);
|
||||
}
|
||||
|
||||
|
@ -231,9 +231,8 @@ static int load_user_database(Context *c) {
|
|||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Note that we use NULL hash_ops (i.e. trivial_hash_ops) here, so identical strings can
|
||||
* exist in the set. */
|
||||
r = set_ensure_consume(&c->names, /* hash_ops= */ NULL, n);
|
||||
/* Note that we use trivial_hash_ops_free here, so identical strings can exist in the set. */
|
||||
r = set_ensure_consume(&c->names, &trivial_hash_ops_free, n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(r > 0); /* The set uses pointer comparisons, so n must not be in the set. */
|
||||
|
@ -274,9 +273,8 @@ static int load_group_database(Context *c) {
|
|||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Note that we use NULL hash_ops (i.e. trivial_hash_ops) here, so identical strings can
|
||||
* exist in the set. */
|
||||
r = set_ensure_consume(&c->names, /* hash_ops= */ NULL, n);
|
||||
/* Note that we use trivial_hash_ops_free here, so identical strings can exist in the set. */
|
||||
r = set_ensure_consume(&c->names, &trivial_hash_ops_free, n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(r > 0); /* The set uses pointer comparisons, so n must not be in the set. */
|
||||
|
|
|
@ -64,7 +64,7 @@ typedef struct SysvStub {
|
|||
bool loaded;
|
||||
} SysvStub;
|
||||
|
||||
static SysvStub* free_sysvstub(SysvStub *s) {
|
||||
static SysvStub* sysvstub_free(SysvStub *s) {
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
|
@ -78,11 +78,12 @@ static SysvStub* free_sysvstub(SysvStub *s) {
|
|||
strv_free(s->wanted_by);
|
||||
return mfree(s);
|
||||
}
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(SysvStub*, free_sysvstub);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(SysvStub*, sysvstub_free);
|
||||
|
||||
static void free_sysvstub_hashmapp(Hashmap **h) {
|
||||
hashmap_free_with_destructor(*h, free_sysvstub);
|
||||
}
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
sysvstub_hash_ops,
|
||||
char, string_hash_func, string_compare_func,
|
||||
SysvStub, sysvstub_free);
|
||||
|
||||
static int add_alias(const char *service, const char *alias) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
|
@ -728,7 +729,7 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
|
|||
|
||||
FOREACH_DIRENT(de, d, log_error_errno(errno, "Failed to enumerate directory %s, ignoring: %m", *path)) {
|
||||
_cleanup_free_ char *fpath = NULL, *name = NULL;
|
||||
_cleanup_(free_sysvstubp) SysvStub *service = NULL;
|
||||
_cleanup_(sysvstub_freep) SysvStub *service = NULL;
|
||||
struct stat st;
|
||||
|
||||
if (fstatat(dirfd(d), de->d_name, &st, 0) < 0) {
|
||||
|
@ -894,7 +895,7 @@ finish:
|
|||
}
|
||||
|
||||
static int run(const char *dest, const char *dest_early, const char *dest_late) {
|
||||
_cleanup_(free_sysvstub_hashmapp) Hashmap *all_services = NULL;
|
||||
_cleanup_hashmap_free_ Hashmap *all_services = NULL;
|
||||
_cleanup_(lookup_paths_done) LookupPaths lp = {};
|
||||
SysvStub *service;
|
||||
int r;
|
||||
|
@ -910,7 +911,7 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
all_services = hashmap_new(&string_hash_ops);
|
||||
all_services = hashmap_new(&sysvstub_hash_ops);
|
||||
if (!all_services)
|
||||
return log_oom();
|
||||
|
||||
|
|
|
@ -1104,7 +1104,7 @@ TEST(fdopen_independent) {
|
|||
zero(buf);
|
||||
assert_se(fread(buf, 1, sizeof(buf), f) == strlen(TEST_TEXT));
|
||||
ASSERT_STREQ(buf, TEST_TEXT);
|
||||
assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE) == O_RDONLY);
|
||||
assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE_STRICT) == O_RDONLY);
|
||||
assert_se(FLAGS_SET(fcntl(fileno(f), F_GETFD), FD_CLOEXEC));
|
||||
f = safe_fclose(f);
|
||||
|
||||
|
@ -1112,7 +1112,7 @@ TEST(fdopen_independent) {
|
|||
zero(buf);
|
||||
assert_se(fread(buf, 1, sizeof(buf), f) == strlen(TEST_TEXT));
|
||||
ASSERT_STREQ(buf, TEST_TEXT);
|
||||
assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE) == O_RDONLY);
|
||||
assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE_STRICT) == O_RDONLY);
|
||||
assert_se(!FLAGS_SET(fcntl(fileno(f), F_GETFD), FD_CLOEXEC));
|
||||
f = safe_fclose(f);
|
||||
|
||||
|
@ -1120,7 +1120,7 @@ TEST(fdopen_independent) {
|
|||
zero(buf);
|
||||
assert_se(fread(buf, 1, sizeof(buf), f) == strlen(TEST_TEXT));
|
||||
ASSERT_STREQ(buf, TEST_TEXT);
|
||||
assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE) == O_RDWR);
|
||||
assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE_STRICT) == O_RDWR);
|
||||
assert_se(FLAGS_SET(fcntl(fileno(f), F_GETFD), FD_CLOEXEC));
|
||||
f = safe_fclose(f);
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ static LinkConfig* link_config_free(LinkConfig *config) {
|
|||
erase_and_free(config->wol_password);
|
||||
cpu_set_free(config->rps_cpu_mask);
|
||||
|
||||
ordered_hashmap_free_with_destructor(config->sr_iov_by_section, sr_iov_free);
|
||||
ordered_hashmap_free(config->sr_iov_by_section);
|
||||
|
||||
return mfree(config);
|
||||
}
|
||||
|
|
|
@ -38,14 +38,14 @@ directory (`OutputDirectory=`) to point to the other directory using `mkosi/mkos
|
|||
After the image has been built, the integration tests can be run with:
|
||||
|
||||
```shell
|
||||
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build --suite integration-tests --num-processes "$(($(nproc) / 4))"
|
||||
$ mkosi -f sandbox -- meson test -C build --setup=integration --suite integration-tests --num-processes "$(($(nproc) / 4))"
|
||||
```
|
||||
|
||||
As usual, specific tests can be run in meson by appending the name of the test
|
||||
which is usually the name of the directory e.g.
|
||||
|
||||
```shell
|
||||
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -v TEST-01-BASIC
|
||||
$ mkosi -f sandbox -- meson test -C build --setup=integration -v TEST-01-BASIC
|
||||
```
|
||||
|
||||
See `mkosi -f sandbox -- meson introspect build --tests` for a list of tests.
|
||||
|
@ -55,7 +55,7 @@ To interactively debug a failing integration test, the `--interactive` option
|
|||
newer:
|
||||
|
||||
```shell
|
||||
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -i TEST-01-BASIC
|
||||
$ mkosi -f sandbox -- meson test -C build --setup=integration -i TEST-01-BASIC
|
||||
```
|
||||
|
||||
Due to limitations in meson, the integration tests do not yet depend on the
|
||||
|
@ -64,7 +64,7 @@ running the integration tests. To rebuild the image and rerun a test, the
|
|||
following command can be used:
|
||||
|
||||
```shell
|
||||
$ mkosi -f sandbox -- meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -v TEST-01-BASIC
|
||||
$ mkosi -f sandbox -- meson compile -C build mkosi && mkosi -f sandbox -- meson test -C build --setup=integration -v TEST-01-BASIC
|
||||
```
|
||||
|
||||
The integration tests use the same mkosi configuration that's used when you run
|
||||
|
@ -78,7 +78,7 @@ To iterate on an integration test, let's first get a shell in the integration te
|
|||
the following:
|
||||
|
||||
```shell
|
||||
$ mkosi -f sandbox -- meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 TEST_SHELL=1 mkosi -f sandbox -- meson test -C build -i TEST-01-BASIC
|
||||
$ mkosi -f sandbox -- meson compile -C build mkosi && mkosi -f sandbox -- meson test -C build --setup=shell -i TEST-01-BASIC
|
||||
```
|
||||
|
||||
This will get us a shell in the integration test environment after booting the machine without running the
|
||||
|
@ -107,7 +107,7 @@ re-running the test will first install the new packages we just built, make a ne
|
|||
the test again. You can keep running the loop of `mkosi -R`, `systemctl soft-reboot` and
|
||||
`systemctl start ...` until the changes to the integration test are working.
|
||||
|
||||
If you're debugging a failing integration test (running `meson test --interactive` without `TEST_SHELL`),
|
||||
If you're debugging a failing integration test (running `meson test --interactive`),
|
||||
there's no need to run `systemctl start ...`, running `systemctl soft-reboot` on its own is sufficient to
|
||||
rerun the test.
|
||||
|
||||
|
@ -120,10 +120,6 @@ rerun the test.
|
|||
`TEST_NO_KVM=1`: Disable qemu KVM auto-detection (may be necessary when you're
|
||||
trying to run the *vanilla* qemu and have both qemu and qemu-kvm installed)
|
||||
|
||||
`TEST_SHELL=1`: Configure the machine to be more *user-friendly* for
|
||||
interactive debugging (e.g. by setting a usable default terminal, suppressing
|
||||
the shutdown after the test, etc.).
|
||||
|
||||
`TEST_MATCH_SUBTEST=subtest`: If the test makes use of `run_subtests` use this
|
||||
variable to provide a POSIX extended regex to run only subtests matching the
|
||||
expression.
|
||||
|
|
|
@ -361,7 +361,7 @@ def statfs(path: Path) -> str:
|
|||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--mkosi', required=True)
|
||||
parser.add_argument('--mkosi', default=None)
|
||||
parser.add_argument('--meson-source-dir', required=True, type=Path)
|
||||
parser.add_argument('--meson-build-dir', required=True, type=Path)
|
||||
parser.add_argument('--name', required=True)
|
||||
|
@ -379,6 +379,12 @@ def main() -> None:
|
|||
parser.add_argument('mkosi_args', nargs='*')
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.mkosi:
|
||||
args.mkosi = shutil.which('mkosi')
|
||||
if not args.mkosi:
|
||||
print('Could not find mkosi which is required to run the integration tests', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# The meson source directory can either be the top-level repository directory or the
|
||||
# test/integration-tests/standalone subdirectory in the repository directory. The mkosi configuration
|
||||
# will always be a parent directory of one of these directories and at most 4 levels upwards, so don't
|
||||
|
@ -395,13 +401,6 @@ def main() -> None:
|
|||
)
|
||||
exit(1)
|
||||
|
||||
if not bool(int(os.getenv('SYSTEMD_INTEGRATION_TESTS', '0'))):
|
||||
print(
|
||||
f'SYSTEMD_INTEGRATION_TESTS=1 not found in environment, skipping {args.name}',
|
||||
file=sys.stderr,
|
||||
)
|
||||
exit(77)
|
||||
|
||||
if args.slow and not bool(int(os.getenv('SYSTEMD_SLOW_TESTS', '0'))):
|
||||
print(
|
||||
f'SYSTEMD_SLOW_TESTS=1 not found in environment, skipping {args.name}',
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# We'd give these more descriptive names but only alphanumeric characters are allowed.
|
||||
add_test_setup('integration')
|
||||
add_test_setup('shell', env : {'TEST_SHELL' : '1'})
|
||||
|
||||
integration_test_wrapper = find_program('integration-test-wrapper.py')
|
||||
integration_tests = []
|
||||
integration_test_template = {
|
||||
|
@ -129,11 +133,11 @@ foreach integration_test : integration_tests
|
|||
integration_test_args += ['--skip']
|
||||
endif
|
||||
|
||||
if not mkosi.found()
|
||||
continue
|
||||
if mkosi.found()
|
||||
integration_test_args += ['--mkosi', mkosi.full_path()]
|
||||
endif
|
||||
|
||||
integration_test_args += ['--mkosi', mkosi.full_path(), '--']
|
||||
integration_test_args += ['--']
|
||||
|
||||
if integration_test['cmdline'].length() > 0
|
||||
integration_test_args += [
|
||||
|
@ -151,19 +155,12 @@ foreach integration_test : integration_tests
|
|||
|
||||
integration_test_args += integration_test['mkosi-args']
|
||||
|
||||
integration_test_env = {}
|
||||
|
||||
if want_integration_tests
|
||||
integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'}
|
||||
endif
|
||||
|
||||
# We don't explicitly depend on the "mkosi" target because that means the image is rebuilt on every
|
||||
# "ninja -C build". Instead, the mkosi target has to be rebuilt manually before running the
|
||||
# integration tests with mkosi.
|
||||
test(
|
||||
integration_test['name'],
|
||||
integration_test_wrapper,
|
||||
env : integration_test_env,
|
||||
args : integration_test_args,
|
||||
timeout : integration_test['timeout'],
|
||||
priority : integration_test['priority'],
|
||||
|
|
|
@ -16,7 +16,6 @@ project('systemd-testsuite',
|
|||
|
||||
fs = import('fs')
|
||||
mkosi = find_program('mkosi', required : true)
|
||||
want_integration_tests = true
|
||||
|
||||
# meson refuses .. in subdir() so we use a symlink to trick it into accepting it anyway.
|
||||
subdir('integration-tests')
|
||||
|
|
|
@ -61,4 +61,13 @@ ssh -o StrictHostKeyChecking=no -v -i "$ROOTID" machine/.host cat /etc/machine-i
|
|||
modprobe vsock_loopback ||:
|
||||
if test -e /dev/vsock -a -d /sys/module/vsock_loopback ; then
|
||||
ssh -o StrictHostKeyChecking=no -v -i "$ROOTID" vsock/1 cat /etc/machine-id | cmp - /etc/machine-id
|
||||
|
||||
if ! command -v scp &> /dev/null ; then
|
||||
echo "scp not found, skipping subtest" >&2
|
||||
else
|
||||
OUT_FILE=$(mktemp -u)
|
||||
scp -o StrictHostKeyChecking=no -v -i "$ROOTID" vsock,1:/etc/machine-id "$OUT_FILE"
|
||||
cmp "$OUT_FILE" /etc/machine-id
|
||||
rm -f "$OUT_FILE"
|
||||
fi
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue