chiark / gitweb /
manager: always pull 'following' units into transaction
authorLennart Poettering <lennart@poettering.net>
Sun, 14 Nov 2010 22:47:53 +0000 (23:47 +0100)
committerLennart Poettering <lennart@poettering.net>
Sun, 14 Nov 2010 22:48:21 +0000 (23:48 +0100)
TODO
src/device.c
src/list.h
src/manager.c
src/swap.c
src/unit.c
src/unit.h

diff --git a/TODO b/TODO
index d02dbd7..645b075 100644 (file)
--- a/TODO
+++ b/TODO
 
 * in the PAM module rely on loginuid to figure out XDG_RUNTIME_DIR
 
+* automatically determine TERM= based on tty name. (TERM=linux vs. TERM=vt100-nav)
+
+* declare /etc/system-release cross-distro standard
+
 Pre v12:
 
 * fsck-root.service/start gets queued twice
 
-* pull in 'following' units in transactions
-
 * fix hotplug transactions
 
 * plymouth agent start loop
index 7b73110..7cb4ff6 100644 (file)
@@ -401,6 +401,39 @@ static Unit *device_following(Unit *u) {
         return UNIT(first);
 }
 
+static int device_following_set(Unit *u, Set **_s) {
+        Device *d = DEVICE(u);
+        Device *other;
+        Set *s;
+        int r;
+
+        assert(d);
+        assert(_s);
+
+        if (!d->same_sysfs_prev && !d->same_sysfs_next) {
+                *_s = NULL;
+                return 0;
+        }
+
+        if (!(s = set_new(NULL, NULL)))
+                return -ENOMEM;
+
+        for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
+                if ((r = set_put(s, other)) < 0)
+                        goto fail;
+
+        for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev)
+                if ((r = set_put(s, other)) < 0)
+                        goto fail;
+
+        *_s = s;
+        return 1;
+
+fail:
+        set_free(s);
+        return r;
+}
+
 static void device_shutdown(Manager *m) {
         assert(m);
 
@@ -550,6 +583,7 @@ const UnitVTable device_vtable = {
         .bus_invalidating_properties =  bus_device_invalidating_properties,
 
         .following = device_following,
+        .following_set = device_following_set,
 
         .enumerate = device_enumerate,
         .shutdown = device_shutdown
index 3cf18f1..2bec8c9 100644 (file)
                 }                                                       \
         } while(false)
 
+#define LIST_JUST_US(name,item)                                         \
+        (!(item)->name##_prev && !(item)->name##_next)                  \
+
 #define LIST_FOREACH(name,i,head)                                       \
         for ((i) = (head); (i); (i) = (i)->name##_next)
 
index 932441c..32cd642 100644 (file)
@@ -1445,6 +1445,22 @@ static int transaction_add_job_and_dependencies(
                 return -ENOMEM;
 
         if (is_new) {
+                Set *following;
+
+                /* If we are following some other unit, make sure we
+                 * add all dependencies of everybody following. */
+                if (unit_following_set(ret->unit, &following) > 0) {
+                        SET_FOREACH(dep, following, i)
+                                if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, false, override, false, e, NULL)) < 0) {
+                                        log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+
+                        set_free(following);
+                }
+
                 /* Finally, recursively add in all dependencies. */
                 if (type == JOB_START || type == JOB_RELOAD_OR_START) {
                         SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES], i)
index ddda9e1..6de7928 100644 (file)
@@ -1162,6 +1162,39 @@ static Unit *swap_following(Unit *u) {
         return UNIT(first);
 }
 
+static int swap_following_set(Unit *u, Set **_set) {
+        Swap *s = SWAP(u);
+        Swap *other;
+        Set *set;
+        int r;
+
+        assert(s);
+        assert(_set);
+
+        if (LIST_JUST_US(same_proc_swaps, s)) {
+                *_set = NULL;
+                return 0;
+        }
+
+        if (!(set = set_new(NULL, NULL)))
+                return -ENOMEM;
+
+        LIST_FOREACH_AFTER(same_proc_swaps, other, s)
+                if ((r = set_put(set, other)) < 0)
+                        goto fail;
+
+        LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
+                if ((r = set_put(set, other)) < 0)
+                        goto fail;
+
+        *_set = set;
+        return 1;
+
+fail:
+        set_free(set);
+        return r;
+}
+
 static void swap_shutdown(Manager *m) {
         assert(m);
 
@@ -1319,6 +1352,7 @@ const UnitVTable swap_vtable = {
         .bus_invalidating_properties =  bus_swap_invalidating_properties,
 
         .following = swap_following,
+        .following_set = swap_following_set,
 
         .enumerate = swap_enumerate,
         .shutdown = swap_shutdown
index ee1dc85..b3a8210 100644 (file)
@@ -2319,6 +2319,18 @@ int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error) {
         return UNIT_VTABLE(u)->kill(u, w, m, signo, error);
 }
 
+
+int unit_following_set(Unit *u, Set **s) {
+        assert(u);
+        assert(s);
+
+        if (UNIT_VTABLE(u)->following_set)
+                return UNIT_VTABLE(u)->following_set(u, s);
+
+        *s = NULL;
+        return 0;
+}
+
 static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
         [UNIT_STUB] = "stub",
         [UNIT_LOADED] = "loaded",
index 796aee5..b260dd5 100644 (file)
@@ -329,6 +329,9 @@ struct UnitVTable {
         /* Return the unit this unit is following */
         Unit *(*following)(Unit *u);
 
+        /* Return the set of units that are following each other */
+        int (*following_set)(Unit *u, Set **s);
+
         /* This is called for each unit type and should be used to
          * enumerate existing devices and load them. However,
          * everything that is loaded here should still stay in
@@ -508,6 +511,8 @@ bool unit_pending_active(Unit *u);
 
 int unit_add_default_target_dependency(Unit *u, Unit *target);
 
+int unit_following_set(Unit *u, Set **s);
+
 UnitType unit_name_to_type(const char *n);
 bool unit_name_is_valid(const char *n, bool template_ok);