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; }