代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/systemd 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From bc6377762c210d1bdd7fd2465930731d87dda576 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <[email protected]>
Date: Sat, 29 Apr 2023 04:31:53 +0900
Subject: [PATCH] core/path: do not enqueue new job in .trigger_notify callback
Otherwise,
1. X.path triggered X.service, and the service has waiting start job,
2. systemctl stop X.service
3. the waiting start job is cancelled to install new stop job,
4. path_trigger_notify() is called, and may reinstall new start job,
5. the stop job cannot be installed, and triggeres assertion.
So, instead, let's add a defer event source, then enqueue the new start
job after the stop (or any other type) job finished.
Fixes https://github.com/systemd/systemd/issues/24577#issuecomment-1522628906.
Conflict:NA
Reference:https://github.com/systemd/systemd-stable/commit/bc6377762c210d1bdd7fd2465930731d87dda576
---
src/core/path.c | 68 +++++++++++++++++++++++++++++++++++++++++++++----
src/core/path.h | 2 ++
2 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/src/core/path.c b/src/core/path.c
index 9f6a246ab0..c95663c3aa 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -10,6 +10,7 @@
#include "dbus-path.h"
#include "dbus-unit.h"
#include "escape.h"
+#include "event-util.h"
#include "fd-util.h"
#include "glob-util.h"
#include "inotify-util.h"
@@ -300,6 +301,7 @@ static void path_done(Unit *u) {
assert(p);
+ p->trigger_notify_event_source = sd_event_source_disable_unref(p->trigger_notify_event_source);
path_free_specs(p);
}
@@ -575,6 +577,9 @@ static void path_enter_waiting(Path *p, bool initial, bool from_trigger_notify)
Unit *trigger;
int r;
+ if (p->trigger_notify_event_source)
+ (void) event_source_disable(p->trigger_notify_event_source);
+
/* If the triggered unit is already running, so are we */
trigger = UNIT_TRIGGER(UNIT(p));
if (trigger && !UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(trigger))) {
@@ -799,8 +804,28 @@ fail:
return 0;
}
-static void path_trigger_notify(Unit *u, Unit *other) {
+static void path_trigger_notify_impl(Unit *u, Unit *other, bool on_defer);
+
+static int path_trigger_notify_on_defer(sd_event_source *s, void *userdata) {
+ Path *p = ASSERT_PTR(userdata);
+ Unit *trigger;
+
+ assert(s);
+
+ trigger = UNIT_TRIGGER(UNIT(p));
+ if (!trigger) {
+ log_unit_error(UNIT(p), "Unit to trigger vanished.");
+ path_enter_dead(p, PATH_FAILURE_RESOURCES);
+ return 0;
+ }
+
+ path_trigger_notify_impl(UNIT(p), trigger, /* on_defer = */ true);
+ return 0;
+}
+
+static void path_trigger_notify_impl(Unit *u, Unit *other, bool on_defer) {
Path *p = PATH(u);
+ int r;
assert(u);
assert(other);
@@ -826,13 +851,46 @@ static void path_trigger_notify(Unit *u, Unit *other) {
if (p->state == PATH_RUNNING &&
UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
- log_unit_debug(UNIT(p), "Got notified about unit deactivation.");
- path_enter_waiting(p, false, true);
+ if (!on_defer)
+ log_unit_debug(u, "Got notified about unit deactivation.");
} else if (p->state == PATH_WAITING &&
!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
- log_unit_debug(UNIT(p), "Got notified about unit activation.");
- path_enter_waiting(p, false, true);
+ if (!on_defer)
+ log_unit_debug(u, "Got notified about unit activation.");
+ } else
+ return;
+
+ if (on_defer) {
+ path_enter_waiting(p, /* initial = */ false, /* from_trigger_notify = */ true);
+ return;
}
+
+ /* Do not call path_enter_waiting() directly from path_trigger_notify(), as this may be called by
+ * job_install() -> job_finish_and_invalidate() -> unit_trigger_notify(), and path_enter_waiting()
+ * may install another job and will trigger assertion in job_install().
+ * https://github.com/systemd/systemd/issues/24577#issuecomment-1522628906
+ * Hence, first setup defer event source here, and call path_enter_waiting() slightly later. */
+ if (p->trigger_notify_event_source) {
+ r = sd_event_source_set_enabled(p->trigger_notify_event_source, SD_EVENT_ONESHOT);
+ if (r < 0) {
+ log_unit_warning_errno(u, r, "Failed to enable event source for triggering notify: %m");
+ path_enter_dead(p, PATH_FAILURE_RESOURCES);
+ return;
+ }
+ } else {
+ r = sd_event_add_defer(u->manager->event, &p->trigger_notify_event_source, path_trigger_notify_on_defer, p);
+ if (r < 0) {
+ log_unit_warning_errno(u, r, "Failed to allocate event source for triggering notify: %m");
+ path_enter_dead(p, PATH_FAILURE_RESOURCES);
+ return;
+ }
+
+ (void) sd_event_source_set_description(p->trigger_notify_event_source, "path-trigger-notify");
+ }
+}
+
+static void path_trigger_notify(Unit *u, Unit *other) {
+ path_trigger_notify_impl(u, other, /* on_defer = */ false);
}
static void path_reset_failed(Unit *u) {
diff --git a/src/core/path.h b/src/core/path.h
index c76103cc12..cb5b662911 100644
--- a/src/core/path.h
+++ b/src/core/path.h
@@ -65,6 +65,8 @@ struct Path {
PathResult result;
RateLimit trigger_limit;
+
+ sd_event_source *trigger_notify_event_source;
};
struct ActivationDetailsPath {
--
2.39.1
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。