chiark / gitweb /
manager: notify plymouth about progress if it is running
authorLennart Poettering <lennart@poettering.net>
Wed, 6 Oct 2010 01:55:49 +0000 (03:55 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 6 Oct 2010 01:55:49 +0000 (03:55 +0200)
fixme
src/manager.c
src/manager.h
src/unit.c

diff --git a/fixme b/fixme
index 6619940aeabe8a5df0a1c6a5caacd2bcf72e27f0..7021a8a28ad18eb25e11c82783a111298a2a72de 100644 (file)
--- 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
index 1be2bfdfc5701a0838caff411431e99e1dd8d68b..c062cfb5ed3f19fb33bde2d7456843022902c960 100644 (file)
@@ -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,
index 10ff24c798aec59577fecda1c2271cd8901a636a..5037127655db799a26cf08d40add610b0d285bca 100644 (file)
@@ -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);
 
index 71ef2a706da447494a909ddaea074c10b2241e80..2f8b92d3b5c08f3eba35efd63b769b3fb2d21b79 100644 (file)
@@ -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))