diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index 20bbae44871..2db2c2e1aa6 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -3333,7 +3333,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
- readonly b BindJournalSockets = ...;
+ readonly b BindLogSockets = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -3934,7 +3934,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
-
+
@@ -4646,7 +4646,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
-
+
@@ -5474,7 +5474,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
- readonly b BindJournalSockets = ...;
+ readonly b BindLogSockets = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -6087,7 +6087,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
-
+
@@ -6773,7 +6773,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
-
+
@@ -7465,7 +7465,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
- readonly b BindJournalSockets = ...;
+ readonly b BindLogSockets = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -8004,7 +8004,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
-
+
@@ -8602,7 +8602,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
-
+
@@ -9417,7 +9417,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
- readonly b BindJournalSockets = ...;
+ readonly b BindLogSockets = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -9942,7 +9942,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
-
+
@@ -10526,7 +10526,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
-
+
@@ -12175,7 +12175,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
LiveMountResult,
PrivateTmpEx,
ImportCredentialEx, and
- BindJournalSockets were added in version 257.
+ BindLogSockets were added in version 257.
Socket Unit Objects
@@ -12214,7 +12214,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
PassFileDescriptorsToExec were added in version 256.
PrivateTmpEx,
ImportCredentialEx, and
- BindJournalSockets were added in version 257.
+ BindLogSockets were added in version 257.
Mount Unit Objects
@@ -12250,7 +12250,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
MemoryZSwapWriteback were added in version 256.
PrivateTmpEx,
ImportCredentialEx, and
- BindJournalSockets were added in version 257.
+ BindLogSockets were added in version 257.
Swap Unit Objects
@@ -12286,7 +12286,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
MemoryZSwapWriteback were added in version 256.
PrivateTmpEx,
ImportCredentialEx, and
- BindJournalSockets were added in version 257.
+ BindLogSockets were added in version 257.
Slice Unit Objects
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 03189615692..232ae7e96ec 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -367,7 +367,7 @@
- BindJournalSockets=
+ BindLogSockets=
Takes a boolean argument. If true, sockets from
systemd-journald.socket8
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 4679f54a3e6..6023436b90a 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -55,7 +55,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system,
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long);
static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
static BUS_DEFINE_PROPERTY_GET(property_get_mount_apivfs, "b", ExecContext, exec_context_get_effective_mount_apivfs);
-static BUS_DEFINE_PROPERTY_GET(property_get_bind_journal_sockets, "b", ExecContext, exec_context_get_effective_bind_journal_sockets);
+static BUS_DEFINE_PROPERTY_GET(property_get_bind_log_sockets, "b", ExecContext, exec_context_get_effective_bind_log_sockets);
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_class);
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_data);
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
@@ -1194,7 +1194,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MountAPIVFS", "b", property_get_mount_apivfs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("BindJournalSockets", "b", property_get_bind_journal_sockets, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("BindLogSockets", "b", property_get_bind_log_sockets, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1866,8 +1866,8 @@ int bus_exec_context_set_transient_property(
if (streq(name, "MountAPIVFS"))
return bus_set_transient_tristate(u, name, &c->mount_apivfs, message, flags, error);
- if (streq(name, "BindJournalSockets"))
- return bus_set_transient_tristate(u, name, &c->bind_journal_sockets, message, flags, error);
+ if (streq(name, "BindLogSockets"))
+ return bus_set_transient_tristate(u, name, &c->bind_log_sockets, message, flags, error);
if (streq(name, "PrivateNetwork"))
return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);
diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c
index 1a2595c8bf4..f1d25b31126 100644
--- a/src/core/exec-invoke.c
+++ b/src/core/exec-invoke.c
@@ -2641,23 +2641,9 @@ static int compile_bind_mounts(
return -ENOMEM;
FOREACH_ARRAY(item, context->bind_mounts, context->n_bind_mounts) {
- _cleanup_free_ char *s = NULL, *d = NULL;
-
- s = strdup(item->source);
- if (!s)
- return -ENOMEM;
-
- d = strdup(item->destination);
- if (!d)
- return -ENOMEM;
-
- bind_mounts[h++] = (BindMount) {
- .source = TAKE_PTR(s),
- .destination = TAKE_PTR(d),
- .read_only = item->read_only,
- .recursive = item->recursive,
- .ignore_enoent = item->ignore_enoent,
- };
+ r = bind_mount_add(&bind_mounts, &h, item);
+ if (r < 0)
+ return r;
}
for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
@@ -3235,7 +3221,7 @@ static int apply_mount_namespace(
.private_tmp = needs_sandboxing ? context->private_tmp : false,
.mount_apivfs = needs_sandboxing && exec_context_get_effective_mount_apivfs(context),
- .bind_journal_sockets = needs_sandboxing && exec_context_get_effective_bind_journal_sockets(context),
+ .bind_log_sockets = needs_sandboxing && exec_context_get_effective_bind_log_sockets(context),
/* If NNP is on, we can turn on MS_NOSUID, since it won't have any effect anymore. */
.mount_nosuid = needs_sandboxing && context->no_new_privileges && !mac_selinux_use(),
@@ -3857,7 +3843,7 @@ static bool exec_context_need_unprivileged_private_users(
context->ipc_namespace_path ||
context->private_mounts > 0 ||
context->mount_apivfs > 0 ||
- context->bind_journal_sockets > 0 ||
+ context->bind_log_sockets > 0 ||
context->n_bind_mounts > 0 ||
context->n_temporary_filesystems > 0 ||
context->root_directory ||
diff --git a/src/core/execute-serialize.c b/src/core/execute-serialize.c
index 32d6118ab70..9f287dc12b3 100644
--- a/src/core/execute-serialize.c
+++ b/src/core/execute-serialize.c
@@ -1854,7 +1854,7 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) {
if (r < 0)
return r;
- r = serialize_item_tristate(f, "exec-context-bind-journal-sockets", c->bind_journal_sockets);
+ r = serialize_item_tristate(f, "exec-context-bind-log-sockets", c->bind_log_sockets);
if (r < 0)
return r;
@@ -2730,8 +2730,8 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
r = safe_atoi(val, &c->mount_apivfs);
if (r < 0)
return r;
- } else if ((val = startswith(l, "exec-context-bind-journal-sockets="))) {
- r = safe_atoi(val, &c->bind_journal_sockets);
+ } else if ((val = startswith(l, "exec-context-bind-log-sockets="))) {
+ r = safe_atoi(val, &c->bind_log_sockets);
if (r < 0)
return r;
} else if ((val = startswith(l, "exec-context-memory-ksm="))) {
diff --git a/src/core/execute.c b/src/core/execute.c
index 7a365e23b91..fdbe1e3210e 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -284,7 +284,7 @@ bool exec_needs_mount_namespace(
context->directories[EXEC_DIRECTORY_LOGS].n_items > 0))
return true;
- if (exec_context_get_effective_bind_journal_sockets(context))
+ if (exec_context_get_effective_bind_log_sockets(context))
return true;
return false;
@@ -539,7 +539,7 @@ void exec_context_init(ExecContext *c) {
.tty_cols = UINT_MAX,
.private_mounts = -1,
.mount_apivfs = -1,
- .bind_journal_sockets = -1,
+ .bind_log_sockets = -1,
.memory_ksm = -1,
.set_login_environment = -1,
};
@@ -980,7 +980,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
"%sProtectHome: %s\n"
"%sProtectSystem: %s\n"
"%sMountAPIVFS: %s\n"
- "%sBindJournalSockets: %s\n"
+ "%sBindLogSockets: %s\n"
"%sIgnoreSIGPIPE: %s\n"
"%sMemoryDenyWriteExecute: %s\n"
"%sRestrictRealtime: %s\n"
@@ -1006,7 +1006,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
prefix, protect_home_to_string(c->protect_home),
prefix, protect_system_to_string(c->protect_system),
prefix, yes_no(exec_context_get_effective_mount_apivfs(c)),
- prefix, yes_no(exec_context_get_effective_bind_journal_sockets(c)),
+ prefix, yes_no(exec_context_get_effective_bind_log_sockets(c)),
prefix, yes_no(c->ignore_sigpipe),
prefix, yes_no(c->memory_deny_write_execute),
prefix, yes_no(c->restrict_realtime),
@@ -1489,16 +1489,16 @@ bool exec_context_get_effective_mount_apivfs(const ExecContext *c) {
return false;
}
-bool exec_context_get_effective_bind_journal_sockets(const ExecContext *c) {
+bool exec_context_get_effective_bind_log_sockets(const ExecContext *c) {
assert(c);
/* If log namespace is specified, "/run/systemd/journal.namespace/" would be bind mounted to
- * "/run/systemd/journal/", which effectively means BindJournalSockets=yes */
+ * "/run/systemd/journal/", which effectively means BindLogSockets=yes */
if (c->log_namespace)
return true;
- if (c->bind_journal_sockets >= 0)
- return c->bind_journal_sockets > 0;
+ if (c->bind_log_sockets >= 0)
+ return c->bind_log_sockets > 0;
if (exec_context_get_effective_mount_apivfs(c))
return true;
diff --git a/src/core/execute.h b/src/core/execute.h
index 5754273999b..f9c88e9a763 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -313,7 +313,7 @@ struct ExecContext {
int private_mounts;
int mount_apivfs;
- int bind_journal_sockets;
+ int bind_log_sockets;
int memory_ksm;
PrivateTmp private_tmp;
bool private_network;
@@ -520,7 +520,7 @@ bool exec_context_maintains_privileges(const ExecContext *c);
int exec_context_get_effective_ioprio(const ExecContext *c);
bool exec_context_get_effective_mount_apivfs(const ExecContext *c);
-bool exec_context_get_effective_bind_journal_sockets(const ExecContext *c);
+bool exec_context_get_effective_bind_log_sockets(const ExecContext *c);
void exec_context_free_log_extra_fields(ExecContext *c);
diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
index 32ac87ce85f..b6a9c708e49 100644
--- a/src/core/load-fragment-gperf.gperf.in
+++ b/src/core/load-fragment-gperf.gperf.in
@@ -137,7 +137,7 @@
{{type}}.ProtectHome, config_parse_protect_home, 0, offsetof({{type}}, exec_context.protect_home)
{{type}}.MountFlags, config_parse_exec_mount_propagation_flag, 0, offsetof({{type}}, exec_context.mount_propagation_flag)
{{type}}.MountAPIVFS, config_parse_tristate, 0, offsetof({{type}}, exec_context.mount_apivfs)
-{{type}}.BindJournalSockets, config_parse_tristate, 0, offsetof({{type}}, exec_context.bind_journal_sockets)
+{{type}}.BindLogSockets, config_parse_tristate, 0, offsetof({{type}}, exec_context.bind_log_sockets)
{{type}}.Personality, config_parse_personality, 0, offsetof({{type}}, exec_context.personality)
{{type}}.RuntimeDirectoryPreserve, config_parse_exec_preserve_mode, 0, offsetof({{type}}, exec_context.runtime_directory_preserve_mode)
{{type}}.RuntimeDirectoryMode, config_parse_mode, 0, offsetof({{type}}, exec_context.directories[EXEC_DIRECTORY_RUNTIME].mode)
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 323ff4c2794..ba5163cdb8c 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -120,10 +120,10 @@ typedef struct MountList {
size_t n_mounts;
} MountList;
-static const BindMount bind_journal_sockets_table[] = {
- { (char*) "/run/systemd/journal/socket", (char*) "/run/systemd/journal/socket", .read_only = true, .ignore_enoent = true },
- { (char*) "/run/systemd/journal/stdout", (char*) "/run/systemd/journal/stdout", .read_only = true, .ignore_enoent = true },
- { (char*) "/run/systemd/journal/dev-log", (char*) "/run/systemd/journal/dev-log", .read_only = true, .ignore_enoent = true },
+static const BindMount bind_log_sockets_table[] = {
+ { (char*) "/run/systemd/journal/socket", (char*) "/run/systemd/journal/socket", .read_only = true, .nosuid = true, .noexec = true, .nodev = true, .ignore_enoent = true },
+ { (char*) "/run/systemd/journal/stdout", (char*) "/run/systemd/journal/stdout", .read_only = true, .nosuid = true, .noexec = true, .nodev = true, .ignore_enoent = true },
+ { (char*) "/run/systemd/journal/dev-log", (char*) "/run/systemd/journal/dev-log", .read_only = true, .nosuid = true, .noexec = true, .nodev = true, .ignore_enoent = true },
};
/* If MountAPIVFS= is used, let's mount /sys, /proc, /dev and /run into the it, but only as a fallback if the user hasn't mounted
@@ -447,6 +447,8 @@ static int append_bind_mounts(MountList *ml, const BindMount *binds, size_t n) {
.mode = b->recursive ? MOUNT_BIND_RECURSIVE : MOUNT_BIND,
.read_only = b->read_only,
.nosuid = b->nosuid,
+ .noexec = b->noexec,
+ .flags = b->nodev ? MS_NODEV : 0,
.source_const = b->source,
.ignore = b->ignore_enoent,
};
@@ -1146,7 +1148,9 @@ static int mount_private_dev(const MountEntry *m, const NamespaceParameters *p)
FOREACH_STRING(d, "/dev/mqueue", "/dev/hugepages")
(void) bind_mount_device_dir(temporary_mount, d);
- if ((!p->root_image && !p->root_directory) || p->bind_journal_sockets) {
+ /* We assume /run/systemd/journal/ is available if not changing root, which isn't entirely accurate
+ * but shouldn't matter, as either way the user would get ENOENT when accessing /dev/log */
+ if ((!p->root_image && !p->root_directory) || p->bind_log_sockets) {
const char *devlog = strjoina(temporary_mount, "/dev/log");
if (symlink("/run/systemd/journal/dev-log", devlog) < 0)
log_debug_errno(errno,
@@ -2597,8 +2601,8 @@ int setup_namespace(const NamespaceParameters *p, char **error_path) {
.source_malloc = TAKE_PTR(q),
};
- } else if (p->bind_journal_sockets) {
- r = append_bind_mounts(&ml, bind_journal_sockets_table, ELEMENTSOF(bind_journal_sockets_table));
+ } else if (p->bind_log_sockets) {
+ r = append_bind_mounts(&ml, bind_log_sockets_table, ELEMENTSOF(bind_log_sockets_table));
if (r < 0)
return r;
}
@@ -2777,7 +2781,6 @@ void bind_mount_free_many(BindMount *b, size_t n) {
int bind_mount_add(BindMount **b, size_t *n, const BindMount *item) {
_cleanup_free_ char *s = NULL, *d = NULL;
- BindMount *c;
assert(b);
assert(n);
@@ -2791,17 +2794,16 @@ int bind_mount_add(BindMount **b, size_t *n, const BindMount *item) {
if (!d)
return -ENOMEM;
- c = reallocarray(*b, *n + 1, sizeof(BindMount));
- if (!c)
+ if (!GREEDY_REALLOC(*b, *n + 1))
return -ENOMEM;
- *b = c;
-
- c[(*n)++] = (BindMount) {
+ (*b)[(*n)++] = (BindMount) {
.source = TAKE_PTR(s),
.destination = TAKE_PTR(d),
.read_only = item->read_only,
+ .nodev = item->nodev,
.nosuid = item->nosuid,
+ .noexec = item->noexec,
.recursive = item->recursive,
.ignore_enoent = item->ignore_enoent,
};
diff --git a/src/core/namespace.h b/src/core/namespace.h
index 538d23753c2..d961a66b4f3 100644
--- a/src/core/namespace.h
+++ b/src/core/namespace.h
@@ -65,7 +65,9 @@ struct BindMount {
char *source;
char *destination;
bool read_only;
+ bool nodev;
bool nosuid;
+ bool noexec;
bool recursive;
bool ignore_enoent;
};
@@ -152,7 +154,7 @@ struct NamespaceParameters {
bool private_ipc;
bool mount_apivfs;
- bool bind_journal_sockets;
+ bool bind_log_sockets;
bool mount_nosuid;
ProtectHome protect_home;
diff --git a/src/core/service.c b/src/core/service.c
index 663fdb30f2c..ca1f54340d0 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1130,42 +1130,37 @@ static int service_is_suitable_main_pid(Service *s, PidRef *pid, int prio) {
static int service_load_pid_file(Service *s, bool may_warn) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- bool questionable_pid_file = false;
+ _cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *k = NULL;
- _cleanup_close_ int fd = -EBADF;
- int r, prio;
+ bool questionable_pid_file = false;
+ int r, prio = may_warn ? LOG_INFO : LOG_DEBUG;
assert(s);
if (!s->pid_file)
return -ENOENT;
- prio = may_warn ? LOG_INFO : LOG_DEBUG;
-
- r = chase(s->pid_file, NULL, CHASE_SAFE, NULL, &fd);
+ r = chase_and_fopen_unlocked(s->pid_file, NULL, CHASE_SAFE, "re", NULL, &f);
if (r == -ENOLINK) {
log_unit_debug_errno(UNIT(s), r,
"Potentially unsafe symlink chain, will now retry with relaxed checks: %s", s->pid_file);
questionable_pid_file = true;
- r = chase(s->pid_file, NULL, 0, NULL, &fd);
+ r = chase_and_fopen_unlocked(s->pid_file, NULL, 0, "re", NULL, &f);
}
if (r < 0)
return log_unit_full_errno(UNIT(s), prio, r,
- "Can't open PID file %s (yet?) after %s: %m", s->pid_file, service_state_to_string(s->state));
+ "Can't open PID file '%s' (yet?) after %s: %m", s->pid_file, service_state_to_string(s->state));
- /* Let's read the PID file now that we chased it down. But we need to convert the O_PATH fd
- * chase() returned us into a proper fd first. */
- r = read_one_line_file(FORMAT_PROC_FD_PATH(fd), &k);
+ /* Let's read the PID file now that we chased it down. */
+ r = read_line(f, LINE_MAX, &k);
if (r < 0)
- return log_unit_error_errno(UNIT(s), r,
- "Can't convert PID files %s O_PATH file descriptor to proper file descriptor: %m",
- s->pid_file);
+ return log_unit_error_errno(UNIT(s), r, "Failed to read PID file '%s': %m", s->pid_file);
r = pidref_set_pidstr(&pidref, k);
if (r < 0)
- return log_unit_full_errno(UNIT(s), prio, r, "Failed to parse PID from file %s: %m", s->pid_file);
+ return log_unit_full_errno(UNIT(s), prio, r, "Failed to create reference to PID %s from file '%s': %m", k, s->pid_file);
if (s->main_pid_known && pidref_equal(&pidref, &s->main_pid))
return 0;
@@ -1182,14 +1177,14 @@ static int service_load_pid_file(Service *s, bool may_warn) {
/* Hmm, it's not clear if the new main PID is safe. Let's allow this if the PID file is owned by root */
- if (fstat(fd, &st) < 0)
- return log_unit_error_errno(UNIT(s), errno, "Failed to fstat() PID file O_PATH fd: %m");
+ if (fstat(fileno(f), &st) < 0)
+ return log_unit_error_errno(UNIT(s), errno, "Failed to fstat() PID file '%s': %m", s->pid_file);
if (st.st_uid != 0)
return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(EPERM),
- "New main PID "PID_FMT" does not belong to service, and PID file is not owned by root. Refusing.", pidref.pid);
+ "New main PID "PID_FMT" from PID file does not belong to service, and PID file is not owned by root. Refusing.", pidref.pid);
- log_unit_debug(UNIT(s), "New main PID "PID_FMT" does not belong to service, but we'll accept it since PID file is owned by root.", pidref.pid);
+ log_unit_debug(UNIT(s), "New main PID "PID_FMT" does not belong to service, accepting anyway since PID file is owned by root.", pidref.pid);
}
if (s->main_pid_known) {
@@ -1456,10 +1451,9 @@ static int service_collect_fds(
rn_socket_fds = 1;
} else {
- Unit *u;
-
/* Pass all our configured sockets for singleton services */
+ Unit *u;
UNIT_FOREACH_DEPENDENCY(u, UNIT(s), UNIT_ATOM_TRIGGERED_BY) {
_cleanup_free_ int *cfds = NULL;
int cn_fds;
@@ -1472,8 +1466,7 @@ static int service_collect_fds(
cn_fds = socket_collect_fds(sock, &cfds);
if (cn_fds < 0)
return cn_fds;
-
- if (cn_fds <= 0)
+ if (cn_fds == 0)
continue;
if (!rfds) {
@@ -2029,22 +2022,6 @@ static ServiceState service_determine_dead_state(Service *s) {
return s->fd_store && s->fd_store_preserve_mode == EXEC_PRESERVE_YES ? SERVICE_DEAD_RESOURCES_PINNED : SERVICE_DEAD;
}
-static void service_set_debug_invocation(Service *s, bool enable) {
- assert(s);
-
- if (s->restart_mode != SERVICE_RESTART_MODE_DEBUG)
- return;
-
- if (enable == UNIT(s)->debug_invocation)
- return; /* Nothing to do */
-
- UNIT(s)->debug_invocation = enable;
- unit_overwrite_log_level_max(UNIT(s), enable ? LOG_PRI(LOG_DEBUG) : s->exec_context.log_level_max);
-
- if (enable)
- log_unit_notice(UNIT(s), "Service failed, subsequent restarts will be executed with debug level logging.");
-}
-
static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
ServiceState end_state, restart_state;
int r;
@@ -2108,13 +2085,19 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
return service_enter_dead(s, SERVICE_FAILURE_RESOURCES, /* allow_restart= */ false);
}
- log_unit_debug(UNIT(s), "Next restart interval calculated as: %s", FORMAT_TIMESPAN(restart_usec_next, 0));
-
/* If the relevant option is set, and the unit doesn't already have logging level set to
* debug, enable it now. Make sure to overwrite the state in /run/systemd/units/ too, to
* ensure journald doesn't prune the messages. The previous state is saved and restored
* once the auto-restart flow ends. */
- service_set_debug_invocation(s, /* enable= */ true);
+ if (s->restart_mode == SERVICE_RESTART_MODE_DEBUG) {
+ r = unit_set_debug_invocation(UNIT(s), true);
+ if (r < 0)
+ log_unit_warning_errno(UNIT(s), r, "Failed to enable debug invocation, ignoring: %m");
+ if (r > 0)
+ log_unit_notice(UNIT(s), "Service dead, subsequent restarts will be executed with debug level logging.");
+ }
+
+ log_unit_debug(UNIT(s), "Next restart interval calculated as: %s", FORMAT_TIMESPAN(restart_usec_next, 0));
service_set_state(s, SERVICE_AUTO_RESTART);
} else {
@@ -2123,7 +2106,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
* can still introspect the counter. */
service_set_state(s, end_state);
- service_set_debug_invocation(s, /* enable= */ false);
+ (void) unit_set_debug_invocation(UNIT(s), false);
}
/* The new state is in effect, let's decrease the fd store ref counter again. Let's also re-add us to the GC
@@ -4959,7 +4942,7 @@ static void service_reset_failed(Unit *u) {
s->live_mount_result = SERVICE_SUCCESS;
s->n_restarts = 0;
- service_set_debug_invocation(s, /* enable= */ false);
+ (void) unit_set_debug_invocation(u, /* enable= */ false);
}
static PidRef* service_main_pid(Unit *u, bool *ret_is_alien) {
diff --git a/src/core/unit-serialize.c b/src/core/unit-serialize.c
index 8baa30f9e5f..f96bae19f9e 100644
--- a/src/core/unit-serialize.c
+++ b/src/core/unit-serialize.c
@@ -101,6 +101,8 @@ int unit_serialize_state(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
(void) serialize_bool(f, "transient", u->transient);
(void) serialize_bool(f, "in-audit", u->in_audit);
+ (void) serialize_bool(f, "debug-invocation", u->debug_invocation);
+
(void) serialize_bool(f, "exported-invocation-id", u->exported_invocation_id);
(void) serialize_bool(f, "exported-log-level-max", u->exported_log_level_max);
(void) serialize_bool(f, "exported-log-extra-fields", u->exported_log_extra_fields);
@@ -265,6 +267,9 @@ int unit_deserialize_state(Unit *u, FILE *f, FDSet *fds) {
else if (MATCH_DESERIALIZE("in-audit", l, v, parse_boolean, u->in_audit))
continue;
+ else if (MATCH_DESERIALIZE("debug-invocation", l, v, parse_boolean, u->debug_invocation))
+ continue;
+
else if (MATCH_DESERIALIZE("exported-invocation-id", l, v, parse_boolean, u->exported_invocation_id))
continue;
diff --git a/src/core/unit.c b/src/core/unit.c
index 4468733a636..cebae4d53e4 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -5839,14 +5839,27 @@ void unit_unlink_state_files(Unit *u) {
}
}
-int unit_overwrite_log_level_max(Unit *u, int log_level_max) {
+int unit_set_debug_invocation(Unit *u, bool enable) {
+ int r;
+
assert(u);
- if (!u->exported_log_level_max)
+ if (u->debug_invocation == enable)
return 0; /* Nothing to do */
+ u->debug_invocation = enable;
+
/* Ensure that the new log level is exported for the journal, in place of the previous one */
- return unit_export_log_level_max(u, log_level_max, /* overwrite= */ true);
+ if (u->exported_log_level_max) {
+ const ExecContext *ec = unit_get_exec_context(u);
+ if (ec) {
+ r = unit_export_log_level_max(u, enable ? LOG_PRI(LOG_DEBUG) : ec->log_level_max, /* overwrite= */ true);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ return 1;
}
int unit_prepare_exec(Unit *u) {
diff --git a/src/core/unit.h b/src/core/unit.h
index 8aac5f59992..5ffd82b67eb 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -992,7 +992,8 @@ void unit_remove_dependencies(Unit *u, UnitDependencyMask mask);
void unit_export_state_files(Unit *u);
void unit_unlink_state_files(Unit *u);
-int unit_overwrite_log_level_max(Unit *u, int log_level_max);
+
+int unit_set_debug_invocation(Unit *u, bool enable);
int unit_prepare_exec(Unit *u);
diff --git a/src/portable/profile/default/service.conf b/src/portable/profile/default/service.conf
index 07f985cefa5..35dfd778f28 100644
--- a/src/portable/profile/default/service.conf
+++ b/src/portable/profile/default/service.conf
@@ -2,7 +2,7 @@
[Service]
MountAPIVFS=yes
-BindJournalSockets=yes
+BindLogSockets=yes
BindReadOnlyPaths=/etc/machine-id
BindReadOnlyPaths=-/etc/resolv.conf
BindReadOnlyPaths=/run/dbus/system_bus_socket
diff --git a/src/portable/profile/nonetwork/service.conf b/src/portable/profile/nonetwork/service.conf
index ee7aa2d5253..e8d2a9bb1a1 100644
--- a/src/portable/profile/nonetwork/service.conf
+++ b/src/portable/profile/nonetwork/service.conf
@@ -2,7 +2,7 @@
[Service]
MountAPIVFS=yes
-BindJournalSockets=yes
+BindLogSockets=yes
BindReadOnlyPaths=/etc/machine-id
BindReadOnlyPaths=/run/dbus/system_bus_socket
DynamicUser=yes
diff --git a/src/portable/profile/strict/service.conf b/src/portable/profile/strict/service.conf
index ed14387b5d0..aa5bcfbb08e 100644
--- a/src/portable/profile/strict/service.conf
+++ b/src/portable/profile/strict/service.conf
@@ -2,7 +2,7 @@
[Service]
MountAPIVFS=yes
-BindJournalSockets=yes
+BindLogSockets=yes
BindReadOnlyPaths=/etc/machine-id
DynamicUser=yes
RemoveIPC=yes
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index edfe1482c81..6987a885d1e 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -1076,7 +1076,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
"ProtectClock",
"ProtectControlGroups",
"MountAPIVFS",
- "BindJournalSockets",
+ "BindLogSockets",
"CPUSchedulingResetOnFork",
"LockPersonality",
"ProtectHostname",
diff --git a/test/units/TEST-50-DISSECT.dissect.sh b/test/units/TEST-50-DISSECT.dissect.sh
index 5e4899788f9..15f663faf54 100755
--- a/test/units/TEST-50-DISSECT.dissect.sh
+++ b/test/units/TEST-50-DISSECT.dissect.sh
@@ -74,9 +74,9 @@ fi
systemd-dissect --umount "$IMAGE_DIR/mount"
systemd-dissect --umount "$IMAGE_DIR/mount2"
-# Test BindJournalSockets=
+# Test BindLogSockets=
systemd-run --wait -p RootImage="$MINIMAL_IMAGE.raw" mountpoint /run/systemd/journal/socket
-(! systemd-run --wait -p RootImage="$MINIMAL_IMAGE.raw" -p BindJournalSockets=no ls /run/systemd/journal/socket)
+(! systemd-run --wait -p RootImage="$MINIMAL_IMAGE.raw" -p BindLogSockets=no ls /run/systemd/journal/socket)
(! systemd-run --wait -p RootImage="$MINIMAL_IMAGE.raw" -p MountAPIVFS=no ls /run/systemd/journal/socket)
systemd-run -P -p RootImage="$MINIMAL_IMAGE.raw" cat /usr/lib/os-release | grep -q -F "MARKER=1"
@@ -86,7 +86,7 @@ systemd-run -P \
-p RootImage="$MINIMAL_IMAGE.raw" \
-p RootHash="$MINIMAL_IMAGE.foohash" \
-p RootVerity="$MINIMAL_IMAGE.fooverity" \
- -p BindJournalSockets=yes \
+ -p BindLogSockets=yes \
cat /usr/lib/os-release | grep -q -F "MARKER=1"
# Let's use the long option name just here as a test
systemd-run -P \