Print this page
    
7711 SMF: Finish implementing support for degraded state
    
      
        | Split | Close | 
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/svc/startd/startd.h
          +++ new/usr/src/cmd/svc/startd/startd.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  
    | ↓ 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) 2015, Joyent, Inc. All rights reserved.
       25 + * Copyright 2017 RackTop Systems.
  25   26   */
  26   27  
  27   28  #ifndef _STARTD_H
  28   29  #define _STARTD_H
  29   30  
  30   31  #include <sys/time.h>
  31   32  #include <librestart.h>
  32   33  #include <librestart_priv.h>
  33   34  #include <libscf.h>
  34   35  #include <libsysevent.h>
  35   36  #include <libuutil.h>
  36   37  #include <pthread.h>
  37   38  #include <synch.h>
  38   39  #include <stdio.h>
  39   40  #include <syslog.h>
  40   41  #include <umem.h>
  41   42  
  42   43  #ifdef  __cplusplus
  43   44  extern "C" {
  44   45  #endif
  45   46  
  46   47  /*
  47   48   * We want MUTEX_HELD, but we also want pthreads.  So we're stuck with this
  48   49   * for the native build, at least until the build machines can catch up
  49   50   * with the latest version of MUTEX_HELD() in <synch.h>.
  50   51   */
  51   52  #if defined(NATIVE_BUILD)
  52   53  #undef  MUTEX_HELD
  53   54  #define MUTEX_HELD(m)           _mutex_held((mutex_t *)(m))
  54   55  #endif
  55   56  
  56   57  #ifndef NDEBUG
  57   58  
  58   59  #define MUTEX_LOCK(mp)  {                                               \
  59   60          int err;                                                        \
  60   61          if ((err = pthread_mutex_lock((mp))) != 0) {                    \
  61   62                  (void) fprintf(stderr,                                  \
  62   63                      "pthread_mutex_lock() failed on %s:%d: %s\n",       \
  63   64                      __FILE__, __LINE__, strerror(err));                 \
  64   65                  abort();                                                \
  65   66          }                                                               \
  66   67  }
  67   68  
  68   69  #define MUTEX_UNLOCK(mp)        {                                       \
  69   70          int err;                                                        \
  70   71          if ((err = pthread_mutex_unlock((mp))) != 0) {                  \
  71   72                  (void) fprintf(stderr,                                  \
  72   73                      "pthread_mutex_unlock() failed on %s:%d: %s\n",     \
  73   74                      __FILE__, __LINE__, strerror(err));                 \
  74   75                  abort();                                                \
  75   76          }                                                               \
  76   77  }
  77   78  
  78   79  #else
  79   80  
  80   81  #define MUTEX_LOCK(mp)          (void) pthread_mutex_lock((mp))
  81   82  #define MUTEX_UNLOCK(mp)        (void) pthread_mutex_unlock((mp))
  82   83  
  83   84  #endif
  84   85  
  85   86  #define bad_error(func, err)                                    \
  86   87          uu_panic("%s:%d: %s() failed with unexpected "          \
  87   88              "error %d.  Aborting.\n", __FILE__, __LINE__, (func), (err));
  88   89  
  89   90  #define min(a, b)       (((a) < (b)) ? (a) : (b))
  90   91  
  91   92  #define FAULT_COUNT_INCR        0
  92   93  #define FAULT_COUNT_RESET       1
  93   94  
  94   95  #define FAULT_THRESHOLD         3
  95   96  
  96   97  #define MAX_CONFIGD_RETRIES     5
  97   98  #define MAX_EMI_RETRIES         5
  98   99  #define MAX_MOUNT_RETRIES       5
  99  100  #define MAX_SULOGIN_RETRIES     5
 100  101  
 101  102  #define RETURN_SUCCESS          0
 102  103  #define RETURN_RETRY            -1
 103  104  #define RETURN_FATAL            -2
 104  105  
 105  106  #define LIBSCF_SUCCESS          0
 106  107  #define LIBSCF_PROPERTY_ABSENT  -1
 107  108  #define LIBSCF_PGROUP_ABSENT    -2
 108  109  #define LIBSCF_PROPERTY_ERROR   -3
 109  110  
 110  111  #define METHOD_START            0
 111  112  #define METHOD_STOP             1
 112  113  #define METHOD_REFRESH          2
 113  114  
 114  115  #define METHOD_TIMEOUT_INFINITE 0
 115  116  
 116  117  /*
 117  118   * Contract cookies used by startd.
 118  119   */
 119  120  #define CONFIGD_COOKIE          0x10
 120  121  #define SULOGIN_COOKIE          0x11
 121  122  #define METHOD_START_COOKIE     0x20
 122  123  #define METHOD_OTHER_COOKIE     0x21
 123  124  #define MONITOR_COOKIE          0x30
 124  125  #define EMI_COOKIE              0x31
 125  126  
 126  127  
 127  128  #define ALLOC_RETRY             3
 128  129  #define ALLOC_DELAY             10
 129  130  #define ALLOC_DELAY_MULT        10
 130  131  
 131  132  #define safe_scf_scope_create(h)        \
 132  133          libscf_object_create((void *(*)(scf_handle_t *))scf_scope_create, (h))
 133  134  #define safe_scf_service_create(h)      \
 134  135          libscf_object_create((void *(*)(scf_handle_t *))scf_service_create, (h))
 135  136  #define safe_scf_instance_create(h)     libscf_object_create(   \
 136  137          (void *(*)(scf_handle_t *))scf_instance_create, (h))
 137  138  #define safe_scf_snapshot_create(h)     libscf_object_create(   \
 138  139          (void *(*)(scf_handle_t *))scf_snapshot_create, (h))
 139  140  #define safe_scf_snaplevel_create(h)    libscf_object_create(   \
 140  141          (void *(*)(scf_handle_t *))scf_snaplevel_create, (h))
 141  142  #define safe_scf_pg_create(h)           \
 142  143          libscf_object_create((void *(*)(scf_handle_t *))scf_pg_create, (h))
 143  144  #define safe_scf_property_create(h)     libscf_object_create(   \
 144  145          (void *(*)(scf_handle_t *))scf_property_create, (h))
 145  146  #define safe_scf_value_create(h)        \
 146  147          libscf_object_create((void *(*)(scf_handle_t *))scf_value_create, (h))
 147  148  #define safe_scf_iter_create(h)         \
 148  149          libscf_object_create((void *(*)(scf_handle_t *))scf_iter_create, (h))
 149  150  #define safe_scf_transaction_create(h)  libscf_object_create(   \
 150  151          (void *(*)(scf_handle_t *))     scf_transaction_create, (h))
 151  152  #define safe_scf_entry_create(h)        \
 152  153          libscf_object_create((void *(*)(scf_handle_t *))scf_entry_create, (h))
 153  154  
 154  155  #define startd_alloc(sz)        \
 155  156          startd_alloc_retry((void *(*)(size_t, int))umem_alloc, (sz))
 156  157  #define startd_zalloc(sz)       \
  
    | ↓ open down ↓ | 122 lines elided | ↑ open up ↑ | 
 157  158          startd_alloc_retry((void *(*)(size_t, int))umem_zalloc, (sz))
 158  159  
 159  160  
 160  161  extern pthread_mutexattr_t mutex_attrs;
 161  162  
 162  163  /*
 163  164   * Definitions for administrative actions.
 164  165   *   Note that the ordering in admin_action_t, admin_actions, and admin_events
 165  166   *   must match.  admin_actions and admin_events are defined in startd.c.
 166  167   */
 167      -#define NACTIONS                        6
      168 +#define NACTIONS                        8
 168  169  
 169  170  typedef enum {
 170  171          ADMIN_EVENT_DEGRADED = 0x0,
 171  172          ADMIN_EVENT_MAINT_OFF,
 172  173          ADMIN_EVENT_MAINT_ON,
 173  174          ADMIN_EVENT_MAINT_ON_IMMEDIATE,
 174  175          ADMIN_EVENT_REFRESH,
 175  176          ADMIN_EVENT_RESTART
 176  177  } admin_action_t;
 177  178  
 178  179  extern const char * const admin_actions[NACTIONS];
 179  180  extern const int admin_events[NACTIONS];
 180  181  
 181  182  #define LOG_DATE_SIZE   32      /* Max size of timestamp in log output */
 182  183  
 183  184  extern ssize_t max_scf_name_size;
 184  185  extern ssize_t max_scf_value_size;
 185  186  extern ssize_t max_scf_fmri_size;
 186  187  
 187  188  extern mode_t fmask;
 188  189  extern mode_t dmask;
 189  190  
 190  191  #define LOG_PREFIX_EARLY        "/etc/svc/volatile/"
 191  192  #define LOG_PREFIX_NORMAL       "/var/svc/log/"
 192  193  
 193  194  #define LOG_SUFFIX              ".log"
 194  195  
 195  196  #define STARTD_DEFAULT_LOG      "svc.startd.log"
 196  197  #define EMI_LOG ((const char *) "system-early-manifest-import:default.log")
 197  198  
 198  199  extern const char *log_directory;       /* Current log directory path */
 199  200  
 200  201  #define FS_TIMEZONE_DIR         "/usr/share/lib/zoneinfo"
 201  202  #define FS_LOCALE_DIR           "/usr/lib/locale"
 202  203  
 203  204  /*
 204  205   * Simple dictionary representation.
 205  206   */
 206  207  typedef struct dictionary {
 207  208          uu_list_t               *dict_list;
 208  209          int                     dict_new_id;
 209  210          pthread_mutex_t         dict_lock;
 210  211  } dictionary_t;
 211  212  
 212  213  typedef struct dict_entry {
 213  214          int                     de_id;
 214  215          const char              *de_name;
 215  216          uu_list_node_t          de_link;
 216  217  } dict_entry_t;
 217  218  
 218  219  extern dictionary_t *dictionary;
 219  220  
 220  221  typedef struct timeout_queue {
 221  222          uu_list_t               *tq_list;
 222  223          pthread_mutex_t         tq_lock;
 223  224  } timeout_queue_t;
 224  225  
 225  226  typedef struct timeout_entry {
 226  227          hrtime_t                te_timeout;     /* timeout expiration time */
 227  228          ctid_t                  te_ctid;
 228  229          char                    *te_fmri;
 229  230          char                    *te_logstem;
 230  231          volatile int            te_fired;
 231  232          uu_list_node_t          te_link;
 232  233  } timeout_entry_t;
 233  234  
 234  235  extern timeout_queue_t *timeouts;
 235  236  
 236  237  /*
 237  238   * State definitions.
 238  239   */
 239  240  typedef enum {
 240  241          STATE_NONE = 0x0,
 241  242          STATE_UNINIT,
 242  243          STATE_MAINT,
 243  244          STATE_OFFLINE,
 244  245          STATE_DISABLED,
 245  246          STATE_ONLINE,
 246  247          STATE_DEGRADED
 247  248  } instance_state_t;
 248  249  
 249  250  #define STATE_MAX       (STATE_DEGRADED + 1)
 250  251  
 251  252  extern const char * const instance_state_str[STATE_MAX];
 252  253  
 253  254  typedef enum {
 254  255          GVT_UNSUPPORTED = -1,
 255  256          GVT_UNKNOWN = 0,
 256  257          GVT_SVC,                /* service */
 257  258          GVT_INST,               /* instance */
 258  259          GVT_FILE,               /* file: */
 259  260          GVT_GROUP               /* dependency group */
 260  261  } gv_type_t;
 261  262  
 262  263  typedef enum {
 263  264          DEPGRP_UNSUPPORTED = -1,
 264  265          DEPGRP_REQUIRE_ANY = 1,
 265  266          DEPGRP_REQUIRE_ALL,
 266  267          DEPGRP_EXCLUDE_ALL,
 267  268          DEPGRP_OPTIONAL_ALL
 268  269  } depgroup_type_t;
 269  270  
 270  271  typedef enum {
 271  272          METHOD_RESTART_UNKNOWN = -1,
 272  273          METHOD_RESTART_ALL = 0,
 273  274          METHOD_RESTART_EXTERNAL_FAULT,
 274  275          METHOD_RESTART_ANY_FAULT,
 275  276          METHOD_RESTART_OTHER
 276  277  } method_restart_t;
 277  278  
 278  279  typedef enum {
 279  280          PROPAGATE_START,
 280  281          PROPAGATE_STOP,
 281  282          PROPAGATE_SAT
 282  283  } propagate_event_t;
 283  284  
 284  285  /*
 285  286   * Graph representation.
 286  287   */
 287  288  #define GV_CONFIGURED   0x01    /* Service exists in repository, ready */
 288  289  #define GV_ENABLED      0x02    /* Service should be online */
 289  290  #define GV_ENBLD_NOOVR  0x04    /* GV_ENABLED, ignoring override */
 290  291  #define GV_INSUBGRAPH   0x08    /* Current milestone depends on service */
 291  292  #define GV_DEATHROW     0x10    /* Service is on deathrow */
 292  293  #define GV_TOOFFLINE    0x20    /* Services in subtree to offline */
 293  294  #define GV_TODISABLE    0x40    /* Services in subtree to disable */
 294  295  
 295  296  /* ID must come first to support search */
 296  297  typedef struct graph_vertex {
 297  298          int                             gv_id;
 298  299          char                            *gv_name;
 299  300          uu_list_node_t                  gv_link;
 300  301  
 301  302          uint_t                          gv_flags;
 302  303          restarter_instance_state_t      gv_state;
 303  304  
 304  305          gv_type_t                       gv_type;
 305  306  
 306  307          depgroup_type_t                 gv_depgroup;
 307  308          restarter_error_t               gv_restart;
 308  309  
 309  310          void                            (*gv_start_f)(struct graph_vertex *);
 310  311          void                            (*gv_post_online_f)(void);
 311  312          void                            (*gv_post_disable_f)(void);
 312  313  
 313  314          int                             gv_restarter_id;
 314  315          evchan_t                        *gv_restarter_channel;
 315  316  
 316  317          int                             gv_delegate_initialized;
 317  318          evchan_t                        *gv_delegate_channel;
 318  319  
 319  320          uu_list_t                       *gv_dependencies;
 320  321          uu_list_t                       *gv_dependents;
 321  322  
 322  323          /*
 323  324           * gv_refs represents the number of references besides dependencies.
 324  325           * The vertex cannot be removed when gv_refs > 0.
 325  326           *
 326  327           * Currently, only relevant for GVT_SVC and GVT_INST type vertices.
 327  328           */
 328  329          int                             gv_refs;
 329  330  
 330  331          int32_t                         gv_stn_tset;
 331  332          int32_t                         gv_reason;
 332  333  } graph_vertex_t;
 333  334  
 334  335  typedef struct graph_edge {
 335  336          graph_vertex_t  *ge_vertex;
 336  337          uu_list_node_t  ge_link;
  
    | ↓ open down ↓ | 159 lines elided | ↑ open up ↑ | 
 337  338          graph_vertex_t  *ge_parent;
 338  339  } graph_edge_t;
 339  340  
 340  341  int libscf_get_info_events_all(scf_propertygroup_t *);
 341  342  int32_t libscf_get_stn_tset(scf_instance_t *);
 342  343  
 343  344  /*
 344  345   * Restarter transition outcomes
 345  346   */
 346  347  typedef enum {
      348 +        DEGRADE_REQUESTED,
 347  349          MAINT_REQUESTED,
 348  350          START_REQUESTED,
 349  351          START_FAILED_REPEATEDLY,
 350  352          START_FAILED_CONFIGURATION,
 351  353          START_FAILED_FATAL,
 352  354          START_FAILED_TIMEOUT_FATAL,
 353  355          START_FAILED_OTHER
 354  356  } start_outcome_t;
 355  357  
 356  358  typedef void (*instance_hook_t)(void);
 357  359  
 358  360  typedef struct service_hook_assn {
 359  361          char    *sh_fmri;
 360  362          instance_hook_t sh_pre_online_hook;
 361  363          instance_hook_t sh_post_online_hook;
 362  364          instance_hook_t sh_post_offline_hook;
 363  365  } service_hook_assn_t;
 364  366  
 365  367  /*
 366  368   * Restarter instance stop reasons.
 367  369   */
 368  370  typedef enum {
 369  371          RSTOP_EXIT = 0x0,       /* exited or empty */
 370  372          RSTOP_CORE,             /* core dumped */
 371  373          RSTOP_SIGNAL,           /* external fatal signal received */
 372  374          RSTOP_HWERR,            /* uncorrectable hardware error */
 373  375          RSTOP_DEPENDENCY,       /* dependency activity caused stop */
 374  376          RSTOP_DISABLE,          /* disabled */
 375  377          RSTOP_RESTART,          /* restart requested */
 376  378          RSTOP_ERR_CFG,          /* wait svc exited with a config. error */
 377  379          RSTOP_ERR_EXIT          /* wait svc exited with an error */
 378  380  } stop_cause_t;
 379  381  
 380  382  /*
 381  383   * Restarter instance maintenance clear reasons.
 382  384   */
 383  385  typedef enum {
 384  386          RUNMAINT_CLEAR = 0x0,
 385  387          RUNMAINT_DISABLE
 386  388  } unmaint_cause_t;
 387  389  
 388  390  /*
 389  391   * Restarter instance flags
 390  392   */
 391  393  #define RINST_CONTRACT          0x00000000      /* progeny constitute inst */
 392  394  #define RINST_TRANSIENT         0x10000000      /* inst operates momentarily */
 393  395  #define RINST_WAIT              0x20000000      /* child constitutes inst */
 394  396  #define RINST_STYLE_MASK        0xf0000000
 395  397  
 396  398  #define RINST_RETAKE_RUNNING    0x01000000      /* pending running snapshot */
 397  399  #define RINST_RETAKE_START      0x02000000      /* pending start snapshot */
 398  400  
 399  401  #define RINST_RETAKE_MASK       0x0f000000
 400  402  
 401  403  #define RINST_START_TIMES       5               /* failures to consider */
 402  404  #define RINST_FAILURE_RATE_NS   600000000000LL  /* 1 failure/10 minutes */
 403  405  #define RINST_WT_SVC_FAILURE_RATE_NS    NANOSEC /* 1 failure/second */
 404  406  
 405  407  /* Number of events in the queue when we start dropping ADMIN events. */
 406  408  #define RINST_QUEUE_THRESHOLD   100
 407  409  
 408  410  typedef struct restarter_inst {
 409  411          int                     ri_id;
 410  412          instance_data_t         ri_i;
 411  413          char                    *ri_common_name; /* template localized name */
 412  414          char                    *ri_C_common_name; /* C locale name */
 413  415  
 414  416          char                    *ri_logstem;    /* logfile name */
 415  417          char                    *ri_utmpx_prefix;
 416  418          uint_t                  ri_flags;
 417  419          instance_hook_t         ri_pre_online_hook;
 418  420          instance_hook_t         ri_post_online_hook;
 419  421          instance_hook_t         ri_post_offline_hook;
 420  422  
 421  423          hrtime_t                ri_start_time[RINST_START_TIMES];
 422  424          uint_t                  ri_start_index; /* times started */
 423  425  
 424  426          uu_list_node_t          ri_link;
 425  427          pthread_mutex_t         ri_lock;
 426  428  
 427  429          /*
 428  430           * When we start a thread to we execute a method for this instance, we
 429  431           * put the thread id in ri_method_thread.  Threads with ids other than
 430  432           * this which acquire ri_lock while ri_method_thread is nonzero should
 431  433           * wait on ri_method_cv.  ri_method_waiters should be incremented while
 432  434           * waiting so the instance won't be deleted.
 433  435           */
 434  436          pthread_t               ri_method_thread;
 435  437          pthread_cond_t          ri_method_cv;
 436  438          uint_t                  ri_method_waiters;
 437  439  
 438  440          /*
 439  441           * These fields are provided so functions can operate on this structure
 440  442           * and the repository without worrying about whether the instance has
 441  443           * been deleted from the repository (this is possible because
 442  444           * ri_i.i_fmri names the instance this structure represents -- see
 443  445           * libscf_reget_inst()).  ri_m_inst is the scf_instance_t for the
 444  446           * instance, and ri_mi_deleted is true if the instance has been deleted.
 445  447           */
 446  448          scf_instance_t          *ri_m_inst;
 447  449          boolean_t               ri_mi_deleted;
 448  450  
 449  451          /*
 450  452           * We maintain a pointer to any pending timeout for this instance
 451  453           * for quick reference/deletion.
 452  454           */
 453  455          timeout_entry_t         *ri_timeout;
 454  456  
 455  457          /*
 456  458           * Instance event queue.  Graph events are queued here as a list
 457  459           * of restarter_instance_qentry_t's, and the lock is held separately.
 458  460           * If both ri_lock and ri_queue_lock are grabbed, ri_lock must be
 459  461           * grabbed first.  ri_queue_lock protects all ri_queue_* structure
 460  462           * members.
 461  463           */
 462  464          pthread_mutex_t         ri_queue_lock;
 463  465          pthread_cond_t          ri_queue_cv;
 464  466          uu_list_t               *ri_queue;
 465  467          int                     ri_queue_thread;
 466  468  
 467  469  } restarter_inst_t;
 468  470  
 469  471  typedef struct restarter_instance_list {
 470  472          uu_list_t               *ril_instance_list;
 471  473          pthread_mutex_t         ril_lock;
 472  474  } restarter_instance_list_t;
 473  475  
 474  476  typedef struct restarter_instance_qentry {
 475  477          restarter_event_type_t  riq_type;
 476  478          int32_t                 riq_reason;
 477  479          uu_list_node_t          riq_link;
 478  480  } restarter_instance_qentry_t;
 479  481  
 480  482  typedef struct fork_info {
 481  483          int                     sf_id;
 482  484          int                     sf_method_type;
 483  485          restarter_error_t       sf_event_type;
 484  486          restarter_str_t         sf_reason;
 485  487  } fork_info_t;
 486  488  
 487  489  typedef struct wait_info {
 488  490          uu_list_node_t          wi_link;
 489  491  
 490  492          int                     wi_fd;          /* psinfo file descriptor */
 491  493          id_t                    wi_pid;         /* process ID */
 492  494          const char              *wi_fmri;       /* instance FMRI */
 493  495          int                     wi_parent;      /* startd is parent */
 494  496          int                     wi_ignore;      /* ignore events */
 495  497  } wait_info_t;
 496  498  
 497  499  #define STARTD_LOG_FILE         0x1
 498  500  #define STARTD_LOG_TERMINAL     0x2
 499  501  #define STARTD_LOG_SYSLOG       0x4
 500  502  
 501  503  #define STARTD_BOOT_QUIET       0x1
 502  504  #define STARTD_BOOT_VERBOSE     0x2
 503  505  
 504  506  /*
 505  507   * Internal debug flags used to reduce the amount of data sent to the
 506  508   * internal debug buffer. They can be turned on & off dynamically using
 507  509   * internal_debug_flags variable in mdb. By default, they're off.
 508  510   */
 509  511  #define DEBUG_DEPENDENCIES      0x1
 510  512  
 511  513  typedef struct startd_state {
 512  514          /* Logging configuration */
 513  515          char            *st_log_prefix; /* directory prefix */
 514  516          char            *st_log_file;   /* startd file in above dir */
 515  517          uint_t          st_log_flags;   /* message destination */
 516  518          int             st_log_level_min; /* minimum required to log */
 517  519          int             st_log_timezone_known; /* timezone is available */
 518  520          int             st_log_locale_known; /* locale is available */
 519  521          int             st_log_login_reached; /* login service reached */
 520  522  
 521  523          /* Boot configuration */
 522  524          uint_t          st_boot_flags;  /* serial boot, etc. */
 523  525          uint_t          st_initial;     /* first startd on system */
 524  526  
 525  527          /* System configuration */
 526  528          char            *st_subgraph;   /* milestone subgraph request */
 527  529  
 528  530          uint_t          st_load_complete;  /* graph load completed */
 529  531          uint_t          st_load_instances; /* restarter instances to load */
 530  532          pthread_mutex_t st_load_lock;
 531  533          pthread_cond_t  st_load_cv;
 532  534  
 533  535          /* Repository configuration */
 534  536          pid_t           st_configd_pid; /* PID of our svc.configd */
 535  537                                          /* instance */
 536  538          int             st_configd_lives; /* configd started */
 537  539          pthread_mutex_t st_configd_live_lock;
 538  540          pthread_cond_t  st_configd_live_cv;
 539  541  
 540  542          char            *st_door_path;
 541  543  
 542  544          /* General information */
 543  545          uint_t          st_flags;
 544  546          struct timeval  st_start_time;  /* effective system start time */
 545  547          char            *st_locale;
 546  548  } startd_state_t;
 547  549  
 548  550  extern startd_state_t *st;
 549  551  
 550  552  extern boolean_t booting_to_single_user;
 551  553  
 552  554  extern const char *event_names[];
 553  555  
 554  556  /*
 555  557   * Structures for contract to instance hash table, implemented in
 556  558   * contract.c and used by restarter.c and method.c
 557  559   */
 558  560  typedef struct contract_entry {
 559  561          ctid_t          ce_ctid;
 560  562          int             ce_instid;
 561  563  
 562  564          uu_list_node_t  ce_link;
 563  565  } contract_entry_t;
 564  566  
 565  567  extern volatile uint16_t        storing_contract;
 566  568  
 567  569  uu_list_pool_t *contract_list_pool;
 568  570  
 569  571  /* contract.c */
 570  572  ctid_t contract_init(void);
 571  573  void contract_abandon(ctid_t);
 572  574  int contract_kill(ctid_t, int, const char *);
 573  575  int contract_is_empty(ctid_t);
 574  576  void contract_hash_init();
 575  577  void contract_hash_store(ctid_t, int);
 576  578  void contract_hash_remove(ctid_t);
 577  579  int lookup_inst_by_contract(ctid_t);
 578  580  
 579  581  /* dict.c */
 580  582  void dict_init(void);
 581  583  int dict_lookup_byname(const char *);
 582  584  int dict_insert(const char *);
 583  585  
 584  586  /* expand.c */
 585  587  int expand_method_tokens(const char *, scf_instance_t *,
 586  588      scf_snapshot_t *, int, char **);
 587  589  
 588  590  /* env.c */
 589  591  void init_env(void);
 590  592  char **set_smf_env(char **, size_t, const char *,
 591  593      const restarter_inst_t *, const char *);
 592  594  
 593  595  /* file.c */
 594  596  int file_ready(graph_vertex_t *);
 595  597  
 596  598  /* fork.c */
 597  599  int fork_mount(char *, char *);
 598  600  void fork_sulogin(boolean_t, const char *, ...);
 599  601  void fork_rc_script(char, const char *, boolean_t);
 600  602  
 601  603  void *fork_configd_thread(void *);
 602  604  
 603  605  pid_t startd_fork1(int *);
 604  606  void fork_with_timeout(const char *, uint_t, uint_t);
 605  607  void fork_emi();
 606  608  
 607  609  /* graph.c */
 608  610  void graph_init(void);
 609  611  void *single_user_thread(void *);
 610  612  void *graph_thread(void *);
 611  613  void *graph_event_thread(void *);
 612  614  void *repository_event_thread(void *);
 613  615  int dgraph_add_instance(const char *, scf_instance_t *, boolean_t);
 614  616  void graph_engine_start(void);
 615  617  void graph_enable_by_vertex(graph_vertex_t *, int, int);
 616  618  int refresh_vertex(graph_vertex_t *, scf_instance_t *);
 617  619  void vertex_send_event(graph_vertex_t *, restarter_event_type_t);
 618  620  void graph_start_if_satisfied(graph_vertex_t *);
 619  621  int vertex_subgraph_dependencies_shutdown(scf_handle_t *, graph_vertex_t *,
 620  622      restarter_instance_state_t);
 621  623  void graph_transition_sulogin(restarter_instance_state_t,
 622  624      restarter_instance_state_t);
 623  625  void graph_transition_propagate(graph_vertex_t *, propagate_event_t,
 624  626      restarter_error_t);
 625  627  void graph_offline_subtree_leaves(graph_vertex_t *, void *);
 626  628  void offline_vertex(graph_vertex_t *);
 627  629  
 628  630  /* libscf.c - common */
 629  631  char *inst_fmri_to_svc_fmri(const char *);
 630  632  void *libscf_object_create(void *(*)(scf_handle_t *), scf_handle_t *);
 631  633  int libscf_instance_get_fmri(scf_instance_t *, char **);
 632  634  int libscf_fmri_get_instance(scf_handle_t *, const char *, scf_instance_t **);
 633  635  int libscf_lookup_instance(const char *, scf_instance_t *);
 634  636  int libscf_set_reconfig(int);
 635  637  scf_snapshot_t *libscf_get_or_make_running_snapshot(scf_instance_t *,
 636  638      const char *, boolean_t);
 637  639  int libscf_inst_set_count_prop(scf_instance_t *, const char *,
 638  640      const char *pgtype, uint32_t, const char *, uint64_t);
 639  641  
 640  642  /* libscf.c - used by graph.c */
 641  643  int libscf_get_deathrow(scf_handle_t *, scf_instance_t *, int *);
 642  644  int libscf_get_basic_instance_data(scf_handle_t *, scf_instance_t *,
 643  645      const char *, int *, int *, char **);
 644  646  int libscf_inst_get_or_add_pg(scf_instance_t *, const char *, const char *,
 645  647      uint32_t, scf_propertygroup_t *);
 646  648  int libscf_read_states(const scf_propertygroup_t *,
 647  649      restarter_instance_state_t *, restarter_instance_state_t *);
 648  650  int depgroup_empty(scf_handle_t *, scf_propertygroup_t *);
 649  651  gv_type_t depgroup_read_scheme(scf_handle_t *, scf_propertygroup_t *);
 650  652  depgroup_type_t depgroup_read_grouping(scf_handle_t *, scf_propertygroup_t *);
 651  653  restarter_error_t depgroup_read_restart(scf_handle_t *, scf_propertygroup_t *);
 652  654  int libscf_set_enable_ovr(scf_instance_t *, int);
 653  655  int libscf_set_deathrow(scf_instance_t *, int);
 654  656  int libscf_delete_enable_ovr(scf_instance_t *);
 655  657  int libscf_get_milestone(scf_instance_t *, scf_property_t *, scf_value_t *,
 656  658      char *, size_t);
 657  659  int libscf_extract_runlevel(scf_property_t *, char *);
 658  660  int libscf_clear_runlevel(scf_propertygroup_t *, const char *milestone);
 659  661  
 660  662  typedef int (*callback_t)(void *, void *);
 661  663  
 662  664  int walk_dependency_pgs(scf_instance_t *, callback_t, void *);
 663  665  int walk_property_astrings(scf_property_t *, callback_t, void *);
 664  666  void libscf_reset_start_times(restarter_inst_t *, int);
 665  667  
 666  668  /* libscf.c - used by restarter.c/method.c/expand.c */
 667  669  char *libscf_get_method(scf_handle_t *, int, restarter_inst_t *,
 668  670      scf_snapshot_t *, method_restart_t *, uint_t *, uint8_t *, uint64_t *,
 669  671      uint8_t *);
 670  672  void libscf_populate_graph(scf_handle_t *h);
 671  673  int update_fault_count(restarter_inst_t *, int);
 672  674  int libscf_unset_action(scf_handle_t *, scf_propertygroup_t *, admin_action_t,
 673  675      int64_t);
 674  676  int libscf_get_startd_properties(scf_instance_t *, scf_snapshot_t *, uint_t *,
 675  677      char **);
 676  678  int libscf_get_template_values(scf_instance_t *, scf_snapshot_t *, char **,
 677  679      char **);
 678  680  
 679  681  int libscf_read_method_ids(scf_handle_t *, scf_instance_t *, const char *,
 680  682      ctid_t *, ctid_t *, pid_t *);
 681  683  int libscf_write_start_pid(scf_instance_t *, pid_t);
 682  684  int libscf_write_method_status(scf_instance_t *, const char *, int);
 683  685  int libscf_note_method_log(scf_instance_t *, const char *, const char *);
 684  686  
 685  687  scf_handle_t *libscf_handle_create_bound(scf_version_t);
 686  688  void libscf_handle_rebind(scf_handle_t *);
 687  689  scf_handle_t *libscf_handle_create_bound_loop(void);
 688  690  
 689  691  scf_snapshot_t *libscf_get_running_snapshot(scf_instance_t *);
 690  692  int libscf_snapshots_poststart(scf_handle_t *, const char *, boolean_t);
 691  693  int libscf_snapshots_refresh(scf_instance_t *, const char *);
 692  694  
 693  695  int instance_is_transient_style(restarter_inst_t *);
 694  696  int instance_is_wait_style(restarter_inst_t *);
 695  697  
 696  698  int libscf_create_self(scf_handle_t *);
 697  699  
 698  700  void libscf_reget_instance(restarter_inst_t *);
 699  701  
 700  702  /* log.c */
 701  703  void log_init();
 702  704  void log_error(int, const char *, ...);
 703  705  void log_framework(int, const char *, ...);
 704  706  void log_framework2(int, int, const char *, ...);
 705  707  void log_console(int, const char *, ...);
 706  708  void log_preexec(void);
 707  709  void setlog(const char *);
 708  710  void log_transition(const restarter_inst_t *, start_outcome_t);
 709  711  void log_instance(const restarter_inst_t *, boolean_t, const char *, ...);
 710  712  void log_instance_fmri(const char *, const char *, boolean_t,
 711  713      const char *, ...);
 712  714  
 713  715  /* method.c */
 714  716  void *method_thread(void *);
 715  717  void method_remove_contract(restarter_inst_t *, boolean_t, boolean_t);
 716  718  int method_rate_critical(restarter_inst_t *);
 717  719  
 718  720  /* misc.c */
 719  721  void startd_close(int);
 720  722  void startd_fclose(FILE *);
 721  723  int fmri_canonify(const char *, char **, boolean_t);
 722  724  int fs_is_read_only(char *, ulong_t *);
 723  725  int fs_remount(char *);
 724  726  void xstr_sanitize(char *);
 725  727  
 726  728  /* restarter.c */
 727  729  void restarter_init(void);
 728  730  void restarter_start(void);
 729  731  int instance_in_transition(restarter_inst_t *);
 730  732  int restarter_instance_update_states(scf_handle_t *, restarter_inst_t *,
 731  733      restarter_instance_state_t, restarter_instance_state_t, restarter_error_t,
 732  734      restarter_str_t);
 733  735  int stop_instance_fmri(scf_handle_t *, const char *, uint_t);
 734  736  restarter_inst_t *inst_lookup_by_id(int);
 735  737  void restarter_mark_pending_snapshot(const char *, uint_t);
 736  738  void *restarter_post_fsminimal_thread(void *);
 737  739  void timeout_insert(restarter_inst_t *, ctid_t, uint64_t);
 738  740  void timeout_remove(restarter_inst_t *, ctid_t);
 739  741  void timeout_init(void);
 740  742  int is_timeout_ovr(restarter_inst_t *);
 741  743  
 742  744  /* startd.c */
 743  745  void *safe_realloc(void *, size_t);
 744  746  char *safe_strdup(const char *s);
 745  747  void *startd_alloc_retry(void *(*)(size_t, int), size_t);
 746  748  void startd_free(void *, size_t);
 747  749  uu_list_pool_t *startd_list_pool_create(const char *, size_t, size_t,
 748  750      uu_compare_fn_t *, uint32_t);
 749  751  uu_list_t *startd_list_create(uu_list_pool_t *, void *, uint32_t);
 750  752  pthread_t startd_thread_create(void *(*)(void *), void *);
 751  753  
 752  754  /* special.c */
 753  755  void special_null_transition(void);
 754  756  void special_online_hooks_get(const char *, instance_hook_t *,
 755  757      instance_hook_t *, instance_hook_t *);
 756  758  
 757  759  /* transition.c */
 758  760  int gt_transition(scf_handle_t *, graph_vertex_t *, restarter_error_t,
 759  761      restarter_instance_state_t);
 760  762  
 761  763  /* utmpx.c */
 762  764  void utmpx_init(void);
 763  765  void utmpx_clear_old(void);
 764  766  int utmpx_mark_init(pid_t, char *);
 765  767  void utmpx_mark_dead(pid_t, int, boolean_t);
 766  768  char utmpx_get_runlevel(void);
 767  769  void utmpx_set_runlevel(char, char, boolean_t);
 768  770  void utmpx_write_boottime(void);
 769  771  void utmpx_prefork(void);
 770  772  void utmpx_postfork(void);
 771  773  
 772  774  /* wait.c */
 773  775  void wait_init(void);
 774  776  void wait_prefork(void);
 775  777  void wait_postfork(pid_t);
 776  778  int wait_register(pid_t, const char *, int, int);
 777  779  void *wait_thread(void *);
 778  780  void wait_ignore_by_fmri(const char *);
 779  781  
 780  782  /* proc.c */
 781  783  ctid_t proc_get_ctid();
 782  784  
 783  785  /* deathrow.c */
 784  786  extern void deathrow_init();
 785  787  extern void deathrow_fini();
 786  788  extern boolean_t is_fmri_in_deathrow(const char *);
 787  789  
 788  790  #ifdef  __cplusplus
 789  791  }
 790  792  #endif
 791  793  
 792  794  #endif  /* _STARTD_H */
  
    | ↓ open down ↓ | 436 lines elided | ↑ open up ↑ | 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX