X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fgetty-generator.c;h=1263785fb51127d646fc11495ec5d03d57d9c0ad;hp=b8228e98223f83506a54019f427389f46a18f959;hb=fc8af9ff3fbbbf21bf26f21d2eb100f26afc201a;hpb=4c12626c8e3491570b395d68380543e10c98ad33 diff --git a/src/getty-generator.c b/src/getty-generator.c index b8228e982..1263785fb 100644 --- a/src/getty-generator.c +++ b/src/getty-generator.c @@ -26,6 +26,7 @@ #include "log.h" #include "util.h" #include "unit-name.h" +#include "virt.h" const char *arg_dest = "/tmp"; @@ -33,6 +34,9 @@ static int add_symlink(const char *fservice, const char *tservice) { char *from = NULL, *to = NULL; int r; + assert(fservice); + assert(tservice); + asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", fservice); asprintf(&to, "%s/getty.target.wants/%s", arg_dest, tservice); @@ -44,9 +48,15 @@ static int add_symlink(const char *fservice, const char *tservice) { mkdir_parents(to, 0755); - if ((r = symlink(from, to)) < 0) { - log_error("Failed to create symlink from %s to %s: %m", from, to); - r = -errno; + r = symlink(from, to); + if (r < 0) { + if (errno == EEXIST) + /* In case console=hvc0 is passed this will very likely result in EEXIST */ + r = 0; + else { + log_error("Failed to create symlink from %s to %s: %m", from, to); + r = -errno; + } } finish: @@ -57,26 +67,53 @@ finish: return r; } +static int add_serial_getty(const char *tty) { + char *n; + int r; + + assert(tty); + + log_debug("Automatically adding serial getty for /dev/%s.", tty); + + n = unit_name_replace_instance("serial-getty@.service", tty); + if (!n) { + log_error("Out of memory"); + return -ENOMEM; + } + + r = add_symlink("serial-getty@.service", n); + free(n); + + return r; +} + int main(int argc, char *argv[]) { + + static const char virtualization_consoles[] = + "hvc0\0" + "xvc0\0" + "hvsi0\0"; + int r = EXIT_SUCCESS; char *active; + const char *j; if (argc > 2) { log_error("This program takes one or no arguments."); return EXIT_FAILURE; } - if (argc > 1) - arg_dest = argv[1]; - - log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); umask(0022); + if (argc > 1) + arg_dest = argv[1]; + if (detect_container(NULL) > 0) { - log_debug("Automatic adding console shell."); + log_debug("Automatically adding console shell."); if (add_symlink("console-shell.service", "console-shell.service") < 0) r = EXIT_FAILURE; @@ -88,47 +125,56 @@ int main(int argc, char *argv[]) { if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { const char *tty; - if ((tty = strrchr(active, ' '))) + tty = strrchr(active, ' '); + if (tty) tty ++; else tty = active; /* Automatically add in a serial getty on the kernel * console */ - if (!tty_is_vc(tty)) { - char *n; + if (tty_is_vc(tty)) + free(active); + else { + int k; /* We assume that gettys on virtual terminals are * started via manual configuration and do this magic * only for non-VC terminals. */ - log_debug("Automatically adding serial getty for /dev/%s.", tty); + k = add_serial_getty(tty); + free(active); - if (!(n = unit_name_replace_instance("serial-getty@.service", tty)) || - add_symlink("serial-getty@.service", n) < 0) + if (k < 0) { r = EXIT_FAILURE; - - free(n); + goto finish; + } } - - free(active); } /* Automatically add in a serial getty on the first * virtualizer console */ - if (access("/sys/class/tty/hvc0", F_OK) == 0) { - log_debug("Automatically adding serial getty for hvc0."); + NULSTR_FOREACH(j, virtualization_consoles) { + char *p; + int k; - if (add_symlink("serial-getty@.service", "serial-getty@hvc0.service") < 0) + if (asprintf(&p, "/sys/class/tty/%s", j) < 0) { + log_error("Out of memory"); r = EXIT_FAILURE; + goto finish; + } - } + k = access(p, F_OK); + free(p); - if (access("/sys/class/tty/xvc0", F_OK) == 0) { - log_debug("Automatically adding serial getty for xvc0."); + if (k < 0) + continue; - if (add_symlink("serial-getty@.service", "serial-getty@xvc0.service") < 0) + k = add_serial_getty(j); + if (k < 0) { r = EXIT_FAILURE; + goto finish; + } } finish: