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;