diff -Nru systemd-237/debian/changelog systemd-237/debian/changelog --- systemd-237/debian/changelog 2019-02-28 22:03:40.000000000 +0100 +++ systemd-237/debian/changelog 2019-03-13 07:42:11.000000000 +0100 @@ -1,3 +1,9 @@ +systemd (237-3ubuntu10.15.1) bionic; urgency=medium + + * fix race + + -- Michael Vogt Wed, 13 Mar 2019 07:42:11 +0100 + systemd (237-3ubuntu10.15) bionic; urgency=medium [ Victor Tapia ] diff -Nru systemd-237/debian/patches/fix-race-daemon-reload-8803.patch systemd-237/debian/patches/fix-race-daemon-reload-8803.patch --- systemd-237/debian/patches/fix-race-daemon-reload-8803.patch 1970-01-01 01:00:00.000000000 +0100 +++ systemd-237/debian/patches/fix-race-daemon-reload-8803.patch 2019-03-13 07:42:11.000000000 +0100 @@ -0,0 +1,164 @@ +Index: systemd-237/src/core/job.c +=================================================================== +--- systemd-237.orig/src/core/job.c ++++ systemd-237/src/core/job.c +@@ -57,6 +57,7 @@ Job* job_new_raw(Unit *unit) { + j->manager = unit->manager; + j->unit = unit; + j->type = _JOB_TYPE_INVALID; ++ j->reloaded = false; + + return j; + } +@@ -78,7 +79,7 @@ Job* job_new(Unit *unit, JobType type) { + return j; + } + +-void job_free(Job *j) { ++void job_unlink(Job *j) { + assert(j); + assert(!j->installed); + assert(!j->transaction_prev); +@@ -86,16 +87,33 @@ void job_free(Job *j) { + assert(!j->subject_list); + assert(!j->object_list); + +- if (j->in_run_queue) ++ if (j->in_run_queue) { + LIST_REMOVE(run_queue, j->manager->run_queue, j); ++ j->in_run_queue = false; ++ } + +- if (j->in_dbus_queue) ++ if (j->in_dbus_queue) { + LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j); ++ j->in_dbus_queue = false; ++ } + +- if (j->in_gc_queue) ++ if (j->in_gc_queue) { + LIST_REMOVE(gc_queue, j->manager->gc_job_queue, j); ++ j->in_gc_queue = false; ++ } + +- sd_event_source_unref(j->timer_event_source); ++ j->timer_event_source = sd_event_source_unref(j->timer_event_source); ++} ++ ++void job_free(Job *j) { ++ assert(j); ++ assert(!j->installed); ++ assert(!j->transaction_prev); ++ assert(!j->transaction_next); ++ assert(!j->subject_list); ++ assert(!j->object_list); ++ ++ job_unlink(j); + + sd_bus_track_unref(j->bus_track); + strv_free(j->deserialized_clients); +@@ -255,6 +273,7 @@ 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++; +@@ -849,6 +868,19 @@ static void job_fail_dependencies(Unit * + } + } + ++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; +@@ -888,7 +920,12 @@ int job_finish_and_invalidate(Job *j, Jo + j->manager->n_failed_jobs++; + + job_uninstall(j); +- job_free(j); ++ /* Remember jobs started before the reload */ ++ if (MANAGER_IS_RELOADING(j->manager) && j->reloaded) { ++ if (job_save_pending_finished_job(j) < 0) ++ job_free(j); ++ } else ++ job_free(j); + + /* Fail depending jobs on failure */ + if (result != JOB_DONE && recursive) { +Index: systemd-237/src/core/job.h +=================================================================== +--- systemd-237.orig/src/core/job.h ++++ systemd-237/src/core/job.h +@@ -174,10 +174,12 @@ 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); + Job* job_new_raw(Unit *unit); ++void job_unlink(Job *job); + void job_free(Job *job); + Job* job_install(Job *j); + int job_install_deserialized(Job *j); +Index: systemd-237/src/core/manager.c +=================================================================== +--- systemd-237.orig/src/core/manager.c ++++ systemd-237/src/core/manager.c +@@ -3043,6 +3043,17 @@ 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; +@@ -3146,6 +3157,9 @@ int manager_reload(Manager *m) { + assert(m->n_reloading > 0); + m->n_reloading--; + ++ if (!MANAGER_IS_RELOADING(m)) ++ manager_flush_finished_jobs(m); ++ + m->send_reloading_done = true; + + return r; +Index: systemd-237/src/core/manager.h +=================================================================== +--- systemd-237.orig/src/core/manager.h ++++ systemd-237/src/core/manager.h +@@ -305,6 +305,9 @@ 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; diff -Nru systemd-237/debian/patches/series systemd-237/debian/patches/series --- systemd-237/debian/patches/series 2019-02-28 22:03:40.000000000 +0100 +++ systemd-237/debian/patches/series 2019-03-13 07:42:00.000000000 +0100 @@ -97,3 +97,4 @@ sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch journal-do-not-remove-multiple-spaces-after-identifi.patch stop-mount-error-propagation.patch +fix-race-daemon-reload-8803.patch