From 7cb0030f6cec6c0a83c7c11ecc4adfb55aaf0e0b Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 16 Nov 2025 15:59:28 +0100 Subject: [PATCH 1/4] core/unit: no need to handle intermediate job types in unit_process_job() Installed jobs are always collapsed, i.e. can only be of types accepted by job_run_and_invalidate() modulo JOB_NOP which is stored in Unit.nop_job (if any). Let's trim the unreachable branches. --- src/core/unit.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index a85987c74b..b6dc962f86 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2610,6 +2610,7 @@ static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { JobResult result; assert(j); + assert(j->installed); if (j->state == JOB_WAITING) /* So we reached a different state for this job. Let's see if we can run it now if it failed previously @@ -2642,8 +2643,6 @@ static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { break; case JOB_RELOAD: - case JOB_RELOAD_OR_START: - case JOB_TRY_RELOAD: if (j->state == JOB_RUNNING) { if (ns == UNIT_ACTIVE) @@ -2660,7 +2659,6 @@ static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { case JOB_STOP: case JOB_RESTART: - case JOB_TRY_RESTART: if (UNIT_IS_INACTIVE_OR_FAILED(ns)) job_finish_and_invalidate(j, JOB_DONE, true, false); From a5b1a794612b8802fcfd818be04814e9c0423840 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sat, 15 Nov 2025 21:06:39 +0100 Subject: [PATCH 2/4] core/unit: mark running reload job as canceled if the unit deactivated The semantics of reload is that the service updates its extrinsic state and continues execution. If it actually deactivated we shouldn't spuriously notify the caller that reload succeeded. --- src/core/unit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/unit.c b/src/core/unit.c index b6dc962f86..7675082e22 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2651,7 +2651,7 @@ static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { unexpected = true; if (UNIT_IS_INACTIVE_OR_FAILED(ns)) - job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false); + job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_CANCELED, true, false); } } From 2334953a498e919d5301222bd3f74dbfcb2b8cf8 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sat, 15 Nov 2025 21:08:50 +0100 Subject: [PATCH 3/4] core/unit: always propagate reload_result as job result, even if state is unexpected The end state of unit shouldn't have any impact on reload job, as either way the reload operation has been aborted. --- src/core/unit.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index 7675082e22..8a406a9334 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2649,9 +2649,7 @@ static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { job_finish_and_invalidate(j, reload_success ? JOB_DONE : JOB_FAILED, true, false); else if (!IN_SET(ns, UNIT_ACTIVATING, UNIT_RELOADING, UNIT_REFRESHING)) { unexpected = true; - - if (UNIT_IS_INACTIVE_OR_FAILED(ns)) - job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_CANCELED, true, false); + job_finish_and_invalidate(j, reload_success ? JOB_CANCELED : JOB_FAILED, true, false); } } From aea6c4b53f7f1f1d76413ea67737e3c276f60f46 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 16 Nov 2025 15:33:53 +0100 Subject: [PATCH 4/4] core/unit: modernize unit_process_job() a bit * Inline one condition * Annotate boolean args with names --- src/core/unit.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index 8a406a9334..ddae43a673 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2607,7 +2607,6 @@ static void unit_emit_audit_stop(Unit *u, UnitActiveState state) { static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { bool unexpected = false; - JobResult result; assert(j); assert(j->installed); @@ -2626,18 +2625,12 @@ static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { case JOB_VERIFY_ACTIVE: if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) - job_finish_and_invalidate(j, JOB_DONE, true, false); + job_finish_and_invalidate(j, JOB_DONE, /* recursive = */ true, /* already = */ false); else if (j->state == JOB_RUNNING && ns != UNIT_ACTIVATING) { unexpected = true; - if (UNIT_IS_INACTIVE_OR_FAILED(ns)) { - if (ns == UNIT_FAILED) - result = JOB_FAILED; - else - result = JOB_DONE; - - job_finish_and_invalidate(j, result, true, false); - } + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, /* recursive = */ true, /* already = */ false); } break; @@ -2646,10 +2639,10 @@ static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { if (j->state == JOB_RUNNING) { if (ns == UNIT_ACTIVE) - job_finish_and_invalidate(j, reload_success ? JOB_DONE : JOB_FAILED, true, false); + job_finish_and_invalidate(j, reload_success ? JOB_DONE : JOB_FAILED, /* recursive = */ true, /* already = */ false); else if (!IN_SET(ns, UNIT_ACTIVATING, UNIT_RELOADING, UNIT_REFRESHING)) { unexpected = true; - job_finish_and_invalidate(j, reload_success ? JOB_CANCELED : JOB_FAILED, true, false); + job_finish_and_invalidate(j, reload_success ? JOB_CANCELED : JOB_FAILED, /* recursive = */ true, /* already = */ false); } } @@ -2659,10 +2652,10 @@ static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) { case JOB_RESTART: if (UNIT_IS_INACTIVE_OR_FAILED(ns)) - job_finish_and_invalidate(j, JOB_DONE, true, false); + job_finish_and_invalidate(j, JOB_DONE, /* recursive = */ true, /* already = */ false); else if (j->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) { unexpected = true; - job_finish_and_invalidate(j, JOB_FAILED, true, false); + job_finish_and_invalidate(j, JOB_FAILED, /* recursive = */ true, /* already = */ false); } break;