X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Flogind-user.c;h=adbe638d46422d73b61ebfa95bdb39ee225ef236;hb=299404a19f26aa4f203042d8285ee0b7afa5bf40;hp=316c4cd0956c290da578f1afaef39b3830f95dbc;hpb=fb6becb4436ae4078337011b2017ce294e7361cf;p=elogind.git diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 316c4cd09..adbe638d4 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -338,26 +338,29 @@ static int user_start_slice(User *u) { dbus_error_init(&error); if (!u->slice) { - char lu[DECIMAL_STR_MAX(unsigned long) + 1]; + char lu[DECIMAL_STR_MAX(unsigned long) + 1], *slice; sprintf(lu, "%lu", (unsigned long) u->uid); - r = build_subslice(SPECIAL_USER_SLICE, lu, &u->slice); + r = build_subslice(SPECIAL_USER_SLICE, lu, &slice); if (r < 0) return r; - r = hashmap_put(u->manager->user_units, u->slice, u); - if (r < 0) - log_warning("Failed to create mapping between unit and user"); - } + r = manager_start_unit(u->manager, slice, &error, &job); + if (r < 0) { + log_error("Failed to start user slice: %s", bus_error(&error, r)); + dbus_error_free(&error); - r = manager_start_unit(u->manager, u->slice, &error, &job); - if (r < 0) { - log_error("Failed to start user slice: %s", bus_error(&error, r)); - dbus_error_free(&error); + free(slice); + } else { + u->slice = slice; + + free(u->slice_job); + u->slice_job = job; + } } - free(u->slice_job); - u->slice_job = job; + if (u->slice) + hashmap_put(u->manager->user_units, u->slice, u); return 0; } @@ -372,26 +375,29 @@ static int user_start_service(User *u) { dbus_error_init(&error); if (!u->service) { - char lu[DECIMAL_STR_MAX(unsigned long) + 1]; + char lu[DECIMAL_STR_MAX(unsigned long) + 1], *service; sprintf(lu, "%lu", (unsigned long) u->uid); - u->service = unit_name_build("user", lu, ".service"); - if (!u->service) + service = unit_name_build("user", lu, ".service"); + if (!service) return log_oom(); - r = hashmap_put(u->manager->user_units, u->service, u); - if (r < 0) - log_warning("Failed to create mapping between service and user"); - } + r = manager_start_unit(u->manager, service, &error, &job); + if (r < 0) { + log_error("Failed to start user service: %s", bus_error(&error, r)); + dbus_error_free(&error); - r = manager_start_unit(u->manager, u->service, &error, &job); - if (r < 0) { - log_error("Failed to start user service: %s", bus_error(&error, r)); - dbus_error_free(&error); + free(service); + } else { + u->service = service; + + free(u->service_job); + u->service_job = job; + } } - free(u->service_job); - u->service_job = job; + if (u->service) + hashmap_put(u->manager->user_units, u->service, u); return 0; } @@ -484,21 +490,6 @@ static int user_stop_service(User *u) { return r; } -/* static int user_shall_kill(User *u) { */ -/* assert(u); */ - -/* if (!u->manager->kill_user_processes) */ -/* return false; */ - -/* if (strv_contains(u->manager->kill_exclude_users, u->name)) */ -/* return false; */ - -/* if (strv_isempty(u->manager->kill_only_users)) */ -/* return true; */ - -/* return strv_contains(u->manager->kill_only_users, u->name); */ -/* } */ - static int user_remove_runtime_path(User *u) { int r; @@ -522,9 +513,6 @@ int user_stop(User *u) { int r = 0, k; assert(u); - if (u->started) - log_debug("User %s logged out.", u->name); - LIST_FOREACH(sessions_by_user, s, u->sessions) { k = session_stop(s); if (k < 0) @@ -541,6 +529,26 @@ int user_stop(User *u) { if (k < 0) r = k; + user_save(u); + + return r; +} + +int user_finalize(User *u) { + Session *s; + int r = 0, k; + + assert(u); + + if (u->started) + log_debug("User %s logged out.", u->name); + + LIST_FOREACH(sessions_by_user, s, u->sessions) { + k = session_finalize(s); + if (k < 0) + r = k; + } + /* Kill XDG_RUNTIME_DIR */ k = user_remove_runtime_path(u); if (k < 0) @@ -549,10 +557,10 @@ int user_stop(User *u) { unlink(u->state_file); user_add_to_gc_queue(u); - if (u->started) + if (u->started) { user_send_signal(u, false); - - u->started = false; + u->started = false; + } return r; } @@ -618,6 +626,15 @@ int user_check_gc(User *u, bool drop_not_started) { if (user_check_linger_file(u) > 0) return 1; + if (u->slice_job || u->service_job) + return 1; + + if (u->slice && manager_unit_is_active(u->manager, u->slice) != 0) + return 1; + + if (u->service && manager_unit_is_active(u->manager, u->service) != 0) + return 1; + return 0; } @@ -637,8 +654,11 @@ UserState user_get_state(User *u) { assert(u); + if (u->closing) + return USER_CLOSING; + if (u->slice_job || u->service_job) - return u->started ? USER_OPENING : USER_CLOSING; + return USER_OPENING; LIST_FOREACH(sessions_by_user, i, u->sessions) { if (session_is_active(i))