X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ffsckd%2Ffsckd.c;h=6b35fc26a2f69d3eedbb6658bd78198f4bcc71fd;hb=c40f68e17922f0198837f9caf26817c986573760;hp=4851b9275889f0981aa59cefa44d889e244b13a1;hpb=e78e0674f3ec8512370110383889848dc662639b;p=elogind.git diff --git a/src/fsckd/fsckd.c b/src/fsckd/fsckd.c index 4851b9275..6b35fc26a 100644 --- a/src/fsckd/fsckd.c +++ b/src/fsckd/fsckd.c @@ -76,10 +76,13 @@ typedef struct Manager { LIST_HEAD(Client, clients); unsigned n_clients; - int clear; + size_t clear; + int connection_fd; + sd_event_source *connection_event_source; + + bool show_status_console; - FILE *console; double percent; int numdevices; @@ -96,6 +99,36 @@ static void manager_free(Manager *m); DEFINE_TRIVIAL_CLEANUP_FUNC(Client*, client_free); DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); +static int manager_write_console(Manager *m, const char *message) { + _cleanup_fclose_ FILE *console = NULL; + int l; + size_t j; + + assert(m); + + if (!m->show_status_console) + return 0; + + /* Reduce the SAK window by opening and closing console on every request */ + console = fopen("/dev/console", "we"); + if (!console) + return -errno; + + if (message) { + fprintf(console, "\r%s\r%n", message, &l); + if (m->clear < (size_t)l) + m->clear = (size_t)l; + } else { + fputc('\r', console); + for (j = 0; j < m->clear; j++) + fputc(' ', console); + fputc('\r', console); + } + fflush(console); + + return 0; +} + static double compute_percent(int pass, size_t cur, size_t max) { /* Values stolen from e2fsck */ @@ -198,9 +231,12 @@ static int manager_connect_plymouth(Manager *m) { union sockaddr_union sa = PLYMOUTH_SOCKET; int r; + if (!plymouth_running()) + return 0; + /* try to connect or reconnect if sending a message */ if (m->plymouth_fd >= 0) - return 0; + return 1; m->plymouth_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); if (m->plymouth_fd < 0) @@ -239,12 +275,15 @@ static int plymouth_send_message(int plymouth_fd, const char *message, bool upda } static int manager_send_plymouth_message(Manager *m, const char *message) { - const char *plymouth_cancel_message = NULL; + const char *plymouth_cancel_message = NULL, *l10n_cancel_message = NULL; int r; r = manager_connect_plymouth(m); if (r < 0) return r; + /* 0 means that plymouth isn't running, do not send any message yet */ + else if (r == 0) + return 0; if (!m->plymouth_cancel_sent) { @@ -255,7 +294,8 @@ static int manager_send_plymouth_message(Manager *m, const char *message) { m->plymouth_cancel_sent = true; - plymouth_cancel_message = strjoina("fsckd-cancel-msg:", _("Press Ctrl+C to cancel all filesystem checks in progress")); + l10n_cancel_message = _("Press Ctrl+C to cancel all filesystem checks in progress"); + plymouth_cancel_message = strjoina("fsckd-cancel-msg:", l10n_cancel_message); r = plymouth_send_message(m->plymouth_fd, plymouth_cancel_message, false); if (r < 0) @@ -281,7 +321,7 @@ static int manager_update_global_progress(Manager *m) { Client *current = NULL; _cleanup_free_ char *console_message = NULL; _cleanup_free_ char *fsck_message = NULL; - int current_numdevices = 0, l = 0, r; + int current_numdevices = 0, r; double current_percent = 100; /* get the overall percentage */ @@ -308,19 +348,14 @@ static int manager_update_global_progress(Manager *m) { if (asprintf(&fsck_message, "fsckd:%d:%3.1f:%s", m->numdevices, m->percent, console_message) < 0) return -ENOMEM; - /* write to console */ - if (m->console) { - fprintf(m->console, "\r%s\r%n", console_message, &l); - fflush(m->console); - } + r = manager_write_console(m, console_message); + if (r < 0) + return r; /* try to connect to plymouth and send message */ r = manager_send_plymouth_message(m, fsck_message); if (r < 0) - log_debug("Couldn't send message to plymouth"); - - if (l > m->clear) - m->clear = l; + return r; } return 0; } @@ -349,9 +384,7 @@ static int client_progress_handler(sd_event_source *s, int fd, uint32_t revents, else { log_warning("Closing bad behaving fsck client connection at fd %d", client->fd); client_free(client); - r = manager_update_global_progress(m); - if (r < 0) - log_warning_errno(r, "Couldn't update global progress: %m"); + manager_update_global_progress(m); } return 0; } @@ -375,9 +408,7 @@ static int client_progress_handler(sd_event_source *s, int fd, uint32_t revents, } else log_error_errno(r, "Unknown error while trying to read fsck data: %m"); - r = manager_update_global_progress(m); - if (r < 0) - log_warning_errno(r, "Couldn't update global progress: %m"); + manager_update_global_progress(m); return 0; } @@ -434,16 +465,9 @@ static void manager_free(Manager *m) { return; /* clear last line */ - if (m->console && m->clear > 0) { - unsigned j; - - fputc('\r', m->console); - for (j = 0; j < (unsigned) m->clear; j++) - fputc(' ', m->console); - fputc('\r', m->console); - fflush(m->console); - } + manager_write_console(m, NULL); + sd_event_source_unref(m->connection_event_source); safe_close(m->connection_fd); while (m->clients) @@ -451,9 +475,6 @@ static void manager_free(Manager *m) { manager_disconnect_plymouth(m); - if (m->console) - fclose(m->console); - sd_event_unref(m->event); free(m); @@ -477,13 +498,10 @@ static int manager_new(Manager **ret, int fd) { if (r < 0) return r; - if (access("/run/systemd/show-status", F_OK) >= 0) { - m->console = fopen("/dev/console", "we"); - if (!m->console) - return -errno; - } + if (access("/run/systemd/show-status", F_OK) >= 0) + m->show_status_console = true; - r = sd_event_add_io(m->event, NULL, fd, EPOLLIN, manager_new_connection_handler, m); + r = sd_event_add_io(m->event, &m->connection_event_source, fd, EPOLLIN, manager_new_connection_handler, m); if (r < 0) return r;