Print this page
7246 SMF stops dependents in the wrong order
7267 SMF is fast and loose with optional dependencies
*** 20,29 ****
--- 20,30 ----
*/
/*
* 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.
*/
/*
* graph.c - master restarter graph engine
*
*** 205,215 ****
(state) == RESTARTER_STATE_DEGRADED || \
(state) == RESTARTER_STATE_OFFLINE)
#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;
static uu_list_t *dgraph;
static pthread_mutex_t dgraph_lock;
--- 206,215 ----
*** 303,313 ****
static char target_milestone_as_runlevel(void);
static void graph_runlevel_changed(char rl, int online);
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()
* This function can compare either int *id or * graph_vertex_t *gv
* values, as the vertex id is always the first element of a
--- 303,312 ----
*** 1326,1346 ****
edge = uu_list_next(groupv->gv_dependencies, edge)) {
v = edge->ge_vertex;
switch (v->gv_type) {
case GVT_INST:
! /* Skip missing or disabled instances */
! if ((v->gv_flags & (GV_CONFIGURED | GV_ENABLED)) !=
! (GV_CONFIGURED | GV_ENABLED))
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) {
/*
* For offline dependencies, treat unsatisfiable
* as satisfied.
--- 1325,1341 ----
edge = uu_list_next(groupv->gv_dependencies, edge)) {
v = edge->ge_vertex;
switch (v->gv_type) {
case GVT_INST:
! /* Skip missing instances */
! if ((v->gv_flags & GV_CONFIGURED) == 0)
continue;
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.
*** 1352,1362 ****
/*
* The service is enabled, but hasn't
* transitioned out of disabled yet. Treat it
* as unsatisfied (not unsatisfiable).
*/
! i = 0;
} else {
i = dependency_satisfied(v, satbility);
}
break;
--- 1347,1357 ----
/*
* The service is enabled, but hasn't
* transitioned out of disabled yet. Treat it
* as unsatisfied (not unsatisfiable).
*/
! i = v->gv_flags & GV_ENABLED ? 0 : 1;
} else {
i = dependency_satisfied(v, satbility);
}
break;
*** 1381,1414 ****
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 | GV_ENABLED)) !=
! (GV_CONFIGURED | GV_ENABLED))
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
* unsatisfiable as satisfied.
*/
i = dependency_satisfied(v2, B_TRUE);
if (i == -1)
i = 1;
} else if (v2->gv_state ==
RESTARTER_STATE_DISABLED) {
! i = 0;
} else {
i = dependency_satisfied(v2, satbility);
}
if (i == 1) {
--- 1376,1403 ----
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;
if (v2->gv_state == RESTARTER_STATE_MAINT)
continue;
svc_any_qualified = B_TRUE;
if (v2->gv_state == RESTARTER_STATE_OFFLINE) {
/*
* For offline dependencies, treat
* unsatisfiable as satisfied.
*/
i = dependency_satisfied(v2, B_TRUE);
if (i == -1)
i = 1;
} else if (v2->gv_state ==
RESTARTER_STATE_DISABLED) {
! i = v2->gv_flags & GV_ENABLED ? 0 : 1;
} else {
i = dependency_satisfied(v2, satbility);
}
if (i == 1) {
*** 4373,4383 ****
/*
* Returns true only if none of this service's dependents are 'up' -- online
* 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
insubtree_dependents_down(graph_vertex_t *v)
{
graph_vertex_t *vv;
graph_edge_t *e;
--- 4362,4372 ----
/*
* Returns true only if none of this service's dependents are 'up' -- online
* or degraded (offline is considered down in this situation). This function
* is somehow similar to is_nonsubgraph_leaf() but works on subtrees.
*/
! boolean_t
insubtree_dependents_down(graph_vertex_t *v)
{
graph_vertex_t *vv;
graph_edge_t *e;
*** 4389,4408 ****
if (vv->gv_type == GVT_INST) {
if ((vv->gv_flags & GV_CONFIGURED) == 0)
continue;
if ((vv->gv_flags & GV_TOOFFLINE) == 0)
! continue;
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.
*/
if (is_depgrp_bypassed(vv))
continue;
/*
--- 4378,4397 ----
if (vv->gv_type == GVT_INST) {
if ((vv->gv_flags & GV_CONFIGURED) == 0)
continue;
if ((vv->gv_flags & GV_TOOFFLINE) == 0)
! return (B_FALSE);
if ((vv->gv_state == RESTARTER_STATE_ONLINE) ||
(vv->gv_state == RESTARTER_STATE_DEGRADED))
return (B_FALSE);
} else {
/*
! * 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;
/*
*** 4560,4569 ****
--- 4549,4567 ----
void
offline_subtree_leaves(graph_vertex_t *v, void *arg)
{
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);
return;
}
*** 5459,5470 ****
v->gv_flags |= GV_TOOFFLINE;
log_framework(LOG_DEBUG, "%s added to subtree\n", v->gv_name);
break;
case GVT_GROUP:
/*
! * Skip all excluded and optional_all dependencies and decide
! * whether to offline the service based on restart_on attribute.
*/
if (is_depgrp_bypassed(v))
return (UU_WALK_NEXT);
break;
}
--- 5457,5468 ----
v->gv_flags |= GV_TOOFFLINE;
log_framework(LOG_DEBUG, "%s added to subtree\n", v->gv_name);
break;
case GVT_GROUP:
/*
! * 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);
break;
}