From: Mike Yuan Date: Sat, 8 Jul 2023 11:45:51 +0000 (+0800) Subject: core: refuse late merge only for anchor job when JOB_RESTART_DEPENDENCIES X-Git-Tag: v254-rc2~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39939e7d0279ad38bfc11956ad44f0ce0b1f41f4;p=thirdparty%2Fsystemd.git core: refuse late merge only for anchor job when JOB_RESTART_DEPENDENCIES Follow-up for 2a39b91459a4c27985d9a58309c0fda25f3cd397 The mentioned change makes all jobs in the transaction unmergeable if mode == JOB_RESTART_DEPENDENCIES, but we only want the anchor job to be re-enqueued. --- diff --git a/src/core/job.c b/src/core/job.c index 95e71c48e23..acf8a78f413 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -217,10 +217,11 @@ static void job_merge_into_installed(Job *j, Job *other) { j->ignore_order = j->ignore_order || other->ignore_order; } -Job* job_install(Job *j, JobMode mode) { +Job* job_install(Job *j, bool refuse_late_merge) { Job **pj; Job *uj; + assert(j); assert(!j->installed); assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION); assert(j->state == JOB_WAITING); @@ -235,7 +236,7 @@ Job* job_install(Job *j, JobMode mode) { /* not conflicting, i.e. mergeable */ if (uj->state == JOB_WAITING || - (job_type_allows_late_merge(j->type) && mode != JOB_RESTART_DEPENDENCIES && job_type_is_superset(uj->type, j->type))) { + (!refuse_late_merge && job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) { job_merge_into_installed(uj, j); log_unit_debug(uj->unit, "Merged %s/%s into installed job %s/%s as %"PRIu32, diff --git a/src/core/job.h b/src/core/job.h index 2c4fbdf4eda..891d87a79cd 100644 --- a/src/core/job.h +++ b/src/core/job.h @@ -169,7 +169,7 @@ Job* job_new(Unit *unit, JobType type); Job* job_new_raw(Unit *unit); void job_unlink(Job *job); Job* job_free(Job *job); -Job* job_install(Job *j, JobMode mode); +Job* job_install(Job *j, bool refuse_late_merge); int job_install_deserialized(Job *j); void job_uninstall(Job *j); void job_dump(Job *j, FILE *f, const char *prefix); diff --git a/src/core/transaction.c b/src/core/transaction.c index 8b8e02f1c77..ffc063a6842 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -657,14 +657,19 @@ static int transaction_apply( /* Clean the job dependencies */ transaction_unlink_job(tr, j, false); - installed_job = job_install(j, mode); + /* When RestartMode=direct is used, the service being restarted don't enter the inactive/failed + * state, i.e. unit_process_job -> job_finish_and_invalidate is never called, and the previous + * job might still be running (especially for Type=oneshot services). We need to refuse + * late merge and re-enqueue the anchor job. */ + installed_job = job_install(j, + /* refuse_late_merge = */ mode == JOB_RESTART_DEPENDENCIES && j == tr->anchor_job); if (installed_job != j) { /* j has been merged into a previously installed job */ if (tr->anchor_job == j) tr->anchor_job = installed_job; + hashmap_remove_value(m->jobs, UINT32_TO_PTR(j->id), j); - job_free(j); - j = installed_job; + free_and_replace_full(j, installed_job, job_free); } job_add_to_run_queue(j);