chiark / gitweb /
shared: move fdset.c from core/ to shared/ since it is used by more than the core now
[elogind.git] / src / core / manager.c
index 54600c6bfc97f08aed6b0c9b5c22ecf48dc5ec19..a3839e1538e29cf61ac4613871f07b650ca49e3c 100644 (file)
@@ -154,7 +154,12 @@ static int manager_setup_time_change(Manager *m) {
         }
 
         zero(its);
-        its.it_value.tv_sec = 10000000000; /* Year 2287 or so... */
+
+        /* We only care for the cancellation event, hence we set the
+         * timeout to the latest possible value. */
+        assert_cc(sizeof(time_t) == sizeof(long));
+        its.it_value.tv_sec = LONG_MAX;
+
         if (timerfd_settime(m->time_change_watch.fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
                 log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
                 close_nointr_nofail(m->time_change_watch.fd);
@@ -701,6 +706,16 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
                         r = q;
         }
 
+        /* Any fds left? Find some unit which wants them. This is
+         * useful to allow container managers to pass some file
+         * descriptors to us pre-initialized. This enables
+         * socket-based activation of entire containers. */
+        if (fdset_size(fds) > 0) {
+                q = manager_distribute_fds(m, fds);
+                if (q < 0)
+                        r = q;
+        }
+
         /* Third, fire things up! */
         q = manager_coldplug(m);
         if (q < 0)
@@ -1161,7 +1176,8 @@ static int manager_process_signal_fd(Manager *m) {
         assert(m);
 
         for (;;) {
-                if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
+                n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi));
+                if (n != sizeof(sfsi)) {
 
                         if (n >= 0)
                                 return -EIO;
@@ -1802,7 +1818,8 @@ int manager_open_serialization(Manager *m, FILE **_f) {
         log_debug("Serializing state to %s", path);
         free(path);
 
-        if (!(f = fdopen(fd, "w+")))
+        f = fdopen(fd, "w+");
+        if (!f)
                 return -errno;
 
         *_f = f;
@@ -1960,7 +1977,8 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                 if ((r = manager_load_unit(m, strstrip(name), NULL, NULL, &u)) < 0)
                         goto finish;
 
-                if ((r = unit_deserialize(u, f, fds)) < 0)
+                r = unit_deserialize(u, f, fds);
+                if (r < 0)
                         goto finish;
         }
 
@@ -1976,6 +1994,28 @@ finish:
         return r;
 }
 
+int manager_distribute_fds(Manager *m, FDSet *fds) {
+        Unit *u;
+        Iterator i;
+        int r;
+
+        assert(m);
+
+        HASHMAP_FOREACH(u, m->units, i) {
+
+                if (fdset_size(fds) <= 0)
+                        break;
+
+                if (UNIT_VTABLE(u)->distribute_fds) {
+                        r = UNIT_VTABLE(u)->distribute_fds(u, fds);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}
+
 int manager_reload(Manager *m) {
         int r, q;
         FILE *f;