librestart.h revision 11482:7315713fb22c
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 2010 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
38extern "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
66typedef struct restarter_event_handle restarter_event_handle_t;
67typedef struct restarter_event restarter_event_t;
68
69typedef 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#define	RESTARTER_EVENT_TYPE_STOP_RESET			16
128
129#define	RESTARTER_EVENT_ERROR			-1
130
131#define	RESTARTER_EVENT_INSTANCE_DISABLED	0
132#define	RESTARTER_EVENT_INSTANCE_ENABLED	1
133
134typedef enum {
135	RESTARTER_STATE_NONE,
136	RESTARTER_STATE_UNINIT,
137	RESTARTER_STATE_MAINT,
138	RESTARTER_STATE_OFFLINE,
139	RESTARTER_STATE_DISABLED,
140	RESTARTER_STATE_ONLINE,
141	RESTARTER_STATE_DEGRADED
142} restarter_instance_state_t;
143
144/*
145 * These values are ordered by severity of required restart, as we use
146 * integer comparisons to determine error flow.
147 */
148typedef enum {
149	RERR_UNSUPPORTED = -1,
150	RERR_NONE = 0,			/* no error, restart, refresh */
151	RERR_FAULT,			/* fault occurred */
152	RERR_RESTART,			/* transition due to restart */
153	RERR_REFRESH			/* transition due to refresh */
154} restarter_error_t;
155/*
156 * restarter_store_contract() and restarter_remove_contract() types
157 */
158typedef enum {
159	RESTARTER_CONTRACT_PRIMARY,
160	RESTARTER_CONTRACT_TRANSIENT
161} restarter_contract_type_t;
162
163/*
164 * restarter_bind_handle() registers a delegate with svc.startd to
165 * begin consuming events.
166 *
167 * On initial bind, the delgated restarter receives an event for each
168 * instance it is responsible for, as if that instance was new.
169 *
170 * callers must have superuser privileges
171 *
172 * The event handler can return 0 for success, or EAGAIN to request
173 * retry of event delivery. EAGAIN may be returned 3 times before the
174 * event is discarded.
175 */
176int restarter_bind_handle(uint32_t, const char *,
177    int (*event_handler)(restarter_event_t *), int,
178    restarter_event_handle_t **);
179
180restarter_event_type_t restarter_event_get_type(restarter_event_t *);
181uint64_t restarter_event_get_seq(restarter_event_t *);
182void restarter_event_get_time(restarter_event_t *, hrtime_t *);
183ssize_t restarter_event_get_instance(restarter_event_t *, char *, size_t);
184restarter_event_handle_t *restarter_event_get_handle(restarter_event_t *);
185
186/*
187 * The following functions work only on certain types of events.
188 * They fail with a return of -1 if they're called on an inappropriate event.
189 */
190int restarter_event_get_enabled(restarter_event_t *);
191int restarter_event_get_current_states(restarter_event_t *,
192    restarter_instance_state_t *, restarter_instance_state_t *);
193
194/*
195 * Functions for updating the repository.
196 */
197
198/*
199 * When setting state to "maintenance", callers of restarter_set_states() can
200 * set aux_state to "service_request" to communicate that another service has
201 * requested maintenance state for the target service.
202 *
203 * Callers should use restarter_inst_validate_aux_fmri() to validate the fmri
204 * of the requested service and pass "service_request" for aux_state when
205 * calling restarter_set_states(). See inetd and startd for examples.
206 */
207int restarter_set_states(restarter_event_handle_t *, const char *,
208    restarter_instance_state_t, restarter_instance_state_t,
209    restarter_instance_state_t, restarter_instance_state_t, restarter_error_t,
210    const char *);
211int restarter_event_publish_retry(evchan_t *, const char *, const char *,
212    const char *, const char *, nvlist_t *, uint32_t);
213
214int restarter_store_contract(scf_instance_t *, ctid_t,
215    restarter_contract_type_t);
216int restarter_remove_contract(scf_instance_t *, ctid_t,
217    restarter_contract_type_t);
218
219ssize_t restarter_state_to_string(restarter_instance_state_t, char *, size_t);
220restarter_instance_state_t restarter_string_to_state(char *);
221
222#define	RESTARTER_METHOD_CONTEXT_VERSION	7
223
224struct method_context {
225	/* Stable */
226	uid_t		uid, euid;
227	gid_t		gid, egid;
228	int		ngroups;		/* -1 means use initgroups(). */
229	gid_t		groups[NGROUPS_MAX];
230	priv_set_t	*lpriv_set, *priv_set;
231	char		*corefile_pattern;	/* Optional. */
232	char		*project;		/* NULL for no change */
233	char		*resource_pool;		/* NULL for project default */
234	char		*working_dir;		/* NULL for :default */
235	char		**env;			/* NULL for no env */
236	size_t		env_sz;			/* size of env array */
237
238	/* Private */
239	char		*vbuf;
240	ssize_t		vbuf_sz;
241	struct passwd	pwd;
242	char		*pwbuf;
243	ssize_t		pwbufsz;
244};
245
246/*
247 * An error structure that contains a message string, and a type
248 * that can be used to determine course of action by the reciever
249 * of the error structure.
250 *
251 * type - usually will be an errno equivalent but could contain
252 * 	defined error types for exampe SCF_ERROR_XXX
253 * msg - must be at the end of the structure as if the message is
254 * 	longer than EMSGSIZE we will reallocate the structure to
255 * 	handle the overflow
256 */
257typedef struct mc_error {
258	int	destroy;	/* Flag to indicate destruction steps */
259	int	type;		/* Type of error for decision making */
260	int	size;		/* The size of the error message string */
261	char 	msg[RESTARTER_ERRMSGSZ];
262} mc_error_t;
263
264int restarter_rm_libs_loadable(void);
265/* instance, restarter name, method name, command line, structure pointer */
266mc_error_t *restarter_get_method_context(uint_t, scf_instance_t *,
267    scf_snapshot_t *, const char *, const char *, struct method_context **);
268void restarter_mc_error_destroy(mc_error_t *);
269int restarter_set_method_context(struct method_context *, const char **);
270void restarter_free_method_context(struct method_context *);
271
272
273int restarter_is_null_method(const char *);
274int restarter_is_kill_method(const char *);
275int restarter_is_kill_proc_method(const char *);
276
277/* Validate the inst fmri specified in  restarter_actions/auxiliary_fmri */
278int restarter_inst_validate_ractions_aux_fmri(scf_instance_t *);
279
280/* Delete instance's restarter_actions/auxiliary_fmri property */
281int restarter_inst_reset_ractions_aux_fmri(scf_instance_t *);
282
283/* Get boolean value from instance's restarter_actions/auxiliary_tty */
284int restarter_inst_ractions_from_tty(scf_instance_t *);
285
286/* Delete instance's restarter/auxiliary_fmri property */
287int restarter_inst_reset_aux_fmri(scf_instance_t *);
288
289/*
290 * Set instance's restarter/auxiliary_fmri, value come from
291 * restarter_actions/auxliary_fmri
292 */
293int restarter_inst_set_aux_fmri(scf_instance_t *);
294
295#ifdef	__cplusplus
296}
297#endif
298
299#endif	/* _LIBRESTART_H */
300