diff options
-rw-r--r-- | Makefile.am | 20 | ||||
-rw-r--r-- | src/auto-serial-getty.c | 189 | ||||
-rw-r--r-- | src/main.c | 29 | ||||
-rw-r--r-- | src/manager.c | 19 | ||||
-rw-r--r-- | src/manager.h | 4 | ||||
-rw-r--r-- | src/special.h | 2 | ||||
-rw-r--r-- | src/target.c | 45 | ||||
-rw-r--r-- | units/systemd-auto-serial-getty.service.in | 16 |
8 files changed, 99 insertions, 225 deletions
diff --git a/Makefile.am b/Makefile.am index 725685dfb0..ed37278d33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -73,7 +73,6 @@ rootlibexec_PROGRAMS = \ systemd-update-utmp \ systemd-random-seed \ systemd-shutdownd \ - systemd-auto-serial-getty \ systemd-modules-load \ systemd-remount-api-vfs \ systemd-kmsg-syslogd @@ -179,7 +178,6 @@ nodist_systemunit_DATA = \ units/systemd-logger.service \ units/systemd-shutdownd.service \ units/systemd-kmsg-syslogd.service \ - units/systemd-auto-serial-getty.service \ units/systemd-modules-load.service \ units/systemd-remount-api-vfs.service \ units/systemd-update-utmp-runlevel.service \ @@ -206,7 +204,6 @@ EXTRA_DIST = \ units/systemd-logger.service.in \ units/systemd-shutdownd.service.in \ units/systemd-kmsg-syslogd.service.in \ - units/systemd-auto-serial-getty.service.in \ units/systemd-modules-load.service.in \ units/systemd-remount-api-vfs.service.in \ units/systemd-update-utmp-runlevel.service.in \ @@ -575,18 +572,6 @@ systemd_shutdownd_CFLAGS = \ systemd_shutdownd_LDADD = \ libsystemd-basic.la -systemd_auto_serial_getty_SOURCES = \ - src/auto-serial-getty.c \ - src/dbus-common.c - -systemd_auto_serial_getty_CFLAGS = \ - $(AM_CFLAGS) \ - $(DBUS_CFLAGS) - -systemd_auto_serial_getty_LDADD = \ - libsystemd-basic.la \ - $(DBUS_LIBS) - systemd_modules_load_SOURCES = \ src/modules-load.c @@ -896,14 +881,13 @@ install-data-hook: $(LN_S) $(systemunitdir)/reboot.target ctrl-alt-del.target && \ $(LN_S) $(systemunitdir)/rescue.target kbrequest.target ) ( 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 systemd-auto-serial-getty.service && \ + 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 && \ - $(LN_S) $(systemunitdir)/systemd-auto-serial-getty.service systemd-auto-serial-getty.service ) + $(LN_S) $(systemunitdir)/getty@.service getty@tty6.service ) ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ rm -f getty.target remote-fs.target && \ $(LN_S) $(systemunitdir)/getty.target getty.target && \ diff --git a/src/auto-serial-getty.c b/src/auto-serial-getty.c deleted file mode 100644 index 355cdfd6a6..0000000000 --- a/src/auto-serial-getty.c +++ /dev/null @@ -1,189 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include <dbus/dbus.h> - -#include "util.h" -#include "log.h" -#include "dbus-common.h" - -static int spawn_getty(DBusConnection *bus, const char *console) { - DBusMessage *m = NULL, *reply = NULL; - DBusError error; - const char *fail = "fail"; - char *name; - int r = -EIO; - - dbus_error_init(&error); - - assert(bus); - assert(console); - - /* FIXME: we probably should escape the tty name properly here */ - if (asprintf(&name, "serial-getty@%s.service", console) < 0) - return -ENOMEM; - - if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) { - log_error("Could not allocate message."); - goto finish; - } - - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &fail, - DBUS_TYPE_INVALID)) { - log_error("Could not attach target and flag information to message."); - goto finish; - } - - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { - log_error("Failed to start unit: %s", bus_error_message(&error)); - goto finish; - } - - r = 0; - -finish: - if (m) - dbus_message_unref(m); - - if (reply) - dbus_message_unref(reply); - - dbus_error_free(&error); - - free(name); - - return r; -} - -static int parse_proc_cmdline_word(const char *word, char **console) { - assert(word); - - if (startswith(word, "console=")) { - const char *k; - size_t l; - char *w = NULL; - - k = word + 8; - l = strcspn(k, ","); - - if (l < 4 || - !startswith(k, "tty") || - k[3+strspn(k+3, "0123456789")] != 0) { - - if (!(w = strndup(k, l))) - return -ENOMEM; - - } - - free(*console); - *console = w; - } - - return 0; -} - -static int parse_proc_cmdline(char **console) { - char *line; - int r; - char *w; - size_t l; - char *state; - - assert(console); - - if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { - log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); - return 0; - } - - FOREACH_WORD_QUOTED(w, l, line, state) { - char *word; - - if (!(word = strndup(w, l))) { - r = -ENOMEM; - goto finish; - } - - r = parse_proc_cmdline_word(word, console); - free(word); - - if (r < 0) - goto finish; - } - - r = 0; - -finish: - free(line); - return r; -} - -int main(int argc, char *argv[]) { - DBusError error; - int r = 1; - char *console = NULL; - DBusConnection *bus = NULL; - - dbus_error_init(&error); - - if (argc > 1) { - log_error("This program does not take arguments."); - return 1; - } - - log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); - log_parse_environment(); - log_open(); - - if (bus_connect(DBUS_BUS_SYSTEM, &bus, NULL, &error) < 0) { - log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); - goto finish; - } - - if (parse_proc_cmdline(&console) < 0) - goto finish; - - if (console) - if (spawn_getty(bus, console) < 0) - goto finish; - - r = 0; - -finish: - free(console); - - if (bus) { - dbus_connection_close(bus); - dbus_connection_unref(bus); - } - - dbus_error_free(&error); - - dbus_shutdown(); - - return r; -} diff --git a/src/main.c b/src/main.c index f1fa569112..53a455b505 100644 --- a/src/main.c +++ b/src/main.c @@ -66,6 +66,7 @@ static bool arg_show_status = true; static bool arg_sysv_console = true; static bool arg_mount_auto = true; static bool arg_swap_auto = true; +static char *arg_console = NULL; static FILE* serialization = NULL; @@ -335,6 +336,26 @@ static int parse_proc_cmdline_word(const char *word) { "systemd.log_color=0|1 Highlight important log messages\n" "systemd.log_location=0|1 Include code location in log messages\n"); + } else if (startswith(word, "console=")) { + const char *k; + size_t l; + char *w = NULL; + + k = word + 8; + l = strcspn(k, ","); + + /* Ignore the console setting if set to a VT */ + if (l < 4 || + !startswith(k, "tty") || + k[3+strspn(k+3, "0123456789")] != 0) { + + if (!(w = strndup(k, l))) + return -ENOMEM; + } + + free(arg_console); + arg_console = w; + } else if (streq(word, "quiet")) { arg_show_status = false; arg_sysv_console = false; @@ -993,6 +1014,9 @@ int main(int argc, char *argv[]) { m->mount_auto = arg_mount_auto; m->swap_auto = arg_swap_auto; + if (arg_console) + manager_set_console(m, arg_console); + if ((r = manager_startup(m, serialization, fds)) < 0) log_error("Failed to fully start up daemon: %s", strerror(-r)); @@ -1090,9 +1114,12 @@ finish: manager_free(m); free(arg_default_unit); + free(arg_console); dbus_shutdown(); + label_finish(); + if (reexecute) { const char *args[15]; unsigned i = 0; @@ -1157,7 +1184,5 @@ finish: if (getpid() == 1) freeze(); - label_finish(); - return retval; } diff --git a/src/manager.c b/src/manager.c index 09b2c789ed..0afc99243e 100644 --- a/src/manager.c +++ b/src/manager.c @@ -112,6 +112,8 @@ static int manager_setup_notify(Manager *m) { if (!(m->notify_socket = strdup(sa.un.sun_path+1))) return -ENOMEM; + log_debug("Using notification socket %s", m->notify_socket); + return 0; } @@ -447,6 +449,7 @@ void manager_free(Manager *m) { #endif free(m->notify_socket); + free(m->console); lookup_paths_free(&m->lookup_paths); strv_free(m->environment); @@ -2553,6 +2556,22 @@ void manager_reset_maintenance(Manager *m) { unit_reset_maintenance(u); } +int manager_set_console(Manager *m, const char *console) { + char *c; + + assert(m); + + if (!(c = strdup(console))) + return -ENOMEM; + + free(m->console); + m->console = c; + + log_debug("Using kernel console %s", c); + + return 0; +} + static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = { [MANAGER_SYSTEM] = "system", [MANAGER_SESSION] = "session" diff --git a/src/manager.h b/src/manager.h index e3c6db23bd..6186cb2333 100644 --- a/src/manager.h +++ b/src/manager.h @@ -140,6 +140,8 @@ struct Manager { dual_timestamp startup_timestamp; + char *console; + /* Data specific to the device subsystem */ struct udev* udev; struct udev_monitor* udev_monitor; @@ -237,6 +239,8 @@ unsigned manager_dispatch_load_queue(Manager *m); unsigned manager_dispatch_run_queue(Manager *m); unsigned manager_dispatch_dbus_queue(Manager *m); +int manager_set_console(Manager *m, const char *console); + int manager_loop(Manager *m); void manager_dispatch_bus_name_owner_changed(Manager *m, const char *name, const char* old_owner, const char *new_owner); diff --git a/src/special.h b/src/special.h index 7bf207053c..0cc5cc647b 100644 --- a/src/special.h +++ b/src/special.h @@ -59,6 +59,8 @@ #define SPECIAL_POWEROFF_TARGET "poweroff.target" #define SPECIAL_REBOOT_TARGET "reboot.target" #define SPECIAL_DBUS_SERVICE "dbus.service" +#define SPECIAL_GETTY_TARGET "getty.target" +#define SPECIAL_SERIAL_GETTY_SERVICE "serial-getty@.service" #ifndef SPECIAL_SYSLOG_SERVICE #define SPECIAL_SYSLOG_SERVICE "syslog.service" diff --git a/src/target.c b/src/target.c index c7285fa737..c350d8fa19 100644 --- a/src/target.c +++ b/src/target.c @@ -21,6 +21,7 @@ #include <errno.h> #include <signal.h> +#include <unistd.h> #include "unit.h" #include "target.h" @@ -28,6 +29,7 @@ #include "log.h" #include "dbus-target.h" #include "special.h" +#include "unit-name.h" static const UnitActiveState state_translation_table[_TARGET_STATE_MAX] = { [TARGET_DEAD] = UNIT_INACTIVE, @@ -76,6 +78,46 @@ static int target_add_default_dependencies(Target *t) { return 0; } +static int target_add_getty_dependencies(Target *t) { + char *n; + int r; + + assert(t); + + if (!unit_has_name(UNIT(t), SPECIAL_GETTY_TARGET)) + return 0; + + /* Automatically add in a serial getty on the kernel + * console */ + if (t->meta.manager->console) { + log_debug("Automatically adding serial getty for %s", t->meta.manager->console); + if (!(n = unit_name_replace_instance(SPECIAL_SERIAL_GETTY_SERVICE, t->meta.manager->console))) + return -ENOMEM; + + r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_WANTS, n, NULL, true); + free(n); + + if (r < 0) + return r; + } + + /* Automatically add in a serial getty on the first + * virtualizer console */ + if (access("/sys/class/tty/hvc0", F_OK) == 0) { + log_debug("Automatic adding serial getty for hvc0"); + if (!(n = unit_name_replace_instance(SPECIAL_SERIAL_GETTY_SERVICE, "hvc0"))) + return -ENOMEM; + + r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_WANTS, n, NULL, true); + free(n); + + if (r < 0) + return r; + } + + return 0; +} + static int target_load(Unit *u) { Target *t = TARGET(u); int r; @@ -90,6 +132,9 @@ static int target_load(Unit *u) { if (u->meta.default_dependencies) if ((r = target_add_default_dependencies(t)) < 0) return r; + + if ((r = target_add_getty_dependencies(t)) < 0) + return r; } return 0; diff --git a/units/systemd-auto-serial-getty.service.in b/units/systemd-auto-serial-getty.service.in deleted file mode 100644 index 8051c7446a..0000000000 --- a/units/systemd-auto-serial-getty.service.in +++ /dev/null @@ -1,16 +0,0 @@ -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -[Unit] -Description=Automatically Spawn getty on Serial Kernel Console - -[Service] -Type=oneshot -ExecStart=@rootlibexecdir@/systemd-auto-serial-getty - -[Install] -WantedBy=getty.target |