10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*3175Sskamm * Common Development and Distribution License (the "License"). 6*3175Sskamm * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*3175Sskamm * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _INETD_IMPL_H 270Sstevel@tonic-gate #define _INETD_IMPL_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 310Sstevel@tonic-gate 320Sstevel@tonic-gate /* 330Sstevel@tonic-gate * Header file containing inetd's shared types/data structures and 340Sstevel@tonic-gate * function declarations. 350Sstevel@tonic-gate */ 360Sstevel@tonic-gate 370Sstevel@tonic-gate #ifdef __cplusplus 380Sstevel@tonic-gate extern "C" { 390Sstevel@tonic-gate #endif 400Sstevel@tonic-gate 410Sstevel@tonic-gate #include <sys/types.h> 420Sstevel@tonic-gate #include <sys/socket.h> 430Sstevel@tonic-gate #include <stdarg.h> 440Sstevel@tonic-gate #include <rpc/rpc.h> 450Sstevel@tonic-gate #include <assert.h> 460Sstevel@tonic-gate #include <libscf.h> 470Sstevel@tonic-gate #include <libinetutil.h> 480Sstevel@tonic-gate #include <inetsvc.h> 490Sstevel@tonic-gate #include <librestart.h> 500Sstevel@tonic-gate #include <libuutil.h> 510Sstevel@tonic-gate #include <wordexp.h> 520Sstevel@tonic-gate 530Sstevel@tonic-gate 540Sstevel@tonic-gate /* 550Sstevel@tonic-gate * Number of consecutive retries of a repository operation that failed due 560Sstevel@tonic-gate * to a broken connection performed before giving up and failing. 570Sstevel@tonic-gate */ 580Sstevel@tonic-gate #define REP_OP_RETRIES 10 590Sstevel@tonic-gate 600Sstevel@tonic-gate /* retryable SMF method error */ 610Sstevel@tonic-gate #define SMF_EXIT_ERR_OTHER 1 620Sstevel@tonic-gate 630Sstevel@tonic-gate /* inetd's syslog ident string */ 640Sstevel@tonic-gate #define SYSLOG_IDENT "inetd" 650Sstevel@tonic-gate 660Sstevel@tonic-gate /* Is this instance currently executing a method ? */ 670Sstevel@tonic-gate #define INST_IN_TRANSITION(i) ((i)->next_istate != IIS_NONE) 680Sstevel@tonic-gate 690Sstevel@tonic-gate /* Names of properties that inetd uses to store instance state. */ 700Sstevel@tonic-gate #define PR_NAME_NON_START_PID "non_start_pid" 710Sstevel@tonic-gate #define PR_NAME_START_PIDS "start_pids" 720Sstevel@tonic-gate #define PR_NAME_CUR_INT_STATE "cur_state" 730Sstevel@tonic-gate #define PR_NAME_NEXT_INT_STATE "next_state" 740Sstevel@tonic-gate 750Sstevel@tonic-gate /* Connection backlog applied to connection oriented services. */ 760Sstevel@tonic-gate #define CONNECTION_BACKLOG 10 770Sstevel@tonic-gate 780Sstevel@tonic-gate /* 790Sstevel@tonic-gate * Instance states used internal to svc.inetd. 800Sstevel@tonic-gate * NOTE: The states table in cmd/cmd-inetd/inetd/inetd.c relies on the 810Sstevel@tonic-gate * ordering of this enumeration, so take care if modifying it. 820Sstevel@tonic-gate */ 830Sstevel@tonic-gate typedef enum { 840Sstevel@tonic-gate IIS_UNINITIALIZED, 850Sstevel@tonic-gate IIS_ONLINE, 860Sstevel@tonic-gate IIS_IN_ONLINE_METHOD, 870Sstevel@tonic-gate IIS_OFFLINE, 880Sstevel@tonic-gate IIS_IN_OFFLINE_METHOD, 890Sstevel@tonic-gate IIS_DISABLED, 900Sstevel@tonic-gate IIS_IN_DISABLE_METHOD, 910Sstevel@tonic-gate IIS_IN_REFRESH_METHOD, 920Sstevel@tonic-gate IIS_MAINTENANCE, 930Sstevel@tonic-gate IIS_OFFLINE_CONRATE, 940Sstevel@tonic-gate IIS_OFFLINE_BIND, 950Sstevel@tonic-gate IIS_OFFLINE_COPIES, 960Sstevel@tonic-gate IIS_DEGRADED, 970Sstevel@tonic-gate IIS_NONE 980Sstevel@tonic-gate } internal_inst_state_t; 990Sstevel@tonic-gate 1000Sstevel@tonic-gate /* 1010Sstevel@tonic-gate * inetd's instance methods. 1020Sstevel@tonic-gate * NOTE: The methods table in cmd/cmd-inetd/inetd/util.c relies on the 1030Sstevel@tonic-gate * ordering of this enumeration, so take care if modifying it. 1040Sstevel@tonic-gate */ 1050Sstevel@tonic-gate typedef enum { 1060Sstevel@tonic-gate IM_START, 1070Sstevel@tonic-gate IM_ONLINE, 1080Sstevel@tonic-gate IM_OFFLINE, 1090Sstevel@tonic-gate IM_DISABLE, 1100Sstevel@tonic-gate IM_REFRESH, 1110Sstevel@tonic-gate NUM_METHODS, 1120Sstevel@tonic-gate IM_NONE 1130Sstevel@tonic-gate } instance_method_t; 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate /* Collection of information pertaining to a method */ 1160Sstevel@tonic-gate typedef struct { 1170Sstevel@tonic-gate char *exec_path; /* path passed to exec() */ 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate /* 1200Sstevel@tonic-gate * Structure returned from wordexp(3c) that contains an expansion of the 1210Sstevel@tonic-gate * exec property into a form suitable for exec(2). 1220Sstevel@tonic-gate */ 1230Sstevel@tonic-gate wordexp_t exec_args_we; 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate /* 1260Sstevel@tonic-gate * Copy of the first argument of the above wordexp_t structure in the 1270Sstevel@tonic-gate * event that an alternate arg0 is provided, and we replace the first 1280Sstevel@tonic-gate * argument with the alternate arg0. This is necessary so the 1290Sstevel@tonic-gate * contents of the wordexp_t structure can be returned to their 1300Sstevel@tonic-gate * original form as returned from wordexp(3c), which is a requirement 1310Sstevel@tonic-gate * for calling wordfree(3c), wordexp()'s associated cleanup routine. 1320Sstevel@tonic-gate */ 1330Sstevel@tonic-gate const char *wordexp_arg0_backup; 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate /* time a method can run for before being considered broken */ 1360Sstevel@tonic-gate int timeout; 1370Sstevel@tonic-gate } method_info_t; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate typedef struct { 1400Sstevel@tonic-gate basic_cfg_t *basic; 1410Sstevel@tonic-gate method_info_t *methods[NUM_METHODS]; 1420Sstevel@tonic-gate } instance_cfg_t; 1430Sstevel@tonic-gate 1440Sstevel@tonic-gate /* 1450Sstevel@tonic-gate * Structure used to construct a list of int64_t's and their associated 1460Sstevel@tonic-gate * scf values. Used to store lists of process ids, internal states, and to 1470Sstevel@tonic-gate * store the associated scf value used when writing the values back to the 1480Sstevel@tonic-gate * repository. 1490Sstevel@tonic-gate */ 1500Sstevel@tonic-gate typedef struct { 1510Sstevel@tonic-gate int64_t val; 1520Sstevel@tonic-gate scf_value_t *scf_val; 1530Sstevel@tonic-gate uu_list_node_t link; 1540Sstevel@tonic-gate } rep_val_t; 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate /* Structure containing the state and configuration of a service instance. */ 1570Sstevel@tonic-gate typedef struct { 1580Sstevel@tonic-gate char *fmri; 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate /* fd we're going to take a connection on */ 1610Sstevel@tonic-gate int conn_fd; 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate /* number of copies of this instance active */ 1640Sstevel@tonic-gate int64_t copies; 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate /* connection rate counters */ 1670Sstevel@tonic-gate int64_t conn_rate_count; 1680Sstevel@tonic-gate time_t conn_rate_start; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate /* failure rate counters */ 1710Sstevel@tonic-gate int64_t fail_rate_count; 1720Sstevel@tonic-gate time_t fail_rate_start; 1730Sstevel@tonic-gate /* bind failure count */ 1740Sstevel@tonic-gate int64_t bind_fail_count; 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate /* pids of currently running methods */ 1770Sstevel@tonic-gate uu_list_t *non_start_pid; 1780Sstevel@tonic-gate uu_list_t *start_pids; 1790Sstevel@tonic-gate 180*3175Sskamm /* ctids of currently running start methods */ 181*3175Sskamm uu_list_t *start_ctids; 182*3175Sskamm 1830Sstevel@tonic-gate /* remote address, used for TCP tracing */ 1840Sstevel@tonic-gate struct sockaddr_storage remote_addr; 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate internal_inst_state_t cur_istate; 1870Sstevel@tonic-gate internal_inst_state_t next_istate; 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate /* repository compatible versions of the above 2 states */ 1900Sstevel@tonic-gate uu_list_t *cur_istate_rep; 1910Sstevel@tonic-gate uu_list_t *next_istate_rep; 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate /* 1940Sstevel@tonic-gate * Current instance configuration resulting from its repository 1950Sstevel@tonic-gate * configuration. 1960Sstevel@tonic-gate */ 1970Sstevel@tonic-gate instance_cfg_t *config; 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate /* 2000Sstevel@tonic-gate * Soon to be applied instance configuration. This configuration was 2010Sstevel@tonic-gate * read during a refresh when this instance was online, and the 2020Sstevel@tonic-gate * instance needed taking offline for this configuration to be applied. 2030Sstevel@tonic-gate * The instance is currently on its way offline, and this configuration 2040Sstevel@tonic-gate * will become the current configuration when it arrives there. 2050Sstevel@tonic-gate */ 2060Sstevel@tonic-gate instance_cfg_t *new_config; 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate /* current pending conrate-offline/method timer; -1 if none pending */ 2090Sstevel@tonic-gate iu_timer_id_t timer_id; 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate /* current pending bind retry timer; -1 if none pending */ 2120Sstevel@tonic-gate iu_timer_id_t bind_timer_id; 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate /* 2150Sstevel@tonic-gate * Flags that assist in the fanout of an instance arriving in the 2160Sstevel@tonic-gate * offline state on-route to some other state. 2170Sstevel@tonic-gate */ 2180Sstevel@tonic-gate boolean_t disable_req; 2190Sstevel@tonic-gate boolean_t maintenance_req; 2200Sstevel@tonic-gate boolean_t conn_rate_exceeded; 2210Sstevel@tonic-gate boolean_t bind_retries_exceeded; 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate /* 2240Sstevel@tonic-gate * Event waiting to be processed. RESTARTER_EVENT_TYPE_INVALID is used 2250Sstevel@tonic-gate * to mean no event waiting. 2260Sstevel@tonic-gate */ 2270Sstevel@tonic-gate restarter_event_type_t pending_rst_event; 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate /* link to next instance in list */ 2300Sstevel@tonic-gate uu_list_node_t link; 2310Sstevel@tonic-gate } instance_t; 2320Sstevel@tonic-gate 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate /* Structure used to store information pertaining to instance method types. */ 2350Sstevel@tonic-gate typedef struct { 2360Sstevel@tonic-gate instance_method_t method; 2370Sstevel@tonic-gate const char *name; 2380Sstevel@tonic-gate internal_inst_state_t dst_state; 2390Sstevel@tonic-gate } method_type_info_t; 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate extern uu_list_t *instance_list; 2430Sstevel@tonic-gate extern struct pollfd *poll_fds; 2440Sstevel@tonic-gate extern nfds_t num_pollfds; 2450Sstevel@tonic-gate extern method_type_info_t methods[]; 2460Sstevel@tonic-gate extern iu_tq_t *timer_queue; 2470Sstevel@tonic-gate extern uu_list_pool_t *conn_ind_pool; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate /* 2500Sstevel@tonic-gate * util.c 2510Sstevel@tonic-gate */ 2520Sstevel@tonic-gate extern void msg_init(void); 2530Sstevel@tonic-gate extern void msg_fini(void); 2540Sstevel@tonic-gate /* PRINTFLIKE1 */ 2550Sstevel@tonic-gate extern void debug_msg(const char *, ...); 2560Sstevel@tonic-gate /* PRINTFLIKE1 */ 2570Sstevel@tonic-gate extern void error_msg(const char *, ...); 2580Sstevel@tonic-gate /* PRINTFLIKE1 */ 2590Sstevel@tonic-gate extern void warn_msg(const char *, ...); 2600Sstevel@tonic-gate extern void poll_fini(void); 2610Sstevel@tonic-gate extern boolean_t isset_pollfd(int); 2620Sstevel@tonic-gate extern void clear_pollfd(int); 2630Sstevel@tonic-gate extern int set_pollfd(int, uint16_t); 2640Sstevel@tonic-gate extern struct pollfd *find_pollfd(int); 2650Sstevel@tonic-gate extern int safe_read(int, void *, size_t); 2660Sstevel@tonic-gate extern boolean_t copies_limit_exceeded(instance_t *); 2670Sstevel@tonic-gate extern void cancel_inst_timer(instance_t *); 2680Sstevel@tonic-gate extern void cancel_bind_timer(instance_t *); 2690Sstevel@tonic-gate extern void enable_blocking(int); 2700Sstevel@tonic-gate extern void disable_blocking(int); 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate /* 2730Sstevel@tonic-gate * tlx.c 2740Sstevel@tonic-gate */ 2750Sstevel@tonic-gate extern rpc_info_t *create_rpc_info(const char *, const char *, const char *, 2760Sstevel@tonic-gate int, int); 2770Sstevel@tonic-gate extern void destroy_rpc_info(rpc_info_t *); 2780Sstevel@tonic-gate extern boolean_t rpc_info_equal(const rpc_info_t *, const rpc_info_t *); 2790Sstevel@tonic-gate extern int register_rpc_service(const char *, const rpc_info_t *); 2800Sstevel@tonic-gate extern void unregister_rpc_service(const char *, const rpc_info_t *); 2810Sstevel@tonic-gate extern int create_bound_endpoint(const char *, tlx_info_t *); 2820Sstevel@tonic-gate extern void close_net_fd(instance_t *, int); 2830Sstevel@tonic-gate extern int tlx_accept(const char *, tlx_info_t *, struct sockaddr_storage *); 2840Sstevel@tonic-gate extern struct t_call *dequeue_conind(uu_list_t *); 2850Sstevel@tonic-gate extern int queue_conind(uu_list_t *, struct t_call *); 2860Sstevel@tonic-gate extern void tlx_fini(void); 2870Sstevel@tonic-gate extern int tlx_init(void); 2880Sstevel@tonic-gate extern boolean_t tlx_info_equal(const tlx_info_t *, const tlx_info_t *, 2890Sstevel@tonic-gate boolean_t); 2900Sstevel@tonic-gate extern void consume_wait_data(instance_t *, int); 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate /* 2930Sstevel@tonic-gate * config.c 2940Sstevel@tonic-gate */ 2950Sstevel@tonic-gate extern int config_init(void); 2960Sstevel@tonic-gate extern void config_fini(void); 2970Sstevel@tonic-gate extern boolean_t socket_info_equal(const socket_info_t *, const socket_info_t *, 2980Sstevel@tonic-gate boolean_t); 2990Sstevel@tonic-gate extern boolean_t method_info_equal(const method_info_t *, 3000Sstevel@tonic-gate const method_info_t *); 3010Sstevel@tonic-gate extern struct method_context *read_method_context(const char *, const char *, 3020Sstevel@tonic-gate const char *, const char **); 3030Sstevel@tonic-gate extern void destroy_instance_cfg(instance_cfg_t *); 3040Sstevel@tonic-gate extern instance_cfg_t *read_instance_cfg(const char *); 3050Sstevel@tonic-gate extern boolean_t bind_config_equal(const basic_cfg_t *, const basic_cfg_t *); 3060Sstevel@tonic-gate extern int read_enable_merged(const char *, boolean_t *); 3070Sstevel@tonic-gate 3080Sstevel@tonic-gate /* 3090Sstevel@tonic-gate * repval.c 3100Sstevel@tonic-gate */ 3110Sstevel@tonic-gate extern void repval_fini(void); 3120Sstevel@tonic-gate extern int repval_init(void); 3130Sstevel@tonic-gate extern uu_list_t *create_rep_val_list(void); 3140Sstevel@tonic-gate extern void destroy_rep_val_list(uu_list_t *); 3150Sstevel@tonic-gate extern scf_error_t store_rep_vals(uu_list_t *, const char *, const char *); 3160Sstevel@tonic-gate extern scf_error_t retrieve_rep_vals(uu_list_t *, const char *, const char *); 3170Sstevel@tonic-gate extern rep_val_t *find_rep_val(uu_list_t *, int64_t); 3180Sstevel@tonic-gate extern int set_single_rep_val(uu_list_t *, int64_t); 3190Sstevel@tonic-gate extern int64_t get_single_rep_val(uu_list_t *); 3200Sstevel@tonic-gate extern int add_rep_val(uu_list_t *, int64_t); 3210Sstevel@tonic-gate extern void remove_rep_val(uu_list_t *, int64_t); 3220Sstevel@tonic-gate extern void empty_rep_val_list(uu_list_t *); 3230Sstevel@tonic-gate extern int make_handle_bound(scf_handle_t *); 324*3175Sskamm extern int add_remove_contract(instance_t *, boolean_t, ctid_t); 325*3175Sskamm extern int iterate_repository_contracts(instance_t *, int); 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate /* 3280Sstevel@tonic-gate * contracts.c 3290Sstevel@tonic-gate */ 3300Sstevel@tonic-gate extern int contract_init(void); 3310Sstevel@tonic-gate extern void contract_fini(void); 3320Sstevel@tonic-gate void contract_postfork(void); 3330Sstevel@tonic-gate int contract_prefork(void); 3340Sstevel@tonic-gate extern int get_latest_contract(ctid_t *cid); 3350Sstevel@tonic-gate extern int adopt_contract(ctid_t, const char *); 3360Sstevel@tonic-gate extern int abandon_contract(ctid_t); 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate /* 3390Sstevel@tonic-gate * inetd.c 3400Sstevel@tonic-gate */ 3410Sstevel@tonic-gate extern void process_offline_inst(instance_t *); 3420Sstevel@tonic-gate extern void process_non_start_term(instance_t *, int); 3430Sstevel@tonic-gate extern void process_start_term(instance_t *); 3440Sstevel@tonic-gate extern void remove_method_ids(instance_t *, pid_t, ctid_t, instance_method_t); 3450Sstevel@tonic-gate 3460Sstevel@tonic-gate /* 3470Sstevel@tonic-gate * env.c 3480Sstevel@tonic-gate */ 3490Sstevel@tonic-gate char **set_smf_env(struct method_context *, instance_t *, const char *); 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate /* 3520Sstevel@tonic-gate * wait.c 3530Sstevel@tonic-gate */ 3540Sstevel@tonic-gate extern int register_method(instance_t *, pid_t, ctid_t cid, instance_method_t); 3550Sstevel@tonic-gate extern int method_init(void); 3560Sstevel@tonic-gate extern void method_fini(void); 3570Sstevel@tonic-gate extern void process_terminated_methods(void); 3580Sstevel@tonic-gate extern void unregister_instance_methods(const instance_t *); 3590Sstevel@tonic-gate extern void method_preexec(void); 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate #ifdef __cplusplus 3620Sstevel@tonic-gate } 3630Sstevel@tonic-gate #endif 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate #endif /* _INETD_IMPL_H */ 366