Compare commits
10 Commits
0a13d80ef0
...
5ea9aa237b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ea9aa237b | ||
|
|
04a0c174c3 | ||
|
|
8cd2917618 | ||
|
|
4a5b21b9be | ||
|
|
8f9981b19d | ||
|
|
79244683b7 | ||
|
|
54330e0ee2 | ||
|
|
ecfedff322 | ||
|
|
4cfc514b17 | ||
|
|
b81c9fa518 |
@ -1,222 +0,0 @@
|
||||
From 49f6a75e648c113fa9985675f47f78a4cd57c084 Mon Sep 17 00:00:00 2001
|
||||
From: yangbin <robin.yb@huawei.com>
|
||||
Date: Fri, 26 Jul 2019 10:02:58 +0800
|
||||
Subject: [PATCH] systemd-core: Add new rules for lower priority events to
|
||||
preempt over higher priority events
|
||||
|
||||
1. When a high priority event happenes very frequent, and this event takes long time for execution,systemd will get into busy for handling this event only, and lower priority events will have no any change to dispatch and run.
|
||||
|
||||
2. One example is the event for /proc/self/mountinfo, which have a very high priority with -10.
|
||||
When there are many mountpoints in mountinfo(for example, there may be many netns mountpoints),this event will take long time to finish.
|
||||
Then if now there are mountpoints in repeating mounting and unmounting(for example, /run/user/uid mountpoint will be mounted then unmounted when for one su command),
|
||||
this event will take all time of systemd, and lower priority lower events will not be dispatched anyway.
|
||||
This will case a very severity problem that zombie process will not be reaped, for the evnet for reaping zombies has a lower priority of -6.
|
||||
|
||||
3. This patch fix this problem by add the following rules to allow lower priority events to preempt over higher priority events.
|
||||
a) If a higher priority event has already been execute for a certain count in consecutive, it can be preempted by lower priority events. The default value for this count is 10, and can be configured through 'sd_event_source_set_preempt_dispatch_count'.
|
||||
b) If a lower priority gets into pending for 10 times in consecutive, it can preempt over higher priority events.
|
||||
c) If a lower priority is in pending, and is not dispatched over 50 iteration, it can preempt over higher priority events.
|
||||
d) The above rules only works for events with priority equal or higher than 'SD_EVENT_PRIORITY_NORMAL' or evnets with type of SOURCE_DEFER, since SOURCE_DEFER events is used for job running queues.
|
||||
---
|
||||
src/core/mount.c | 4 ++
|
||||
src/libsystemd/sd-event/sd-event.c | 87 ++++++++++++++++++++++++++++++
|
||||
src/systemd/sd-event.h | 1 +
|
||||
3 files changed, 92 insertions(+)
|
||||
|
||||
diff --git a/src/core/mount.c b/src/core/mount.c
|
||||
index 1b94ab4..78b6e30 100644
|
||||
--- a/src/core/mount.c
|
||||
+++ b/src/core/mount.c
|
||||
@@ -1742,6 +1742,10 @@ static void mount_enumerate(Manager *m) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ r = sd_event_source_set_preempt_dispatch_count(m->mount_event_source, 5);
|
||||
+ if (r < 0)
|
||||
+ goto fail;
|
||||
+
|
||||
(void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch");
|
||||
}
|
||||
|
||||
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
|
||||
index d53b9a7..7e33061 100644
|
||||
--- a/src/libsystemd/sd-event/sd-event.c
|
||||
+++ b/src/libsystemd/sd-event/sd-event.c
|
||||
@@ -26,6 +26,11 @@
|
||||
#include "time-util.h"
|
||||
#include "util.h"
|
||||
|
||||
+#define DEFAULT_PREEMPTED_ITERATION_COUNT (3)
|
||||
+#define DEFAULT_PREEMPT_DISPATCH_COUNT (10)
|
||||
+#define DEFAULT_PREEMPT_PENDING_COUNT (10)
|
||||
+#define DEFAULT_PREEMPT_ITERATION_COUNT (30)
|
||||
+
|
||||
#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
|
||||
|
||||
typedef enum EventSourceType {
|
||||
@@ -103,6 +108,11 @@ struct sd_event_source {
|
||||
uint64_t pending_iteration;
|
||||
uint64_t prepare_iteration;
|
||||
|
||||
+ uint64_t preempted_iteration; /*The iteration that dispatched_count is greater than preempt_dispatch_count*/
|
||||
+ unsigned pending_count; /*times of pending not dispatched*/
|
||||
+ unsigned dispatched_count; /*consecutive dispatched count*/
|
||||
+ unsigned preempt_dispatch_count; /*Will be preempted by lower priority if dispatched count reaches to this*/
|
||||
+
|
||||
sd_event_destroy_t destroy_callback;
|
||||
|
||||
LIST_FIELDS(sd_event_source, sources);
|
||||
@@ -301,6 +311,11 @@ struct sd_event {
|
||||
|
||||
LIST_HEAD(sd_event_source, sources);
|
||||
|
||||
+ /*last dispatched source, its type is sd_event_source,
|
||||
+ * here use void to avoid accessing its members,
|
||||
+ * for it may have been freed already.*/
|
||||
+ void *last_source;
|
||||
+
|
||||
usec_t last_run, last_log;
|
||||
unsigned delays[sizeof(usec_t) * 8];
|
||||
};
|
||||
@@ -314,8 +329,42 @@ static sd_event *event_resolve(sd_event *e) {
|
||||
return e == SD_EVENT_DEFAULT ? default_event : e;
|
||||
}
|
||||
|
||||
+static int preempt_prioq_compare(const sd_event_source *x, const sd_event_source *y) {
|
||||
+ if((x->priority > SD_EVENT_PRIORITY_NORMAL && x->type != SOURCE_DEFER)
|
||||
+ || (y->priority > SD_EVENT_PRIORITY_NORMAL && y->type != SOURCE_DEFER)) {
|
||||
+ return 0; /*only high priority evnets can preempt*/
|
||||
+ }
|
||||
+
|
||||
+ if(x->priority <= y->priority) {
|
||||
+ if(x->dispatched_count >= x->preempt_dispatch_count)
|
||||
+ return 1;
|
||||
+ if(y->type != SOURCE_DEFER) { /*pending state for defer event is always true*/
|
||||
+ /*y has lower priority, but its pending count is greater than x, so y wins*/
|
||||
+ if(y->pending_count >= (x->pending_count + DEFAULT_PREEMPT_PENDING_COUNT))
|
||||
+ return 1;
|
||||
+ /*y has lower priority, but is in pending longer than x, so y wins*/
|
||||
+ if(x->pending_iteration >= (y->pending_iteration + DEFAULT_PREEMPT_ITERATION_COUNT))
|
||||
+ return 1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if(y->dispatched_count >= y->preempt_dispatch_count)
|
||||
+ return -1;
|
||||
+ if(x->type != SOURCE_DEFER) { /*pending state for defer event is always true*/
|
||||
+ /*x has lower priority, but its pending count is greater than y, so x wins*/
|
||||
+ if(x->pending_count >= (y->pending_count + DEFAULT_PREEMPT_PENDING_COUNT))
|
||||
+ return -1;
|
||||
+ /*x has lower priority, but is in pending longer than y, so x wins*/
|
||||
+ if(y->pending_iteration >= (x->pending_iteration + DEFAULT_PREEMPT_ITERATION_COUNT))
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int pending_prioq_compare(const void *a, const void *b) {
|
||||
const sd_event_source *x = a, *y = b;
|
||||
+ int r;
|
||||
|
||||
assert(x->pending);
|
||||
assert(y->pending);
|
||||
@@ -326,6 +375,10 @@ static int pending_prioq_compare(const void *a, const void *b) {
|
||||
if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
|
||||
return 1;
|
||||
|
||||
+ r = preempt_prioq_compare(a, b);
|
||||
+ if(r)
|
||||
+ return r;
|
||||
+
|
||||
/* Lower priority values first */
|
||||
if (x->priority < y->priority)
|
||||
return -1;
|
||||
@@ -1030,6 +1083,17 @@ static int source_set_pending(sd_event_source *s, bool b) {
|
||||
assert(s);
|
||||
assert(s->type != SOURCE_EXIT);
|
||||
|
||||
+ if (b && s->pending == b)
|
||||
+ s->pending_count++;
|
||||
+ else
|
||||
+ s->pending_count = (b ? 1 : 0);
|
||||
+ if (b && s->preempted_iteration &&
|
||||
+ (s->pending_count >= DEFAULT_PREEMPTED_ITERATION_COUNT ||
|
||||
+ s->event->iteration >= (s->preempted_iteration + DEFAULT_PREEMPTED_ITERATION_COUNT)) ) {
|
||||
+ s->dispatched_count = 0;
|
||||
+ s->preempted_iteration = 0;
|
||||
+ }
|
||||
+
|
||||
if (s->pending == b)
|
||||
return 0;
|
||||
|
||||
@@ -1097,6 +1161,7 @@ static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType t
|
||||
.type = type,
|
||||
.pending_index = PRIOQ_IDX_NULL,
|
||||
.prepare_index = PRIOQ_IDX_NULL,
|
||||
+ .preempt_dispatch_count = DEFAULT_PREEMPT_DISPATCH_COUNT,
|
||||
};
|
||||
|
||||
if (!floating)
|
||||
@@ -2263,6 +2328,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
|
||||
return r;
|
||||
}
|
||||
|
||||
+ s->pending_count = 0;
|
||||
switch (s->type) {
|
||||
|
||||
case SOURCE_IO:
|
||||
@@ -3055,6 +3121,19 @@ static int process_inotify(sd_event *e) {
|
||||
return done;
|
||||
}
|
||||
|
||||
+static void source_dispatch_pre(sd_event_source *s) {
|
||||
+ if(s->event->last_source == s) {
|
||||
+ s->dispatched_count++;
|
||||
+ if(s->dispatched_count >= s->preempt_dispatch_count)
|
||||
+ s->preempted_iteration = s->event->iteration;
|
||||
+ } else {
|
||||
+ s->preempted_iteration = 0;
|
||||
+ s->dispatched_count = 0;
|
||||
+ }
|
||||
+ s->event->last_source = s;
|
||||
+ s->pending_count = 0;
|
||||
+}
|
||||
+
|
||||
static int source_dispatch(sd_event_source *s) {
|
||||
EventSourceType saved_type;
|
||||
int r = 0;
|
||||
@@ -3095,6 +3174,7 @@ static int source_dispatch(sd_event_source *s) {
|
||||
return r;
|
||||
}
|
||||
|
||||
+ source_dispatch_pre(s);
|
||||
s->dispatching = true;
|
||||
|
||||
switch (s->type) {
|
||||
@@ -3793,3 +3873,10 @@ _public_ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_d
|
||||
|
||||
return !!s->destroy_callback;
|
||||
}
|
||||
+
|
||||
+_public_ int sd_event_source_set_preempt_dispatch_count(sd_event_source *s, unsigned count) {
|
||||
+ assert_return(s, -EINVAL);
|
||||
+
|
||||
+ s->preempt_dispatch_count = count;
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
|
||||
index 7fcae4a..fdf9108 100644
|
||||
--- a/src/systemd/sd-event.h
|
||||
+++ b/src/systemd/sd-event.h
|
||||
@@ -143,6 +143,7 @@ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid);
|
||||
int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret);
|
||||
int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback);
|
||||
int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret);
|
||||
+int sd_event_source_set_preempt_dispatch_count(sd_event_source *s, unsigned count);
|
||||
|
||||
/* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref);
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
From a5c08598384d44ad3bce24ff63ab320b3b3e5292 Mon Sep 17 00:00:00 2001
|
||||
From: huangkaibin <huangkaibin@huawei.com>
|
||||
Date: Wed, 31 Jan 2018 22:28:36 +0800
|
||||
Subject: [PATCH] systemd-core: Serialize pids for scope unit when it is not
|
||||
started
|
||||
|
||||
1. when a scope unit is initialized, and daemon-reload is performed before it is started,
|
||||
pids (generally comes from dbus) belog to this scope will not be attached to the cgroup of this scope,
|
||||
because these pids are not serialized and are lost during daemon-reload.
|
||||
2. this patch fix this problem by serializing scope pids when the state of the scope is DEAD(the init state).
|
||||
---
|
||||
src/core/scope.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
diff --git a/src/core/scope.c b/src/core/scope.c
|
||||
index ae6614f..8d96ee1 100644
|
||||
--- a/src/core/scope.c
|
||||
+++ b/src/core/scope.c
|
||||
@@ -194,6 +194,8 @@ static int scope_load(Unit *u) {
|
||||
|
||||
static int scope_coldplug(Unit *u) {
|
||||
Scope *s = SCOPE(u);
|
||||
+ Iterator i;
|
||||
+ void *pidp = NULL;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
@@ -214,6 +216,12 @@ static int scope_coldplug(Unit *u) {
|
||||
bus_scope_track_controller(s);
|
||||
|
||||
scope_set_state(s, s->deserialized_state);
|
||||
+ if (s->state == SCOPE_DEAD && !u->cgroup_path && !set_isempty(u->pids)) {
|
||||
+ SET_FOREACH(pidp, u->pids, i) {
|
||||
+ log_unit_info(u, "Rewatch pid from serialized pids. unit: %s, pid: %u", u->id, PTR_TO_UINT32(pidp));
|
||||
+ unit_watch_pid(u, PTR_TO_UINT32(pidp));
|
||||
+ }
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -396,6 +404,8 @@ static int scope_get_timeout(Unit *u, usec_t *timeout) {
|
||||
}
|
||||
|
||||
static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
+ Iterator i;
|
||||
+ void *pidp = NULL;
|
||||
Scope *s = SCOPE(u);
|
||||
|
||||
assert(s);
|
||||
@@ -408,6 +418,14 @@ static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
if (s->controller)
|
||||
unit_serialize_item(u, f, "controller", s->controller);
|
||||
|
||||
+ /*serialize pids when scope is not started*/
|
||||
+ if (s->state == SCOPE_DEAD && !u->cgroup_path && !set_isempty(u->pids)) {
|
||||
+ SET_FOREACH(pidp, u->pids, i) {
|
||||
+ log_unit_info(u, "scope is not started yet, pids are serialized. unit: %s, pid: %u", u->id, PTR_TO_UINT32(pidp));
|
||||
+ unit_serialize_item_format(u, f, "scope_pids", PID_FMT, PTR_TO_UINT32(pidp));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -443,6 +461,21 @@ static int scope_deserialize_item(Unit *u, const char *key, const char *value, F
|
||||
if (r < 0)
|
||||
log_oom();
|
||||
|
||||
+ } else if (streq(key, "scope_pids")) {
|
||||
+ pid_t pid;
|
||||
+
|
||||
+ if (parse_pid(value, &pid) < 0)
|
||||
+ log_unit_debug(u, "Failed to parse scope-pid value %s.", value);
|
||||
+ else {
|
||||
+ if(!u->pids) {
|
||||
+ r = set_ensure_allocated(&u->pids, NULL);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ }
|
||||
+ r = set_put(u->pids, pid);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ }
|
||||
} else
|
||||
log_unit_debug(u, "Unknown serialization key: %s", key);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
From 650352c713aeb3b47807c9699ceeb168f9f880b8 Mon Sep 17 00:00:00 2001
|
||||
From: huangkaibin <huangkaibin@huawei.com>
|
||||
Date: Tue, 13 Mar 2018 20:51:37 +0800
|
||||
Subject: [PATCH] systemd-core: Do not finish job during daemon reloading in
|
||||
unit_notify.
|
||||
|
||||
1. During daemon reload, a service unit will restore its state from dead to its deserialized state,
|
||||
and unit_notify will be triggered to notify the state change.
|
||||
Since JobRemove signal will not be sent during daemon-reload(see details of job_uninstall),
|
||||
if one job is finished in unit_notify due to the deserialization of a service, the corresponding
|
||||
job observers(such as systemctl) will not receive any JobRemove signals will hang forever.
|
||||
2. The above problem will cause a systemctl command to hang forever by using the following steps to reproduce.
|
||||
a) Ensuere a service(named A)is in running state.
|
||||
b) execute "systemctl daemon-reload" and "systemctl start A" concurrently
|
||||
c) the systemctl command will hang for it is in waiting for the JobRemoved signal, but not signals will come from systemd.
|
||||
3. This patch fix this bug by not finishing job in unit_notify when it is in daemon reload.
|
||||
---
|
||||
src/core/unit.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||
index 9e5f1a8..2da6f61 100644
|
||||
--- a/src/core/unit.c
|
||||
+++ b/src/core/unit.c
|
||||
@@ -1831,7 +1831,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
|
||||
|
||||
unit_update_on_console(u);
|
||||
|
||||
- if (u->job) {
|
||||
+ if (u->job &&
|
||||
+ !(m->n_reloading > 0 && u->job->state != JOB_RUNNING && os == UNIT_INACTIVE)) { /*do not finish job during daemon-reload*/
|
||||
unexpected = false;
|
||||
|
||||
if (u->job->state == JOB_WAITING)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
30
backport-fix-cgtop-sscanf-return-code-checks.patch
Normal file
30
backport-fix-cgtop-sscanf-return-code-checks.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From bab356f5a0b8d4a43a71076c2333ff4da7ed737e Mon Sep 17 00:00:00 2001
|
||||
From: Luca Boccassi <bluca@debian.org>
|
||||
Date: Fri, 19 Jan 2024 15:12:49 +0000
|
||||
Subject: [PATCH] cgtop: fix sscanf return code checks
|
||||
|
||||
sscanf can return EOF on error, so check that we get a result instead.
|
||||
|
||||
CodeQL#2386 and CodeQL#2387
|
||||
|
||||
(cherry picked from commit 204d52c4b79eb19d2919cb5214e999c58a6679c6)
|
||||
---
|
||||
src/cgtop/cgtop.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
|
||||
index e34da7cf728..ca514554408 100644
|
||||
--- a/src/cgtop/cgtop.c
|
||||
+++ b/src/cgtop/cgtop.c
|
||||
@@ -310,9 +310,9 @@ static int process(
|
||||
|
||||
if (all_unified) {
|
||||
while (!isempty(l)) {
|
||||
- if (sscanf(l, "rbytes=%" SCNu64, &k))
|
||||
+ if (sscanf(l, "rbytes=%" SCNu64, &k) == 1)
|
||||
rd += k;
|
||||
- else if (sscanf(l, "wbytes=%" SCNu64, &k))
|
||||
+ else if (sscanf(l, "wbytes=%" SCNu64, &k) == 1)
|
||||
wr += k;
|
||||
|
||||
l += strcspn(l, WHITESPACE);
|
||||
@ -0,0 +1,32 @@
|
||||
From 4c3e455c093c274e3ccbc4662e47a72c3f43a34d Mon Sep 17 00:00:00 2001
|
||||
From: Mike Yuan <me@yhndnzj.com>
|
||||
Date: Mon, 5 Feb 2024 04:53:14 +0800
|
||||
Subject: [PATCH] login/user-runtime-dir: properly check for mount point
|
||||
|
||||
(cherry picked from commit 561d8793058bba886d71f96fa157ca77cd6b5c23)
|
||||
(cherry picked from commit 0ec2d29241b9d5d77630ba5ad7fa1cf4f632e1f6)
|
||||
(cherry picked from commit ad9eafcc8264976b762efe4d0ce70f924d2be0bc)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/systemd/systemd-stable/commit/4c3e455c093c274e3ccbc4662e47a72c3f43a34d
|
||||
|
||||
---
|
||||
src/login/user-runtime-dir.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c
|
||||
index f96a2d8662..c74d8b8d0e 100644
|
||||
--- a/src/login/user-runtime-dir.c
|
||||
+++ b/src/login/user-runtime-dir.c
|
||||
@@ -66,7 +66,7 @@ static int user_mkdir_runtime_path(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create /run/user: %m");
|
||||
|
||||
- if (path_is_mount_point(runtime_path, NULL, 0) >= 0)
|
||||
+ if (path_is_mount_point(runtime_path, NULL, 0) > 0)
|
||||
log_debug("%s is already a mount point", runtime_path);
|
||||
else {
|
||||
char options[sizeof("mode=0700,uid=,gid=,size=,smackfsroot=*")
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,160 @@
|
||||
From 9d3aec2603e9d10889797f1412fafd16c25a4920 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 17 Feb 2022 14:40:25 +0100
|
||||
Subject: [PATCH] pid1: lookup owning PID of BusName= name of services
|
||||
asynchronously
|
||||
|
||||
A first step of removing blocking calls to the D-Bus broker from PID 1.
|
||||
There's a lot more to got (i.e. grep src/core/ for sd_bus_creds
|
||||
basically), but it's a start.
|
||||
|
||||
Removing blocking calls to D-Bus broker deals systematicallly with
|
||||
deadlocks caused by dbus-daemon blocking on synchronous IPC calls back
|
||||
to PID1 (e.g. Varlink calls through nss-systemd). Bugs such as #15316.
|
||||
|
||||
Also-see: https://github.com/systemd/systemd/pull/22038#issuecomment-1042958390
|
||||
(cherry picked from commit e39eb045a502d599e6cd3fda7a46020dd438d018)
|
||||
(cherry picked from commit cf390149cb25248169c482e315a1a7ff02eaf956)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/systemd/systemd/commit/1daa382a7f9e55d11f7b59b144a9963688169843
|
||||
---
|
||||
src/core/service.c | 91 ++++++++++++++++++++++++++++++++++++----------
|
||||
src/core/service.h | 2 +
|
||||
2 files changed, 74 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 4cada77..2e3720b 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -407,6 +407,8 @@ static void service_done(Unit *u) {
|
||||
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
|
||||
s->exec_fd_event_source = sd_event_source_unref(s->exec_fd_event_source);
|
||||
|
||||
+ s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot);
|
||||
+
|
||||
service_release_resources(u);
|
||||
}
|
||||
|
||||
@@ -4079,6 +4081,60 @@ static int service_get_timeout(Unit *u, usec_t *timeout) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static bool pick_up_pid_from_bus_name(Service *s) {
|
||||
+ assert(s);
|
||||
+
|
||||
+ /* If the service is running but we have no main PID yet, get it from the owner of the D-Bus name */
|
||||
+
|
||||
+ return !pid_is_valid(s->main_pid) &&
|
||||
+ IN_SET(s->state,
|
||||
+ SERVICE_START,
|
||||
+ SERVICE_START_POST,
|
||||
+ SERVICE_RUNNING,
|
||||
+ SERVICE_RELOAD);
|
||||
+}
|
||||
+
|
||||
+static int bus_name_pid_lookup_callback(sd_bus_message *reply, void *userdata, sd_bus_error *ret_error) {
|
||||
+ const sd_bus_error *e;
|
||||
+ Unit *u = userdata;
|
||||
+ uint32_t pid;
|
||||
+ Service *s;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(reply);
|
||||
+ assert(u);
|
||||
+
|
||||
+ s = SERVICE(u);
|
||||
+ s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot);
|
||||
+
|
||||
+ if (!s->bus_name || !pick_up_pid_from_bus_name(s))
|
||||
+ return 1;
|
||||
+
|
||||
+ e = sd_bus_message_get_error(reply);
|
||||
+ if (e) {
|
||||
+ r = sd_bus_error_get_errno(e);
|
||||
+ log_warning_errno(r, "GetConnectionUnixProcessID() failed: %s", bus_error_message(e, r));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ r = sd_bus_message_read(reply, "u", &pid);
|
||||
+ if (r < 0) {
|
||||
+ bus_log_parse_error(r);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (!pid_is_valid(pid)) {
|
||||
+ log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "GetConnectionUnixProcessID() returned invalid PID");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, s->bus_name, (pid_t) pid);
|
||||
+
|
||||
+ service_set_main_pid(s, pid);
|
||||
+ unit_watch_pid(UNIT(s), pid, false);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static void service_bus_name_owner_change(Unit *u, const char *new_owner) {
|
||||
|
||||
Service *s = SERVICE(u);
|
||||
@@ -4109,28 +4165,25 @@ static void service_bus_name_owner_change(Unit *u, const char *new_owner) {
|
||||
else if (s->state == SERVICE_START && new_owner)
|
||||
service_enter_start_post(s);
|
||||
|
||||
- } else if (new_owner &&
|
||||
- s->main_pid <= 0 &&
|
||||
- IN_SET(s->state,
|
||||
- SERVICE_START,
|
||||
- SERVICE_START_POST,
|
||||
- SERVICE_RUNNING,
|
||||
- SERVICE_RELOAD)) {
|
||||
-
|
||||
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||
- pid_t pid;
|
||||
+ } else if (new_owner && pick_up_pid_from_bus_name(s)) {
|
||||
|
||||
/* Try to acquire PID from bus service */
|
||||
|
||||
- r = sd_bus_get_name_creds(u->manager->api_bus, s->bus_name, SD_BUS_CREDS_PID, &creds);
|
||||
- if (r >= 0)
|
||||
- r = sd_bus_creds_get_pid(creds, &pid);
|
||||
- if (r >= 0) {
|
||||
- log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, s->bus_name, pid);
|
||||
-
|
||||
- service_set_main_pid(s, pid);
|
||||
- unit_watch_pid(UNIT(s), pid, false);
|
||||
- }
|
||||
+ s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot);
|
||||
+
|
||||
+ r = sd_bus_call_method_async(
|
||||
+ u->manager->api_bus,
|
||||
+ &s->bus_name_pid_lookup_slot,
|
||||
+ "org.freedesktop.DBus",
|
||||
+ "/org/freedesktop/DBus",
|
||||
+ "org.freedesktop.DBus",
|
||||
+ "GetConnectionUnixProcessID",
|
||||
+ bus_name_pid_lookup_callback,
|
||||
+ s,
|
||||
+ "s",
|
||||
+ s->bus_name);
|
||||
+ if (r < 0)
|
||||
+ log_debug_errno(r, "Failed to request owner PID of service name, ignoring: %m");
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/core/service.h b/src/core/service.h
|
||||
index 11e861a..04809e9 100644
|
||||
--- a/src/core/service.h
|
||||
+++ b/src/core/service.h
|
||||
@@ -174,6 +174,8 @@ struct Service {
|
||||
NotifyAccess notify_access;
|
||||
NotifyState notify_state;
|
||||
|
||||
+ sd_bus_slot *bus_name_pid_lookup_slot;
|
||||
+
|
||||
sd_event_source *exec_fd_event_source;
|
||||
|
||||
ServiceFDStore *fd_store;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,125 @@
|
||||
From 0863a55ae95fe6bf7312b7a864d07a9e3fbee563 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 17 Feb 2022 14:49:54 +0100
|
||||
Subject: [PATCH] pid1: set SYSTEMD_NSS_DYNAMIC_BYPASS=1 env var for
|
||||
dbus-daemon
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There's currently a deadlock between PID 1 and dbus-daemon: in some
|
||||
cases dbus-daemon will do NSS lookups (which are blocking) at the same
|
||||
time PID 1 synchronously blocks on some call to dbus-daemon. Let's break
|
||||
that by setting SYSTEMD_NSS_DYNAMIC_BYPASS=1 env var for dbus-daemon,
|
||||
which will disable synchronously blocking varlink calls from nss-systemd
|
||||
to PID 1.
|
||||
|
||||
In the long run we should fix this differently: remove all synchronous
|
||||
calls to dbus-daemon from PID 1. This is not trivial however: so far we
|
||||
had the rule that synchronous calls from PID 1 to the dbus broker are OK
|
||||
as long as they only go to interfaces implemented by the broke itself
|
||||
rather than services reachable through it. Given that the relationship
|
||||
between PID 1 and dbus is kinda special anyway, this was considered
|
||||
acceptable for the sake of simplicity, since we quite often need
|
||||
metadata about bus peers from the broker, and the asynchronous logic
|
||||
would substantially complicate even the simplest method handlers.
|
||||
|
||||
This mostly reworks the existing code that sets SYSTEMD_NSS_BYPASS_BUS=
|
||||
(which is a similar hack to deal with deadlocks between nss-systemd and
|
||||
dbus-daemon itself) to set SYSTEMD_NSS_DYNAMIC_BYPASS=1 instead. No code
|
||||
was checking SYSTEMD_NSS_BYPASS_BUS= anymore anyway, and it used to
|
||||
solve a similar problem, hence it's an obvious piece of code to rework
|
||||
like this.
|
||||
|
||||
Issue originally tracked down by Lukas Märdian. This patch is inspired
|
||||
and closely based on his patch:
|
||||
|
||||
https://github.com/systemd/systemd/pull/22038
|
||||
|
||||
Fixes: #15316
|
||||
Co-authored-by: Lukas Märdian <slyon@ubuntu.com>
|
||||
(cherry picked from commit de90700f36f2126528f7ce92df0b5b5d5e277558)
|
||||
(cherry picked from commit 367041af816d48d4852140f98fd0ba78ed83f9e4)
|
||||
|
||||
Conflict:different code contexts, manual synchronization patch
|
||||
Reference:https://github.com/systemd/systemd/commit/0863a55ae95fe6bf7312b7a864d07a9e3fbee563
|
||||
---
|
||||
src/core/execute.c | 10 +++++-----
|
||||
src/core/execute.h | 26 +++++++++++++-------------
|
||||
src/core/service.c | 2 +-
|
||||
3 files changed, 19 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||
index 28efe5c36f..37f63a9378 100644
|
||||
--- a/src/core/execute.c
|
||||
+++ b/src/core/execute.c
|
||||
@@ -1828,11 +1828,11 @@ static int build_environment(
|
||||
our_env[n_env++] = x;
|
||||
}
|
||||
|
||||
- /* If this is D-Bus, tell the nss-systemd module, since it relies on being able to use D-Bus look up dynamic
|
||||
- * users via PID 1, possibly dead-locking the dbus daemon. This way it will not use D-Bus to resolve names, but
|
||||
- * check the database directly. */
|
||||
- if (p->flags & EXEC_NSS_BYPASS_BUS) {
|
||||
- x = strdup("SYSTEMD_NSS_BYPASS_BUS=1");
|
||||
+ /* If this is D-Bus, tell the nss-systemd module, since it relies on being able to use blocking
|
||||
+ * Varlink calls back to us for look up dynamic users in PID 1. Break the deadlock between D-Bus and
|
||||
+ * PID 1 by disabling use of PID1' NSS interface for looking up dynamic users. */
|
||||
+ if (p->flags & EXEC_NSS_DYNAMIC_BYPASS) {
|
||||
+ x = strdup("SYSTEMD_NSS_DYNAMIC_BYPASS=1");
|
||||
if (!x)
|
||||
return -ENOMEM;
|
||||
our_env[n_env++] = x;
|
||||
diff --git a/src/core/execute.h b/src/core/execute.h
|
||||
index 4c7a5b874f..47349a69a2 100644
|
||||
--- a/src/core/execute.h
|
||||
+++ b/src/core/execute.h
|
||||
@@ -297,20 +297,20 @@ static inline bool exec_context_restrict_namespaces_set(const ExecContext *c) {
|
||||
}
|
||||
|
||||
typedef enum ExecFlags {
|
||||
- EXEC_APPLY_SANDBOXING = 1 << 0,
|
||||
- EXEC_APPLY_CHROOT = 1 << 1,
|
||||
- EXEC_APPLY_TTY_STDIN = 1 << 2,
|
||||
- EXEC_PASS_LOG_UNIT = 1 << 3, /* Whether to pass the unit name to the service's journal stream connection */
|
||||
- EXEC_CHOWN_DIRECTORIES = 1 << 4, /* chown() the runtime/state/cache/log directories to the user we run as, under all conditions */
|
||||
- EXEC_NSS_BYPASS_BUS = 1 << 5, /* Set the SYSTEMD_NSS_BYPASS_BUS environment variable, to disable nss-systemd for dbus */
|
||||
- EXEC_CGROUP_DELEGATE = 1 << 6,
|
||||
- EXEC_IS_CONTROL = 1 << 7,
|
||||
- EXEC_CONTROL_CGROUP = 1 << 8, /* Place the process not in the indicated cgroup but in a subcgroup '/.control', but only EXEC_CGROUP_DELEGATE and EXEC_IS_CONTROL is set, too */
|
||||
+ EXEC_APPLY_SANDBOXING = 1 << 0,
|
||||
+ EXEC_APPLY_CHROOT = 1 << 1,
|
||||
+ EXEC_APPLY_TTY_STDIN = 1 << 2,
|
||||
+ EXEC_PASS_LOG_UNIT = 1 << 3, /* Whether to pass the unit name to the service's journal stream connection */
|
||||
+ EXEC_CHOWN_DIRECTORIES = 1 << 4, /* Set the SYSTEMD_NSS_DYNAMIC_BYPASS environment variable, to disable nss-systemd blocking on PID 1, for use by dbus-daemon */
|
||||
+ EXEC_NSS_DYNAMIC_BYPASS = 1 << 5, /* Set the EXEC_NSS_DYNAMIC_BYPASS environment variable, to disable nss-systemd for dbus */
|
||||
+ EXEC_CGROUP_DELEGATE = 1 << 6,
|
||||
+ EXEC_IS_CONTROL = 1 << 7,
|
||||
+ EXEC_CONTROL_CGROUP = 1 << 8, /* Place the process not in the indicated cgroup but in a subcgroup '/.control', but only EXEC_CGROUP_DELEGATE and EXEC_IS_CONTROL is set, too */
|
||||
|
||||
/* The following are not used by execute.c, but by consumers internally */
|
||||
- EXEC_PASS_FDS = 1 << 9,
|
||||
- EXEC_SETENV_RESULT = 1 << 10,
|
||||
- EXEC_SET_WATCHDOG = 1 << 11,
|
||||
+ EXEC_PASS_FDS = 1 << 9,
|
||||
+ EXEC_SETENV_RESULT = 1 << 10,
|
||||
+ EXEC_SET_WATCHDOG = 1 << 11,
|
||||
} ExecFlags;
|
||||
|
||||
/* Parameters for a specific invocation of a command. This structure is put together right before a command is
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index f6eb46cb54..a480edc439 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -1573,7 +1573,7 @@ static int service_spawn(
|
||||
return -ENOMEM;
|
||||
|
||||
/* System D-Bus needs nss-systemd disabled, so that we don't deadlock */
|
||||
- SET_FLAG(exec_params.flags, EXEC_NSS_BYPASS_BUS,
|
||||
+ SET_FLAG(exec_params.flags, EXEC_NSS_DYNAMIC_BYPASS,
|
||||
MANAGER_IS_SYSTEM(UNIT(s)->manager) && unit_has_name(UNIT(s), SPECIAL_DBUS_SERVICE));
|
||||
|
||||
strv_free_and_replace(exec_params.environment, final_env);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
53
backport-pid1-watch-bus-name-always-when-we-have-it.patch
Normal file
53
backport-pid1-watch-bus-name-always-when-we-have-it.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From b301230a6ce52989053b12324fcaef0d45610ee6 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 17 Feb 2022 17:23:48 +0100
|
||||
Subject: [PATCH] pid1: watch bus name always when we have it
|
||||
|
||||
Previously we'd only watch configured service bus names if Type=dbus was
|
||||
set. Let's also watch it for other types. This is useful to pick up the
|
||||
main PID of such a service. In fact the code to pick it up was already
|
||||
in place, alas it didn't do anything given the signal was never received
|
||||
for it. Fix that.
|
||||
|
||||
(It's also useful for debugging)
|
||||
|
||||
(cherry picked from commit 1e8b312e5a22538f91defb89cf2997e09e106297)
|
||||
(cherry picked from commit a51e540b278827c0fc59760b9c77cd42cbddc0d2)
|
||||
|
||||
Conflict:different code contexts, manual synchronization patch
|
||||
Reference:https://github.com/systemd/systemd/commit/b301230a6ce52989053b12324fcaef0d45610ee6
|
||||
---
|
||||
src/core/service.c | 18 ++++++++++--------
|
||||
1 file changed, 10 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 7b90822f68..5f56217904 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -697,14 +697,16 @@ static int service_setup_bus_name(Service *s) {
|
||||
if (!s->bus_name)
|
||||
return 0;
|
||||
|
||||
- r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, true, UNIT_DEPENDENCY_FILE);
|
||||
- if (r < 0)
|
||||
- return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
|
||||
+ if (s->type == SERVICE_DBUS) {
|
||||
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, true, UNIT_DEPENDENCY_FILE);
|
||||
+ if (r < 0)
|
||||
+ return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
|
||||
|
||||
- /* We always want to be ordered against dbus.socket if both are in the transaction. */
|
||||
- r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, true, UNIT_DEPENDENCY_FILE);
|
||||
- if (r < 0)
|
||||
- return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
|
||||
+ /* We always want to be ordered against dbus.socket if both are in the transaction. */
|
||||
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, true, UNIT_DEPENDENCY_FILE);
|
||||
+ if (r < 0)
|
||||
+ return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
|
||||
+ }
|
||||
|
||||
r = unit_watch_bus_name(UNIT(s), s->bus_name);
|
||||
if (r == -EEXIST)
|
||||
--
|
||||
2.33.0
|
||||
|
||||
32
backport-user-util-validate-the-right-field.patch
Normal file
32
backport-user-util-validate-the-right-field.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 3db209c9567c728c13b5d901e81f151ed1d2b0f7 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Fri, 19 Jan 2024 11:32:26 +0100
|
||||
Subject: [PATCH] user-util: validate the right field
|
||||
|
||||
(cherry picked from commit 829854afa5e38db30be207fc8f8f80705e623795)
|
||||
(cherry picked from commit 624984ff423a98f1fd66e64ddfe3a8972d2f911f)
|
||||
(cherry picked from commit 641b8d700694984e40199008b059a65184dc946b)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/systemd/systemd-stable/commit/3db209c9567c728c13b5d901e81f151ed1d2b0f7
|
||||
|
||||
---
|
||||
src/basic/user-util.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
|
||||
index 519ab70118..c81d19409d 100644
|
||||
--- a/src/basic/user-util.c
|
||||
+++ b/src/basic/user-util.c
|
||||
@@ -314,7 +314,7 @@ int get_user_creds(
|
||||
if (shell) {
|
||||
if (FLAGS_SET(flags, USER_CREDS_CLEAN) &&
|
||||
(isempty(p->pw_shell) ||
|
||||
- !path_is_valid(p->pw_dir) ||
|
||||
+ !path_is_valid(p->pw_shell) ||
|
||||
!path_is_absolute(p->pw_shell) ||
|
||||
is_nologin_shell(p->pw_shell)))
|
||||
*shell = NULL;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
From 95100aa8fa3182f3b066bdc5927b0a78c37550aa Mon Sep 17 00:00:00 2001
|
||||
From: huangkaibin <huangkaibin@huawei.com>
|
||||
Date: Mon, 23 Jul 2018 17:58:18 +0800
|
||||
Subject: [PATCH] systemd-udevd: Call malloc_trim to return memory to OS
|
||||
immediately in forked children.
|
||||
|
||||
hen there are many events from kernel, memory used to store these events(in event_list)
|
||||
will be large, may be up to 100M. The forked child process will have a copy of these events and
|
||||
release them using free. But since glibc will release memory to OS immediately, and if this child process
|
||||
is stuck due I/O waiting(in D state), these memory will never be released until it is recoveried from D-state.
|
||||
When there are so many such child processes, it will eat up much memory from system.
|
||||
This patch fix this problem by invoking glibc's malloc_trim to release memory immediately when the child is forked.
|
||||
---
|
||||
meson.build | 6 ++++++
|
||||
src/udev/udevd.c | 12 ++++++++++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index c14540a..5ee2fa7 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -518,6 +518,12 @@ else
|
||||
conf.set10('HAVE_GETRANDOM', have)
|
||||
endif
|
||||
|
||||
+if cc.has_function('malloc_trim', prefix : '''#include <malloc.h>''')
|
||||
+ conf.set10('HAVE_MALLOC_TRIM', true)
|
||||
+else
|
||||
+ conf.set10('HAVE_MALLOC_TRIM', false)
|
||||
+endif
|
||||
+
|
||||
#####################################################################
|
||||
|
||||
sed = find_program('sed')
|
||||
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
|
||||
index c1119c3..62f1c44 100644
|
||||
--- a/src/udev/udevd.c
|
||||
+++ b/src/udev/udevd.c
|
||||
@@ -27,6 +27,9 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
+#ifdef HAVE_MALLOC_TRIM
|
||||
+#include <malloc.h>
|
||||
+#endif
|
||||
|
||||
#include "sd-daemon.h"
|
||||
#include "sd-event.h"
|
||||
@@ -233,6 +236,15 @@ static void worker_spawn(Manager *manager, struct event *event) {
|
||||
|
||||
manager->event = sd_event_unref(manager->event);
|
||||
|
||||
+#ifdef HAVE_MALLOC_TRIM
|
||||
+ /* unused memory inherits from parent has been freed, but it will
|
||||
+ * not release to OS immediately. We do the optimization by invoking
|
||||
+ * glibc's malloc_trim to force these unused memory to return to OS immediately.
|
||||
+ * Otherwise when there are many forked process, it will eat up system's memory,
|
||||
+ * and will cause OOM problem.
|
||||
+ */
|
||||
+ malloc_trim(0);
|
||||
+#endif
|
||||
sigfillset(&mask);
|
||||
fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
|
||||
if (fd_signal < 0) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
155
process-util-log-more-information-when-runnin.patch
Normal file
155
process-util-log-more-information-when-runnin.patch
Normal file
@ -0,0 +1,155 @@
|
||||
From f5747a70602fa145988a1c4047fe5bd49ebacace Mon Sep 17 00:00:00 2001
|
||||
From: licunlong <licunlong1@huawei.com>
|
||||
Date: Tue, 24 Dec 2024 15:44:36 +0800
|
||||
Subject: [PATCH] process-util: log more information when running systemctl.
|
||||
|
||||
Print the PID and its cmdline to the system log when a process
|
||||
runs systemctl command.
|
||||
---
|
||||
src/basic/process-util.c | 31 +++++++++++++++++++++++++++++++
|
||||
src/basic/process-util.h | 1 +
|
||||
src/systemctl/systemctl.c | 12 ++++++++++++
|
||||
src/test/test-process-util.c | 22 ++++++++++++++++++++++
|
||||
4 files changed, 66 insertions(+)
|
||||
|
||||
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
|
||||
index 9e1f1df..c77f509 100644
|
||||
--- a/src/basic/process-util.c
|
||||
+++ b/src/basic/process-util.c
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "stat-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
+#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
#include "utf8.h"
|
||||
@@ -189,6 +190,36 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int print_process_cmdline_with_arg(pid_t pid, int argc, char *argv[], char *filter[]) {
|
||||
+ bool is_filtered = false;
|
||||
+ int r;
|
||||
+ const char *arg_cmdline = "[";
|
||||
+ _cleanup_free_ char *cmdline = NULL;
|
||||
+
|
||||
+ r = get_process_cmdline(pid, SIZE_MAX, 0, &cmdline);
|
||||
+ if (r < 0) {
|
||||
+ syslog(LOG_INFO, "Failed to get cmdline of PID %d. Ignoring.", pid);
|
||||
+ return r;
|
||||
+ } else {
|
||||
+ for (int i = 0; i < argc; i++ ) {
|
||||
+ if (filter && strv_find(filter, argv[i])) {
|
||||
+ is_filtered = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (i == 0) {
|
||||
+ arg_cmdline = strjoina(arg_cmdline, argv[i]);
|
||||
+ } else {
|
||||
+ arg_cmdline = strjoina(arg_cmdline, " ", argv[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ if (!is_filtered) {
|
||||
+ syslog(LOG_INFO, "%s] called by PID %d (%s)", arg_cmdline, pid, cmdline);
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
int rename_process(const char name[]) {
|
||||
static size_t mm_size = 0;
|
||||
static char *mm = NULL;
|
||||
diff --git a/src/basic/process-util.h b/src/basic/process-util.h
|
||||
index 41d4759..4d8147e 100644
|
||||
--- a/src/basic/process-util.h
|
||||
+++ b/src/basic/process-util.h
|
||||
@@ -38,6 +38,7 @@ typedef enum ProcessCmdlineFlags {
|
||||
|
||||
int get_process_comm(pid_t pid, char **name);
|
||||
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line);
|
||||
+int print_process_cmdline_with_arg(pid_t pid, int argc, char *argv[], char *filter[]);
|
||||
int get_process_exe(pid_t pid, char **name);
|
||||
int get_process_uid(pid_t pid, uid_t *uid);
|
||||
int get_process_gid(pid_t pid, gid_t *gid);
|
||||
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
||||
index 1c01914..edba8e0 100644
|
||||
--- a/src/systemctl/systemctl.c
|
||||
+++ b/src/systemctl/systemctl.c
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <locale.h>
|
||||
+#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
@@ -9272,6 +9273,14 @@ static int logind_cancel_shutdown(void) {
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
int r;
|
||||
+ pid_t ppid;
|
||||
+ char *filter[] = {
|
||||
+ "status", "show", "cat",
|
||||
+ "is-active", "is-failed", "is-enabled", "is-system-running",
|
||||
+ "list-units", "list-sockets", "list-timers", "list-dependencies",
|
||||
+ "list-unit-files", "list-machines", "list-jobs",
|
||||
+ "get-default", "show-environment", NULL
|
||||
+ };
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
log_parse_environment();
|
||||
@@ -9291,6 +9300,9 @@ static int run(int argc, char *argv[]) {
|
||||
if (r <= 0)
|
||||
goto finish;
|
||||
|
||||
+ ppid = getppid();
|
||||
+ (void) print_process_cmdline_with_arg(ppid, argc, argv, filter);
|
||||
+
|
||||
if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) {
|
||||
if (!arg_quiet)
|
||||
log_info("Running in chroot, ignoring request.");
|
||||
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
|
||||
index 8dc9fdd..1cb4ee2 100644
|
||||
--- a/src/test/test-process-util.c
|
||||
+++ b/src/test/test-process-util.c
|
||||
@@ -601,6 +601,27 @@ static void test_ioprio_class_from_to_string(void) {
|
||||
test_ioprio_class_from_to_string_one("-1", -1);
|
||||
}
|
||||
|
||||
+static void test_print_process_cmdline_with_arg(pid_t pid) {
|
||||
+ char *arg_filter_empty[] = {"", NULL};
|
||||
+ char *arg_filter_1_in[] = {"status", NULL};
|
||||
+ char *arg_filter_1_no[] = {"stop", NULL};
|
||||
+ char *arg_filter_2_in[] = {"restart", "status", NULL};
|
||||
+ char *arg_filter_2_no[] = {"restart", "stop", NULL};
|
||||
+ char *arg_var_1[1] = {"systemctl"};
|
||||
+ char *arg_var_10[10] = {"systemctl", "restart", "1", "2", "3", "4", "5", "6", "7", "8"};
|
||||
+ char *arg_var_filter[3] = {"systemctl", "status", "dbus.service"};
|
||||
+ assert_se(print_process_cmdline_with_arg(pid, 0, NULL, NULL) >=0);
|
||||
+ assert_se(print_process_cmdline_with_arg(pid, 1, arg_var_1, NULL) >= 0);
|
||||
+ assert_se(print_process_cmdline_with_arg(pid, 10, arg_var_10, NULL) >= 0);
|
||||
+ assert_se(print_process_cmdline_with_arg(897349, 1, arg_var_1, NULL) < 0);
|
||||
+ assert_se(print_process_cmdline_with_arg(897349, 10, arg_var_10, NULL) < 0);
|
||||
+ assert_se(print_process_cmdline_with_arg(pid, 3, arg_var_filter, arg_filter_empty) >= 0);
|
||||
+ assert_se(print_process_cmdline_with_arg(pid, 3, arg_var_filter, arg_filter_1_in) >= 0);
|
||||
+ assert_se(print_process_cmdline_with_arg(pid, 3, arg_var_filter, arg_filter_1_no) >= 0);
|
||||
+ assert_se(print_process_cmdline_with_arg(pid, 3, arg_var_filter, arg_filter_2_in) >= 0);
|
||||
+ assert_se(print_process_cmdline_with_arg(pid, 3, arg_var_filter, arg_filter_2_no) >= 0);
|
||||
+}
|
||||
+
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
@@ -627,6 +648,7 @@ int main(int argc, char *argv[]) {
|
||||
test_safe_fork();
|
||||
test_pid_to_ptr();
|
||||
test_ioprio_class_from_to_string();
|
||||
+ test_print_process_cmdline_with_arg(getpid());
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
From 1245ae05c6e2ca7a2af055f9c44f19a0db2971a5 Mon Sep 17 00:00:00 2001
|
||||
From: yangbin <robin.yb@huawei.com>
|
||||
Date: Thu, 15 Aug 2019 15:24:03 +0800
|
||||
Subject: [PATCH 3/3] systemd-core: Close and free dbus when bus authenticating
|
||||
timedout
|
||||
|
||||
1. when timedout happened on authenticating a private dbus(can be established by systemctl command),
|
||||
this dbus will never be freed and closed, and will left on systemd permanently even through the client
|
||||
(for example, systemctl command) has closed the connection. This is because when timedout happend,
|
||||
the event and also the timer to watch dbus actions is disabled by sd_event_source_set_enabled
|
||||
from source_dispatch function, and systemd can do nothing on it since this dbus will not be activated again.
|
||||
2. If a private dbus staying on authenticating state, and when systemd sends a signal message, it will also
|
||||
add this message to the message write queue of this bus and will never send it out because the dbus is not in running.
|
||||
systemd does this for it believe that the bus will change from authenticating to running sometime, but actually it will not.
|
||||
3. When many private dbuses are left as authenticating and many signal messages are sent from dbus, it will eat up our memory
|
||||
to hold these dbuses and messages, and memory usage of systemd will grow very fast.
|
||||
4. This patch fix this problem by closing and freeing the dbus when authenticating timedout.
|
||||
---
|
||||
src/libsystemd/sd-bus/sd-bus.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
|
||||
index 05cb4c3..65cf449 100644
|
||||
--- a/src/libsystemd/sd-bus/sd-bus.c
|
||||
+++ b/src/libsystemd/sd-bus/sd-bus.c
|
||||
@@ -2946,6 +2946,11 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit
|
||||
if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
|
||||
bus_enter_closing(bus);
|
||||
r = 1;
|
||||
+ } else if(r == -ETIMEDOUT && !bus->is_system) {
|
||||
+ /*close dbus directly when timedout happened and it is a private dbus*/
|
||||
+ log_info("Private bus is closed due authentication timedout.");
|
||||
+ bus_enter_closing(bus);
|
||||
+ r = 1;
|
||||
} else if (r < 0)
|
||||
return r;
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
34
systemd.spec
34
systemd.spec
@ -16,7 +16,7 @@
|
||||
Name: systemd
|
||||
Url: https://systemd.io/
|
||||
Version: 243
|
||||
Release: 78
|
||||
Release: 83
|
||||
License: MIT and LGPLv2+ and GPLv2+
|
||||
Summary: System and Service Manager
|
||||
|
||||
@ -305,6 +305,12 @@ Patch0257: backport-utmp-remove-dev-from-line.patch
|
||||
Patch0258: backport-core-exec-do-not-crash-with-UtmpMode-user-without-Us.patch
|
||||
Patch0259: backport-CVE-2023-50387.patch
|
||||
Patch0260: backport-CVE-2023-50868.patch
|
||||
Patch0261: backport-login-user-runtime-dir-properly-check-for-mount-poin.patch
|
||||
Patch0262: backport-user-util-validate-the-right-field.patch
|
||||
Patch0263: backport-fix-cgtop-sscanf-return-code-checks.patch
|
||||
Patch0264: backport-pid1-set-SYSTEMD_NSS_DYNAMIC_BYPASS-1-env-var-for-db.patch
|
||||
Patch0265: backport-pid1-lookup-owning-PID-of-BusName-name-of-services-a.patch
|
||||
Patch0266: backport-pid1-watch-bus-name-always-when-we-have-it.patch
|
||||
|
||||
#openEuler
|
||||
Patch9002: 1509-fix-journal-file-descriptors-leak-problems.patch
|
||||
@ -321,6 +327,7 @@ Patch9010: fix-capsh-drop-but-ping-success.patch
|
||||
Patch9011: 0998-resolved-create-etc-resolv.conf-symlink-at-runtime.patch
|
||||
Patch9012: set-kernel-core_pipe_limit-to-16.patch
|
||||
Patch9013: disable-systemd-timesyncd-networkd-resolved-by-defau.patch
|
||||
Patch9014: process-util-log-more-information-when-runnin.patch
|
||||
|
||||
BuildRequires: gcc, gcc-c++
|
||||
BuildRequires: libcap-devel, libmount-devel, pam-devel, libselinux-devel
|
||||
@ -1712,6 +1719,31 @@ fi
|
||||
%exclude /usr/share/man/man3/*
|
||||
|
||||
%changelog
|
||||
* Thu Jan 2 2025 Han Jinpeng <hanjinpeng@kylinos.cn> - 243-83
|
||||
- Enhance the logging function of the systemctl command
|
||||
Add process-util-log-more-information-when-runnin.patch
|
||||
|
||||
* Tue Nov 5 2024 zhangyao <zhangyao108@huawei.com> - 243-82
|
||||
- sync community patches
|
||||
add backport-pid1-set-SYSTEMD_NSS_DYNAMIC_BYPASS-1-env-var-for-db.patch
|
||||
backport-pid1-lookup-owning-PID-of-BusName-name-of-services-a.patch
|
||||
backport-pid1-watch-bus-name-always-when-we-have-it.patch
|
||||
|
||||
* Thu Aug 22 2024 zhangyao <zhangyao108@huawei.com> - 243-81
|
||||
- remove redundant patch
|
||||
del 1610-add-new-rules-for-lower-priority-events-to-preempt.patch
|
||||
core-bugfix-call-malloc_trim-to-return-memory-to-OS-immediately.patch
|
||||
1612-serialize-pids-for-scope-when-not-started.patch
|
||||
systemd-core-Close-and-free-dbus-when-bus-authentica.patch
|
||||
1615-do-not-finish-job-during-daemon-reload-in-unit_notify.patch
|
||||
|
||||
* Thu Aug 1 2024 Han Jinpeng <hanjinpeng@kylinos.cn> - 243-80
|
||||
- backport: fix cgtop sscanf return code checks
|
||||
|
||||
* Mon Apr 29 2024 huyubiao <huyubiao@huawei.com> - 243-79
|
||||
- add backport-login-user-runtime-dir-properly-check-for-mount-poin.patch
|
||||
backport-user-util-validate-the-right-field.patch
|
||||
|
||||
* Wed Apr 17 2024 huyubiao <huyubiao@huawei.com> - 243-78
|
||||
- fix CVE-2023-50387 and CVE-2023-50868
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user