From addedec48ba0ffc4472ef6d3b5a45c9d4239f1cd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 3 Jan 2012 21:47:54 +0100 Subject: [PATCH] logind: if we can't open /dev/tty0, assume there is no VT subsystem and don't pretend we could do VT switching --- src/login/logind-dbus.c | 2 +- src/login/logind-seat-dbus.c | 2 +- src/login/logind-seat.c | 28 +++++++++++++++++++++------- src/login/logind-seat.h | 1 + src/login/logind-session.c | 4 ++-- src/login/logind.c | 7 ++++++- src/login/sd-login.c | 2 +- 7 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 0550d1bd1..efbc040ad 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -301,7 +301,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess return -EINVAL; if (s) { - if (seat_is_vtconsole(s)) { + if (seat_can_multi_session(s)) { if (vtnr <= 0 || vtnr > 63) return -EINVAL; } else { diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c index 3a916eef7..a15689b18 100644 --- a/src/login/logind-seat-dbus.c +++ b/src/login/logind-seat-dbus.c @@ -141,7 +141,7 @@ static int bus_seat_append_multi_session(DBusMessageIter *i, const char *propert assert(property); assert(s); - b = seat_is_vtconsole(s); + b = seat_can_multi_session(s); if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) return -ENOMEM; diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 3cf3958c8..8c83a2c5e 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -101,8 +101,10 @@ int seat_save(Seat *s) { fprintf(f, "# This is private data. Do not parse.\n" - "IS_VTCONSOLE=%i\n", - seat_is_vtconsole(s)); + "IS_VTCONSOLE=%i\n" + "CAN_MULTI_SESSION=%i\n", + seat_is_vtconsole(s), + seat_can_multi_session(s)); if (s->active) { assert(s->active->user); @@ -191,7 +193,7 @@ int seat_preallocate_vts(Seat *s) { if (s->manager->n_autovts <= 0) return 0; - if (!seat_is_vtconsole(s)) + if (!seat_can_multi_session(s)) return 0; for (i = 1; i <= s->manager->n_autovts; i++) { @@ -266,7 +268,7 @@ int seat_active_vt_changed(Seat *s, int vtnr) { assert(s); assert(vtnr >= 1); - if (!seat_is_vtconsole(s)) + if (!seat_can_multi_session(s)) return -EINVAL; log_debug("VT changed to %i", vtnr); @@ -290,7 +292,7 @@ int seat_read_active_vt(Seat *s) { assert(s); - if (!seat_is_vtconsole(s)) + if (!seat_can_multi_session(s)) return 0; lseek(s->manager->console_active_fd, SEEK_SET, 0); @@ -388,7 +390,7 @@ int seat_attach_session(Seat *s, Session *session) { assert(session); assert(!session->seat); - if (!seat_is_vtconsole(s) && s->sessions) + if (!seat_can_multi_session(s) && s->sessions) return -EEXIST; session->seat = s; @@ -396,7 +398,7 @@ int seat_attach_session(Seat *s, Session *session) { seat_send_changed(s, "Sessions\0"); - if (!seat_is_vtconsole(s)) { + if (!seat_can_multi_session(s)) { assert(!s->active); seat_set_active(s, session); } @@ -410,6 +412,18 @@ bool seat_is_vtconsole(Seat *s) { return s->manager->vtconsole == s; } +bool seat_can_multi_session(Seat *s) { + assert(s); + + if (!seat_is_vtconsole(s)) + return false; + + /* If we can't watch which VT is in the foreground, we don't + * support VT switching */ + + return s->manager->console_active_fd >= 0; +} + int seat_get_idle_hint(Seat *s, dual_timestamp *t) { Session *session; bool idle_hint = true; diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h index 5bce1434e..3b2c7f096 100644 --- a/src/login/logind-seat.h +++ b/src/login/logind-seat.h @@ -62,6 +62,7 @@ int seat_preallocate_vts(Seat *s); int seat_attach_session(Seat *s, Session *session); bool seat_is_vtconsole(Seat *s); +bool seat_can_multi_session(Seat *s); int seat_get_idle_hint(Seat *s, dual_timestamp *t); int seat_start(Seat *s); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 63ee75808..58c70c3db 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -185,7 +185,7 @@ int session_save(Session *s) { "SERVICE=%s\n", s->service); - if (s->seat && seat_is_vtconsole(s->seat)) + if (s->seat && seat_can_multi_session(s->seat)) fprintf(f, "VTNR=%i\n", s->vtnr); @@ -270,7 +270,7 @@ int session_load(Session *s) { seat_attach_session(o, s); } - if (vtnr && s->seat && seat_is_vtconsole(s->seat)) { + if (vtnr && s->seat && seat_can_multi_session(s->seat)) { int v; k = safe_atoi(vtnr, &v); diff --git a/src/login/logind.c b/src/login/logind.c index 4633a5ef2..3a1903ca1 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -655,7 +655,6 @@ int manager_dispatch_seat_udev(Manager *m) { return r; } - int manager_dispatch_vcsa_udev(Manager *m) { struct udev_device *d; int r = 0; @@ -906,6 +905,12 @@ static int manager_connect_console(Manager *m) { m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC); if (m->console_active_fd < 0) { + + /* On certain architectures (S390 and Xen), /dev/tty0 + does not exist, so don't fail if we can't open it.*/ + if (errno == ENOENT) + return 0; + log_error("Failed to open /sys/class/tty/tty0/active: %m"); return -errno; } diff --git a/src/login/sd-login.c b/src/login/sd-login.c index 1d4368187..e857ae08d 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -574,7 +574,7 @@ _public_ int sd_seat_can_multi_session(const char *seat) { return -ENOMEM; r = parse_env_file(p, NEWLINE, - "IS_VTCONSOLE", &s, + "CAN_MULTI_SESSION", &s, NULL); free(p); -- 2.30.2