summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cmd-inet/usr.lib/inetd/inetd_impl.h
blob: 463c92eddaf077859a466f91662bfc790dbd6e73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _INETD_IMPL_H
#define	_INETD_IMPL_H

/*
 * Header file containing inetd's shared types/data structures and
 * function declarations.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/socket.h>
#include <stdarg.h>
#include <rpc/rpc.h>
#include <assert.h>
#include <libscf.h>
#include <libinetutil.h>
#include <inetsvc.h>
#include <librestart.h>
#include <libuutil.h>
#include <wordexp.h>


/*
 * Number of consecutive retries of a repository operation that failed due
 * to a broken connection performed before giving up and failing.
 */
#define	REP_OP_RETRIES 10

/* retryable SMF method error */
#define	SMF_EXIT_ERR_OTHER 1

/* inetd's syslog ident string */
#define	SYSLOG_IDENT    "inetd"

/* Is this instance currently executing a method ? */
#define	INST_IN_TRANSITION(i)	((i)->next_istate != IIS_NONE)

/* Names of properties that inetd uses to store instance state. */
#define	PR_NAME_NON_START_PID	"non_start_pid"
#define	PR_NAME_START_PIDS	"start_pids"
#define	PR_NAME_CUR_INT_STATE	"cur_state"
#define	PR_NAME_NEXT_INT_STATE	"next_state"

/* Name of the property group that holds debug flag */
#define	PG_NAME_APPLICATION_CONFIG	"config"

/* Name of the property which holds the debug flag value */
#define	PR_NAME_DEBUG_FLAG	"debug"

/*
 * Instance states used internal to svc.inetd.
 * NOTE: The states table in cmd/cmd-inetd/inetd/inetd.c relies on the
 * ordering of this enumeration, so take care if modifying it.
 */
typedef enum {
	IIS_UNINITIALIZED,
	IIS_ONLINE,
	IIS_IN_ONLINE_METHOD,
	IIS_OFFLINE,
	IIS_IN_OFFLINE_METHOD,
	IIS_DISABLED,
	IIS_IN_DISABLE_METHOD,
	IIS_IN_REFRESH_METHOD,
	IIS_MAINTENANCE,
	IIS_OFFLINE_CONRATE,
	IIS_OFFLINE_BIND,
	IIS_OFFLINE_COPIES,
	IIS_DEGRADED,
	IIS_NONE
} internal_inst_state_t;

/*
 * inetd's instance methods.
 * NOTE: The methods table in cmd/cmd-inetd/inetd/util.c relies on the
 * ordering of this enumeration, so take care if modifying it.
 */
typedef enum {
	IM_START,
	IM_ONLINE,
	IM_OFFLINE,
	IM_DISABLE,
	IM_REFRESH,
	NUM_METHODS,
	IM_NONE
} instance_method_t;

/* Collection of information pertaining to a method */
typedef struct {
	char *exec_path;	/* path passed to exec() */

	/*
	 * Structure returned from wordexp(3c) that contains an expansion of the
	 * exec property into a form suitable for exec(2).
	 */
	wordexp_t	exec_args_we;

	/*
	 * Copy of the first argument of the above wordexp_t structure in the
	 * event that an alternate arg0 is provided, and we replace the first
	 * argument with the alternate arg0. This is necessary so the
	 * contents of the wordexp_t structure can be returned to their
	 * original form as returned from wordexp(3c), which is a requirement
	 * for calling wordfree(3c), wordexp()'s associated cleanup routine.
	 */
	const char	*wordexp_arg0_backup;

	/* time a method can run for before being considered broken */
	int		timeout;
} method_info_t;

typedef struct {
	basic_cfg_t	*basic;
	method_info_t	*methods[NUM_METHODS];
} instance_cfg_t;

/*
 * Structure used to construct a list of int64_t's and their associated
 * scf values. Used to store lists of process ids, internal states, and to
 * store the associated scf value used when writing the values back to the
 * repository.
 */
typedef struct {
	int64_t		val;
	scf_value_t	*scf_val;
	uu_list_node_t	link;
} rep_val_t;

/* Structure containing the state and configuration of a service instance. */
typedef struct {
	char			*fmri;

	/* fd we're going to take a connection on */
	int			conn_fd;

	/* number of copies of this instance active */
	int64_t			copies;

	/* connection rate counters */
	int64_t			conn_rate_count;
	time_t			conn_rate_start;

	/* failure rate counters */
	int64_t			fail_rate_count;
	time_t			fail_rate_start;
	/* bind failure count */
	int64_t			bind_fail_count;

	/* pids of currently running methods */
	uu_list_t		*non_start_pid;
	uu_list_t		*start_pids;

	/* ctids of currently running start methods */
	uu_list_t		*start_ctids;

	/* remote address, used for TCP tracing */
	struct sockaddr_storage	remote_addr;

	internal_inst_state_t	cur_istate;
	internal_inst_state_t	next_istate;

	/* repository compatible versions of the above 2 states */
	uu_list_t		*cur_istate_rep;
	uu_list_t		*next_istate_rep;

	/*
	 * Current instance configuration resulting from its repository
	 * configuration.
	 */
	instance_cfg_t		*config;

	/*
	 * Soon to be applied instance configuration. This configuration was
	 * read during a refresh when this instance was online, and the
	 * instance needed taking offline for this configuration to be applied.
	 * The instance is currently on its way offline, and this configuration
	 * will become the current configuration when it arrives there.
	 */
	instance_cfg_t		*new_config;

	/* current pending conrate-offline/method timer; -1 if none pending */
	iu_timer_id_t		timer_id;

	/* current pending bind retry timer; -1 if none pending */
	iu_timer_id_t		bind_timer_id;

	/*
	 * Flags that assist in the fanout of an instance arriving in the
	 * offline state on-route to some other state.
	 */
	boolean_t		disable_req;
	boolean_t		maintenance_req;
	boolean_t		conn_rate_exceeded;
	boolean_t		bind_retries_exceeded;

	/*
	 * Event waiting to be processed. RESTARTER_EVENT_TYPE_INVALID is used
	 * to mean no event waiting.
	 */
	restarter_event_type_t	pending_rst_event;

	/* link to next instance in list */
	uu_list_node_t		link;
} instance_t;


