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 _INETD_IMPL_H
27#define	_INETD_IMPL_H
28
29/*
30 * Header file containing inetd's shared types/data structures and
31 * function declarations.
32 */
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <stdarg.h>
41#include <rpc/rpc.h>
42#include <assert.h>
43#include <libscf.h>
44#include <libinetutil.h>
45#include <inetsvc.h>
46#include <librestart.h>
47#include <libuutil.h>
48#include <wordexp.h>
49
50
51/*
52 * Number of consecutive retries of a repository operation that failed due
53 * to a broken connection performed before giving up and failing.
54 */
55#define	REP_OP_RETRIES 10
56
57/* retryable SMF method error */
58#define	SMF_EXIT_ERR_OTHER 1
59
60/* inetd's syslog ident string */
61#define	SYSLOG_IDENT    "inetd"
62
63/* Is this instance currently executing a method ? */
64#define	INST_IN_TRANSITION(i)	((i)->next_istate != IIS_NONE)
65
66/* Names of properties that inetd uses to store instance state. */
67#define	PR_NAME_NON_START_PID	"non_start_pid"
68#define	PR_NAME_START_PIDS	"start_pids"
69#define	PR_NAME_CUR_INT_STATE	"cur_state"
70#define	PR_NAME_NEXT_INT_STATE	"next_state"
71
72/* Name of the property group that holds debug flag */
73#define	PG_NAME_APPLICATION_CONFIG	"config"
74
75/* Name of the property which holds the debug flag value */
76#define	PR_NAME_DEBUG_FLAG	"debug"
77
78/*
79 * Instance states used internal to svc.inetd.
80 * NOTE: The states table in cmd/cmd-inetd/inetd/inetd.c relies on the
81 * ordering of this enumeration, so take care if modifying it.
82 */
83typedef enum {
84	IIS_UNINITIALIZED,
85	IIS_ONLINE,
86	IIS_IN_ONLINE_METHOD,
87	IIS_OFFLINE,
88	IIS_IN_OFFLINE_METHOD,
89	IIS_DISABLED,
90	IIS_IN_DISABLE_METHOD,
91	IIS_IN_REFRESH_METHOD,
92	IIS_MAINTENANCE,
93	IIS_OFFLINE_CONRATE,
94	IIS_OFFLINE_BIND,
95	IIS_OFFLINE_COPIES,
96	IIS_DEGRADED,
97	IIS_NONE
98} internal_inst_state_t;
99
100/*
101 * inetd's instance methods.
102 * NOTE: The methods table in cmd/cmd-inetd/inetd/util.c relies on the
103 * ordering of this enumeration, so take care if modifying it.
104 */
105typedef enum {
106	IM_START,
107	IM_ONLINE,
108	IM_OFFLINE,
109	IM_DISABLE,
110	IM_REFRESH,
111	NUM_METHODS,
112	IM_NONE
113} instance_method_t;
114
115/* Collection of information pertaining to a method */
116typedef struct {
117	char *exec_path;	/* path passed to exec() */
118
119	/*
120	 * Structure returned from wordexp(3c) that contains an expansion of the
121	 * exec property into a form suitable for exec(2).
122	 */
123	wordexp_t	exec_args_we;
124
125	/*
126	 * Copy of the first argument of the above wordexp_t structure in the
127	 * event that an alternate arg0 is provided, and we replace the first
128	 * argument with the alternate arg0. This is necessary so the
129	 * contents of the wordexp_t structure can be returned to their
130	 * original form as returned from wordexp(3c), which is a requirement
131	 * for calling wordfree(3c), wordexp()'s associated cleanup routine.
132	 */
133	const char	*wordexp_arg0_backup;
134
135	/* time a method can run for before being considered broken */
136	int		timeout;
137} method_info_t;
138
139typedef struct {
140	basic_cfg_t	*basic;
141	method_info_t	*methods[NUM_METHODS];
142} instance_cfg_t;
143
144/*
145 * Structure used to construct a list of int64_t's and their associated
146 * scf values. Used to store lists of process ids, internal states, and to
147 * store the associated scf value used when writing the values back to the
148 * repository.
149 */
150typedef struct {
151	int64_t		val;
152	scf_value_t	*scf_val;
153	uu_list_node_t	link;
154} rep_val_t;
155
156/* Structure containing the state and configuration of a service instance. */
157typedef struct {
158	char			*fmri;
159
160	/* fd we're going to take a connection on */
161	int			conn_fd;
162
163	/* number of copies of this instance active */
164	int64_t			copies;
165
166	/* connection rate counters */
167	int64_t			conn_rate_count;
168	time_t			conn_rate_start;
169
170	/* failure rate counters */
171	int64_t			fail_rate_count;
172	time_t			fail_rate_start;
173	/* bind failure count */
174	int64_t			bind_fail_count;
175
176	/* pids of currently running methods */
177	uu_list_t		*non_start_pid;
178	uu_list_t		*start_pids;
179
180	/* ctids of currently running start methods */
181	uu_list_t		*start_ctids;
182
183	/* remote address, used for TCP tracing */
184	struct sockaddr_storage	remote_addr;
185
186	internal_inst_state_t	cur_istate;
187	internal_inst_state_t	next_istate;
188
189	/* repository compatible versions of the above 2 states */
190	uu_list_t		*cur_istate_rep;
191	uu_list_t		*next_istate_rep;
192
193	/*
194	 * Current instance configuration resulting from its repository
195	 * configuration.
196	 */
197	instance_cfg_t		*config;
198
199	/*
200	 * Soon to be applied instance configuration. This configuration was
201	 * read during a refresh when this instance was online, and the
202	 * instance needed taking offline for this configuration to be applied.
203	 * The instance is currently on its way offline, and this configuration
204	 * will become the current configuration when it arrives there.
205	 */
206	instance_cfg_t		*new_config;
207
208	/* current pending conrate-offline/method timer; -1 if none pending */
209	iu_timer_id_t		timer_id;
210
211	/* current pending bind retry timer; -1 if none pending */
212	iu_timer_id_t		bind_timer_id;
213
214	/*
215	 * Flags that assist in the fanout of an instance arriving in the
216	 * offline state on-route to some other state.
217	 */
218	boolean_t		disable_req;
219	boolean_t		maintenance_req;
220	boolean_t		conn_rate_exceeded;
221	boolean_t		bind_retries_exceeded;
222
223	/*
224	 * Event waiting to be processed. RESTARTER_EVENT_TYPE_INVALID is used
225	 * to mean no event waiting.
226	 */
227	restarter_event_type_t	pending_rst_event;
228
229	/* link to next instance in list */
230	uu_list_node_t		link;
231} instance_t;
232
233
234/* Structure used to store information pertaining to instance method types. */
235typedef struct {
236	instance_method_t	method;
237	const char		*name;
238	internal_inst_state_t	dst_state;
239} method_type_info_t;
240
241
242extern uu_list_t *instance_list;
243extern struct pollfd *poll_fds;
244extern nfds_t num_pollfds;
245extern method_type_info_t methods[];
246extern iu_tq_t *timer_queue;
247extern uu_list_pool_t *conn_ind_pool;
248extern boolean_t debug_enabled;
249
250/*
251 * util.c
252 */
253extern void msg_init(void);
254extern void msg_fini(void);
255/* PRINTFLIKE1 */
256extern void debug_msg(const char *, ...);
257/* PRINTFLIKE1 */
258extern void error_msg(const char *, ...);
259/* PRINTFLIKE1 */
260extern void warn_msg(const char *, ...);
261extern void poll_fini(void);
262extern boolean_t isset_pollfd(int);
263extern void clear_pollfd(int);
264extern int set_pollfd(int, uint16_t);
265extern struct pollfd *find_pollfd(int);
266extern int safe_read(int, void *, size_t);
267extern boolean_t copies_limit_exceeded(instance_t *);
268extern void cancel_inst_timer(instance_t *);
269extern void cancel_bind_timer(instance_t *);
270extern void enable_blocking(int);
271extern void disable_blocking(int);
272
273/*
274 * tlx.c
275 */
276extern rpc_info_t *create_rpc_info(const char *, const char *, const char *,
277    int, int);
278extern void destroy_rpc_info(rpc_info_t *);
279extern boolean_t rpc_info_equal(const rpc_info_t *, const rpc_info_t *);
280extern int register_rpc_service(const char *, const rpc_info_t *);
281extern void unregister_rpc_service(const char *, const rpc_info_t *);
282extern int create_bound_endpoint(const instance_t *, tlx_info_t *);
283extern void close_net_fd(instance_t *, int);
284extern int tlx_accept(const char *, tlx_info_t *, struct sockaddr_storage *);
285extern struct t_call *dequeue_conind(uu_list_t *);
286extern int queue_conind(uu_list_t *, struct t_call *);
287extern void tlx_fini(void);
288extern int tlx_init(void);
289extern boolean_t tlx_info_equal(const tlx_info_t *, const tlx_info_t *,
290    boolean_t);
291extern void consume_wait_data(instance_t *, int);
292
293/*
294 * config.c
295 */
296extern int config_init(void);
297extern void config_fini(void);
298extern boolean_t socket_info_equal(const socket_info_t *, const socket_info_t *,
299    boolean_t);
300extern boolean_t method_info_equal(const method_info_t *,
301    const method_info_t *);
302extern struct method_context *read_method_context(const char *, const char *,
303    const char *);
304extern void destroy_instance_cfg(instance_cfg_t *);
305extern instance_cfg_t *read_instance_cfg(const char *);
306extern boolean_t bind_config_equal(const basic_cfg_t *, const basic_cfg_t *);
307extern int read_enable_merged(const char *, boolean_t *);
308extern void refresh_debug_flag(void);
309
310/*
311 * repval.c
312 */
313extern void repval_fini(void);
314extern int repval_init(void);
315extern uu_list_t *create_rep_val_list(void);
316extern void destroy_rep_val_list(uu_list_t *);
317extern scf_error_t store_rep_vals(uu_list_t *, const char *, const char *);
318extern scf_error_t retrieve_rep_vals(uu_list_t *, const char *, const char *);
319extern rep_val_t *find_rep_val(uu_list_t *, int64_t);
320extern int set_single_rep_val(uu_list_t *, int64_t);
321extern int64_t get_single_rep_val(uu_list_t *);
322extern int add_rep_val(uu_list_t *, int64_t);
323extern void remove_rep_val(uu_list_t *, int64_t);
324extern void empty_rep_val_list(uu_list_t *);
325extern int make_handle_bound(scf_handle_t *);
326extern int add_remove_contract(instance_t *, boolean_t, ctid_t);
327extern int iterate_repository_contracts(instance_t *, int);
328
329/*
330 * contracts.c
331 */
332extern int contract_init(void);
333extern void contract_fini(void);
334void contract_postfork(void);
335int contract_prefork(const char *, int);
336extern int get_latest_contract(ctid_t *cid);
337extern int adopt_contract(ctid_t, const char *);
338extern int abandon_contract(ctid_t);
339
340/*
341 * inetd.c
342 */
343extern void process_offline_inst(instance_t *);
344extern void process_non_start_term(instance_t *, int);
345extern void process_start_term(instance_t *, char *);
346extern void remove_method_ids(instance_t *, pid_t, ctid_t, instance_method_t);
347
348/*
349 * env.c
350 */
351char **set_smf_env(struct method_context *, instance_t *, const char *);
352
353/*
354 * wait.c
355 */
356extern int register_method(instance_t *, pid_t, ctid_t cid, instance_method_t,
357    char *);
358extern int method_init(void);
359extern void method_fini(void);
360extern void process_terminated_methods(void);
361extern void unregister_instance_methods(const instance_t *);
362extern void method_preexec(void);
363
364#ifdef __cplusplus
365}
366#endif
367
368#endif /* _INETD_IMPL_H */
369