basebuilder_pel7x64builder0
3 years ago
41 changed files with 3670 additions and 23 deletions
@ -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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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