/* Structure used to store information pertaining to instance method types. */
typedef struct {
	instance_method_t	method;
	const char		*name;
	internal_inst_state_t	dst_state;
} method_type_info_t;


extern uu_list_t *instance_list;
extern struct pollfd *poll_fds;
extern nfds_t num_pollfds;
extern method_type_info_t methods[];
extern iu_tq_t *timer_queue;
extern uu_list_pool_t *conn_ind_pool;
extern boolean_t debug_enabled;

/*
 * util.c
 */
extern void msg_init(void);
extern void msg_fini(void);
/* PRINTFLIKE1 */
extern void debug_msg(const char *, ...);
/* PRINTFLIKE1 */
extern void error_msg(const char *, ...);
/* PRINTFLIKE1 */
extern void warn_msg(const char *, ...);
extern void poll_fini(void);
extern boolean_t isset_pollfd(int);
extern void clear_pollfd(int);
extern int set_pollfd(int, uint16_t);
extern struct pollfd *find_pollfd(int);
extern int safe_read(int, void *, size_t);
extern boolean_t copies_limit_exceeded(instance_t *);
extern void cancel_inst_timer(instance_t *);
extern void cancel_bind_timer(instance_t *);
extern void enable_blocking(int);
extern void disable_blocking(int);

/*
 * tlx.c
 */
extern rpc_info_t *create_rpc_info(const char *, const char *, const char *,
    int, int);
extern void destroy_rpc_info(rpc_info_t *);
extern boolean_t rpc_info_equal(const rpc_info_t *, const rpc_info_t *);
extern int register_rpc_service(const char *, const rpc_info_t *);
extern void unregister_rpc_service(const char *, const rpc_info_t *);
extern int create_bound_endpoint(const instance_t *, tlx_info_t *);
extern void close_net_fd(instance_t *, int);
extern int tlx_accept(const char *, tlx_info_t *, struct sockaddr_storage *);
extern struct t_call *dequeue_conind(uu_list_t *);
extern int queue_conind(uu_list_t *, struct t_call *);
extern void tlx_fini(void);
extern int tlx_init(void);
extern boolean_t tlx_info_equal(const tlx_info_t *, const tlx_info_t *,
    boolean_t);
extern void consume_wait_data(instance_t *, int);

/*
 * config.c
 */
extern int config_init(void);
extern void config_fini(void);
extern boolean_t socket_info_equal(const socket_info_t *, const socket_info_t *,
    boolean_t);
extern boolean_t method_info_equal(const method_info_t *,
    const method_info_t *);
extern struct method_context *read_method_context(const char *, const char *,
    const char *);
extern void destroy_instance_cfg(instance_cfg_t *);
extern instance_cfg_t *read_instance_cfg(const char *);
extern boolean_t bind_config_equal(const basic_cfg_t *, const basic_cfg_t *);
extern int read_enable_merged(const char *, boolean_t *);
extern void refresh_debug_flag(void);

/*
 * repval.c
 */
extern void repval_fini(void);
extern int repval_init(void);
extern uu_list_t *create_rep_val_list(void);
extern void destroy_rep_val_list(uu_list_t *);
extern scf_error_t store_rep_vals(uu_list_t *, const char *, const char *);
extern scf_error_t retrieve_rep_vals(uu_list_t *, const char *, const char *);
extern rep_val_t *find_rep_val(uu_list_t *, int64_t);
extern int set_single_rep_val(uu_list_t *, int64_t);
extern int64_t get_single_rep_val(uu_list_t *);
extern int add_rep_val(uu_list_t *, int64_t);
extern void remove_rep_val(uu_list_t *, int64_t);
extern void empty_rep_val_list(uu_list_t *);
extern int make_handle_bound(scf_handle_t *);
extern int add_remove_contract(instance_t *, boolean_t, ctid_t);
extern int iterate_repository_contracts(instance_t *, int);

/*
 * contracts.c
 */
extern int contract_init(void);
extern void contract_fini(void);
void contract_postfork(void);
int contract_prefork(const char *, int);
extern int get_latest_contract(ctid_t *cid);
extern int adopt_contract(ctid_t, const char *);
extern int abandon_contract(ctid_t);

/*
 * inetd.c
 */
extern void process_offline_inst(instance_t *);
extern void process_non_start_term(instance_t *, int);
extern void process_start_term(instance_t *, char *);
extern void remove_method_ids(instance_t *, pid_t, ctid_t, instance_method_t);

/*
 * env.c
 */
char **set_smf_env(struct method_context *, instance_t *, const char *);

/*
 * wait.c
 */
extern int register_method(instance_t *, pid_t, ctid_t cid, instance_method_t,
    char *);
extern int method_init(void);
extern void method_fini(void);
extern void process_terminated_methods(void);
extern void unregister_instance_methods(const instance_t *);
extern void method_preexec(void);

#ifdef __cplusplus
}
#endif

#endif /* _INETD_IMPL_H */