summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/chase.c12
-rw-r--r--src/basic/fs-util.c50
-rw-r--r--src/basic/fs-util.h8
-rw-r--r--src/basic/label.c30
-rw-r--r--src/basic/label.h14
-rw-r--r--src/basic/lock-util.c8
-rw-r--r--src/basic/meson.build1
-rw-r--r--src/basic/stat-util.c2
-rw-r--r--src/basic/user-util.c8
-rw-r--r--src/basic/user-util.h4
-rw-r--r--src/boot/bootctl-status.c8
-rw-r--r--src/boot/bootctl.c4
-rw-r--r--src/boot/bootctl.h4
-rw-r--r--src/boot/efi/proto/tcg.h2
-rw-r--r--src/core/automount.c2
-rw-r--r--src/core/cgroup.c4
-rw-r--r--src/core/execute.c2
-rw-r--r--src/core/kmod-setup.c42
-rw-r--r--src/core/main.c8
-rw-r--r--src/core/manager.c2
-rw-r--r--src/core/namespace.c2
-rw-r--r--src/core/scope.c5
-rw-r--r--src/core/service.c5
-rw-r--r--src/core/socket.c2
-rw-r--r--src/core/transaction.c2
-rw-r--r--src/core/unit.c5
-rw-r--r--src/dissect/dissect.c2
-rw-r--r--src/hostname/hostnamed.c2
-rw-r--r--src/hwdb/hwdb.c2
-rw-r--r--src/journal-remote/journal-remote-write.c11
-rw-r--r--src/journal/journalctl.c519
-rw-r--r--src/libsystemd-network/fuzz-dhcp-server.c30
-rw-r--r--src/libsystemd/libsystemd.sym1
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c73
-rw-r--r--src/libsystemd/sd-id128/id128-util.c4
-rw-r--r--src/libsystemd/sd-journal/sd-journal.c10
-rw-r--r--src/locale/localed.c2
-rw-r--r--src/login/logind-user.c2
-rw-r--r--src/login/logind.c2
-rw-r--r--src/login/user-runtime-dir.c4
-rw-r--r--src/machine/machinectl.c2
-rw-r--r--src/network/wait-online/manager.c22
-rw-r--r--src/nspawn/nspawn-mount.c2
-rw-r--r--src/oom/test-oomd-util.c2
-rw-r--r--src/resolve/resolved-resolv-conf.c2
-rw-r--r--src/resolve/resolved.c2
-rw-r--r--src/shared/btrfs-util.c2
-rw-r--r--src/shared/creds-util.c3
-rw-r--r--src/shared/dev-setup.c2
-rw-r--r--src/shared/find-esp.c64
-rw-r--r--src/shared/find-esp.h8
-rw-r--r--src/shared/hwdb-util.c2
-rw-r--r--src/shared/label-util.c (renamed from src/shared/label.c)13
-rw-r--r--src/shared/label-util.h (renamed from src/shared/label.h)2
-rw-r--r--src/shared/loop-util.c11
-rw-r--r--src/shared/loopback-setup.c49
-rw-r--r--src/shared/machine-pool.c2
-rw-r--r--src/shared/meson.build2
-rw-r--r--src/shared/mount-setup.c2
-rw-r--r--src/shared/mount-util.c2
-rw-r--r--src/shared/selinux-util.c18
-rw-r--r--src/shared/selinux-util.h2
-rw-r--r--src/shared/smack-util.c21
-rw-r--r--src/shared/smack-util.h3
-rw-r--r--src/systemctl/systemctl-edit.c2
-rw-r--r--src/systemd/sd-journal.h1
-rw-r--r--src/sysusers/sysusers.c2
-rw-r--r--src/test/test-dlopen.c10
-rw-r--r--src/test/test-execute.c14
-rw-r--r--src/test/test-fs-util.c24
-rw-r--r--src/test/test-loopback.c32
-rw-r--r--src/test/udev-rule-runner.c2
-rw-r--r--src/timedate/timedated.c2
-rw-r--r--src/tmpfiles/tmpfiles.c10
-rw-r--r--src/udev/udev-node.c2
-rw-r--r--src/udev/udevadm.c2
-rw-r--r--src/udev/udevd.c2
-rw-r--r--src/update-done/update-done.c2
-rw-r--r--src/user-sessions/user-sessions.c2
79 files changed, 806 insertions, 443 deletions
diff --git a/src/basic/chase.c b/src/basic/chase.c
index 373252b645..983901f714 100644
--- a/src/basic/chase.c
+++ b/src/basic/chase.c
@@ -325,7 +325,11 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
return r;
if (FLAGS_SET(flags, CHASE_MKDIR_0755) && !isempty(todo)) {
- child = xopenat(fd, first, O_DIRECTORY|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0755);
+ child = xopenat(fd,
+ first,
+ O_DIRECTORY|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC,
+ /* xopen_flags = */ 0,
+ 0755);
if (child < 0)
return child;
} else if (FLAGS_SET(flags, CHASE_PARENT) && isempty(todo)) {
@@ -628,6 +632,7 @@ int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, i
/* Shortcut this call if none of the special features of this call are requested */
return RET_NERRNO(xopenat(AT_FDCWD, path,
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
+ /* xopen_flags = */ 0,
mode));
r = chase(path, root, CHASE_PARENT|chase_flags, &p, &path_fd);
@@ -645,7 +650,7 @@ int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, i
return r;
}
- r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, mode);
+ r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (r < 0)
return r;
@@ -834,6 +839,7 @@ int chase_and_openat(int dir_fd, const char *path, ChaseFlags chase_flags, int o
/* Shortcut this call if none of the special features of this call are requested */
return RET_NERRNO(xopenat(dir_fd, path,
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
+ /* xopen_flags = */ 0,
mode));
r = chaseat(dir_fd, path, chase_flags|CHASE_PARENT, &p, &path_fd);
@@ -846,7 +852,7 @@ int chase_and_openat(int dir_fd, const char *path, ChaseFlags chase_flags, int o
return r;
}
- r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, mode);
+ r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (r < 0)
return r;
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 1e1413dc80..04a6531dcb 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -14,6 +14,7 @@
#include "fileio.h"
#include "fs-util.h"
#include "hostname-util.h"
+#include "label.h"
#include "lock-util.h"
#include "log.h"
#include "macro.h"
@@ -1034,7 +1035,7 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) {
path = fname;
}
- fd = xopenat(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, mode);
+ fd = xopenat(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (IN_SET(fd, -ELOOP, -ENOTDIR))
return -EEXIST;
if (fd < 0)
@@ -1090,7 +1091,7 @@ int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, b
}
}
-int xopenat(int dir_fd, const char *path, int flags, mode_t mode) {
+int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) {
_cleanup_close_ int fd = -EBADF;
bool made = false;
int r;
@@ -1099,14 +1100,20 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) {
assert(path);
if (isempty(path)) {
- assert(!FLAGS_SET(flags, O_CREAT|O_EXCL));
- return fd_reopen(dir_fd, flags & ~O_NOFOLLOW);
+ assert(!FLAGS_SET(open_flags, O_CREAT|O_EXCL));
+ return fd_reopen(dir_fd, open_flags & ~O_NOFOLLOW);
}
- if (FLAGS_SET(flags, O_DIRECTORY|O_CREAT)) {
+ if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
+ r = label_ops_pre(dir_fd, path, FLAGS_SET(open_flags, O_DIRECTORY) ? S_IFDIR : S_IFREG);
+ if (r < 0)
+ return r;
+ }
+
+ if (FLAGS_SET(open_flags, O_DIRECTORY|O_CREAT)) {
r = RET_NERRNO(mkdirat(dir_fd, path, mode));
if (r == -EEXIST) {
- if (FLAGS_SET(flags, O_EXCL))
+ if (FLAGS_SET(open_flags, O_EXCL))
return -EEXIST;
made = false;
@@ -1115,10 +1122,17 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) {
else
made = true;
- flags &= ~(O_EXCL|O_CREAT);
+ if (FLAGS_SET(xopen_flags, XO_LABEL)) {
+ r = label_ops_post(dir_fd, path);
+ if (r < 0)
+ return r;
+ }
+
+ open_flags &= ~(O_EXCL|O_CREAT);
+ xopen_flags &= ~XO_LABEL;
}
- fd = RET_NERRNO(openat(dir_fd, path, flags, mode));
+ fd = RET_NERRNO(openat(dir_fd, path, open_flags, mode));
if (fd < 0) {
if (IN_SET(fd,
/* We got ENOENT? then someone else immediately removed it after we
@@ -1137,10 +1151,24 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) {
return fd;
}
+ if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
+ r = label_ops_post(dir_fd, path);
+ if (r < 0)
+ return r;
+ }
+
return TAKE_FD(fd);
}
-int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType locktype, int operation) {
+int xopenat_lock(
+ int dir_fd,
+ const char *path,
+ int open_flags,
+ XOpenFlags xopen_flags,
+ mode_t mode,
+ LockType locktype,
+ int operation) {
+
_cleanup_close_ int fd = -EBADF;
int r;
@@ -1150,13 +1178,13 @@ int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType
/* POSIX/UNPOSIX locks don't work on directories (errno is set to -EBADF so let's return early with
* the same error here). */
- if (FLAGS_SET(flags, O_DIRECTORY) && locktype != LOCK_BSD)
+ if (FLAGS_SET(open_flags, O_DIRECTORY) && locktype != LOCK_BSD)
return -EBADF;
for (;;) {
struct stat st;
- fd = xopenat(dir_fd, path, flags, mode);
+ fd = xopenat(dir_fd, path, open_flags, xopen_flags, mode);
if (fd < 0)
return fd;
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index cf381dfc26..a19836d138 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -132,6 +132,10 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode);
int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created);
-int xopenat(int dir_fd, const char *path, int flags, mode_t mode);
+typedef enum XOpenFlags {
+ XO_LABEL = 1 << 0,
+} XOpenFlags;
-int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType locktype, int operation);
+int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode);
+
+int xopenat_lock(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation);
diff --git a/src/basic/label.c b/src/basic/label.c
new file mode 100644
index 0000000000..f134e77589
--- /dev/null
+++ b/src/basic/label.c
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <errno.h>
+#include <stddef.h>
+
+#include "label.h"
+
+static const LabelOps *label_ops = NULL;
+
+int label_ops_set(const LabelOps *ops) {
+ if (label_ops)
+ return -EBUSY;
+
+ label_ops = ops;
+ return 0;
+}
+
+int label_ops_pre(int dir_fd, const char *path, mode_t mode) {
+ if (!label_ops || !label_ops->pre)
+ return 0;
+
+ return label_ops->pre(dir_fd, path, mode);
+}
+
+int label_ops_post(int dir_fd, const char *path) {
+ if (!label_ops || !label_ops->post)
+ return 0;
+
+ return label_ops->post(dir_fd, path);
+}
diff --git a/src/basic/label.h b/src/basic/label.h
new file mode 100644
index 0000000000..9644e435a3
--- /dev/null
+++ b/src/basic/label.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <sys/types.h>
+
+typedef struct LabelOps {
+ int (*pre)(int dir_fd, const char *path, mode_t mode);
+ int (*post)(int dir_fd, const char *path);
+} LabelOps;
+
+int label_ops_set(const LabelOps *label_ops);
+
+int label_ops_pre(int dir_fd, const char *path, mode_t mode);
+int label_ops_post(int dir_fd, const char *path);
diff --git a/src/basic/lock-util.c b/src/basic/lock-util.c
index 8ca30a50f0..3614fbe37c 100644
--- a/src/basic/lock-util.c
+++ b/src/basic/lock-util.c
@@ -37,7 +37,13 @@ int make_lock_file_at(int dir_fd, const char *p, int operation, LockFile *ret) {
if (!t)
return -ENOMEM;
- fd = xopenat_lock(dfd, p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600, LOCK_UNPOSIX, operation);
+ fd = xopenat_lock(dfd,
+ p,
+ O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY,
+ /* xopen_flags = */ 0,
+ 0600,
+ LOCK_UNPOSIX,
+ operation);
if (fd < 0)
return fd == -EAGAIN ? -EBUSY : fd;
diff --git a/src/basic/meson.build b/src/basic/meson.build
index ee94337140..9358a40001 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -44,6 +44,7 @@ basic_sources = files(
'inotify-util.c',
'io-util.c',
'ioprio-util.c',
+ 'label.c',
'limits-util.c',
'locale-util.c',
'lock-util.c',
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index 843cc025dc..633d9479dd 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -464,7 +464,7 @@ int xstatfsat(int dir_fd, const char *path, struct statfs *ret) {
assert(path);
assert(ret);
- fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY, 0);
+ fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0);
if (fd < 0)
return fd;
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index 3325aabe4d..6bdf26b42a 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -127,7 +127,7 @@ char* getlogname_malloc(void) {
return uid_to_name(uid);
}
-char *getusername_malloc(void) {
+char* getusername_malloc(void) {
const char *e;
e = secure_getenv("USER");
@@ -171,7 +171,7 @@ const char* default_root_shell_at(int rfd) {
return "/bin/sh";
}
-const char *default_root_shell(const char *root) {
+const char* default_root_shell(const char *root) {
_cleanup_close_ int rfd = -EBADF;
rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH);
@@ -847,7 +847,7 @@ bool valid_gecos(const char *d) {
return true;
}
-char *mangle_gecos(const char *d) {
+char* mangle_gecos(const char *d) {
char *mangled;
/* Makes sure the provided string becomes valid as a GEGOS field, by dropping bad chars. glibc's
@@ -1059,7 +1059,7 @@ int is_this_me(const char *username) {
return uid == getuid();
}
-const char *get_home_root(void) {
+const char* get_home_root(void) {
const char *e;
/* For debug purposes allow overriding where we look for home dirs */
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
index c82941dd81..8b829a9ae2 100644
--- a/src/basic/user-util.h
+++ b/src/basic/user-util.h
@@ -103,7 +103,7 @@ typedef enum ValidUserFlags {
bool valid_user_group_name(const char *u, ValidUserFlags flags);
bool valid_gecos(const char *d);
-char *mangle_gecos(const char *d);
+char* mangle_gecos(const char *d);
bool valid_home(const char *p);
static inline bool valid_shell(const char *p) {
@@ -136,7 +136,7 @@ const char* default_root_shell(const char *root);
int is_this_me(const char *username);
-const char *get_home_root(void);
+const char* get_home_root(void);
static inline bool hashed_password_is_locked_or_invalid(const char *password) {
return password && password[0] != '$';
diff --git a/src/boot/bootctl-status.c b/src/boot/bootctl-status.c
index 3da6478259..b51bd2681e 100644
--- a/src/boot/bootctl-status.c
+++ b/src/boot/bootctl-status.c
@@ -319,7 +319,7 @@ int verb_status(int argc, char *argv[], void *userdata) {
dev_t esp_devid = 0, xbootldr_devid = 0;
int r, k;
- r = acquire_esp(/* unprivileged_mode= */ geteuid() != 0, /* graceful= */ false, NULL, NULL, NULL, &esp_uuid, &esp_devid);
+ r = acquire_esp(/* unprivileged_mode= */ -1, /* graceful= */ false, NULL, NULL, NULL, &esp_uuid, &esp_devid);
if (arg_print_esp_path) {
if (r == -EACCES) /* If we couldn't acquire the ESP path, log about access errors (which is the only
* error the find_esp_and_warn() won't log on its own) */
@@ -330,7 +330,7 @@ int verb_status(int argc, char *argv[], void *userdata) {
puts(arg_esp_path);
}
- r = acquire_xbootldr(/* unprivileged_mode= */ geteuid() != 0, &xbootldr_uuid, &xbootldr_devid);
+ r = acquire_xbootldr(/* unprivileged_mode= */ -1, &xbootldr_uuid, &xbootldr_devid);
if (arg_print_dollar_boot_path) {
if (r == -EACCES)
return log_error_errno(r, "Failed to determine XBOOTLDR partition: %m");
@@ -770,13 +770,13 @@ int verb_list(int argc, char *argv[], void *userdata) {
* Here we're interested in the latter but not the former, hence request the mode, and log about
* EACCES. */
- r = acquire_esp(/* unprivileged_mode= */ geteuid() != 0, /* graceful= */ false, NULL, NULL, NULL, NULL, &esp_devid);
+ r = acquire_esp(/* unprivileged_mode= */ -1, /* graceful= */ false, NULL, NULL, NULL, NULL, &esp_devid);
if (r == -EACCES) /* We really need the ESP path for this call, hence also log about access errors */
return log_error_errno(r, "Failed to determine ESP location: %m");
if (r < 0)
return r;
- r = acquire_xbootldr(/* unprivileged_mode= */ geteuid() != 0, NULL, &xbootldr_devid);
+ r = acquire_xbootldr(/* unprivileged_mode= */ -1, NULL, &xbootldr_devid);
if (r == -EACCES)
return log_error_errno(r, "Failed to determine XBOOTLDR partition: %m");
if (r < 0)
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index 65608f5e83..da55ad8e0d 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -64,7 +64,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_efi_boot_option_description, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
int acquire_esp(
- bool unprivileged_mode,
+ int unprivileged_mode,
bool graceful,
uint32_t *ret_part,
uint64_t *ret_pstart,
@@ -101,7 +101,7 @@ int acquire_esp(
}
int acquire_xbootldr(
- bool unprivileged_mode,
+ int unprivileged_mode,
sd_id128_t *ret_uuid,
dev_t *ret_devid) {
diff --git a/src/boot/bootctl.h b/src/boot/bootctl.h
index dd98b959c2..e395b3324a 100644
--- a/src/boot/bootctl.h
+++ b/src/boot/bootctl.h
@@ -42,5 +42,5 @@ static inline const char *arg_dollar_boot_path(void) {
return arg_xbootldr_path ?: arg_esp_path;
}
-int acquire_esp(bool unprivileged_mode, bool graceful, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
-int acquire_xbootldr(bool unprivileged_mode, sd_id128_t *ret_uuid, dev_t *ret_devid);
+int acquire_esp(int unprivileged_mode, bool graceful, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
+int acquire_xbootldr(int unprivileged_mode, sd_id128_t *ret_uuid, dev_t *ret_devid);
diff --git a/src/boot/efi/proto/tcg.h b/src/boot/efi/proto/tcg.h
index af6989c854..d8802ae0e3 100644
--- a/src/boot/efi/proto/tcg.h
+++ b/src/boot/efi/proto/tcg.h
@@ -54,7 +54,7 @@ typedef struct {
uint8_t Digest[20];
} Digest;
uint32_t EventSize;
- uint8_t Event[0];
+ uint8_t Event[];
} _packed_ TCG_PCR_EVENT;
typedef struct {
diff --git a/src/core/automount.c b/src/core/automount.c
index 5df697bf22..3254275d6b 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -21,7 +21,7 @@
#include "format-util.h"
#include "fstab-util.h"
#include "io-util.h"
-#include "label.h"
+#include "label-util.h"
#include "mkdir-label.h"
#include "mount-util.h"
#include "mount.h"
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 4ec5dfa587..839b1676c8 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -3142,7 +3142,9 @@ static int on_cgroup_empty_event(sd_event_source *s, void *userdata) {
unit_add_to_gc_queue(u);
- if (UNIT_VTABLE(u)->notify_cgroup_empty)
+ if (IN_SET(unit_active_state(u), UNIT_INACTIVE, UNIT_FAILED))
+ unit_prune_cgroup(u);
+ else if (UNIT_VTABLE(u)->notify_cgroup_empty)
UNIT_VTABLE(u)->notify_cgroup_empty(u);
return 0;
diff --git a/src/core/execute.c b/src/core/execute.c
index 5e327465da..b2804e52e9 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -65,7 +65,7 @@
#include "hexdecoct.h"
#include "io-util.h"
#include "ioprio-util.h"
-#include "label.h"
+#include "label-util.h"
#include "log.h"
#include "macro.h"
#include "manager.h"
diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c
index c09e17f568..a99309f5c2 100644
--- a/src/core/kmod-setup.c
+++ b/src/core/kmod-setup.c
@@ -107,6 +107,27 @@ static bool has_virtio_console(void) {
return r > 0;
}
+static bool has_virtio_vsock(void) {
+ int r;
+
+ /* Directory traversal might be slow, hence let's do a cheap check first if it's even worth it */
+ if (detect_vm() == VIRTUALIZATION_NONE)
+ return false;
+
+ r = recurse_dir_at(
+ AT_FDCWD,
+ "/sys/devices/pci0000:00",
+ /* statx_mask= */ 0,
+ /* n_depth_max= */ 3,
+ RECURSE_DIR_ENSURE_TYPE,
+ match_modalias_recurse_dir_cb,
+ STRV_MAKE("virtio:d00000013v"));
+ if (r < 0)
+ log_debug_errno(r, "Failed to determine whether host has virtio-vsock device, ignoring: %m");
+
+ return r > 0;
+}
+
static bool in_qemu(void) {
return IN_SET(detect_vm(), VIRTUALIZATION_KVM, VIRTUALIZATION_QEMU);
}
@@ -124,35 +145,38 @@ int kmod_setup(void) {
} kmod_table[] = {
/* This one we need to load explicitly, since auto-loading on use doesn't work
* before udev created the ghost device nodes, and we need it earlier than that. */
- { "autofs4", "/sys/class/misc/autofs", true, false, NULL },
+ { "autofs4", "/sys/class/misc/autofs", true, false, NULL },
/* This one we need to load explicitly, since auto-loading of IPv6 is not done when
* we try to configure ::1 on the loopback device. */
- { "ipv6", "/sys/module/ipv6", false, true, NULL },
+ { "ipv6", "/sys/module/ipv6", false, true, NULL },
/* This should never be a module */
- { "unix", "/proc/net/unix", true, true, NULL },
+ { "unix", "/proc/net/unix", true, true, NULL },
#if HAVE_LIBIPTC
/* netfilter is needed by networkd, nspawn among others, and cannot be autoloaded */
- { "ip_tables", "/proc/net/ip_tables_names", false, false, NULL },
+ { "ip_tables", "/proc/net/ip_tables_names", false, false, NULL },
#endif
/* virtio_rng would be loaded by udev later, but real entropy might be needed very early */
- { "virtio_rng", NULL, false, false, has_virtio_rng },
+ { "virtio_rng", NULL, false, false, has_virtio_rng },
/* we want early logging to hvc consoles if possible, and make sure systemd-getty-generator
* can rely on all consoles being probed already.*/
- { "virtio_console", NULL, false, false, has_virtio_console },
+ { "virtio_console", NULL, false, false, has_virtio_console },
+
+ /* Make sure we can send sd-notify messages over vsock as early as possible. */
+ { "vmw_vsock_virtio_transport", NULL, false, false, has_virtio_vsock },
/* qemu_fw_cfg would be loaded by udev later, but we want to import credentials from it super early */
- { "qemu_fw_cfg", "/sys/firmware/qemu_fw_cfg", false, false, in_qemu },
+ { "qemu_fw_cfg", "/sys/firmware/qemu_fw_cfg", false, false, in_qemu },
/* dmi-sysfs is needed to import credentials from it super early */
- { "dmi-sysfs", "/sys/firmware/dmi/entries", false, false, NULL },
+ { "dmi-sysfs", "/sys/firmware/dmi/entries", false, false, NULL },
#if HAVE_TPM2
/* Make sure the tpm subsystem is available which ConditionSecurity=tpm2 depends on. */
- { "tpm", "/sys/class/tpmrm", false, false, efi_has_tpm2 },
+ { "tpm", "/sys/class/tpmrm", false, false, efi_has_tpm2 },
#endif
};
_cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL;
diff --git a/src/core/main.c b/src/core/main.c
index 08d416bc14..c69f9b9afe 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -2849,8 +2849,8 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (mac_selinux_init() < 0) {
- error_message = "Failed to initialize SELinux support";
+ if (mac_init() < 0) {
+ error_message = "Failed to initialize MAC support";
goto finish;
}
@@ -2922,8 +2922,8 @@ int main(int argc, char *argv[]) {
* operate. */
capability_ambient_set_apply(0, /* also_inherit= */ false);
- if (mac_selinux_init() < 0) {
- error_message = "Failed to initialize SELinux support";
+ if (mac_init() < 0) {
+ error_message = "Failed to initialize MAC support";
goto finish;
}
}
diff --git a/src/core/manager.c b/src/core/manager.c
index f8d469ebf6..78d1a032e6 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -54,7 +54,7 @@
#include "inotify-util.h"
#include "install.h"
#include "io-util.h"
-#include "label.h"
+#include "label-util.h"
#include "load-fragment.h"
#include "locale-setup.h"
#include "log.h"
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 1116ece59d..b00f27e08f 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -22,7 +22,7 @@
#include "fd-util.h"
#include "format-util.h"
#include "glyph-util.h"
-#include "label.h"
+#include "label-util.h"
#include "list.h"
#include "lock-util.h"
#include "loop-util.h"
diff --git a/src/core/scope.c b/src/core/scope.c
index 761eb5ea56..72253421e2 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -629,11 +629,6 @@ static void scope_notify_cgroup_empty_event(Unit *u) {
if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
scope_enter_dead(s, SCOPE_SUCCESS);
-
- /* If the cgroup empty notification comes when the unit is not active, we must have failed to clean
- * up the cgroup earlier and should do it now. */
- if (IN_SET(s->state, SCOPE_DEAD, SCOPE_FAILED))
- unit_prune_cgroup(u);
}
static void scope_notify_cgroup_oom_event(Unit *u, bool managed_oom) {
diff --git a/src/core/service.c b/src/core/service.c
index 533d7d3771..38f8745674 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -3648,12 +3648,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
/* If the cgroup empty notification comes when the unit is not active, we must have failed to clean
* up the cgroup earlier and should do it now. */
- case SERVICE_DEAD:
- case SERVICE_FAILED:
- case SERVICE_DEAD_BEFORE_AUTO_RESTART:
- case SERVICE_FAILED_BEFORE_AUTO_RESTART:
case SERVICE_AUTO_RESTART:
- case SERVICE_DEAD_RESOURCES_PINNED:
unit_prune_cgroup(u);
break;
diff --git a/src/core/socket.c b/src/core/socket.c
index a6477de5a0..7c596182c2 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -26,7 +26,7 @@
#include "in-addr-util.h"
#include "io-util.h"
#include "ip-protocol-list.h"
-#include "label.h"
+#include "label-util.h"
#include "log.h"
#include "mkdir-label.h"
#include "parse-util.h"
diff --git a/src/core/transaction.c b/src/core/transaction.c
index c3d6ffccc1..65a00bd928 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -325,6 +325,8 @@ static char* merge_unit_ids(const char* unit_log_field, char * const* pairs) {
_cleanup_free_ char *ans = NULL;
size_t size = 0;
+ assert(unit_log_field);
+
STRV_FOREACH_PAIR(unit_id, job_type, pairs) {
size_t next;
diff --git a/src/core/unit.c b/src/core/unit.c
index 90f87a95f5..8b4fb0fce4 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -32,7 +32,7 @@
#include "id128-util.h"
#include "install.h"
#include "io-util.h"
-#include "label.h"
+#include "label-util.h"
#include "load-dropin.h"
#include "load-fragment.h"
#include "log.h"
@@ -441,6 +441,9 @@ bool unit_may_gc(Unit *u) {
if (u->perpetual)
return false;
+ if (u->in_cgroup_empty_queue)
+ return false;
+
if (sd_bus_track_count(u->bus_track) > 0)
return false;
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index 2d33a967ca..45e0abc63d 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -96,6 +96,8 @@ static int help(void) {
_cleanup_free_ char *link = NULL;
int r;
+ pager_open(arg_pager_flags);
+
r = terminal_urlify_man("systemd-dissect", "1", &link);
if (r < 0)
return log_oom();
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index 36ab0148b9..97b1c61748 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -1524,7 +1524,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c
index edc5dfc1f5..4287b1f066 100644
--- a/src/hwdb/hwdb.c
+++ b/src/hwdb/hwdb.c
@@ -124,7 +124,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/journal-remote/journal-remote-write.c b/src/journal-remote/journal-remote-write.c
index 2d8188ec62..515ea2681e 100644
--- a/src/journal-remote/journal-remote-write.c
+++ b/src/journal-remote/journal-remote-write.c
@@ -28,19 +28,20 @@ int writer_new(RemoteServer *server, Writer **ret) {
assert(server);
assert(ret);
- w = new0(Writer, 1);
+ w = new(Writer, 1);
if (!w)
return -ENOMEM;
- w->n_ref = 1;
- w->metrics = server->metrics;
+ *w = (Writer) {
+ .n_ref = 1,
+ .metrics = server->metrics,
+ .server = server,
+ };
w->mmap = mmap_cache_new();
if (!w->mmap)
return -ENOMEM;
- w->server = server;
-
if (is_dir(server->output, /* follow = */ true) > 0) {
w->output = strdup(server->output);
if (!w->output)
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index c53f2d5847..4f9c1f4780 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -65,6 +65,7 @@
#include "rlimit-util.h"
#include "set.h"
#include "sigbus.h"
+#include "signal-util.h"
#include "static-destruct.h"
#include "stdio-util.h"
#include "string-table.h"
@@ -115,7 +116,7 @@ static char *arg_verify_key = NULL;
static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
static bool arg_force = false;
#endif
-static usec_t arg_since, arg_until;
+static usec_t arg_since = 0, arg_until = 0;
static bool arg_since_set = false, arg_until_set = false;
static char **arg_syslog_identifier = NULL;
static char **arg_system_units = NULL;
@@ -1047,7 +1048,10 @@ static int parse_argv(int argc, char *argv[]) {
assert_not_reached();
}
- if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
+ if (arg_no_tail)
+ arg_lines = ARG_LINES_ALL;
+
+ if (arg_follow && !arg_since_set && arg_lines == ARG_LINES_DEFAULT)
arg_lines = 10;
if (arg_follow && !arg_merge && !arg_boot) {
@@ -2058,51 +2062,295 @@ static int sync_journal(void) {
return simple_varlink_call("--sync", "io.systemd.Journal.Synchronize");
}
-static int wait_for_change(sd_journal *j, int poll_fd) {
- struct pollfd pollfds[] = {
- { .fd = poll_fd, .events = POLLIN },
- { .fd = STDOUT_FILENO },
- };
- usec_t timeout;
+static int action_list_fields(sd_journal *j) {
+ const void *data;
+ size_t size;
+ int r, n_shown = 0;
+
+ assert(arg_field);
+
+ r = sd_journal_set_data_threshold(j, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to unset data size threshold: %m");
+
+ r = sd_journal_query_unique(j, arg_field);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query unique data objects: %m");
+
+ SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
+ const void *eq;
+
+ if (arg_lines >= 0 && n_shown >= arg_lines)
+ break;
+
+ eq = memchr(data, '=', size);
+ if (eq)
+ printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
+ else
+ printf("%.*s\n", (int) size, (const char*) data);
+
+ n_shown++;
+ }
+
+ return 0;
+}
+
+static int update_cursor(sd_journal *j) {
+ _cleanup_free_ char *cursor = NULL;
int r;
assert(j);
- assert(poll_fd >= 0);
- /* Much like sd_journal_wait() but also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that,
- * i.e. when it is closed. */
+ if (!arg_show_cursor && !arg_cursor_file)
+ return 0;
- r = sd_journal_get_timeout(j, &timeout);
+ r = sd_journal_get_cursor(j, &cursor);
+ if (r == -EADDRNOTAVAIL)
+ return 0;
if (r < 0)
- return log_error_errno(r, "Failed to determine journal waiting time: %m");
+ return log_error_errno(r, "Failed to get cursor: %m");
- r = ppoll_usec(pollfds, ELEMENTSOF(pollfds), timeout);
- if (r == -EINTR)
- return 0;
+ if (arg_show_cursor)
+ printf("-- cursor: %s\n", cursor);
+
+ if (arg_cursor_file) {
+ r = write_string_file(arg_cursor_file, cursor, WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_ATOMIC);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write new cursor to %s: %m", arg_cursor_file);
+ }
+
+ return 0;
+}
+
+typedef struct Context {
+ sd_journal *journal;
+ bool need_seek;
+ bool since_seeked;
+ bool ellipsized;
+ bool previous_boot_id_valid;
+ sd_id128_t previous_boot_id;
+ sd_id128_t previous_boot_id_output;
+ dual_timestamp previous_ts_output;
+} Context;
+
+static int show(Context *c) {
+ sd_journal *j;
+ int r, n_shown = 0;
+
+ assert(c);
+
+ j = ASSERT_PTR(c->journal);
+
+ while (arg_lines < 0 || n_shown < arg_lines || arg_follow) {
+ int flags;
+ size_t highlight[2] = {};
+
+ if (c->need_seek) {
+ r = sd_journal_step_one(j, !arg_reverse);
+ if (r < 0)
+ return log_error_errno(r, "Failed to iterate through journal: %m");
+ if (r == 0)
+ break;
+ }
+
+ if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set)) {
+ /* If --lines= is set, we usually rely on the n_shown to tell us
+ * when to stop. However, if --since= is set too, we may end up
+ * having less than --lines= to output. In this case let's also
+ * check if the entry is in range. */
+
+ usec_t usec;
+
+ r = sd_journal_get_realtime_usec(j, &usec);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine timestamp: %m");
+ if (usec > arg_until)
+ break;
+ }
+
+ if (arg_since_set && (arg_reverse || !c->since_seeked)) {
+ usec_t usec;
+
+ r = sd_journal_get_realtime_usec(j, &usec);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine timestamp: %m");
+
+ if (usec < arg_since) {
+ if (arg_reverse)
+ break; /* Reached the earliest entry */
+
+ /* arg_lines >= 0 (!since_seeked):
+ * We jumped arg_lines back and it seems to be too much */
+ r = sd_journal_seek_realtime_usec(j, arg_since);
+ if (r < 0)
+ return log_error_errno(r, "Failed to seek to date: %m");
+ c->since_seeked = true;
+
+ c->need_seek = true;
+ continue;
+ }
+ c->since_seeked = true; /* We're surely within the range of --since now */
+ }
+
+ if (!arg_merge && !arg_quiet) {
+ sd_id128_t boot_id;
+
+ r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
+ if (r >= 0) {
+ if (c->previous_boot_id_valid &&
+ !sd_id128_equal(boot_id, c->previous_boot_id))
+ printf("%s-- Boot "SD_ID128_FORMAT_STR" --%s\n",
+ ansi_highlight(), SD_ID128_FORMAT_VAL(boot_id), ansi_normal());
+
+ c->previous_boot_id = boot_id;
+ c->previous_boot_id_valid = true;
+ }
+ }
+
+ if (arg_compiled_pattern) {
+ const void *message;
+ size_t len;
+
+ r = sd_journal_get_data(j, "MESSAGE", &message, &len);
+ if (r < 0) {
+ if (r == -ENOENT) {
+ c->need_seek = true;
+ continue;
+ }
+
+ return log_error_errno(r, "Failed to get MESSAGE field: %m");
+ }
+
+ assert_se(message = startswith(message, "MESSAGE="));
+
+ r = pattern_matches_and_log(arg_compiled_pattern, message,
+ len - strlen("MESSAGE="), highlight);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ c->need_seek = true;
+ continue;
+ }
+ }
+
+ flags =
+ arg_all * OUTPUT_SHOW_ALL |
+ arg_full * OUTPUT_FULL_WIDTH |
+ colors_enabled() * OUTPUT_COLOR |
+ arg_catalog * OUTPUT_CATALOG |
+ arg_utc * OUTPUT_UTC |
+ arg_no_hostname * OUTPUT_NO_HOSTNAME;
+
+ r = show_journal_entry(stdout, j, arg_output, 0, flags,
+ arg_output_fields, highlight, &c->ellipsized,
+ &c->previous_ts_output, &c->previous_boot_id_output);
+ c->need_seek = true;
+ if (r == -EADDRNOTAVAIL)
+ break;
+ if (r < 0)
+ return r;
+
+ n_shown++;
+
+ /* If journalctl take a long time to process messages, and during that time journal file
+ * rotation occurs, a journalctl client will keep those rotated files open until it calls
+ * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below
+ * in the "following" case. By periodically calling sd_journal_process() during the processing
+ * loop we shrink the window of time a client instance has open file descriptors for rotated
+ * (deleted) journal files. */
+ if ((n_shown % PROCESS_INOTIFY_INTERVAL) == 0) {
+ r = sd_journal_process(j);
+ if (r < 0)
+ return log_error_errno(r, "Failed to process inotify events: %m");
+ }
+ }
+
+ return n_shown;
+}
+
+static int show_and_fflush(Context *c, sd_event_source *s) {
+ int r;
+
+ assert(c);
+ assert(s);
+
+ r = show(c);
+ if (r < 0)
+ return sd_event_exit(sd_event_source_get_event(s), r);
+
+ fflush(stdout);
+ return 0;
+}
+
+static int on_journal_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+ Context *c = ASSERT_PTR(userdata);
+ int r;
+
+ assert(s);
+
+ r = sd_journal_process(c->journal);
+ if (r < 0) {
+ log_error_errno(r, "Failed to process journal events: %m");
+ return sd_event_exit(sd_event_source_get_event(s), r);
+ }
+
+ return show_and_fflush(c, s);
+}
+
+static int on_first_event(sd_event_source *s, void *userdata) {
+ return show_and_fflush(userdata, s);
+}
+
+static int on_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
+ assert(s);
+ assert(si);
+ assert(IN_SET(si->ssi_signo, SIGTERM, SIGINT));
+
+ return sd_event_exit(sd_event_source_get_event(s), si->ssi_signo);
+}
+
+static int setup_event(Context *c, int fd, sd_event **ret) {
+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+ int r;
+
+ assert(arg_follow);
+ assert(c);
+ assert(fd >= 0);
+ assert(ret);
+
+ r = sd_event_default(&e);
if (r < 0)
- return log_error_errno(r, "Couldn't wait for journal event: %m");
+ return log_error_errno(r, "Failed to allocate sd_event object: %m");
+
+ (void) sd_event_add_signal(e, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_signal, NULL);
+ (void) sd_event_add_signal(e, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_signal, NULL);
- if (pollfds[1].revents & (POLLHUP|POLLERR)) /* STDOUT has been closed? */
- return log_debug_errno(SYNTHETIC_ERRNO(ECANCELED),
- "Standard output has been closed.");
+ r = sd_event_add_io(e, NULL, fd, EPOLLIN, &on_journal_event, c);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add io event source for journal: %m");
- r = sd_journal_process(j);
+ /* Also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, i.e. when it is closed. */
+ r = sd_event_add_io(e, NULL, STDOUT_FILENO, EPOLLHUP|EPOLLERR, NULL, INT_TO_PTR(-ECANCELED));
if (r < 0)
- return log_error_errno(r, "Failed to process journal events: %m");
+ return log_error_errno(r, "Failed to add io event source for stdout: %m");
+
+ if (arg_lines != 0 || arg_since_set) {
+ r = sd_event_add_defer(e, NULL, on_first_event, c);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add defer event source: %m");
+ }
+ *ret = TAKE_PTR(e);
return 0;
}
static int run(int argc, char *argv[]) {
+ bool need_seek = false, since_seeked = false, use_cursor = false, after_cursor = false;
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
_cleanup_(umount_and_freep) char *mounted_dir = NULL;
- bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false, since_seeked = false;
- bool use_cursor = false, after_cursor = false;
_cleanup_(sd_journal_closep) sd_journal *j = NULL;
- sd_id128_t previous_boot_id = SD_ID128_NULL, previous_boot_id_output = SD_ID128_NULL;
- dual_timestamp previous_ts_output = DUAL_TIMESTAMP_NULL;
_cleanup_close_ int machine_fd = -EBADF;
- int n_shown = 0, r, poll_fd = -EBADF;
+ int n_shown, r, poll_fd = -EBADF;
setlocale(LC_ALL, "");
log_setup();
@@ -2381,37 +2629,8 @@ static int run(int argc, char *argv[]) {
log_debug("Journal filter: %s", filter);
}
- if (arg_action == ACTION_LIST_FIELDS) {
- const void *data;
- size_t size;
-
- assert(arg_field);
-
- r = sd_journal_set_data_threshold(j, 0);
- if (r < 0)
- return log_error_errno(r, "Failed to unset data size threshold: %m");
-
- r = sd_journal_query_unique(j, arg_field);
- if (r < 0)
- return log_error_errno(r, "Failed to query unique data objects: %m");
-
- SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
- const void *eq;
-
- if (arg_lines >= 0 && n_shown >= arg_lines)
- break;
-
- eq = memchr(data, '=', size);
- if (eq)
- printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
- else
- printf("%.*s\n", (int) size, (const char*) data);
-
- n_shown++;
- }
-
- return 0;
- }
+ if (arg_action == ACTION_LIST_FIELDS)
+ return action_list_fields(j);
/* Opening the fd now means the first sd_journal_wait() will actually wait */
if (arg_follow) {
@@ -2540,169 +2759,53 @@ static int run(int argc, char *argv[]) {
}
}
- for (;;) {
- while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
- int flags;
- size_t highlight[2] = {};
-
- if (need_seek) {
- if (!arg_reverse)
- r = sd_journal_next(j);
- else
- r = sd_journal_previous(j);
- if (r < 0)
- return log_error_errno(r, "Failed to iterate through journal: %m");
- if (r == 0)
- break;
- }
-
- if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set)) {
- /* If --lines= is set, we usually rely on the n_shown to tell us
- * when to stop. However, if --since= is set too, we may end up
- * having less than --lines= to output. In this case let's also
- * check if the entry is in range. */
-
- usec_t usec;
-
- r = sd_journal_get_realtime_usec(j, &usec);
- if (r < 0)
- return log_error_errno(r, "Failed to determine timestamp: %m");
- if (usec > arg_until)
- break;
- }
-
- if (arg_since_set && (arg_reverse || !since_seeked)) {
- usec_t usec;
-
- r = sd_journal_get_realtime_usec(j, &usec);
- if (r < 0)
- return log_error_errno(r, "Failed to determine timestamp: %m");
-
- if (usec < arg_since) {
- if (arg_reverse)
- break; /* Reached the earliest entry */
-
- /* arg_lines >= 0 (!since_seeked):
- * We jumped arg_lines back and it seems to be too much */
- r = sd_journal_seek_realtime_usec(j, arg_since);
- if (r < 0)
- return log_error_errno(r, "Failed to seek to date: %m");
- since_seeked = true;
-
- need_seek = true;
- continue;
- }
- since_seeked = true; /* We're surely within the range of --since now */
- }
-
- if (!arg_merge && !arg_quiet) {
- sd_id128_t boot_id;
-
- r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
- if (r >= 0) {
- if (previous_boot_id_valid &&
- !sd_id128_equal(boot_id, previous_boot_id))
- printf("%s-- Boot "SD_ID128_FORMAT_STR" --%s\n",
- ansi_highlight(), SD_ID128_FORMAT_VAL(boot_id), ansi_normal());
-
- previous_boot_id = boot_id;
- previous_boot_id_valid = true;
- }
- }
-
- if (arg_compiled_pattern) {
- const void *message;
- size_t len;
-
- r = sd_journal_get_data(j, "MESSAGE", &message, &len);
- if (r < 0) {
- if (r == -ENOENT) {
- need_seek = true;
- continue;
- }
-
- return log_error_errno(r, "Failed to get MESSAGE field: %m");
- }
-
- assert_se(message = startswith(message, "MESSAGE="));
-
- r = pattern_matches_and_log(arg_compiled_pattern, message,
- len - strlen("MESSAGE="), highlight);
- if (r < 0)
- return r;
- if (r == 0) {
- need_seek = true;
- continue;
- }
- }
+ Context c = {
+ .journal = j,
+ .need_seek = need_seek,
+ .since_seeked = since_seeked,
+ };
- flags =
- arg_all * OUTPUT_SHOW_ALL |
- arg_full * OUTPUT_FULL_WIDTH |
- colors_enabled() * OUTPUT_COLOR |
- arg_catalog * OUTPUT_CATALOG |
- arg_utc * OUTPUT_UTC |
- arg_no_hostname * OUTPUT_NO_HOSTNAME;
-
- r = show_journal_entry(stdout, j, arg_output, 0, flags,
- arg_output_fields, highlight, &ellipsized,
- &previous_ts_output, &previous_boot_id_output);
- need_seek = true;
- if (r == -EADDRNOTAVAIL)
- break;
- if (r < 0)
- return r;
+ if (arg_follow) {
+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+ int sig;
- n_shown++;
+ assert(poll_fd >= 0);
- /* If journalctl take a long time to process messages, and during that time journal file
- * rotation occurs, a journalctl client will keep those rotated files open until it calls
- * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below
- * in the "following" case. By periodically calling sd_journal_process() during the processing
- * loop we shrink the window of time a client instance has open file descriptors for rotated
- * (deleted) journal files. */
- if ((n_shown % PROCESS_INOTIFY_INTERVAL) == 0) {
- r = sd_journal_process(j);
- if (r < 0)
- return log_error_errno(r, "Failed to process inotify events: %m");
- }
- }
+ r = setup_event(&c, poll_fd, &e);
+ if (r < 0)
+ return r;
- if (!arg_follow) {
- if (n_shown == 0 && !arg_quiet)
- printf("-- No entries --\n");
- break;
- }
+ r = sd_event_loop(e);
+ if (r < 0)
+ return r;
+ sig = r;
- fflush(stdout);
+ /* unref signal event sources. */
+ e = sd_event_unref(e);
- r = wait_for_change(j, poll_fd);
+ r = update_cursor(j);
if (r < 0)
return r;
- first_line = false;
+ /* re-send the original signal. */
+ assert(SIGNAL_VALID(sig));
+ if (raise(sig) < 0)
+ log_error("Failed to raise the original signal SIG%s, ignoring: %m", signal_to_string(sig));
+
+ return 0;
}
- if (arg_show_cursor || arg_cursor_file) {
- _cleanup_free_ char *cursor = NULL;
+ r = show(&c);
+ if (r < 0)
+ return r;
+ n_shown = r;
- r = sd_journal_get_cursor(j, &cursor);
- if (r < 0 && r != -EADDRNOTAVAIL)
- return log_error_errno(r, "Failed to get cursor: %m");
- if (r >= 0) {
- if (arg_show_cursor)
- printf("-- cursor: %s\n", cursor);
+ if (n_shown == 0 && !arg_quiet)
+ printf("-- No entries --\n");
- if (arg_cursor_file) {
- r = write_string_file(arg_cursor_file, cursor,
- WRITE_STRING_FILE_CREATE |
- WRITE_STRING_FILE_ATOMIC);
- if (r < 0)
- return log_error_errno(r, "Failed to write new cursor to %s: %m",
- arg_cursor_file);
- }
- }
- }
+ r = update_cursor(j);
+ if (r < 0)
+ return r;
if (arg_compiled_pattern && n_shown == 0)
/* --grep was used, no error was thrown, but the pattern didn't
diff --git a/src/libsystemd-network/fuzz-dhcp-server.c b/src/libsystemd-network/fuzz-dhcp-server.c
index ad00654a91..192e209a2f 100644
--- a/src/libsystemd-network/fuzz-dhcp-server.c
+++ b/src/libsystemd-network/fuzz-dhcp-server.c
@@ -19,30 +19,32 @@ ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) {
static int add_lease(sd_dhcp_server *server, const struct in_addr *server_address, uint8_t i) {
_cleanup_(dhcp_lease_freep) DHCPLease *lease = NULL;
- static const uint8_t chaddr[] = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
int r;
assert(server);
- lease = new0(DHCPLease, 1);
+ lease = new(DHCPLease, 1);
if (!lease)
return -ENOMEM;
- lease->client_id.data = malloc(2);
+ *lease = (DHCPLease) {
+ .address = htobe32(UINT32_C(10) << 24 | i),
+ .chaddr = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .expiration = UINT64_MAX,
+ .gateway = server_address->s_addr,
+ .hlen = ETH_ALEN,
+ .htype = ARPHRD_ETHER,
+
+ .client_id.length = 2,
+ };
+
+ lease->client_id.data = new(uint8_t, lease->client_id.length);
if (!lease->client_id.data)
return -ENOMEM;
- lease->client_id.length = 2;
lease->client_id.data[0] = 2;
lease->client_id.data[1] = i;
- lease->address = htobe32(UINT32_C(10) << 24 | i);
- lease->gateway = server_address->s_addr;
- lease->expiration = UINT64_MAX;
- lease->htype = ARPHRD_ETHER;
- lease->hlen = ETH_ALEN;
- memcpy(lease->chaddr, chaddr, ETH_ALEN);
-
lease->server = server; /* This must be set just before hashmap_put(). */
r = hashmap_ensure_put(&server->bound_leases_by_client_id, &dhcp_lease_hash_ops, &lease->client_id, lease);
@@ -54,22 +56,18 @@ static int add_lease(sd_dhcp_server *server, const struct in_addr *server_addres
return r;
TAKE_PTR(lease);
-
return 0;
}
static int add_static_lease(sd_dhcp_server *server, uint8_t i) {
uint8_t id[2] = { 2, i };
- int r;
assert(server);
- r = sd_dhcp_server_set_static_lease(
+ return sd_dhcp_server_set_static_lease(
server,
&(struct in_addr) { .s_addr = htobe32(UINT32_C(10) << 24 | i)},
id, ELEMENTSOF(id));
-
- return r;
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 35352dc832..936a3577f5 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -825,4 +825,5 @@ global:
sd_event_trim_memory;
sd_pid_notify_barrier;
sd_event_source_leave_ratelimit;
+ sd_journal_step_one;
} LIBSYSTEMD_253;
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index 8538b7ab82..c4472d204e 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -450,13 +450,11 @@ static int vsock_bind_privileged_port(int fd) {
return r;
}
-_public_ int sd_pid_notify_with_fds(
+static int pid_notify_with_fds_internal(
pid_t pid,
- int unset_environment,
const char *state,
const int *fds,
unsigned n_fds) {
-
SocketAddress address;
struct iovec iovec;
struct msghdr msghdr = {
@@ -470,15 +468,11 @@ _public_ int sd_pid_notify_with_fds(
bool send_ucred;
int r;
- if (!state) {
- r = -EINVAL;
- goto finish;
- }
+ if (!state)
+ return -EINVAL;
- if (n_fds > 0 && !fds) {
- r = -EINVAL;
- goto finish;
- }
+ if (n_fds > 0 && !fds)
+ return -EINVAL;
e = getenv("NOTIFY_SOCKET");
if (!e)
@@ -489,46 +483,38 @@ _public_ int sd_pid_notify_with_fds(
if (r == -EPROTO)
r = socket_address_parse_vsock(&address, e);
if (r < 0)
- goto finish;
+ return r;
msghdr.msg_namelen = address.size;
/* If we didn't get an address (which is a normal pattern when specifying VSOCK tuples) error out,
* we always require a specific CID. */
- if (address.sockaddr.vm.svm_family == AF_VSOCK && address.sockaddr.vm.svm_cid == VMADDR_CID_ANY) {
- r = -EINVAL;
- goto finish;
- }
+ if (address.sockaddr.vm.svm_family == AF_VSOCK && address.sockaddr.vm.svm_cid == VMADDR_CID_ANY)
+ return -EINVAL;
/* At the time of writing QEMU does not yet support AF_VSOCK + SOCK_DGRAM and returns
* ENODEV. Fallback to SOCK_SEQPACKET in that case. */
fd = socket(address.sockaddr.sa.sa_family, SOCK_DGRAM|SOCK_CLOEXEC, 0);
if (fd < 0) {
- if (!(ERRNO_IS_NOT_SUPPORTED(errno) || errno == ENODEV) || address.sockaddr.sa.sa_family != AF_VSOCK) {
- r = -errno;
- goto finish;
- }
+ if (!(ERRNO_IS_NOT_SUPPORTED(errno) || errno == ENODEV) || address.sockaddr.sa.sa_family != AF_VSOCK)
+ return log_debug_errno(errno, "Failed to open datagram notify socket to '%s': %m", e);
fd = socket(address.sockaddr.sa.sa_family, SOCK_SEQPACKET|SOCK_CLOEXEC, 0);
- if (fd < 0) {
- r = -errno;
- goto finish;
- }
+ if (fd < 0)
+ return log_debug_errno(errno, "Failed to open sequential packet socket to '%s': %m", e);
r = vsock_bind_privileged_port(fd);
if (r < 0 && !ERRNO_IS_PRIVILEGE(r))
- goto finish;
+ return log_debug_errno(r, "Failed to bind socket to privileged port: %m");
- if (connect(fd, &address.sockaddr.sa, address.size) < 0) {
- r = -errno;
- goto finish;
- }
+ if (connect(fd, &address.sockaddr.sa, address.size) < 0)
+ return log_debug_errno(errno, "Failed to connect socket to '%s': %m", e);
msghdr.msg_name = NULL;
msghdr.msg_namelen = 0;
} else if (address.sockaddr.sa.sa_family == AF_VSOCK) {
r = vsock_bind_privileged_port(fd);
if (r < 0 && !ERRNO_IS_PRIVILEGE(r))
- goto finish;
+ return log_debug_errno(r, "Failed to bind socket to privileged port: %m");
}
(void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
@@ -575,10 +561,8 @@ _public_ int sd_pid_notify_with_fds(
}
/* First try with fake ucred data, as requested */
- if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) {
- r = 1;
- goto finish;
- }
+ if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0)
+ return 1;
/* If that failed, try with our own ucred instead */
if (send_ucred) {
@@ -586,15 +570,24 @@ _public_ int sd_pid_notify_with_fds(
if (msghdr.msg_controllen == 0)
msghdr.msg_control = NULL;
- if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) {
- r = 1;
- goto finish;
- }
+ if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0)
+ return 1;
}
- r = -errno;
+ return log_debug_errno(errno, "Failed to send notify message to '%s': %m", e);
+}
+
+_public_ int sd_pid_notify_with_fds(
+ pid_t pid,
+ int unset_environment,
+ const char *state,
+ const int *fds,
+ unsigned n_fds) {
+
+ int r;
+
+ r = pid_notify_with_fds_internal(pid, state, fds, n_fds);
-finish:
if (unset_environment)
assert_se(unsetenv("NOTIFY_SOCKET") == 0);
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
index 76c9d1c051..edadd86eaa 100644
--- a/src/libsystemd/sd-id128/id128-util.c
+++ b/src/libsystemd/sd-id128/id128-util.c
@@ -119,7 +119,7 @@ int id128_read_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t *ret) {
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
- fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY, 0);
+ fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0);
if (fd < 0)
return fd;
@@ -165,7 +165,7 @@ int id128_write_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t id) {
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
- fd = xopenat(dir_fd, path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, 0444);
+ fd = xopenat(dir_fd, path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, /* xopen_flags = */ 0, 0444);
if (fd < 0)
return fd;
diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c
index 47532e2cbc..957817bfab 100644
--- a/src/libsystemd/sd-journal/sd-journal.c
+++ b/src/libsystemd/sd-journal/sd-journal.c
@@ -979,6 +979,16 @@ _public_ int sd_journal_previous(sd_journal *j) {
return real_journal_next(j, DIRECTION_UP);
}
+_public_ int sd_journal_step_one(sd_journal *j, int advanced) {
+ assert_return(j, -EINVAL);
+
+ if (j->current_location.type == LOCATION_HEAD)
+ return sd_journal_next(j);
+ if (j->current_location.type == LOCATION_TAIL)
+ return sd_journal_previous(j);
+ return real_journal_next(j, advanced ? DIRECTION_DOWN : DIRECTION_UP);
+}
+
static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t skip) {
int c = 0, r;
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 63ff69d7d3..9e5b7b03c0 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -657,7 +657,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 6161af9a74..7a6056086a 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -17,7 +17,7 @@
#include "format-util.h"
#include "fs-util.h"
#include "hashmap.h"
-#include "label.h"
+#include "label-util.h"
#include "limits-util.h"
#include "logind-dbus.h"
#include "logind-user-dbus.h"
diff --git a/src/login/logind.c b/src/login/logind.c
index cfb3ef500c..8323bcc0cb 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -1194,7 +1194,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c
index 5a16d1684d..ed8a80e6ed 100644
--- a/src/login/user-runtime-dir.c
+++ b/src/login/user-runtime-dir.c
@@ -10,7 +10,7 @@
#include "dev-setup.h"
#include "format-util.h"
#include "fs-util.h"
-#include "label.h"
+#include "label-util.h"
#include "limits-util.h"
#include "main-func.h"
#include "mkdir-label.h"
@@ -202,7 +202,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 197d0cfa1c..8d7d464a4a 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -1462,7 +1462,7 @@ static int edit_settings(int argc, char *argv[], void *userdata) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"Edit is only supported on the host machine.");
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c
index 2e845aa19f..9213795f54 100644
--- a/src/network/wait-online/manager.c
+++ b/src/network/wait-online/manager.c
@@ -162,12 +162,13 @@ bool manager_configured(Manager *m) {
return true;
}
- /* With '--any' : no interface is ready
- * Without '--any': all interfaces are ready */
+ /* With '--any' : no interface is ready → return false
+ * Without '--any': all interfaces are ready → return true */
return !m->any;
}
/* wait for all links networkd manages */
+ bool has_online = false;
HASHMAP_FOREACH(l, m->links_by_index) {
if (manager_ignore_link(m, l)) {
log_link_debug(l, "link is ignored");
@@ -179,13 +180,20 @@ bool manager_configured(Manager *m) {
_LINK_OPERSTATE_INVALID });
if (r < 0 && !m->any) /* Unlike the above loop, unmanaged interfaces are ignored here. */
return false;
- if (r > 0 && m->any)
- return true;
+ if (r > 0) {
+ if (m->any)
+ return true;
+ has_online = true;
+ }
}
- /* With '--any' : no interface is ready
- * Without '--any': all interfaces are ready or unmanaged */
- return !m->any;
+ /* With '--any' : no interface is ready → return false
+ * Without '--any': all interfaces are ready or unmanaged
+ *
+ * In this stage, drivers for interfaces may not be loaded yet, and there may be only lo.
+ * To avoid that wait-online exits earlier than that drivers are loaded, let's request at least one
+ * managed online interface exists. See issue #27822. */
+ return !m->any && has_online;
}
static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index fcf5c710f1..0a85b5d89a 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -9,7 +9,7 @@
#include "fd-util.h"
#include "format-util.h"
#include "fs-util.h"
-#include "label.h"
+#include "label-util.h"
#include "mkdir-label.h"
#include "mount-util.h"
#include "mountpoint-util.h"
diff --git a/src/oom/test-oomd-util.c b/src/oom/test-oomd-util.c
index ef99d924bb..dc659b6551 100644
--- a/src/oom/test-oomd-util.c
+++ b/src/oom/test-oomd-util.c
@@ -204,7 +204,7 @@ static void test_oomd_update_cgroup_contexts_between_hashmaps(void) {
}
static void test_oomd_system_context_acquire(void) {
- _cleanup_(unlink_tempfilep) char path[] = "/oomdgetsysctxtestXXXXXX";
+ _cleanup_(unlink_tempfilep) char path[] = "/tmp/oomdgetsysctxtestXXXXXX";
_cleanup_close_ int fd = -EBADF;
OomdSystemContext ctx;
diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c
index 5749aa1dc3..52e31d2fd3 100644
--- a/src/resolve/resolved-resolv-conf.c
+++ b/src/resolve/resolved-resolv-conf.c
@@ -10,7 +10,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
-#include "label.h"
+#include "label-util.h"
#include "ordered-set.h"
#include "resolved-conf.h"
#include "resolved-dns-server.h"
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index f9d3281509..1625c5189d 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -38,7 +38,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c
index 7909184f2d..16295a5823 100644
--- a/src/shared/btrfs-util.c
+++ b/src/shared/btrfs-util.c
@@ -223,7 +223,7 @@ int btrfs_get_block_device_at(int dir_fd, const char *path, dev_t *ret) {
assert(path);
assert(ret);
- fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, 0);
+ fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0);
if (fd < 0)
return fd;
diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c
index 59f580775d..efc36e2d6d 100644
--- a/src/shared/creds-util.c
+++ b/src/shared/creds-util.c
@@ -342,6 +342,9 @@ int get_credential_host_secret(CredentialSecretFlags flags, void **ret, size_t *
filename = "credential.secret";
}
+ assert(dirname);
+ assert(filename);
+
mkdir_parents(dirname, 0755);
dfd = open_mkdir_at(AT_FDCWD, dirname, O_CLOEXEC, 0755);
if (dfd < 0)
diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c
index e0db777c96..7dca6ad7d4 100644
--- a/src/shared/dev-setup.c
+++ b/src/shared/dev-setup.c
@@ -6,7 +6,7 @@
#include "alloc-util.h"
#include "dev-setup.h"
-#include "label.h"
+#include "label-util.h"
#include "log.h"
#include "mkdir-label.h"
#include "nulstr-util.h"
diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c
index c4cf508517..d9336f4431 100644
--- a/src/shared/find-esp.c
+++ b/src/shared/find-esp.c
@@ -31,7 +31,7 @@ typedef enum VerifyESPFlags {
static int verify_esp_blkid(
dev_t devid,
- bool searching,
+ VerifyESPFlags flags,
uint32_t *ret_part,
uint64_t *ret_pstart,
uint64_t *ret_psize,
@@ -44,6 +44,7 @@ static int verify_esp_blkid(
#if HAVE_BLKID
_cleanup_(blkid_free_probep) blkid_probe b = NULL;
_cleanup_free_ char *node = NULL;
+ bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING);
const char *v;
int r;
@@ -65,9 +66,9 @@ static int verify_esp_blkid(
r = blkid_do_safeprobe(b);
if (r == -2)
return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" is ambiguous.", node);
- else if (r == 1)
+ if (r == 1)
return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" does not contain a label.", node);
- else if (r != 0)
+ if (r != 0)
return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe file system \"%s\": %m", node);
r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
@@ -146,12 +147,13 @@ static int verify_esp_blkid(
static int verify_esp_udev(
dev_t devid,
- bool searching,
+ VerifyESPFlags flags,
uint32_t *ret_part,
uint64_t *ret_pstart,
uint64_t *ret_psize,
sd_id128_t *ret_uuid) {
+ bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING);
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
sd_id128_t uuid = SD_ID128_NULL;
uint64_t pstart = 0, psize = 0;
@@ -240,10 +242,11 @@ static int verify_esp_udev(
static int verify_fsroot_dir(
int dir_fd,
const char *path,
- bool searching,
- bool unprivileged_mode,
+ VerifyESPFlags flags,
dev_t *ret_dev) {
+ bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING),
+ unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE);
_cleanup_free_ char *f = NULL;
STRUCT_NEW_STATX_DEFINE(sxa);
STRUCT_NEW_STATX_DEFINE(sxb);
@@ -377,7 +380,7 @@ static int verify_esp(
relax_checks ||
detect_container() > 0;
- r = verify_fsroot_dir(pfd, p, searching, unprivileged_mode, relax_checks ? NULL : &devid);
+ r = verify_fsroot_dir(pfd, p, flags, relax_checks ? NULL : &devid);
if (r < 0)
return r;
@@ -392,9 +395,9 @@ static int verify_esp(
* however blkid can't work if we have no privileges to access block devices directly, which is why
* we use udev in that case. */
if (unprivileged_mode)
- r = verify_esp_udev(devid, searching, ret_part, ret_pstart, ret_psize, ret_uuid);
+ r = verify_esp_udev(devid, flags, ret_part, ret_pstart, ret_psize, ret_uuid);
else
- r = verify_esp_blkid(devid, searching, ret_part, ret_pstart, ret_psize, ret_uuid);
+ r = verify_esp_blkid(devid, flags, ret_part, ret_pstart, ret_psize, ret_uuid);
if (r < 0)
return r;
@@ -425,7 +428,7 @@ finish:
int find_esp_and_warn_at(
int rfd,
const char *path,
- bool unprivileged_mode,
+ int unprivileged_mode,
char **ret_path,
uint32_t *ret_part,
uint64_t *ret_pstart,
@@ -433,7 +436,7 @@ int find_esp_and_warn_at(
sd_id128_t *ret_uuid,
dev_t *ret_devid) {
- VerifyESPFlags flags = (unprivileged_mode ? VERIFY_ESP_UNPRIVILEGED_MODE : 0);
+ VerifyESPFlags flags;
int r;
/* This logs about all errors except:
@@ -444,6 +447,10 @@ int find_esp_and_warn_at(
assert(rfd >= 0 || rfd == AT_FDCWD);
+ if (unprivileged_mode < 0)
+ unprivileged_mode = geteuid() != 0;
+ flags = unprivileged_mode > 0 ? VERIFY_ESP_UNPRIVILEGED_MODE : 0;
+
r = dir_fd_is_root_or_cwd(rfd);
if (r < 0)
return log_error_errno(r, "Failed to check if directory file descriptor is root: %m");
@@ -509,7 +516,7 @@ int find_esp_and_warn_at(
int find_esp_and_warn(
const char *root,
const char *path,
- bool unprivileged_mode,
+ int unprivileged_mode,
char **ret_path,
uint32_t *ret_part,
uint64_t *ret_pstart,
@@ -560,12 +567,13 @@ int find_esp_and_warn(
static int verify_xbootldr_blkid(
dev_t devid,
- bool searching,
+ VerifyESPFlags flags,
sd_id128_t *ret_uuid) {
sd_id128_t uuid = SD_ID128_NULL;
#if HAVE_BLKID
+ bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING);
_cleanup_(blkid_free_probep) blkid_probe b = NULL;
_cleanup_free_ char *node = NULL;
const char *type, *v;
@@ -644,9 +652,10 @@ static int verify_xbootldr_blkid(
static int verify_xbootldr_udev(
dev_t devid,
- bool searching,
+ VerifyESPFlags flags,
sd_id128_t *ret_uuid) {
+ bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING);
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
sd_id128_t uuid = SD_ID128_NULL;
const char *node, *type, *v;
@@ -718,15 +727,16 @@ static int verify_xbootldr_udev(
static int verify_xbootldr(
int rfd,
const char *path,
- bool searching,
- bool unprivileged_mode,
+ VerifyESPFlags flags,
char **ret_path,
sd_id128_t *ret_uuid,
dev_t *ret_devid) {
_cleanup_free_ char *p = NULL;
_cleanup_close_ int pfd = -EBADF;
- bool relax_checks;
+ bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING),
+ unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE),
+ relax_checks;
dev_t devid = 0;
int r;
@@ -743,7 +753,7 @@ static int verify_xbootldr(
getenv_bool("SYSTEMD_RELAX_XBOOTLDR_CHECKS") > 0 ||
detect_container() > 0;
- r = verify_fsroot_dir(pfd, p, searching, unprivileged_mode, relax_checks ? NULL : &devid);
+ r = verify_fsroot_dir(pfd, p, flags, relax_checks ? NULL : &devid);
if (r < 0)
return r;
@@ -751,9 +761,9 @@ static int verify_xbootldr(
goto finish;
if (unprivileged_mode)
- r = verify_xbootldr_udev(devid, searching, ret_uuid);
+ r = verify_xbootldr_udev(devid, flags, ret_uuid);
else
- r = verify_xbootldr_blkid(devid, searching, ret_uuid);
+ r = verify_xbootldr_blkid(devid, flags, ret_uuid);
if (r < 0)
return r;
@@ -778,19 +788,25 @@ finish:
int find_xbootldr_and_warn_at(
int rfd,
const char *path,
- bool unprivileged_mode,
+ int unprivileged_mode,
char **ret_path,
sd_id128_t *ret_uuid,
dev_t *ret_devid) {
+ VerifyESPFlags flags = 0;
int r;
/* Similar to find_esp_and_warn(), but finds the XBOOTLDR partition. Returns the same errors. */
assert(rfd >= 0 || rfd == AT_FDCWD);
+ if (unprivileged_mode < 0)
+ unprivileged_mode = geteuid() != 0;
+ if (unprivileged_mode)
+ flags |= VERIFY_ESP_UNPRIVILEGED_MODE;
+
if (path)
- return verify_xbootldr(rfd, path, /* searching= */ false, unprivileged_mode, ret_path, ret_uuid, ret_devid);
+ return verify_xbootldr(rfd, path, flags, ret_path, ret_uuid, ret_devid);
path = getenv("SYSTEMD_XBOOTLDR_PATH");
if (path) {
@@ -822,7 +838,7 @@ int find_xbootldr_and_warn_at(
return 0;
}
- r = verify_xbootldr(rfd, "/boot", /* searching= */ true, unprivileged_mode, ret_path, ret_uuid, ret_devid);
+ r = verify_xbootldr(rfd, "/boot", flags | VERIFY_ESP_SEARCHING, ret_path, ret_uuid, ret_devid);
if (r < 0) {
if (!IN_SET(r, -ENOENT, -EADDRNOTAVAIL, -ENOTDIR)) /* This one is not it */
return r;
@@ -836,7 +852,7 @@ int find_xbootldr_and_warn_at(
int find_xbootldr_and_warn(
const char *root,
const char *path,
- bool unprivileged_mode,
+ int unprivileged_mode,
char **ret_path,
sd_id128_t *ret_uuid,
dev_t *ret_devid) {
diff --git a/src/shared/find-esp.h b/src/shared/find-esp.h
index 94f320195b..2e132a74aa 100644
--- a/src/shared/find-esp.h
+++ b/src/shared/find-esp.h
@@ -8,8 +8,8 @@
#include "sd-id128.h"
-int find_esp_and_warn_at(int rfd, const char *path, bool unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
-int find_esp_and_warn(const char *root, const char *path, bool unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
+int find_esp_and_warn_at(int rfd, const char *path, int unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
+int find_esp_and_warn(const char *root, const char *path, int unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
-int find_xbootldr_and_warn_at(int rfd, const char *path, bool unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid);
-int find_xbootldr_and_warn(const char *root, const char *path, bool unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid);
+int find_xbootldr_and_warn_at(int rfd, const char *path, int unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid);
+int find_xbootldr_and_warn(const char *root, const char *path, int unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid);
diff --git a/src/shared/hwdb-util.c b/src/shared/hwdb-util.c
index 785611f8c4..a2fbcd7078 100644
--- a/src/shared/hwdb-util.c
+++ b/src/shared/hwdb-util.c
@@ -11,7 +11,7 @@
#include "fs-util.h"
#include "hwdb-internal.h"
#include "hwdb-util.h"
-#include "label.h"
+#include "label-util.h"
#include "mkdir-label.h"
#include "nulstr-util.h"
#include "path-util.h"
diff --git a/src/shared/label.c b/src/shared/label-util.c
index 66fcc0a31f..3316c9ed37 100644
--- a/src/shared/label.c
+++ b/src/shared/label-util.c
@@ -7,6 +7,7 @@
#include "btrfs-util.h"
#include "fs-util.h"
#include "label.h"
+#include "label-util.h"
#include "macro.h"
#include "selinux-util.h"
#include "smack-util.h"
@@ -115,3 +116,15 @@ int btrfs_subvol_make_label(const char *path) {
return mac_smack_fix(path, 0);
}
+
+int mac_init(void) {
+ int r;
+
+ assert(!(mac_selinux_use() && mac_smack_use()));
+
+ r = mac_selinux_init();
+ if (r < 0)
+ return r;
+
+ return mac_smack_init();
+}
diff --git a/src/shared/label.h b/src/shared/label-util.h
index 2f899e2bdd..2f8c539618 100644
--- a/src/shared/label.h
+++ b/src/shared/label-util.h
@@ -24,3 +24,5 @@ static inline int symlink_atomic_label(const char *from, const char *to) {
int mknod_label(const char *pathname, mode_t mode, dev_t dev);
int btrfs_subvol_make_label(const char *path);
+
+int mac_init(void);
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
index 5418871093..3e51c93ede 100644
--- a/src/shared/loop-util.c
+++ b/src/shared/loop-util.c
@@ -677,9 +677,9 @@ int loop_device_make_by_path_at(
direct_flags = FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) ? O_DIRECT : 0;
rdwr_flags = open_flags >= 0 ? open_flags : O_RDWR;
- fd = xopenat(dir_fd, path, basic_flags|direct_flags|rdwr_flags, 0);
+ fd = xopenat(dir_fd, path, basic_flags|direct_flags|rdwr_flags, /* xopen_flags = */ 0, /* mode = */ 0);
if (fd < 0 && direct_flags != 0) /* If we had O_DIRECT on, and things failed with that, let's immediately try again without */
- fd = xopenat(dir_fd, path, basic_flags|rdwr_flags, 0);
+ fd = xopenat(dir_fd, path, basic_flags|rdwr_flags, /* xopen_flags = */ 0, /* mode = */ 0);
else
direct = direct_flags != 0;
if (fd < 0) {
@@ -689,9 +689,9 @@ int loop_device_make_by_path_at(
if (open_flags >= 0 || !(ERRNO_IS_PRIVILEGE(r) || r == -EROFS))
return r;
- fd = xopenat(dir_fd, path, basic_flags|direct_flags|O_RDONLY, 0);
+ fd = xopenat(dir_fd, path, basic_flags|direct_flags|O_RDONLY, /* xopen_flags = */ 0, /* mode = */ 0);
if (fd < 0 && direct_flags != 0) /* as above */
- fd = xopenat(dir_fd, path, basic_flags|O_RDONLY, 0);
+ fd = xopenat(dir_fd, path, basic_flags|O_RDONLY, /* xopen_flags = */ 0, /* mode = */ 0);
else
direct = direct_flags != 0;
if (fd < 0)
@@ -818,7 +818,8 @@ static LoopDevice* loop_device_free(LoopDevice *d) {
/* Now that the block device is released, let's also try to remove it */
if (control >= 0) {
- useconds_t delay = 5 * USEC_PER_MSEC;
+ useconds_t delay = 5 * USEC_PER_MSEC; /* A total delay of 5090 ms between 39 attempts,
+ * (4*5 + 5*10 + 5*20 + … + 3*640) = 5090. */
for (unsigned attempt = 1;; attempt++) {
if (ioctl(control, LOOP_CTL_REMOVE, d->nr) >= 0)
diff --git a/src/shared/loopback-setup.c b/src/shared/loopback-setup.c
index 5dbc4b1af2..a02baf8399 100644
--- a/src/shared/loopback-setup.c
+++ b/src/shared/loopback-setup.c
@@ -114,9 +114,15 @@ static int add_ipv6_address(sd_netlink *rtnl, struct state *s) {
if (r < 0)
return r;
- r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
+ uint32_t flags = IFA_F_PERMANENT|IFA_F_NOPREFIXROUTE;
+ r = sd_rtnl_message_addr_set_flags(req, flags & 0xffu); /* rtnetlink wants low 8 bit of flags via regular flags field… */
if (r < 0)
return r;
+ if ((flags & ~0xffu) != 0) {
+ r = sd_netlink_message_append_u32(req, IFA_FLAGS, flags); /* …and the rest of the flags via IFA_FLAGS */
+ if (r < 0)
+ return r;
+ }
r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_HOST);
if (r < 0)
@@ -134,22 +140,22 @@ static int add_ipv6_address(sd_netlink *rtnl, struct state *s) {
return 0;
}
-static bool check_loopback(sd_netlink *rtnl) {
+static int check_loopback(sd_netlink *rtnl) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
unsigned flags;
int r;
r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, LOOPBACK_IFINDEX);
if (r < 0)
- return false;
+ return r;
r = sd_netlink_call(rtnl, req, USEC_INFINITY, &reply);
if (r < 0)
- return false;
+ return r;
r = sd_rtnl_message_link_get_flags(reply, &flags);
if (r < 0)
- return false;
+ return r;
return flags & IFF_UP;
}
@@ -170,9 +176,11 @@ int loopback_setup(void) {
};
int r;
+ /* Note, we, generally assume callers ignore the return code here (except test cases), hence only log add LOG_WARN level. */
+
r = sd_netlink_open(&rtnl);
if (r < 0)
- return log_error_errno(r, "Failed to open netlink: %m");
+ return log_warning_errno(r, "Failed to open netlink, ignoring: %m");
/* Note that we add the IP addresses here explicitly even though the kernel does that too implicitly when
* setting up the loopback device. The reason we do this here a second time (and possibly race against the
@@ -182,35 +190,42 @@ int loopback_setup(void) {
r = add_ipv4_address(rtnl, &state_4);
if (r < 0)
- return log_error_errno(r, "Failed to enqueue IPv4 loopback address add request: %m");
+ return log_warning_errno(r, "Failed to enqueue IPv4 loopback address add request, ignoring: %m");
r = add_ipv6_address(rtnl, &state_6);
if (r < 0)
- return log_error_errno(r, "Failed to enqueue IPv6 loopback address add request: %m");
+ return log_warning_errno(r, "Failed to enqueue IPv6 loopback address add request, ignoring: %m");
r = start_loopback(rtnl, &state_up);
if (r < 0)
- return log_error_errno(r, "Failed to enqueue loopback interface start request: %m");
+ return log_warning_errno(r, "Failed to enqueue loopback interface start request, ignoring: %m");
while (state_4.n_messages + state_6.n_messages + state_up.n_messages > 0) {
r = sd_netlink_wait(rtnl, LOOPBACK_SETUP_TIMEOUT_USEC);
if (r < 0)
- return log_error_errno(r, "Failed to wait for netlink event: %m");
+ return log_warning_errno(r, "Failed to wait for netlink event, ignoring: %m");
r = sd_netlink_process(rtnl, NULL);
if (r < 0)
- return log_warning_errno(r, "Failed to process netlink event: %m");
+ return log_warning_errno(r, "Failed to process netlink event, ignoring: %m");
}
/* Note that we don't really care whether the addresses could be added or not */
if (state_up.rcode != 0) {
- /* If we lack the permissions to configure the loopback device,
- * but we find it to be already configured, let's exit cleanly,
- * in order to supported unprivileged containers. */
- if (ERRNO_IS_PRIVILEGE(state_up.rcode) && check_loopback(rtnl))
- return 0;
- return log_warning_errno(state_up.rcode, "Failed to configure loopback network device: %m");
+ /* If we lack the permissions to configure the loopback device, but we find it to be already
+ * configured, let's exit cleanly, in order to supported unprivileged containers. */
+ if (ERRNO_IS_PRIVILEGE(state_up.rcode)) {
+ r = check_loopback(rtnl);
+ if (r < 0)
+ log_debug_errno(r, "Failed to check if loopback device might already be up, ignoring: %m");
+ else if (r > 0) {
+ log_debug("Configuring loopback failed, but device is already up, suppressing failure.");
+ return 0;
+ }
+ }
+
+ return log_warning_errno(state_up.rcode, "Failed to configure loopback network device, ignoring: %m");
}
return 0;
diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c
index fb0b2f5adc..b372de40a3 100644
--- a/src/shared/machine-pool.c
+++ b/src/shared/machine-pool.c
@@ -3,7 +3,7 @@
#include <errno.h>
#include "btrfs-util.h"
-#include "label.h"
+#include "label-util.h"
#include "machine-pool.h"
#include "missing_magic.h"
#include "stat-util.h"
diff --git a/src/shared/meson.build b/src/shared/meson.build
index 021ba517f8..31241bc08d 100644
--- a/src/shared/meson.build
+++ b/src/shared/meson.build
@@ -96,7 +96,7 @@ shared_sources = files(
'kernel-image.c',
'keyring-util.c',
'killall.c',
- 'label.c',
+ 'label-util.c',
'libcrypt-util.c',
'libfido2-util.c',
'libmount-util.c',
diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c
index 6162a58d9a..fd14cd8598 100644
--- a/src/shared/mount-setup.c
+++ b/src/shared/mount-setup.c
@@ -17,7 +17,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
-#include "label.h"
+#include "label-util.h"
#include "log.h"
#include "macro.h"
#include "mkdir-label.h"
diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c
index 7a06cc75ae..81b681afa7 100644
--- a/src/shared/mount-util.c
+++ b/src/shared/mount-util.c
@@ -22,7 +22,7 @@
#include "glyph-util.h"
#include "hashmap.h"
#include "initrd-util.h"
-#include "label.h"
+#include "label-util.h"
#include "libmount-util.h"
#include "missing_mount.h"
#include "missing_syscall.h"
diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c
index cc00a85952..a38a56f434 100644
--- a/src/shared/selinux-util.c
+++ b/src/shared/selinux-util.c
@@ -20,6 +20,7 @@
#include "alloc-util.h"
#include "errno-util.h"
#include "fd-util.h"
+#include "label.h"
#include "log.h"
#include "macro.h"
#include "mallinfo-util.h"
@@ -54,6 +55,15 @@ static bool have_status_page = false;
: -ERRNO_VALUE(_e); \
_enforcing ? _r : 0; \
})
+
+static int mac_selinux_label_pre(int dir_fd, const char *path, mode_t mode) {
+ return mac_selinux_create_file_prepare_at(dir_fd, path, mode);
+}
+
+static int mac_selinux_label_post(int dir_fd, const char *path) {
+ mac_selinux_create_file_clear();
+ return 0;
+}
#endif
bool mac_selinux_use(void) {
@@ -128,6 +138,10 @@ static int open_label_db(void) {
int mac_selinux_init(void) {
#if HAVE_SELINUX
+ static const LabelOps label_ops = {
+ .pre = mac_selinux_label_pre,
+ .post = mac_selinux_label_post,
+ };
int r;
if (initialized)
@@ -152,6 +166,10 @@ int mac_selinux_init(void) {
return r;
}
+ r = label_ops_set(&label_ops);
+ if (r < 0)
+ return r;
+
/* Save the current policyload sequence number, so mac_selinux_maybe_reload() does not trigger on
* first call without any actual change. */
last_policyload = selinux_status_policyload();
diff --git a/src/shared/selinux-util.h b/src/shared/selinux-util.h
index e9771a28fe..238550ef52 100644
--- a/src/shared/selinux-util.h
+++ b/src/shared/selinux-util.h
@@ -7,7 +7,7 @@
#include <sys/types.h>
#include "macro.h"
-#include "label.h"
+#include "label-util.h"
#if HAVE_SELINUX
#include <selinux/selinux.h>
diff --git a/src/shared/smack-util.c b/src/shared/smack-util.c
index 8c28dd91d7..1f88e724d0 100644
--- a/src/shared/smack-util.c
+++ b/src/shared/smack-util.c
@@ -15,6 +15,7 @@
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
+#include "label.h"
#include "log.h"
#include "macro.h"
#include "path-util.h"
@@ -288,3 +289,23 @@ int renameat_and_apply_smack_floor_label(int fdf, const char *from, int fdt, con
return 0;
#endif
}
+
+static int mac_smack_label_pre(int dir_fd, const char *path, mode_t mode) {
+ return 0;
+}
+
+static int mac_smack_label_post(int dir_fd, const char *path) {
+ return mac_smack_fix_full(dir_fd, path, NULL, 0);
+}
+
+int mac_smack_init(void) {
+ static const LabelOps label_ops = {
+ .pre = mac_smack_label_pre,
+ .post = mac_smack_label_post,
+ };
+
+ if (!mac_smack_use())
+ return 0;
+
+ return label_ops_set(&label_ops);
+}
diff --git a/src/shared/smack-util.h b/src/shared/smack-util.h
index 17b31c6c25..f6ed2ece38 100644
--- a/src/shared/smack-util.h
+++ b/src/shared/smack-util.h
@@ -10,7 +10,7 @@
#include <stdbool.h>
#include <sys/types.h>
-#include "label.h"
+#include "label-util.h"
#include "macro.h"
#define SMACK_FLOOR_LABEL "_"
@@ -28,6 +28,7 @@ typedef enum SmackAttr {
} SmackAttr;
bool mac_smack_use(void);
+int mac_smack_init(void);
int mac_smack_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags);
static inline int mac_smack_fix(const char *path, LabelFixFlags flags) {
diff --git a/src/systemctl/systemctl-edit.c b/src/systemctl/systemctl-edit.c
index 561b01a67a..aff823d773 100644
--- a/src/systemctl/systemctl-edit.c
+++ b/src/systemctl/systemctl-edit.c
@@ -333,7 +333,7 @@ int verb_edit(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h
index 24e67663b9..4af540400d 100644
--- a/src/systemd/sd-journal.h
+++ b/src/systemd/sd-journal.h
@@ -93,6 +93,7 @@ void sd_journal_close(sd_journal *j);
int sd_journal_previous(sd_journal *j);
int sd_journal_next(sd_journal *j);
+int sd_journal_step_one(sd_journal *j, int advanced);
int sd_journal_previous_skip(sd_journal *j, uint64_t skip);
int sd_journal_next_skip(sd_journal *j, uint64_t skip);
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 12adad516e..cfa4823df7 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -2178,7 +2178,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/test/test-dlopen.c b/src/test/test-dlopen.c
index 35981ebc3b..9c315373b4 100644
--- a/src/test/test-dlopen.c
+++ b/src/test/test-dlopen.c
@@ -6,10 +6,14 @@
#include "macro.h"
int main(int argc, char **argv) {
- void *handle;
+ void *handles[argc - 1];
+ int i;
- assert_se(handle = dlopen(argv[1], RTLD_NOW));
- assert_se(dlclose(handle) == 0);
+ for (i = 0; i < argc - 1; i++)
+ assert_se(handles[i] = dlopen(argv[i + 1], RTLD_NOW));
+
+ for (i--; i >= 0; i--)
+ assert_se(dlclose(handles[i]) == 0);
return EXIT_SUCCESS;
}
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index ae6227c492..a07c837e3f 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -206,6 +206,17 @@ static bool is_inaccessible_available(void) {
return true;
}
+static void start_parent_slices(Unit *unit) {
+ Unit *slice;
+
+ slice = UNIT_GET_SLICE(unit);
+ if (slice) {
+ start_parent_slices(slice);
+ int r = unit_start(slice, NULL);
+ assert_se(r >= 0 || r == -EALREADY);
+ }
+}
+
static void _test(const char *file, unsigned line, const char *func,
Manager *m, const char *unit_name, int status_expected, int code_expected) {
Unit *unit;
@@ -213,6 +224,9 @@ static void _test(const char *file, unsigned line, const char *func,
assert_se(unit_name);
assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0);
+ /* We need to start the slices as well otherwise the slice cgroups might be pruned
+ * in on_cgroup_empty_event. */
+ start_parent_slices(unit);
assert_se(unit_start(unit, NULL) >= 0);
check_main_result(file, line, func, m, unit, status_expected, code_expected);
}
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index fa33b807b2..873052e24d 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -680,26 +680,26 @@ TEST(xopenat) {
/* Test that xopenat() creates directories if O_DIRECTORY is specified. */
- assert_se((fd = xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_EXCL|O_CLOEXEC, 0755)) >= 0);
+ assert_se((fd = xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_EXCL|O_CLOEXEC, 0, 0755)) >= 0);
assert_se((fd_verify_directory(fd) >= 0));
fd = safe_close(fd);
- assert_se(xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_EXCL|O_CLOEXEC, 0755) == -EEXIST);
+ assert_se(xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_EXCL|O_CLOEXEC, 0, 0755) == -EEXIST);
- assert_se((fd = xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_CLOEXEC, 0755)) >= 0);
+ assert_se((fd = xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_CLOEXEC, 0, 0755)) >= 0);
assert_se((fd_verify_directory(fd) >= 0));
fd = safe_close(fd);
/* Test that xopenat() creates regular files if O_DIRECTORY is not specified. */
- assert_se((fd = xopenat(tfd, "def", O_CREAT|O_EXCL|O_CLOEXEC, 0644)) >= 0);
+ assert_se((fd = xopenat(tfd, "def", O_CREAT|O_EXCL|O_CLOEXEC, 0, 0644)) >= 0);
assert_se(fd_verify_regular(fd) >= 0);
fd = safe_close(fd);
/* Test that we can reopen an existing fd with xopenat() by specifying an empty path. */
- assert_se((fd = xopenat(tfd, "def", O_PATH|O_CLOEXEC, 0)) >= 0);
- assert_se((fd2 = xopenat(fd, "", O_RDWR|O_CLOEXEC, 0644)) >= 0);
+ assert_se((fd = xopenat(tfd, "def", O_PATH|O_CLOEXEC, 0, 0)) >= 0);
+ assert_se((fd2 = xopenat(fd, "", O_RDWR|O_CLOEXEC, 0, 0644)) >= 0);
}
TEST(xopenat_lock) {
@@ -713,11 +713,11 @@ TEST(xopenat_lock) {
* and close the file descriptor and still properly create the directory and acquire the lock in
* another process. */
- fd = xopenat_lock(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0755, LOCK_BSD, LOCK_EX);
+ fd = xopenat_lock(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX);
assert_se(fd >= 0);
assert_se(faccessat(tfd, "abc", F_OK, 0) >= 0);
assert_se(fd_verify_directory(fd) >= 0);
- assert_se(xopenat_lock(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN);
+ assert_se(xopenat_lock(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN);
pid_t pid = fork();
assert_se(pid >= 0);
@@ -725,11 +725,11 @@ TEST(xopenat_lock) {
if (pid == 0) {
safe_close(fd);
- fd = xopenat_lock(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0755, LOCK_BSD, LOCK_EX);
+ fd = xopenat_lock(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX);
assert_se(fd >= 0);
assert_se(faccessat(tfd, "abc", F_OK, 0) >= 0);
assert_se(fd_verify_directory(fd) >= 0);
- assert_se(xopenat_lock(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN);
+ assert_se(xopenat_lock(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN);
_exit(EXIT_SUCCESS);
}
@@ -748,8 +748,8 @@ TEST(xopenat_lock) {
assert_se(wait_for_terminate(pid, &si) >= 0);
assert_se(si.si_code == CLD_EXITED);
- assert_se(xopenat_lock(tfd, "abc", 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF);
- assert_se(xopenat_lock(tfd, "def", O_DIRECTORY, 0755, LOCK_POSIX, LOCK_EX) == -EBADF);
+ assert_se(xopenat_lock(tfd, "abc", 0, 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF);
+ assert_se(xopenat_lock(tfd, "def", O_DIRECTORY, 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF);
}
static int intro(void) {
diff --git a/src/test/test-loopback.c b/src/test/test-loopback.c
index 58d8c29dbb..c18f07cfed 100644
--- a/src/test/test-loopback.c
+++ b/src/test/test-loopback.c
@@ -1,20 +1,44 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include <sched.h>
#include <stdio.h>
#include <string.h>
+#include "errno-util.h"
#include "log.h"
#include "loopback-setup.h"
#include "tests.h"
-int main(int argc, char* argv[]) {
+TEST_RET(loopback_setup) {
int r;
- test_setup_logging(LOG_DEBUG);
+ if (unshare(CLONE_NEWUSER | CLONE_NEWNET) < 0) {
+ if (ERRNO_IS_PRIVILEGE(errno) || ERRNO_IS_NOT_SUPPORTED(errno)) {
+ log_notice("Skipping test, lacking privileges or namespaces not supported");
+ return EXIT_TEST_SKIP;
+ }
+ return log_error_errno(errno, "Failed to create user+network namespace: %m");
+ }
r = loopback_setup();
if (r < 0)
- log_error_errno(r, "loopback: %m");
+ return log_error_errno(r, "loopback: %m");
- return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ log_info("> ipv6 main");
+ system("ip -6 route show table main");
+ log_info("> ipv6 local");
+ system("ip -6 route show table local");
+ log_info("> ipv4 main");
+ system("ip -4 route show table main");
+ log_info("> ipv4 local");
+ system("ip -4 route show table local");
+
+ return EXIT_SUCCESS;
+}
+
+static int intro(void) {
+ log_show_color(true);
+ return EXIT_SUCCESS;
}
+
+DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);
diff --git a/src/test/udev-rule-runner.c b/src/test/udev-rule-runner.c
index 0b5938802a..f7ba143325 100644
--- a/src/test/udev-rule-runner.c
+++ b/src/test/udev-rule-runner.c
@@ -117,7 +117,7 @@ static int run(int argc, char *argv[]) {
log_debug("version %s", GIT_VERSION);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index ad483301ef..ad1d492d6b 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -392,7 +392,7 @@ static int context_write_data_local_rtc(Context *c) {
}
}
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index e16f26d8d5..1cb8f06b3e 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -41,7 +41,7 @@
#include "glob-util.h"
#include "hexdecoct.h"
#include "io-util.h"
-#include "label.h"
+#include "label-util.h"
#include "log.h"
#include "macro.h"
#include "main-func.h"
@@ -800,7 +800,11 @@ static int dir_cleanup(
cutoff_nsec, sub_path, age_by_file, false))
continue;
- fd = xopenat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME, 0);
+ fd = xopenat(dirfd(d),
+ de->d_name,
+ O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME,
+ /* xopen_flags = */ 0,
+ /* mode = */ 0);
if (fd < 0 && fd != -ENOENT)
log_warning_errno(fd, "Opening file \"%s\" failed, ignoring: %m", sub_path);
if (fd >= 0 && flock(fd, LOCK_EX|LOCK_NB) < 0 && errno == EAGAIN) {
@@ -4326,7 +4330,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
index e49e959cd8..098e8ed0cc 100644
--- a/src/udev/udev-node.c
+++ b/src/udev/udev-node.c
@@ -15,7 +15,7 @@
#include "format-util.h"
#include "fs-util.h"
#include "hexdecoct.h"
-#include "label.h"
+#include "label-util.h"
#include "mkdir-label.h"
#include "parse-util.h"
#include "path-util.h"
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
index b803f7bb0f..51dc041a29 100644
--- a/src/udev/udevadm.c
+++ b/src/udev/udevadm.c
@@ -130,7 +130,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index b3aabcaa1f..cf00576cfb 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -2019,7 +2019,7 @@ int run_udevd(int argc, char *argv[]) {
/* set umask before creating any file/directory */
umask(022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index 6518830717..f448b3b1d1 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -48,7 +48,7 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return EXIT_FAILURE;
diff --git a/src/user-sessions/user-sessions.c b/src/user-sessions/user-sessions.c
index 37867ee3ed..58054f89fb 100644
--- a/src/user-sessions/user-sessions.c
+++ b/src/user-sessions/user-sessions.c
@@ -25,7 +25,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;