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