diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-11-21 14:41:32 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-11-22 10:24:32 +0100 |
commit | eec12b7756e2cada16e3b8a9c02f9eaf62df5409 (patch) | |
tree | 6c8c1ebc656435a12714a8072ad8185f59038beb /src/machine | |
parent | machine: simplify machine_start_scope() (diff) | |
download | systemd-eec12b7756e2cada16e3b8a9c02f9eaf62df5409.tar.xz systemd-eec12b7756e2cada16e3b8a9c02f9eaf62df5409.zip |
machined: simplify reference handling for units
Before, we'd unref from machine_stop_unit, still keeping the unit name around,
and only forget the name later, when garbage collecting. If we didn't call
manager_stop_unit(), then we wouldn't do the unref. Let's unref at the same
point where we do garbage collection, so that it is always true that
iff we have the name generated with AddRef=1, then have a reference to the unit,
and as soon as we forget the name, we drop the reference.
This should fix the issue when repeated systemd-nspawn --register=yes fails
with "scope already exists" error.
Incidentally, this fixes an error in the code path where r was used instead of q.
Diffstat (limited to 'src/machine')
-rw-r--r-- | src/machine/machine.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/src/machine/machine.c b/src/machine/machine.c index 38c09d7117..d35eb1c14d 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -478,7 +478,7 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) { static int machine_stop_scope(Machine *m) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; char *job = NULL; - int r, q; + int r; assert(m); assert(m->class != MACHINE_HOST); @@ -487,20 +487,11 @@ static int machine_stop_scope(Machine *m) { return 0; r = manager_stop_unit(m->manager, m->unit, &error, &job); - if (r < 0) { - log_error_errno(r, "Failed to stop machine scope: %s", bus_error_message(&error, r)); - sd_bus_error_free(&error); - } else - free_and_replace(m->scope_job, job); - - if (m->referenced) { - q = manager_unref_unit(m->manager, m->unit, &error); - if (q < 0) - log_warning_errno(q, "Failed to drop reference to machine scope, ignoring: %s", bus_error_message(&error, r)); - m->referenced = false; - } + if (r < 0) + return log_error_errno(r, "Failed to stop machine scope: %s", bus_error_message(&error, r)); - return r; + free_and_replace(m->scope_job, job); + return 0; } int machine_stop(Machine *m) { @@ -654,6 +645,18 @@ void machine_release_unit(Machine *m) { if (!m->unit) return; + if (m->referenced) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + int r; + + r = manager_unref_unit(m->manager, m->unit, &error); + if (r < 0) + log_warning_errno(r, "Failed to drop reference to machine scope, ignoring: %s", + bus_error_message(&error, r)); + + m->referenced = false; + } + (void) hashmap_remove(m->manager->machine_units, m->unit); m->unit = mfree(m->unit); } |