From d0a522eb312a0f6014e756d3fc066efc37fceaf7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 28 Jun 2011 00:26:10 +0200 Subject: [PATCH] logind: autospawn gettys when necessary --- Makefile.am | 19 ++++++-------- src/logind.c | 57 ++++++++++++++++++++++++++++++++++++++--- units/getty@.service.m4 | 2 +- 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/Makefile.am b/Makefile.am index bfc10795..dc1a87ed 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1513,26 +1513,23 @@ endif $(LN_S) graphical.target runlevel5.target && \ $(LN_S) reboot.target runlevel6.target ) ( cd $(DESTDIR)$(systemunitdir) && \ - rm -f default.target ctrl-alt-del.target dbus-org.freedesktop.hostname1.service dbus-org.freedesktop.locale1.service dbus-org.freedesktop.timedate1.service dbus-org.freedesktop.login1.service && \ + rm -f default.target ctrl-alt-del.target dbus-org.freedesktop.hostname1.service dbus-org.freedesktop.locale1.service dbus-org.freedesktop.timedate1.service dbus-org.freedesktop.login1.service autovt-getty@.service && \ $(LN_S) graphical.target default.target && \ $(LN_S) reboot.target ctrl-alt-del.target && \ $(LN_S) systemd-hostnamed.service dbus-org.freedesktop.hostname1.service && \ $(LN_S) systemd-localed.service dbus-org.freedesktop.locale1.service && \ $(LN_S) systemd-timedated.service dbus-org.freedesktop.timedate1.service && \ - $(LN_S) systemd-logind.service dbus-org.freedesktop.login1.service ) + $(LN_S) systemd-logind.service dbus-org.freedesktop.login1.service && \ + $(LN_S) getty@.service autovt-getty@.service ) ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ - rm -f getty.target systemd-user-sessions.service systemd-ask-password-wall.path && \ + rm -f getty.target systemd-user-sessions.service systemd-ask-password-wall.path systemd-logind.service && \ $(LN_S) ../getty.target getty.target && \ $(LN_S) ../systemd-user-sessions.service systemd-user-sessions.service && \ - $(LN_S) ../systemd-ask-password-wall.path systemd-ask-password-wall.path ) + $(LN_S) ../systemd-ask-password-wall.path systemd-ask-password-wall.path && \ + $(LN_S) ../systemd-logind.service systemd-logind.service ) ( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \ - rm -f getty@tty1.service getty@tty2.service getty@tty3.service getty@tty4.service getty@tty5.service getty@tty6.service && \ - $(LN_S) $(systemunitdir)/getty@.service getty@tty1.service && \ - $(LN_S) $(systemunitdir)/getty@.service getty@tty2.service && \ - $(LN_S) $(systemunitdir)/getty@.service getty@tty3.service && \ - $(LN_S) $(systemunitdir)/getty@.service getty@tty4.service && \ - $(LN_S) $(systemunitdir)/getty@.service getty@tty5.service && \ - $(LN_S) $(systemunitdir)/getty@.service getty@tty6.service ) + rm -f getty@tty1.service && \ + $(LN_S) $(systemunitdir)/getty@.service getty@tty1.service ) ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ rm -f remote-fs.target && \ $(LN_S) $(systemunitdir)/remote-fs.target remote-fs.target ) diff --git a/src/logind.c b/src/logind.c index 3100fd25..701ef494 100644 --- a/src/logind.c +++ b/src/logind.c @@ -652,7 +652,13 @@ static int vt_is_busy(int vtnr) { assert(vtnr >= 1); - fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); + /* We explicitly open /dev/tty1 here instead of /dev/tty0. If + * we'd open the latter we'd open the foreground tty which + * hence would be unconditionally busy. By opening /dev/tty1 + * we avoid this. Since tty1 is special and needs to be an + * explicitly loaded getty or DM this is safe. */ + + fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC); if (fd < 0) return -errno; @@ -668,16 +674,61 @@ static int vt_is_busy(int vtnr) { int manager_spawn_autovt(Manager *m, int vtnr) { int r; + DBusMessage *message = NULL, *reply = NULL; + char *name = NULL; + const char *mode = "fail"; + DBusError error; assert(m); + dbus_error_init(&error); + r = vt_is_busy(vtnr); if (r != 0) return r; - /* ... */ + message = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"); + if (!message) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (asprintf(&name, "autovt-getty@tty%i.service", vtnr) < 0) { + log_error("Could not allocate service name."); + r = -ENOMEM; + goto finish; + } - return 0; + if (!dbus_message_append_args(message, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not attach target and flag information to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(m->bus, message, -1, &error); + if (!reply) { + log_error("Failed to start unit: %s", bus_error_message(&error)); + goto finish; + } + + r = 0; + +finish: + free(name); + + if (message) + dbus_message_unref(message); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; } void manager_cgroup_notify_empty(Manager *m, const char *cgroup) { diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index bfceb39f..b1115672 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -51,4 +51,4 @@ Environment=LANG= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MES KillSignal=SIGHUP [Install] -Alias=getty.target.wants/getty@tty1.service getty.target.wants/getty@tty2.service getty.target.wants/getty@tty3.service getty.target.wants/getty@tty4.service getty.target.wants/getty@tty5.service getty.target.wants/getty@tty6.service +Alias=getty.target.wants/getty@tty1.service -- 2.39.5