summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2011-06-28 00:26:10 +0200
committerLennart Poettering <lennart@poettering.net>2011-06-28 00:26:10 +0200
commitd0a522eb312a0f6014e756d3fc066efc37fceaf7 (patch)
tree70c22872b026e41e96ce05ce9529997ba3ec5ad2 /src
parent734b933ace7aac5d9c1d7507f9d30f73390ce102 (diff)
logind: autospawn gettys when necessary
Diffstat (limited to 'src')
-rw-r--r--src/logind.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/src/logind.c b/src/logind.c
index 3100fd2517..701ef494e8 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) {