Print this page
7267 SMF is fast and loose with optional dependencies (fixes)
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Albert Lee <trisk@omniti.com>
*** 209,218 ****
--- 209,222 ----
#define is_depgrp_bypassed(v) ((v->gv_type == GVT_GROUP) && \
((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;
/*
*** 1296,1306 ****
if (satbility && s == 0)
satisfiable = B_TRUE;
}
! return (!satbility || satisfiable ? 0 : -1);
}
/*
* An optional_all dependency only considers elements which are configured,
* enabled, and not in maintenance. If any are unsatisfied, then the dependency
--- 1300,1310 ----
if (satbility && s == 0)
satisfiable = B_TRUE;
}
! return ((!satbility || satisfiable) ? 0 : -1);
}
/*
* An optional_all dependency only considers elements which are configured,
* enabled, and not in maintenance. If any are unsatisfied, then the dependency
*** 1335,1359 ****
if (v->gv_state == RESTARTER_STATE_MAINT)
continue;
any_qualified = B_TRUE;
! if (v->gv_state == RESTARTER_STATE_OFFLINE) {
/*
! * For offline 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);
}
break;
--- 1339,1357 ----
if (v->gv_state == RESTARTER_STATE_MAINT)
continue;
any_qualified = B_TRUE;
! if (v->gv_state == RESTARTER_STATE_OFFLINE ||
! v->gv_state == RESTARTER_STATE_DISABLED) {
/*
! * For offline/disabled dependencies,
! * treat unsatisfiable as satisfied.
*/
i = dependency_satisfied(v, B_TRUE);
if (i == -1)
i = 1;
} else {
i = dependency_satisfied(v, satbility);
}
break;
*** 1544,1574 ****
}
return (-1);
}
/*
! * 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_TODISABLE)
return (-1);
if (v->gv_flags & GV_TOOFFLINE)
return (0);
-
- switch (v->gv_state) {
- case RESTARTER_STATE_ONLINE:
- case RESTARTER_STATE_DEGRADED:
return (1);
case RESTARTER_STATE_OFFLINE:
! if (!satbility)
! return (0);
return (instance_satisfied(v, satbility) != -1 ?
0 : -1);
case RESTARTER_STATE_DISABLED:
case RESTARTER_STATE_MAINT:
return (-1);
case RESTARTER_STATE_UNINIT:
return (0);
--- 1542,1580 ----
}
return (-1);
}
/*
! * 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.
*/
+ 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 || 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);
case RESTARTER_STATE_UNINIT:
return (0);
*** 1667,1677 ****
*/
/*ARGSUSED*/
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);
--- 1673,1683 ----
*/
/*ARGSUSED*/
static int
satbility_cb(graph_vertex_t *v, void *arg)
{
! if (is_inst_bypassed(v))
return (UU_WALK_NEXT);
if (v->gv_type == GVT_INST)
graph_start_if_satisfied(v);
*** 1698,1708 ****
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:
/* Restarter */
--- 1704,1714 ----
static void
propagate_start(graph_vertex_t *v, void *arg)
{
restarter_error_t err = (restarter_error_t)arg;
! if (is_inst_bypassed(v))
return;
switch (v->gv_type) {
case GVT_INST:
/* Restarter */
*** 1758,1768 ****
static void
propagate_stop(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:
/* Restarter */
--- 1764,1774 ----
static void
propagate_stop(graph_vertex_t *v, void *arg)
{
restarter_error_t err = (restarter_error_t)arg;
! if (is_inst_bypassed(v))
return;
switch (v->gv_type) {
case GVT_INST:
/* Restarter */
*** 1788,1798 ****
abort();
/* NOTREACHED */
case GVT_GROUP:
if (v->gv_depgroup == DEPGRP_EXCLUDE_ALL) {
! graph_walk_dependents(v, propagate_start, NULL);
break;
}
if (err == RERR_NONE || err > v->gv_restart)
break;
--- 1794,1805 ----
abort();
/* NOTREACHED */
case GVT_GROUP:
if (v->gv_depgroup == DEPGRP_EXCLUDE_ALL) {
! graph_walk_dependents(v, propagate_start,
! (void *)RERR_NONE);
break;
}
if (err == RERR_NONE || err > v->gv_restart)
break;
*** 4356,4366 ****
return (B_FALSE);
} else {
/*
* Skip all excluded dependents and decide whether
* to offline the service based on the restart_on
! * on attribute.
*/
if (is_depgrp_bypassed(vv))
continue;
/*
--- 4363,4373 ----
return (B_FALSE);
} else {
/*
* Skip all excluded dependents and decide whether
* to offline the service based on the restart_on
! * attribute.
*/
if (is_depgrp_bypassed(vv))
continue;
/*
*** 5408,5419 ****
if (v->gv_flags & GV_TOOFFLINE)
return (UU_WALK_NEXT);
switch (v->gv_type) {
case GVT_INST:
! /* If the instance is already disabled, skip it. */
! if (!(v->gv_flags & GV_ENABLED))
return (UU_WALK_NEXT);
v->gv_flags |= GV_TOOFFLINE;
log_framework(LOG_DEBUG, "%s added to subtree\n", v->gv_name);
break;
--- 5415,5426 ----
if (v->gv_flags & GV_TOOFFLINE)
return (UU_WALK_NEXT);
switch (v->gv_type) {
case GVT_INST:
! /* If the instance is already offline, skip it. */
! if (!inst_running(v))
return (UU_WALK_NEXT);
v->gv_flags |= GV_TOOFFLINE;
log_framework(LOG_DEBUG, "%s added to subtree\n", v->gv_name);
break;