--- old/usr/src/cmd/svc/startd/graph.c	2016-07-31 04:30:35.491985009 +0100
+++ new/usr/src/cmd/svc/startd/graph.c	2016-07-31 04:30:35.499513577 +0100
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2015, Syneto S.R.L. All rights reserved.
+ * Copyright 2016 RackTop Systems.
  */
 
 /*
@@ -207,7 +208,6 @@
 
 #define	is_depgrp_bypassed(v) ((v->gv_type == GVT_GROUP) && \
 	((v->gv_depgroup == DEPGRP_EXCLUDE_ALL) || \
-	(v->gv_depgroup == DEPGRP_OPTIONAL_ALL) || \
 	(v->gv_restart < RERR_RESTART)))
 
 static uu_list_pool_t *graph_edge_pool, *graph_vertex_pool;
@@ -305,7 +305,6 @@
 static int dgraph_set_milestone(const char *, scf_handle_t *, boolean_t);
 static boolean_t should_be_in_subgraph(graph_vertex_t *v);
 static int mark_subtree(graph_edge_t *, void *);
-static boolean_t insubtree_dependents_down(graph_vertex_t *);
 
 /*
  * graph_vertex_compare()
@@ -1328,17 +1327,13 @@
 
 		switch (v->gv_type) {
 		case GVT_INST:
-			/* Skip missing or disabled instances */
-			if ((v->gv_flags & (GV_CONFIGURED | GV_ENABLED)) !=
-			    (GV_CONFIGURED | GV_ENABLED))
+			/* Skip missing instances */
+			if ((v->gv_flags & GV_CONFIGURED) == 0)
 				continue;
 
 			if (v->gv_state == RESTARTER_STATE_MAINT)
 				continue;
 
-			if (v->gv_flags & GV_TOOFFLINE)
-				continue;
-
 			any_qualified = B_TRUE;
 			if (v->gv_state == RESTARTER_STATE_OFFLINE) {
 				/*
@@ -1354,7 +1349,7 @@
 				 * transitioned out of disabled yet.  Treat it
 				 * as unsatisfied (not unsatisfiable).
 				 */
-				i = 0;
+				i = v->gv_flags & GV_ENABLED ? 0 : 1;
 			} else {
 				i = dependency_satisfied(v, satbility);
 			}
@@ -1383,19 +1378,13 @@
 				v2 = e2->ge_vertex;
 				assert(v2->gv_type == GVT_INST);
 
-				if ((v2->gv_flags &
-				    (GV_CONFIGURED | GV_ENABLED)) !=
-				    (GV_CONFIGURED | GV_ENABLED))
+				if ((v2->gv_flags & GV_CONFIGURED) == 0)
 					continue;
 
 				if (v2->gv_state == RESTARTER_STATE_MAINT)
 					continue;
 
-				if (v2->gv_flags & GV_TOOFFLINE)
-					continue;
-
 				svc_any_qualified = B_TRUE;
-
 				if (v2->gv_state == RESTARTER_STATE_OFFLINE) {
 					/*
 					 * For offline dependencies, treat
@@ -1406,7 +1395,7 @@
 						i = 1;
 				} else if (v2->gv_state ==
 				    RESTARTER_STATE_DISABLED) {
-					i = 0;
+					i = v2->gv_flags & GV_ENABLED ? 0 : 1;
 				} else {
 					i = dependency_satisfied(v2, satbility);
 				}
@@ -4375,7 +4364,7 @@
  * or degraded (offline is considered down in this situation). This function
  * is somehow similar to is_nonsubgraph_leaf() but works on subtrees.
  */
-static boolean_t
+boolean_t
 insubtree_dependents_down(graph_vertex_t *v)
 {
 	graph_vertex_t *vv;
@@ -4391,16 +4380,16 @@
 				continue;
 
 			if ((vv->gv_flags & GV_TOOFFLINE) == 0)
-				continue;
+				return (B_FALSE);
 
 			if ((vv->gv_state == RESTARTER_STATE_ONLINE) ||
 			    (vv->gv_state == RESTARTER_STATE_DEGRADED))
 				return (B_FALSE);
 		} else {
 			/*
-			 * Skip all excluded and optional_all dependencies
-			 * and decide whether to offline the service based
-			 * on restart_on attribute.
+			 * Skip all excluded dependencies and decide whether
+			 * decide whether to offline the service based on the
+			 * restart_on attribute.
 			 */
 			if (is_depgrp_bypassed(vv))
 				continue;
@@ -4562,6 +4551,15 @@
 {
 	assert(MUTEX_HELD(&dgraph_lock));
 
+	/* If v has up dependents, try to bring them down first. */
+	if (insubtree_dependents_down(v) == B_FALSE) {
+		graph_walk_dependents(v, offline_subtree_leaves, arg);
+
+		/* If we couldn't bring them down, return. */
+		if (insubtree_dependents_down(v) == B_FALSE)
+			return;
+	}
+
 	/* If v isn't an instance, recurse on its dependencies. */
 	if (v->gv_type != GVT_INST) {
 		graph_walk_dependencies(v, offline_subtree_leaves, arg);
@@ -5461,8 +5459,8 @@
 		break;
 	case GVT_GROUP:
 		/*
-		 * Skip all excluded and optional_all dependencies and decide
-		 * whether to offline the service based on restart_on attribute.
+		 * Skip all excluded dependencies and decide whether to offline
+		 * the service based on the restart_on attribute.
 		 */
 		if (is_depgrp_bypassed(v))
 			return (UU_WALK_NEXT);
