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

@@ -20,10 +20,11 @@
  */
 
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright 2017 RackTop Systems.
  */
 
 /*
  * restarter.c - service manipulation
  *

@@ -1745,15 +1746,67 @@
 
         scf_snapshot_destroy(snap);
         scf_instance_destroy(inst);
 }
 
+static void
+degrade_instance(scf_handle_t *h, restarter_inst_t *rip, restarter_str_t reason)
+{
+        scf_instance_t *scf_inst = NULL;
+
+        assert(MUTEX_HELD(&rip->ri_lock));
+
+        log_instance(rip, B_TRUE, "Marking degraded due to %s.",
+            restarter_get_str_short(reason));
+        log_framework(LOG_DEBUG, "%s: marking degraded due to %s.\n",
+            rip->ri_i.i_fmri, restarter_get_str_short(reason));
+
+        /* Services that aren't online are ignored */
+        if (rip->ri_i.i_state != RESTARTER_STATE_ONLINE) {
+                log_framework(LOG_DEBUG,
+                    "%s: degrade_instance -> is not online\n",
+                    rip->ri_i.i_fmri);
+                return;
+        }
+
+        /*
+         * If reason state is restarter_str_service_request and
+         * restarter_actions/auxiliary_fmri property is set with a valid fmri,
+         * copy the fmri to restarter/auxiliary_fmri so svcs -x can use.
+         */
+        if (reason == restarter_str_service_request &&
+            libscf_fmri_get_instance(h, rip->ri_i.i_fmri, &scf_inst) == 0) {
+                if (restarter_inst_validate_ractions_aux_fmri(scf_inst) == 0) {
+                        if (restarter_inst_set_aux_fmri(scf_inst))
+                                log_framework(LOG_DEBUG, "%s: "
+                                    "restarter_inst_set_aux_fmri failed: ",
+                                    rip->ri_i.i_fmri);
+                } else {
+                        log_framework(LOG_DEBUG, "%s: "
+                            "restarter_inst_validate_ractions_aux_fmri "
+                            "failed: ", rip->ri_i.i_fmri);
+
+                        if (restarter_inst_reset_aux_fmri(scf_inst))
+                                log_framework(LOG_DEBUG, "%s: "
+                                    "restarter_inst_reset_aux_fmri failed: ",
+                                    rip->ri_i.i_fmri);
+                }
+                scf_instance_destroy(scf_inst);
+        }
+
+        (void) restarter_instance_update_states(h, rip,
+            RESTARTER_STATE_DEGRADED, RESTARTER_STATE_NONE, RERR_NONE, reason);
+
+        log_transition(rip, DEGRADE_REQUESTED);
+}
+
 const char *event_names[] = { "INVALID", "ADD_INSTANCE", "REMOVE_INSTANCE",
-        "ENABLE", "DISABLE", "ADMIN_DEGRADED", "ADMIN_REFRESH",
-        "ADMIN_RESTART", "ADMIN_MAINT_OFF", "ADMIN_MAINT_ON",
-        "ADMIN_MAINT_ON_IMMEDIATE", "STOP", "START", "DEPENDENCY_CYCLE",
-        "INVALID_DEPENDENCY", "ADMIN_DISABLE", "STOP_RESET"
+        "ENABLE", "DISABLE", "ADMIN_RESTORE", "ADMIN_DEGRADED",
+        "ADMIN_DEGRADE_IMMEDIATE", "ADMIN_REFRESH", "ADMIN_RESTART",
+        "ADMIN_MAINT_OFF", "ADMIN_MAINT_ON", "ADMIN_MAINT_ON_IMMEDIATE",
+        "STOP", "START", "DEPENDENCY_CYCLE", "INVALID_DEPENDENCY",
+        "ADMIN_DISABLE", "STOP_RESET"
 };
 
 /*
  * void *restarter_process_events()
  *

@@ -1864,15 +1917,20 @@
                 case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
                         refresh_instance(h, inst);
                         break;
 
                 case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
-                        log_framework(LOG_WARNING, "Restarter: "
-                            "%s command (for %s) unimplemented.\n",
-                            event_names[event->riq_type], inst->ri_i.i_fmri);
+                case RESTARTER_EVENT_TYPE_ADMIN_DEGRADE_IMMEDIATE:
+                        if (event_from_tty(h, inst) == 0)
+                                degrade_instance(h, inst,
+                                    restarter_str_service_request);
+                        else
+                                degrade_instance(h, inst,
+                                    restarter_str_administrative_request);
                         break;
 
+                case RESTARTER_EVENT_TYPE_ADMIN_RESTORE:
                 case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
                         if (!instance_started(inst)) {
                                 log_framework(LOG_DEBUG, "Restarter: "
                                     "Not restarting %s; not running.\n",
                                     inst->ri_i.i_fmri);

@@ -1945,10 +2003,12 @@
         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
         case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
         case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
+        case RESTARTER_EVENT_TYPE_ADMIN_DEGRADE_IMMEDIATE:
+        case RESTARTER_EVENT_TYPE_ADMIN_RESTORE:
         case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
                 return (1);
         default:
                 return (0);
         }