--- old/usr/src/cmd/svc/startd/graph.c	2016-09-24 03:48:16.057228790 +0100
+++ new/usr/src/cmd/svc/startd/graph.c	2016-09-24 03:48:16.065123447 +0100
@@ -211,6 +211,10 @@
 	((v->gv_depgroup == DEPGRP_EXCLUDE_ALL) || \
 	(v->gv_restart < RERR_RESTART)))
 
+#define	is_inst_bypassed(v) ((v->gv_type == GVT_INST) && \
+	((v->gv_flags & GV_TODISABLE) || \
+	(v->gv_flags & GV_TOOFFLINE)))
+
 static uu_list_pool_t *graph_edge_pool, *graph_vertex_pool;
 static uu_list_t *dgraph;
 static pthread_mutex_t dgraph_lock;
@@ -1298,7 +1302,7 @@
 			satisfiable = B_TRUE;
 	}
 
-	return (!satbility || satisfiable ? 0 : -1);
+	return ((!satbility || satisfiable) ? 0 : -1);
 }
 
 /*
@@ -1337,21 +1341,15 @@
 				continue;
 
 			any_qualified = B_TRUE;
-			if (v->gv_state == RESTARTER_STATE_OFFLINE) {
+			if (v->gv_state == RESTARTER_STATE_OFFLINE ||
+			    v->gv_state == RESTARTER_STATE_DISABLED) {
 				/*
-				 * For offline dependencies, treat unsatisfiable
-				 * as satisfied.
+				 * For offline/disabled dependencies,
+				 * treat unsatisfiable as satisfied.
 				 */
 				i = dependency_satisfied(v, B_TRUE);
 				if (i == -1)
 					i = 1;
-			} else if (v->gv_state == RESTARTER_STATE_DISABLED) {
-				/*
-				 * If the instance is transitioning out of
-				 * disabled the dependency is temporarily
-				 * unsatisfied (not unsatisfiable).
-				 */
-				i = v->gv_flags & GV_ENABLED ? 0 : 1;
 			} else {
 				i = dependency_satisfied(v, satbility);
 			}
@@ -1546,27 +1544,35 @@
 		}
 
 		/*
-		 * Any vertex with the GV_TODISABLE flag set is guaranteed
-		 * to have its dependencies unsatisfiable.  Any vertex with
-		 * GV_TOOFFLINE may be satisfied after it transitions.
+		 * Vertices may be transitioning so we try to figure out if
+		 * the end state is likely to satisfy the dependency instead
+		 * of assuming the dependency is unsatisfied/unsatisfiable.
+		 *
+		 * Support for optional_all dependencies depends on us getting
+		 * this right because unsatisfiable dependencies are treated
+		 * as being satisfied.
 		 */
-		if (v->gv_flags & GV_TODISABLE)
-			return (-1);
-		if (v->gv_flags & GV_TOOFFLINE)
-			return (0);
-
 		switch (v->gv_state) {
 		case RESTARTER_STATE_ONLINE:
 		case RESTARTER_STATE_DEGRADED:
+			if (v->gv_flags & GV_TODISABLE)
+				return (-1);
+			if (v->gv_flags & GV_TOOFFLINE)
+				return (0);
 			return (1);
 
 		case RESTARTER_STATE_OFFLINE:
-			if (!satbility)
-				return (0);
+			if (!satbility || v->gv_flags & GV_TODISABLE)
+				return (satbility ? -1 : 0);
 			return (instance_satisfied(v, satbility) != -1 ?
 			    0 : -1);
 
 		case RESTARTER_STATE_DISABLED:
+			if (!satbility || !(v->gv_flags & GV_ENABLED))
+				return (satbility ? -1 : 0);
+			return (instance_satisfied(v, satbility) != -1 ?
+			    0 : -1);
+
 		case RESTARTER_STATE_MAINT:
 			return (-1);
 
@@ -1669,7 +1675,7 @@
 static int
 satbility_cb(graph_vertex_t *v, void *arg)
 {
-	if (v->gv_flags & GV_TOOFFLINE)
+	if (is_inst_bypassed(v))
 		return (UU_WALK_NEXT);
 
 	if (v->gv_type == GVT_INST)
@@ -1700,7 +1706,7 @@
 {
 	restarter_error_t err = (restarter_error_t)arg;
 
-	if (v->gv_flags & GV_TOOFFLINE)
+	if (is_inst_bypassed(v))
 		return;
 
 	switch (v->gv_type) {
@@ -1760,7 +1766,7 @@
 {
 	restarter_error_t err = (restarter_error_t)arg;
 
-	if (v->gv_flags & GV_TOOFFLINE)
+	if (is_inst_bypassed(v))
 		return;
 
 	switch (v->gv_type) {
@@ -1790,7 +1796,8 @@
 
 	case GVT_GROUP:
 		if (v->gv_depgroup == DEPGRP_EXCLUDE_ALL) {
-			graph_walk_dependents(v, propagate_start, NULL);
+			graph_walk_dependents(v, propagate_start,
+			    (void *)RERR_NONE);
 			break;
 		}
 
@@ -4358,7 +4365,7 @@
 			/*
 			 * Skip all excluded dependents and decide whether
 			 * to offline the service based on the restart_on
-			 * on attribute.
+			 * attribute.
 			 */
 			if (is_depgrp_bypassed(vv))
 				continue;
@@ -5410,8 +5417,8 @@
 
 	switch (v->gv_type) {
 	case GVT_INST:
-		/* If the instance is already disabled, skip it. */
-		if (!(v->gv_flags & GV_ENABLED))
+		/* If the instance is already offline, skip it. */
+		if (!inst_running(v))
 			return (UU_WALK_NEXT);
 
 		v->gv_flags |= GV_TOOFFLINE;
--- old/usr/src/cmd/svc/startd/transition.c	2016-09-24 03:48:16.321888217 +0100
+++ new/usr/src/cmd/svc/startd/transition.c	2016-09-24 03:48:16.326491628 +0100
@@ -163,6 +163,7 @@
     restarter_instance_state_t old_state, restarter_error_t rerr)
 {
 	int to_offline = v->gv_flags & GV_TOOFFLINE;
+	int to_disable = v->gv_flags & GV_TODISABLE;
 
 	v->gv_flags &= ~GV_TOOFFLINE;
 
@@ -173,7 +174,7 @@
 	 * remains offline until the disable process completes.
 	 */
 	if (v->gv_flags & GV_ENABLED) {
-		if (to_offline == 0)
+		if (to_offline == 0 && to_disable == 0)
 			graph_start_if_satisfied(v);
 	} else {
 		if (gt_running(old_state) && v->gv_post_disable_f)
