--- old/usr/src/cmd/svc/startd/graph.c	2016-07-31 22:40:26.800211369 +0100
+++ new/usr/src/cmd/svc/startd/graph.c	2016-07-31 22:40:26.805337541 +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;
@@ -1328,17 +1328,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 +1350,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,17 +1379,12 @@
 				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) {
@@ -1406,7 +1397,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);
 				}
@@ -1608,11 +1599,14 @@
 		}
 
 		/*
-		 * Any vertex with the GV_TOOFFLINE flag set is guaranteed
-		 * to have its dependencies unsatisfiable.
+		 * 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.
 		 */
-		if (v->gv_flags & GV_TOOFFLINE)
+		if (v->gv_flags & GV_TODISABLE)
 			return (-1);
+		if (v->gv_flags & GV_TOOFFLINE)
+			return (0);
 
 		switch (v->gv_state) {
 		case RESTARTER_STATE_ONLINE:
@@ -1728,6 +1722,9 @@
 static int
 satbility_cb(graph_vertex_t *v, void *arg)
 {
+	if (v->gv_flags & GV_TOOFFLINE)
+		return (UU_WALK_NEXT);
+
 	if (v->gv_type == GVT_INST)
 		graph_start_if_satisfied(v);
 
@@ -1742,13 +1739,34 @@
 
 static void propagate_stop(graph_vertex_t *, void *);
 
-/* ARGSUSED */
+/*
+ * propagate_start()
+ *
+ * This function is used to propagate a start event to the dependents of the
+ * given vertex.  Any dependents that are offline but have their dependencies
+ * satisfied are started.  Any dependents that are online and have restart_on
+ * set to "restart" or "refresh" are restarted because their dependencies have
+ * just changed.  This only happens with optional_all dependencies.
+ */
 static void
 propagate_start(graph_vertex_t *v, void *arg)
 {
+	restarter_error_t err = (restarter_error_t)arg;
+
+	if (v->gv_flags & GV_TOOFFLINE)
+		return;
+
 	switch (v->gv_type) {
 	case GVT_INST:
-		graph_start_if_satisfied(v);
+		/* Restarter */
+		if (inst_running(v)) {
+			if (err == RERR_RESTART || err == RERR_REFRESH) {
+				vertex_send_event(v,
+				    RESTARTER_EVENT_TYPE_STOP_RESET);
+			}
+		} else {
+			graph_start_if_satisfied(v);
+		}
 		break;
 
 	case GVT_GROUP:
@@ -1757,10 +1775,11 @@
 			    (void *)RERR_RESTART);
 			break;
 		}
+		err = v->gv_restart;
 		/* FALLTHROUGH */
 
 	case GVT_SVC:
-		graph_walk_dependents(v, propagate_start, NULL);
+		graph_walk_dependents(v, propagate_start, (void *)err);
 		break;
 
 	case GVT_FILE:
@@ -1780,13 +1799,23 @@
 	}
 }
 
+/*
+ * propagate_stop()
+ *
+ * This function is used to propagate a stop event to the dependencies of the
+ * given vertex.  Any dependencies that are online (or in degraded state) with
+ * the restart_on property set to "restart" or "refresh" will be restarted as
+ * their dependencies have just changed.  This only happens for optional_all
+ * dependencies.
+ */
 static void
 propagate_stop(graph_vertex_t *v, void *arg)
 {
-	graph_edge_t *e;
-	graph_vertex_t *svc;
 	restarter_error_t err = (restarter_error_t)arg;
 
+	if (v->gv_flags & GV_TOOFFLINE)
+		return;
+
 	switch (v->gv_type) {
 	case GVT_INST:
 		/* Restarter */
@@ -1821,19 +1850,7 @@
 		if (err == RERR_NONE || err > v->gv_restart)
 			break;
 
-		assert(uu_list_numnodes(v->gv_dependents) == 1);
-		e = uu_list_first(v->gv_dependents);
-		svc = e->ge_vertex;
-
-		if (inst_running(svc)) {
-			if (err == RERR_RESTART || err == RERR_REFRESH) {
-				vertex_send_event(svc,
-				    RESTARTER_EVENT_TYPE_STOP_RESET);
-			} else {
-				vertex_send_event(svc,
-				    RESTARTER_EVENT_TYPE_STOP);
-			}
-		}
+		graph_walk_dependents(v, propagate_stop, arg);
 		break;
 
 	default:
@@ -4398,9 +4415,9 @@
 				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 dependents and decide whether
+			 * to offline the service based on the restart_on
+			 * on attribute.
 			 */
 			if (is_depgrp_bypassed(vv))
 				continue;
@@ -4965,7 +4982,7 @@
 	if (type == PROPAGATE_STOP) {
 		graph_walk_dependents(v, propagate_stop, (void *)rerr);
 	} else if (type == PROPAGATE_START || type == PROPAGATE_SAT) {
-		graph_walk_dependents(v, propagate_start, NULL);
+		graph_walk_dependents(v, propagate_start, (void *)RERR_NONE);
 
 		if (type == PROPAGATE_SAT)
 			propagate_satbility(v);
@@ -5036,7 +5053,7 @@
 	v->gv_flags &= ~GV_CONFIGURED;
 	v->gv_flags &= ~GV_DEATHROW;
 
-	graph_walk_dependents(v, propagate_start, NULL);
+	graph_walk_dependents(v, propagate_start, (void *)RERR_NONE);
 	propagate_satbility(v);
 
 	/*
@@ -5461,8 +5478,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 dependents and decide whether to offline
+		 * the service based on the restart_on attribute.
 		 */
 		if (is_depgrp_bypassed(v))
 			return (UU_WALK_NEXT);
