core/transaction: fix issue in dropping unmergeable jobs (#38776)

Fixes #38765.
This commit is contained in:
Daan De Meyer
2025-09-04 08:57:59 +02:00
committed by GitHub
2 changed files with 34 additions and 4 deletions

View File

@@ -15,6 +15,7 @@
#include "strv.h"
#include "transaction.h"
static bool job_matters_to_anchor(Job *job);
static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies);
static void transaction_delete_job(Transaction *tr, Job *j, bool delete_dependencies) {
@@ -171,6 +172,7 @@ static int delete_one_unmergeable_job(Transaction *tr, Job *job) {
* another unit in which case we
* rather remove the start. */
/* Update test/units/TEST-87-AUX-UTILS-VM.sh when logs below are changed. */
log_unit_debug(j->unit,
"Looking at job %s/%s conflicted_by=%s",
j->unit->id, job_type_to_string(j->type),
@@ -216,17 +218,18 @@ static int delete_one_unmergeable_job(Transaction *tr, Job *job) {
return -EINVAL;
}
static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
static int transaction_ensure_mergeable(Transaction *tr, bool matters_to_anchor, sd_bus_error *e) {
Job *j;
int r;
assert(tr);
/* First step, check whether any of the jobs for one specific
* task conflict. If so, try to drop one of them. */
HASHMAP_FOREACH(j, tr->jobs) {
JobType t;
if (job_matters_to_anchor(j) != matters_to_anchor)
continue;
t = j->type;
LIST_FOREACH(transaction, k, j->transaction_next) {
if (job_type_merge_and_collapse(&t, k->type, j->unit) >= 0)
@@ -253,7 +256,26 @@ static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
}
}
/* Second step, merge the jobs. */
return 0;
}
static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
Job *j;
int r;
assert(tr);
/* First step, try to drop unmergeable jobs for jobs that matter to anchor. */
r = transaction_ensure_mergeable(tr, /* matters_to_anchor = */ true, e);
if (r < 0)
return r;
/* Second step, do the same for jobs that not matter to anchor. */
r = transaction_ensure_mergeable(tr, /* matters_to_anchor = */ false, e);
if (r < 0)
return r;
/* Third step, merge the jobs. */
HASHMAP_FOREACH(j, tr->jobs) {
JobType t = j->type;

View File

@@ -3,6 +3,14 @@
set -eux
set -o pipefail
# For issue #38765
journalctl --sync
if journalctl -q -o short-monotonic --grep "Looking at job .*/.* conflicted_by=(yes|no)" >/failed; then
echo "Found unexpected unmergeable jobs"
cat /failed
exit 1
fi
# shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/test-control.sh