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