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