Print this page
7369 SMF is fast and loose with exclude dependencies

@@ -1427,19 +1427,21 @@
                                 continue;
 
                         switch (v->gv_state) {
                         case RESTARTER_STATE_ONLINE:
                         case RESTARTER_STATE_DEGRADED:
-                                LOG_EXCLUDE(groupv, v);
-                                return (v->gv_flags & GV_ENABLED ? -1 : 0);
-
                         case RESTARTER_STATE_OFFLINE:
-                        case RESTARTER_STATE_UNINIT:
                                 LOG_EXCLUDE(groupv, v);
-                                return (0);
+                                return (v->gv_flags & GV_TODISABLE ? 0 : -1);
 
                         case RESTARTER_STATE_DISABLED:
+                        case RESTARTER_STATE_UNINIT:
+                                if (v->gv_flags & GV_ENABLED) {
+                                        LOG_EXCLUDE(groupv, v);
+                                        return (-1);
+                                }
+                                /* FALLTHROUGH */
                         case RESTARTER_STATE_MAINT:
                                 continue;
 
                         default:
 #ifndef NDEBUG

@@ -1449,11 +1451,11 @@
                                 abort();
                         }
                         /* NOTREACHED */
 
                 case GVT_SVC:
-                        break;
+                        return (exclude_all_satisfied(v, satbility));
 
                 case GVT_FILE:
                         if (!file_ready(v))
                                 continue;
                         LOG_EXCLUDE(groupv, v);

@@ -1465,47 +1467,10 @@
                         uu_warn("%s:%d: Unexpected vertex type %d.\n", __FILE__,
                             __LINE__, v->gv_type);
 #endif
                         abort();
                 }
-
-                /* v represents a service */
-                if (uu_list_numnodes(v->gv_dependencies) == 0)
-                        continue;
-
-                for (e2 = uu_list_first(v->gv_dependencies);
-                    e2 != NULL;
-                    e2 = uu_list_next(v->gv_dependencies, e2)) {
-                        v2 = e2->ge_vertex;
-                        assert(v2->gv_type == GVT_INST);
-
-                        if ((v2->gv_flags & GV_CONFIGURED) == 0)
-                                continue;
-
-                        switch (v2->gv_state) {
-                        case RESTARTER_STATE_ONLINE:
-                        case RESTARTER_STATE_DEGRADED:
-                                LOG_EXCLUDE(groupv, v2);
-                                return (v2->gv_flags & GV_ENABLED ? -1 : 0);
-
-                        case RESTARTER_STATE_OFFLINE:
-                        case RESTARTER_STATE_UNINIT:
-                                LOG_EXCLUDE(groupv, v2);
-                                return (0);
-
-                        case RESTARTER_STATE_DISABLED:
-                        case RESTARTER_STATE_MAINT:
-                                continue;
-
-                        default:
-#ifndef NDEBUG
-                                uu_warn("%s:%d: Unexpected vertex type %d.\n",
-                                    __FILE__, __LINE__, v2->gv_type);
-#endif
-                                abort();
-                        }
-                }
         }
 
         return (1);
 }
 

@@ -1516,13 +1481,50 @@
  *   without administrator intervention.
  */
 static int
 instance_satisfied(graph_vertex_t *v, boolean_t satbility)
 {
+        graph_edge_t *e;
+        boolean_t any_unsatisfied;
+        boolean_t any_unsatisfiable;
+
         assert(v->gv_type == GVT_INST);
         assert(!inst_running(v));
 
+        any_unsatisfied = B_FALSE;
+        any_unsatisfiable = B_FALSE;
+
+        /*
+         * Walk the dependents of the given vertex looking for any exclude_all
+         * dependency groups with running instances.  If they are all going to
+         * be disabled consider the dependency unsatisfied, not unsatisfaible.
+         */
+        for (e = uu_list_first(v->gv_dependents); e != NULL;
+            e = uu_list_next(v->gv_dependents, e)) {
+                graph_edge_t *e2;
+
+                if (e->ge_vertex->gv_type != GVT_GROUP ||
+                    e->ge_vertex->gv_depgroup != DEPGRP_EXCLUDE_ALL)
+                        continue;
+
+                for (e2 = uu_list_first(e->ge_vertex->gv_dependents);
+                    e2 != NULL;
+                    e2 = uu_list_next(e->ge_vertex->gv_dependents, e2)) {
+
+                        if (!inst_running(e2->ge_vertex))
+                                continue;
+
+                        if (e2->ge_vertex->gv_flags & GV_TODISABLE)
+                                any_unsatisfied = B_TRUE;
+                        else
+                                any_unsatisfiable = B_TRUE;
+                }
+        }
+
+        if (any_unsatisfied || any_unsatisfiable)
+                return (any_unsatisfiable ? -1 : 0);
+
         return (require_all_satisfied(v, satbility));
 }
 
 /*
  * Decide whether v can satisfy a dependency.  v can either be a child of

@@ -4537,11 +4539,11 @@
          */
         if ((v->gv_flags & GV_TOOFFLINE) == 0)
                 return;
 
         /* If v isn't a leaf because it's already down, recurse. */
-        if (!up_state(v->gv_state)) {
+        if (!inst_running(v) && (v->gv_flags & GV_TODISABLE) == 0) {
                 graph_walk_dependencies(v, offline_subtree_leaves, arg);
                 return;
         }
 
         /* if v is a leaf, offline it or disable it if it's the last one */