From: Lennart Poettering Date: Wed, 6 Oct 2010 01:55:49 +0000 (+0200) Subject: manager: notify plymouth about progress if it is running X-Git-Tag: v11~5 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=e983b76024342278a0377eae116c925f2567776e manager: notify plymouth about progress if it is running --- diff --git a/fixme b/fixme index 6619940ae..7021a8a28 100644 --- a/fixme +++ b/fixme @@ -82,8 +82,6 @@ later: * ask-password tty agent, ask-password plymouth agent -* plymouth update status hookup - * ask-password tty timeout * properly handle multiple inotify events per read() in path.c and util.c diff --git a/src/manager.c b/src/manager.c index 1be2bfdfc..c062cfb5e 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2299,6 +2299,75 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) { } +void manager_send_unit_plymouth(Manager *m, Unit *u) { + int fd = -1; + union sockaddr_union sa; + int n = 0; + char *message = NULL; + ssize_t r; + + /* Don't generate plymouth events if the service was already + * started and we're just deserializing */ + if (m->n_deserializing > 0) + return; + + if (m->running_as != MANAGER_SYSTEM) + return; + + if (u->meta.type != UNIT_SERVICE && + u->meta.type != UNIT_MOUNT && + u->meta.type != UNIT_SWAP) + return; + + /* We set SOCK_NONBLOCK here so that we rather drop the + * message then wait for plymouth */ + if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("socket() failed: %m"); + return; + } + + zero(sa); + sa.sa.sa_family = AF_UNIX; + strncpy(sa.un.sun_path+1, "/ply-boot-protocol", sizeof(sa.un.sun_path)-1); + if (connect(fd, &sa.sa, sizeof(sa.un)) < 0) { + + if (errno != EPIPE && + errno != EAGAIN && + errno != ENOENT && + errno != ECONNREFUSED && + errno != ECONNRESET && + errno != ECONNABORTED) + log_error("connect() failed: %m"); + + goto finish; + } + + if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->meta.id) + 1), u->meta.id, &n) < 0) { + log_error("Out of memory"); + goto finish; + } + + errno = 0; + if ((r = write(fd, message, n + 1)) != n + 1) { + + if (errno != EPIPE && + errno != EAGAIN && + errno != ENOENT && + errno != ECONNREFUSED && + errno != ECONNRESET && + errno != ECONNABORTED) + log_error("Failed to write Plymouth message: %m"); + + goto finish; + } + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + free(message); +} + void manager_dispatch_bus_name_owner_changed( Manager *m, const char *name, diff --git a/src/manager.h b/src/manager.h index 10ff24c79..503712765 100644 --- a/src/manager.h +++ b/src/manager.h @@ -264,6 +264,7 @@ bool manager_is_booting_or_shutting_down(Manager *m); void manager_reset_failed(Manager *m); void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success); +void manager_send_unit_plymouth(Manager *m, Unit *u); bool manager_unit_pending_inactive(Manager *m, const char *name); diff --git a/src/unit.c b/src/unit.c index 71ef2a706..2f8b92d3b 100644 --- a/src/unit.c +++ b/src/unit.c @@ -1165,10 +1165,13 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { if (u->meta.type == UNIT_SERVICE && !UNIT_IS_ACTIVE_OR_RELOADING(os)) { /* Write audit record if we have just finished starting up */ - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, 1); + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, true); u->meta.in_audit = true; } + if (!UNIT_IS_ACTIVE_OR_RELOADING(os)) + manager_send_unit_plymouth(u->meta.manager, u); + } else { if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE))