# HG changeset patch # User lianep # Date 1152580326 25200 # Node ID 73c7b85b6be0a1c81531765ee2ce36d2b9a84b1b # Parent 011565c76d7c2a225589e2f083323ea77539d732 6440500 no login prompt (hang) when filesystem/local fails diff -r 011565c76d7c -r 73c7b85b6be0 usr/src/cmd/svc/startd/graph.c --- a/usr/src/cmd/svc/startd/graph.c Mon Jul 10 17:57:49 2006 -0700 +++ b/usr/src/cmd/svc/startd/graph.c Mon Jul 10 18:12:06 2006 -0700 @@ -1590,7 +1590,7 @@ * instance transitions between offline -> online, or from !running -> * maintenance, as well as when an instance is removed from the graph. * - * We have to walk the all dependents, since optional_all dependencies several + * We have to walk all the dependents, since optional_all dependencies several * levels up could become (un)satisfied, instead of unsatisfiable. For example, * * +-----+ optional_all +-----+ require_all +-----+ @@ -4006,7 +4006,7 @@ old_state = v->gv_state; v->gv_state = state; - err = gt_transition(h, v, serr, old_state, state); + err = gt_transition(h, v, serr, old_state); MUTEX_UNLOCK(&dgraph_lock); return (err); @@ -4068,31 +4068,34 @@ } /* - * Propagate a start, stop or maintenance event. Use the - * RESTARTER_EVENT_TYPE_START, RESTARTER_EVENT_TYPE_STOP, and - * RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON respectively to represent those - * events. + * Propagate a start, stop event, or a satisfiability event. * - * For maintenance, we need to propagate_satbility() as well to - * take care of walking further down the graph than just the direct - * dependents. + * PROPAGATE_START and PROPAGATE_STOP simply propagate the transition event + * to direct dependents. PROPAGATE_SAT propagates a start then walks the + * full dependent graph to check for newly satisfied nodes. This is + * necessary for cases when non-direct dependents may be effected but direct + * dependents may not (e.g. for optional_all evaluations, see the + * propagate_satbility() comments). + * + * PROPAGATE_SAT should be used whenever a non-running service moves into + * a state which can satisfy optional dependencies, like disabled or + * maintenance. */ void -graph_transition_propagate(graph_vertex_t *v, restarter_event_type_t propagate, +graph_transition_propagate(graph_vertex_t *v, propagate_event_t type, restarter_error_t rerr) { - if (propagate == RESTARTER_EVENT_TYPE_STOP) { + if (type == PROPAGATE_STOP) { graph_walk_dependents(v, propagate_stop, (void *)rerr); - } else if (propagate == RESTARTER_EVENT_TYPE_START || - propagate == RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON) { + } else if (type == PROPAGATE_START || type == PROPAGATE_SAT) { graph_walk_dependents(v, propagate_start, NULL); - if (propagate == RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON) + if (type == PROPAGATE_SAT) propagate_satbility(v); } else { #ifndef NDEBUG - uu_warn("%s:%d: Unexpected propagate value %d.\n", __FILE__, - __LINE__, propagate); + uu_warn("%s:%d: Unexpected type value %d.\n", __FILE__, + __LINE__, type); #endif abort(); } diff -r 011565c76d7c -r 73c7b85b6be0 usr/src/cmd/svc/startd/startd.h --- a/usr/src/cmd/svc/startd/startd.h Mon Jul 10 17:57:49 2006 -0700 +++ b/usr/src/cmd/svc/startd/startd.h Mon Jul 10 18:12:06 2006 -0700 @@ -274,6 +274,12 @@ METHOD_RESTART_OTHER } method_restart_t; +typedef enum { + PROPAGATE_START, + PROPAGATE_STOP, + PROPAGATE_SAT +} propagate_event_t; + /* * Graph representation. */ @@ -587,7 +593,7 @@ graph_vertex_t *v, int was_running); void graph_transition_sulogin(restarter_instance_state_t, restarter_instance_state_t); -void graph_transition_propagate(graph_vertex_t *, restarter_event_type_t, +void graph_transition_propagate(graph_vertex_t *, propagate_event_t, restarter_error_t); /* libscf.c - common */ @@ -717,7 +723,7 @@ /* transition.c */ int gt_transition(scf_handle_t *, graph_vertex_t *, restarter_error_t, - restarter_instance_state_t, restarter_instance_state_t); + restarter_instance_state_t); /* utmpx.c */ void utmpx_init(void); diff -r 011565c76d7c -r 73c7b85b6be0 usr/src/cmd/svc/startd/transition.c --- a/usr/src/cmd/svc/startd/transition.c Mon Jul 10 17:57:49 2006 -0700 +++ b/usr/src/cmd/svc/startd/transition.c Mon Jul 10 18:12:06 2006 -0700 @@ -96,7 +96,7 @@ log_framework(LOG_DEBUG, "Propagating stop of %s.\n", v->gv_name); - graph_transition_propagate(v, RESTARTER_EVENT_TYPE_STOP, rerr); + graph_transition_propagate(v, PROPAGATE_STOP, rerr); } graph_transition_sulogin(RESTARTER_STATE_UNINIT, old_state); @@ -109,16 +109,22 @@ { vertex_subgraph_dependencies_shutdown(h, v, gt_running(old_state)); + /* + * If the service was running, propagate a stop event. If the + * service was not running the maintenance transition may satisfy + * optional dependencies and should be propagated to determine + * whether new dependents are satisfiable. + */ if (gt_running(old_state)) { - log_framework(LOG_DEBUG, "Propagating stop of %s.\n", - v->gv_name); + log_framework(LOG_DEBUG, "Propagating maintenance (stop) of " + "%s.\n", v->gv_name); - graph_transition_propagate(v, RESTARTER_EVENT_TYPE_STOP, rerr); - } else if (v->gv_state == RESTARTER_STATE_MAINT) { + graph_transition_propagate(v, PROPAGATE_STOP, rerr); + } else { log_framework(LOG_DEBUG, "Propagating maintenance of %s.\n", v->gv_name); - graph_transition_propagate(v, RESTARTER_EVENT_TYPE_START, rerr); + graph_transition_propagate(v, PROPAGATE_SAT, rerr); } graph_transition_sulogin(RESTARTER_STATE_MAINT, old_state); @@ -147,7 +153,7 @@ log_framework(LOG_DEBUG, "Propagating stop of %s.\n", v->gv_name); - graph_transition_propagate(v, RESTARTER_EVENT_TYPE_STOP, rerr); + graph_transition_propagate(v, PROPAGATE_STOP, rerr); } graph_transition_sulogin(RESTARTER_STATE_OFFLINE, old_state); @@ -172,21 +178,22 @@ } /* - * If the service was running, propagate this as a stop. - * Otherwise, we treat other transitions as a start propagate, - * since they can satisfy optional_all dependencies. + * If the service was running, propagate this as a stop. If the + * service was not running the disabled transition may satisfy + * optional dependencies and should be propagated to determine + * whether new dependents are satisfiable. */ if (gt_running(old_state)) { log_framework(LOG_DEBUG, "Propagating stop of %s.\n", v->gv_name); - graph_transition_propagate(v, RESTARTER_EVENT_TYPE_STOP, rerr); + graph_transition_propagate(v, PROPAGATE_STOP, rerr); - } else if (v->gv_state == RESTARTER_STATE_DISABLED) { + } else { log_framework(LOG_DEBUG, "Propagating disable of %s.\n", v->gv_name); - graph_transition_propagate(v, RESTARTER_EVENT_TYPE_START, rerr); + graph_transition_propagate(v, PROPAGATE_SAT, rerr); } graph_transition_sulogin(RESTARTER_STATE_DISABLED, old_state); @@ -239,15 +246,14 @@ log_framework(LOG_DEBUG, "Propagating start of %s.\n", v->gv_name); - graph_transition_propagate(v, - RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON, rerr); + graph_transition_propagate(v, PROPAGATE_START, rerr); } else if (rerr == RERR_REFRESH) { /* For refresh we'll get a message sans state change */ log_framework(LOG_DEBUG, "Propagating refresh of %s.\n", v->gv_name); - graph_transition_propagate(v, RESTARTER_EVENT_TYPE_STOP, rerr); + graph_transition_propagate(v, PROPAGATE_STOP, rerr); } return (0); @@ -286,10 +292,13 @@ * state machine. It can return: * 0 success * ECONNABORTED repository connection aborted + * + * v->gv_state should be set to the state we're transitioning to before + * calling this function. */ int gt_transition(scf_handle_t *h, graph_vertex_t *v, restarter_error_t rerr, - restarter_instance_state_t old_state, restarter_instance_state_t new_state) + restarter_instance_state_t old_state) { int err = 0; @@ -302,7 +311,7 @@ /* * Now call the appropriate gt_enter function for the new state. */ - switch (new_state) { + switch (v->gv_state) { case RESTARTER_STATE_UNINIT: err = gt_enter_uninit(h, v, old_state, rerr); break; @@ -328,10 +337,10 @@ break; default: - /* Shouldn't have been passed an invalid state. */ + /* Shouldn't be in an invalid state. */ #ifndef NDEBUG uu_warn("%s:%d: Uncaught case %d.\n", __FILE__, __LINE__, - new_state); + v->gv_state); #endif abort(); }