Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_LIBRESTART_H
     27 #define	_LIBRESTART_H
     28 
     29 #include <libsysevent.h>
     30 #include <libcontract.h>
     31 #include <libscf.h>
     32 #include <limits.h>
     33 #include <priv.h>
     34 #include <pwd.h>
     35 #include <sys/types.h>
     36 
     37 #ifdef	__cplusplus
     38 extern "C" {
     39 #endif
     40 
     41 /*
     42  * There are 3 parts to librestart.
     43  *	1) The event protocol from the master restarter to its delegates.
     44  *	2) A functional interface for updating the repository.
     45  *	3) Convenience functions for common restarter tasks.
     46  *
     47  * Event protocol
     48  *	We need a reliable event protocol, as there's no way to define
     49  *	restarter events as idempotent.
     50  *
     51  *	Currently using sysevent channels as the reliable event implementation.
     52  *	This could change if the implementation proves unsuitable, but
     53  *	the API defined here should abstract anything but a change in
     54  *	the fundamental event model.
     55  *
     56  *	We offer functions to tease apart the event rather than generic
     57  *	nvpair interfaces. This is because each event type has a well-
     58  *	defined set of fields.
     59  */
     60 
     61 /*
     62  * Some of the functions have external contracted consumers, review contracts
     63  * when making incompatible changes.
     64  */
     65 
     66 typedef struct restarter_event_handle restarter_event_handle_t;
     67 typedef struct restarter_event restarter_event_t;
     68 
     69 typedef uint32_t restarter_event_type_t;
     70 
     71 /*
     72  * Define an event protocol version. In theory, we could use this in
     73  * the future to support delegated restarters which use an older
     74  * protocol. In practice, increment RESTARTER_EVENT_VERSION whenever the
     75  * protocol might have changed.
     76  */
     77 #define	RESTARTER_EVENT_VERSION		4
     78 
     79 #define	RESTARTER_FLAG_DEBUG		1
     80 
     81 #define	RESTARTER_ERRMSGSZ		1024
     82 
     83 /*
     84  * Event types
     85  *	RESTARTER_EVENT_TYPE_ADD_INSTANCE
     86  *		responsible for a new (stopped) instance
     87  *	RESTARTER_EVENT_TYPE_REMOVE_INSTANCE
     88  *		no longer responsible for this instance; stop it and return
     89  *	RESTARTER_EVENT_TYPE_ENABLE
     90  *		no guarantee that dependencies are met; see
     91  *		RESTARTER_EVENT_TYPE_START
     92  *	RESTARTER_EVENT_TYPE_DISABLE
     93  *		no guarantee that instance was running
     94  *	RESTARTER_EVENT_TYPE_ADMIN_DEGRADED
     95  *	RESTARTER_EVENT_TYPE_ADMIN_REFRESH
     96  *	RESTARTER_EVENT_TYPE_ADMIN_RESTART
     97  *	RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF
     98  *	RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON
     99  *	RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE
    100  *	RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF
    101  *	RESTARTER_EVENT_TYPE_STOP
    102  *		dependencies are, or are becoming, unsatisfied
    103  *	RESTARTER_EVENT_TYPE_START
    104  *		dependencies have become satisfied
    105  *	RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE
    106  *		instance caused a dependency cycle
    107  *	RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY
    108  *		instance has an invalid dependency
    109  */
    110 
    111 #define	RESTARTER_EVENT_TYPE_INVALID			0
    112 #define	RESTARTER_EVENT_TYPE_ADD_INSTANCE		1
    113 #define	RESTARTER_EVENT_TYPE_REMOVE_INSTANCE		2
    114 #define	RESTARTER_EVENT_TYPE_ENABLE			3
    115 #define	RESTARTER_EVENT_TYPE_DISABLE			4
    116 #define	RESTARTER_EVENT_TYPE_ADMIN_DEGRADED		5
    117 #define	RESTARTER_EVENT_TYPE_ADMIN_REFRESH		6
    118 #define	RESTARTER_EVENT_TYPE_ADMIN_RESTART		7
    119 #define	RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF		8
    120 #define	RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON		9
    121 #define	RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE	10
    122 #define	RESTARTER_EVENT_TYPE_STOP			11
    123 #define	RESTARTER_EVENT_TYPE_START			12
    124 #define	RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE		13
    125 #define	RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY		14
    126 #define	RESTARTER_EVENT_TYPE_ADMIN_DISABLE		15
    127 
    128 #define	RESTARTER_EVENT_ERROR			-1
    129 
    130 #define	RESTARTER_EVENT_INSTANCE_DISABLED	0
    131 #define	RESTARTER_EVENT_INSTANCE_ENABLED	1
    132 
    133 typedef enum {
    134 	RESTARTER_STATE_NONE,
    135 	RESTARTER_STATE_UNINIT,
    136 	RESTARTER_STATE_MAINT,
    137 	RESTARTER_STATE_OFFLINE,
    138 	RESTARTER_STATE_DISABLED,
    139 	RESTARTER_STATE_ONLINE,
    140 	RESTARTER_STATE_DEGRADED
    141 } restarter_instance_state_t;
    142 
    143 /*
    144  * These values are ordered by severity of required restart, as we use
    145  * integer comparisons to determine error flow.
    146  */
    147 typedef enum {
    148 	RERR_UNSUPPORTED = -1,
    149 	RERR_NONE = 0,			/* no error, restart, refresh */
    150 	RERR_FAULT,			/* fault occurred */
    151 	RERR_RESTART,			/* transition due to restart */
    152 	RERR_REFRESH			/* transition due to refresh */
    153 } restarter_error_t;
    154 /*
    155  * restarter_store_contract() and restarter_remove_contract() types
    156  */
    157 typedef enum {
    158 	RESTARTER_CONTRACT_PRIMARY,
    159 	RESTARTER_CONTRACT_TRANSIENT
    160 } restarter_contract_type_t;
    161 
    162 /*
    163  * restarter_bind_handle() registers a delegate with svc.startd to
    164  * begin consuming events.
    165  *
    166  * On initial bind, the delgated restarter receives an event for each
    167  * instance it is responsible for, as if that instance was new.
    168  *
    169  * callers must have superuser privileges
    170  *
    171  * The event handler can return 0 for success, or EAGAIN to request
    172  * retry of event delivery. EAGAIN may be returned 3 times before the
    173  * event is discarded.
    174  */
    175 int restarter_bind_handle(uint32_t, const char *,
    176     int (*event_handler)(restarter_event_t *), int,
    177     restarter_event_handle_t **);
    178 
    179 restarter_event_type_t restarter_event_get_type(restarter_event_t *);
    180 uint64_t restarter_event_get_seq(restarter_event_t *);
    181 void restarter_event_get_time(restarter_event_t *, hrtime_t *);
    182 ssize_t restarter_event_get_instance(restarter_event_t *, char *, size_t);
    183 restarter_event_handle_t *restarter_event_get_handle(restarter_event_t *);
    184 
    185 /*
    186  * The following functions work only on certain types of events.
    187  * They fail with a return of -1 if they're called on an inappropriate event.
    188  */
    189 int restarter_event_get_enabled(restarter_event_t *);
    190 int restarter_event_get_current_states(restarter_event_t *,
    191     restarter_instance_state_t *, restarter_instance_state_t *);
    192 
    193 /*
    194  * Functions for updating the repository.
    195  */
    196 
    197 /*
    198  * When setting state to "maintenance", callers of restarter_set_states() can
    199  * set aux_state to "service_request" to communicate that another service has
    200  * requested maintenance state for the target service.
    201  *
    202  * Callers should use restarter_inst_validate_aux_fmri() to validate the fmri
    203  * of the requested service and pass "service_request" for aux_state when
    204  * calling restarter_set_states(). See inetd and startd for examples.
    205  */
    206 int restarter_set_states(restarter_event_handle_t *, const char *,
    207     restarter_instance_state_t, restarter_instance_state_t,
    208     restarter_instance_state_t, restarter_instance_state_t, restarter_error_t,
    209     const char *);
    210 int restarter_event_publish_retry(evchan_t *, const char *, const char *,
    211     const char *, const char *, nvlist_t *, uint32_t);
    212 
    213 int restarter_store_contract(scf_instance_t *, ctid_t,
    214     restarter_contract_type_t);
    215 int restarter_remove_contract(scf_instance_t *, ctid_t,
    216     restarter_contract_type_t);
    217 
    218 ssize_t restarter_state_to_string(restarter_instance_state_t, char *, size_t);
    219 restarter_instance_state_t restarter_string_to_state(char *);
    220 
    221 #define	RESTARTER_METHOD_CONTEXT_VERSION	7
    222 
    223 struct method_context {
    224 	/* Stable */
    225 	uid_t		uid, euid;
    226 	gid_t		gid, egid;
    227 	int		ngroups;		/* -1 means use initgroups(). */
    228 	gid_t		groups[NGROUPS_MAX];
    229 	priv_set_t	*lpriv_set, *priv_set;
    230 	char		*corefile_pattern;	/* Optional. */
    231 	char		*project;		/* NULL for no change */
    232 	char		*resource_pool;		/* NULL for project default */
    233 	char		*working_dir;		/* NULL for :default */
    234 	char		**env;			/* NULL for no env */
    235 	size_t		env_sz;			/* size of env array */
    236 
    237 	/* Private */
    238 	char		*vbuf;
    239 	ssize_t		vbuf_sz;
    240 	struct passwd	pwd;
    241 	char		*pwbuf;
    242 	ssize_t		pwbufsz;
    243 };
    244 
    245 /*
    246  * An error structure that contains a message string, and a type
    247  * that can be used to determine course of action by the reciever
    248  * of the error structure.
    249  *
    250  * type - usually will be an errno equivalent but could contain
    251  * 	defined error types for exampe SCF_ERROR_XXX
    252  * msg - must be at the end of the structure as if the message is
    253  * 	longer than EMSGSIZE we will reallocate the structure to
    254  * 	handle the overflow
    255  */
    256 typedef struct mc_error {
    257 	int	destroy;	/* Flag to indicate destruction steps */
    258 	int	type;		/* Type of error for decision making */
    259 	int	size;		/* The size of the error message string */
    260 	char 	msg[RESTARTER_ERRMSGSZ];
    261 } mc_error_t;
    262 
    263 int restarter_rm_libs_loadable(void);
    264 /* instance, restarter name, method name, command line, structure pointer */
    265 mc_error_t *restarter_get_method_context(uint_t, scf_instance_t *,
    266     scf_snapshot_t *, const char *, const char *, struct method_context **);
    267 void restarter_mc_error_destroy(mc_error_t *);
    268 int restarter_set_method_context(struct method_context *, const char **);
    269 void restarter_free_method_context(struct method_context *);
    270 
    271 
    272 int restarter_is_null_method(const char *);
    273 int restarter_is_kill_method(const char *);
    274 int restarter_is_kill_proc_method(const char *);
    275 
    276 /* Validate the inst fmri specified in  restarter_actions/auxiliary_fmri */
    277 int restarter_inst_validate_ractions_aux_fmri(scf_instance_t *);
    278 
    279 /* Delete instance's restarter_actions/auxiliary_fmri property */
    280 int restarter_inst_reset_ractions_aux_fmri(scf_instance_t *);
    281 
    282 /* Get boolean value from instance's restarter_actions/auxiliary_tty */
    283 int restarter_inst_ractions_from_tty(scf_instance_t *);
    284 
    285 /* Delete instance's restarter/auxiliary_fmri property */
    286 int restarter_inst_reset_aux_fmri(scf_instance_t *);
    287 
    288 /*
    289  * Set instance's restarter/auxiliary_fmri, value come from
    290  * restarter_actions/auxliary_fmri
    291  */
    292 int restarter_inst_set_aux_fmri(scf_instance_t *);
    293 
    294 #ifdef	__cplusplus
    295 }
    296 #endif
    297 
    298 #endif	/* _LIBRESTART_H */
    299