import CS git systemd-239-82.el8_10.17

This commit is contained in:
AlmaLinux RelEng Bot 2026-06-16 12:28:44 -04:00
parent 090e90a906
commit 82d69edaf9
7 changed files with 482 additions and 1 deletions

View File

@ -0,0 +1,48 @@
From a403a9f149773b8c7900e9b32f72949e023b8e99 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 10 Dec 2018 18:52:11 +0100
Subject: [PATCH] job: update job_free() to follow our usual return-NULL style
(cherry picked from commit 728ba51e98959dfd9ad9f70cf6526b0a84b529a0)
Related: RHEL-168671
---
src/core/job.c | 4 ++--
src/core/job.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/core/job.c b/src/core/job.c
index 55f36b928f..9e6756caa2 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -87,7 +87,7 @@ void job_unlink(Job *j) {
j->timer_event_source = sd_event_source_unref(j->timer_event_source);
}
-void job_free(Job *j) {
+Job* job_free(Job *j) {
assert(j);
assert(!j->installed);
assert(!j->transaction_prev);
@@ -100,7 +100,7 @@ void job_free(Job *j) {
sd_bus_track_unref(j->bus_track);
strv_free(j->deserialized_clients);
- free(j);
+ return mfree(j);
}
static void job_set_state(Job *j, JobState state) {
diff --git a/src/core/job.h b/src/core/job.h
index 189fea20ca..7b4d2e7317 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -162,7 +162,7 @@ struct Job {
Job* job_new(Unit *unit, JobType type);
Job* job_new_raw(Unit *unit);
void job_unlink(Job *job);
-void job_free(Job *job);
+Job* job_free(Job *job);
Job* job_install(Job *j);
int job_install_deserialized(Job *j);
void job_uninstall(Job *j);

View File

@ -0,0 +1,135 @@
From c9a7e899240de5af6c5756065b7c8ba38719bfd9 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 10 Dec 2018 18:52:28 +0100
Subject: [PATCH] core: don't track jobs-finishing-during-reload explicitly
Memory management is borked for this, and moreover this is unnecessary
since f0831ed2a03, i.e. since coldplug() and catchup() are two different
concepts: the former restoring the state from before a reload, the
latter than adjusting it again to the actual status in effect after the
reload.
Fixes: #10716
Mostly reverts: #8803
(cherry picked from commit 4a53080be637f6dad91515fc896d9f77fbc17f0c)
Related: RHEL-168671
---
src/core/job.c | 21 +--------------------
src/core/job.h | 1 -
src/core/manager.c | 14 --------------
src/core/manager.h | 3 ---
4 files changed, 1 insertion(+), 38 deletions(-)
diff --git a/src/core/job.c b/src/core/job.c
index 9e6756caa2..30a0c8cd68 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -39,7 +39,6 @@ Job* job_new_raw(Unit *unit) {
j->manager = unit->manager;
j->unit = unit;
j->type = _JOB_TYPE_INVALID;
- j->reloaded = false;
return j;
}
@@ -255,7 +254,6 @@ int job_install_deserialized(Job *j) {
*pj = j;
j->installed = true;
- j->reloaded = true;
if (j->state == JOB_RUNNING)
j->unit->manager->n_running_jobs++;
@@ -959,19 +957,6 @@ static void job_fail_dependencies(Unit *u, UnitDependency d) {
}
}
-static int job_save_pending_finished_job(Job *j) {
- int r;
-
- assert(j);
-
- r = set_ensure_allocated(&j->manager->pending_finished_jobs, NULL);
- if (r < 0)
- return r;
-
- job_unlink(j);
- return set_put(j->manager->pending_finished_jobs, j);
-}
-
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
Unit *u;
Unit *other;
@@ -1011,11 +996,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
j->manager->n_failed_jobs++;
job_uninstall(j);
- /* Keep jobs started before the reload to send singal later, free all others */
- if (!MANAGER_IS_RELOADING(j->manager) ||
- !j->reloaded ||
- job_save_pending_finished_job(j) < 0)
- job_free(j);
+ job_free(j);
/* Fail depending jobs on failure */
if (result != JOB_DONE && recursive) {
diff --git a/src/core/job.h b/src/core/job.h
index 7b4d2e7317..f40010f38d 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -156,7 +156,6 @@ struct Job {
bool irreversible:1;
bool in_gc_queue:1;
bool ref_by_private_bus:1;
- bool reloaded:1;
};
Job* job_new(Unit *unit, JobType type);
diff --git a/src/core/manager.c b/src/core/manager.c
index 51325f0212..f242f0cc00 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -3450,17 +3450,6 @@ finish:
return r;
}
-static void manager_flush_finished_jobs(Manager *m) {
- Job *j;
-
- while ((j = set_steal_first(m->pending_finished_jobs))) {
- bus_job_send_removed_signal(j);
- job_free(j);
- }
-
- m->pending_finished_jobs = set_free(m->pending_finished_jobs);
-}
-
int manager_reload(Manager *m) {
int r, q;
_cleanup_fclose_ FILE *f = NULL;
@@ -3582,9 +3571,6 @@ int manager_reload(Manager *m) {
if (q < 0 && r >= 0)
r = q;
- if (!MANAGER_IS_RELOADING(m))
- manager_flush_finished_jobs(m);
-
m->send_reloading_done = true;
return r;
diff --git a/src/core/manager.h b/src/core/manager.h
index e713250238..a043a469a2 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -310,9 +310,6 @@ struct Manager {
/* non-zero if we are reloading or reexecuting, */
int n_reloading;
- /* A set which contains all jobs that started before reload and finished
- * during it */
- Set *pending_finished_jobs;
unsigned n_installed_jobs;
unsigned n_failed_jobs;

View File

@ -0,0 +1,34 @@
From ee856def59ca099ed0477d66538493ccfed51f46 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 10 Dec 2018 19:38:38 +0100
Subject: [PATCH] job: be more careful when removing job object from jobs hash
table
Let's validate that the ID is actually allocated to us before remove a
job.
This is relevant as various bits of code will call job_free() on
partially set up Job objects, and we really shouldn't remove another job
object accidentally from the hash table, when the set up didn't
complete.
(cherry picked from commit 48235ad6b7ef168e029d48701a08b62b616bcdd2)
Related: RHEL-168671
---
src/core/job.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/job.c b/src/core/job.c
index 30a0c8cd68..9f9396312f 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -148,7 +148,7 @@ void job_uninstall(Job *j) {
unit_add_to_gc_queue(j->unit);
- hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
+ hashmap_remove_value(j->manager->jobs, UINT32_TO_PTR(j->id), j);
j->installed = false;
}

View File

@ -0,0 +1,142 @@
From 2710b77aad881e18166dac0899431506cf364ca3 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 10 Dec 2018 19:40:37 +0100
Subject: [PATCH] core: rework how we deserialize jobs
Let's add a helper call unit_deserialize_job() for this purpose, and
let's move registration in the global jobs hash table into
job_install_deserialized() so that it it is done after all superficial
checks are done, and before transitioning into installed states, so that
rollback code is not necessary anymore.
(cherry picked from commit b17c9620c87a1d8117da72b30a2e096df02a2bb5)
Related: RHEL-168671
---
src/core/job.c | 22 +++++++++++++--------
src/core/job.h | 2 ++
src/core/unit.c | 52 +++++++++++++++++++++++++------------------------
3 files changed, 43 insertions(+), 33 deletions(-)
diff --git a/src/core/job.c b/src/core/job.c
index 9f9396312f..9b0c260f4f 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -238,19 +238,25 @@ Job* job_install(Job *j) {
int job_install_deserialized(Job *j) {
Job **pj;
+ int r;
assert(!j->installed);
- if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
- log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
- return -EINVAL;
- }
+ if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION)
+ return log_unit_debug_errno(j->unit, -EINVAL,
+ "Invalid job type %s in deserialization.",
+ strna(job_type_to_string(j->type)));
pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
- if (*pj) {
- log_unit_debug(j->unit, "Unit already has a job installed. Not installing deserialized job.");
- return -EEXIST;
- }
+ if (*pj)
+ return log_unit_debug_errno(j->unit, -EEXIST,
+ "Unit already has a job installed. Not installing deserialized job.");
+
+ r = hashmap_put(j->manager->jobs, UINT32_TO_PTR(j->id), j);
+ if (r == -EEXIST)
+ return log_unit_debug_errno(j->unit, r, "Job ID %" PRIu32 " already used, cannot deserialize job.", j->id);
+ if (r < 0)
+ return log_unit_debug_errno(j->unit, r, "Failed to insert job into jobs hash table: %m");
*pj = j;
j->installed = true;
diff --git a/src/core/job.h b/src/core/job.h
index f40010f38d..0dccc4225b 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -222,6 +222,8 @@ void job_add_to_gc_queue(Job *j);
int job_get_before(Job *j, Job*** ret);
int job_get_after(Job *j, Job*** ret);
+DEFINE_TRIVIAL_CLEANUP_FUNC(Job*, job_free);
+
const char* job_type_to_string(JobType t) _const_;
JobType job_type_from_string(const char *s) _pure_;
diff --git a/src/core/unit.c b/src/core/unit.c
index 70e1d68ea4..9dada18378 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -3440,6 +3440,29 @@ void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *f
fputc('\n', f);
}
+static int unit_deserialize_job(Unit *u, FILE *f) {
+ _cleanup_(job_freep) Job *j = NULL;
+ int r;
+
+ assert(u);
+ assert(f);
+
+ j = job_new_raw(u);
+ if (!j)
+ return log_oom();
+
+ r = job_deserialize(j, f);
+ if (r < 0)
+ return r;
+
+ r = job_install_deserialized(j);
+ if (r < 0)
+ return r;
+
+ TAKE_PTR(j);
+ return 0;
+}
+
int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
int r;
@@ -3473,32 +3496,11 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
if (streq(l, "job")) {
if (v[0] == '\0') {
- /* new-style serialized job */
- Job *j;
-
- j = job_new_raw(u);
- if (!j)
- return log_oom();
-
- r = job_deserialize(j, f);
- if (r < 0) {
- job_free(j);
- return r;
- }
-
- r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
- if (r < 0) {
- job_free(j);
- return r;
- }
-
- r = job_install_deserialized(j);
- if (r < 0) {
- hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
- job_free(j);
+ /* New-style serialized job */
+ r = unit_deserialize_job(u, f);
+ if (r < 0)
return r;
- }
- } else /* legacy for pre-44 */
+ } else /* Legacy for pre-44 */
log_unit_warning(u, "Update from too old systemd versions are unsupported, cannot deserialize job: %s", v);
continue;
} else if (streq(l, "state-change-timestamp")) {

View File

@ -0,0 +1,72 @@
From cd6e9c951e745fce3e1b8bf5ddae551276ea564c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 11 Dec 2018 11:59:39 +0100
Subject: [PATCH] core: when a unit state changes only propagate to jobs after
reloading is complete
Previously, we'd immediately propagate unit state changes into any jobs
pending for them, always. With this we only do this if the manager is
out of the "reload" state. This fixes the problem #8803 tried to
address, by simply not completing jobs until after the reload (and thus
reestablishment of the dbus connection) is complete.
Note that there's no need to later on explicitly catch up with the
missed job state changes (i.e. there's no need to call
unit_process_job() later one explicitly). That's because for jobs in
JOB_WAITING state on deserialization all jobs are requeued into the run
queue anyway, and thus checked again if they can complete now. And for
JOB_RUNNING jobs unit_catchup() phase is going to trigger missed out
state changes *after* the reload complete anyway (after all that's what
distinguishes from unit_coldplug()).
Replaces: #8803
(cherry picked from commit a1c7334b619de28ec20392628db3a0f46b5f0bdc)
Related: RHEL-168671
---
src/core/unit.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index 9dada18378..29dea1f6db 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2379,7 +2379,6 @@ static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags)
}
void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags) {
- bool unexpected;
Manager *m;
assert(u);
@@ -2418,20 +2417,18 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
unit_update_on_console(u);
- /* Let's propagate state changes to the job */
- if (u->job)
- unexpected = unit_process_job(u->job, ns, flags);
- else
- unexpected = true;
-
if (!MANAGER_IS_RELOADING(m)) {
+ bool unexpected;
+
+ /* Let's propagate state changes to the job */
+ if (u->job)
+ unexpected = unit_process_job(u->job, ns, flags);
+ else
+ unexpected = true;
- /* If this state change happened without being
- * requested by a job, then let's retroactively start
- * or stop dependencies. We skip that step when
- * deserializing, since we don't want to create any
- * additional jobs just because something is already
- * activated. */
+ /* If this state change happened without being requested by a job, then let's retroactively start or
+ * stop dependencies. We skip that step when deserializing, since we don't want to create any
+ * additional jobs just because something is already activated. */
if (unexpected) {
if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))

View File

@ -0,0 +1,36 @@
From dd0c1ce0eec10226da5789c43ba4b3f5305ea012 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 11 Dec 2018 15:22:10 +0100
Subject: [PATCH] core: extend comments regarding coldplug() vs. catchup()
(cherry picked from commit a95c0505ad89b77878ed05192fe91175cf42e8b5)
Related: RHEL-168671
---
src/core/unit.h | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/core/unit.h b/src/core/unit.h
index e2dd7949e5..914035d55c 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -446,11 +446,16 @@ typedef struct UnitVTable {
int (*load)(Unit *u);
/* During deserialization we only record the intended state to return to. With coldplug() we actually put the
- * deserialized state in effect. This is where unit_notify() should be called to start things up. */
+ * deserialized state in effect. This is where unit_notify() should be called to start things up. Note that
+ * this callback is invoked *before* we leave the reloading state of the manager, i.e. *before* we consider the
+ * reloading to be complete. Thus, this callback should just restore the exact same state for any unit that was
+ * in effect before the reload, i.e. units should not catch up with changes happened during the reload. That's
+ * what catchup() below is for. */
int (*coldplug)(Unit *u);
- /* This is called shortly after all units' coldplug() call was invoked. It's supposed to catch up state changes
- * we missed so far (for example because they took place while we were reloading/reexecing) */
+ /* This is called shortly after all units' coldplug() call was invoked, and *after* the manager left the
+ * reloading state. It's supposed to catch up with state changes due to external events we missed so far (for
+ * example because they took place while we were reloading/reexecing) */
void (*catchup)(Unit *u);
void (*dump)(Unit *u, FILE *f, const char *prefix);

View File

@ -13,7 +13,7 @@
Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd
Version: 239
Release: 82%{?dist}.16
Release: 82%{?dist}.17
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager
@ -1125,6 +1125,12 @@ Patch1072: 1072-udev-check-for-invalid-chars-in-various-fields-recei.patch
Patch1073: 1073-udev-fix-review-mixup.patch
Patch1074: 1074-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch
Patch1075: 1075-core-manager-fix-memory-leak.patch
Patch1076: 1076-job-update-job_free-to-follow-our-usual-return-NULL-.patch
Patch1077: 1077-core-don-t-track-jobs-finishing-during-reload-explic.patch
Patch1078: 1078-job-be-more-careful-when-removing-job-object-from-jo.patch
Patch1079: 1079-core-rework-how-we-deserialize-jobs.patch
Patch1080: 1080-core-when-a-unit-state-changes-only-propagate-to-job.patch
Patch1081: 1081-core-extend-comments-regarding-coldplug-vs.-catchup.patch
%ifarch %{ix86} x86_64 aarch64
%global have_gnu_efi 1
@ -1751,6 +1757,14 @@ fi
%files tests -f .file-list-tests
%changelog
* Mon May 25 2026 systemd maintenance team <systemd-maint@redhat.com> - 239-82.17
- job: update job_free() to follow our usual return-NULL style (RHEL-168671)
- core: don't track jobs-finishing-during-reload explicitly (RHEL-168671)
- job: be more careful when removing job object from jobs hash table (RHEL-168671)
- core: rework how we deserialize jobs (RHEL-168671)
- core: when a unit state changes only propagate to jobs after reloading is complete (RHEL-168671)
- core: extend comments regarding coldplug() vs. catchup() (RHEL-168671)
* Thu Apr 16 2026 systemd maintenance team <systemd-maint@redhat.com> - 239-82.16
- core: validate input cgroup path more prudently (RHEL-152085)
- nspawn: normalize pivot_root paths (RHEL-163868)