basebuilder_pel7x64builder0
4 years ago
41 changed files with 3670 additions and 23 deletions
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
From 4ebd0ef2af8b302bafa76383a5c182a5a749654a Mon Sep 17 00:00:00 2001 |
||||
From: Jan Synacek <jsynacek@redhat.com> |
||||
Date: Fri, 8 Nov 2019 12:46:23 +0100 |
||||
Subject: [PATCH] sd-bus: bump message queue size again |
||||
|
||||
Simliarly to issue #4068, the current limit turns out to be too small for a |
||||
big storage setup that uses many small disks. Let's bump it further. |
||||
|
||||
Resolves: #1770158 |
||||
--- |
||||
src/libsystemd/sd-bus/bus-internal.h | 4 ++-- |
||||
1 file changed, 2 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h |
||||
index 33a5569146..87c6d8cb76 100644 |
||||
--- a/src/libsystemd/sd-bus/bus-internal.h |
||||
+++ b/src/libsystemd/sd-bus/bus-internal.h |
||||
@@ -326,8 +326,8 @@ struct sd_bus { |
||||
|
||||
#define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC)) |
||||
|
||||
-#define BUS_WQUEUE_MAX (192*1024) |
||||
-#define BUS_RQUEUE_MAX (192*1024) |
||||
+#define BUS_WQUEUE_MAX (384*1024) |
||||
+#define BUS_RQUEUE_MAX (384*1024) |
||||
|
||||
#define BUS_MESSAGE_SIZE_MAX (128*1024*1024) |
||||
#define BUS_AUTH_SIZE_MAX (64*1024) |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
From 8a2dc9e983d6fb67955ae68da0a4af4248ecaf2d Mon Sep 17 00:00:00 2001 |
||||
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com> |
||||
Date: Sat, 23 Nov 2019 13:37:02 +0100 |
||||
Subject: [PATCH] unit: fix potential use of cgroup_path after free() when |
||||
freeing unit |
||||
|
||||
Resolves: #1760149 |
||||
--- |
||||
src/core/cgroup.c | 3 +-- |
||||
src/core/unit.c | 2 +- |
||||
2 files changed, 2 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/src/core/cgroup.c b/src/core/cgroup.c |
||||
index 0ce265dbf4..9af8126957 100644 |
||||
--- a/src/core/cgroup.c |
||||
+++ b/src/core/cgroup.c |
||||
@@ -874,8 +874,7 @@ void unit_destroy_cgroup_if_empty(Unit *u) { |
||||
|
||||
hashmap_remove(u->manager->cgroup_unit, u->cgroup_path); |
||||
|
||||
- free(u->cgroup_path); |
||||
- u->cgroup_path = NULL; |
||||
+ u->cgroup_path = mfree(u->cgroup_path); |
||||
u->cgroup_realized = false; |
||||
u->cgroup_realized_mask = 0; |
||||
} |
||||
diff --git a/src/core/unit.c b/src/core/unit.c |
||||
index 294c9eb70f..0dc66203a4 100644 |
||||
--- a/src/core/unit.c |
||||
+++ b/src/core/unit.c |
||||
@@ -515,7 +515,7 @@ void unit_free(Unit *u) { |
||||
|
||||
if (u->cgroup_path) { |
||||
hashmap_remove(u->manager->cgroup_unit, u->cgroup_path); |
||||
- free(u->cgroup_path); |
||||
+ u->cgroup_path = mfree(u->cgroup_path); |
||||
} |
||||
|
||||
set_remove(u->manager->failed_units, u); |
@ -0,0 +1,261 @@
@@ -0,0 +1,261 @@
|
||||
From 94da4f86eab658c14feac290663634ca29348a60 Mon Sep 17 00:00:00 2001 |
||||
From: David Tardon <dtardon@redhat.com> |
||||
Date: Thu, 3 Oct 2019 19:05:06 +0200 |
||||
Subject: [PATCH] add test for ExecStopPost |
||||
|
||||
This is a follow-up to #4843. |
||||
|
||||
(cherry picked from commit 02baf239d87295362740d961765091b778795573) |
||||
|
||||
Related: #1733998 |
||||
--- |
||||
test/TEST-42-EXECSTOPPOST/Makefile | 10 +++ |
||||
test/TEST-42-EXECSTOPPOST/test.sh | 95 ++++++++++++++++++++ |
||||
test/TEST-42-EXECSTOPPOST/testsuite.sh | 119 +++++++++++++++++++++++++ |
||||
3 files changed, 224 insertions(+) |
||||
create mode 100644 test/TEST-42-EXECSTOPPOST/Makefile |
||||
create mode 100755 test/TEST-42-EXECSTOPPOST/test.sh |
||||
create mode 100755 test/TEST-42-EXECSTOPPOST/testsuite.sh |
||||
|
||||
diff --git a/test/TEST-42-EXECSTOPPOST/Makefile b/test/TEST-42-EXECSTOPPOST/Makefile |
||||
new file mode 100644 |
||||
index 0000000000..5e89a29eff |
||||
--- /dev/null |
||||
+++ b/test/TEST-42-EXECSTOPPOST/Makefile |
||||
@@ -0,0 +1,10 @@ |
||||
+all: |
||||
+ @make -s --no-print-directory -C ../.. all |
||||
+ @basedir=../.. TEST_BASE_DIR=../ ./test.sh --all |
||||
+setup: |
||||
+ @make --no-print-directory -C ../.. all |
||||
+ @basedir=../.. TEST_BASE_DIR=../ ./test.sh --setup |
||||
+clean: |
||||
+ @basedir=../.. TEST_BASE_DIR=../ ./test.sh --clean |
||||
+run: |
||||
+ @basedir=../.. TEST_BASE_DIR=../ ./test.sh --run |
||||
diff --git a/test/TEST-42-EXECSTOPPOST/test.sh b/test/TEST-42-EXECSTOPPOST/test.sh |
||||
new file mode 100755 |
||||
index 0000000000..0958e01d68 |
||||
--- /dev/null |
||||
+++ b/test/TEST-42-EXECSTOPPOST/test.sh |
||||
@@ -0,0 +1,95 @@ |
||||
+#!/bin/bash |
||||
+TEST_DESCRIPTION="test that ExecStopPost= is always run" |
||||
+ |
||||
+. $TEST_BASE_DIR/test-functions |
||||
+ |
||||
+check_result_qemu() { |
||||
+ ret=1 |
||||
+ mkdir -p $TESTDIR/root |
||||
+ mount ${LOOPDEV}p1 $TESTDIR/root |
||||
+ [[ -e $TESTDIR/root/testok ]] && ret=0 |
||||
+ [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR |
||||
+ [[ -f $TESTDIR/root/var/log/journal ]] && cp -a $TESTDIR/root/var/log/journal $TESTDIR |
||||
+ umount $TESTDIR/root |
||||
+ [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed |
||||
+ ls -l $TESTDIR/journal/*/*.journal |
||||
+ test -s $TESTDIR/failed && ret=$(($ret+1)) |
||||
+ return $ret |
||||
+} |
||||
+ |
||||
+test_run() { |
||||
+ if run_qemu; then |
||||
+ check_result_qemu || return 1 |
||||
+ else |
||||
+ dwarn "can't run QEMU, skipping" |
||||
+ fi |
||||
+ if check_nspawn; then |
||||
+ run_nspawn |
||||
+ check_result_nspawn || return 1 |
||||
+ else |
||||
+ dwarn "can't run systemd-nspawn, skipping" |
||||
+ fi |
||||
+ return 0 |
||||
+} |
||||
+ |
||||
+test_setup() { |
||||
+ create_empty_image |
||||
+ mkdir -p $TESTDIR/root |
||||
+ mount ${LOOPDEV}p1 $TESTDIR/root |
||||
+ |
||||
+ ( |
||||
+ LOG_LEVEL=5 |
||||
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) |
||||
+ |
||||
+ setup_basic_environment |
||||
+ dracut_install false true env touch |
||||
+ |
||||
+ # mask some services that we do not want to run in these tests |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service |
||||
+ |
||||
+ # setup policy for Type=dbus test |
||||
+ mkdir -p $initdir/etc/dbus-1/system.d |
||||
+ cat > $initdir/etc/dbus-1/system.d/systemd.test.ExecStopPost.conf <<EOF |
||||
+<?xml version="1.0"?> |
||||
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" |
||||
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> |
||||
+<busconfig> |
||||
+ <policy user="root"> |
||||
+ <allow own="systemd.test.ExecStopPost"/> |
||||
+ </policy> |
||||
+</busconfig> |
||||
+EOF |
||||
+ |
||||
+ # setup the testsuite service |
||||
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF |
||||
+[Unit] |
||||
+Description=Testsuite service |
||||
+ |
||||
+[Service] |
||||
+ExecStart=/bin/bash -x /testsuite.sh |
||||
+Type=oneshot |
||||
+StandardOutput=tty |
||||
+StandardError=tty |
||||
+NotifyAccess=all |
||||
+EOF |
||||
+ cp testsuite.sh $initdir/ |
||||
+ |
||||
+ setup_testsuite |
||||
+ ) |
||||
+ setup_nspawn_root |
||||
+ |
||||
+ ddebug "umount $TESTDIR/root" |
||||
+ umount $TESTDIR/root |
||||
+} |
||||
+ |
||||
+test_cleanup() { |
||||
+ umount $TESTDIR/root 2>/dev/null |
||||
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV |
||||
+ return 0 |
||||
+} |
||||
+ |
||||
+do_test "$@" |
||||
diff --git a/test/TEST-42-EXECSTOPPOST/testsuite.sh b/test/TEST-42-EXECSTOPPOST/testsuite.sh |
||||
new file mode 100755 |
||||
index 0000000000..a7e663adb3 |
||||
--- /dev/null |
||||
+++ b/test/TEST-42-EXECSTOPPOST/testsuite.sh |
||||
@@ -0,0 +1,119 @@ |
||||
+#!/bin/bash |
||||
+set -ex |
||||
+ |
||||
+systemd-analyze set-log-level debug |
||||
+ |
||||
+# Emulates systemd-run to overcome its limitations on RHEL-7, like nonexistent |
||||
+# support for --wait and only a handful of supported properties. |
||||
+systemd-run-wait() { |
||||
+ local unit="$1" |
||||
+ local unitfile=/etc/systemd/system/$unit |
||||
+ |
||||
+ shift |
||||
+ |
||||
+ cat > $unitfile <<EOF |
||||
+[Service] |
||||
+StandardOutput=tty |
||||
+StandardError=tty |
||||
+EOF |
||||
+ |
||||
+ # The $OPTIND variable used by geopts is NOT reset on function exit in the |
||||
+ # same shell session, so let's do it manually to always get relevant results |
||||
+ OPTIND=1 |
||||
+ |
||||
+ while getopts p: opt ; do |
||||
+ case $opt in |
||||
+ p) echo "$OPTARG" >> $unitfile ;; |
||||
+ esac |
||||
+ done |
||||
+ shift $((OPTIND - 1)) |
||||
+ echo "ExecStart=/usr/bin/env $@" >> $unitfile |
||||
+ systemctl daemon-reload |
||||
+ |
||||
+ systemctl start $unit |
||||
+ while systemctl is-active -q $unit ; do |
||||
+ sleep 1 |
||||
+ done |
||||
+ ! systemctl is-failed -q $unit |
||||
+} |
||||
+ |
||||
+systemd-run-wait simple1.service -p Type=simple -p ExecStopPost='/bin/touch /run/simple1' true |
||||
+test -f /run/simple1 |
||||
+ |
||||
+! systemd-run-wait simple2.service -p Type=simple -p ExecStopPost='/bin/touch /run/simple2' false |
||||
+test -f /run/simple2 |
||||
+ |
||||
+cat > /tmp/forking1.sh <<EOF |
||||
+#!/bin/bash |
||||
+ |
||||
+set -eux |
||||
+ |
||||
+sleep 4 & |
||||
+MAINPID=\$! |
||||
+disown |
||||
+ |
||||
+systemd-notify MAINPID=\$MAINPID |
||||
+EOF |
||||
+chmod +x /tmp/forking1.sh |
||||
+ |
||||
+# RHEL 7 doesn't support NotifyAccess=exec |
||||
+systemd-run-wait forking1.service -p Type=forking -p NotifyAccess=main -p ExecStopPost='/bin/touch /run/forking1' /tmp/forking1.sh |
||||
+test -f /run/forking1 |
||||
+ |
||||
+cat > /tmp/forking2.sh <<EOF |
||||
+#!/bin/bash |
||||
+ |
||||
+set -eux |
||||
+ |
||||
+( sleep 4; exit 1 ) & |
||||
+MAINPID=\$! |
||||
+disown |
||||
+ |
||||
+systemd-notify MAINPID=\$MAINPID |
||||
+EOF |
||||
+chmod +x /tmp/forking2.sh |
||||
+ |
||||
+# RHEL 7 doesn't support NotifyAccess=exec |
||||
+! systemd-run-wait forking2.service -p Type=forking -p NotifyAccess=main -p ExecStopPost='/bin/touch /run/forking2' /tmp/forking2.sh |
||||
+test -f /run/forking2 |
||||
+ |
||||
+systemd-run-wait oneshot1.service -p Type=oneshot -p ExecStopPost='/bin/touch /run/oneshot1' true |
||||
+test -f /run/oneshot1 |
||||
+ |
||||
+! systemd-run-wait oneshot2.service -p Type=oneshot -p ExecStopPost='/bin/touch /run/oneshot2' false |
||||
+test -f /run/oneshot2 |
||||
+ |
||||
+systemd-run-wait dbus1.service -p Type=dbus -p BusName=systemd.test.ExecStopPost -p ExecStopPost='/bin/touch /run/dbus1' \ |
||||
+ busctl call org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus RequestName su systemd.test.ExecStopPost 4 \ |
||||
+ || : |
||||
+test -f /run/dbus1 |
||||
+ |
||||
+! systemd-run-wait dbus2.service -p Type=dbus -p BusName=systemd.test.ExecStopPost -p ExecStopPost='/bin/touch /run/dbus2' true |
||||
+test -f /run/dbus2 |
||||
+ |
||||
+cat > /tmp/notify1.sh <<EOF |
||||
+#!/bin/bash |
||||
+ |
||||
+set -eux |
||||
+ |
||||
+systemd-notify --ready |
||||
+EOF |
||||
+chmod +x /tmp/notify1.sh |
||||
+ |
||||
+systemd-run-wait notify1.service -p Type=notify -p ExecStopPost='/bin/touch /run/notify1' /tmp/notify1.sh |
||||
+test -f /run/notify1 |
||||
+ |
||||
+! systemd-run-wait notify2.service -p Type=notify -p ExecStopPost='/bin/touch /run/notify2' true |
||||
+test -f /run/notify2 |
||||
+ |
||||
+systemd-run-wait idle1.service -p Type=idle -p ExecStopPost='/bin/touch /run/idle1' true |
||||
+test -f /run/idle1 |
||||
+ |
||||
+! systemd-run-wait idle2.service -p Type=idle -p ExecStopPost='/bin/touch /run/idle2' false |
||||
+test -f /run/idle2 |
||||
+ |
||||
+systemd-analyze log-level info |
||||
+ |
||||
+echo OK > /testok |
||||
+ |
||||
+exit 0 |
@ -0,0 +1,112 @@
@@ -0,0 +1,112 @@
|
||||
From 70215e23a5c77445ed1b62186c069a173c632618 Mon Sep 17 00:00:00 2001 |
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> |
||||
Date: Sat, 22 Oct 2016 22:16:02 -0400 |
||||
Subject: [PATCH] core: when restarting services, don't close fds |
||||
|
||||
We would close all the stored fds in service_release_resources(), which of |
||||
course broke the whole concept of storing fds over service restart. |
||||
|
||||
Fixes #4408. |
||||
|
||||
(cherry picked from commit f0bfbfac43b7faa68ef1bb2ad659c191b9ec85d2) |
||||
(cherry picked from commit 4c271437cd695c31e76adb191013009689a7797c) |
||||
Resolves: #1757704 |
||||
--- |
||||
src/core/service.c | 22 +++++++++++++++------- |
||||
src/core/unit.c | 6 ++++-- |
||||
src/core/unit.h | 2 +- |
||||
3 files changed, 20 insertions(+), 10 deletions(-) |
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c |
||||
index e538280bad..3c2f69a003 100644 |
||||
--- a/src/core/service.c |
||||
+++ b/src/core/service.c |
||||
@@ -258,7 +258,17 @@ static void service_fd_store_unlink(ServiceFDStore *fs) { |
||||
free(fs); |
||||
} |
||||
|
||||
-static void service_release_resources(Unit *u) { |
||||
+static void service_release_fd_store(Service *s) { |
||||
+ assert(s); |
||||
+ |
||||
+ log_unit_debug(UNIT(s)->id, "Releasing all stored fds"); |
||||
+ while (s->fd_store) |
||||
+ service_fd_store_unlink(s->fd_store); |
||||
+ |
||||
+ assert(s->n_fd_store == 0); |
||||
+} |
||||
+ |
||||
+static void service_release_resources(Unit *u, bool inactive) { |
||||
Service *s = SERVICE(u); |
||||
|
||||
assert(s); |
||||
@@ -266,12 +276,10 @@ static void service_release_resources(Unit *u) { |
||||
if (!s->fd_store) |
||||
return; |
||||
|
||||
- log_debug("Releasing all resources for %s", u->id); |
||||
- |
||||
- while (s->fd_store) |
||||
- service_fd_store_unlink(s->fd_store); |
||||
+ log_unit_debug(u->id, "Releasing resources."); |
||||
|
||||
- assert(s->n_fd_store == 0); |
||||
+ if (inactive) |
||||
+ service_release_fd_store(s); |
||||
} |
||||
|
||||
static void service_done(Unit *u) { |
||||
@@ -319,7 +327,7 @@ static void service_done(Unit *u) { |
||||
|
||||
s->timer_event_source = sd_event_source_unref(s->timer_event_source); |
||||
|
||||
- service_release_resources(u); |
||||
+ service_release_resources(u, true); |
||||
} |
||||
|
||||
static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) { |
||||
diff --git a/src/core/unit.c b/src/core/unit.c |
||||
index 0dc66203a4..22e31a76b3 100644 |
||||
--- a/src/core/unit.c |
||||
+++ b/src/core/unit.c |
||||
@@ -285,6 +285,7 @@ int unit_set_description(Unit *u, const char *description) { |
||||
|
||||
bool unit_may_gc(Unit *u) { |
||||
UnitActiveState state; |
||||
+ bool inactive; |
||||
assert(u); |
||||
|
||||
/* Checks whether the unit is ready to be unloaded for garbage collection. |
||||
@@ -302,16 +303,17 @@ bool unit_may_gc(Unit *u) { |
||||
return false; |
||||
|
||||
state = unit_active_state(u); |
||||
+ inactive = state == UNIT_INACTIVE; |
||||
|
||||
/* If the unit is inactive and failed and no job is queued for |
||||
* it, then release its runtime resources */ |
||||
if (UNIT_IS_INACTIVE_OR_FAILED(state) && |
||||
UNIT_VTABLE(u)->release_resources) |
||||
- UNIT_VTABLE(u)->release_resources(u); |
||||
+ UNIT_VTABLE(u)->release_resources(u, inactive); |
||||
|
||||
/* But we keep the unit object around for longer when it is |
||||
* referenced or configured to not be gc'ed */ |
||||
- if (state != UNIT_INACTIVE) |
||||
+ if (!inactive) |
||||
return false; |
||||
|
||||
if (UNIT_VTABLE(u)->no_gc) |
||||
diff --git a/src/core/unit.h b/src/core/unit.h |
||||
index 719fc95260..232be8164f 100644 |
||||
--- a/src/core/unit.h |
||||
+++ b/src/core/unit.h |
||||
@@ -360,7 +360,7 @@ struct UnitVTable { |
||||
|
||||
/* When the unit is not running and no job for it queued we |
||||
* shall release its runtime resources */ |
||||
- void (*release_resources)(Unit *u); |
||||
+ void (*release_resources)(Unit *u, bool inactive); |
||||
|
||||
/* Return true when this unit is suitable for snapshotting */ |
||||
bool (*check_snapshot)(Unit *u); |
@ -0,0 +1,170 @@
@@ -0,0 +1,170 @@
|
||||
From 29254c6a73ede5af4df1c364c958a978f5a7af8a Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Mon, 13 Nov 2017 15:08:49 +0100 |
||||
Subject: [PATCH] unit: rework a bit how we keep the service fdstore from being |
||||
destroyed during service restart |
||||
|
||||
When preparing for a restart we quickly go through the DEAD/INACTIVE |
||||
service state before entering AUTO_RESTART. When doing this, we need to |
||||
make sure we don't destroy the FD store. Previously this was done by |
||||
checking the failure state of the unit, and keeping the FD store around |
||||
when the unit failed, under the assumption that the restart logic will |
||||
then get into action. |
||||
|
||||
This is not entirely correct howver, as there might be failure states |
||||
that will no result in restarts. |
||||
|
||||
With this commit we slightly alter the logic: a ref counter for the fd |
||||
store is added, that is increased right before we handle the restart |
||||
logic, and decreased again right-after. |
||||
|
||||
This should ensure that the fdstore lives exactly as long as it needs. |
||||
|
||||
Follow-up for f0bfbfac43b7faa68ef1bb2ad659c191b9ec85d2. |
||||
|
||||
(cherry picked from commit 7eb2a8a1259043e107ebec94e30ed160a93f40a7) |
||||
(cherry picked from commit e2636bde0f07319d0d35262dac6ff2638ba4e598) |
||||
Resolves: #1757704 |
||||
--- |
||||
src/core/service.c | 23 ++++++++++++++++++----- |
||||
src/core/service.h | 1 + |
||||
src/core/unit.c | 12 ++++-------- |
||||
src/core/unit.h | 5 ++--- |
||||
4 files changed, 25 insertions(+), 16 deletions(-) |
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c |
||||
index 3c2f69a003..e32cdf4594 100644 |
||||
--- a/src/core/service.c |
||||
+++ b/src/core/service.c |
||||
@@ -261,6 +261,9 @@ static void service_fd_store_unlink(ServiceFDStore *fs) { |
||||
static void service_release_fd_store(Service *s) { |
||||
assert(s); |
||||
|
||||
+ if (s->n_keep_fd_store > 0) |
||||
+ return; |
||||
+ |
||||
log_unit_debug(UNIT(s)->id, "Releasing all stored fds"); |
||||
while (s->fd_store) |
||||
service_fd_store_unlink(s->fd_store); |
||||
@@ -268,7 +271,7 @@ static void service_release_fd_store(Service *s) { |
||||
assert(s->n_fd_store == 0); |
||||
} |
||||
|
||||
-static void service_release_resources(Unit *u, bool inactive) { |
||||
+static void service_release_resources(Unit *u) { |
||||
Service *s = SERVICE(u); |
||||
|
||||
assert(s); |
||||
@@ -278,8 +281,7 @@ static void service_release_resources(Unit *u, bool inactive) { |
||||
|
||||
log_unit_debug(u->id, "Releasing resources."); |
||||
|
||||
- if (inactive) |
||||
- service_release_fd_store(s); |
||||
+ service_release_fd_store(s); |
||||
} |
||||
|
||||
static void service_done(Unit *u) { |
||||
@@ -327,7 +329,7 @@ static void service_done(Unit *u) { |
||||
|
||||
s->timer_event_source = sd_event_source_unref(s->timer_event_source); |
||||
|
||||
- service_release_resources(u, true); |
||||
+ service_release_resources(u); |
||||
} |
||||
|
||||
static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) { |
||||
@@ -1330,6 +1332,10 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) |
||||
if (f != SERVICE_SUCCESS) |
||||
s->result = f; |
||||
|
||||
+ /* Make sure service_release_resources() doesn't destroy our FD store, while we are changing through |
||||
+ * SERVICE_FAILED/SERVICE_DEAD before entering into SERVICE_AUTO_RESTART. */ |
||||
+ s->n_keep_fd_store++; |
||||
+ |
||||
service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD); |
||||
|
||||
if (s->result != SERVICE_SUCCESS) { |
||||
@@ -1351,12 +1357,19 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) |
||||
(!IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) || !set_contains(s->restart_prevent_status.signal, INT_TO_PTR(s->main_exec_status.status)))) { |
||||
|
||||
r = service_arm_timer(s, s->restart_usec); |
||||
- if (r < 0) |
||||
+ if (r < 0) { |
||||
+ s->n_keep_fd_store--; |
||||
goto fail; |
||||
+ } |
||||
|
||||
service_set_state(s, SERVICE_AUTO_RESTART); |
||||
} |
||||
|
||||
+ /* The new state is in effect, let's decrease the fd store ref counter again. Let's also readd us to the GC |
||||
+ * queue, so that the fd store is possibly gc'ed again */ |
||||
+ s->n_keep_fd_store--; |
||||
+ unit_add_to_gc_queue(UNIT(s)); |
||||
+ |
||||
s->forbid_restart = false; |
||||
|
||||
/* We want fresh tmpdirs in case service is started again immediately */ |
||||
diff --git a/src/core/service.h b/src/core/service.h |
||||
index 82938a1fc4..e5753f1f4c 100644 |
||||
--- a/src/core/service.h |
||||
+++ b/src/core/service.h |
||||
@@ -215,6 +215,7 @@ struct Service { |
||||
ServiceFDStore *fd_store; |
||||
unsigned n_fd_store; |
||||
unsigned n_fd_store_max; |
||||
+ unsigned n_keep_fd_store; |
||||
}; |
||||
|
||||
extern const UnitVTable service_vtable; |
||||
diff --git a/src/core/unit.c b/src/core/unit.c |
||||
index 22e31a76b3..eff9fdbe70 100644 |
||||
--- a/src/core/unit.c |
||||
+++ b/src/core/unit.c |
||||
@@ -285,7 +285,6 @@ int unit_set_description(Unit *u, const char *description) { |
||||
|
||||
bool unit_may_gc(Unit *u) { |
||||
UnitActiveState state; |
||||
- bool inactive; |
||||
assert(u); |
||||
|
||||
/* Checks whether the unit is ready to be unloaded for garbage collection. |
||||
@@ -303,17 +302,14 @@ bool unit_may_gc(Unit *u) { |
||||
return false; |
||||
|
||||
state = unit_active_state(u); |
||||
- inactive = state == UNIT_INACTIVE; |
||||
|
||||
- /* If the unit is inactive and failed and no job is queued for |
||||
- * it, then release its runtime resources */ |
||||
+ /* If the unit is inactive and failed and no job is queued for it, then release its runtime resources */ |
||||
if (UNIT_IS_INACTIVE_OR_FAILED(state) && |
||||
UNIT_VTABLE(u)->release_resources) |
||||
- UNIT_VTABLE(u)->release_resources(u, inactive); |
||||
+ UNIT_VTABLE(u)->release_resources(u); |
||||
|
||||
- /* But we keep the unit object around for longer when it is |
||||
- * referenced or configured to not be gc'ed */ |
||||
- if (!inactive) |
||||
+ /* But we keep the unit object around for longer when it is referenced or configured to not be gc'ed */ |
||||
+ if (state != UNIT_INACTIVE) |
||||
return false; |
||||
|
||||
if (UNIT_VTABLE(u)->no_gc) |
||||
diff --git a/src/core/unit.h b/src/core/unit.h |
||||
index 232be8164f..3b0fd8d9df 100644 |
||||
--- a/src/core/unit.h |
||||
+++ b/src/core/unit.h |
||||
@@ -358,9 +358,8 @@ struct UnitVTable { |
||||
* even though nothing references it and it isn't active in any way. */ |
||||
bool (*may_gc)(Unit *u); |
||||
|
||||
- /* When the unit is not running and no job for it queued we |
||||
- * shall release its runtime resources */ |
||||
- void (*release_resources)(Unit *u, bool inactive); |
||||
+ /* When the unit is not running and no job for it queued we shall release its runtime resources */ |
||||
+ void (*release_resources)(Unit *u); |
||||
|
||||
/* Return true when this unit is suitable for snapshotting */ |
||||
bool (*check_snapshot)(Unit *u); |
@ -0,0 +1,145 @@
@@ -0,0 +1,145 @@
|
||||
From 5042511b6d12e30fc66e5a404153aac6c63af7d9 Mon Sep 17 00:00:00 2001 |
||||
From: Evgeny Vereshchagin <evvers@ya.ru> |
||||
Date: Tue, 17 Nov 2015 11:21:23 +0000 |
||||
Subject: [PATCH] tests: add basic journal test |
||||
|
||||
(cherry picked from commit 1c36b4a73b876258fbe01fbe9bc9b750b7dcc9ce) |
||||
(cherry picked from commit e974b9915ccc7bf56d23fd6fc67631990d893c89) |
||||
Resolves: #1757704 |
||||
--- |
||||
test/TEST-04-JOURNAL/Makefile | 1 + |
||||
test/TEST-04-JOURNAL/test-journal.sh | 18 +++++++ |
||||
test/TEST-04-JOURNAL/test.sh | 76 ++++++++++++++++++++++++++++ |
||||
test/test-functions | 2 +- |
||||
4 files changed, 96 insertions(+), 1 deletion(-) |
||||
create mode 120000 test/TEST-04-JOURNAL/Makefile |
||||
create mode 100755 test/TEST-04-JOURNAL/test-journal.sh |
||||
create mode 100755 test/TEST-04-JOURNAL/test.sh |
||||
|
||||
diff --git a/test/TEST-04-JOURNAL/Makefile b/test/TEST-04-JOURNAL/Makefile |
||||
new file mode 120000 |
||||
index 0000000000..e9f93b1104 |
||||
--- /dev/null |
||||
+++ b/test/TEST-04-JOURNAL/Makefile |
||||
@@ -0,0 +1 @@ |
||||
+../TEST-01-BASIC/Makefile |
||||
\ No newline at end of file |
||||
diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh |
||||
new file mode 100755 |
||||
index 0000000000..c75f396ceb |
||||
--- /dev/null |
||||
+++ b/test/TEST-04-JOURNAL/test-journal.sh |
||||
@@ -0,0 +1,18 @@ |
||||
+#!/bin/bash |
||||
+ |
||||
+set -x |
||||
+set -e |
||||
+set -o pipefail |
||||
+ |
||||
+# Test stdout stream |
||||
+ |
||||
+# Skip empty lines |
||||
+ID=$(journalctl --new-id128 | sed -n 2p) |
||||
+>/expected |
||||
+printf $'\n\n\n' | systemd-cat -t "$ID" --level-prefix false |
||||
+journalctl --flush |
||||
+journalctl -b -o cat -t "$ID" >/output |
||||
+cmp /expected /output |
||||
+ |
||||
+touch /testok |
||||
+exit 0 |
||||
diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh |
||||
new file mode 100755 |
||||
index 0000000000..e37cb7d412 |
||||
--- /dev/null |
||||
+++ b/test/TEST-04-JOURNAL/test.sh |
||||
@@ -0,0 +1,76 @@ |
||||
+#!/bin/bash |
||||
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- |
||||
+# ex: ts=8 sw=4 sts=4 et filetype=sh |
||||
+TEST_DESCRIPTION="Journal-related tests" |
||||
+ |
||||
+. $TEST_BASE_DIR/test-functions |
||||
+ |
||||
+check_result_qemu() { |
||||
+ ret=1 |
||||
+ mkdir -p $TESTDIR/root |
||||
+ mount ${LOOPDEV}p1 $TESTDIR/root |
||||
+ [[ -e $TESTDIR/root/testok ]] && ret=0 |
||||
+ [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR |
||||
+ cp -a $TESTDIR/root/var/log/journal $TESTDIR |
||||
+ umount $TESTDIR/root |
||||
+ [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed |
||||
+ ls -l $TESTDIR/journal/*/*.journal |
||||
+ test -s $TESTDIR/failed && ret=$(($ret+1)) |
||||
+ return $ret |
||||
+} |
||||
+ |
||||
+test_run() { |
||||
+ if run_qemu; then |
||||
+ check_result_qemu || return 1 |
||||
+ else |
||||
+ dwarn "can't run QEMU, skipping" |
||||
+ fi |
||||
+ if check_nspawn; then |
||||
+ run_nspawn |
||||
+ check_result_nspawn || return 1 |
||||
+ else |
||||
+ dwarn "can't run systemd-nspawn, skipping" |
||||
+ fi |
||||
+ return 0 |
||||
+} |
||||
+ |
||||
+test_setup() { |
||||
+ create_empty_image |
||||
+ mkdir -p $TESTDIR/root |
||||
+ mount ${LOOPDEV}p1 $TESTDIR/root |
||||
+ |
||||
+ # Create what will eventually be our root filesystem onto an overlay |
||||
+ ( |
||||
+ LOG_LEVEL=5 |
||||
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) |
||||
+ |
||||
+ setup_basic_environment |
||||
+ |
||||
+ # setup the testsuite service |
||||
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF |
||||
+[Unit] |
||||
+Description=Testsuite service |
||||
+After=multi-user.target |
||||
+ |
||||
+[Service] |
||||
+ExecStart=/test-journal.sh |
||||
+Type=oneshot |
||||
+EOF |
||||
+ |
||||
+ cp test-journal.sh $initdir/ |
||||
+ |
||||
+ setup_testsuite |
||||
+ ) |
||||
+ setup_nspawn_root |
||||
+ |
||||
+ ddebug "umount $TESTDIR/root" |
||||
+ umount $TESTDIR/root |
||||
+} |
||||
+ |
||||
+test_cleanup() { |
||||
+ umount $TESTDIR/root 2>/dev/null |
||||
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV |
||||
+ return 0 |
||||
+} |
||||
+ |
||||
+do_test "$@" |
||||
diff --git a/test/test-functions b/test/test-functions |
||||
index e50ce556fd..d5e9650903 100644 |
||||
--- a/test/test-functions |
||||
+++ b/test/test-functions |
||||
@@ -12,7 +12,7 @@ if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then |
||||
ROOTLIBDIR=/usr/lib/systemd |
||||
fi |
||||
|
||||
-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe chmod chown ln" |
||||
+BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe chmod chown ln sed cmp tee" |
||||
DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname" |
||||
|
||||
function find_qemu_bin() { |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
From ae68ff48fffe8df34c2065ad221b7d2377523edc Mon Sep 17 00:00:00 2001 |
||||
From: Evgeny Vereshchagin <evvers@ya.ru> |
||||
Date: Wed, 30 Dec 2015 03:33:43 +0000 |
||||
Subject: [PATCH] tests: add regression test for `systemctl restart |
||||
systemd-journald` |
||||
|
||||
See https://github.com/systemd/systemd/issues/2236 |
||||
|
||||
(cherry picked from commit 3889613ec6bc54b9e02955f62b9d5c5b571c3d4b) |
||||
(cherry picked from commit 4dc893c03fe9c56a3d3070fb8583f5584014aa49) |
||||
Resolves: #1757704 |
||||
--- |
||||
test/TEST-04-JOURNAL/test-journal.sh | 8 ++++++++ |
||||
test/TEST-04-JOURNAL/test.sh | 9 +++++++++ |
||||
2 files changed, 17 insertions(+) |
||||
|
||||
diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh |
||||
index c75f396ceb..701b0cf724 100755 |
||||
--- a/test/TEST-04-JOURNAL/test-journal.sh |
||||
+++ b/test/TEST-04-JOURNAL/test-journal.sh |
||||
@@ -14,5 +14,13 @@ journalctl --flush |
||||
journalctl -b -o cat -t "$ID" >/output |
||||
cmp /expected /output |
||||
|
||||
+# Don't lose streams on restart |
||||
+systemctl start forever-print-hola |
||||
+sleep 3 |
||||
+systemctl restart systemd-journald |
||||
+sleep 3 |
||||
+systemctl stop forever-print-hola |
||||
+[[ ! -f "/i-lose-my-logs" ]] |
||||
+ |
||||
touch /testok |
||||
exit 0 |
||||
diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh |
||||
index e37cb7d412..6aea67ba4e 100755 |
||||
--- a/test/TEST-04-JOURNAL/test.sh |
||||
+++ b/test/TEST-04-JOURNAL/test.sh |
||||
@@ -55,6 +55,15 @@ After=multi-user.target |
||||
[Service] |
||||
ExecStart=/test-journal.sh |
||||
Type=oneshot |
||||
+EOF |
||||
+ |
||||
+ cat >$initdir/etc/systemd/system/forever-print-hola.service <<EOF |
||||
+[Unit] |
||||
+Description=ForeverPrintHola service |
||||
+ |
||||
+[Service] |
||||
+Type=simple |
||||
+ExecStart=/bin/sh -x -c 'while :; do printf "Hola\n" || touch /i-lose-my-logs; sleep 1; done' |
||||
EOF |
||||
|
||||
cp test-journal.sh $initdir/ |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
From 65fb1fbdcf80b77378bfea8962611eeb8220cb28 Mon Sep 17 00:00:00 2001 |
||||
From: Evgeny Vereshchagin <evvers@ya.ru> |
||||
Date: Thu, 20 Oct 2016 13:18:12 +0000 |
||||
Subject: [PATCH] tests: add test that journald keeps fds over termination by |
||||
signal |
||||
|
||||
This test fails before previous commit, and passes with it. |
||||
|
||||
(cherry picked from commit bff653e3970bb79832568ae86b095ee530b62302) |
||||
(cherry picked from commit ee8f69ae5ddac6f05c56ea7dbcb76fbbb2e355ee) |
||||
Resolves: #1757704 |
||||
--- |
||||
test/TEST-04-JOURNAL/test-journal.sh | 8 ++++++++ |
||||
1 file changed, 8 insertions(+) |
||||
|
||||
diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh |
||||
index 701b0cf724..d0b05c46d6 100755 |
||||
--- a/test/TEST-04-JOURNAL/test-journal.sh |
||||
+++ b/test/TEST-04-JOURNAL/test-journal.sh |
||||
@@ -22,5 +22,13 @@ sleep 3 |
||||
systemctl stop forever-print-hola |
||||
[[ ! -f "/i-lose-my-logs" ]] |
||||
|
||||
+# https://github.com/systemd/systemd/issues/4408 |
||||
+rm -f /i-lose-my-logs |
||||
+systemctl start forever-print-hola |
||||
+sleep 3 |
||||
+systemctl kill --signal=SIGKILL systemd-journald |
||||
+sleep 3 |
||||
+[[ ! -f "/i-lose-my-logs" ]] |
||||
+ |
||||
touch /testok |
||||
exit 0 |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
From 351e67e1a7259ac31ec3a7c2d5e850e60f622a5a Mon Sep 17 00:00:00 2001 |
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> |
||||
Date: Tue, 31 Jan 2017 19:55:33 -0500 |
||||
Subject: [PATCH] nss-util: silence warning about deprecated RES_USE_INET6 |
||||
MIME-Version: 1.0 |
||||
Content-Type: text/plain; charset=UTF-8 |
||||
Content-Transfer-Encoding: 8bit |
||||
|
||||
src/nss-resolve/nss-resolve.c: In function ‘_nss_resolve_gethostbyname_r’: |
||||
src/nss-resolve/nss-resolve.c:680:13: warning: RES_USE_INET6 is deprecated |
||||
NSS_GETHOSTBYNAME_FALLBACKS(resolve); |
||||
^~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
In glibc bz #19582, RES_USE_INET6 was deprecated. This might make sense for |
||||
clients, but they didn't take into account nss module implementations which |
||||
*must* continue to support the option. glibc internally defines |
||||
DEPRECATED_RES_USE_INET6 which can be used without emitting a warning, but |
||||
it's not exported publicly. Let's do the same, and just copy the definition |
||||
to our header. |
||||
|
||||
(cherry picked from commit 6154d33de3f15bbd5d5df718103af9c37ba0a768) |
||||
|
||||
Resolves: #1799002 |
||||
--- |
||||
src/shared/nss-util.h | 6 +++++- |
||||
1 file changed, 5 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/shared/nss-util.h b/src/shared/nss-util.h |
||||
index 230a986040..01524289c5 100644 |
||||
--- a/src/shared/nss-util.h |
||||
+++ b/src/shared/nss-util.h |
||||
@@ -25,6 +25,10 @@ |
||||
#include <netdb.h> |
||||
#include <resolv.h> |
||||
|
||||
+#ifndef DEPRECATED_RES_USE_INET6 |
||||
+# define DEPRECATED_RES_USE_INET6 0x00002000 |
||||
+#endif |
||||
+ |
||||
#define NSS_GETHOSTBYNAME_PROTOTYPES(module) \ |
||||
enum nss_status _nss_##module##_gethostbyname4_r( \ |
||||
const char *name, \ |
||||
@@ -90,7 +94,7 @@ enum nss_status _nss_##module##_gethostbyname_r( \ |
||||
int *errnop, int *h_errnop) { \ |
||||
enum nss_status ret = NSS_STATUS_NOTFOUND; \ |
||||
\ |
||||
- if (_res.options & RES_USE_INET6) \ |
||||
+ if (_res.options & DEPRECATED_RES_USE_INET6) \ |
||||
ret = _nss_##module##_gethostbyname3_r( \ |
||||
name, \ |
||||
AF_INET6, \ |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
From 248925c68092bab7ce0231449176db153f55d818 Mon Sep 17 00:00:00 2001 |
||||
From: Jan Synacek <jsynacek@redhat.com> |
||||
Date: Tue, 7 Jan 2020 11:22:26 +0100 |
||||
Subject: [PATCH] journal: do not trigger assertion when journal_file_close() |
||||
get NULL |
||||
|
||||
We generally expect destructors to not complain if a NULL argument is passed. |
||||
|
||||
Closes #12400. |
||||
|
||||
(cherry picked from commit c377a6f3ad3d9bed4ce7e873e8e9ec6b1650c57d) |
||||
Resolves: #1786046 |
||||
--- |
||||
src/journal/journal-file.c | 3 ++- |
||||
src/journal/journald-server.c | 7 ++----- |
||||
2 files changed, 4 insertions(+), 6 deletions(-) |
||||
|
||||
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c |
||||
index 586f620e21..cf8dad3fcd 100644 |
||||
--- a/src/journal/journal-file.c |
||||
+++ b/src/journal/journal-file.c |
||||
@@ -129,7 +129,8 @@ int journal_file_set_offline(JournalFile *f) { |
||||
} |
||||
|
||||
void journal_file_close(JournalFile *f) { |
||||
- assert(f); |
||||
+ if (!f) |
||||
+ return; |
||||
|
||||
#ifdef HAVE_GCRYPT |
||||
/* Write the final tag */ |
||||
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c |
||||
index aaabb2f7ab..ffe2daa7be 100644 |
||||
--- a/src/journal/journald-server.c |
||||
+++ b/src/journal/journald-server.c |
||||
@@ -1933,11 +1933,8 @@ void server_done(Server *s) { |
||||
while (s->stdout_streams) |
||||
stdout_stream_free(s->stdout_streams); |
||||
|
||||
- if (s->system_journal) |
||||
- journal_file_close(s->system_journal); |
||||
- |
||||
- if (s->runtime_journal) |
||||
- journal_file_close(s->runtime_journal); |
||||
+ (void) journal_file_close(s->system_journal); |
||||
+ (void) journal_file_close(s->runtime_journal); |
||||
|
||||
while ((f = ordered_hashmap_steal_first(s->user_journals))) |
||||
journal_file_close(f); |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
From f5e4e0c8139bc0fe001846fabe83c3220fe4bea7 Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Wed, 28 Nov 2018 12:41:44 +0100 |
||||
Subject: [PATCH] mount: don't propagate errors from mount_setup_unit() further |
||||
up |
||||
|
||||
If we can't process a specific line in /proc/self/mountinfo we should |
||||
log about it (which we do), but this should not affect other lines, nor |
||||
further processing of mount units. Let's keep these failures local. |
||||
|
||||
Fixes: #10874 |
||||
(cherry picked from commit ba0d56f55f2073164799be714b5bd1aad94d059a) |
||||
Resolves: #1804757 |
||||
--- |
||||
src/core/mount.c | 9 +++------ |
||||
1 file changed, 3 insertions(+), 6 deletions(-) |
||||
|
||||
diff --git a/src/core/mount.c b/src/core/mount.c |
||||
index 3167bd6bb1..126038c27f 100644 |
||||
--- a/src/core/mount.c |
||||
+++ b/src/core/mount.c |
||||
@@ -1571,7 +1571,7 @@ fail: |
||||
static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { |
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; |
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; |
||||
- int r = 0; |
||||
+ int r; |
||||
|
||||
assert(m); |
||||
|
||||
@@ -1587,7 +1587,6 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { |
||||
if (r < 0) |
||||
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m"); |
||||
|
||||
- r = 0; |
||||
for (;;) { |
||||
const char *device, *path, *options, *fstype; |
||||
_cleanup_free_ const char *d = NULL, *p = NULL; |
||||
@@ -1615,12 +1614,10 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { |
||||
|
||||
(void) device_found_node(m, d, true, DEVICE_FOUND_MOUNT, set_flags); |
||||
|
||||
- k = mount_setup_unit(m, d, p, options, fstype, set_flags); |
||||
- if (r == 0 && k < 0) |
||||
- r = k; |
||||
+ (void) mount_setup_unit(m, d, p, options, fstype, set_flags); |
||||
} |
||||
|
||||
- return r; |
||||
+ return 0; |
||||
} |
||||
|
||||
static void mount_shutdown(Manager *m) { |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
From 774f040ecc62e9c559269bb13afb1c4d04e1b6ab Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Wed, 28 Nov 2018 14:51:04 +0100 |
||||
Subject: [PATCH] mount: when allocating a Mount object based on |
||||
/proc/self/mountinfo mark it so |
||||
|
||||
Let's set 'from_proc_self_mountinfo' right away, since we know its from |
||||
there. This is important so that when the load queue is dispatched (and |
||||
thus mount_load() called) this |
||||
fact is already known. |
||||
|
||||
(cherry picked from commit 6d7e89b07065b8c49af47aaf1ccc336d017fc3a2) |
||||
Related: #1804757 |
||||
--- |
||||
src/core/mount.c | 7 +++++++ |
||||
1 file changed, 7 insertions(+) |
||||
|
||||
diff --git a/src/core/mount.c b/src/core/mount.c |
||||
index 126038c27f..34c4b548ad 100644 |
||||
--- a/src/core/mount.c |
||||
+++ b/src/core/mount.c |
||||
@@ -1480,6 +1480,13 @@ static int mount_setup_unit( |
||||
} |
||||
} |
||||
|
||||
+ /* This unit was generated because /proc/self/mountinfo reported it. Remember this, so that by the time we load |
||||
+ * the unit file for it (and thus add in extra deps right after) we know what source to attributes the deps |
||||
+ * to.*/ |
||||
+ MOUNT(u)->from_proc_self_mountinfo = true; |
||||
+ |
||||
+ /* We have only allocated the stub now, let's enqueue this unit for loading now, so that everything else is |
||||
+ * loaded in now. */ |
||||
unit_add_to_load_queue(u); |
||||
changed = true; |
||||
} else { |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
From 591bcfa98983c97df4dbb9d15bc272c3fc093863 Mon Sep 17 00:00:00 2001 |
||||
From: David Tardon <dtardon@redhat.com> |
||||
Date: Mon, 16 Mar 2020 09:37:22 +0100 |
||||
Subject: [PATCH] fix the fix for #1691511 |
||||
|
||||
The fix for #1691511 should have been used only for existing mounts |
||||
(mount_setup_existing_unit() in current master). |
||||
|
||||
Related: #1804757 |
||||
--- |
||||
src/core/mount.c | 6 +++++- |
||||
1 file changed, 5 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/core/mount.c b/src/core/mount.c |
||||
index 34c4b548ad..56fda1b73f 100644 |
||||
--- a/src/core/mount.c |
||||
+++ b/src/core/mount.c |
||||
@@ -1416,6 +1416,7 @@ static int mount_setup_unit( |
||||
bool load_extras = false; |
||||
MountParameters *p; |
||||
bool delete, changed = false; |
||||
+ bool just_mounted; |
||||
Unit *u; |
||||
int r; |
||||
|
||||
@@ -1489,6 +1490,7 @@ static int mount_setup_unit( |
||||
* loaded in now. */ |
||||
unit_add_to_load_queue(u); |
||||
changed = true; |
||||
+ just_mounted = true; |
||||
} else { |
||||
delete = false; |
||||
|
||||
@@ -1518,6 +1520,8 @@ static int mount_setup_unit( |
||||
load_extras = true; |
||||
changed = true; |
||||
} |
||||
+ |
||||
+ just_mounted = !MOUNT(u)->from_proc_self_mountinfo || MOUNT(u)->just_mounted; |
||||
} |
||||
|
||||
w = strdup(what); |
||||
@@ -1537,7 +1541,7 @@ static int mount_setup_unit( |
||||
|
||||
if (set_flags) { |
||||
MOUNT(u)->is_mounted = true; |
||||
- MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo || MOUNT(u)->just_mounted; |
||||
+ MOUNT(u)->just_mounted = just_mounted; |
||||
MOUNT(u)->just_changed = changed; |
||||
} |
||||
|
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
From f99cc28e392874b317b4ff2054bbd6970f71ecdd Mon Sep 17 00:00:00 2001 |
||||
From: Long Li <longli@microsoft.com> |
||||
Date: Wed, 21 Mar 2018 03:51:28 -0700 |
||||
Subject: [PATCH] v3: Properly parsing SCSI Hyperv devices (#8509) |
||||
|
||||
Since 2016, Hyperv devices moved to using standard way to expose UUID to sysfs. Fix the parsing function to work with the newer format. |
||||
|
||||
Change log: |
||||
v2: changed code to work with both old and new path format |
||||
v3: changed guid_str_len type to size_t, fixed length in char guid[] in handle_scsi_hyperv() |
||||
|
||||
(cherry picked from commit cf3fabacaa141a1224a2ad239806a1fa28b51687) |
||||
|
||||
Resolves: #1809053 |
||||
--- |
||||
src/udev/udev-builtin-path_id.c | 18 ++++++++++++------ |
||||
1 file changed, 12 insertions(+), 6 deletions(-) |
||||
|
||||
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c |
||||
index d113ff21b0..b0bcd80571 100644 |
||||
--- a/src/udev/udev-builtin-path_id.c |
||||
+++ b/src/udev/udev-builtin-path_id.c |
||||
@@ -424,14 +424,16 @@ out: |
||||
return hostdev; |
||||
} |
||||
|
||||
-static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char **path) { |
||||
+static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char **path, size_t guid_str_len) { |
||||
struct udev_device *hostdev; |
||||
struct udev_device *vmbusdev; |
||||
const char *guid_str; |
||||
- char *lun = NULL; |
||||
- char guid[38]; |
||||
+ _cleanup_free_ char *lun = NULL; |
||||
+ char guid[39]; |
||||
size_t i, k; |
||||
|
||||
+ assert(guid_str_len < sizeof(guid)); |
||||
+ |
||||
hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host"); |
||||
if (!hostdev) |
||||
return NULL; |
||||
@@ -444,10 +446,10 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char * |
||||
if (!guid_str) |
||||
return NULL; |
||||
|
||||
- if (strlen(guid_str) < 37 || guid_str[0] != '{' || guid_str[36] != '}') |
||||
+ if (strlen(guid_str) < guid_str_len || guid_str[0] != '{' || guid_str[guid_str_len-1] != '}') |
||||
return NULL; |
||||
|
||||
- for (i = 1, k = 0; i < 36; i++) { |
||||
+ for (i = 1, k = 0; i < guid_str_len-1; i++) { |
||||
if (guid_str[i] == '-') |
||||
continue; |
||||
guid[k++] = guid_str[i]; |
||||
@@ -545,7 +547,11 @@ static struct udev_device *handle_scsi(struct udev_device *parent, bool enable_n |
||||
} |
||||
|
||||
if (strstr(name, "/vmbus_") != NULL) { |
||||
- parent = handle_scsi_hyperv(parent, path); |
||||
+ parent = handle_scsi_hyperv(parent, path, 37); |
||||
+ goto out; |
||||
+ } |
||||
+ else if (strstr(name, "/VMBUS")) { |
||||
+ parent = handle_scsi_hyperv(parent, path, 38); |
||||
goto out; |
||||
} |
||||
|
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
From a1e395b76292480649c1d94893af93c1262b2f5f Mon Sep 17 00:00:00 2001 |
||||
From: Kenneth D'souza <kdsouza@redhat.com> |
||||
Date: Mon, 30 Sep 2019 16:01:21 +0530 |
||||
Subject: [PATCH] Consider smb3 as remote filesystem |
||||
|
||||
Currently systemd will treat smb3 as local filesystem and cause |
||||
can't boot failures. Add smb3 to the list of remote filesystems |
||||
to fix this issue. |
||||
|
||||
Signed-off-by: Kenneth D'souza <kdsouza@redhat.com> |
||||
(cherry picked from commit ff7d6a740b0c6fa3be63d3908a0858730a0837c5) |
||||
|
||||
Resolves: #1811700 |
||||
--- |
||||
src/shared/util.c | 1 + |
||||
1 file changed, 1 insertion(+) |
||||
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c |
||||
index ce6678eb38..3fb4492a81 100644 |
||||
--- a/src/shared/util.c |
||||
+++ b/src/shared/util.c |
||||
@@ -1937,6 +1937,7 @@ bool fstype_is_network(const char *fstype) { |
||||
static const char table[] = |
||||
"afs\0" |
||||
"cifs\0" |
||||
+ "smb3\0" |
||||
"smbfs\0" |
||||
"sshfs\0" |
||||
"ncpfs\0" |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
From 070dfe9be5cf873e2a815232900da9651dfe4544 Mon Sep 17 00:00:00 2001 |
||||
From: David Tardon <dtardon@redhat.com> |
||||
Date: Tue, 17 Mar 2020 10:49:44 +0100 |
||||
Subject: [PATCH] mount: don't add Requires for tmp.mount |
||||
|
||||
This is a follow-up to #1372249. |
||||
|
||||
rhel-only |
||||
Resolves: #1813270 |
||||
--- |
||||
src/core/mount.c | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/core/mount.c b/src/core/mount.c |
||||
index 56fda1b73f..72e981676d 100644 |
||||
--- a/src/core/mount.c |
||||
+++ b/src/core/mount.c |
||||
@@ -300,7 +300,7 @@ static int mount_add_mount_links(Mount *m) { |
||||
if (r < 0) |
||||
return r; |
||||
|
||||
- if (UNIT(m)->fragment_path) { |
||||
+ if (UNIT(m)->fragment_path && !streq(UNIT(m)->id, "tmp.mount")) { |
||||
/* If we have fragment configuration, then make this dependency required */ |
||||
r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true); |
||||
if (r < 0) |
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
From 24622692a67b59e943afc1d309da696e48bf6a54 Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Fri, 15 Dec 2017 22:24:16 +0100 |
||||
Subject: [PATCH] sd-bus: when attached to an sd-event loop, disconnect on |
||||
processing errors |
||||
|
||||
If we can't process the bus for some reason we shouldn't just disable |
||||
the event source, but log something and give up on the connection. Hence |
||||
do that, and disconnect. |
||||
|
||||
(cherry-picked from commit 5ae37ad833583e6c1c7765767b7f8360afca3b07) |
||||
|
||||
Resolves: #1769928 |
||||
--- |
||||
src/libsystemd/sd-bus/sd-bus.c | 45 +++++++++++++++++++++------------- |
||||
1 file changed, 28 insertions(+), 17 deletions(-) |
||||
|
||||
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c |
||||
index 44ed2c7497..2c8cc66367 100644 |
||||
--- a/src/libsystemd/sd-bus/sd-bus.c |
||||
+++ b/src/libsystemd/sd-bus/sd-bus.c |
||||
@@ -3037,8 +3037,10 @@ static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userd |
||||
assert(bus); |
||||
|
||||
r = sd_bus_process(bus, NULL); |
||||
- if (r < 0) |
||||
- return r; |
||||
+ if (r < 0) { |
||||
+ log_debug_errno(r, "Processing of bus failed, closing down: %m"); |
||||
+ bus_enter_closing(bus); |
||||
+ } |
||||
|
||||
return 1; |
||||
} |
||||
@@ -3050,8 +3052,10 @@ static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) { |
||||
assert(bus); |
||||
|
||||
r = sd_bus_process(bus, NULL); |
||||
- if (r < 0) |
||||
- return r; |
||||
+ if (r < 0) { |
||||
+ log_debug_errno(r, "Processing of bus failed, closing down: %m"); |
||||
+ bus_enter_closing(bus); |
||||
+ } |
||||
|
||||
return 1; |
||||
} |
||||
@@ -3065,38 +3069,45 @@ static int prepare_callback(sd_event_source *s, void *userdata) { |
||||
assert(bus); |
||||
|
||||
e = sd_bus_get_events(bus); |
||||
- if (e < 0) |
||||
- return e; |
||||
+ if (e < 0) { |
||||
+ r = e; |
||||
+ goto fail; |
||||
+ } |
||||
|
||||
if (bus->output_fd != bus->input_fd) { |
||||
|
||||
r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN); |
||||
if (r < 0) |
||||
- return r; |
||||
+ goto fail; |
||||
|
||||
r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT); |
||||
- if (r < 0) |
||||
- return r; |
||||
- } else { |
||||
+ } else |
||||
r = sd_event_source_set_io_events(bus->input_io_event_source, e); |
||||
- if (r < 0) |
||||
- return r; |
||||
- } |
||||
+ if (r < 0) |
||||
+ goto fail; |
||||
|
||||
r = sd_bus_get_timeout(bus, &until); |
||||
if (r < 0) |
||||
- return r; |
||||
+ goto fail; |
||||
if (r > 0) { |
||||
int j; |
||||
|
||||
j = sd_event_source_set_time(bus->time_event_source, until); |
||||
- if (j < 0) |
||||
- return j; |
||||
+ if (j < 0) { |
||||
+ r = j; |
||||
+ goto fail; |
||||
+ } |
||||
} |
||||
|
||||
r = sd_event_source_set_enabled(bus->time_event_source, r > 0); |
||||
if (r < 0) |
||||
- return r; |
||||
+ goto fail; |
||||
+ |
||||
+ return 1; |
||||
+ |
||||
+fail: |
||||
+ log_debug_errno(r, "Preparing of bus events failed, closing down: %m"); |
||||
+ bus_enter_closing(bus); |
||||
|
||||
return 1; |
||||
} |
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
From 8a98e68dc1fdf10881fffc40604dfd28a49fdc27 Mon Sep 17 00:00:00 2001 |
||||
From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com> |
||||
Date: Tue, 4 Feb 2020 14:23:14 +0100 |
||||
Subject: [PATCH] sd-journal: close journal files that were deleted by journald |
||||
before we've setup inotify watch |
||||
|
||||
(cherry-picked from commit 28ca867abdb20d0e4ac1901e2ed669cdb41ea3f6) |
||||
|
||||
Fixes #14695 |
||||
|
||||
Related: #1812889 |
||||
--- |
||||
src/journal/journal-file.c | 2 +- |
||||
src/journal/journal-file.h | 1 + |
||||
src/journal/sd-journal.c | 15 +++++++++++++++ |
||||
3 files changed, 17 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c |
||||
index cf8dad3fcd..86a7e2642a 100644 |
||||
--- a/src/journal/journal-file.c |
||||
+++ b/src/journal/journal-file.c |
||||
@@ -337,7 +337,7 @@ static int journal_file_verify_header(JournalFile *f) { |
||||
return 0; |
||||
} |
||||
|
||||
-static int journal_file_fstat(JournalFile *f) { |
||||
+int journal_file_fstat(JournalFile *f) { |
||||
assert(f); |
||||
assert(f->fd >= 0); |
||||
|
||||
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h |
||||
index 37749c4459..ee9772b9bb 100644 |
||||
--- a/src/journal/journal-file.h |
||||
+++ b/src/journal/journal-file.h |
||||
@@ -139,6 +139,7 @@ int journal_file_open( |
||||
|
||||
int journal_file_set_offline(JournalFile *f); |
||||
void journal_file_close(JournalFile *j); |
||||
+int journal_file_fstat(JournalFile *j); |
||||
|
||||
int journal_file_open_reliably( |
||||
const char *fname, |
||||
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c |
||||
index 004fe646d4..09466df810 100644 |
||||
--- a/src/journal/sd-journal.c |
||||
+++ b/src/journal/sd-journal.c |
||||
@@ -2386,6 +2386,8 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { |
||||
assert_return(!journal_pid_changed(j), -ECHILD); |
||||
|
||||
if (j->inotify_fd < 0) { |
||||
+ Iterator i; |
||||
+ JournalFile *f; |
||||
|
||||
/* This is the first invocation, hence create the |
||||
* inotify watch */ |
||||
@@ -2393,6 +2395,19 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { |
||||
if (r < 0) |
||||
return r; |
||||
|
||||
+ /* Server might have done some vacuuming while we weren't watching. |
||||
+ Get rid of the deleted files now so they don't stay around indefinitely. */ |
||||
+ ORDERED_HASHMAP_FOREACH(f, j->files, i) { |
||||
+ r = journal_file_fstat(f); |
||||
+ if (r < 0) { |
||||
+ log_error("Failed to fstat() journal file '%s' : %m", f->path); |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
+ if (f->last_stat.st_nlink <= 0) |
||||
+ remove_file_real(j, f); |
||||
+ } |
||||
+ |
||||
/* The journal might have changed since the context |
||||
* object was created and we weren't watching before, |
||||
* hence don't wait for anything, and return |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
From 7fe6194a2a7872532f121e6159d4fa60d1c85c50 Mon Sep 17 00:00:00 2001 |
||||
From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com> |
||||
Date: Fri, 27 Mar 2020 17:01:59 +0100 |
||||
Subject: [PATCH] sd-journal: remove the dead code and actually fix #14695 |
||||
|
||||
journal_file_fstat() returns an error if we call it on already unlinked |
||||
journal file and hence we never reach remove_file_real() which is the |
||||
entire point. |
||||
|
||||
I must have made some mistake while testing the fix that got me thinking |
||||
the issue is gone while opposite was true. |
||||
|
||||
Fixes #14695 |
||||
|
||||
(cherry-picked from commit 8581b9f9732d4c158bb5f773230a65ce77f2c292) |
||||
|
||||
Resolves: #1812889 |
||||
--- |
||||
src/journal/sd-journal.c | 7 +++---- |
||||
1 file changed, 3 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c |
||||
index 09466df810..1f03c8e8ba 100644 |
||||
--- a/src/journal/sd-journal.c |
||||
+++ b/src/journal/sd-journal.c |
||||
@@ -2399,13 +2399,12 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { |
||||
Get rid of the deleted files now so they don't stay around indefinitely. */ |
||||
ORDERED_HASHMAP_FOREACH(f, j->files, i) { |
||||
r = journal_file_fstat(f); |
||||
- if (r < 0) { |
||||
+ if (r == -EIDRM) |
||||
+ remove_file_real(j, f); |
||||
+ else if (r < 0) { |
||||
log_error("Failed to fstat() journal file '%s' : %m", f->path); |
||||
continue; |
||||
} |
||||
- |
||||
- if (f->last_stat.st_nlink <= 0) |
||||
- remove_file_real(j, f); |
||||
} |
||||
|
||||
/* The journal might have changed since the context |
@ -0,0 +1,259 @@
@@ -0,0 +1,259 @@
|
||||
From b77d7c2a22c679cb9445f34c59462804051bd12f Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Mon, 25 Sep 2017 19:53:19 +0200 |
||||
Subject: [PATCH] swap: adjust swap.c in a similar way to what we just did to |
||||
mount.c |
||||
|
||||
Also drop the redundant states and make all similar changes too. |
||||
Thankfully the swap.c state engine is much simpler than mount.c's, hence |
||||
this should be easier to digest. |
||||
|
||||
(cherry picked from commit 50864457e1bc5f7a4ab2fd02e1565bc5d135d2f3) |
||||
|
||||
Related: #1749621 |
||||
--- |
||||
src/core/swap.c | 96 +++++++++++++++++++++++-------------------------- |
||||
src/core/swap.h | 2 -- |
||||
2 files changed, 44 insertions(+), 54 deletions(-) |
||||
|
||||
diff --git a/src/core/swap.c b/src/core/swap.c |
||||
index 4a5e882332..c9cce3d945 100644 |
||||
--- a/src/core/swap.c |
||||
+++ b/src/core/swap.c |
||||
@@ -49,8 +49,6 @@ static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = { |
||||
[SWAP_ACTIVATING_DONE] = UNIT_ACTIVE, |
||||
[SWAP_ACTIVE] = UNIT_ACTIVE, |
||||
[SWAP_DEACTIVATING] = UNIT_DEACTIVATING, |
||||
- [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING, |
||||
- [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING, |
||||
[SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING, |
||||
[SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING, |
||||
[SWAP_FAILED] = UNIT_FAILED |
||||
@@ -490,8 +488,6 @@ static void swap_set_state(Swap *s, SwapState state) { |
||||
s->state = state; |
||||
|
||||
if (state != SWAP_ACTIVATING && |
||||
- state != SWAP_ACTIVATING_SIGTERM && |
||||
- state != SWAP_ACTIVATING_SIGKILL && |
||||
state != SWAP_ACTIVATING_DONE && |
||||
state != SWAP_DEACTIVATING && |
||||
state != SWAP_DEACTIVATING_SIGTERM && |
||||
@@ -538,8 +534,6 @@ static int swap_coldplug(Unit *u, Hashmap *deferred_work) { |
||||
return 0; |
||||
|
||||
if (new_state == SWAP_ACTIVATING || |
||||
- new_state == SWAP_ACTIVATING_SIGTERM || |
||||
- new_state == SWAP_ACTIVATING_SIGKILL || |
||||
new_state == SWAP_ACTIVATING_DONE || |
||||
new_state == SWAP_DEACTIVATING || |
||||
new_state == SWAP_DEACTIVATING_SIGTERM || |
||||
@@ -682,6 +676,15 @@ static void swap_enter_active(Swap *s, SwapResult f) { |
||||
swap_set_state(s, SWAP_ACTIVE); |
||||
} |
||||
|
||||
+static void swap_enter_dead_or_active(Swap *s, SwapResult f) { |
||||
+ assert(s); |
||||
+ |
||||
+ if (s->from_proc_swaps) |
||||
+ swap_enter_active(s, f); |
||||
+ else |
||||
+ swap_enter_dead(s, f); |
||||
+} |
||||
+ |
||||
static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { |
||||
int r; |
||||
|
||||
@@ -693,8 +696,7 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { |
||||
r = unit_kill_context( |
||||
UNIT(s), |
||||
&s->kill_context, |
||||
- (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ? |
||||
- KILL_KILL : KILL_TERMINATE, |
||||
+ state != SWAP_DEACTIVATING_SIGTERM ? KILL_KILL : KILL_TERMINATE, |
||||
-1, |
||||
s->control_pid, |
||||
false); |
||||
@@ -707,18 +709,16 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { |
||||
goto fail; |
||||
|
||||
swap_set_state(s, state); |
||||
- } else if (state == SWAP_ACTIVATING_SIGTERM) |
||||
- swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS); |
||||
- else if (state == SWAP_DEACTIVATING_SIGTERM) |
||||
+ } else if (state == SWAP_DEACTIVATING_SIGTERM && s->kill_context.send_sigkill) |
||||
swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS); |
||||
else |
||||
- swap_enter_dead(s, SWAP_SUCCESS); |
||||
+ swap_enter_dead_or_active(s, SWAP_SUCCESS); |
||||
|
||||
return; |
||||
|
||||
fail: |
||||
log_unit_warning_errno(UNIT(s)->id, r, "%s failed to kill processes: %m", UNIT(s)->id); |
||||
- swap_enter_dead(s, SWAP_FAILURE_RESOURCES); |
||||
+ swap_enter_dead_or_active(s, SWAP_FAILURE_RESOURCES); |
||||
} |
||||
|
||||
static void swap_enter_activating(Swap *s) { |
||||
@@ -781,7 +781,7 @@ static void swap_enter_activating(Swap *s) { |
||||
|
||||
fail: |
||||
log_unit_warning_errno(UNIT(s)->id, r, "%s failed to run 'swapon' task: %m", UNIT(s)->id); |
||||
- swap_enter_dead(s, SWAP_FAILURE_RESOURCES); |
||||
+ swap_enter_dead_or_active(s, SWAP_FAILURE_RESOURCES); |
||||
} |
||||
|
||||
static void swap_enter_deactivating(Swap *s) { |
||||
@@ -811,7 +811,7 @@ static void swap_enter_deactivating(Swap *s) { |
||||
|
||||
fail: |
||||
log_unit_warning_errno(UNIT(s)->id, r, "%s failed to run 'swapoff' task: %m", UNIT(s)->id); |
||||
- swap_enter_active(s, SWAP_FAILURE_RESOURCES); |
||||
+ swap_enter_dead_or_active(s, SWAP_FAILURE_RESOURCES); |
||||
} |
||||
|
||||
static int swap_start(Unit *u) { |
||||
@@ -824,11 +824,10 @@ static int swap_start(Unit *u) { |
||||
|
||||
if (s->state == SWAP_DEACTIVATING || |
||||
s->state == SWAP_DEACTIVATING_SIGTERM || |
||||
- s->state == SWAP_DEACTIVATING_SIGKILL || |
||||
- s->state == SWAP_ACTIVATING_SIGTERM || |
||||
- s->state == SWAP_ACTIVATING_SIGKILL) |
||||
+ s->state == SWAP_DEACTIVATING_SIGKILL) |
||||
return -EAGAIN; |
||||
|
||||
+ /* Already on it! */ |
||||
if (s->state == SWAP_ACTIVATING) |
||||
return 0; |
||||
|
||||
@@ -854,22 +853,30 @@ static int swap_stop(Unit *u) { |
||||
|
||||
assert(s); |
||||
|
||||
- if (s->state == SWAP_DEACTIVATING || |
||||
- s->state == SWAP_DEACTIVATING_SIGTERM || |
||||
- s->state == SWAP_DEACTIVATING_SIGKILL || |
||||
- s->state == SWAP_ACTIVATING_SIGTERM || |
||||
- s->state == SWAP_ACTIVATING_SIGKILL) |
||||
+ switch (s->state) { |
||||
+ |
||||
+ case SWAP_DEACTIVATING: |
||||
+ case SWAP_DEACTIVATING_SIGTERM: |
||||
+ case SWAP_DEACTIVATING_SIGKILL: |
||||
+ /* Already on it */ |
||||
+ return 0; |
||||
+ |
||||
+ case SWAP_ACTIVATING: |
||||
+ case SWAP_ACTIVATING_DONE: |
||||
+ /* There's a control process pending, directly enter kill mode */ |
||||
+ swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_SUCCESS); |
||||
return 0; |
||||
|
||||
- assert(s->state == SWAP_ACTIVATING || |
||||
- s->state == SWAP_ACTIVATING_DONE || |
||||
- s->state == SWAP_ACTIVE); |
||||
+ case SWAP_ACTIVE: |
||||
+ if (detect_container(NULL) > 0) |
||||
+ return -EPERM; |
||||
|
||||
- if (detect_container(NULL) > 0) |
||||
- return -EPERM; |
||||
+ swap_enter_deactivating(s); |
||||
+ return 1; |
||||
|
||||
- swap_enter_deactivating(s); |
||||
- return 1; |
||||
+ default: |
||||
+ assert_not_reached("Unexpected state."); |
||||
+ } |
||||
} |
||||
|
||||
static int swap_serialize(Unit *u, FILE *f, FDSet *fds) { |
||||
@@ -1002,10 +1009,8 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { |
||||
|
||||
case SWAP_ACTIVATING: |
||||
case SWAP_ACTIVATING_DONE: |
||||
- case SWAP_ACTIVATING_SIGTERM: |
||||
- case SWAP_ACTIVATING_SIGKILL: |
||||
|
||||
- if (f == SWAP_SUCCESS) |
||||
+ if (f == SWAP_SUCCESS || s->from_proc_swaps) |
||||
swap_enter_active(s, f); |
||||
else |
||||
swap_enter_dead(s, f); |
||||
@@ -1015,7 +1020,7 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { |
||||
case SWAP_DEACTIVATING_SIGKILL: |
||||
case SWAP_DEACTIVATING_SIGTERM: |
||||
|
||||
- swap_enter_dead(s, f); |
||||
+ swap_enter_dead_or_active(s, f); |
||||
break; |
||||
|
||||
default: |
||||
@@ -1037,7 +1042,7 @@ static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userd |
||||
case SWAP_ACTIVATING: |
||||
case SWAP_ACTIVATING_DONE: |
||||
log_unit_warning(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id); |
||||
- swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); |
||||
+ swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); |
||||
break; |
||||
|
||||
case SWAP_DEACTIVATING: |
||||
@@ -1045,30 +1050,19 @@ static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userd |
||||
swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); |
||||
break; |
||||
|
||||
- case SWAP_ACTIVATING_SIGTERM: |
||||
- if (s->kill_context.send_sigkill) { |
||||
- log_unit_warning(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id); |
||||
- swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); |
||||
- } else { |
||||
- log_unit_warning(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id); |
||||
- swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); |
||||
- } |
||||
- break; |
||||
- |
||||
case SWAP_DEACTIVATING_SIGTERM: |
||||
if (s->kill_context.send_sigkill) { |
||||
- log_unit_warning(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id); |
||||
+ log_unit_warning(UNIT(s)->id, "Swap process timed out. Killing."); |
||||
swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); |
||||
} else { |
||||
- log_unit_warning(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id); |
||||
- swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); |
||||
+ log_unit_warning(UNIT(s)->id, "Swap process timed out. Skipping SIGKILL. Ignoring."); |
||||
+ swap_enter_dead_or_active(s, SWAP_FAILURE_TIMEOUT); |
||||
} |
||||
break; |
||||
|
||||
- case SWAP_ACTIVATING_SIGKILL: |
||||
case SWAP_DEACTIVATING_SIGKILL: |
||||
log_unit_warning(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id); |
||||
- swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); |
||||
+ swap_enter_dead_or_active(s, SWAP_FAILURE_TIMEOUT); |
||||
break; |
||||
|
||||
default: |
||||
@@ -1428,8 +1422,6 @@ static const char* const swap_state_table[_SWAP_STATE_MAX] = { |
||||
[SWAP_ACTIVATING_DONE] = "activating-done", |
||||
[SWAP_ACTIVE] = "active", |
||||
[SWAP_DEACTIVATING] = "deactivating", |
||||
- [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm", |
||||
- [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill", |
||||
[SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm", |
||||
[SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill", |
||||
[SWAP_FAILED] = "failed" |
||||
diff --git a/src/core/swap.h b/src/core/swap.h |
||||
index 914a2dbccd..f46873b5e1 100644 |
||||
--- a/src/core/swap.h |
||||
+++ b/src/core/swap.h |
||||
@@ -34,8 +34,6 @@ typedef enum SwapState { |
||||
SWAP_ACTIVATING_DONE, /* /sbin/swapon is running, and the swap is done. */ |
||||
SWAP_ACTIVE, |
||||
SWAP_DEACTIVATING, |
||||
- SWAP_ACTIVATING_SIGTERM, |
||||
- SWAP_ACTIVATING_SIGKILL, |
||||
SWAP_DEACTIVATING_SIGTERM, |
||||
SWAP_DEACTIVATING_SIGKILL, |
||||
SWAP_FAILED, |
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
From e2cf8d5fcec71c1c4ca7223c51552847eb2a456e Mon Sep 17 00:00:00 2001 |
||||
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com> |
||||
Date: Wed, 24 Jul 2019 23:54:48 -0400 |
||||
Subject: [PATCH] swap: finish the secondary swap units' jobs if deactivation |
||||
of the primary swap unit fails |
||||
|
||||
Currently, if deactivation of the primary swap unit fails: |
||||
|
||||
# LANG=C systemctl --no-pager stop dev-mapper-fedora\\x2dswap.swap |
||||
Job for dev-mapper-fedora\x2dswap.swap failed. |
||||
See "systemctl status "dev-mapper-fedora\\x2dswap.swap"" and "journalctl -xe" for details. |
||||
|
||||
then there are still the running stop jobs for all the secondary swap units |
||||
that follow the primary one: |
||||
|
||||
# systemctl list-jobs |
||||
JOB UNIT TYPE STATE |
||||
3233 dev-disk-by\x2duuid-2dc8b9b1\x2da0a5\x2d44d8\x2d89c4\x2d6cdd26cd5ce0.swap stop running |
||||
3232 dev-dm\x2d1.swap stop running |
||||
3231 dev-disk-by\x2did-dm\x2duuid\x2dLVM\x2dyuXWpCCIurGzz2nkGCVnUFSi7GH6E3ZcQjkKLnF0Fil0RJmhoLN8fcOnDybWCMTj.swap stop running |
||||
3230 dev-disk-by\x2did-dm\x2dname\x2dfedora\x2dswap.swap stop running |
||||
3234 dev-fedora-swap.swap stop running |
||||
|
||||
5 jobs listed. |
||||
|
||||
This remains endlessly because their JobTimeoutUSec is infinity: |
||||
|
||||
# LANG=C systemctl show -p JobTimeoutUSec dev-fedora-swap.swap |
||||
JobTimeoutUSec=infinity |
||||
|
||||
If this issue happens during system shutdown, the system shutdown appears to |
||||
get hang and the system will be forcibly shutdown or rebooted 30 minutes later |
||||
by the following configuration: |
||||
|
||||
# grep -E "^JobTimeout" /usr/lib/systemd/system/reboot.target |
||||
JobTimeoutSec=30min |
||||
JobTimeoutAction=reboot-force |
||||
|
||||
The scenario in the real world seems that there is some service unit with |
||||
KillMode=none, processes whose memory is being swapped out are not killed |
||||
during stop operation in the service unit and then swapoff command fails. |
||||
|
||||
On the other hand, it works well in successful case of swapoff command because |
||||
the secondary jobs monitor /proc/swaps file and can detect deletion of the |
||||
corresponding swap file. |
||||
|
||||
This commit fixes the issue by finishing the secondary swap units' jobs if |
||||
deactivation of the primary swap unit fails. |
||||
|
||||
Fixes: #11577 |
||||
(cherry picked from commit 9c1f969d40f84d5cc98d810bab8b24148b2d8928) |
||||
|
||||
Resolves: #1749621 |
||||
--- |
||||
src/core/swap.c | 10 ++++++++-- |
||||
1 file changed, 8 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/src/core/swap.c b/src/core/swap.c |
||||
index c9cce3d945..ff27936142 100644 |
||||
--- a/src/core/swap.c |
||||
+++ b/src/core/swap.c |
||||
@@ -679,9 +679,15 @@ static void swap_enter_active(Swap *s, SwapResult f) { |
||||
static void swap_enter_dead_or_active(Swap *s, SwapResult f) { |
||||
assert(s); |
||||
|
||||
- if (s->from_proc_swaps) |
||||
+ if (s->from_proc_swaps) { |
||||
+ Swap *other; |
||||
+ |
||||
swap_enter_active(s, f); |
||||
- else |
||||
+ |
||||
+ LIST_FOREACH_OTHERS(same_devnode, other, s) |
||||
+ if (UNIT(other)->job) |
||||
+ swap_enter_dead_or_active(other, f); |
||||
+ } else |
||||
swap_enter_dead(s, f); |
||||
} |
||||
|
@ -0,0 +1,317 @@
@@ -0,0 +1,317 @@
|
||||
From 909d27fffffb28f4da7752be25e5c47990eba641 Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Mon, 13 Nov 2017 17:14:07 +0100 |
||||
Subject: [PATCH] core: add a new unit file setting CollectMode= for tweaking |
||||
the GC logic |
||||
|
||||
Right now, the option only takes one of two possible values "inactive" |
||||
or "inactive-or-failed", the former being the default, and exposing same |
||||
behaviour as the status quo ante. If set to "inactive-or-failed" units |
||||
may be collected by the GC logic when in the "failed" state too. |
||||
|
||||
This logic should be a nicer alternative to using the "-" modifier for |
||||
ExecStart= and friends, as the exit data is collected and logged about |
||||
and only removed when the GC comes along. This should be useful in |
||||
particular for per-connection socket-activated services, as well as |
||||
"systemd-run" command lines that shall leave no artifacts in the |
||||
system. |
||||
|
||||
I was thinking about whether to expose this as a boolean, but opted for |
||||
an enum instead, as I have the suspicion other tweaks like this might be |
||||
a added later on, in which case we extend this setting instead of having |
||||
to add yet another one. |
||||
|
||||
Also, let's add some documentation for the GC logic. |
||||
|
||||
(cherry-picked from commit 5afe510c89f26b0e721b276a0e78af914b47f0b0) |
||||
|
||||
Resolves: #1817576 |
||||
--- |
||||
man/systemd.unit.xml | 56 +++++++++++++++++++++++++++ |
||||
src/core/dbus-unit.c | 20 ++++++++++ |
||||
src/core/load-fragment-gperf.gperf.m4 | 1 + |
||||
src/core/load-fragment.c | 2 + |
||||
src/core/load-fragment.h | 1 + |
||||
src/core/unit.c | 36 ++++++++++++++--- |
||||
src/core/unit.h | 13 +++++++ |
||||
7 files changed, 124 insertions(+), 5 deletions(-) |
||||
|
||||
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml |
||||
index 414749bae9..0c06add166 100644 |
||||
--- a/man/systemd.unit.xml |
||||
+++ b/man/systemd.unit.xml |
||||
@@ -303,6 +303,45 @@ |
||||
</para> |
||||
</refsect1> |
||||
|
||||
+ <refsect1> |
||||
+ <title>Unit Garbage Collection</title> |
||||
+ |
||||
+ <para>The system and service manager loads a unit's configuration automatically when a unit is referenced for the |
||||
+ first time. It will automatically unload the unit configuration and state again when the unit is not needed anymore |
||||
+ ("garbage collection"). A unit may be referenced through a number of different mechanisms:</para> |
||||
+ |
||||
+ <orderedlist> |
||||
+ <listitem><para>Another loaded unit references it with a dependency such as <varname>After=</varname>, |
||||
+ <varname>Wants=</varname>, …</para></listitem> |
||||
+ |
||||
+ <listitem><para>The unit is currently starting, running, reloading or stopping.</para></listitem> |
||||
+ |
||||
+ <listitem><para>The unit is currently in the <constant>failed</constant> state. (But see below.)</para></listitem> |
||||
+ |
||||
+ <listitem><para>A job for the unit is pending.</para></listitem> |
||||
+ |
||||
+ <listitem><para>The unit is pinned by an active IPC client program.</para></listitem> |
||||
+ |
||||
+ <listitem><para>The unit is a special "perpetual" unit that is always active and loaded. Examples for perpetual |
||||
+ units are the root mount unit <filename>-.mount</filename> or the scope unit <filename>init.scope</filename> that |
||||
+ the service manager itself lives in.</para></listitem> |
||||
+ |
||||
+ <listitem><para>The unit has running processes associated with it.</para></listitem> |
||||
+ </orderedlist> |
||||
+ |
||||
+ <para>The garbage collection logic may be altered with the <varname>CollectMode=</varname> option, which allows |
||||
+ configuration whether automatic unloading of units that are in <constant>failed</constant> state is permissible, |
||||
+ see below.</para> |
||||
+ |
||||
+ <para>Note that when a unit's configuration and state is unloaded, all execution results, such as exit codes, exit |
||||
+ signals, resource consumption and other statistics are lost, except for what is stored in the log subsystem.</para> |
||||
+ |
||||
+ <para>Use <command>systemctl daemon-reload</command> or an equivalent command to reload unit configuration while |
||||
+ the unit is already loaded. In this case all configuration settings are flushed out and replaced with the new |
||||
+ configuration (which however might not be in effect immediately), however all runtime state is |
||||
+ saved/restored.</para> |
||||
+ </refsect1> |
||||
+ |
||||
<refsect1> |
||||
<title>[Unit] Section Options</title> |
||||
|
||||
@@ -666,6 +705,23 @@ |
||||
ones.</para></listitem> |
||||
</varlistentry> |
||||
|
||||
+ <varlistentry> |
||||
+ <term><varname>CollectMode=</varname></term> |
||||
+ |
||||
+ <listitem><para>Tweaks the "garbage collection" algorithm for this unit. Takes one of <option>inactive</option> |
||||
+ or <option>inactive-or-failed</option>. If set to <option>inactive</option> the unit will be unloaded if it is |
||||
+ in the <constant>inactive</constant> state and is not referenced by clients, jobs or other units — however it |
||||
+ is not unloaded if it is in the <constant>failed</constant> state. In <option>failed</option> mode, failed |
||||
+ units are not unloaded until the user invoked <command>systemctl reset-failed</command> on them to reset the |
||||
+ <constant>failed</constant> state, or an equivalent command. This behaviour is altered if this option is set to |
||||
+ <option>inactive-or-failed</option>: in this case the unit is unloaded even if the unit is in a |
||||
+ <constant>failed</constant> state, and thus an explicitly resetting of the <constant>failed</constant> state is |
||||
+ not necessary. Note that if this mode is used unit results (such as exit codes, exit signals, consumed |
||||
+ resources, …) are flushed out immediately after the unit completed, except for what is stored in the logging |
||||
+ subsystem. Defaults to <option>inactive</option>.</para> |
||||
+ </listitem> |
||||
+ </varlistentry> |
||||
+ |
||||
<varlistentry> |
||||
<term><varname>JobTimeoutSec=</varname></term> |
||||
<term><varname>JobTimeoutAction=</varname></term> |
||||
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c |
||||
index 77073308c8..ea6ac6767f 100644 |
||||
--- a/src/core/dbus-unit.c |
||||
+++ b/src/core/dbus-unit.c |
||||
@@ -34,6 +34,7 @@ |
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState); |
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode); |
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction); |
||||
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode); |
||||
|
||||
static int property_get_names( |
||||
sd_bus *bus, |
||||
@@ -605,6 +606,7 @@ const sd_bus_vtable bus_unit_vtable[] = { |
||||
SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0), |
||||
SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST), |
||||
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST), |
||||
+ SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), 0), |
||||
|
||||
SD_BUS_METHOD("Start", "s", "o", method_start, 0), |
||||
SD_BUS_METHOD("Stop", "s", "o", method_stop, 0), |
||||
@@ -937,6 +939,24 @@ static int bus_unit_set_transient_property( |
||||
|
||||
return 1; |
||||
|
||||
+ } else if (streq(name, "CollectMode")) { |
||||
+ const char *s; |
||||
+ CollectMode m; |
||||
+ |
||||
+ r = sd_bus_message_read(message, "s", &s); |
||||
+ if (r < 0) |
||||
+ return r; |
||||
+ |
||||
+ m = collect_mode_from_string(s); |
||||
+ if (m < 0) |
||||
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown garbage collection mode: %s", s); |
||||
+ |
||||
+ if (mode != UNIT_CHECK) { |
||||
+ u->collect_mode = m; |
||||
+ unit_write_drop_in_format(u, mode, name, "[Unit]\nCollectMode=%s", collect_mode_to_string(m)); |
||||
+ } |
||||
+ |
||||
+ return 1; |
||||
} else if (streq(name, "Slice") && unit_get_cgroup_context(u)) { |
||||
const char *s; |
||||
|
||||
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 |
||||
index 664bba0ef6..3a8ee96fa3 100644 |
||||
--- a/src/core/load-fragment-gperf.gperf.m4 |
||||
+++ b/src/core/load-fragment-gperf.gperf.m4 |
||||
@@ -200,6 +200,7 @@ Unit.AssertCapability, config_parse_unit_condition_string, CONDITION_C |
||||
Unit.AssertHost, config_parse_unit_condition_string, CONDITION_HOST, offsetof(Unit, asserts) |
||||
Unit.AssertACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, offsetof(Unit, asserts) |
||||
Unit.AssertNull, config_parse_unit_condition_null, 0, offsetof(Unit, asserts) |
||||
+Unit.CollectMode, config_parse_collect_mode, 0, offsetof(Unit, collect_mode) |
||||
m4_dnl |
||||
Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file) |
||||
Service.ExecStartPre, config_parse_exec, SERVICE_EXEC_START_PRE, offsetof(Service, exec_command) |
||||
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c |
||||
index 1721fea8f3..8d73d5df41 100644 |
||||
--- a/src/core/load-fragment.c |
||||
+++ b/src/core/load-fragment.c |
||||
@@ -98,6 +98,8 @@ int config_parse_warn_compat( |
||||
return 0; |
||||
} |
||||
|
||||
+DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, "Failed to parse garbage collection mode"); |
||||
+ |
||||
int config_parse_unit_deps(const char *unit, |
||||
const char *filename, |
||||
unsigned line, |
||||
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h |
||||
index 4bd286c11b..7b1193ddb2 100644 |
||||
--- a/src/core/load-fragment.h |
||||
+++ b/src/core/load-fragment.h |
||||
@@ -110,6 +110,7 @@ int config_parse_cpu_quota(const char *unit, const char *filename, unsigned line |
||||
int config_parse_protect_home(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); |
||||
int config_parse_protect_system(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); |
||||
int config_parse_bus_name(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); |
||||
+int config_parse_collect_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); |
||||
|
||||
/* gperf prototypes */ |
||||
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length); |
||||
diff --git a/src/core/unit.c b/src/core/unit.c |
||||
index eff9fdbe70..502830d2cb 100644 |
||||
--- a/src/core/unit.c |
||||
+++ b/src/core/unit.c |
||||
@@ -67,7 +67,7 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { |
||||
[UNIT_TIMER] = &timer_vtable, |
||||
[UNIT_PATH] = &path_vtable, |
||||
[UNIT_SLICE] = &slice_vtable, |
||||
- [UNIT_SCOPE] = &scope_vtable |
||||
+ [UNIT_SCOPE] = &scope_vtable, |
||||
}; |
||||
|
||||
static int maybe_warn_about_dependency(const char *id, const char *other, UnitDependency dependency); |
||||
@@ -285,6 +285,7 @@ int unit_set_description(Unit *u, const char *description) { |
||||
|
||||
bool unit_may_gc(Unit *u) { |
||||
UnitActiveState state; |
||||
+ |
||||
assert(u); |
||||
|
||||
/* Checks whether the unit is ready to be unloaded for garbage collection. |
||||
@@ -308,16 +309,31 @@ bool unit_may_gc(Unit *u) { |
||||
UNIT_VTABLE(u)->release_resources) |
||||
UNIT_VTABLE(u)->release_resources(u); |
||||
|
||||
- /* But we keep the unit object around for longer when it is referenced or configured to not be gc'ed */ |
||||
- if (state != UNIT_INACTIVE) |
||||
- return false; |
||||
- |
||||
if (UNIT_VTABLE(u)->no_gc) |
||||
return false; |
||||
|
||||
if (u->no_gc) |
||||
return false; |
||||
|
||||
+ /* But we keep the unit object around for longer when it is referenced or configured to not be gc'ed */ |
||||
+ switch (u->collect_mode) { |
||||
+ |
||||
+ case COLLECT_INACTIVE: |
||||
+ if (state != UNIT_INACTIVE) |
||||
+ return false; |
||||
+ |
||||
+ break; |
||||
+ |
||||
+ case COLLECT_INACTIVE_OR_FAILED: |
||||
+ if (!IN_SET(state, UNIT_INACTIVE, UNIT_FAILED)) |
||||
+ return false; |
||||
+ |
||||
+ break; |
||||
+ |
||||
+ default: |
||||
+ assert_not_reached("Unknown garbage collection mode"); |
||||
+ } |
||||
+ |
||||
if (UNIT_VTABLE(u)->may_gc && !UNIT_VTABLE(u)->may_gc(u)) |
||||
return false; |
||||
|
||||
@@ -896,6 +912,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { |
||||
"%s\tMay GC: %s\n" |
||||
"%s\tNeed Daemon Reload: %s\n" |
||||
"%s\tTransient: %s\n" |
||||
+ "%s\tGarbage Collection Mode: %s\n" |
||||
"%s\tSlice: %s\n" |
||||
"%s\tCGroup: %s\n" |
||||
"%s\tCGroup realized: %s\n" |
||||
@@ -913,6 +930,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { |
||||
prefix, yes_no(unit_may_gc(u)), |
||||
prefix, yes_no(unit_need_daemon_reload(u)), |
||||
prefix, yes_no(u->transient), |
||||
+ prefix, collect_mode_to_string(u->collect_mode), |
||||
prefix, strna(unit_slice_name(u)), |
||||
prefix, strna(u->cgroup_path), |
||||
prefix, yes_no(u->cgroup_realized), |
||||
@@ -3732,3 +3750,11 @@ static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = { |
||||
}; |
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState); |
||||
+ |
||||
+static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { |
||||
+ [COLLECT_INACTIVE] = "inactive", |
||||
+ [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", |
||||
+}; |
||||
+ |
||||
+DEFINE_STRING_TABLE_LOOKUP(collect_mode, CollectMode); |
||||
+ |
||||
diff --git a/src/core/unit.h b/src/core/unit.h |
||||
index 3b0fd8d9df..8cc7a9e0b2 100644 |
||||
--- a/src/core/unit.h |
||||
+++ b/src/core/unit.h |
||||
@@ -60,6 +60,13 @@ typedef enum KillOperation { |
||||
KILL_ABORT, |
||||
} KillOperation; |
||||
|
||||
+typedef enum CollectMode { |
||||
+ COLLECT_INACTIVE, |
||||
+ COLLECT_INACTIVE_OR_FAILED, |
||||
+ _COLLECT_MODE_MAX, |
||||
+ _COLLECT_MODE_INVALID = -1, |
||||
+} CollectMode; |
||||
+ |
||||
static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) { |
||||
return t == UNIT_ACTIVE || t == UNIT_RELOADING; |
||||
} |
||||
@@ -198,6 +205,9 @@ struct Unit { |
||||
/* How to start OnFailure units */ |
||||
JobMode on_failure_job_mode; |
||||
|
||||
+ /* Tweaking the GC logic */ |
||||
+ CollectMode collect_mode; |
||||
+ |
||||
/* Garbage collect us we nobody wants or requires us anymore */ |
||||
bool stop_when_unneeded; |
||||
|
||||
@@ -630,6 +640,9 @@ pid_t unit_main_pid(Unit *u); |
||||
const char *unit_active_state_to_string(UnitActiveState i) _const_; |
||||
UnitActiveState unit_active_state_from_string(const char *s) _pure_; |
||||
|
||||
+const char* collect_mode_to_string(CollectMode m) _const_; |
||||
+CollectMode collect_mode_from_string(const char *s) _pure_; |
||||
+ |
||||
bool unit_needs_console(Unit *u); |
||||
|
||||
/* Macros which append UNIT= or USER_UNIT= to the message */ |
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
From c2975479c63cafea5a5f0254f4525136244f3301 Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Mon, 13 Nov 2017 17:17:53 +0100 |
||||
Subject: [PATCH] run: add "-G" as shortcut for |
||||
"--property=CollectMode=inactive-or-failed" |
||||
|
||||
This option is likely to be very useful for systemd-run invocations, |
||||
hence let's add a shortcut for it. |
||||
|
||||
With this new concepts it's now very easy to put together systemd-run |
||||
invocations that leave zero artifacts in the system, including when they |
||||
fail. |
||||
|
||||
(cherry-picked from commit fe9d0be90ba142bf06d43a831d8be53283415caa) |
||||
|
||||
Related: #1817576 |
||||
--- |
||||
man/systemd-run.xml | 15 +++++++++++++++ |
||||
src/run/run.c | 15 ++++++++++++++- |
||||
2 files changed, 29 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/man/systemd-run.xml b/man/systemd-run.xml |
||||
index f46fc3abf4..97cf2879eb 100644 |
||||
--- a/man/systemd-run.xml |
||||
+++ b/man/systemd-run.xml |
||||
@@ -294,6 +294,21 @@ |
||||
<command>set-property</command> command.</para> </listitem> |
||||
</varlistentry> |
||||
|
||||
+ <varlistentry> |
||||
+ <term><option>-G</option></term> |
||||
+ <term><option>--collect</option></term> |
||||
+ |
||||
+ <listitem><para>Unload the transient unit after it completed, even if it failed. Normally, without this option, |
||||
+ all units that ran and failed are kept in memory until the user explicitly resets their failure state with |
||||
+ <command>systemctl reset-failed</command> or an equivalent command. On the other hand, units that ran |
||||
+ successfully are unloaded immediately. If this option is turned on the "garbage collection" of units is more |
||||
+ aggressive, and unloads units regardless if they exited successfully or failed. This option is a shortcut for |
||||
+ <command>--property=CollectMode=inactive-or-failed</command>, see the explanation for |
||||
+ <varname>CollectMode=</varname> in |
||||
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for further |
||||
+ information.</para></listitem> |
||||
+ </varlistentry> |
||||
+ |
||||
<xi:include href="user-system-options.xml" xpointer="system" /> |
||||
<xi:include href="user-system-options.xml" xpointer="host" /> |
||||
<xi:include href="user-system-options.xml" xpointer="machine" /> |
||||
diff --git a/src/run/run.c b/src/run/run.c |
||||
index bbb542b65b..df97641f87 100644 |
||||
--- a/src/run/run.c |
||||
+++ b/src/run/run.c |
||||
@@ -60,6 +60,7 @@ static usec_t arg_on_unit_inactive = 0; |
||||
static char *arg_on_calendar = NULL; |
||||
static char **arg_timer_property = NULL; |
||||
static bool arg_quiet = false; |
||||
+static bool arg_aggressive_gc = false; |
||||
|
||||
static void help(void) { |
||||
printf("%s [OPTIONS...] {COMMAND} [ARGS...]\n\n" |
||||
@@ -84,6 +85,7 @@ static void help(void) { |
||||
" --setenv=NAME=VALUE Set environment\n" |
||||
" -t --pty Run service on pseudo tty\n" |
||||
" -q --quiet Suppress information messages during runtime\n\n" |
||||
+ " -G --collect Unload unit after it ran, even when failed\n\n" |
||||
"Timer options:\n\n" |
||||
" --on-active=SECONDS Run after SECONDS delay\n" |
||||
" --on-boot=SECONDS Run SECONDS after machine was booted up\n" |
||||
@@ -153,6 +155,7 @@ static int parse_argv(int argc, char *argv[]) { |
||||
{ "on-unit-inactive", required_argument, NULL, ARG_ON_UNIT_INACTIVE }, |
||||
{ "on-calendar", required_argument, NULL, ARG_ON_CALENDAR }, |
||||
{ "timer-property", required_argument, NULL, ARG_TIMER_PROPERTY }, |
||||
+ { "collect", no_argument, NULL, 'G' }, |
||||
{}, |
||||
}; |
||||
|
||||
@@ -162,7 +165,7 @@ static int parse_argv(int argc, char *argv[]) { |
||||
assert(argc >= 0); |
||||
assert(argv); |
||||
|
||||
- while ((c = getopt_long(argc, argv, "+hrH:M:p:tq", options, NULL)) >= 0) |
||||
+ while ((c = getopt_long(argc, argv, "+hrH:M:p:tqG", options, NULL)) >= 0) |
||||
|
||||
switch (c) { |
||||
|
||||
@@ -329,6 +332,10 @@ static int parse_argv(int argc, char *argv[]) { |
||||
|
||||
break; |
||||
|
||||
+ case 'G': |
||||
+ arg_aggressive_gc = true; |
||||
+ break; |
||||
+ |
||||
case '?': |
||||
return -EINVAL; |
||||
|
||||
@@ -382,6 +389,12 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) { |
||||
if (r < 0) |
||||
return r; |
||||
|
||||
+ if (arg_aggressive_gc) { |
||||
+ r = sd_bus_message_append(m, "(sv)", "CollectMode", "s", "inactive-or-failed"); |
||||
+ if (r < 0) |
||||
+ return r; |
||||
+ } |
||||
+ |
||||
STRV_FOREACH(i, properties) { |
||||
r = sd_bus_message_open_container(m, 'r', "sv"); |
||||
if (r < 0) |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
From b12e40d3e16b998542faef3fe916d5605b3fe0cb Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Thu, 29 Nov 2018 16:40:13 +0100 |
||||
Subject: [PATCH] core: clarify that the CollectMode bus property is constant |
||||
|
||||
it's configured from unit files only, and hence is constant. |
||||
|
||||
(cherry-picked from commit 641e0d7a1bf4e24f5bf5f99a2d74a97635335c8e) |
||||
|
||||
Related: #1817576 |
||||
--- |
||||
src/core/dbus-unit.c | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c |
||||
index ea6ac6767f..8febdfd021 100644 |
||||
--- a/src/core/dbus-unit.c |
||||
+++ b/src/core/dbus-unit.c |
||||
@@ -606,7 +606,7 @@ const sd_bus_vtable bus_unit_vtable[] = { |
||||
SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0), |
||||
SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST), |
||||
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST), |
||||
- SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), 0), |
||||
+ SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), SD_BUS_VTABLE_PROPERTY_CONST), |
||||
|
||||
SD_BUS_METHOD("Start", "s", "o", method_start, 0), |
||||
SD_BUS_METHOD("Stop", "s", "o", method_stop, 0), |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
From 1b723aea42e29becd0be2fdef990401803dbfba6 Mon Sep 17 00:00:00 2001 |
||||
From: Joerg Steffens <joerg.steffens@bareos.com> |
||||
Date: Tue, 21 Nov 2017 12:21:49 +0100 |
||||
Subject: [PATCH] udev-rules: make tape-changers also apprear in |
||||
/dev/tape/by-path/ |
||||
|
||||
It is important to be able to access tape changer ("Medium Changers") by |
||||
persistant name. |
||||
While tape devices can be accessed via /dev/tape/by-id/ and |
||||
/dev/tape/by-path/, tape-changers could only be accessed by |
||||
/dev/tape/by-id/. |
||||
However, in some cases, especially when accessing Amazon Webservice |
||||
Storage Gateway VTLs (or accessing iSCSI VTLs in general?) this does not |
||||
work, as all tape devices and the tape changer have the same ENV{ID_SERIAL}. |
||||
The results is, that only the last device is available in |
||||
/dev/tape/by-id/, as the former devices have been overwritten. |
||||
|
||||
As this behavior is hard to change without breaking consistentcy, |
||||
this additional device in /dev/tape/by-path/ can be used to access the medium changes. |
||||
The tape devices can also be accessed by this path. |
||||
|
||||
The content of the directory will now look like: |
||||
|
||||
# SCSI tape device, rewind (unchanged) |
||||
/dev/tape/by-path/$env{ID_PATH} -> ../../st* |
||||
|
||||
# SCSI tape device, no-rewind (unchanged) |
||||
/dev/tape/by-path/$env{ID_PATH}-nst -> ../../nst* |
||||
|
||||
# SCSI tape changer device (newly added) |
||||
/dev/tape/by-path/$env{ID_PATH}-changer -> ../../sg* |
||||
|
||||
Tape devices and tape changer have different ID_PATHs. |
||||
SCSI tape changer get the suffix "-changer" |
||||
to make them better distinguishable from tape devices. |
||||
|
||||
(cherry-picked from commmit 7f8ddf96a25162f06bd94a684cf700c128d18142) |
||||
|
||||
Resolves: #1814028 |
||||
--- |
||||
rules/60-persistent-storage-tape.rules | 3 +++ |
||||
1 file changed, 3 insertions(+) |
||||
|
||||
diff --git a/rules/60-persistent-storage-tape.rules b/rules/60-persistent-storage-tape.rules |
||||
index f2eabd92a8..99898c147b 100644 |
||||
--- a/rules/60-persistent-storage-tape.rules |
||||
+++ b/rules/60-persistent-storage-tape.rules |
||||
@@ -8,6 +8,9 @@ ACTION=="remove", GOTO="persistent_storage_tape_end" |
||||
SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{program}="scsi_id --sg-version=3 --export --whitelisted -d $devnode", \ |
||||
SYMLINK+="tape/by-id/scsi-$env{ID_SERIAL}" |
||||
|
||||
+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{builtin}="path_id", \ |
||||
+ SYMLINK+="tape/by-path/$env{ID_PATH}-changer" |
||||
+ |
||||
SUBSYSTEM!="scsi_tape", GOTO="persistent_storage_tape_end" |
||||
|
||||
KERNEL=="st*[0-9]|nst*[0-9]", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{ieee1394_id}", ENV{ID_BUS}="ieee1394" |
@ -0,0 +1,209 @@
@@ -0,0 +1,209 @@
|
||||
From fb419649754767124f30dba36f8fdbd114b0e9d7 Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Wed, 22 Jan 2020 12:04:38 +0100 |
||||
Subject: [PATCH] logind: check PolicyKit before allowing VT switch |
||||
|
||||
Let's lock this down a bit. Effectively nothing much changes, since the |
||||
default PK policy will allow users on the VT to change VT. Only users |
||||
with no local VT session won't be able to switch VTs. |
||||
|
||||
(cherry picked from commit 4acf0cfd2f92edb94ad48d04f1ce6c9ab4e19d55) |
||||
|
||||
Resolves: #1797672 |
||||
--- |
||||
src/login/logind-dbus.c | 18 ++++++-- |
||||
src/login/logind-seat-dbus.c | 50 +++++++++++++++++++++- |
||||
src/login/logind-session-dbus.c | 16 ++++++- |
||||
src/login/logind-session.h | 2 + |
||||
src/login/org.freedesktop.login1.policy.in | 10 +++++ |
||||
5 files changed, 89 insertions(+), 7 deletions(-) |
||||
|
||||
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c |
||||
index 63b9a0df36..019aa193f5 100644 |
||||
--- a/src/login/logind-dbus.c |
||||
+++ b/src/login/logind-dbus.c |
||||
@@ -854,11 +854,9 @@ static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *u |
||||
if (r < 0) |
||||
return r; |
||||
|
||||
- r = session_activate(session); |
||||
- if (r < 0) |
||||
- return r; |
||||
+ /* PolicyKit is done by bus_session_method_activate() */ |
||||
|
||||
- return sd_bus_reply_method_return(message, NULL); |
||||
+ return bus_session_method_activate(bus, message, session, error); |
||||
} |
||||
|
||||
static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { |
||||
@@ -890,6 +888,18 @@ static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, |
||||
if (session->seat != seat) |
||||
return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name); |
||||
|
||||
+ r = bus_verify_polkit_async( |
||||
+ message, |
||||
+ CAP_SYS_ADMIN, |
||||
+ "org.freedesktop.login1.chvt", |
||||
+ false, |
||||
+ &m->polkit_registry, |
||||
+ error); |
||||
+ if (r < 0) |
||||
+ return r; |
||||
+ if (r == 0) |
||||
+ return 1; /* Will call us back */ |
||||
+ |
||||
r = session_activate(session); |
||||
if (r < 0) |
||||
return r; |
||||
diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c |
||||
index 50b0b8842f..f49e416fce 100644 |
||||
--- a/src/login/logind-seat-dbus.c |
||||
+++ b/src/login/logind-seat-dbus.c |
||||
@@ -229,6 +229,18 @@ static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *u |
||||
if (session->seat != s) |
||||
return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", name, s->id); |
||||
|
||||
+ r = bus_verify_polkit_async( |
||||
+ message, |
||||
+ CAP_SYS_ADMIN, |
||||
+ "org.freedesktop.login1.chvt", |
||||
+ false, |
||||
+ &s->manager->polkit_registry, |
||||
+ error); |
||||
+ if (r < 0) |
||||
+ return r; |
||||
+ if (r == 0) |
||||
+ return 1; /* Will call us back */ |
||||
+ |
||||
r = session_activate(session); |
||||
if (r < 0) |
||||
return r; |
||||
@@ -250,7 +262,19 @@ static int method_switch_to(sd_bus *bus, sd_bus_message *message, void *userdata |
||||
return r; |
||||
|
||||
if (to <= 0) |
||||
- return -EINVAL; |
||||
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid virtual terminal"); |
||||
+ |
||||
+ r = bus_verify_polkit_async( |
||||
+ message, |
||||
+ CAP_SYS_ADMIN, |
||||
+ "org.freedesktop.login1.chvt", |
||||
+ false, |
||||
+ &s->manager->polkit_registry, |
||||
+ error); |
||||
+ if (r < 0) |
||||
+ return r; |
||||
+ if (r == 0) |
||||
+ return 1; /* Will call us back */ |
||||
|
||||
r = seat_switch_to(s, to); |
||||
if (r < 0) |
||||
@@ -267,6 +291,18 @@ static int method_switch_to_next(sd_bus *bus, sd_bus_message *message, void *use |
||||
assert(message); |
||||
assert(s); |
||||
|
||||
+ r = bus_verify_polkit_async( |
||||
+ message, |
||||
+ CAP_SYS_ADMIN, |
||||
+ "org.freedesktop.login1.chvt", |
||||
+ false, |
||||
+ &s->manager->polkit_registry, |
||||
+ error); |
||||
+ if (r < 0) |
||||
+ return r; |
||||
+ if (r == 0) |
||||
+ return 1; /* Will call us back */ |
||||
+ |
||||
r = seat_switch_to_next(s); |
||||
if (r < 0) |
||||
return r; |
||||
@@ -282,6 +318,18 @@ static int method_switch_to_previous(sd_bus *bus, sd_bus_message *message, void |
||||
assert(message); |
||||
assert(s); |
||||
|
||||
+ r = bus_verify_polkit_async( |
||||
+ message, |
||||
+ CAP_SYS_ADMIN, |
||||
+ "org.freedesktop.login1.chvt", |
||||
+ false, |
||||
+ &s->manager->polkit_registry, |
||||
+ error); |
||||
+ if (r < 0) |
||||
+ return r; |
||||
+ if (r == 0) |
||||
+ return 1; /* Will call us back */ |
||||
+ |
||||
r = seat_switch_to_previous(s); |
||||
if (r < 0) |
||||
return r; |
||||
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c |
||||
index 75b7186e8f..0ec4196257 100644 |
||||
--- a/src/login/logind-session-dbus.c |
||||
+++ b/src/login/logind-session-dbus.c |
||||
@@ -213,7 +213,7 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata |
||||
return sd_bus_reply_method_return(message, NULL); |
||||
} |
||||
|
||||
-static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { |
||||
+int bus_session_method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { |
||||
Session *s = userdata; |
||||
int r; |
||||
|
||||
@@ -221,6 +221,18 @@ static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, |
||||
assert(message); |
||||
assert(s); |
||||
|
||||
+ r = bus_verify_polkit_async( |
||||
+ message, |
||||
+ CAP_SYS_ADMIN, |
||||
+ "org.freedesktop.login1.chvt", |
||||
+ false, |
||||
+ &s->manager->polkit_registry, |
||||
+ error); |
||||
+ if (r < 0) |
||||
+ return r; |
||||
+ if (r == 0) |
||||
+ return 1; /* Will call us back */ |
||||
+ |
||||
r = session_activate(s); |
||||
if (r < 0) |
||||
return r; |
||||
@@ -506,7 +518,7 @@ const sd_bus_vtable session_vtable[] = { |
||||
SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), |
||||
|
||||
SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), |
||||
- SD_BUS_METHOD("Activate", NULL, NULL, method_activate, SD_BUS_VTABLE_UNPRIVILEGED), |
||||
+ SD_BUS_METHOD("Activate", NULL, NULL, bus_session_method_activate, SD_BUS_VTABLE_UNPRIVILEGED), |
||||
SD_BUS_METHOD("Lock", NULL, NULL, method_lock, 0), |
||||
SD_BUS_METHOD("Unlock", NULL, NULL, method_lock, 0), |
||||
SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, SD_BUS_VTABLE_UNPRIVILEGED), |
||||
diff --git a/src/login/logind-session.h b/src/login/logind-session.h |
||||
index d662082d85..b498f49592 100644 |
||||
--- a/src/login/logind-session.h |
||||
+++ b/src/login/logind-session.h |
||||
@@ -184,3 +184,5 @@ void session_leave_vt(Session *s); |
||||
bool session_is_controller(Session *s, const char *sender); |
||||
int session_set_controller(Session *s, const char *sender, bool force); |
||||
void session_drop_controller(Session *s); |
||||
+ |
||||
+int bus_session_method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); |
||||
diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in |
||||
index 49094eeddb..fa51ed8d74 100644 |
||||
--- a/src/login/org.freedesktop.login1.policy.in |
||||
+++ b/src/login/org.freedesktop.login1.policy.in |
||||
@@ -270,4 +270,14 @@ |
||||
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.hibernate</annotate> |
||||
</action> |
||||
|
||||
+ <action id="org.freedesktop.login1.chvt"> |
||||
+ <description gettext-domain="systemd">Change Session</description> |
||||
+ <message gettext-domain="systemd">Authentication is required for changing the virtual terminal.</message> |
||||
+ <defaults> |
||||
+ <allow_any>auth_admin_keep</allow_any> |
||||
+ <allow_inactive>auth_admin_keep</allow_inactive> |
||||
+ <allow_active>yes</allow_active> |
||||
+ </defaults> |
||||
+ </action> |
||||
+ |
||||
</policyconfig> |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
From 016f8f9305a5584d718579f90ee537398dfed33b Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Thu, 14 Sep 2017 18:26:10 +0200 |
||||
Subject: [PATCH] timer: don't use persietent file timestamps from the future |
||||
(#6823) |
||||
|
||||
Also, use the mtime rather than the atime of the timestamp file. While |
||||
the atime is not completely wrong, the mtime appears more appropriate |
||||
as that's what we actually explicitly change, and is not effected by |
||||
mere reading. |
||||
|
||||
Fixes: #6821 |
||||
(cherry picked from commit 77542a7905520f1d637912bf47bddb4855506e41) |
||||
|
||||
Resolves: #1769923 |
||||
--- |
||||
src/core/timer.c | 20 +++++++++++++++++--- |
||||
1 file changed, 17 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/src/core/timer.c b/src/core/timer.c |
||||
index 1d4868643a..fb192d558a 100644 |
||||
--- a/src/core/timer.c |
||||
+++ b/src/core/timer.c |
||||
@@ -595,9 +595,23 @@ static int timer_start(Unit *u) { |
||||
if (t->stamp_path) { |
||||
struct stat st; |
||||
|
||||
- if (stat(t->stamp_path, &st) >= 0) |
||||
- t->last_trigger.realtime = timespec_load(&st.st_atim); |
||||
- else if (errno == ENOENT) |
||||
+ if (stat(t->stamp_path, &st) >= 0) { |
||||
+ usec_t ft; |
||||
+ |
||||
+ /* Load the file timestamp, but only if it is actually in the past. If it is in the future, |
||||
+ * something is wrong with the system clock. */ |
||||
+ |
||||
+ ft = timespec_load(&st.st_mtim); |
||||
+ if (ft < now(CLOCK_REALTIME)) |
||||
+ t->last_trigger.realtime = ft; |
||||
+ else { |
||||
+ char z[FORMAT_TIMESTAMP_MAX]; |
||||
+ |
||||
+ log_unit_warning(u->id, "%s not using persistent file timestamp %s as it is in the future.", |
||||
+ u->id, format_timestamp(z, sizeof(z), ft)); |
||||
+ } |
||||
+ |
||||
+ } else if (errno == ENOENT) |
||||
/* The timer has never run before, |
||||
* make sure a stamp file exists. |
||||
*/ |
@ -0,0 +1,193 @@
@@ -0,0 +1,193 @@
|
||||
From b1135a4f292a4bc193bcef768898d06f8b732215 Mon Sep 17 00:00:00 2001 |
||||
From: Anita Zhang <the.anitazha@gmail.com> |
||||
Date: Sat, 25 Jan 2020 16:46:16 +0100 |
||||
Subject: [PATCH] core: transition to FINAL_SIGTERM state after ExecStopPost= |
||||
|
||||
Fixes #14566 |
||||
|
||||
(cherry picked from commit c1566ef0d22ed786b9ecf4c476e53b8a91e67578) |
||||
|
||||
Resolves: #1766477 |
||||
--- |
||||
src/core/service.c | 10 +++ |
||||
test/TEST-47-ISSUE-14566/Makefile | 1 + |
||||
test/TEST-47-ISSUE-14566/repro.sh | 5 ++ |
||||
test/TEST-47-ISSUE-14566/test.sh | 91 +++++++++++++++++++++++++++ |
||||
test/TEST-47-ISSUE-14566/testsuite.sh | 21 +++++++ |
||||
5 files changed, 128 insertions(+) |
||||
create mode 120000 test/TEST-47-ISSUE-14566/Makefile |
||||
create mode 100755 test/TEST-47-ISSUE-14566/repro.sh |
||||
create mode 100755 test/TEST-47-ISSUE-14566/test.sh |
||||
create mode 100755 test/TEST-47-ISSUE-14566/testsuite.sh |
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c |
||||
index e32cdf4594..7f0e6df412 100644 |
||||
--- a/src/core/service.c |
||||
+++ b/src/core/service.c |
||||
@@ -2751,6 +2751,12 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { |
||||
break; |
||||
|
||||
case SERVICE_STOP_POST: |
||||
+ |
||||
+ if (control_pid_good(s) <= 0) |
||||
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); |
||||
+ |
||||
+ break; |
||||
+ |
||||
case SERVICE_FINAL_SIGTERM: |
||||
case SERVICE_FINAL_SIGKILL: |
||||
|
||||
@@ -2894,6 +2900,10 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { |
||||
break; |
||||
|
||||
case SERVICE_STOP_POST: |
||||
+ if (main_pid_good(s) <= 0) |
||||
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); |
||||
+ break; |
||||
+ |
||||
case SERVICE_FINAL_SIGTERM: |
||||
case SERVICE_FINAL_SIGKILL: |
||||
if (main_pid_good(s) <= 0) |
||||
diff --git a/test/TEST-47-ISSUE-14566/Makefile b/test/TEST-47-ISSUE-14566/Makefile |
||||
new file mode 120000 |
||||
index 0000000000..e9f93b1104 |
||||
--- /dev/null |
||||
+++ b/test/TEST-47-ISSUE-14566/Makefile |
||||
@@ -0,0 +1 @@ |
||||
+../TEST-01-BASIC/Makefile |
||||
\ No newline at end of file |
||||
diff --git a/test/TEST-47-ISSUE-14566/repro.sh b/test/TEST-47-ISSUE-14566/repro.sh |
||||
new file mode 100755 |
||||
index 0000000000..5217602257 |
||||
--- /dev/null |
||||
+++ b/test/TEST-47-ISSUE-14566/repro.sh |
||||
@@ -0,0 +1,5 @@ |
||||
+#!/bin/bash |
||||
+ |
||||
+sleep infinity & |
||||
+echo $! > /leakedtestpid |
||||
+wait $! |
||||
diff --git a/test/TEST-47-ISSUE-14566/test.sh b/test/TEST-47-ISSUE-14566/test.sh |
||||
new file mode 100755 |
||||
index 0000000000..35d72d17ee |
||||
--- /dev/null |
||||
+++ b/test/TEST-47-ISSUE-14566/test.sh |
||||
@@ -0,0 +1,91 @@ |
||||
+#!/bin/bash |
||||
+TEST_DESCRIPTION="Test that KillMode=mixed does not leave left over proccesses with ExecStopPost=" |
||||
+. $TEST_BASE_DIR/test-functions |
||||
+ |
||||
+check_result_qemu() { |
||||
+ ret=1 |
||||
+ mkdir -p $TESTDIR/root |
||||
+ mount ${LOOPDEV}p1 $TESTDIR/root |
||||
+ [[ -e $TESTDIR/root/testok ]] && ret=0 |
||||
+ [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR |
||||
+ [[ -f $TESTDIR/root/var/log/journal ]] && cp -a $TESTDIR/root/var/log/journal $TESTDIR |
||||
+ umount $TESTDIR/root |
||||
+ [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed |
||||
+ ls -l $TESTDIR/journal/*/*.journal |
||||
+ test -s $TESTDIR/failed && ret=$(($ret+1)) |
||||
+ return $ret |
||||
+} |
||||
+ |
||||
+test_run() { |
||||
+ if run_qemu; then |
||||
+ check_result_qemu || return 1 |
||||
+ else |
||||
+ dwarn "can't run QEMU, skipping" |
||||
+ fi |
||||
+ if check_nspawn; then |
||||
+ run_nspawn |
||||
+ check_result_nspawn || return 1 |
||||
+ else |
||||
+ dwarn "can't run systemd-nspawn, skipping" |
||||
+ fi |
||||
+ return 0 |
||||
+} |
||||
+ |
||||
+test_setup() { |
||||
+ create_empty_image |
||||
+ mkdir -p $TESTDIR/root |
||||
+ mount ${LOOPDEV}p1 $TESTDIR/root |
||||
+ |
||||
+ ( |
||||
+ LOG_LEVEL=5 |
||||
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) |
||||
+ |
||||
+ setup_basic_environment |
||||
+ |
||||
+ # mask some services that we do not want to run in these tests |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket |
||||
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service |
||||
+ |
||||
+ # setup the testsuite service |
||||
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF |
||||
+[Unit] |
||||
+Description=Testsuite service |
||||
+ |
||||
+[Service] |
||||
+ExecStart=/testsuite.sh |
||||
+Type=oneshot |
||||
+StandardOutput=tty |
||||
+StandardError=tty |
||||
+NotifyAccess=all |
||||
+EOF |
||||
+ cat > $initdir/etc/systemd/system/issue_14566_test.service << EOF |
||||
+[Unit] |
||||
+Description=Issue 14566 Repro |
||||
+ |
||||
+[Service] |
||||
+ExecStart=/repro.sh |
||||
+ExecStopPost=/bin/true |
||||
+KillMode=mixed |
||||
+EOF |
||||
+ |
||||
+ cp testsuite.sh $initdir/ |
||||
+ cp repro.sh $initdir/ |
||||
+ |
||||
+ setup_testsuite |
||||
+ ) |
||||
+ setup_nspawn_root |
||||
+ |
||||
+ ddebug "umount $TESTDIR/root" |
||||
+ umount $TESTDIR/root |
||||
+} |
||||
+ |
||||
+test_cleanup() { |
||||
+ umount $TESTDIR/root 2>/dev/null |
||||
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV |
||||
+ return 0 |
||||
+} |
||||
+ |
||||
+do_test "$@" |
||||
diff --git a/test/TEST-47-ISSUE-14566/testsuite.sh b/test/TEST-47-ISSUE-14566/testsuite.sh |
||||
new file mode 100755 |
||||
index 0000000000..6363266713 |
||||
--- /dev/null |
||||
+++ b/test/TEST-47-ISSUE-14566/testsuite.sh |
||||
@@ -0,0 +1,21 @@ |
||||
+#!/bin/bash |
||||
+set -ex |
||||
+ |
||||
+systemd-analyze set-log-level debug |
||||
+ |
||||
+systemctl start issue_14566_test |
||||
+systemctl status issue_14566_test |
||||
+ |
||||
+leaked_pid=$(cat /leakedtestpid) |
||||
+ |
||||
+systemctl stop issue_14566_test |
||||
+ |
||||
+# Leaked PID will still be around if we're buggy. |
||||
+# I personally prefer to see 42. |
||||
+ps -p "$leaked_pid" && exit 42 |
||||
+ |
||||
+systemd-analyze log-level info |
||||
+ |
||||
+echo OK > /testok |
||||
+ |
||||
+exit 0 |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
From b88483b804e92a59800e8785c87d17a7213aafc4 Mon Sep 17 00:00:00 2001 |
||||
From: ven <2988994+hexiaowen@users.noreply.github.com> |
||||
Date: Wed, 22 May 2019 14:24:28 +0800 |
||||
Subject: [PATCH] =?UTF-8?q?bus=5Fopen=20leak=20sd=5Fevent=5Fsource=20when?= |
||||
=?UTF-8?q?=20udevadm=20trigger=E3=80=82?= |
||||
MIME-Version: 1.0 |
||||
Content-Type: text/plain; charset=UTF-8 |
||||
Content-Transfer-Encoding: 8bit |
||||
|
||||
On my host, when executing the udevadm trigger, I only receive the change event, which causes memleak |
||||
|
||||
(cherry picked from commit b2774a3ae692113e1f47a336a6c09bac9cfb49ad) |
||||
|
||||
Resolves: #1798503 |
||||
--- |
||||
src/login/logind-button.c | 1 + |
||||
1 file changed, 1 insertion(+) |
||||
|
||||
diff --git a/src/login/logind-button.c b/src/login/logind-button.c |
||||
index d7211e66ce..9145176e58 100644 |
||||
--- a/src/login/logind-button.c |
||||
+++ b/src/login/logind-button.c |
||||
@@ -259,6 +259,7 @@ int button_open(Button *b) { |
||||
goto fail; |
||||
} |
||||
|
||||
+ b->io_event_source = sd_event_source_unref(b->io_event_source); |
||||
r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b); |
||||
if (r < 0) { |
||||
log_error_errno(r, "Failed to add button event: %m"); |
@ -0,0 +1,117 @@
@@ -0,0 +1,117 @@
|
||||
From 21b3ef4130291a1e3c184bb47c80cb962b32b782 Mon Sep 17 00:00:00 2001 |
||||
From: Klearchos Chaloulos <klearchos.chaloulos@nokia.com> |
||||
Date: Tue, 1 Dec 2015 19:29:59 +0200 |
||||
Subject: [PATCH] journal-remote: split-mode=host, remove port from journal |
||||
filename |
||||
|
||||
When constructing the journal filename to store logs from a remote host, remove the port of the tcp connection, as the port will change with every reboot/connection loss between sender/reveiver machines. Having the port in the filename will cause a new journal file to be created for every reboot or connection loss. |
||||
For the implementation, a new argument "bool include_port" is added to the getpeername_pretty() function. This is passed to the sockaddr_pretty() function. The value of the include_port argument is set to true in all calls of getpeername_pretty(), except for 2 calls in journal-remote.c, where it is set to false. |
||||
|
||||
(cherry picked from commit 366b7db4b65b994cd33cf4fd3c1be429be561307) |
||||
|
||||
Resolves: #1244691 |
||||
--- |
||||
src/activate/activate.c | 2 +- |
||||
src/core/service.c | 2 +- |
||||
src/journal-remote/journal-remote.c | 4 ++-- |
||||
src/shared/socket-util.c | 4 ++-- |
||||
src/shared/socket-util.h | 2 +- |
||||
src/socket-proxy/socket-proxyd.c | 2 +- |
||||
6 files changed, 8 insertions(+), 8 deletions(-) |
||||
|
||||
diff --git a/src/activate/activate.c b/src/activate/activate.c |
||||
index 2689934c40..a456af1573 100644 |
||||
--- a/src/activate/activate.c |
||||
+++ b/src/activate/activate.c |
||||
@@ -241,7 +241,7 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) { |
||||
} |
||||
|
||||
getsockname_pretty(fd2, &local); |
||||
- getpeername_pretty(fd2, &peer); |
||||
+ getpeername_pretty(fd2, true, &peer); |
||||
log_info("Connection from %s to %s", strna(peer), strna(local)); |
||||
|
||||
return launch1(name, argv, envp, fd2); |
||||
diff --git a/src/core/service.c b/src/core/service.c |
||||
index 7f0e6df412..dd0ae7cb88 100644 |
||||
--- a/src/core/service.c |
||||
+++ b/src/core/service.c |
||||
@@ -3309,7 +3309,7 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context |
||||
if (s->state != SERVICE_DEAD) |
||||
return -EAGAIN; |
||||
|
||||
- if (getpeername_pretty(fd, &peer) >= 0) { |
||||
+ if (getpeername_pretty(fd, true, &peer) >= 0) { |
||||
|
||||
if (UNIT(s)->description) { |
||||
_cleanup_free_ char *a; |
||||
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c |
||||
index 431e28329b..166bdad541 100644 |
||||
--- a/src/journal-remote/journal-remote.c |
||||
+++ b/src/journal-remote/journal-remote.c |
||||
@@ -620,7 +620,7 @@ static int request_handler( |
||||
if (r < 0) |
||||
return code; |
||||
} else { |
||||
- r = getnameinfo_pretty(fd, &hostname); |
||||
+ r = getpeername_pretty(fd, false, &hostname); |
||||
if (r < 0) { |
||||
return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, |
||||
"Cannot check remote hostname"); |
||||
@@ -880,7 +880,7 @@ static int remoteserver_init(RemoteServer *s, |
||||
} else if (sd_is_socket(fd, AF_UNSPEC, 0, false)) { |
||||
char *hostname; |
||||
|
||||
- r = getnameinfo_pretty(fd, &hostname); |
||||
+ r = getpeername_pretty(fd, false, &hostname); |
||||
if (r < 0) |
||||
return log_error_errno(r, "Failed to retrieve remote name: %m"); |
||||
|
||||
diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c |
||||
index b14e368176..d492ae4222 100644 |
||||
--- a/src/shared/socket-util.c |
||||
+++ b/src/shared/socket-util.c |
||||
@@ -612,7 +612,7 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ |
||||
return 0; |
||||
} |
||||
|
||||
-int getpeername_pretty(int fd, char **ret) { |
||||
+int getpeername_pretty(int fd, bool include_port, char **ret) { |
||||
union sockaddr_union sa; |
||||
socklen_t salen = sizeof(sa); |
||||
int r; |
||||
@@ -642,7 +642,7 @@ int getpeername_pretty(int fd, char **ret) { |
||||
/* For remote sockets we translate IPv6 addresses back to IPv4 |
||||
* if applicable, since that's nicer. */ |
||||
|
||||
- return sockaddr_pretty(&sa.sa, salen, true, true, ret); |
||||
+ return sockaddr_pretty(&sa.sa, salen, true, include_port, ret); |
||||
} |
||||
|
||||
int getsockname_pretty(int fd, char **ret) { |
||||
diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h |
||||
index 9200ce8822..403c9bc098 100644 |
||||
--- a/src/shared/socket-util.h |
||||
+++ b/src/shared/socket-util.h |
||||
@@ -102,7 +102,7 @@ bool socket_ipv6_is_supported(void); |
||||
int sockaddr_port(const struct sockaddr *_sa) _pure_; |
||||
|
||||
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret); |
||||
-int getpeername_pretty(int fd, char **ret); |
||||
+int getpeername_pretty(int fd, bool include_port, char **ret); |
||||
int getsockname_pretty(int fd, char **ret); |
||||
|
||||
int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret); |
||||
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c |
||||
index a3c3c87f11..b0a062b716 100644 |
||||
--- a/src/socket-proxy/socket-proxyd.c |
||||
+++ b/src/socket-proxy/socket-proxyd.c |
||||
@@ -504,7 +504,7 @@ static int accept_cb(sd_event_source *s, int fd, uint32_t revents, void *userdat |
||||
if (errno != -EAGAIN) |
||||
log_warning_errno(errno, "Failed to accept() socket: %m"); |
||||
} else { |
||||
- getpeername_pretty(nfd, &peer); |
||||
+ getpeername_pretty(nfd, true, &peer); |
||||
log_debug("New connection from %s", strna(peer)); |
||||
|
||||
r = add_connection_socket(context, nfd); |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
From d081baa951ee0d1c918170c7c666208fe04944e2 Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Fri, 8 Sep 2017 17:24:57 +0200 |
||||
Subject: [PATCH] core: downgrade log message about inability to propagate |
||||
cgroup release message |
||||
|
||||
If dbus is already down during shutdown, we can't propagate the cgroup |
||||
release message anymore, but that's expected and nothing to warn about. |
||||
Hence let's downgrade the message from LOG_WARN to LOG_DEBUG. |
||||
|
||||
Fixes: #6777 |
||||
(cherry picked from commit d5f1532657da107f1c8be8a97c15d964cd96665c) |
||||
|
||||
Resolves: #1679934 |
||||
--- |
||||
src/core/dbus.c | 2 +- |
||||
src/core/manager.c | 2 +- |
||||
2 files changed, 2 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/src/core/dbus.c b/src/core/dbus.c |
||||
index d551eab016..9d19138ab3 100644 |
||||
--- a/src/core/dbus.c |
||||
+++ b/src/core/dbus.c |
||||
@@ -93,7 +93,7 @@ int bus_forward_agent_released(Manager *m, const char *path) { |
||||
"Released", |
||||
"s", path); |
||||
if (r < 0) |
||||
- return log_warning_errno(r, "Failed to propagate agent release message: %m"); |
||||
+ return log_debug_errno(r, "Failed to propagate agent release message: %m"); |
||||
|
||||
return 1; |
||||
} |
||||
diff --git a/src/core/manager.c b/src/core/manager.c |
||||
index 4c87ad8a2f..7bbe912dc9 100644 |
||||
--- a/src/core/manager.c |
||||
+++ b/src/core/manager.c |
||||
@@ -1666,7 +1666,7 @@ static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, ui |
||||
buf[n] = 0; |
||||
|
||||
manager_notify_cgroup_empty(m, buf); |
||||
- bus_forward_agent_released(m, buf); |
||||
+ (void) bus_forward_agent_released(m, buf); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
From 0693f51f979f260426cddc1f270e28e3cb2b46fa Mon Sep 17 00:00:00 2001 |
||||
From: tblume <Thomas.Blume@suse.com> |
||||
Date: Thu, 30 Mar 2017 11:21:18 +0200 |
||||
Subject: [PATCH] units: move Before deps for quota services to |
||||
remote-fs.target (#5627) |
||||
|
||||
Creating quota on an iscsi device is causing dependency loops at next reboot. |
||||
Reason is that systemd-quotacheck and quotaon.service are ordered before |
||||
local-fs.target and quota enabled mounts have a before dependency to them. |
||||
This cannot work for _netdev mounts, because network activation is ordered |
||||
after local-fs.target. |
||||
Moving the Before dependency for systemd-quotacheck and quotaon.service |
||||
to remote-fs.target fixes this. |
||||
|
||||
(cherry picked from commit 4e6f13af93a551933a75331b1f67123b3d09f6ef) |
||||
|
||||
Resolves: #1693374 |
||||
--- |
||||
units/quotaon.service.in | 2 +- |
||||
units/systemd-quotacheck.service.in | 2 +- |
||||
2 files changed, 2 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/units/quotaon.service.in b/units/quotaon.service.in |
||||
index 49a50a7feb..57667e110d 100644 |
||||
--- a/units/quotaon.service.in |
||||
+++ b/units/quotaon.service.in |
||||
@@ -10,7 +10,7 @@ Description=Enable File System Quotas |
||||
Documentation=man:quotaon(8) |
||||
DefaultDependencies=no |
||||
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-quotacheck.service |
||||
-Before=local-fs.target shutdown.target |
||||
+Before=remote-fs.target shutdown.target |
||||
ConditionPathExists=@QUOTAON@ |
||||
|
||||
[Service] |
||||
diff --git a/units/systemd-quotacheck.service.in b/units/systemd-quotacheck.service.in |
||||
index f726ea1bcd..41c9bea6d2 100644 |
||||
--- a/units/systemd-quotacheck.service.in |
||||
+++ b/units/systemd-quotacheck.service.in |
||||
@@ -10,7 +10,7 @@ Description=File System Quota Check |
||||
Documentation=man:systemd-quotacheck.service(8) |
||||
DefaultDependencies=no |
||||
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service |
||||
-Before=local-fs.target shutdown.target |
||||
+Before=remote-fs.target shutdown.target |
||||
ConditionPathExists=@QUOTACHECK@ |
||||
|
||||
[Service] |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
From 7e8934693393c45ba76155088b01ad1ace9daeac Mon Sep 17 00:00:00 2001 |
||||
From: David Tardon <dtardon@redhat.com> |
||||
Date: Tue, 3 Dec 2019 13:57:38 +0100 |
||||
Subject: [PATCH] set kptr_restrict=1 |
||||
|
||||
Resolves: #1689344 |
||||
--- |
||||
sysctl.d/50-default.conf | 3 +++ |
||||
1 file changed, 3 insertions(+) |
||||
|
||||
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf |
||||
index 44c48236cc..b1806502e8 100644 |
||||
--- a/sysctl.d/50-default.conf |
||||
+++ b/sysctl.d/50-default.conf |
||||
@@ -20,6 +20,9 @@ kernel.sysrq = 16 |
||||
# Append the PID to the core filename |
||||
kernel.core_uses_pid = 1 |
||||
|
||||
+# https://bugzilla.redhat.com/show_bug.cgi?id=1689344 |
||||
+kernel.kptr_restrict = 1 |
||||
+ |
||||
# Source route verification |
||||
net.ipv4.conf.default.rp_filter = 1 |
||||
net.ipv4.conf.all.rp_filter = 1 |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
From 19bb218559b8dca65bbb68ad7a4ff0bc9cbfe8fb Mon Sep 17 00:00:00 2001 |
||||
From: Stepan Broz <sbroz@redhat.com> |
||||
Date: Wed, 11 Mar 2020 14:45:26 +0100 |
||||
Subject: [PATCH] journal: break recursion |
||||
|
||||
available_space(s, true) tries to log the current status, which does, in |
||||
turn, lead to another call to available_space(s, true) and so on and so |
||||
on... The call sequence is: |
||||
|
||||
available_space() |
||||
server_driver_message() |
||||
dispatch_message_real() |
||||
write_to_journal() |
||||
find_journal() |
||||
system_journal_open() |
||||
available_space() |
||||
|
||||
RHEL-only |
||||
|
||||
Resolves: #1778744 |
||||
--- |
||||
src/journal/journald-server.c | 12 ++++++------ |
||||
1 file changed, 6 insertions(+), 6 deletions(-) |
||||
|
||||
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c |
||||
index ffe2daa7be..11348af490 100644 |
||||
--- a/src/journal/journald-server.c |
||||
+++ b/src/journal/journald-server.c |
||||
@@ -311,7 +311,7 @@ static bool flushed_flag_is_set(void) { |
||||
return access("/run/systemd/journal/flushed", F_OK) >= 0; |
||||
} |
||||
|
||||
-static int system_journal_open(Server *s, bool flush_requested) { |
||||
+static int system_journal_open(Server *s, bool flush_requested, bool verbose) { |
||||
int r; |
||||
char *fn; |
||||
sd_id128_t machine; |
||||
@@ -344,7 +344,7 @@ static int system_journal_open(Server *s, bool flush_requested) { |
||||
|
||||
if (r >= 0) { |
||||
server_fix_perms(s, s->system_journal, 0); |
||||
- available_space(s, true); |
||||
+ available_space(s, verbose); |
||||
} else { |
||||
if (r != -ENOENT && r != -EROFS) |
||||
log_warning_errno(r, "Failed to open system journal: %m"); |
||||
@@ -406,7 +406,7 @@ static int system_journal_open(Server *s, bool flush_requested) { |
||||
|
||||
if (s->runtime_journal) { |
||||
server_fix_perms(s, s->runtime_journal, 0); |
||||
- available_space(s, true); |
||||
+ available_space(s, verbose); |
||||
} |
||||
} |
||||
|
||||
@@ -430,7 +430,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { |
||||
* else that's left the journals as NULL). |
||||
* |
||||
* Fixes https://github.com/systemd/systemd/issues/3968 */ |
||||
- (void) system_journal_open(s, false); |
||||
+ (void) system_journal_open(s, false, false); |
||||
|
||||
/* We split up user logs only on /var, not on /run. If the |
||||
* runtime file is open, we write to it exclusively, in order |
||||
@@ -1132,7 +1132,7 @@ int server_flush_to_var(Server *s, bool require_flag_file) { |
||||
if (require_flag_file && !flushed_flag_is_set()) |
||||
return 0; |
||||
|
||||
- system_journal_open(s, true); |
||||
+ system_journal_open(s, true, true); |
||||
|
||||
if (!s->system_journal) |
||||
return 0; |
||||
@@ -1903,7 +1903,7 @@ int server_init(Server *s) { |
||||
|
||||
(void) server_connect_notify(s); |
||||
|
||||
- r = system_journal_open(s, false); |
||||
+ r = system_journal_open(s, false, true); |
||||
if (r < 0) |
||||
return r; |
||||
|
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
From d27610cfef24a985116ed88f29a462f627745b19 Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Tue, 19 May 2015 16:00:24 +0200 |
||||
Subject: [PATCH] core: enforce a ratelimiter when stopping units due to |
||||
StopWhenUnneeded=1 |
||||
|
||||
Otherwise we might end up in an endless stop loop. |
||||
|
||||
http://lists.freedesktop.org/archives/systemd-devel/2015-April/030224.html |
||||
(cherry picked from commit bea355dac94e82697aa98e25d80ee4248263bf92) |
||||
|
||||
Related: #1775291 |
||||
--- |
||||
src/core/unit.c | 10 ++++++++++ |
||||
src/core/unit.h | 3 +++ |
||||
2 files changed, 13 insertions(+) |
||||
|
||||
diff --git a/src/core/unit.c b/src/core/unit.c |
||||
index 502830d2cb..750b8b9a5c 100644 |
||||
--- a/src/core/unit.c |
||||
+++ b/src/core/unit.c |
||||
@@ -97,6 +97,8 @@ Unit *unit_new(Manager *m, size_t size) { |
||||
u->on_failure_job_mode = JOB_REPLACE; |
||||
u->sigchldgen = 0; |
||||
|
||||
+ RATELIMIT_INIT(u->check_unneeded_ratelimit, 10 * USEC_PER_SEC, 16); |
||||
+ |
||||
return u; |
||||
} |
||||
|
||||
@@ -1612,6 +1614,14 @@ static void unit_check_unneeded(Unit *u) { |
||||
if (unit_active_or_pending(other)) |
||||
return; |
||||
|
||||
+ /* If stopping a unit fails continously we might enter a stop |
||||
+ * loop here, hence stop acting on the service being |
||||
+ * unnecessary after a while. */ |
||||
+ if (!ratelimit_test(&u->check_unneeded_ratelimit)) { |
||||
+ log_unit_warning(u->id, "Unit not needed anymore, but not stopping since we tried this too often recently."); |
||||
+ return; |
||||
+ } |
||||
+ |
||||
log_unit_info(u->id, "Unit %s is not needed anymore. Stopping.", u->id); |
||||
|
||||
/* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ |
||||
diff --git a/src/core/unit.h b/src/core/unit.h |
||||
index 8cc7a9e0b2..e930d8ba5f 100644 |
||||
--- a/src/core/unit.h |
||||
+++ b/src/core/unit.h |
||||
@@ -192,6 +192,9 @@ struct Unit { |
||||
/* Error code when we didn't manage to load the unit (negative) */ |
||||
int load_error; |
||||
|
||||
+ /* Make sure we never enter endless loops with the check unneeded logic */ |
||||
+ RateLimit check_unneeded_ratelimit; |
||||
+ |
||||
/* Cached unit file state and preset */ |
||||
UnitFileState unit_file_state; |
||||
int unit_file_preset; |
@ -0,0 +1,342 @@
@@ -0,0 +1,342 @@
|
||||
From ba36c6a8c8d134aa7196750af4a6651d5810f6d3 Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Thu, 9 Aug 2018 16:26:27 +0200 |
||||
Subject: [PATCH] core: rework StopWhenUnneeded= logic |
||||
|
||||
Previously, we'd act immediately on StopWhenUnneeded= when a unit state |
||||
changes. With this rework we'll maintain a queue instead: whenever |
||||
there's the chance that StopWhenUneeded= might have an effect we enqueue |
||||
the unit, and process it later when we have nothing better to do. |
||||
|
||||
This should make the implementation a bit more reliable, as the unit notify event |
||||
cannot immediately enqueue tons of side-effect jobs that might |
||||
contradict each other, but we do so only in a strictly ordered fashion, |
||||
from the main event loop. |
||||
|
||||
This slightly changes the check when to consider a unit "unneeded". |
||||
Previously, we'd assume that a unit in "deactivating" state could also |
||||
be cleaned up. With this new logic we'll only consider units unneeded |
||||
that are fully up and have no job queued. This means that whenever |
||||
there's something pending for a unit we won't clean it up. |
||||
|
||||
(cherry picked from commit a3c1168ac293f16d9343d248795bb4c246aaff4a) |
||||
|
||||
Resolves: #1775291 |
||||
--- |
||||
src/core/manager.c | 43 +++++++++++++++ |
||||
src/core/manager.h | 3 ++ |
||||
src/core/unit.c | 132 ++++++++++++++++++++++++--------------------- |
||||
src/core/unit.h | 7 +++ |
||||
4 files changed, 124 insertions(+), 61 deletions(-) |
||||
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c |
||||
index 7bbe912dc9..db562b18a5 100644 |
||||
--- a/src/core/manager.c |
||||
+++ b/src/core/manager.c |
||||
@@ -961,6 +961,45 @@ static unsigned manager_dispatch_gc_queue(Manager *m) { |
||||
return n; |
||||
} |
||||
|
||||
+static unsigned manager_dispatch_stop_when_unneeded_queue(Manager *m) { |
||||
+ unsigned n = 0; |
||||
+ Unit *u; |
||||
+ int r; |
||||
+ |
||||
+ assert(m); |
||||
+ |
||||
+ while ((u = m->stop_when_unneeded_queue)) { |
||||
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; |
||||
+ assert(m->stop_when_unneeded_queue); |
||||
+ |
||||
+ assert(u->in_stop_when_unneeded_queue); |
||||
+ LIST_REMOVE(stop_when_unneeded_queue, m->stop_when_unneeded_queue, u); |
||||
+ u->in_stop_when_unneeded_queue = false; |
||||
+ |
||||
+ n++; |
||||
+ |
||||
+ if (!unit_is_unneeded(u)) |
||||
+ continue; |
||||
+ |
||||
+ log_unit_debug(u->id, "Unit is not needed anymore."); |
||||
+ |
||||
+ /* If stopping a unit fails continuously we might enter a stop loop here, hence stop acting on the |
||||
+ * service being unnecessary after a while. */ |
||||
+ |
||||
+ if (!ratelimit_test(&u->check_unneeded_ratelimit)) { |
||||
+ log_unit_warning(u->id, "Unit not needed anymore, but not stopping since we tried this too often recently."); |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
+ /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ |
||||
+ r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, &error, NULL); |
||||
+ if (r < 0) |
||||
+ log_unit_warning_errno(u->id, r, "Failed to enqueue stop job, ignoring: %s", bus_error_message(&error, r)); |
||||
+ } |
||||
+ |
||||
+ return n; |
||||
+} |
||||
+ |
||||
static void manager_clear_jobs_and_units(Manager *m) { |
||||
Unit *u; |
||||
|
||||
@@ -977,6 +1016,7 @@ static void manager_clear_jobs_and_units(Manager *m) { |
||||
assert(!m->dbus_job_queue); |
||||
assert(!m->cleanup_queue); |
||||
assert(!m->gc_queue); |
||||
+ assert(!m->stop_when_unneeded_queue); |
||||
|
||||
assert(hashmap_isempty(m->jobs)); |
||||
assert(hashmap_isempty(m->units)); |
||||
@@ -2259,6 +2299,9 @@ int manager_loop(Manager *m) { |
||||
if (manager_dispatch_cgroup_queue(m) > 0) |
||||
continue; |
||||
|
||||
+ if (manager_dispatch_stop_when_unneeded_queue(m) > 0) |
||||
+ continue; |
||||
+ |
||||
if (manager_dispatch_dbus_queue(m) > 0) |
||||
continue; |
||||
|
||||
diff --git a/src/core/manager.h b/src/core/manager.h |
||||
index cfc564dfb6..f9280956e9 100644 |
||||
--- a/src/core/manager.h |
||||
+++ b/src/core/manager.h |
||||
@@ -117,6 +117,9 @@ struct Manager { |
||||
/* Target units whose default target dependencies haven't been set yet */ |
||||
LIST_HEAD(Unit, target_deps_queue); |
||||
|
||||
+ /* Units that might be subject to StopWhenUnneeded= clean-up */ |
||||
+ LIST_HEAD(Unit, stop_when_unneeded_queue); |
||||
+ |
||||
sd_event *event; |
||||
|
||||
/* We use two hash tables here, since the same PID might be |
||||
diff --git a/src/core/unit.c b/src/core/unit.c |
||||
index 750b8b9a5c..2b058dd3e8 100644 |
||||
--- a/src/core/unit.c |
||||
+++ b/src/core/unit.c |
||||
@@ -396,6 +396,22 @@ void unit_add_to_dbus_queue(Unit *u) { |
||||
u->in_dbus_queue = true; |
||||
} |
||||
|
||||
+void unit_add_to_stop_when_unneeded_queue(Unit *u) { |
||||
+ assert(u); |
||||
+ |
||||
+ if (u->in_stop_when_unneeded_queue) |
||||
+ return; |
||||
+ |
||||
+ if (!u->stop_when_unneeded) |
||||
+ return; |
||||
+ |
||||
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) |
||||
+ return; |
||||
+ |
||||
+ LIST_PREPEND(stop_when_unneeded_queue, u->manager->stop_when_unneeded_queue, u); |
||||
+ u->in_stop_when_unneeded_queue = true; |
||||
+} |
||||
+ |
||||
static void bidi_set_free(Unit *u, Set *s) { |
||||
Iterator i; |
||||
Unit *other; |
||||
@@ -560,6 +576,9 @@ void unit_free(Unit *u) { |
||||
u->manager->n_in_gc_queue--; |
||||
} |
||||
|
||||
+ if (u->in_stop_when_unneeded_queue) |
||||
+ LIST_REMOVE(stop_when_unneeded_queue, u->manager->stop_when_unneeded_queue, u); |
||||
+ |
||||
if (u->on_console) |
||||
manager_unref_console(u->manager); |
||||
|
||||
@@ -1583,49 +1602,68 @@ bool unit_can_reload(Unit *u) { |
||||
return UNIT_VTABLE(u)->can_reload(u); |
||||
} |
||||
|
||||
-static void unit_check_unneeded(Unit *u) { |
||||
- Iterator i; |
||||
- Unit *other; |
||||
+bool unit_is_unneeded(Unit *u) { |
||||
+ static const UnitDependency deps[] = { |
||||
+ UNIT_REQUIRED_BY, |
||||
+ UNIT_REQUIRED_BY_OVERRIDABLE, |
||||
+ UNIT_WANTED_BY, |
||||
+ UNIT_BOUND_BY, |
||||
+ }; |
||||
+ size_t j; |
||||
|
||||
assert(u); |
||||
|
||||
- /* If this service shall be shut down when unneeded then do |
||||
- * so. */ |
||||
- |
||||
if (!u->stop_when_unneeded) |
||||
- return; |
||||
+ return false; |
||||
|
||||
- if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) |
||||
- return; |
||||
+ /* Don't clean up while the unit is transitioning or is even inactive. */ |
||||
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) |
||||
+ return false; |
||||
+ if (u->job) |
||||
+ return false; |
||||
|
||||
- SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i) |
||||
- if (unit_active_or_pending(other)) |
||||
- return; |
||||
+ for (j = 0; j < ELEMENTSOF(deps); j++) { |
||||
+ Unit *other; |
||||
+ Iterator i; |
||||
|
||||
- SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) |
||||
- if (unit_active_or_pending(other)) |
||||
- return; |
||||
+ /* If a dependending unit has a job queued, or is active (or in transitioning), or is marked for |
||||
+ * restart, then don't clean this one up. */ |
||||
|
||||
- SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i) |
||||
- if (unit_active_or_pending(other)) |
||||
- return; |
||||
+ SET_FOREACH(other, u->dependencies[deps[j]], i) { |
||||
+ if (u->job) |
||||
+ return false; |
||||
|
||||
- SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i) |
||||
- if (unit_active_or_pending(other)) |
||||
- return; |
||||
- |
||||
- /* If stopping a unit fails continously we might enter a stop |
||||
- * loop here, hence stop acting on the service being |
||||
- * unnecessary after a while. */ |
||||
- if (!ratelimit_test(&u->check_unneeded_ratelimit)) { |
||||
- log_unit_warning(u->id, "Unit not needed anymore, but not stopping since we tried this too often recently."); |
||||
- return; |
||||
+ if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) |
||||
+ return false; |
||||
+ } |
||||
} |
||||
|
||||
- log_unit_info(u->id, "Unit %s is not needed anymore. Stopping.", u->id); |
||||
+ return true; |
||||
+} |
||||
|
||||
- /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ |
||||
- manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL); |
||||
+static void check_unneeded_dependencies(Unit *u) { |
||||
+ |
||||
+ static const UnitDependency deps[] = { |
||||
+ UNIT_REQUIRES, |
||||
+ UNIT_REQUIRES_OVERRIDABLE, |
||||
+ UNIT_REQUISITE, |
||||
+ UNIT_REQUISITE_OVERRIDABLE, |
||||
+ UNIT_WANTS, |
||||
+ UNIT_BINDS_TO, |
||||
+ }; |
||||
+ size_t j; |
||||
+ |
||||
+ assert(u); |
||||
+ |
||||
+ /* Add all units this unit depends on to the queue that processes StopWhenUnneeded= behaviour. */ |
||||
+ |
||||
+ for (j = 0; j < ELEMENTSOF(deps); j++) { |
||||
+ Unit *other; |
||||
+ Iterator i; |
||||
+ |
||||
+ SET_FOREACH(other, u->dependencies[deps[j]], i) |
||||
+ unit_add_to_stop_when_unneeded_queue(other); |
||||
+ } |
||||
} |
||||
|
||||
static void unit_check_binds_to(Unit *u) { |
||||
@@ -1711,34 +1749,6 @@ static void retroactively_stop_dependencies(Unit *u) { |
||||
manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); |
||||
} |
||||
|
||||
-static void check_unneeded_dependencies(Unit *u) { |
||||
- Iterator i; |
||||
- Unit *other; |
||||
- |
||||
- assert(u); |
||||
- assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))); |
||||
- |
||||
- /* Garbage collect services that might not be needed anymore, if enabled */ |
||||
- SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i) |
||||
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) |
||||
- unit_check_unneeded(other); |
||||
- SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) |
||||
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) |
||||
- unit_check_unneeded(other); |
||||
- SET_FOREACH(other, u->dependencies[UNIT_WANTS], i) |
||||
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) |
||||
- unit_check_unneeded(other); |
||||
- SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i) |
||||
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) |
||||
- unit_check_unneeded(other); |
||||
- SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i) |
||||
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) |
||||
- unit_check_unneeded(other); |
||||
- SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i) |
||||
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) |
||||
- unit_check_unneeded(other); |
||||
-} |
||||
- |
||||
void unit_start_on_failure(Unit *u) { |
||||
Unit *other; |
||||
Iterator i; |
||||
@@ -1916,7 +1926,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su |
||||
} |
||||
|
||||
/* stop unneeded units regardless if going down was expected or not */ |
||||
- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) |
||||
+ if (UNIT_IS_INACTIVE_OR_FAILED(ns)) |
||||
check_unneeded_dependencies(u); |
||||
|
||||
if (ns != os && ns == UNIT_FAILED) { |
||||
@@ -1977,7 +1987,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su |
||||
if (u->manager->n_reloading <= 0) { |
||||
/* Maybe we finished startup and are now ready for |
||||
* being stopped because unneeded? */ |
||||
- unit_check_unneeded(u); |
||||
+ unit_add_to_stop_when_unneeded_queue(u); |
||||
|
||||
/* Maybe we finished startup, but something we needed |
||||
* has vanished? Let's die then. (This happens when |
||||
diff --git a/src/core/unit.h b/src/core/unit.h |
||||
index e930d8ba5f..f426f3df21 100644 |
||||
--- a/src/core/unit.h |
||||
+++ b/src/core/unit.h |
||||
@@ -172,6 +172,9 @@ struct Unit { |
||||
/* Target dependencies queue */ |
||||
LIST_FIELDS(Unit, target_deps_queue); |
||||
|
||||
+ /* Queue of units with StopWhenUnneeded set that shell be checked for clean-up. */ |
||||
+ LIST_FIELDS(Unit, stop_when_unneeded_queue); |
||||
+ |
||||
/* PIDs we keep an eye on. Note that a unit might have many |
||||
* more, but these are the ones we care enough about to |
||||
* process SIGCHLD for */ |
||||
@@ -245,6 +248,7 @@ struct Unit { |
||||
bool in_gc_queue:1; |
||||
bool in_cgroup_queue:1; |
||||
bool in_target_deps_queue:1; |
||||
+ bool in_stop_when_unneeded_queue:1; |
||||
|
||||
bool sent_dbus_new_signal:1; |
||||
|
||||
@@ -518,6 +522,7 @@ void unit_add_to_dbus_queue(Unit *u); |
||||
void unit_add_to_cleanup_queue(Unit *u); |
||||
void unit_add_to_gc_queue(Unit *u); |
||||
void unit_add_to_target_deps_queue(Unit *u); |
||||
+void unit_add_to_stop_when_unneeded_queue(Unit *u); |
||||
|
||||
int unit_merge(Unit *u, Unit *other); |
||||
int unit_merge_by_name(Unit *u, const char *other); |
||||
@@ -637,6 +642,8 @@ int unit_make_transient(Unit *u); |
||||
|
||||
int unit_require_mounts_for(Unit *u, const char *path); |
||||
|
||||
+bool unit_is_unneeded(Unit *u); |
||||
+ |
||||
pid_t unit_control_pid(Unit *u); |
||||
pid_t unit_main_pid(Unit *u); |
||||
|
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
From 8ee652948b0255005e4c9d278ac06b30711d9dbd Mon Sep 17 00:00:00 2001 |
||||
From: chenglin130 <cheng.lin130@zte.com.cn> |
||||
Date: Sat, 9 Nov 2019 23:04:04 +0800 |
||||
Subject: [PATCH] core: coldplug possible nop_job |
||||
|
||||
When a unit in a state INACTIVE or DEACTIVATING, JobType JOB_TRY_RESTART or |
||||
JOB_TRY_RELOAD will be collapsed to JOB_NOP. And use u->nop_job instead |
||||
of u->job. |
||||
|
||||
If a JOB_NOP job is going on with a waiting state, a parallel daemon-reload |
||||
just install it during deserialization. Without a coldplug, the job will |
||||
not be in m->run_queue, which results in a hung try-restart or |
||||
try-reload process. |
||||
|
||||
Reproduce: |
||||
1. run systemctl try-restart test.servcie (inactive) repeatly in a terminal. |
||||
2. run systemctl daemon-reload repeatly in other terminals. |
||||
|
||||
After successful reproduce, systemctl list-jobs will list the hang job. |
||||
|
||||
Upsteam: |
||||
https://github.com/systemd/systemd/pull/13124 |
||||
|
||||
Resolves: #1829754 |
||||
--- |
||||
src/core/unit.c | 6 ++++-- |
||||
1 file changed, 4 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/src/core/unit.c b/src/core/unit.c |
||||
index 2b058dd3e8..d953780a52 100644 |
||||
--- a/src/core/unit.c |
||||
+++ b/src/core/unit.c |
||||
@@ -2918,6 +2918,7 @@ static int unit_add_deserialized_job_coldplug(Unit *u) { |
||||
|
||||
int unit_coldplug(Unit *u, Hashmap *deferred_work) { |
||||
int r; |
||||
+ Job *uj; |
||||
|
||||
assert(u); |
||||
|
||||
@@ -2925,8 +2926,9 @@ int unit_coldplug(Unit *u, Hashmap *deferred_work) { |
||||
if ((r = UNIT_VTABLE(u)->coldplug(u, deferred_work)) < 0) |
||||
return r; |
||||
|
||||
- if (u->job) { |
||||
- r = job_coldplug(u->job); |
||||
+ uj = u->job ?: u->nop_job; |
||||
+ if (uj) { |
||||
+ r = job_coldplug(uj); |
||||
if (r < 0) |
||||
return r; |
||||
} else if (u->deserialized_job >= 0) |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
From df8adf9c8a8258ae041db28f4bf411da6156170a Mon Sep 17 00:00:00 2001 |
||||
From: Lennart Poettering <lennart@poettering.net> |
||||
Date: Wed, 22 Apr 2020 20:34:02 +0200 |
||||
Subject: [PATCH] core: make sure to restore the control command id, too |
||||
|
||||
Fixes: #15356 |
||||
(cherry picked from commit e9da62b18af647bfa73807e1c7fc3bfa4bb4b2ac) |
||||
|
||||
Resolves: #1828953 |
||||
--- |
||||
src/core/service.c | 5 +++-- |
||||
1 file changed, 3 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c |
||||
index dd0ae7cb88..4c73b6ef96 100644 |
||||
--- a/src/core/service.c |
||||
+++ b/src/core/service.c |
||||
@@ -2263,9 +2263,10 @@ static int service_deserialize_exec_command(Unit *u, const char *key, const char |
||||
break; |
||||
} |
||||
|
||||
- if (command && control) |
||||
+ if (command && control) { |
||||
s->control_command = command; |
||||
- else if (command) |
||||
+ s->control_command_id = id; |
||||
+ } else if (command) |
||||
s->main_command = command; |
||||
else |
||||
log_unit_warning(u->id, "Current command vanished from the unit file, execution of the command list won't be resumed."); |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
From 20fb5227cd981c5eb188a6ad738672486e40a50e Mon Sep 17 00:00:00 2001 |
||||
From: David Tardon <dtardon@redhat.com> |
||||
Date: Mon, 11 May 2020 13:34:24 +0200 |
||||
Subject: [PATCH] avoid double free |
||||
|
||||
This was a mis-merge in the fix for #1809053 (commit |
||||
f99cc28e392874b317b4ff2054bbd6970f71ecdd). |
||||
|
||||
Resolves: #1832816 |
||||
--- |
||||
src/udev/udev-builtin-path_id.c | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c |
||||
index b0bcd80571..1db403b39c 100644 |
||||
--- a/src/udev/udev-builtin-path_id.c |
||||
+++ b/src/udev/udev-builtin-path_id.c |
||||
@@ -428,7 +428,7 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char * |
||||
struct udev_device *hostdev; |
||||
struct udev_device *vmbusdev; |
||||
const char *guid_str; |
||||
- _cleanup_free_ char *lun = NULL; |
||||
+ char *lun = NULL; |
||||
char guid[39]; |
||||
size_t i, k; |
||||
|
Loading…
Reference in new issue