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