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