librestart.h revision 759:3ca039a1de60
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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_LIBRESTART_H
28#define	_LIBRESTART_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#include <libcontract.h>
33#include <libscf.h>
34#include <limits.h>
35#include <priv.h>
36#include <pwd.h>
37#include <sys/types.h>
38
39#ifdef	__cplusplus
40extern "C" {
41#endif
42
43/*
44 * There are 3 parts to librestart.
45 *	1) The event protocol from the master restarter to its delegates.
46 *	2) A functional interface for updating the repository.
47 *	3) Convenience functions for common restarter tasks.
48 *
49 * Event protocol
50 *	We need a reliable event protocol, as there's no way to define
51 *	restarter events as idempotent.
52 *
53 *	Currently using sysevent channels as the reliable event implementation.
54 *	This could change if the implementation proves unsuitable, but
55 *	the API defined here should abstract anything but a change in
56 *	the fundamental event model.
57 *
58 *	We offer functions to tease apart the event rather than generic
59 *	nvpair interfaces. This is because each event type has a well-
60 *	defined set of fields.
61 */
62
63typedef struct restarter_event_handle restarter_event_handle_t;
64typedef struct restarter_event restarter_event_t;
65
66typedef uint32_t restarter_event_type_t;
67
68/*
69 * Define an event protocol version. In theory, we could use this in
70 * the future to support delegated restarters which use an older
71 * protocol. In practice, increment RESTARTER_EVENT_VERSION whenever the
72 * protocol might have changed.
73 */
74#define	RESTARTER_EVENT_VERSION		4
75
76#define	RESTARTER_FLAG_DEBUG		1
77
78/*
79 * Event types
80 *	RESTARTER_EVENT_TYPE_ADD_INSTANCE
81 *		responsible for a new (stopped) instance
82 *	RESTARTER_EVENT_TYPE_REMOVE_INSTANCE
83 *		no longer responsible for this instance; stop it and return
84 *	RESTARTER_EVENT_TYPE_ENABLE
85 *		no guarantee that dependencies are met; see
86 *		RESTARTER_EVENT_TYPE_START
87 *	RESTARTER_EVENT_TYPE_DISABLE
88 *		no guarantee that instance was running
89 *	RESTARTER_EVENT_TYPE_ADMIN_DEGRADED
90 *	RESTARTER_EVENT_TYPE_ADMIN_REFRESH
91 *	RESTARTER_EVENT_TYPE_ADMIN_RESTART
92 *	RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF
93 *	RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON
94 *	RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE
95 *	RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF
96 *	RESTARTER_EVENT_TYPE_STOP
97 *		dependencies are, or are becoming, unsatisfied
98 *	RESTARTER_EVENT_TYPE_START
99 *		dependencies have become satisfied
100 *	RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE
101 *		instance caused a dependency cycle
102 *	RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY
103 *		instance has an invalid dependency
104 */
105
106#define	RESTARTER_EVENT_TYPE_INVALID			0
107#define	RESTARTER_EVENT_TYPE_ADD_INSTANCE		1
108#define	RESTARTER_EVENT_TYPE_REMOVE_INSTANCE		2
109#define	RESTARTER_EVENT_TYPE_ENABLE			3
110#define	RESTARTER_EVENT_TYPE_DISABLE			4
111#define	RESTARTER_EVENT_TYPE_ADMIN_DEGRADED		5
112#define	RESTARTER_EVENT_TYPE_ADMIN_REFRESH		6
113#define	RESTARTER_EVENT_TYPE_ADMIN_RESTART		7
114#define	RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF		8
115#define	RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON		9
116#define	RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE	10
117#define	RESTARTER_EVENT_TYPE_STOP			11
118#define	RESTARTER_EVENT_TYPE_START			12
119#define	RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE		13
120#define	RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY		14
121#define	RESTARTER_EVENT_TYPE_ADMIN_DISABLE		15
122
123#define	RESTARTER_EVENT_ERROR			-1
124
125#define	RESTARTER_EVENT_INSTANCE_DISABLED	0
126#define	RESTARTER_EVENT_INSTANCE_ENABLED	1
127
128typedef enum {
129	RESTARTER_STATE_NONE,
130	RESTARTER_STATE_UNINIT,
131	RESTARTER_STATE_MAINT,
132	RESTARTER_STATE_OFFLINE,
133	RESTARTER_STATE_DISABLED,
134	RESTARTER_STATE_ONLINE,
135	RESTARTER_STATE_DEGRADED
136} restarter_instance_state_t;
137
138/*
139 * These values are ordered by severity of required restart, as we use
140 * integer comparisons to determine error flow.
141 */
142typedef enum {
143	RERR_UNSUPPORTED = -1,
144	RERR_NONE = 0,			/* no error, restart, refresh */
145	RERR_FAULT,			/* fault occurred */
146	RERR_RESTART,			/* transition due to restart */
147	RERR_REFRESH			/* transition due to refresh */
148} restarter_error_t;
149
150/*
151 * restarter_store_contract() and restarter_remove_contract() types
152 */
153typedef enum {
154	RESTARTER_CONTRACT_PRIMARY,
155	RESTARTER_CONTRACT_TRANSIENT
156} restarter_contract_type_t;
157
158/*
159 * restarter_bind_handle() registers a delegate with svc.startd to
160 * begin consuming events.
161 *
162 * On initial bind, the delgated restarter receives an event for each
163 * instance it is responsible for, as if that instance was new.
164 *
165 * callers must have superuser privileges
166 *
167 * The event handler can return 0 for success, or EAGAIN to request
168 * retry of event delivery. EAGAIN may be returned 3 times before the
169 * event is discarded.
170 */
171int restarter_bind_handle(uint32_t, const char *,
172    int (*event_handler)(restarter_event_t *), int,
173    restarter_event_handle_t **);
174
175restarter_event_type_t restarter_event_get_type(restarter_event_t *);
176uint64_t restarter_event_get_seq(restarter_event_t *);
177void restarter_event_get_time(restarter_event_t *, hrtime_t *);
178ssize_t restarter_event_get_instance(restarter_event_t *, char *, size_t);
179restarter_event_handle_t *restarter_event_get_handle(restarter_event_t *);
180
181/*
182 * The following functions work only on certain types of events.
183 * They fail with a return of -1 if they're called on an inappropriate event.
184 */
185int restarter_event_get_enabled(restarter_event_t *);
186int restarter_event_get_current_states(restarter_event_t *,
187    restarter_instance_state_t *, restarter_instance_state_t *);
188
189/*
190 * Functions for updating the repository.
191 */
192int restarter_set_states(restarter_event_handle_t *, const char *,
193    restarter_instance_state_t, restarter_instance_state_t,
194    restarter_instance_state_t, restarter_instance_state_t, restarter_error_t,
195    const char *);
196
197int restarter_store_contract(scf_instance_t *, ctid_t,
198    restarter_contract_type_t);
199int restarter_remove_contract(scf_instance_t *, ctid_t,
200    restarter_contract_type_t);
201
202ssize_t restarter_state_to_string(restarter_instance_state_t, char *, size_t);
203restarter_instance_state_t restarter_string_to_state(char *);
204
205#define	RESTARTER_METHOD_CONTEXT_VERSION	6
206
207struct method_context {
208	/* Stable */
209	uid_t		uid, euid;
210	gid_t		gid, egid;
211	int		ngroups;		/* -1 means use initgroups(). */
212	gid_t		groups[NGROUPS_MAX-1];
213	priv_set_t	*lpriv_set, *priv_set;
214	char		*corefile_pattern;	/* Optional. */
215	char		*project;		/* NULL for no change */
216	char		*resource_pool;		/* NULL for project default */
217	char		*working_dir;		/* NULL for :default */
218	char		**env;			/* NULL for no env */
219	size_t		env_sz;			/* size of env array */
220
221	/* Private */
222	char		*vbuf;
223	ssize_t		vbuf_sz;
224	struct passwd	pwd;
225	char		*pwbuf;
226	ssize_t		pwbufsz;
227};
228
229int restarter_rm_libs_loadable(void);
230/* instance, restarter name, method name, command line, structure pointer */
231const char *restarter_get_method_context(uint_t, scf_instance_t *,
232    scf_snapshot_t *, const char *, const char *, struct method_context **);
233int restarter_set_method_context(struct method_context *, const char **);
234void restarter_free_method_context(struct method_context *);
235
236
237int restarter_is_null_method(const char *);
238int restarter_is_kill_method(const char *);
239int restarter_is_kill_proc_method(const char *);
240
241#ifdef	__cplusplus
242}
243#endif
244
245#endif	/* _LIBRESTART_H */
246