Print this page
7711 SMF: Finish implementing support for degraded state


1152                 (void) restarter_instance_update_states(local_handle, inst,
1153                     inst->ri_i.i_state, RESTARTER_STATE_NONE, RERR_NONE,
1154                     restarter_str_none);
1155                 goto out;
1156 
1157         case EINVAL:
1158         case ENOTSUP:
1159         default:
1160                 bad_error("libscf_fmri_get_instance", r);
1161         }
1162 
1163         inst->ri_m_inst = s_inst;
1164         inst->ri_mi_deleted = B_FALSE;
1165 
1166 retry:
1167         if (info->sf_method_type == METHOD_START)
1168                 log_transition(inst, START_REQUESTED);
1169 
1170         r = method_run(&inst, info->sf_method_type, &exit_code);
1171 
1172         if (r == 0 && exit_code == 0) {
1173                 /* Success! */
1174                 assert(inst->ri_i.i_next_state != RESTARTER_STATE_NONE);
1175 
1176                 /*
1177                  * When a stop method succeeds, remove the primary contract of
1178                  * the service, unless we're going to offline, in which case
1179                  * retain the contract so we can transfer inherited contracts to
1180                  * the replacement service.
1181                  */
1182 
1183                 if (info->sf_method_type == METHOD_STOP &&
1184                     inst->ri_i.i_primary_ctid != 0) {
1185                         if (inst->ri_i.i_next_state == RESTARTER_STATE_OFFLINE)
1186                                 inst->ri_i.i_primary_ctid_stopped = 1;
1187                         else
1188                                 method_remove_contract(inst, B_TRUE, B_TRUE);
1189                 }

1190                 /*










1191                  * We don't care whether the handle was rebound because this is
1192                  * the last thing we do with it.
1193                  */
1194                 (void) restarter_instance_update_states(local_handle, inst,
1195                     inst->ri_i.i_next_state, RESTARTER_STATE_NONE,
1196                     info->sf_event_type, info->sf_reason);
1197 
1198                 (void) update_fault_count(inst, FAULT_COUNT_RESET);
1199 
1200                 goto out;
1201         }
1202 
1203         /* Failure.  Retry or go to maintenance. */
1204 
1205         if (r != 0 && r != EAGAIN) {
1206                 retryable = B_FALSE;
1207         } else {
1208                 switch (exit_code) {
1209                 case SMF_EXIT_ERR_CONFIG:
1210                 case SMF_EXIT_ERR_NOSMF:




1152                 (void) restarter_instance_update_states(local_handle, inst,
1153                     inst->ri_i.i_state, RESTARTER_STATE_NONE, RERR_NONE,
1154                     restarter_str_none);
1155                 goto out;
1156 
1157         case EINVAL:
1158         case ENOTSUP:
1159         default:
1160                 bad_error("libscf_fmri_get_instance", r);
1161         }
1162 
1163         inst->ri_m_inst = s_inst;
1164         inst->ri_mi_deleted = B_FALSE;
1165 
1166 retry:
1167         if (info->sf_method_type == METHOD_START)
1168                 log_transition(inst, START_REQUESTED);
1169 
1170         r = method_run(&inst, info->sf_method_type, &exit_code);
1171 
1172         if (r == 0 && (exit_code == 0 || exit_code == SMF_EXIT_MON_DEGRADE)) {
1173                 /* Success! */
1174                 assert(inst->ri_i.i_next_state != RESTARTER_STATE_NONE);
1175 
1176                 /*
1177                  * When a stop method succeeds, remove the primary contract of
1178                  * the service, unless we're going to offline, in which case
1179                  * retain the contract so we can transfer inherited contracts to
1180                  * the replacement service.
1181                  */
1182 
1183                 if (info->sf_method_type == METHOD_STOP &&
1184                     inst->ri_i.i_primary_ctid != 0) {
1185                         if (inst->ri_i.i_next_state == RESTARTER_STATE_OFFLINE)
1186                                 inst->ri_i.i_primary_ctid_stopped = 1;
1187                         else
1188                                 method_remove_contract(inst, B_TRUE, B_TRUE);
1189                 }
1190 
1191                 /*
1192                  * When a start method returns with SMF_EXIT_MON_DEGRADE we
1193                  * transition the service into degraded.
1194                  */
1195                 if (info->sf_method_type == METHOD_START &&
1196                     exit_code == SMF_EXIT_MON_DEGRADE) {
1197                         inst->ri_i.i_next_state = RESTARTER_STATE_DEGRADED;
1198                         info->sf_reason = restarter_str_method_failed;
1199                 }
1200 
1201                 /*
1202                  * We don't care whether the handle was rebound because this is
1203                  * the last thing we do with it.
1204                  */
1205                 (void) restarter_instance_update_states(local_handle, inst,
1206                     inst->ri_i.i_next_state, RESTARTER_STATE_NONE,
1207                     info->sf_event_type, info->sf_reason);
1208 
1209                 (void) update_fault_count(inst, FAULT_COUNT_RESET);
1210 
1211                 goto out;
1212         }
1213 
1214         /* Failure.  Retry or go to maintenance. */
1215 
1216         if (r != 0 && r != EAGAIN) {
1217                 retryable = B_FALSE;
1218         } else {
1219                 switch (exit_code) {
1220                 case SMF_EXIT_ERR_CONFIG:
1221                 case SMF_EXIT_ERR_NOSMF: