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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/svc/startd/restarter.c
          +++ new/usr/src/cmd/svc/startd/restarter.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       25 + * Copyright 2017 RackTop Systems.
  25   26   */
  26   27  
  27   28  /*
  28   29   * restarter.c - service manipulation
  29   30   *
  30   31   * This component manages services whose restarter is svc.startd, the standard
  31   32   * restarter.  It translates restarter protocol events from the graph engine
  32   33   * into actions on processes, as a delegated restarter would do.
  33   34   *
  34   35   * The master restarter manages a number of always-running threads:
↓ open down ↓ 1705 lines elided ↑ open up ↑
1740 1741  
1741 1742                  assert(rip->ri_method_thread == 0);
1742 1743                  rip->ri_method_thread =
1743 1744                      startd_thread_create(method_thread, info);
1744 1745          }
1745 1746  
1746 1747          scf_snapshot_destroy(snap);
1747 1748          scf_instance_destroy(inst);
1748 1749  }
1749 1750  
     1751 +static void
     1752 +degrade_instance(scf_handle_t *h, restarter_inst_t *rip, restarter_str_t reason)
     1753 +{
     1754 +        scf_instance_t *scf_inst = NULL;
     1755 +
     1756 +        assert(MUTEX_HELD(&rip->ri_lock));
     1757 +
     1758 +        log_instance(rip, B_TRUE, "Marking degraded due to %s.",
     1759 +            restarter_get_str_short(reason));
     1760 +        log_framework(LOG_DEBUG, "%s: marking degraded due to %s.\n",
     1761 +            rip->ri_i.i_fmri, restarter_get_str_short(reason));
     1762 +
     1763 +        /* Services that aren't online are ignored */
     1764 +        if (rip->ri_i.i_state != RESTARTER_STATE_ONLINE) {
     1765 +                log_framework(LOG_DEBUG,
     1766 +                    "%s: degrade_instance -> is not online\n",
     1767 +                    rip->ri_i.i_fmri);
     1768 +                return;
     1769 +        }
     1770 +
     1771 +        /*
     1772 +         * If reason state is restarter_str_service_request and
     1773 +         * restarter_actions/auxiliary_fmri property is set with a valid fmri,
     1774 +         * copy the fmri to restarter/auxiliary_fmri so svcs -x can use.
     1775 +         */
     1776 +        if (reason == restarter_str_service_request &&
     1777 +            libscf_fmri_get_instance(h, rip->ri_i.i_fmri, &scf_inst) == 0) {
     1778 +                if (restarter_inst_validate_ractions_aux_fmri(scf_inst) == 0) {
     1779 +                        if (restarter_inst_set_aux_fmri(scf_inst))
     1780 +                                log_framework(LOG_DEBUG, "%s: "
     1781 +                                    "restarter_inst_set_aux_fmri failed: ",
     1782 +                                    rip->ri_i.i_fmri);
     1783 +                } else {
     1784 +                        log_framework(LOG_DEBUG, "%s: "
     1785 +                            "restarter_inst_validate_ractions_aux_fmri "
     1786 +                            "failed: ", rip->ri_i.i_fmri);
     1787 +
     1788 +                        if (restarter_inst_reset_aux_fmri(scf_inst))
     1789 +                                log_framework(LOG_DEBUG, "%s: "
     1790 +                                    "restarter_inst_reset_aux_fmri failed: ",
     1791 +                                    rip->ri_i.i_fmri);
     1792 +                }
     1793 +                scf_instance_destroy(scf_inst);
     1794 +        }
     1795 +
     1796 +        (void) restarter_instance_update_states(h, rip,
     1797 +            RESTARTER_STATE_DEGRADED, RESTARTER_STATE_NONE, RERR_NONE, reason);
     1798 +
     1799 +        log_transition(rip, DEGRADE_REQUESTED);
     1800 +}
     1801 +
1750 1802  const char *event_names[] = { "INVALID", "ADD_INSTANCE", "REMOVE_INSTANCE",
1751      -        "ENABLE", "DISABLE", "ADMIN_DEGRADED", "ADMIN_REFRESH",
1752      -        "ADMIN_RESTART", "ADMIN_MAINT_OFF", "ADMIN_MAINT_ON",
1753      -        "ADMIN_MAINT_ON_IMMEDIATE", "STOP", "START", "DEPENDENCY_CYCLE",
1754      -        "INVALID_DEPENDENCY", "ADMIN_DISABLE", "STOP_RESET"
     1803 +        "ENABLE", "DISABLE", "ADMIN_RESTORE", "ADMIN_DEGRADED",
     1804 +        "ADMIN_DEGRADE_IMMEDIATE", "ADMIN_REFRESH", "ADMIN_RESTART",
     1805 +        "ADMIN_MAINT_OFF", "ADMIN_MAINT_ON", "ADMIN_MAINT_ON_IMMEDIATE",
     1806 +        "STOP", "START", "DEPENDENCY_CYCLE", "INVALID_DEPENDENCY",
     1807 +        "ADMIN_DISABLE", "STOP_RESET"
1755 1808  };
1756 1809  
1757 1810  /*
1758 1811   * void *restarter_process_events()
1759 1812   *
1760 1813   *   Called in a separate thread to process the events on an instance's
1761 1814   *   queue.  Empties the queue completely, and tries to keep the thread
1762 1815   *   around for a little while after the queue is empty to save on
1763 1816   *   startup costs.
1764 1817   */
↓ open down ↓ 94 lines elided ↑ open up ↑
1859 1912                  case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1860 1913                          unmaintain_instance(h, inst, RUNMAINT_CLEAR);
1861 1914                          reset_start_times(inst);
1862 1915                          break;
1863 1916  
1864 1917                  case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1865 1918                          refresh_instance(h, inst);
1866 1919                          break;
1867 1920  
1868 1921                  case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1869      -                        log_framework(LOG_WARNING, "Restarter: "
1870      -                            "%s command (for %s) unimplemented.\n",
1871      -                            event_names[event->riq_type], inst->ri_i.i_fmri);
     1922 +                case RESTARTER_EVENT_TYPE_ADMIN_DEGRADE_IMMEDIATE:
     1923 +                        if (event_from_tty(h, inst) == 0)
     1924 +                                degrade_instance(h, inst,
     1925 +                                    restarter_str_service_request);
     1926 +                        else
     1927 +                                degrade_instance(h, inst,
     1928 +                                    restarter_str_administrative_request);
1872 1929                          break;
1873 1930  
     1931 +                case RESTARTER_EVENT_TYPE_ADMIN_RESTORE:
1874 1932                  case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1875 1933                          if (!instance_started(inst)) {
1876 1934                                  log_framework(LOG_DEBUG, "Restarter: "
1877 1935                                      "Not restarting %s; not running.\n",
1878 1936                                      inst->ri_i.i_fmri);
1879 1937                          } else {
1880 1938                                  /*
1881 1939                                   * Stop the instance.  If it can be restarted,
1882 1940                                   * the graph engine will send a new event.
1883 1941                                   */
↓ open down ↓ 56 lines elided ↑ open up ↑
1940 1998  
1941 1999  static int
1942 2000  is_admin_event(restarter_event_type_t t) {
1943 2001  
1944 2002          switch (t) {
1945 2003          case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1946 2004          case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1947 2005          case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1948 2006          case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1949 2007          case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
     2008 +        case RESTARTER_EVENT_TYPE_ADMIN_DEGRADE_IMMEDIATE:
     2009 +        case RESTARTER_EVENT_TYPE_ADMIN_RESTORE:
1950 2010          case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1951 2011                  return (1);
1952 2012          default:
1953 2013                  return (0);
1954 2014          }
1955 2015  }
1956 2016  
1957 2017  static void
1958 2018  restarter_queue_event(restarter_inst_t *ri, restarter_protocol_event_t *e)
1959 2019  {
↓ open down ↓ 647 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX