X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Flogind-seat.c;h=8d13a63688180d7b029cab930e272259a4e9e64d;hb=c91b060008f145236e99826488f7e10c7f7971b7;hp=3daaf000eaccf0087962cd40a2f8b504d30a3cb7;hpb=42c23dcd12e2b65f7b16b560cabdaf46bafaefec;p=elogind.git diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 3daaf000e..8d13a6368 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -93,11 +93,11 @@ int seat_save(Seat *s) { r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0); if (r < 0) - goto finish; + goto fail; r = fopen_temporary(s->state_file, &f, &temp_path); if (r < 0) - goto finish; + goto fail; fchmod(fileno(f), 0644); @@ -141,19 +141,24 @@ int seat_save(Seat *s) { i->sessions_by_seat_next ? ' ' : '\n'); } - fflush(f); + r = fflush_and_check(f); + if (r < 0) + goto fail; - if (ferror(f) || rename(temp_path, s->state_file) < 0) { + if (rename(temp_path, s->state_file) < 0) { r = -errno; - unlink(s->state_file); - unlink(temp_path); + goto fail; } -finish: - if (r < 0) - log_error_errno(r, "Failed to save seat data %s: %m", s->state_file); + return 0; - return r; +fail: + (void) unlink(s->state_file); + + if (temp_path) + (void) unlink(temp_path); + + return log_error_errno(r, "Failed to save seat data %s: %m", s->state_file); } int seat_load(Seat *s) { @@ -178,6 +183,34 @@ static int vt_allocate(unsigned int vtnr) { return 0; } +int seat_preallocate_vts(Seat *s) { + int r = 0; + unsigned i; + + assert(s); + assert(s->manager); + + log_debug("Preallocating VTs..."); + + if (s->manager->n_autovts <= 0) + return 0; + + if (!seat_has_vts(s)) + return 0; + + for (i = 1; i <= s->manager->n_autovts; i++) { + int q; + + q = vt_allocate(i); + if (q < 0) { + log_error_errno(q, "Failed to preallocate VT %u: %m", i); + r = q; + } + } + + return r; +} + int seat_apply_acls(Seat *s, Session *old_active) { int r; @@ -328,6 +361,7 @@ int seat_active_vt_changed(Seat *s, unsigned int vtnr) { } r = seat_set_active(s, new_active); + manager_spawn_autovt(s->manager, vtnr); return r; } @@ -385,6 +419,9 @@ int seat_start(Seat *s) { LOG_MESSAGE("New seat %s.", s->id), NULL); + /* Initialize VT magic stuff */ + seat_preallocate_vts(s); + /* Read current VT */ seat_read_active_vt(s); @@ -454,7 +491,7 @@ void seat_evict_position(Seat *s, Session *session) { * position (eg., during gdm->session transition), so let's look * for it and set it on the free slot. */ LIST_FOREACH(sessions_by_seat, iter, s->sessions) { - if (iter->position == pos) { + if (iter->position == pos && session_get_state(iter) != SESSION_CLOSING) { s->positions[pos] = iter; break; }