X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Funit.c;h=2f95737da00a8a41d7101580c04b355c1519776b;hp=229bd0f73ad56b20a0ecc3e71f7e838d6ff7d2cb;hb=63c372cb9df3bee01e3bf8cd7f96f336bddda846;hpb=9c3349e23b14db27e7ba45f82cf647899c563ea9 diff --git a/src/core/unit.c b/src/core/unit.c index 229bd0f73..2f95737da 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -278,21 +278,32 @@ int unit_set_description(Unit *u, const char *description) { } bool unit_check_gc(Unit *u) { + UnitActiveState state; assert(u); - if (UNIT_VTABLE(u)->no_gc) + if (u->job) return true; - if (u->no_gc) + if (u->nop_job) return true; - if (u->job) + state = unit_active_state(u); + + /* If the unit is inactive and failed and no job is queued for + * it, then release its runtime resources */ + if (UNIT_IS_INACTIVE_OR_FAILED(state) && + UNIT_VTABLE(u)->release_resources) + UNIT_VTABLE(u)->release_resources(u); + + /* But we keep the unit object around for longer when it is + * referenced or configured to not be gc'ed */ + if (state != UNIT_INACTIVE) return true; - if (u->nop_job) + if (UNIT_VTABLE(u)->no_gc) return true; - if (unit_active_state(u) != UNIT_INACTIVE) + if (u->no_gc) return true; if (u->refs) @@ -857,7 +868,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { assert(u->type >= 0); prefix = strempty(prefix); - prefix2 = strappenda(prefix, "\t"); + prefix2 = strjoina(prefix, "\t"); fprintf(f, "%s-> Unit %s:\n" @@ -1388,7 +1399,6 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { DISABLE_WARNING_FORMAT_NONLITERAL; snprintf(buf, sizeof(buf), format, unit_description(u)); - char_array_0(buf); REENABLE_WARNING; mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING : @@ -1412,6 +1422,7 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { int unit_start(Unit *u) { UnitActiveState state; Unit *following; + int r; assert(u); @@ -1450,9 +1461,6 @@ int unit_start(Unit *u) { return unit_start(following); } - unit_status_log_starting_stopping_reloading(u, JOB_START); - unit_status_print_starting_stopping(u, JOB_START); - if (UNIT_VTABLE(u)->supported && !UNIT_VTABLE(u)->supported(u->manager)) return -ENOTSUP; @@ -1468,7 +1476,14 @@ int unit_start(Unit *u) { unit_add_to_dbus_queue(u); - return UNIT_VTABLE(u)->start(u); + r = UNIT_VTABLE(u)->start(u); + if (r <= 0) + return r; + + /* Log if the start function actually did something */ + unit_status_log_starting_stopping_reloading(u, JOB_START); + unit_status_print_starting_stopping(u, JOB_START); + return r; } bool unit_can_start(Unit *u) { @@ -1492,6 +1507,7 @@ bool unit_can_isolate(Unit *u) { int unit_stop(Unit *u) { UnitActiveState state; Unit *following; + int r; assert(u); @@ -1505,15 +1521,18 @@ int unit_stop(Unit *u) { return unit_stop(following); } - unit_status_log_starting_stopping_reloading(u, JOB_STOP); - unit_status_print_starting_stopping(u, JOB_STOP); - if (!UNIT_VTABLE(u)->stop) return -EBADR; unit_add_to_dbus_queue(u); - return UNIT_VTABLE(u)->stop(u); + r = UNIT_VTABLE(u)->stop(u); + if (r <= 0) + return r; + + unit_status_log_starting_stopping_reloading(u, JOB_STOP); + unit_status_print_starting_stopping(u, JOB_STOP); + return r; } /* Errors: @@ -1524,6 +1543,7 @@ int unit_stop(Unit *u) { int unit_reload(Unit *u) { UnitActiveState state; Unit *following; + int r; assert(u); @@ -1548,10 +1568,14 @@ int unit_reload(Unit *u) { return unit_reload(following); } - unit_status_log_starting_stopping_reloading(u, JOB_RELOAD); - unit_add_to_dbus_queue(u); - return UNIT_VTABLE(u)->reload(u); + + r = UNIT_VTABLE(u)->reload(u); + if (r <= 0) + return r; + + unit_status_log_starting_stopping_reloading(u, JOB_RELOAD); + return r; } bool unit_can_reload(Unit *u) {