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 (c) 2011 Gary Mills 23 * 24 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 25 */ 26 27 /* 28 * NOTES: To be expanded. 29 * 30 * The SMF inetd. 31 * 32 * Below are some high level notes of the operation of the SMF inetd. The 33 * notes don't go into any real detail, and the viewer of this file is 34 * encouraged to look at the code and its associated comments to better 35 * understand inetd's operation. This saves the potential for the code 36 * and these notes diverging over time. 37 * 38 * Inetd's major work is done from the context of event_loop(). Within this 39 * loop, inetd polls for events arriving from a number of different file 40 * descriptors, representing the following event types, and initiates 41 * any necessary event processing: 42 * - incoming network connections/datagrams. 43 * - notification of terminated processes (discovered via contract events). 44 * - instance specific events originating from the SMF master restarter. 45 * - stop/refresh requests from the inetd method processes (coming in on a 46 * Unix Domain socket). 47 * There's also a timeout set for the poll, which is set to the nearest 48 * scheduled timer in a timer queue that inetd uses to perform delayed 49 * processing, such as bind retries. 50 * The SIGHUP and SIGINT signals can also interrupt the poll, and will 51 * result in inetd being refreshed or stopped respectively, as was the 52 * behavior with the old inetd. 53 * 54 * Inetd implements a state machine for each instance. The states within the 55 * machine are: offline, online, disabled, maintenance, uninitialized and 56 * specializations of the offline state for when an instance exceeds one of 57 * its DOS limits. The state of an instance can be changed as a 58 * result/side-effect of one of the above events occurring, or inetd being 59 * started up. The ongoing state of an instance is stored in the SMF 60 * repository, as required of SMF restarters. This enables an administrator 61 * to view the state of each instance, and, if inetd was to terminate 62 * unexpectedly, it could use the stored state to re-commence where it left off. 63 * 64 * Within the state machine a number of methods are run (if provided) as part 65 * of a state transition to aid/ effect a change in an instance's state. The 66 * supported methods are: offline, online, disable, refresh and start. The 67 * latter of these is the equivalent of the server program and its arguments 68 * in the old inetd. 69 * 70 * Events from the SMF master restarter come in on a number of threads 71 * created in the registration routine of librestart, the delegated restarter 72 * library. These threads call into the restart_event_proxy() function 73 * when an event arrives. To serialize the processing of instances, these events 74 * are then written down a pipe to the process's main thread, which listens 75 * for these events via a poll call, with the file descriptor of the other 76 * end of the pipe in its read set, and processes the event appropriately. 77 * When the event has been processed (which may be delayed if the instance 78 * for which the event is for is in the process of executing one of its methods 79 * as part of a state transition) it writes an acknowledgement back down the 80 * pipe the event was received on. The thread in restart_event_proxy() that 81 * wrote the event will read the acknowledgement it was blocked upon, and will 82 * then be able to return to its caller, thus implicitly acknowledging the 83 * event, and allowing another event to be written down the pipe for the main 84 * thread to process. 85 */ 86 87 88 #include <netdb.h> 89 #include <stdio.h> 90 #include <stdio_ext.h> 91 #include <stdlib.h> 92 #include <strings.h> 93 #include <unistd.h> 94 #include <assert.h> 95 #include <sys/types.h> 96 #include <sys/socket.h> 97 #include <netinet/in.h> 98 #include <fcntl.h> 99 #include <signal.h> 100 #include <errno.h> 101 #include <locale.h> 102 #include <syslog.h> 103 #include <libintl.h> 104 #include <librestart.h> 105 #include <pthread.h> 106 #include <sys/stat.h> 107 #include <time.h> 108 #include <limits.h> 109 #include <libgen.h> 110 #include <tcpd.h> 111 #include <libscf.h> 112 #include <libuutil.h> 113 #include <stddef.h> 114 #include <bsm/adt_event.h> 115 #include <ucred.h> 116 #include "inetd_impl.h" 117 118 /* path to inetd's binary */ 119 #define INETD_PATH "/usr/lib/inet/inetd" 120 121 /* 122 * inetd's default configuration file paths. /etc/inetd/inetd.conf is set 123 * be be the primary file, so it is checked before /etc/inetd.conf. 124 */ 125 #define PRIMARY_DEFAULT_CONF_FILE "/etc/inet/inetd.conf" 126 #define SECONDARY_DEFAULT_CONF_FILE "/etc/inetd.conf" 127 128 /* Arguments passed to this binary to request which method to execute. */ 129 #define START_METHOD_ARG "start" 130 #define STOP_METHOD_ARG "stop" 131 #define REFRESH_METHOD_ARG "refresh" 132 133 /* connection backlog for unix domain socket */ 134 #define UDS_BACKLOG 2 135 136 /* number of retries to recv() a request on the UDS socket before giving up */ 137 #define UDS_RECV_RETRIES 10 138 139 /* enumeration of the different ends of a pipe */ 140 enum pipe_end { 141 PE_CONSUMER, 142 PE_PRODUCER 143 }; 144 145 typedef struct { 146 internal_inst_state_t istate; 147 const char *name; 148 restarter_instance_state_t smf_state; 149 instance_method_t method_running; 150 } state_info_t; 151 152 153 /* 154 * Collection of information for each state. 155 * NOTE: This table is indexed into using the internal_inst_state_t 156 * enumeration, so the ordering needs to be kept in synch. 157 */ 158 static state_info_t states[] = { 159 {IIS_UNINITIALIZED, "uninitialized", RESTARTER_STATE_UNINIT, 160 IM_NONE}, 161 {IIS_ONLINE, "online", RESTARTER_STATE_ONLINE, IM_START}, 162 {IIS_IN_ONLINE_METHOD, "online_method", RESTARTER_STATE_OFFLINE, 163 IM_ONLINE}, 164 {IIS_OFFLINE, "offline", RESTARTER_STATE_OFFLINE, IM_NONE}, 165 {IIS_IN_OFFLINE_METHOD, "offline_method", RESTARTER_STATE_OFFLINE, 166 IM_OFFLINE}, 167 {IIS_DISABLED, "disabled", RESTARTER_STATE_DISABLED, IM_NONE}, 168 {IIS_IN_DISABLE_METHOD, "disabled_method", RESTARTER_STATE_OFFLINE, 169 IM_DISABLE}, 170 {IIS_IN_REFRESH_METHOD, "refresh_method", RESTARTER_STATE_ONLINE, 171 IM_REFRESH}, 172 {IIS_MAINTENANCE, "maintenance", RESTARTER_STATE_MAINT, IM_NONE}, 173 {IIS_OFFLINE_CONRATE, "cr_offline", RESTARTER_STATE_OFFLINE, IM_NONE}, 174 {IIS_OFFLINE_BIND, "bind_offline", RESTARTER_STATE_OFFLINE, IM_NONE}, 175 {IIS_OFFLINE_COPIES, "copies_offline", RESTARTER_STATE_OFFLINE, 176 IM_NONE}, 177 {IIS_DEGRADED, "degraded", RESTARTER_STATE_DEGRADED, IM_NONE}, 178 {IIS_NONE, "none", RESTARTER_STATE_NONE, IM_NONE} 179 }; 180 181 /* 182 * Pipe used to send events from the threads created by restarter_bind_handle() 183 * to the main thread of control. 184 */ 185 static int rst_event_pipe[] = {-1, -1}; 186 /* 187 * Used to protect the critical section of code in restarter_event_proxy() that 188 * involves writing an event down the event pipe and reading an acknowledgement. 189 */ 190 static pthread_mutex_t rst_event_pipe_mtx = PTHREAD_MUTEX_INITIALIZER; 191 192 /* handle used in communication with the master restarter */ 193 static restarter_event_handle_t *rst_event_handle = NULL; 194 195 /* set to indicate a refresh of inetd is requested */ 196 static boolean_t refresh_inetd_requested = B_FALSE; 197 198 /* set by the SIGTERM handler to flag we got a SIGTERM */ 199 static boolean_t got_sigterm = B_FALSE; 200 201 /* 202 * Timer queue used to store timers for delayed event processing, such as 203 * bind retries. 204 */ 205 iu_tq_t *timer_queue = NULL; 206 207 /* 208 * fd of Unix Domain socket used to communicate stop and refresh requests 209 * to the inetd start method process. 210 */ 211 static int uds_fd = -1; 212 213 /* 214 * List of inetd's currently managed instances; each containing its state, 215 * and in certain states its configuration. 216 */ 217 static uu_list_pool_t *instance_pool = NULL; 218 uu_list_t *instance_list = NULL; 219 220 /* set to indicate we're being stopped */ 221 boolean_t inetd_stopping = B_FALSE; 222 223 /* TCP wrappers syslog globals. Consumed by libwrap. */ 224 int allow_severity = LOG_INFO; 225 int deny_severity = LOG_WARNING; 226 227 /* path of the configuration file being monitored by check_conf_file() */ 228 static char *conf_file = NULL; 229 230 /* Auditing session handle */ 231 static adt_session_data_t *audit_handle; 232 233 /* Number of pending connections */ 234 static size_t tlx_pending_counter; 235 236 static void uds_fini(void); 237 static int uds_init(void); 238 static int run_method(instance_t *, instance_method_t, const proto_info_t *); 239 static void create_bound_fds(instance_t *); 240 static void destroy_bound_fds(instance_t *); 241 static void destroy_instance(instance_t *); 242 static void inetd_stop(void); 243 static void 244 exec_method(instance_t *instance, instance_method_t method, method_info_t *mi, 245 struct method_context *mthd_ctxt, const proto_info_t *pi) __NORETURN; 246 247 /* 248 * The following two functions are callbacks that libumem uses to determine 249 * inetd's desired debugging/logging levels. The interface they consume is 250 * exported by FMA and is consolidation private. The comments in the two 251 * functions give the environment variable that will effectively be set to 252 * their returned value, and thus whose behavior for this value, described in 253 * umem_debug(3MALLOC), will be followed. 254 */ 255 256 const char * 257 _umem_debug_init(void) 258 { 259 return ("default,verbose"); /* UMEM_DEBUG setting */ 260 } 261 262 const char * 263 _umem_logging_init(void) 264 { 265 return ("fail,contents"); /* UMEM_LOGGING setting */ 266 } 267 268 static void 269 log_invalid_cfg(const char *fmri) 270 { 271 error_msg(gettext( 272 "Invalid configuration for instance %s, placing in maintenance"), 273 fmri); 274 } 275 276 /* 277 * Returns B_TRUE if the instance is in a suitable state for inetd to stop. 278 */ 279 static boolean_t 280 instance_stopped(const instance_t *inst) 281 { 282 return ((inst->cur_istate == IIS_OFFLINE) || 283 (inst->cur_istate == IIS_MAINTENANCE) || 284 (inst->cur_istate == IIS_DISABLED) || 285 (inst->cur_istate == IIS_UNINITIALIZED)); 286 } 287 288 /* 289 * Given the instance fmri, obtain the corresonding scf_instance. 290 * Caller is responsible for freeing the returned scf_instance and 291 * its scf_handle. 292 */ 293 static int 294 fmri_to_instance(char *fmri, scf_instance_t **scf_instp) 295 { 296 int retries, ret = 1; 297 scf_handle_t *h; 298 scf_instance_t *scf_inst; 299 300 if ((h = scf_handle_create(SCF_VERSION)) == NULL) { 301 error_msg(gettext("Failed to get instance for %s"), fmri); 302 return (1); 303 } 304 305 if ((scf_inst = scf_instance_create(h)) == NULL) 306 goto out; 307 308 for (retries = 0; retries <= REP_OP_RETRIES; retries++) { 309 if (make_handle_bound(h) == -1) 310 break; 311 312 if (scf_handle_decode_fmri(h, fmri, NULL, NULL, scf_inst, 313 NULL, NULL, SCF_DECODE_FMRI_EXACT) == 0) { 314 ret = 0; 315 *scf_instp = scf_inst; 316 break; 317 } 318 319 if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 320 break; 321 } 322 323 out: 324 if (ret != 0) { 325 error_msg(gettext("Failed to get instance for %s"), fmri); 326 scf_instance_destroy(scf_inst); 327 scf_handle_destroy(h); 328 } 329 330 return (ret); 331 } 332 333 /* 334 * Updates the current and next repository states of instance 'inst'. If 335 * any errors occur an error message is output. 336 */ 337 static void 338 update_instance_states(instance_t *inst, internal_inst_state_t new_cur_state, 339 internal_inst_state_t new_next_state, restarter_error_t err) 340 { 341 internal_inst_state_t old_cur = inst->cur_istate; 342 internal_inst_state_t old_next = inst->next_istate; 343 scf_instance_t *scf_inst = NULL; 344 scf_error_t sret; 345 int ret; 346 restarter_str_t aux = restarter_str_none; 347 348 /* update the repository/cached internal state */ 349 inst->cur_istate = new_cur_state; 350 inst->next_istate = new_next_state; 351 (void) set_single_rep_val(inst->cur_istate_rep, 352 (int64_t)new_cur_state); 353 (void) set_single_rep_val(inst->next_istate_rep, 354 (int64_t)new_next_state); 355 356 if (((sret = store_rep_vals(inst->cur_istate_rep, inst->fmri, 357 PR_NAME_CUR_INT_STATE)) != 0) || 358 ((sret = store_rep_vals(inst->next_istate_rep, inst->fmri, 359 PR_NAME_NEXT_INT_STATE)) != 0)) 360 error_msg(gettext("Failed to update state of instance %s in " 361 "repository: %s"), inst->fmri, scf_strerror(sret)); 362 363 if (fmri_to_instance(inst->fmri, &scf_inst) == 0) { 364 /* 365 * If transitioning to maintenance, check auxiliary_tty set 366 * by svcadm and assign appropriate value to auxiliary_state. 367 * If the maintenance event comes from a service request, 368 * validate auxiliary_fmri and copy it to 369 * restarter/auxiliary_fmri. 370 */ 371 if (new_cur_state == IIS_MAINTENANCE) { 372 if (restarter_inst_ractions_from_tty(scf_inst) == 0) 373 aux = restarter_str_service_request; 374 else 375 aux = restarter_str_administrative_request; 376 } 377 378 if (aux == restarter_str_service_request) { 379 if (restarter_inst_validate_ractions_aux_fmri( 380 scf_inst) == 0) { 381 if (restarter_inst_set_aux_fmri(scf_inst)) 382 error_msg(gettext("Could not set " 383 "auxiliary_fmri property for %s"), 384 inst->fmri); 385 } else { 386 if (restarter_inst_reset_aux_fmri(scf_inst)) 387 error_msg(gettext("Could not reset " 388 "auxiliary_fmri property for %s"), 389 inst->fmri); 390 } 391 } 392 scf_handle_destroy(scf_instance_handle(scf_inst)); 393 scf_instance_destroy(scf_inst); 394 } 395 396 /* update the repository SMF state */ 397 if ((ret = restarter_set_states(rst_event_handle, inst->fmri, 398 states[old_cur].smf_state, states[new_cur_state].smf_state, 399 states[old_next].smf_state, states[new_next_state].smf_state, 400 err, aux)) != 0) 401 error_msg(gettext("Failed to update state of instance %s in " 402 "repository: %s"), inst->fmri, strerror(ret)); 403 } 404 405 void 406 update_state(instance_t *inst, internal_inst_state_t new_cur, 407 restarter_error_t err) 408 { 409 update_instance_states(inst, new_cur, IIS_NONE, err); 410 } 411 412 /* 413 * Sends a refresh event to the inetd start method process and returns 414 * SMF_EXIT_OK if it managed to send it. If it fails to send the request for 415 * some reason it returns SMF_EXIT_ERR_OTHER. 416 */ 417 static int 418 refresh_method(void) 419 { 420 uds_request_t req = UR_REFRESH_INETD; 421 int fd; 422 423 if ((fd = connect_to_inetd()) < 0) { 424 error_msg(gettext("Failed to connect to inetd: %s"), 425 strerror(errno)); 426 return (SMF_EXIT_ERR_OTHER); 427 } 428 429 /* write the request and return success */ 430 if (safe_write(fd, &req, sizeof (req)) == -1) { 431 error_msg( 432 gettext("Failed to send refresh request to inetd: %s"), 433 strerror(errno)); 434 (void) close(fd); 435 return (SMF_EXIT_ERR_OTHER); 436 } 437 438 (void) close(fd); 439 440 return (SMF_EXIT_OK); 441 } 442 443 /* 444 * Sends a stop event to the inetd start method process and wait till it goes 445 * away. If inetd is determined to have stopped SMF_EXIT_OK is returned, else 446 * SMF_EXIT_ERR_OTHER is returned. 447 */ 448 static int 449 stop_method(void) 450 { 451 uds_request_t req = UR_STOP_INETD; 452 int fd; 453 char c; 454 ssize_t ret; 455 456 if ((fd = connect_to_inetd()) == -1) { 457 debug_msg(gettext("Failed to connect to inetd: %s"), 458 strerror(errno)); 459 /* 460 * Assume connect_to_inetd() failed because inetd was already 461 * stopped, and return success. 462 */ 463 return (SMF_EXIT_OK); 464 } 465 466 /* 467 * This is safe to do since we're fired off in a separate process 468 * than inetd and in the case we get wedged, the stop method timeout 469 * will occur and we'd be killed by our restarter. 470 */ 471 enable_blocking(fd); 472 473 /* write the stop request to inetd and wait till it goes away */ 474 if (safe_write(fd, &req, sizeof (req)) != 0) { 475 error_msg(gettext("Failed to send stop request to inetd")); 476 (void) close(fd); 477 return (SMF_EXIT_ERR_OTHER); 478 } 479 480 /* wait until remote end of socket is closed */ 481 while (((ret = recv(fd, &c, sizeof (c), 0)) != 0) && (errno == EINTR)) 482 ; 483 484 (void) close(fd); 485 486 if (ret != 0) { 487 error_msg(gettext("Failed to determine whether inetd stopped")); 488 return (SMF_EXIT_ERR_OTHER); 489 } 490 491 return (SMF_EXIT_OK); 492 } 493 494 495 /* 496 * This function is called to handle restarter events coming in from the 497 * master restarter. It is registered with the master restarter via 498 * restarter_bind_handle() and simply passes a pointer to the event down 499 * the event pipe, which will be discovered by the poll in the event loop 500 * and processed there. It waits for an acknowledgement to be written back down 501 * the pipe before returning. 502 * Writing a pointer to the function's 'event' parameter down the pipe will 503 * be safe, as the thread in restarter_event_proxy() doesn't return until 504 * the main thread has finished its processing of the passed event, thus 505 * the referenced event will remain around until the function returns. 506 * To impose the limit of only one event being in the pipe and processed 507 * at once, a lock is taken on entry to this function and returned on exit. 508 * Always returns 0. 509 */ 510 static int 511 restarter_event_proxy(restarter_event_t *event) 512 { 513 boolean_t processed; 514 515 (void) pthread_mutex_lock(&rst_event_pipe_mtx); 516 517 /* write the event to the main worker thread down the pipe */ 518 if (safe_write(rst_event_pipe[PE_PRODUCER], &event, 519 sizeof (event)) != 0) 520 goto pipe_error; 521 522 /* 523 * Wait for an acknowledgement that the event has been processed from 524 * the same pipe. In the case that inetd is stopping, any thread in 525 * this function will simply block on this read until inetd eventually 526 * exits. This will result in this function not returning success to 527 * its caller, and the event that was being processed when the 528 * function exited will be re-sent when inetd is next started. 529 */ 530 if (safe_read(rst_event_pipe[PE_PRODUCER], &processed, 531 sizeof (processed)) != 0) 532 goto pipe_error; 533 534 (void) pthread_mutex_unlock(&rst_event_pipe_mtx); 535 536 return (processed ? 0 : EAGAIN); 537 538 pipe_error: 539 /* 540 * Something's seriously wrong with the event pipe. Notify the 541 * worker thread by closing this end of the event pipe and pause till 542 * inetd exits. 543 */ 544 error_msg(gettext("Can't process restarter events: %s"), 545 strerror(errno)); 546 (void) close(rst_event_pipe[PE_PRODUCER]); 547 for (;;) 548 (void) pause(); 549 550 /* NOTREACHED */ 551 } 552 553 /* 554 * Let restarter_event_proxy() know we're finished with the event it's blocked 555 * upon. The 'processed' argument denotes whether we successfully processed the 556 * event. 557 */ 558 static void 559 ack_restarter_event(boolean_t processed) 560 { 561 /* 562 * If safe_write returns -1 something's seriously wrong with the event 563 * pipe, so start the shutdown proceedings. 564 */ 565 if (safe_write(rst_event_pipe[PE_CONSUMER], &processed, 566 sizeof (processed)) == -1) 567 inetd_stop(); 568 } 569 570 /* 571 * Switch the syslog identification string to 'ident'. 572 */ 573 static void 574 change_syslog_ident(const char *ident) 575 { 576 closelog(); 577 openlog(ident, LOG_PID|LOG_CONS, LOG_DAEMON); 578 } 579 580 /* 581 * Perform TCP wrappers checks on this instance. Due to the fact that the 582 * current wrappers code used in Solaris is taken untouched from the open 583 * source version, we're stuck with using the daemon name for the checks, as 584 * opposed to making use of instance FMRIs. Sigh. 585 * Returns B_TRUE if the check passed, else B_FALSE. 586 */ 587 static boolean_t 588 tcp_wrappers_ok(instance_t *instance) 589 { 590 boolean_t rval = B_TRUE; 591 char *daemon_name; 592 basic_cfg_t *cfg = instance->config->basic; 593 struct request_info req; 594 595 /* 596 * Wrap the service using libwrap functions. The code below implements 597 * the functionality of tcpd. This is done only for stream,nowait 598 * services, following the convention of other vendors. udp/dgram and 599 * stream/wait can NOT be wrapped with this libwrap, so be wary of 600 * changing the test below. 601 */ 602 if (cfg->do_tcp_wrappers && !cfg->iswait && !cfg->istlx) { 603 604 daemon_name = instance->config->methods[ 605 IM_START]->exec_args_we.we_wordv[0]; 606 if (*daemon_name == '/') 607 daemon_name = strrchr(daemon_name, '/') + 1; 608 609 /* 610 * Change the syslog message identity to the name of the 611 * daemon being wrapped, as opposed to "inetd". 612 */ 613 change_syslog_ident(daemon_name); 614 615 (void) request_init(&req, RQ_DAEMON, daemon_name, RQ_FILE, 616 instance->conn_fd, NULL); 617 fromhost(&req); 618 619 if (strcasecmp(eval_hostname(req.client), paranoid) == 0) { 620 syslog(deny_severity, 621 "refused connect from %s (name/address mismatch)", 622 eval_client(&req)); 623 if (req.sink != NULL) 624 req.sink(instance->conn_fd); 625 rval = B_FALSE; 626 } else if (!hosts_access(&req)) { 627 syslog(deny_severity, 628 "refused connect from %s (access denied)", 629 eval_client(&req)); 630 if (req.sink != NULL) 631 req.sink(instance->conn_fd); 632 rval = B_FALSE; 633 } else { 634 syslog(allow_severity, "connect from %s", 635 eval_client(&req)); 636 } 637 638 /* Revert syslog identity back to "inetd". */ 639 change_syslog_ident(SYSLOG_IDENT); 640 } 641 return (rval); 642 } 643 644 /* 645 * Handler registered with the timer queue code to remove an instance from 646 * the connection rate offline state when it has been there for its allotted 647 * time. 648 */ 649 /* ARGSUSED */ 650 static void 651 conn_rate_online(iu_tq_t *tq, void *arg) 652 { 653 instance_t *instance = arg; 654 655 assert(instance->cur_istate == IIS_OFFLINE_CONRATE); 656 instance->timer_id = -1; 657 update_state(instance, IIS_OFFLINE, RERR_RESTART); 658 process_offline_inst(instance); 659 } 660 661 /* 662 * Check whether this instance in the offline state is in transition to 663 * another state and do the work to continue this transition. 664 */ 665 void 666 process_offline_inst(instance_t *inst) 667 { 668 if (inst->disable_req) { 669 inst->disable_req = B_FALSE; 670 (void) run_method(inst, IM_DISABLE, NULL); 671 } else if (inst->maintenance_req) { 672 inst->maintenance_req = B_FALSE; 673 update_state(inst, IIS_MAINTENANCE, RERR_RESTART); 674 /* 675 * If inetd is in the process of stopping, we don't want to enter 676 * any states but offline, disabled and maintenance. 677 */ 678 } else if (!inetd_stopping) { 679 if (inst->conn_rate_exceeded) { 680 basic_cfg_t *cfg = inst->config->basic; 681 682 inst->conn_rate_exceeded = B_FALSE; 683 update_state(inst, IIS_OFFLINE_CONRATE, RERR_RESTART); 684 /* 685 * Schedule a timer to bring the instance out of the 686 * connection rate offline state. 687 */ 688 inst->timer_id = iu_schedule_timer(timer_queue, 689 cfg->conn_rate_offline, conn_rate_online, 690 inst); 691 if (inst->timer_id == -1) { 692 error_msg(gettext("%s unable to set timer, " 693 "won't be brought on line after %d " 694 "seconds."), inst->fmri, 695 cfg->conn_rate_offline); 696 } 697 698 } else if (copies_limit_exceeded(inst)) { 699 update_state(inst, IIS_OFFLINE_COPIES, RERR_RESTART); 700 } 701 } 702 } 703 704 /* 705 * Create a socket bound to the instance's configured address. If the 706 * bind fails, returns -1, else the fd of the bound socket. 707 */ 708 static int 709 create_bound_socket(const instance_t *inst, socket_info_t *sock_info) 710 { 711 int fd; 712 int on = 1; 713 const char *fmri = inst->fmri; 714 rpc_info_t *rpc = sock_info->pr_info.ri; 715 const char *proto = sock_info->pr_info.proto; 716 717 fd = socket(sock_info->local_addr.ss_family, sock_info->type, 718 sock_info->protocol); 719 if (fd < 0) { 720 error_msg(gettext( 721 "Socket creation failure for instance %s, proto %s: %s"), 722 fmri, proto, strerror(errno)); 723 return (-1); 724 } 725 726 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) == -1) { 727 error_msg(gettext("setsockopt SO_REUSEADDR failed for service " 728 "instance %s, proto %s: %s"), fmri, proto, strerror(errno)); 729 (void) close(fd); 730 return (-1); 731 } 732 if (inst->config->basic->do_tcp_keepalive && 733 !inst->config->basic->iswait && !inst->config->basic->istlx) { 734 /* set the keepalive option */ 735 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, 736 sizeof (on)) == -1) { 737 error_msg(gettext("setsockopt SO_KEEPALIVE failed for " 738 "service instance %s, proto %s: %s"), fmri, 739 proto, strerror(errno)); 740 (void) close(fd); 741 return (-1); 742 } 743 } 744 if (sock_info->pr_info.v6only) { 745 /* restrict socket to IPv6 communications only */ 746 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, 747 sizeof (on)) == -1) { 748 error_msg(gettext("setsockopt IPV6_V6ONLY failed for " 749 "service instance %s, proto %s: %s"), fmri, proto, 750 strerror(errno)); 751 (void) close(fd); 752 return (-1); 753 } 754 } 755 756 if (rpc != NULL) 757 SS_SETPORT(sock_info->local_addr, 0); 758 759 if (bind(fd, (struct sockaddr *)&(sock_info->local_addr), 760 SS_ADDRLEN(sock_info->local_addr)) < 0) { 761 error_msg(gettext( 762 "Failed to bind to the port of service instance %s, " 763 "proto %s: %s"), fmri, proto, strerror(errno)); 764 (void) close(fd); 765 return (-1); 766 } 767 768 /* 769 * Retrieve and store the address bound to for RPC services. 770 */ 771 if (rpc != NULL) { 772 struct sockaddr_storage ss; 773 int ss_size = sizeof (ss); 774 775 if (getsockname(fd, (struct sockaddr *)&ss, &ss_size) < 0) { 776 error_msg(gettext("Failed getsockname for instance %s, " 777 "proto %s: %s"), fmri, proto, strerror(errno)); 778 (void) close(fd); 779 return (-1); 780 } 781 (void) memcpy(rpc->netbuf.buf, &ss, 782 sizeof (struct sockaddr_storage)); 783 rpc->netbuf.len = SS_ADDRLEN(ss); 784 rpc->netbuf.maxlen = SS_ADDRLEN(ss); 785 } 786 787 if (sock_info->type == SOCK_STREAM) { 788 int qlen = inst->config->basic->conn_backlog; 789 790 debug_msg("Listening for service %s with backlog queue" 791 " size %d", fmri, qlen); 792 (void) listen(fd, qlen); 793 } 794 795 return (fd); 796 } 797 798 /* 799 * Handler registered with the timer queue code to retry the creation 800 * of a bound fd. 801 */ 802 /* ARGSUSED */ 803 static void 804 retry_bind(iu_tq_t *tq, void *arg) 805 { 806 instance_t *instance = arg; 807 808 switch (instance->cur_istate) { 809 case IIS_OFFLINE_BIND: 810 case IIS_ONLINE: 811 case IIS_DEGRADED: 812 case IIS_IN_ONLINE_METHOD: 813 case IIS_IN_REFRESH_METHOD: 814 break; 815 default: 816 #ifndef NDEBUG 817 (void) fprintf(stderr, "%s:%d: Unknown instance state %d.\n", 818 __FILE__, __LINE__, instance->cur_istate); 819 #endif 820 abort(); 821 } 822 823 instance->bind_timer_id = -1; 824 create_bound_fds(instance); 825 } 826 827 /* 828 * For each of the fds for the given instance that are bound, if 'listen' is 829 * set add them to the poll set, else remove them from it. If proto_name is 830 * not NULL then apply the change only to this specific protocol endpoint. 831 * If any additions fail, returns -1, else 0 on success. 832 */ 833 int 834 poll_bound_fds(instance_t *instance, boolean_t listen, char *proto_name) 835 { 836 basic_cfg_t *cfg = instance->config->basic; 837 proto_info_t *pi; 838 int ret = 0; 839 840 for (pi = uu_list_first(cfg->proto_list); pi != NULL; 841 pi = uu_list_next(cfg->proto_list, pi)) { 842 if (pi->listen_fd != -1) { /* fd bound */ 843 if (proto_name == NULL || 844 strcmp(pi->proto, proto_name) == 0) { 845 if (listen == B_FALSE) { 846 clear_pollfd(pi->listen_fd); 847 } else if (set_pollfd(pi->listen_fd, 848 POLLIN) == -1) { 849 ret = -1; 850 } 851 } 852 } 853 } 854 855 return (ret); 856 } 857 858 /* 859 * Handle the case were we either fail to create a bound fd or we fail 860 * to add a bound fd to the poll set for the given instance. 861 */ 862 static void 863 handle_bind_failure(instance_t *instance) 864 { 865 basic_cfg_t *cfg = instance->config->basic; 866 867 /* 868 * We must be being called as a result of a failed poll_bound_fds() 869 * as a bind retry is already scheduled. Just return and let it do 870 * the work. 871 */ 872 if (instance->bind_timer_id != -1) 873 return; 874 875 /* 876 * Check if the rebind retries limit is operative and if so, 877 * if it has been reached. 878 */ 879 if (((cfg->bind_fail_interval <= 0) || /* no retries */ 880 ((cfg->bind_fail_max >= 0) && /* limit reached */ 881 (++instance->bind_fail_count > cfg->bind_fail_max))) || 882 ((instance->bind_timer_id = iu_schedule_timer(timer_queue, 883 cfg->bind_fail_interval, retry_bind, instance)) == -1)) { 884 proto_info_t *pi; 885 886 instance->bind_fail_count = 0; 887 888 switch (instance->cur_istate) { 889 case IIS_DEGRADED: 890 case IIS_ONLINE: 891 /* check if any of the fds are being poll'd upon */ 892 for (pi = uu_list_first(cfg->proto_list); pi != NULL; 893 pi = uu_list_next(cfg->proto_list, pi)) { 894 if ((pi->listen_fd != -1) && 895 (find_pollfd(pi->listen_fd) != NULL)) 896 break; 897 } 898 if (pi != NULL) { /* polling on > 0 fds */ 899 warn_msg(gettext("Failed to bind on " 900 "all protocols for instance %s, " 901 "transitioning to degraded"), 902 instance->fmri); 903 update_state(instance, IIS_DEGRADED, RERR_NONE); 904 instance->bind_retries_exceeded = B_TRUE; 905 break; 906 } 907 908 destroy_bound_fds(instance); 909 /* 910 * In the case we failed the 'bind' because set_pollfd() 911 * failed on all bound fds, use the offline handling. 912 */ 913 /* FALLTHROUGH */ 914 case IIS_OFFLINE: 915 case IIS_OFFLINE_BIND: 916 error_msg(gettext("Too many bind failures for instance " 917 "%s, transitioning to maintenance"), instance->fmri); 918 update_state(instance, IIS_MAINTENANCE, 919 RERR_FAULT); 920 break; 921 case IIS_IN_ONLINE_METHOD: 922 case IIS_IN_REFRESH_METHOD: 923 warn_msg(gettext("Failed to bind on all " 924 "protocols for instance %s, instance will go to " 925 "degraded"), instance->fmri); 926 /* 927 * Set the retries exceeded flag so when the method 928 * completes the instance goes to the degraded state. 929 */ 930 instance->bind_retries_exceeded = B_TRUE; 931 break; 932 default: 933 #ifndef NDEBUG 934 (void) fprintf(stderr, 935 "%s:%d: Unknown instance state %d.\n", 936 __FILE__, __LINE__, instance->cur_istate); 937 #endif 938 abort(); 939 } 940 } else if (instance->cur_istate == IIS_OFFLINE) { 941 /* 942 * bind re-scheduled, so if we're offline reflect this in the 943 * state. 944 */ 945 update_state(instance, IIS_OFFLINE_BIND, RERR_NONE); 946 } 947 } 948 949 950 /* 951 * Check if two transport protocols for RPC conflict. 952 */ 953 954 boolean_t 955 is_rpc_proto_conflict(const char *proto0, const char *proto1) { 956 if (strcmp(proto0, "tcp") == 0) { 957 if (strcmp(proto1, "tcp") == 0) 958 return (B_TRUE); 959 if (strcmp(proto1, "tcp6") == 0) 960 return (B_TRUE); 961 return (B_FALSE); 962 } 963 964 if (strcmp(proto0, "tcp6") == 0) { 965 if (strcmp(proto1, "tcp") == 0) 966 return (B_TRUE); 967 if (strcmp(proto1, "tcp6only") == 0) 968 return (B_TRUE); 969 if (strcmp(proto1, "tcp6") == 0) 970 return (B_TRUE); 971 return (B_FALSE); 972 } 973 974 if (strcmp(proto0, "tcp6only") == 0) { 975 if (strcmp(proto1, "tcp6only") == 0) 976 return (B_TRUE); 977 if (strcmp(proto1, "tcp6") == 0) 978 return (B_TRUE); 979 return (B_FALSE); 980 } 981 982 if (strcmp(proto0, "udp") == 0) { 983 if (strcmp(proto1, "udp") == 0) 984 return (B_TRUE); 985 if (strcmp(proto1, "udp6") == 0) 986 return (B_TRUE); 987 return (B_FALSE); 988 } 989 990 if (strcmp(proto0, "udp6") == 0) { 991 992 if (strcmp(proto1, "udp") == 0) 993 return (B_TRUE); 994 if (strcmp(proto1, "udp6only") == 0) 995 return (B_TRUE); 996 if (strcmp(proto1, "udp6") == 0) 997 return (B_TRUE); 998 return (B_FALSE); 999 } 1000 1001 if (strcmp(proto0, "udp6only") == 0) { 1002 1003 if (strcmp(proto1, "udp6only") == 0) 1004 return (B_TRUE); 1005 if (strcmp(proto1, "udp6") == 0) 1006 return (B_TRUE); 1007 return (0); 1008 } 1009 1010 /* 1011 * If the protocol isn't TCP/IP or UDP/IP assume that it has its own 1012 * port namepsace and that conflicts can be detected by literal string 1013 * comparison. 1014 */ 1015 1016 if (strcmp(proto0, proto1)) 1017 return (FALSE); 1018 1019 return (B_TRUE); 1020 } 1021 1022 1023 /* 1024 * Check if inetd thinks this RPC program number is already registered. 1025 * 1026 * An RPC protocol conflict occurs if 1027 * a) the program numbers are the same and, 1028 * b) the version numbers overlap, 1029 * c) the protocols (TCP vs UDP vs tic*) are the same. 1030 */ 1031 1032 boolean_t 1033 is_rpc_num_in_use(int rpc_n, char *proto, int lowver, int highver) { 1034 instance_t *i; 1035 basic_cfg_t *cfg; 1036 proto_info_t *pi; 1037 1038 for (i = uu_list_first(instance_list); i != NULL; 1039 i = uu_list_next(instance_list, i)) { 1040 1041 if (i->cur_istate != IIS_ONLINE) 1042 continue; 1043 cfg = i->config->basic; 1044 1045 for (pi = uu_list_first(cfg->proto_list); pi != NULL; 1046 pi = uu_list_next(cfg->proto_list, pi)) { 1047 1048 if (pi->ri == NULL) 1049 continue; 1050 if (pi->ri->prognum != rpc_n) 1051 continue; 1052 if (!is_rpc_proto_conflict(pi->proto, proto)) 1053 continue; 1054 if ((lowver < pi->ri->lowver && 1055 highver < pi->ri->lowver) || 1056 (lowver > pi->ri->highver && 1057 highver > pi->ri->highver)) 1058 continue; 1059 return (B_TRUE); 1060 } 1061 } 1062 return (B_FALSE); 1063 } 1064 1065 1066 /* 1067 * Independent of the transport, for each of the entries in the instance's 1068 * proto list this function first attempts to create an associated network fd; 1069 * for RPC services these are then bound to a kernel chosen port and the 1070 * fd is registered with rpcbind; for non-RPC services the fds are bound 1071 * to the port associated with the instance's service name. On any successful 1072 * binds the instance is taken online. Failed binds are handled by 1073 * handle_bind_failure(). 1074 */ 1075 void 1076 create_bound_fds(instance_t *instance) 1077 { 1078 basic_cfg_t *cfg = instance->config->basic; 1079 boolean_t failure = B_FALSE; 1080 boolean_t success = B_FALSE; 1081 proto_info_t *pi; 1082 1083 /* 1084 * Loop through and try and bind any unbound protos. 1085 */ 1086 for (pi = uu_list_first(cfg->proto_list); pi != NULL; 1087 pi = uu_list_next(cfg->proto_list, pi)) { 1088 if (pi->listen_fd != -1) 1089 continue; 1090 if (cfg->istlx) { 1091 pi->listen_fd = create_bound_endpoint(instance, 1092 (tlx_info_t *)pi); 1093 } else { 1094 /* 1095 * We cast pi to a void so we can then go on to cast 1096 * it to a socket_info_t without lint complaining 1097 * about alignment. This is done because the x86 1098 * version of lint thinks a lint suppression directive 1099 * is unnecessary and flags it as such, yet the sparc 1100 * version complains if it's absent. 1101 */ 1102 void *p = pi; 1103 pi->listen_fd = create_bound_socket(instance, 1104 (socket_info_t *)p); 1105 } 1106 if (pi->listen_fd == -1) { 1107 failure = B_TRUE; 1108 continue; 1109 } 1110 1111 if (pi->ri != NULL) { 1112 1113 /* 1114 * Don't register the same RPC program number twice. 1115 * Doing so silently discards the old service 1116 * without causing an error. 1117 */ 1118 if (is_rpc_num_in_use(pi->ri->prognum, pi->proto, 1119 pi->ri->lowver, pi->ri->highver)) { 1120 failure = B_TRUE; 1121 close_net_fd(instance, pi->listen_fd); 1122 pi->listen_fd = -1; 1123 continue; 1124 } 1125 1126 unregister_rpc_service(instance->fmri, pi->ri); 1127 if (register_rpc_service(instance->fmri, pi->ri) == 1128 -1) { 1129 close_net_fd(instance, pi->listen_fd); 1130 pi->listen_fd = -1; 1131 failure = B_TRUE; 1132 continue; 1133 } 1134 } 1135 1136 success = B_TRUE; 1137 } 1138 1139 switch (instance->cur_istate) { 1140 case IIS_OFFLINE: 1141 case IIS_OFFLINE_BIND: 1142 /* 1143 * If we've managed to bind at least one proto lets run the 1144 * online method, so we can start listening for it. 1145 */ 1146 if (success && run_method(instance, IM_ONLINE, NULL) == -1) 1147 return; /* instance gone to maintenance */ 1148 break; 1149 case IIS_ONLINE: 1150 case IIS_IN_REFRESH_METHOD: 1151 /* 1152 * We're 'online', so start polling on any bound fds we're 1153 * currently not. 1154 */ 1155 if (poll_bound_fds(instance, B_TRUE, NULL) != 0) { 1156 failure = B_TRUE; 1157 } else if (!failure) { 1158 /* 1159 * We've successfully bound and poll'd upon all protos, 1160 * so reset the failure count. 1161 */ 1162 instance->bind_fail_count = 0; 1163 } 1164 break; 1165 case IIS_IN_ONLINE_METHOD: 1166 /* 1167 * Nothing to do here as the method completion code will start 1168 * listening for any successfully bound fds. 1169 */ 1170 break; 1171 default: 1172 #ifndef NDEBUG 1173 (void) fprintf(stderr, "%s:%d: Unknown instance state %d.\n", 1174 __FILE__, __LINE__, instance->cur_istate); 1175 #endif 1176 abort(); 1177 } 1178 1179 if (failure) 1180 handle_bind_failure(instance); 1181 } 1182 1183 /* 1184 * Counter to create_bound_fds(), for each of the bound network fds this 1185 * function unregisters the instance from rpcbind if it's an RPC service, 1186 * stops listening for new connections for it and then closes the listening fd. 1187 */ 1188 static void 1189 destroy_bound_fds(instance_t *instance) 1190 { 1191 basic_cfg_t *cfg = instance->config->basic; 1192 proto_info_t *pi; 1193 1194 for (pi = uu_list_first(cfg->proto_list); pi != NULL; 1195 pi = uu_list_next(cfg->proto_list, pi)) { 1196 if (pi->listen_fd != -1) { 1197 if (pi->ri != NULL) 1198 unregister_rpc_service(instance->fmri, pi->ri); 1199 clear_pollfd(pi->listen_fd); 1200 close_net_fd(instance, pi->listen_fd); 1201 pi->listen_fd = -1; 1202 } 1203 } 1204 1205 /* cancel any bind retries */ 1206 if (instance->bind_timer_id != -1) 1207 cancel_bind_timer(instance); 1208 1209 instance->bind_retries_exceeded = B_FALSE; 1210 } 1211 1212 /* 1213 * Perform %A address expansion and return a pointer to a static string 1214 * array containing crafted arguments. This expansion is provided for 1215 * compatibility with 4.2BSD daemons, and as such we've copied the logic of 1216 * the legacy inetd to maintain this compatibility as much as possible. This 1217 * logic is a bit scatty, but it dates back at least as far as SunOS 4.x. 1218 */ 1219 static char ** 1220 expand_address(instance_t *inst, const proto_info_t *pi) 1221 { 1222 static char addrbuf[sizeof ("ffffffff.65536")]; 1223 static char *ret[3]; 1224 instance_cfg_t *cfg = inst->config; 1225 /* 1226 * We cast pi to a void so we can then go on to cast it to a 1227 * socket_info_t without lint complaining about alignment. This 1228 * is done because the x86 version of lint thinks a lint suppression 1229 * directive is unnecessary and flags it as such, yet the sparc 1230 * version complains if it's absent. 1231 */ 1232 const void *p = pi; 1233 1234 /* set ret[0] to the basename of exec path */ 1235 if ((ret[0] = strrchr(cfg->methods[IM_START]->exec_path, '/')) 1236 != NULL) { 1237 ret[0]++; 1238 } else { 1239 ret[0] = cfg->methods[IM_START]->exec_path; 1240 } 1241 1242 if (!cfg->basic->istlx && 1243 (((socket_info_t *)p)->type == SOCK_DGRAM)) { 1244 ret[1] = NULL; 1245 } else { 1246 addrbuf[0] = '\0'; 1247 if (!cfg->basic->iswait && 1248 (inst->remote_addr.ss_family == AF_INET)) { 1249 struct sockaddr_in *sp; 1250 1251 sp = (struct sockaddr_in *)&(inst->remote_addr); 1252 (void) snprintf(addrbuf, sizeof (addrbuf), "%x.%hu", 1253 ntohl(sp->sin_addr.s_addr), ntohs(sp->sin_port)); 1254 } 1255 ret[1] = addrbuf; 1256 ret[2] = NULL; 1257 } 1258 1259 return (ret); 1260 } 1261 1262 /* 1263 * Returns the state associated with the supplied method being run for an 1264 * instance. 1265 */ 1266 static internal_inst_state_t 1267 get_method_state(instance_method_t method) 1268 { 1269 state_info_t *sip; 1270 1271 for (sip = states; sip->istate != IIS_NONE; sip++) { 1272 if (sip->method_running == method) 1273 break; 1274 } 1275 assert(sip->istate != IIS_NONE); 1276 1277 return (sip->istate); 1278 } 1279 1280 /* 1281 * Store the method's PID and CID in the repository. If the store fails 1282 * we ignore it and just drive on. 1283 */ 1284 static void 1285 add_method_ids(instance_t *ins, pid_t pid, ctid_t cid, instance_method_t mthd) 1286 { 1287 if (cid != -1) 1288 (void) add_remove_contract(ins, B_TRUE, cid); 1289 1290 if (mthd == IM_START) { 1291 if (add_rep_val(ins->start_pids, (int64_t)pid) == 0) { 1292 (void) store_rep_vals(ins->start_pids, ins->fmri, 1293 PR_NAME_START_PIDS); 1294 } 1295 } else { 1296 if (add_rep_val(ins->non_start_pid, (int64_t)pid) == 0) { 1297 (void) store_rep_vals(ins->non_start_pid, ins->fmri, 1298 PR_NAME_NON_START_PID); 1299 } 1300 } 1301 } 1302 1303 /* 1304 * Remove the method's PID and CID from the repository. If the removal 1305 * fails we ignore it and drive on. 1306 */ 1307 void 1308 remove_method_ids(instance_t *inst, pid_t pid, ctid_t cid, 1309 instance_method_t mthd) 1310 { 1311 if (cid != -1) 1312 (void) add_remove_contract(inst, B_FALSE, cid); 1313 1314 if (mthd == IM_START) { 1315 remove_rep_val(inst->start_pids, (int64_t)pid); 1316 (void) store_rep_vals(inst->start_pids, inst->fmri, 1317 PR_NAME_START_PIDS); 1318 } else { 1319 remove_rep_val(inst->non_start_pid, (int64_t)pid); 1320 (void) store_rep_vals(inst->non_start_pid, inst->fmri, 1321 PR_NAME_NON_START_PID); 1322 } 1323 } 1324 1325 static instance_t * 1326 create_instance(const char *fmri) 1327 { 1328 instance_t *ret; 1329 1330 if (((ret = calloc(1, sizeof (instance_t))) == NULL) || 1331 ((ret->fmri = strdup(fmri)) == NULL)) 1332 goto alloc_fail; 1333 1334 ret->conn_fd = -1; 1335 1336 ret->copies = 0; 1337 1338 ret->conn_rate_count = 0; 1339 ret->fail_rate_count = 0; 1340 ret->bind_fail_count = 0; 1341 1342 if (((ret->non_start_pid = create_rep_val_list()) == NULL) || 1343 ((ret->start_pids = create_rep_val_list()) == NULL) || 1344 ((ret->start_ctids = create_rep_val_list()) == NULL)) 1345 goto alloc_fail; 1346 1347 ret->cur_istate = IIS_NONE; 1348 ret->next_istate = IIS_NONE; 1349 1350 if (((ret->cur_istate_rep = create_rep_val_list()) == NULL) || 1351 ((ret->next_istate_rep = create_rep_val_list()) == NULL)) 1352 goto alloc_fail; 1353 1354 ret->config = NULL; 1355 ret->new_config = NULL; 1356 1357 ret->timer_id = -1; 1358 ret->bind_timer_id = -1; 1359 1360 ret->disable_req = B_FALSE; 1361 ret->maintenance_req = B_FALSE; 1362 ret->conn_rate_exceeded = B_FALSE; 1363 ret->bind_retries_exceeded = B_FALSE; 1364 1365 ret->pending_rst_event = RESTARTER_EVENT_TYPE_INVALID; 1366 1367 return (ret); 1368 1369 alloc_fail: 1370 error_msg(strerror(errno)); 1371 destroy_instance(ret); 1372 return (NULL); 1373 } 1374 1375 static void 1376 destroy_instance(instance_t *inst) 1377 { 1378 if (inst == NULL) 1379 return; 1380 1381 destroy_instance_cfg(inst->config); 1382 destroy_instance_cfg(inst->new_config); 1383 1384 destroy_rep_val_list(inst->cur_istate_rep); 1385 destroy_rep_val_list(inst->next_istate_rep); 1386 1387 destroy_rep_val_list(inst->start_pids); 1388 destroy_rep_val_list(inst->non_start_pid); 1389 destroy_rep_val_list(inst->start_ctids); 1390 1391 free(inst->fmri); 1392 1393 free(inst); 1394 } 1395 1396 /* 1397 * Retrieves the current and next states internal states. Returns 0 on success, 1398 * else returns one of the following on error: 1399 * SCF_ERROR_NO_MEMORY if memory allocation failed. 1400 * SCF_ERROR_CONNECTION_BROKEN if the connection to the repository was broken. 1401 * SCF_ERROR_TYPE_MISMATCH if the property was of an unexpected type. 1402 * SCF_ERROR_NO_RESOURCES if the server doesn't have adequate resources. 1403 * SCF_ERROR_NO_SERVER if the server isn't running. 1404 */ 1405 static scf_error_t 1406 retrieve_instance_state(instance_t *inst) 1407 { 1408 scf_error_t ret; 1409 1410 /* retrieve internal states */ 1411 if (((ret = retrieve_rep_vals(inst->cur_istate_rep, inst->fmri, 1412 PR_NAME_CUR_INT_STATE)) != 0) || 1413 ((ret = retrieve_rep_vals(inst->next_istate_rep, inst->fmri, 1414 PR_NAME_NEXT_INT_STATE)) != 0)) { 1415 if (ret != SCF_ERROR_NOT_FOUND) { 1416 error_msg(gettext( 1417 "Failed to read state of instance %s: %s"), 1418 inst->fmri, scf_strerror(scf_error())); 1419 return (ret); 1420 } 1421 1422 debug_msg("instance with no previous int state - " 1423 "setting state to uninitialized"); 1424 1425 if ((set_single_rep_val(inst->cur_istate_rep, 1426 (int64_t)IIS_UNINITIALIZED) == -1) || 1427 (set_single_rep_val(inst->next_istate_rep, 1428 (int64_t)IIS_NONE) == -1)) { 1429 return (SCF_ERROR_NO_MEMORY); 1430 } 1431 } 1432 1433 /* update convenience states */ 1434 inst->cur_istate = get_single_rep_val(inst->cur_istate_rep); 1435 inst->next_istate = get_single_rep_val(inst->next_istate_rep); 1436 return (0); 1437 } 1438 1439 /* 1440 * Retrieve stored process ids and register each of them so we process their 1441 * termination. 1442 */ 1443 static int 1444 retrieve_method_pids(instance_t *inst) 1445 { 1446 rep_val_t *rv; 1447 1448 switch (retrieve_rep_vals(inst->start_pids, inst->fmri, 1449 PR_NAME_START_PIDS)) { 1450 case 0: 1451 break; 1452 case SCF_ERROR_NOT_FOUND: 1453 return (0); 1454 default: 1455 error_msg(gettext("Failed to retrieve the start pids of " 1456 "instance %s from repository: %s"), inst->fmri, 1457 scf_strerror(scf_error())); 1458 return (-1); 1459 } 1460 1461 rv = uu_list_first(inst->start_pids); 1462 while (rv != NULL) { 1463 if (register_method(inst, (pid_t)rv->val, (ctid_t)-1, 1464 IM_START, NULL) == 0) { 1465 inst->copies++; 1466 rv = uu_list_next(inst->start_pids, rv); 1467 } else if (errno == ENOENT) { 1468 pid_t pid = (pid_t)rv->val; 1469 1470 /* 1471 * The process must have already terminated. Remove 1472 * it from the list. 1473 */ 1474 rv = uu_list_next(inst->start_pids, rv); 1475 remove_rep_val(inst->start_pids, pid); 1476 } else { 1477 error_msg(gettext("Failed to listen for the completion " 1478 "of %s method of instance %s"), START_METHOD_NAME, 1479 inst->fmri); 1480 rv = uu_list_next(inst->start_pids, rv); 1481 } 1482 } 1483 1484 /* synch the repository pid list to remove any terminated pids */ 1485 (void) store_rep_vals(inst->start_pids, inst->fmri, PR_NAME_START_PIDS); 1486 1487 return (0); 1488 } 1489 1490 /* 1491 * Remove the passed instance from inetd control. 1492 */ 1493 static void 1494 remove_instance(instance_t *instance) 1495 { 1496 switch (instance->cur_istate) { 1497 case IIS_ONLINE: 1498 case IIS_DEGRADED: 1499 /* stop listening for network connections */ 1500 destroy_bound_fds(instance); 1501 break; 1502 case IIS_OFFLINE_BIND: 1503 cancel_bind_timer(instance); 1504 break; 1505 case IIS_OFFLINE_CONRATE: 1506 cancel_inst_timer(instance); 1507 break; 1508 } 1509 1510 /* stop listening for terminated methods */ 1511 unregister_instance_methods(instance); 1512 1513 uu_list_remove(instance_list, instance); 1514 destroy_instance(instance); 1515 } 1516 1517 /* 1518 * Refresh the configuration of instance 'inst'. This method gets called as 1519 * a result of a refresh event for the instance from the master restarter, so 1520 * we can rely upon the instance's running snapshot having been updated from 1521 * its configuration snapshot. 1522 */ 1523 void 1524 refresh_instance(instance_t *inst) 1525 { 1526 instance_cfg_t *cfg; 1527 1528 switch (inst->cur_istate) { 1529 case IIS_MAINTENANCE: 1530 case IIS_DISABLED: 1531 case IIS_UNINITIALIZED: 1532 /* 1533 * Ignore any possible changes, we'll re-read the configuration 1534 * automatically when we exit these states. 1535 */ 1536 break; 1537 1538 case IIS_OFFLINE_COPIES: 1539 case IIS_OFFLINE_BIND: 1540 case IIS_OFFLINE: 1541 case IIS_OFFLINE_CONRATE: 1542 destroy_instance_cfg(inst->config); 1543 if ((inst->config = read_instance_cfg(inst->fmri)) == NULL) { 1544 log_invalid_cfg(inst->fmri); 1545 if (inst->cur_istate == IIS_OFFLINE_BIND) { 1546 cancel_bind_timer(inst); 1547 } else if (inst->cur_istate == IIS_OFFLINE_CONRATE) { 1548 cancel_inst_timer(inst); 1549 } 1550 update_state(inst, IIS_MAINTENANCE, RERR_FAULT); 1551 } else { 1552 switch (inst->cur_istate) { 1553 case IIS_OFFLINE_BIND: 1554 if (copies_limit_exceeded(inst)) { 1555 /* Cancel scheduled bind retries. */ 1556 cancel_bind_timer(inst); 1557 1558 /* 1559 * Take the instance to the copies 1560 * offline state, via the offline 1561 * state. 1562 */ 1563 update_state(inst, IIS_OFFLINE, 1564 RERR_RESTART); 1565 process_offline_inst(inst); 1566 } 1567 break; 1568 1569 case IIS_OFFLINE: 1570 process_offline_inst(inst); 1571 break; 1572 1573 case IIS_OFFLINE_CONRATE: 1574 /* 1575 * Since we're already in a DOS state, 1576 * don't bother evaluating the copies 1577 * limit. This will be evaluated when 1578 * we leave this state in 1579 * process_offline_inst(). 1580 */ 1581 break; 1582 1583 case IIS_OFFLINE_COPIES: 1584 /* 1585 * Check if the copies limit has been increased 1586 * above the current count. 1587 */ 1588 if (!copies_limit_exceeded(inst)) { 1589 update_state(inst, IIS_OFFLINE, 1590 RERR_RESTART); 1591 process_offline_inst(inst); 1592 } 1593 break; 1594 1595 default: 1596 assert(0); 1597 } 1598 } 1599 break; 1600 1601 case IIS_DEGRADED: 1602 case IIS_ONLINE: 1603 if ((cfg = read_instance_cfg(inst->fmri)) != NULL) { 1604 instance_cfg_t *ocfg = inst->config; 1605 1606 /* 1607 * Try to avoid the overhead of taking an instance 1608 * offline and back on again. We do this by limiting 1609 * this behavior to two eventualities: 1610 * - there needs to be a re-bind to listen on behalf 1611 * of the instance with its new configuration. This 1612 * could be because for example its service has been 1613 * associated with a different port, or because the 1614 * v6only protocol option has been newly applied to 1615 * the instance. 1616 * - one or both of the start or online methods of the 1617 * instance have changed in the new configuration. 1618 * Without taking the instance offline when the 1619 * start method changed the instance may be running 1620 * with unwanted parameters (or event an unwanted 1621 * binary); and without taking the instance offline 1622 * if its online method was to change, some part of 1623 * its running environment may have changed and would 1624 * not be picked up until the instance next goes 1625 * offline for another reason. 1626 */ 1627 if ((!bind_config_equal(ocfg->basic, cfg->basic)) || 1628 !method_info_equal(ocfg->methods[IM_ONLINE], 1629 cfg->methods[IM_ONLINE]) || 1630 !method_info_equal(ocfg->methods[IM_START], 1631 cfg->methods[IM_START])) { 1632 destroy_bound_fds(inst); 1633 1634 assert(inst->new_config == NULL); 1635 inst->new_config = cfg; 1636 1637 (void) run_method(inst, IM_OFFLINE, NULL); 1638 } else { /* no bind config / method changes */ 1639 1640 /* 1641 * swap the proto list over from the old 1642 * configuration to the new, so we retain 1643 * our set of network fds. 1644 */ 1645 destroy_proto_list(cfg->basic); 1646 cfg->basic->proto_list = 1647 ocfg->basic->proto_list; 1648 ocfg->basic->proto_list = NULL; 1649 destroy_instance_cfg(ocfg); 1650 inst->config = cfg; 1651 1652 /* re-evaluate copies limits based on new cfg */ 1653 if (copies_limit_exceeded(inst)) { 1654 destroy_bound_fds(inst); 1655 (void) run_method(inst, IM_OFFLINE, 1656 NULL); 1657 } else { 1658 /* 1659 * Since the instance isn't being 1660 * taken offline, where we assume it 1661 * would pick-up any configuration 1662 * changes automatically when it goes 1663 * back online, run its refresh method 1664 * to allow it to pick-up any changes 1665 * whilst still online. 1666 */ 1667 (void) run_method(inst, IM_REFRESH, 1668 NULL); 1669 } 1670 } 1671 } else { 1672 log_invalid_cfg(inst->fmri); 1673 1674 destroy_bound_fds(inst); 1675 1676 inst->maintenance_req = B_TRUE; 1677 (void) run_method(inst, IM_OFFLINE, NULL); 1678 } 1679 break; 1680 1681 default: 1682 debug_msg("Unhandled current state %d for instance in " 1683 "refresh_instance", inst->cur_istate); 1684 assert(0); 1685 } 1686 } 1687 1688 /* 1689 * Called by process_restarter_event() to handle a restarter event for an 1690 * instance. 1691 */ 1692 static void 1693 handle_restarter_event(instance_t *instance, restarter_event_type_t event, 1694 boolean_t send_ack) 1695 { 1696 switch (event) { 1697 case RESTARTER_EVENT_TYPE_ADD_INSTANCE: 1698 /* 1699 * When startd restarts, it sends _ADD_INSTANCE to delegated 1700 * restarters for all those services managed by them. We should 1701 * acknowledge this event, as startd's graph needs to be updated 1702 * about the current state of the service, when startd is 1703 * restarting. 1704 * update_state() is ok to be called here, as commands for 1705 * instances in transition are deferred by 1706 * process_restarter_event(). 1707 */ 1708 update_state(instance, instance->cur_istate, RERR_NONE); 1709 goto done; 1710 case RESTARTER_EVENT_TYPE_ADMIN_REFRESH: 1711 refresh_instance(instance); 1712 goto done; 1713 case RESTARTER_EVENT_TYPE_ADMIN_RESTART: 1714 /* 1715 * We've got a restart event, so if the instance is online 1716 * in any way initiate taking it offline, and rely upon 1717 * our restarter to send us an online event to bring 1718 * it back online. 1719 */ 1720 switch (instance->cur_istate) { 1721 case IIS_ONLINE: 1722 case IIS_DEGRADED: 1723 destroy_bound_fds(instance); 1724 (void) run_method(instance, IM_OFFLINE, NULL); 1725 } 1726 goto done; 1727 case RESTARTER_EVENT_TYPE_REMOVE_INSTANCE: 1728 remove_instance(instance); 1729 goto done; 1730 case RESTARTER_EVENT_TYPE_STOP_RESET: 1731 case RESTARTER_EVENT_TYPE_STOP: 1732 switch (instance->cur_istate) { 1733 case IIS_OFFLINE_CONRATE: 1734 case IIS_OFFLINE_BIND: 1735 case IIS_OFFLINE_COPIES: 1736 /* 1737 * inetd must be closing down as we wouldn't get this 1738 * event in one of these states from the master 1739 * restarter. Take the instance to the offline resting 1740 * state. 1741 */ 1742 if (instance->cur_istate == IIS_OFFLINE_BIND) { 1743 cancel_bind_timer(instance); 1744 } else if (instance->cur_istate == 1745 IIS_OFFLINE_CONRATE) { 1746 cancel_inst_timer(instance); 1747 } 1748 update_state(instance, IIS_OFFLINE, RERR_RESTART); 1749 goto done; 1750 } 1751 break; 1752 } 1753 1754 switch (instance->cur_istate) { 1755 case IIS_OFFLINE: 1756 switch (event) { 1757 case RESTARTER_EVENT_TYPE_START: 1758 /* 1759 * Dependencies are met, let's take the service online. 1760 * Only try and bind for a wait type service if 1761 * no process is running on its behalf. Otherwise, just 1762 * mark the service online and binding will be attempted 1763 * when the process exits. 1764 */ 1765 if (!(instance->config->basic->iswait && 1766 (uu_list_first(instance->start_pids) != NULL))) { 1767 create_bound_fds(instance); 1768 } else { 1769 update_state(instance, IIS_ONLINE, RERR_NONE); 1770 } 1771 break; 1772 case RESTARTER_EVENT_TYPE_DISABLE: 1773 case RESTARTER_EVENT_TYPE_ADMIN_DISABLE: 1774 /* 1775 * The instance should be disabled, so run the 1776 * instance's disabled method that will do the work 1777 * to take it there. 1778 */ 1779 (void) run_method(instance, IM_DISABLE, NULL); 1780 break; 1781 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON: 1782 case RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE: 1783 case RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY: 1784 /* 1785 * The master restarter has requested the instance 1786 * go to maintenance; since we're already offline 1787 * just update the state to the maintenance state. 1788 */ 1789 update_state(instance, IIS_MAINTENANCE, RERR_RESTART); 1790 break; 1791 } 1792 break; 1793 1794 case IIS_OFFLINE_BIND: 1795 switch (event) { 1796 case RESTARTER_EVENT_TYPE_DISABLE: 1797 case RESTARTER_EVENT_TYPE_ADMIN_DISABLE: 1798 /* 1799 * The instance should be disabled. Firstly, as for 1800 * the above dependencies unmet comment, cancel 1801 * the bind retry timer and update the state to 1802 * offline. Then, run the disable method to do the 1803 * work to take the instance from offline to 1804 * disabled. 1805 */ 1806 cancel_bind_timer(instance); 1807 update_state(instance, IIS_OFFLINE, RERR_RESTART); 1808 (void) run_method(instance, IM_DISABLE, NULL); 1809 break; 1810 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON: 1811 case RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE: 1812 case RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY: 1813 /* 1814 * The master restarter has requested the instance 1815 * be placed in the maintenance state. Cancel the 1816 * outstanding retry timer, and since we're already 1817 * offline, update the state to maintenance. 1818 */ 1819 cancel_bind_timer(instance); 1820 update_state(instance, IIS_MAINTENANCE, RERR_RESTART); 1821 break; 1822 } 1823 break; 1824 1825 case IIS_DEGRADED: 1826 case IIS_ONLINE: 1827 switch (event) { 1828 case RESTARTER_EVENT_TYPE_DISABLE: 1829 case RESTARTER_EVENT_TYPE_ADMIN_DISABLE: 1830 /* 1831 * The instance needs to be disabled. Do the same work 1832 * as for the dependencies unmet event below to 1833 * take the instance offline. 1834 */ 1835 destroy_bound_fds(instance); 1836 /* 1837 * Indicate that the offline method is being run 1838 * as part of going to the disabled state, and to 1839 * carry on this transition. 1840 */ 1841 instance->disable_req = B_TRUE; 1842 (void) run_method(instance, IM_OFFLINE, NULL); 1843 break; 1844 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON: 1845 case RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE: 1846 case RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY: 1847 /* 1848 * The master restarter has requested the instance be 1849 * placed in the maintenance state. This involves 1850 * firstly taking the service offline, so do the 1851 * same work as for the dependencies unmet event 1852 * below. We set the maintenance_req flag to 1853 * indicate that when we get to the offline state 1854 * we should be placed directly into the maintenance 1855 * state. 1856 */ 1857 instance->maintenance_req = B_TRUE; 1858 /* FALLTHROUGH */ 1859 case RESTARTER_EVENT_TYPE_STOP_RESET: 1860 case RESTARTER_EVENT_TYPE_STOP: 1861 /* 1862 * Dependencies have become unmet. Close and 1863 * stop listening on the instance's network file 1864 * descriptor, and run the offline method to do 1865 * any work required to take us to the offline state. 1866 */ 1867 destroy_bound_fds(instance); 1868 (void) run_method(instance, IM_OFFLINE, NULL); 1869 } 1870 break; 1871 1872 case IIS_UNINITIALIZED: 1873 if (event == RESTARTER_EVENT_TYPE_DISABLE || 1874 event == RESTARTER_EVENT_TYPE_ADMIN_DISABLE) { 1875 update_state(instance, IIS_DISABLED, RERR_NONE); 1876 break; 1877 } else if (event != RESTARTER_EVENT_TYPE_ENABLE) { 1878 /* 1879 * Ignore other events until we know whether we're 1880 * enabled or not. 1881 */ 1882 break; 1883 } 1884 1885 /* 1886 * We've got an enabled event; make use of the handling in the 1887 * disable case. 1888 */ 1889 /* FALLTHROUGH */ 1890 1891 case IIS_DISABLED: 1892 switch (event) { 1893 case RESTARTER_EVENT_TYPE_ENABLE: 1894 /* 1895 * The instance needs enabling. Commence reading its 1896 * configuration and if successful place the instance 1897 * in the offline state and let process_offline_inst() 1898 * take it from there. 1899 */ 1900 destroy_instance_cfg(instance->config); 1901 instance->config = read_instance_cfg(instance->fmri); 1902 if (instance->config != NULL) { 1903 update_state(instance, IIS_OFFLINE, 1904 RERR_RESTART); 1905 process_offline_inst(instance); 1906 } else { 1907 log_invalid_cfg(instance->fmri); 1908 update_state(instance, IIS_MAINTENANCE, 1909 RERR_RESTART); 1910 } 1911 1912 break; 1913 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON: 1914 case RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE: 1915 case RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY: 1916 /* 1917 * The master restarter has requested the instance be 1918 * placed in the maintenance state, so just update its 1919 * state to maintenance. 1920 */ 1921 update_state(instance, IIS_MAINTENANCE, RERR_RESTART); 1922 break; 1923 } 1924 break; 1925 1926 case IIS_MAINTENANCE: 1927 switch (event) { 1928 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF: 1929 case RESTARTER_EVENT_TYPE_ADMIN_DISABLE: 1930 /* 1931 * The master restarter has requested that the instance 1932 * be taken out of maintenance. Read its configuration, 1933 * and if successful place the instance in the offline 1934 * state and call process_offline_inst() to take it 1935 * from there. 1936 */ 1937 destroy_instance_cfg(instance->config); 1938 instance->config = read_instance_cfg(instance->fmri); 1939 if (instance->config != NULL) { 1940 update_state(instance, IIS_OFFLINE, 1941 RERR_RESTART); 1942 process_offline_inst(instance); 1943 } else { 1944 boolean_t enabled; 1945 1946 /* 1947 * The configuration was invalid. If the 1948 * service has disabled requested, let's 1949 * just place the instance in disabled even 1950 * though we haven't been able to run its 1951 * disable method, as the slightly incorrect 1952 * state is likely to be less of an issue to 1953 * an administrator than refusing to move an 1954 * instance to disabled. If disable isn't 1955 * requested, re-mark the service's state 1956 * as maintenance, so the administrator can 1957 * see the request was processed. 1958 */ 1959 if ((read_enable_merged(instance->fmri, 1960 &enabled) == 0) && !enabled) { 1961 update_state(instance, IIS_DISABLED, 1962 RERR_RESTART); 1963 } else { 1964 log_invalid_cfg(instance->fmri); 1965 update_state(instance, IIS_MAINTENANCE, 1966 RERR_FAULT); 1967 } 1968 } 1969 break; 1970 } 1971 break; 1972 1973 case IIS_OFFLINE_CONRATE: 1974 switch (event) { 1975 case RESTARTER_EVENT_TYPE_DISABLE: 1976 /* 1977 * The instance wants disabling. Take the instance 1978 * offline as for the dependencies unmet event above, 1979 * and then from there run the disable method to do 1980 * the work to take the instance to the disabled state. 1981 */ 1982 cancel_inst_timer(instance); 1983 update_state(instance, IIS_OFFLINE, RERR_RESTART); 1984 (void) run_method(instance, IM_DISABLE, NULL); 1985 break; 1986 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON: 1987 case RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE: 1988 case RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY: 1989 /* 1990 * The master restarter has requested the instance 1991 * be taken to maintenance. Cancel the timer setup 1992 * when we entered this state, and go directly to 1993 * maintenance. 1994 */ 1995 cancel_inst_timer(instance); 1996 update_state(instance, IIS_MAINTENANCE, RERR_RESTART); 1997 break; 1998 } 1999 break; 2000 2001 case IIS_OFFLINE_COPIES: 2002 switch (event) { 2003 case RESTARTER_EVENT_TYPE_DISABLE: 2004 /* 2005 * The instance wants disabling. Update the state 2006 * to offline, and run the disable method to do the 2007 * work to take it to the disabled state. 2008 */ 2009 update_state(instance, IIS_OFFLINE, RERR_RESTART); 2010 (void) run_method(instance, IM_DISABLE, NULL); 2011 break; 2012 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON: 2013 case RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE: 2014 case RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY: 2015 /* 2016 * The master restarter has requested the instance be 2017 * placed in maintenance. Since it's already offline 2018 * simply update the state. 2019 */ 2020 update_state(instance, IIS_MAINTENANCE, RERR_RESTART); 2021 break; 2022 } 2023 break; 2024 2025 default: 2026 debug_msg("handle_restarter_event: instance in an " 2027 "unexpected state"); 2028 assert(0); 2029 } 2030 2031 done: 2032 if (send_ack) 2033 ack_restarter_event(B_TRUE); 2034 } 2035 2036 /* 2037 * Tries to read and process an event from the event pipe. If there isn't one 2038 * or an error occurred processing the event it returns -1. Else, if the event 2039 * is for an instance we're not already managing we read its state, add it to 2040 * our list to manage, and if appropriate read its configuration. Whether it's 2041 * new to us or not, we then handle the specific event. 2042 * Returns 0 if an event was read and processed successfully, else -1. 2043 */ 2044 static int 2045 process_restarter_event(void) 2046 { 2047 char *fmri; 2048 size_t fmri_size; 2049 restarter_event_type_t event_type; 2050 instance_t *instance; 2051 restarter_event_t *event; 2052 ssize_t sz; 2053 2054 /* 2055 * Try to read an event pointer from the event pipe. 2056 */ 2057 errno = 0; 2058 switch (safe_read(rst_event_pipe[PE_CONSUMER], &event, 2059 sizeof (event))) { 2060 case 0: 2061 break; 2062 case 1: 2063 if (errno == EAGAIN) /* no event to read */ 2064 return (-1); 2065 2066 /* other end of pipe closed */ 2067 2068 /* FALLTHROUGH */ 2069 default: /* unexpected read error */ 2070 /* 2071 * There's something wrong with the event pipe. Let's 2072 * shutdown and be restarted. 2073 */ 2074 inetd_stop(); 2075 return (-1); 2076 } 2077 2078 /* 2079 * Check if we're currently managing the instance which the event 2080 * pertains to. If not, read its complete state and add it to our 2081 * list to manage. 2082 */ 2083 2084 fmri_size = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); 2085 if ((fmri = malloc(fmri_size)) == NULL) { 2086 error_msg(strerror(errno)); 2087 goto fail; 2088 } 2089 sz = restarter_event_get_instance(event, fmri, fmri_size); 2090 if (sz >= fmri_size) 2091 assert(0); 2092 2093 for (instance = uu_list_first(instance_list); instance != NULL; 2094 instance = uu_list_next(instance_list, instance)) { 2095 if (strcmp(instance->fmri, fmri) == 0) 2096 break; 2097 } 2098 2099 if (instance == NULL) { 2100 int err; 2101 2102 debug_msg("New instance to manage: %s", fmri); 2103 2104 if (((instance = create_instance(fmri)) == NULL) || 2105 (retrieve_instance_state(instance) != 0) || 2106 (retrieve_method_pids(instance) != 0)) { 2107 destroy_instance(instance); 2108 free(fmri); 2109 goto fail; 2110 } 2111 2112 if (((err = iterate_repository_contracts(instance, 0)) 2113 != 0) && (err != ENOENT)) { 2114 error_msg(gettext( 2115 "Failed to adopt contracts of instance %s: %s"), 2116 instance->fmri, strerror(err)); 2117 destroy_instance(instance); 2118 free(fmri); 2119 goto fail; 2120 } 2121 2122 uu_list_node_init(instance, &instance->link, instance_pool); 2123 (void) uu_list_insert_after(instance_list, NULL, instance); 2124 2125 /* 2126 * Only read configuration for instances that aren't in any of 2127 * the disabled, maintenance or uninitialized states, since 2128 * they'll read it on state exit. 2129 */ 2130 if ((instance->cur_istate != IIS_DISABLED) && 2131 (instance->cur_istate != IIS_MAINTENANCE) && 2132 (instance->cur_istate != IIS_UNINITIALIZED)) { 2133 instance->config = read_instance_cfg(instance->fmri); 2134 if (instance->config == NULL) { 2135 log_invalid_cfg(instance->fmri); 2136 update_state(instance, IIS_MAINTENANCE, 2137 RERR_FAULT); 2138 } 2139 } 2140 } 2141 2142 free(fmri); 2143 2144 event_type = restarter_event_get_type(event); 2145 debug_msg("Event type: %d for instance: %s", event_type, 2146 instance->fmri); 2147 2148 /* 2149 * If the instance is currently running a method, don't process the 2150 * event now, but attach it to the instance for processing when 2151 * the instance finishes its transition. 2152 */ 2153 if (INST_IN_TRANSITION(instance)) { 2154 debug_msg("storing event %d for instance %s", event_type, 2155 instance->fmri); 2156 instance->pending_rst_event = event_type; 2157 } else { 2158 handle_restarter_event(instance, event_type, B_TRUE); 2159 } 2160 2161 return (0); 2162 2163 fail: 2164 ack_restarter_event(B_FALSE); 2165 return (-1); 2166 } 2167 2168 /* 2169 * Do the state machine processing associated with the termination of instance 2170 * 'inst''s start method for the 'proto_name' protocol if this parameter is not 2171 * NULL. 2172 */ 2173 void 2174 process_start_term(instance_t *inst, char *proto_name) 2175 { 2176 basic_cfg_t *cfg; 2177 2178 inst->copies--; 2179 2180 if ((inst->cur_istate == IIS_MAINTENANCE) || 2181 (inst->cur_istate == IIS_DISABLED)) { 2182 /* do any further processing/checks when we exit these states */ 2183 return; 2184 } 2185 2186 cfg = inst->config->basic; 2187 2188 if (cfg->iswait) { 2189 proto_info_t *pi; 2190 boolean_t listen; 2191 2192 switch (inst->cur_istate) { 2193 case IIS_ONLINE: 2194 case IIS_DEGRADED: 2195 case IIS_IN_REFRESH_METHOD: 2196 /* 2197 * A wait type service's start method has exited. 2198 * Check if the method was fired off in this inetd's 2199 * lifetime, or a previous one; if the former, 2200 * re-commence listening on the service's behalf; if 2201 * the latter, mark the service offline and let bind 2202 * attempts commence. 2203 */ 2204 listen = B_FALSE; 2205 for (pi = uu_list_first(cfg->proto_list); pi != NULL; 2206 pi = uu_list_next(cfg->proto_list, pi)) { 2207 /* 2208 * If a bound fd exists, the method was fired 2209 * off during this inetd's lifetime. 2210 */ 2211 if (pi->listen_fd != -1) { 2212 listen = B_TRUE; 2213 if (proto_name == NULL || 2214 strcmp(pi->proto, proto_name) == 0) 2215 break; 2216 } 2217 } 2218 if (pi != NULL) { 2219 if (poll_bound_fds(inst, B_TRUE, proto_name) != 2220 0) 2221 handle_bind_failure(inst); 2222 } else if (listen == B_FALSE) { 2223 update_state(inst, IIS_OFFLINE, RERR_RESTART); 2224 create_bound_fds(inst); 2225 } 2226 } 2227 } else { 2228 /* 2229 * Check if a nowait service should be brought back online 2230 * after exceeding its copies limit. 2231 */ 2232 if ((inst->cur_istate == IIS_OFFLINE_COPIES) && 2233 !copies_limit_exceeded(inst)) { 2234 update_state(inst, IIS_OFFLINE, RERR_NONE); 2235 process_offline_inst(inst); 2236 } 2237 } 2238 } 2239 2240 /* 2241 * If the instance has a pending event process it and initiate the 2242 * acknowledgement. 2243 */ 2244 static void 2245 process_pending_rst_event(instance_t *inst) 2246 { 2247 if (inst->pending_rst_event != RESTARTER_EVENT_TYPE_INVALID) { 2248 restarter_event_type_t re; 2249 2250 debug_msg("Injecting pending event %d for instance %s", 2251 inst->pending_rst_event, inst->fmri); 2252 re = inst->pending_rst_event; 2253 inst->pending_rst_event = RESTARTER_EVENT_TYPE_INVALID; 2254 handle_restarter_event(inst, re, B_TRUE); 2255 } 2256 } 2257 2258 /* 2259 * Do the state machine processing associated with the termination 2260 * of the specified instance's non-start method with the specified status. 2261 * Once the processing of the termination is done, the function also picks up 2262 * any processing that was blocked on the method running. 2263 */ 2264 void 2265 process_non_start_term(instance_t *inst, int status) 2266 { 2267 boolean_t ran_online_method = B_FALSE; 2268 2269 if (status == IMRET_FAILURE) { 2270 error_msg(gettext("The %s method of instance %s failed, " 2271 "transitioning to maintenance"), 2272 methods[states[inst->cur_istate].method_running].name, 2273 inst->fmri); 2274 2275 if ((inst->cur_istate == IIS_IN_ONLINE_METHOD) || 2276 (inst->cur_istate == IIS_IN_REFRESH_METHOD)) 2277 destroy_bound_fds(inst); 2278 2279 update_state(inst, IIS_MAINTENANCE, RERR_FAULT); 2280 2281 inst->maintenance_req = B_FALSE; 2282 inst->conn_rate_exceeded = B_FALSE; 2283 2284 if (inst->new_config != NULL) { 2285 destroy_instance_cfg(inst->new_config); 2286 inst->new_config = NULL; 2287 } 2288 2289 if (!inetd_stopping) 2290 process_pending_rst_event(inst); 2291 2292 return; 2293 } 2294 2295 /* non-failure method return */ 2296 2297 if (status != IMRET_SUCCESS) { 2298 /* 2299 * An instance method never returned a supported return code. 2300 * We'll assume this means the method succeeded for now whilst 2301 * non-GL-cognizant methods are used - eg. pkill. 2302 */ 2303 debug_msg("The %s method of instance %s returned " 2304 "non-compliant exit code: %d, assuming success", 2305 methods[states[inst->cur_istate].method_running].name, 2306 inst->fmri, status); 2307 } 2308 2309 /* 2310 * Update the state from the in-transition state. 2311 */ 2312 switch (inst->cur_istate) { 2313 case IIS_IN_ONLINE_METHOD: 2314 ran_online_method = B_TRUE; 2315 /* FALLTHROUGH */ 2316 case IIS_IN_REFRESH_METHOD: 2317 /* 2318 * If we've exhausted the bind retries, flag that by setting 2319 * the instance's state to degraded. 2320 */ 2321 if (inst->bind_retries_exceeded) { 2322 update_state(inst, IIS_DEGRADED, RERR_NONE); 2323 break; 2324 } 2325 /* FALLTHROUGH */ 2326 default: 2327 update_state(inst, 2328 methods[states[inst->cur_istate].method_running].dst_state, 2329 RERR_NONE); 2330 } 2331 2332 if (inst->cur_istate == IIS_OFFLINE) { 2333 if (inst->new_config != NULL) { 2334 /* 2335 * This instance was found during refresh to need 2336 * taking offline because its newly read configuration 2337 * was sufficiently different. Now we're offline, 2338 * activate this new configuration. 2339 */ 2340 destroy_instance_cfg(inst->config); 2341 inst->config = inst->new_config; 2342 inst->new_config = NULL; 2343 } 2344 2345 /* continue/complete any transitions that are in progress */ 2346 process_offline_inst(inst); 2347 2348 } else if (ran_online_method) { 2349 /* 2350 * We've just successfully executed the online method. We have 2351 * a set of bound network fds that were created before running 2352 * this method, so now we're online start listening for 2353 * connections on them. 2354 */ 2355 if (poll_bound_fds(inst, B_TRUE, NULL) != 0) 2356 handle_bind_failure(inst); 2357 } 2358 2359 /* 2360 * If we're now out of transition (process_offline_inst() could have 2361 * fired off another method), carry out any jobs that were blocked by 2362 * us being in transition. 2363 */ 2364 if (!INST_IN_TRANSITION(inst)) { 2365 if (inetd_stopping) { 2366 if (!instance_stopped(inst)) { 2367 /* 2368 * inetd is stopping, and this instance hasn't 2369 * been stopped. Inject a stop event. 2370 */ 2371 handle_restarter_event(inst, 2372 RESTARTER_EVENT_TYPE_STOP, B_FALSE); 2373 } 2374 } else { 2375 process_pending_rst_event(inst); 2376 } 2377 } 2378 } 2379 2380 /* 2381 * Check if configuration file specified is readable. If not return B_FALSE, 2382 * else return B_TRUE. 2383 */ 2384 static boolean_t 2385 can_read_file(const char *path) 2386 { 2387 int ret; 2388 int serrno; 2389 2390 do { 2391 ret = access(path, R_OK); 2392 } while ((ret < 0) && (errno == EINTR)); 2393 if (ret < 0) { 2394 if (errno != ENOENT) { 2395 serrno = errno; 2396 error_msg(gettext("Failed to access configuration " 2397 "file %s for performing modification checks: %s"), 2398 path, strerror(errno)); 2399 errno = serrno; 2400 } 2401 return (B_FALSE); 2402 } 2403 return (B_TRUE); 2404 } 2405 2406 /* 2407 * Check whether the configuration file has changed contents since inetd 2408 * was last started/refreshed, and if so, log a message indicating that 2409 * inetconv needs to be run. 2410 */ 2411 static void 2412 check_conf_file(void) 2413 { 2414 char *new_hash; 2415 char *old_hash = NULL; 2416 scf_error_t ret; 2417 const char *file; 2418 2419 if (conf_file == NULL) { 2420 /* 2421 * No explicit config file specified, so see if one of the 2422 * default two are readable, checking the primary one first 2423 * followed by the secondary. 2424 */ 2425 if (can_read_file(PRIMARY_DEFAULT_CONF_FILE)) { 2426 file = PRIMARY_DEFAULT_CONF_FILE; 2427 } else if ((errno == ENOENT) && 2428 can_read_file(SECONDARY_DEFAULT_CONF_FILE)) { 2429 file = SECONDARY_DEFAULT_CONF_FILE; 2430 } else { 2431 return; 2432 } 2433 } else { 2434 file = conf_file; 2435 if (!can_read_file(file)) 2436 return; 2437 } 2438 2439 if (calculate_hash(file, &new_hash) == 0) { 2440 ret = retrieve_inetd_hash(&old_hash); 2441 if (((ret == SCF_ERROR_NONE) && 2442 (strcmp(old_hash, new_hash) != 0))) { 2443 /* modified config file */ 2444 warn_msg(gettext( 2445 "Configuration file %s has been modified since " 2446 "inetconv was last run. \"inetconv -i %s\" must be " 2447 "run to apply any changes to the SMF"), file, file); 2448 } else if ((ret != SCF_ERROR_NOT_FOUND) && 2449 (ret != SCF_ERROR_NONE)) { 2450 /* No message if hash not yet computed */ 2451 error_msg(gettext("Failed to check whether " 2452 "configuration file %s has been modified: %s"), 2453 file, scf_strerror(ret)); 2454 } 2455 free(old_hash); 2456 free(new_hash); 2457 } else { 2458 error_msg(gettext("Failed to check whether configuration file " 2459 "%s has been modified: %s"), file, strerror(errno)); 2460 } 2461 } 2462 2463 /* 2464 * Refresh all inetd's managed instances and check the configuration file 2465 * for any updates since inetconv was last run, logging a message if there 2466 * are. We call the SMF refresh function to refresh each instance so that 2467 * the refresh request goes through the framework, and thus results in the 2468 * running snapshot of each instance being updated from the configuration 2469 * snapshot. 2470 */ 2471 static void 2472 inetd_refresh(void) 2473 { 2474 instance_t *inst; 2475 2476 refresh_debug_flag(); 2477 2478 /* call libscf to send refresh requests for all managed instances */ 2479 for (inst = uu_list_first(instance_list); inst != NULL; 2480 inst = uu_list_next(instance_list, inst)) { 2481 if (smf_refresh_instance(inst->fmri) < 0) { 2482 error_msg(gettext("Failed to refresh instance %s: %s"), 2483 inst->fmri, scf_strerror(scf_error())); 2484 } 2485 } 2486 2487 /* 2488 * Log a message if the configuration file has changed since inetconv 2489 * was last run. 2490 */ 2491 check_conf_file(); 2492 } 2493 2494 /* 2495 * Initiate inetd's shutdown. 2496 */ 2497 static void 2498 inetd_stop(void) 2499 { 2500 instance_t *inst; 2501 2502 /* Block handling signals for stop and refresh */ 2503 (void) sighold(SIGHUP); 2504 (void) sighold(SIGTERM); 2505 2506 /* Indicate inetd is coming down */ 2507 inetd_stopping = B_TRUE; 2508 2509 /* Stop polling on restarter events. */ 2510 clear_pollfd(rst_event_pipe[PE_CONSUMER]); 2511 2512 /* Stop polling for any more stop/refresh requests. */ 2513 clear_pollfd(uds_fd); 2514 2515 /* 2516 * Send a stop event to all currently unstopped instances that 2517 * aren't in transition. For those that are in transition, the 2518 * event will get sent when the transition completes. 2519 */ 2520 for (inst = uu_list_first(instance_list); inst != NULL; 2521 inst = uu_list_next(instance_list, inst)) { 2522 if (!instance_stopped(inst) && !INST_IN_TRANSITION(inst)) 2523 handle_restarter_event(inst, 2524 RESTARTER_EVENT_TYPE_STOP, B_FALSE); 2525 } 2526 } 2527 2528 /* 2529 * Sets up the intra-inetd-process Unix Domain Socket. 2530 * Returns -1 on error, else 0. 2531 */ 2532 static int 2533 uds_init(void) 2534 { 2535 struct sockaddr_un addr; 2536 2537 if ((uds_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { 2538 error_msg("socket: %s", strerror(errno)); 2539 return (-1); 2540 } 2541 2542 disable_blocking(uds_fd); 2543 2544 (void) unlink(INETD_UDS_PATH); /* clean-up any stale files */ 2545 2546 (void) memset(&addr, 0, sizeof (addr)); 2547 addr.sun_family = AF_UNIX; 2548 /* CONSTCOND */ 2549 assert(sizeof (INETD_UDS_PATH) <= sizeof (addr.sun_path)); 2550 (void) strlcpy(addr.sun_path, INETD_UDS_PATH, sizeof (addr.sun_path)); 2551 2552 if (bind(uds_fd, (struct sockaddr *)(&addr), sizeof (addr)) < 0) { 2553 error_msg(gettext("Failed to bind socket to %s: %s"), 2554 INETD_UDS_PATH, strerror(errno)); 2555 (void) close(uds_fd); 2556 return (-1); 2557 } 2558 2559 (void) listen(uds_fd, UDS_BACKLOG); 2560 2561 if ((set_pollfd(uds_fd, POLLIN)) == -1) { 2562 (void) close(uds_fd); 2563 (void) unlink(INETD_UDS_PATH); 2564 return (-1); 2565 } 2566 2567 return (0); 2568 } 2569 2570 static void 2571 uds_fini(void) 2572 { 2573 if (uds_fd != -1) 2574 (void) close(uds_fd); 2575 (void) unlink(INETD_UDS_PATH); 2576 } 2577 2578 /* 2579 * Handle an incoming request on the Unix Domain Socket. Returns -1 if there 2580 * was an error handling the event, else 0. 2581 */ 2582 static int 2583 process_uds_event(void) 2584 { 2585 uds_request_t req; 2586 int fd; 2587 struct sockaddr_un addr; 2588 socklen_t len = sizeof (addr); 2589 int ret; 2590 uint_t retries = 0; 2591 ucred_t *ucred = NULL; 2592 uid_t euid; 2593 2594 do { 2595 fd = accept(uds_fd, (struct sockaddr *)&addr, &len); 2596 } while ((fd < 0) && (errno == EINTR)); 2597 if (fd < 0) { 2598 if (errno != EWOULDBLOCK) 2599 error_msg("accept failed: %s", strerror(errno)); 2600 return (-1); 2601 } 2602 2603 if (getpeerucred(fd, &ucred) == -1) { 2604 error_msg("getpeerucred failed: %s", strerror(errno)); 2605 (void) close(fd); 2606 return (-1); 2607 } 2608 2609 /* Check peer credentials before acting on the request */ 2610 euid = ucred_geteuid(ucred); 2611 ucred_free(ucred); 2612 if (euid != 0 && getuid() != euid) { 2613 debug_msg("peer euid %u != uid %u", 2614 (uint_t)euid, (uint_t)getuid()); 2615 (void) close(fd); 2616 return (-1); 2617 } 2618 2619 for (retries = 0; retries < UDS_RECV_RETRIES; retries++) { 2620 if (((ret = safe_read(fd, &req, sizeof (req))) != 1) || 2621 (errno != EAGAIN)) 2622 break; 2623 2624 (void) poll(NULL, 0, 100); /* 100ms pause */ 2625 } 2626 2627 if (ret != 0) { 2628 error_msg(gettext("Failed read: %s"), strerror(errno)); 2629 (void) close(fd); 2630 return (-1); 2631 } 2632 2633 switch (req) { 2634 case UR_REFRESH_INETD: 2635 /* flag the request for event_loop() to process */ 2636 refresh_inetd_requested = B_TRUE; 2637 (void) close(fd); 2638 break; 2639 case UR_STOP_INETD: 2640 inetd_stop(); 2641 break; 2642 default: 2643 error_msg("unexpected UDS request"); 2644 (void) close(fd); 2645 return (-1); 2646 } 2647 2648 return (0); 2649 } 2650 2651 /* 2652 * Perform checks for common exec string errors. We limit the checks to 2653 * whether the file exists, is a regular file, and has at least one execute 2654 * bit set. We leave the core security checks to exec() so as not to duplicate 2655 * and thus incur the associated drawbacks, but hope to catch the common 2656 * errors here. 2657 */ 2658 static boolean_t 2659 passes_basic_exec_checks(const char *instance, const char *method, 2660 const char *path) 2661 { 2662 struct stat sbuf; 2663 2664 /* check the file exists */ 2665 while (stat(path, &sbuf) == -1) { 2666 if (errno != EINTR) { 2667 error_msg(gettext( 2668 "Can't stat the %s method of instance %s: %s"), 2669 method, instance, strerror(errno)); 2670 return (B_FALSE); 2671 } 2672 } 2673 2674 /* 2675 * Check if the file is a regular file and has at least one execute 2676 * bit set. 2677 */ 2678 if ((sbuf.st_mode & S_IFMT) != S_IFREG) { 2679 error_msg(gettext( 2680 "The %s method of instance %s isn't a regular file"), 2681 method, instance); 2682 return (B_FALSE); 2683 } else if ((sbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) { 2684 error_msg(gettext("The %s method instance %s doesn't have " 2685 "any execute permissions set"), method, instance); 2686 return (B_FALSE); 2687 } 2688 2689 return (B_TRUE); 2690 } 2691 2692 static void 2693 exec_method(instance_t *instance, instance_method_t method, method_info_t *mi, 2694 struct method_context *mthd_ctxt, const proto_info_t *pi) 2695 { 2696 char **args; 2697 char **env; 2698 const char *errf; 2699 int serrno; 2700 sigset_t mtset; 2701 basic_cfg_t *cfg = instance->config->basic; 2702 2703 if (method == IM_START) { 2704 /* 2705 * If wrappers checks fail, pretend the method was exec'd and 2706 * failed. 2707 */ 2708 if (!tcp_wrappers_ok(instance)) 2709 exit(IMRET_FAILURE); 2710 } 2711 2712 /* 2713 * Revert the disposition of handled signals and ignored signals to 2714 * their defaults, unblocking any blocked ones as a side effect. 2715 */ 2716 (void) sigset(SIGHUP, SIG_DFL); 2717 (void) sigset(SIGTERM, SIG_DFL); 2718 (void) sigset(SIGINT, SIG_DFL); 2719 2720 /* 2721 * Ensure that other signals are unblocked 2722 */ 2723 (void) sigemptyset(&mtset); 2724 (void) sigprocmask(SIG_SETMASK, &mtset, (sigset_t *)NULL); 2725 2726 /* 2727 * Setup exec arguments. Do this before the fd setup below, so our 2728 * logging related file fd doesn't get taken over before we call 2729 * expand_address(). 2730 */ 2731 if ((method == IM_START) && 2732 (strcmp(mi->exec_args_we.we_wordv[0], "%A") == 0)) { 2733 args = expand_address(instance, pi); 2734 } else { 2735 args = mi->exec_args_we.we_wordv; 2736 } 2737 2738 /* Generate audit trail for start operations */ 2739 if (method == IM_START) { 2740 adt_event_data_t *ae; 2741 struct sockaddr_storage ss; 2742 priv_set_t *privset; 2743 socklen_t sslen = sizeof (ss); 2744 2745 if ((ae = adt_alloc_event(audit_handle, ADT_inetd_connect)) 2746 == NULL) { 2747 error_msg(gettext("Unable to allocate audit event for " 2748 "the %s method of instance %s"), 2749 methods[method].name, instance->fmri); 2750 exit(IMRET_FAILURE); 2751 } 2752 2753 /* 2754 * The inetd_connect audit record consists of: 2755 * Service name 2756 * Execution path 2757 * Remote address and port 2758 * Local port 2759 * Process privileges 2760 */ 2761 ae->adt_inetd_connect.service_name = cfg->svc_name; 2762 ae->adt_inetd_connect.cmd = mi->exec_path; 2763 2764 if (instance->remote_addr.ss_family == AF_INET) { 2765 struct in_addr *in = SS_SINADDR(instance->remote_addr); 2766 ae->adt_inetd_connect.ip_adr[0] = in->s_addr; 2767 ae->adt_inetd_connect.ip_type = ADT_IPv4; 2768 } else { 2769 uint32_t *addr6; 2770 int i; 2771 2772 ae->adt_inetd_connect.ip_type = ADT_IPv6; 2773 addr6 = (uint32_t *)SS_SINADDR(instance->remote_addr); 2774 for (i = 0; i < 4; ++i) 2775 ae->adt_inetd_connect.ip_adr[i] = addr6[i]; 2776 } 2777 2778 ae->adt_inetd_connect.ip_remote_port = 2779 ntohs(SS_PORT(instance->remote_addr)); 2780 2781 if (getsockname(instance->conn_fd, (struct sockaddr *)&ss, 2782 &sslen) == 0) 2783 ae->adt_inetd_connect.ip_local_port = 2784 ntohs(SS_PORT(ss)); 2785 2786 privset = mthd_ctxt->priv_set; 2787 if (privset == NULL) { 2788 privset = priv_allocset(); 2789 if (privset != NULL && 2790 getppriv(PRIV_EFFECTIVE, privset) != 0) { 2791 priv_freeset(privset); 2792 privset = NULL; 2793 } 2794 } 2795 2796 ae->adt_inetd_connect.privileges = privset; 2797 2798 (void) adt_put_event(ae, ADT_SUCCESS, ADT_SUCCESS); 2799 adt_free_event(ae); 2800 2801 if (privset != NULL && mthd_ctxt->priv_set == NULL) 2802 priv_freeset(privset); 2803 } 2804 2805 /* 2806 * Set method context before the fd setup below so we can output an 2807 * error message if it fails. 2808 */ 2809 if ((errno = restarter_set_method_context(mthd_ctxt, &errf)) != 0) { 2810 const char *msg; 2811 2812 if (errno == -1) { 2813 if (strcmp(errf, "core_set_process_path") == 0) { 2814 msg = gettext("Failed to set the corefile path " 2815 "for the %s method of instance %s"); 2816 } else if (strcmp(errf, "setproject") == 0) { 2817 msg = gettext("Failed to assign a resource " 2818 "control for the %s method of instance %s"); 2819 } else if (strcmp(errf, "pool_set_binding") == 0) { 2820 msg = gettext("Failed to bind the %s method of " 2821 "instance %s to a pool due to a system " 2822 "error"); 2823 } else { 2824 assert(0); 2825 abort(); 2826 } 2827 2828 error_msg(msg, methods[method].name, instance->fmri); 2829 2830 exit(IMRET_FAILURE); 2831 } 2832 2833 if (errf != NULL && strcmp(errf, "pool_set_binding") == 0) { 2834 switch (errno) { 2835 case ENOENT: 2836 msg = gettext("Failed to find resource pool " 2837 "for the %s method of instance %s"); 2838 break; 2839 2840 case EBADF: 2841 msg = gettext("Failed to bind the %s method of " 2842 "instance %s to a pool due to invalid " 2843 "configuration"); 2844 break; 2845 2846 case EINVAL: 2847 msg = gettext("Failed to bind the %s method of " 2848 "instance %s to a pool due to invalid " 2849 "pool name"); 2850 break; 2851 2852 default: 2853 assert(0); 2854 abort(); 2855 } 2856 2857 exit(IMRET_FAILURE); 2858 } 2859 2860 if (errf != NULL) { 2861 error_msg(gettext("Failed to set credentials for the " 2862 "%s method of instance %s (%s: %s)"), 2863 methods[method].name, instance->fmri, errf, 2864 strerror(errno)); 2865 exit(IMRET_FAILURE); 2866 } 2867 2868 switch (errno) { 2869 case ENOMEM: 2870 msg = gettext("Failed to set credentials for the %s " 2871 "method of instance %s (out of memory)"); 2872 break; 2873 2874 case ENOENT: 2875 msg = gettext("Failed to set credentials for the %s " 2876 "method of instance %s (no passwd or shadow " 2877 "entry for user)"); 2878 break; 2879 2880 default: 2881 assert(0); 2882 abort(); 2883 } 2884 2885 error_msg(msg, methods[method].name, instance->fmri); 2886 exit(IMRET_FAILURE); 2887 } 2888 2889 /* let exec() free mthd_ctxt */ 2890 2891 /* setup standard fds */ 2892 if (method == IM_START) { 2893 (void) dup2(instance->conn_fd, STDIN_FILENO); 2894 } else { 2895 (void) close(STDIN_FILENO); 2896 (void) open("/dev/null", O_RDONLY); 2897 } 2898 (void) dup2(STDIN_FILENO, STDOUT_FILENO); 2899 (void) dup2(STDIN_FILENO, STDERR_FILENO); 2900 2901 closefrom(STDERR_FILENO + 1); 2902 2903 method_preexec(); 2904 2905 env = set_smf_env(mthd_ctxt, instance, methods[method].name); 2906 2907 if (env != NULL) { 2908 do { 2909 (void) execve(mi->exec_path, args, env); 2910 } while (errno == EINTR); 2911 } 2912 2913 serrno = errno; 2914 /* start up logging again to report the error */ 2915 msg_init(); 2916 errno = serrno; 2917 2918 error_msg( 2919 gettext("Failed to exec %s method of instance %s: %s"), 2920 methods[method].name, instance->fmri, strerror(errno)); 2921 2922 if ((method == IM_START) && (instance->config->basic->iswait)) { 2923 /* 2924 * We couldn't exec the start method for a wait type service. 2925 * Eat up data from the endpoint, so that hopefully the 2926 * service's fd won't wake poll up on the next time round 2927 * event_loop(). This behavior is carried over from the old 2928 * inetd, and it seems somewhat arbitrary that it isn't 2929 * also done in the case of fork failures; but I guess 2930 * it assumes an exec failure is less likely to be the result 2931 * of a resource shortage, and is thus not worth retrying. 2932 */ 2933 consume_wait_data(instance, 0); 2934 } 2935 2936 exit(IMRET_FAILURE); 2937 } 2938 2939 static restarter_error_t 2940 get_method_error_success(instance_method_t method) 2941 { 2942 switch (method) { 2943 case IM_OFFLINE: 2944 return (RERR_RESTART); 2945 case IM_ONLINE: 2946 return (RERR_RESTART); 2947 case IM_DISABLE: 2948 return (RERR_RESTART); 2949 case IM_REFRESH: 2950 return (RERR_REFRESH); 2951 case IM_START: 2952 return (RERR_RESTART); 2953 } 2954 (void) fprintf(stderr, gettext("Internal fatal error in inetd.\n")); 2955 2956 abort(); 2957 /* NOTREACHED */ 2958 } 2959 2960 static int 2961 smf_kill_process(instance_t *instance, int sig) 2962 { 2963 rep_val_t *rv; 2964 int ret = IMRET_SUCCESS; 2965 2966 /* Carry out process assassination */ 2967 for (rv = uu_list_first(instance->start_pids); 2968 rv != NULL; 2969 rv = uu_list_next(instance->start_pids, rv)) { 2970 if ((kill((pid_t)rv->val, sig) != 0) && 2971 (errno != ESRCH)) { 2972 ret = IMRET_FAILURE; 2973 error_msg(gettext("Unable to kill " 2974 "start process (%ld) of instance %s: %s"), 2975 rv->val, instance->fmri, strerror(errno)); 2976 } 2977 } 2978 return (ret); 2979 } 2980 2981 /* 2982 * Runs the specified method of the specified service instance. 2983 * If the method was never specified, we handle it the same as if the 2984 * method was called and returned success, carrying on any transition the 2985 * instance may be in the midst of. 2986 * If the method isn't executable in its specified profile or an error occurs 2987 * forking a process to run the method in the function returns -1. 2988 * If a method binary is successfully executed, the function switches the 2989 * instance's cur state to the method's associated 'run' state and the next 2990 * state to the methods associated next state. 2991 * Returns -1 if there's an error before forking, else 0. 2992 */ 2993 int 2994 run_method(instance_t *instance, instance_method_t method, 2995 const proto_info_t *start_info) 2996 { 2997 pid_t child_pid; 2998 method_info_t *mi; 2999 struct method_context *mthd_ctxt = NULL; 3000 int sig = 0; 3001 int ret; 3002 instance_cfg_t *cfg = instance->config; 3003 ctid_t cid; 3004 boolean_t trans_failure = B_TRUE; 3005 int serrno; 3006 3007 /* 3008 * Don't bother updating the instance's state for the start method 3009 * as there isn't a separate start method state. 3010 */ 3011 if (method != IM_START) 3012 update_instance_states(instance, get_method_state(method), 3013 methods[method].dst_state, 3014 get_method_error_success(method)); 3015 3016 if ((mi = cfg->methods[method]) == NULL) { 3017 /* 3018 * If the absent method is IM_OFFLINE, default action needs 3019 * to be taken to avoid lingering processes which can prevent 3020 * the upcoming rebinding from happening. 3021 */ 3022 if ((method == IM_OFFLINE) && instance->config->basic->iswait) { 3023 warn_msg(gettext("inetd_offline method for instance %s " 3024 "is unspecified. Taking default action: kill."), 3025 instance->fmri); 3026 (void) str2sig("TERM", &sig); 3027 ret = smf_kill_process(instance, sig); 3028 process_non_start_term(instance, ret); 3029 return (0); 3030 } else { 3031 process_non_start_term(instance, IMRET_SUCCESS); 3032 return (0); 3033 } 3034 } 3035 3036 /* Handle special method tokens, not allowed on start */ 3037 if (method != IM_START) { 3038 if (restarter_is_null_method(mi->exec_path)) { 3039 /* :true means nothing should be done */ 3040 process_non_start_term(instance, IMRET_SUCCESS); 3041 return (0); 3042 } 3043 3044 if ((sig = restarter_is_kill_method(mi->exec_path)) >= 0) { 3045 /* Carry out contract assassination */ 3046 ret = iterate_repository_contracts(instance, sig); 3047 /* ENOENT means we didn't find any contracts */ 3048 if (ret != 0 && ret != ENOENT) { 3049 error_msg(gettext("Failed to send signal %d " 3050 "to contracts of instance %s: %s"), sig, 3051 instance->fmri, strerror(ret)); 3052 goto prefork_failure; 3053 } else { 3054 process_non_start_term(instance, IMRET_SUCCESS); 3055 return (0); 3056 } 3057 } 3058 3059 if ((sig = restarter_is_kill_proc_method(mi->exec_path)) >= 0) { 3060 ret = smf_kill_process(instance, sig); 3061 process_non_start_term(instance, ret); 3062 return (0); 3063 } 3064 } 3065 3066 /* 3067 * Get the associated method context before the fork so we can 3068 * modify the instances state if things go wrong. 3069 */ 3070 if ((mthd_ctxt = read_method_context(instance->fmri, 3071 methods[method].name, mi->exec_path)) == NULL) 3072 goto prefork_failure; 3073 3074 /* 3075 * Perform some basic checks before we fork to limit the possibility 3076 * of exec failures, so we can modify the instance state if necessary. 3077 */ 3078 if (!passes_basic_exec_checks(instance->fmri, methods[method].name, 3079 mi->exec_path)) { 3080 trans_failure = B_FALSE; 3081 goto prefork_failure; 3082 } 3083 3084 if (contract_prefork(instance->fmri, method) == -1) 3085 goto prefork_failure; 3086 child_pid = fork(); 3087 serrno = errno; 3088 contract_postfork(); 3089 3090 switch (child_pid) { 3091 case -1: 3092 error_msg(gettext( 3093 "Unable to fork %s method of instance %s: %s"), 3094 methods[method].name, instance->fmri, strerror(serrno)); 3095 if ((serrno != EAGAIN) && (serrno != ENOMEM)) 3096 trans_failure = B_FALSE; 3097 goto prefork_failure; 3098 case 0: /* child */ 3099 exec_method(instance, method, mi, mthd_ctxt, start_info); 3100 /* NOTREACHED */ 3101 default: /* parent */ 3102 restarter_free_method_context(mthd_ctxt); 3103 mthd_ctxt = NULL; 3104 3105 if (get_latest_contract(&cid) < 0) 3106 cid = -1; 3107 3108 /* 3109 * Register this method so its termination is noticed and 3110 * the state transition this method participates in is 3111 * continued. 3112 */ 3113 if (register_method(instance, child_pid, cid, method, 3114 start_info->proto) != 0) { 3115 /* 3116 * Since we will never find out about the termination 3117 * of this method, if it's a non-start method treat 3118 * is as a failure so we don't block restarter event 3119 * processing on it whilst it languishes in a method 3120 * running state. 3121 */ 3122 error_msg(gettext("Failed to monitor status of " 3123 "%s method of instance %s"), methods[method].name, 3124 instance->fmri); 3125 if (method != IM_START) 3126 process_non_start_term(instance, IMRET_FAILURE); 3127 } 3128 3129 add_method_ids(instance, child_pid, cid, method); 3130 3131 /* do tcp tracing for those nowait instances that request it */ 3132 if ((method == IM_START) && cfg->basic->do_tcp_trace && 3133 !cfg->basic->iswait) { 3134 char buf[INET6_ADDRSTRLEN]; 3135 3136 syslog(LOG_NOTICE, "%s[%d] from %s %d", 3137 cfg->basic->svc_name, child_pid, 3138 inet_ntop_native(instance->remote_addr.ss_family, 3139 SS_SINADDR(instance->remote_addr), buf, 3140 sizeof (buf)), 3141 ntohs(SS_PORT(instance->remote_addr))); 3142 } 3143 } 3144 3145 return (0); 3146 3147 prefork_failure: 3148 if (mthd_ctxt != NULL) { 3149 restarter_free_method_context(mthd_ctxt); 3150 mthd_ctxt = NULL; 3151 } 3152 3153 if (method == IM_START) { 3154 /* 3155 * Only place a start method in maintenance if we're sure 3156 * that the failure was non-transient. 3157 */ 3158 if (!trans_failure) { 3159 destroy_bound_fds(instance); 3160 update_state(instance, IIS_MAINTENANCE, RERR_FAULT); 3161 } 3162 } else { 3163 /* treat the failure as if the method ran and failed */ 3164 process_non_start_term(instance, IMRET_FAILURE); 3165 } 3166 3167 return (-1); 3168 } 3169 3170 static int 3171 pending_connections(instance_t *instance, proto_info_t *pi) 3172 { 3173 if (instance->config->basic->istlx) { 3174 tlx_info_t *tl = (tlx_info_t *)pi; 3175 3176 return (uu_list_numnodes(tl->conn_ind_queue) != 0); 3177 } else { 3178 return (0); 3179 } 3180 } 3181 3182 static int 3183 accept_connection(instance_t *instance, proto_info_t *pi) 3184 { 3185 int fd; 3186 socklen_t size; 3187 3188 if (instance->config->basic->istlx) { 3189 tlx_info_t *tl = (tlx_info_t *)pi; 3190 tlx_pending_counter = \ 3191 tlx_pending_counter - uu_list_numnodes(tl->conn_ind_queue); 3192 3193 fd = tlx_accept(instance->fmri, (tlx_info_t *)pi, 3194 &(instance->remote_addr)); 3195 3196 tlx_pending_counter = \ 3197 tlx_pending_counter + uu_list_numnodes(tl->conn_ind_queue); 3198 } else { 3199 size = sizeof (instance->remote_addr); 3200 fd = accept(pi->listen_fd, 3201 (struct sockaddr *)&(instance->remote_addr), &size); 3202 if (fd < 0) 3203 error_msg("accept: %s", strerror(errno)); 3204 } 3205 3206 return (fd); 3207 } 3208 3209 /* 3210 * Handle an incoming connection request for a nowait service. 3211 * This involves accepting the incoming connection on a new fd. Connection 3212 * rate checks are then performed, transitioning the service to the 3213 * conrate offline state if these fail. Otherwise, the service's start method 3214 * is run (performing TCP wrappers checks if applicable as we do), and on 3215 * success concurrent copies checking is done, transitioning the service to the 3216 * copies offline state if this fails. 3217 */ 3218 static void 3219 process_nowait_request(instance_t *instance, proto_info_t *pi) 3220 { 3221 basic_cfg_t *cfg = instance->config->basic; 3222 int ret; 3223 adt_event_data_t *ae; 3224 char buf[BUFSIZ]; 3225 3226 /* accept nowait service connections on a new fd */ 3227 if ((instance->conn_fd = accept_connection(instance, pi)) == -1) { 3228 /* 3229 * Failed accept. Return and allow the event loop to initiate 3230 * another attempt later if the request is still present. 3231 */ 3232 return; 3233 } 3234 3235 /* 3236 * Limit connection rate of nowait services. If either conn_rate_max 3237 * or conn_rate_offline are <= 0, no connection rate limit checking 3238 * is done. If the configured rate is exceeded, the instance is taken 3239 * to the connrate_offline state and a timer scheduled to try and 3240 * bring the instance back online after the configured offline time. 3241 */ 3242 if ((cfg->conn_rate_max > 0) && (cfg->conn_rate_offline > 0)) { 3243 if (instance->conn_rate_count++ == 0) { 3244 instance->conn_rate_start = time(NULL); 3245 } else if (instance->conn_rate_count > 3246 cfg->conn_rate_max) { 3247 time_t now = time(NULL); 3248 3249 if ((now - instance->conn_rate_start) > 1) { 3250 instance->conn_rate_start = now; 3251 instance->conn_rate_count = 1; 3252 } else { 3253 /* Generate audit record */ 3254 if ((ae = adt_alloc_event(audit_handle, 3255 ADT_inetd_ratelimit)) == NULL) { 3256 error_msg(gettext("Unable to allocate " 3257 "rate limit audit event")); 3258 } else { 3259 adt_inetd_ratelimit_t *rl = 3260 &ae->adt_inetd_ratelimit; 3261 /* 3262 * The inetd_ratelimit audit 3263 * record consists of: 3264 * Service name 3265 * Connection rate limit 3266 */ 3267 rl->service_name = cfg->svc_name; 3268 (void) snprintf(buf, sizeof (buf), 3269 "limit=%lld", cfg->conn_rate_max); 3270 rl->limit = buf; 3271 (void) adt_put_event(ae, ADT_SUCCESS, 3272 ADT_SUCCESS); 3273 adt_free_event(ae); 3274 } 3275 3276 error_msg(gettext( 3277 "Instance %s has exceeded its configured " 3278 "connection rate, additional connections " 3279 "will not be accepted for %d seconds"), 3280 instance->fmri, cfg->conn_rate_offline); 3281 3282 close_net_fd(instance, instance->conn_fd); 3283 instance->conn_fd = -1; 3284 3285 destroy_bound_fds(instance); 3286 3287 instance->conn_rate_count = 0; 3288 3289 instance->conn_rate_exceeded = B_TRUE; 3290 (void) run_method(instance, IM_OFFLINE, NULL); 3291 3292 return; 3293 } 3294 } 3295 } 3296 3297 ret = run_method(instance, IM_START, pi); 3298 3299 close_net_fd(instance, instance->conn_fd); 3300 instance->conn_fd = -1; 3301 3302 if (ret == -1) /* the method wasn't forked */ 3303 return; 3304 3305 instance->copies++; 3306 3307 /* 3308 * Limit concurrent connections of nowait services. 3309 */ 3310 if (copies_limit_exceeded(instance)) { 3311 /* Generate audit record */ 3312 if ((ae = adt_alloc_event(audit_handle, ADT_inetd_copylimit)) 3313 == NULL) { 3314 error_msg(gettext("Unable to allocate copy limit " 3315 "audit event")); 3316 } else { 3317 /* 3318 * The inetd_copylimit audit record consists of: 3319 * Service name 3320 * Copy limit 3321 */ 3322 ae->adt_inetd_copylimit.service_name = cfg->svc_name; 3323 (void) snprintf(buf, sizeof (buf), "limit=%lld", 3324 cfg->max_copies); 3325 ae->adt_inetd_copylimit.limit = buf; 3326 (void) adt_put_event(ae, ADT_SUCCESS, ADT_SUCCESS); 3327 adt_free_event(ae); 3328 } 3329 3330 warn_msg(gettext("Instance %s has reached its maximum " 3331 "configured copies, no new connections will be accepted"), 3332 instance->fmri); 3333 destroy_bound_fds(instance); 3334 (void) run_method(instance, IM_OFFLINE, NULL); 3335 } 3336 } 3337 3338 /* 3339 * Handle an incoming request for a wait type service. 3340 * Failure rate checking is done first, taking the service to the maintenance 3341 * state if the checks fail. Following this, the service's start method is run, 3342 * and on success, we stop listening for new requests for this service. 3343 */ 3344 static void 3345 process_wait_request(instance_t *instance, const proto_info_t *pi) 3346 { 3347 basic_cfg_t *cfg = instance->config->basic; 3348 int ret; 3349 adt_event_data_t *ae; 3350 char buf[BUFSIZ]; 3351 3352 instance->conn_fd = pi->listen_fd; 3353 3354 /* 3355 * Detect broken servers and transition them to maintenance. If a 3356 * wait type service exits without accepting the connection or 3357 * consuming (reading) the datagram, that service's descriptor will 3358 * select readable again, and inetd will fork another instance of 3359 * the server. If either wait_fail_cnt or wait_fail_interval are <= 0, 3360 * no failure rate detection is done. 3361 */ 3362 if ((cfg->wait_fail_cnt > 0) && (cfg->wait_fail_interval > 0)) { 3363 if (instance->fail_rate_count++ == 0) { 3364 instance->fail_rate_start = time(NULL); 3365 } else if (instance->fail_rate_count > cfg->wait_fail_cnt) { 3366 time_t now = time(NULL); 3367 3368 if ((now - instance->fail_rate_start) > 3369 cfg->wait_fail_interval) { 3370 instance->fail_rate_start = now; 3371 instance->fail_rate_count = 1; 3372 } else { 3373 /* Generate audit record */ 3374 if ((ae = adt_alloc_event(audit_handle, 3375 ADT_inetd_failrate)) == NULL) { 3376 error_msg(gettext("Unable to allocate " 3377 "failure rate audit event")); 3378 } else { 3379 adt_inetd_failrate_t *fr = 3380 &ae->adt_inetd_failrate; 3381 /* 3382 * The inetd_failrate audit record 3383 * consists of: 3384 * Service name 3385 * Failure rate 3386 * Interval 3387 * Last two are expressed as k=v pairs 3388 * in the values field. 3389 */ 3390 fr->service_name = cfg->svc_name; 3391 (void) snprintf(buf, sizeof (buf), 3392 "limit=%lld,interval=%d", 3393 cfg->wait_fail_cnt, 3394 cfg->wait_fail_interval); 3395 fr->values = buf; 3396 (void) adt_put_event(ae, ADT_SUCCESS, 3397 ADT_SUCCESS); 3398 adt_free_event(ae); 3399 } 3400 3401 error_msg(gettext( 3402 "Instance %s has exceeded its configured " 3403 "failure rate, transitioning to " 3404 "maintenance"), instance->fmri); 3405 instance->fail_rate_count = 0; 3406 3407 destroy_bound_fds(instance); 3408 3409 instance->maintenance_req = B_TRUE; 3410 (void) run_method(instance, IM_OFFLINE, NULL); 3411 return; 3412 } 3413 } 3414 } 3415 3416 ret = run_method(instance, IM_START, pi); 3417 3418 instance->conn_fd = -1; 3419 3420 if (ret == 0) { 3421 /* 3422 * Stop listening for connections now we've fired off the 3423 * server for a wait type instance. 3424 */ 3425 (void) poll_bound_fds(instance, B_FALSE, pi->proto); 3426 } 3427 } 3428 3429 /* 3430 * Process any networks requests for each proto for each instance. 3431 */ 3432 void 3433 process_network_events(void) 3434 { 3435 instance_t *instance; 3436 3437 for (instance = uu_list_first(instance_list); instance != NULL; 3438 instance = uu_list_next(instance_list, instance)) { 3439 basic_cfg_t *cfg; 3440 proto_info_t *pi; 3441 3442 /* 3443 * Ignore instances in states that definitely don't have any 3444 * listening fds. 3445 */ 3446 switch (instance->cur_istate) { 3447 case IIS_ONLINE: 3448 case IIS_DEGRADED: 3449 case IIS_IN_REFRESH_METHOD: 3450 break; 3451 default: 3452 continue; 3453 } 3454 3455 cfg = instance->config->basic; 3456 3457 for (pi = uu_list_first(cfg->proto_list); pi != NULL; 3458 pi = uu_list_next(cfg->proto_list, pi)) { 3459 if (((pi->listen_fd != -1) && 3460 isset_pollfd(pi->listen_fd)) || 3461 pending_connections(instance, pi)) { 3462 if (cfg->iswait) { 3463 process_wait_request(instance, pi); 3464 } else { 3465 process_nowait_request(instance, pi); 3466 } 3467 } 3468 } 3469 } 3470 } 3471 3472 /* ARGSUSED0 */ 3473 static void 3474 sigterm_handler(int sig) 3475 { 3476 got_sigterm = B_TRUE; 3477 } 3478 3479 /* ARGSUSED0 */ 3480 static void 3481 sighup_handler(int sig) 3482 { 3483 refresh_inetd_requested = B_TRUE; 3484 } 3485 3486 /* 3487 * inetd's major work loop. This function sits in poll waiting for events 3488 * to occur, processing them when they do. The possible events are 3489 * master restarter requests, expired timer queue timers, stop/refresh signal 3490 * requests, contract events indicating process termination, stop/refresh 3491 * requests originating from one of the stop/refresh inetd processes and 3492 * network events. 3493 * The loop is exited when a stop request is received and processed, and 3494 * all the instances have reached a suitable 'stopping' state. 3495 */ 3496 static void 3497 event_loop(void) 3498 { 3499 instance_t *instance; 3500 int timeout; 3501 3502 for (;;) { 3503 int pret = -1; 3504 3505 if (tlx_pending_counter != 0) 3506 timeout = 0; 3507 else 3508 timeout = iu_earliest_timer(timer_queue); 3509 3510 if (!got_sigterm && !refresh_inetd_requested) { 3511 pret = poll(poll_fds, num_pollfds, timeout); 3512 if ((pret == -1) && (errno != EINTR)) { 3513 error_msg(gettext("poll failure: %s"), 3514 strerror(errno)); 3515 continue; 3516 } 3517 } 3518 3519 if (got_sigterm) { 3520 msg_fini(); 3521 inetd_stop(); 3522 got_sigterm = B_FALSE; 3523 goto check_if_stopped; 3524 } 3525 3526 /* 3527 * Process any stop/refresh requests from the Unix Domain 3528 * Socket. 3529 */ 3530 if ((pret != -1) && isset_pollfd(uds_fd)) { 3531 while (process_uds_event() == 0) 3532 ; 3533 } 3534 3535 /* 3536 * Process refresh request. We do this check after the UDS 3537 * event check above, as it would be wasted processing if we 3538 * started refreshing inetd based on a SIGHUP, and then were 3539 * told to shut-down via a UDS event. 3540 */ 3541 if (refresh_inetd_requested) { 3542 refresh_inetd_requested = B_FALSE; 3543 if (!inetd_stopping) 3544 inetd_refresh(); 3545 } 3546 3547 /* 3548 * We were interrupted by a signal. Don't waste any more 3549 * time processing a potentially inaccurate poll return. 3550 */ 3551 if (pret == -1) 3552 continue; 3553 3554 /* 3555 * Process any instance restarter events. 3556 */ 3557 if (isset_pollfd(rst_event_pipe[PE_CONSUMER])) { 3558 while (process_restarter_event() == 0) 3559 ; 3560 } 3561 3562 /* 3563 * Process any expired timers (bind retry, con-rate offline, 3564 * method timeouts). 3565 */ 3566 (void) iu_expire_timers(timer_queue); 3567 3568 process_terminated_methods(); 3569 3570 /* 3571 * If inetd is stopping, check whether all our managed 3572 * instances have been stopped and we can return. 3573 */ 3574 if (inetd_stopping) { 3575 check_if_stopped: 3576 for (instance = uu_list_first(instance_list); 3577 instance != NULL; 3578 instance = uu_list_next(instance_list, instance)) { 3579 if (!instance_stopped(instance)) { 3580 debug_msg("%s not yet stopped", 3581 instance->fmri); 3582 break; 3583 } 3584 } 3585 /* if all instances are stopped, return */ 3586 if (instance == NULL) 3587 return; 3588 } 3589 3590 process_network_events(); 3591 } 3592 } 3593 3594 static void 3595 fini(void) 3596 { 3597 method_fini(); 3598 uds_fini(); 3599 if (timer_queue != NULL) 3600 iu_tq_destroy(timer_queue); 3601 3602 3603 /* 3604 * We don't bother to undo the restarter interface at all. 3605 * Because of quirks in the interface, there is no way to 3606 * disconnect from the channel and cause any new events to be 3607 * queued. However, any events which are received and not 3608 * acknowledged will be re-sent when inetd restarts as long as inetd 3609 * uses the same subscriber ID, which it does. 3610 * 3611 * By keeping the event pipe open but ignoring it, any events which 3612 * occur will cause restarter_event_proxy to hang without breaking 3613 * anything. 3614 */ 3615 3616 if (instance_list != NULL) { 3617 void *cookie = NULL; 3618 instance_t *inst; 3619 3620 while ((inst = uu_list_teardown(instance_list, &cookie)) != 3621 NULL) 3622 destroy_instance(inst); 3623 uu_list_destroy(instance_list); 3624 } 3625 if (instance_pool != NULL) 3626 uu_list_pool_destroy(instance_pool); 3627 tlx_fini(); 3628 config_fini(); 3629 repval_fini(); 3630 poll_fini(); 3631 3632 /* Close audit session */ 3633 (void) adt_end_session(audit_handle); 3634 } 3635 3636 static int 3637 init(void) 3638 { 3639 int err; 3640 3641 if (repval_init() < 0) 3642 goto failed; 3643 3644 if (config_init() < 0) 3645 goto failed; 3646 3647 refresh_debug_flag(); 3648 3649 if (tlx_init() < 0) 3650 goto failed; 3651 3652 /* Setup instance list. */ 3653 if ((instance_pool = uu_list_pool_create("instance_pool", 3654 sizeof (instance_t), offsetof(instance_t, link), NULL, 3655 UU_LIST_POOL_DEBUG)) == NULL) { 3656 error_msg("%s: %s", 3657 gettext("Failed to create instance pool"), 3658 uu_strerror(uu_error())); 3659 goto failed; 3660 } 3661 if ((instance_list = uu_list_create(instance_pool, NULL, 0)) == NULL) { 3662 error_msg("%s: %s", 3663 gettext("Failed to create instance list"), 3664 uu_strerror(uu_error())); 3665 goto failed; 3666 } 3667 3668 /* 3669 * Create event pipe to communicate events with the main event 3670 * loop and add it to the event loop's fdset. 3671 */ 3672 if (pipe(rst_event_pipe) < 0) { 3673 error_msg("pipe: %s", strerror(errno)); 3674 goto failed; 3675 } 3676 /* 3677 * We only leave the producer end to block on reads/writes as we 3678 * can't afford to block in the main thread, yet need to in 3679 * the restarter event thread, so it can sit and wait for an 3680 * acknowledgement to be written to the pipe. 3681 */ 3682 disable_blocking(rst_event_pipe[PE_CONSUMER]); 3683 if ((set_pollfd(rst_event_pipe[PE_CONSUMER], POLLIN)) == -1) 3684 goto failed; 3685 3686 /* 3687 * Register with master restarter for managed service events. This 3688 * will fail, amongst other reasons, if inetd is already running. 3689 */ 3690 if ((err = restarter_bind_handle(RESTARTER_EVENT_VERSION, 3691 INETD_INSTANCE_FMRI, restarter_event_proxy, 0, 3692 &rst_event_handle)) != 0) { 3693 error_msg(gettext( 3694 "Failed to register for restarter events: %s"), 3695 strerror(err)); 3696 goto failed; 3697 } 3698 3699 if (contract_init() < 0) 3700 goto failed; 3701 3702 if ((timer_queue = iu_tq_create()) == NULL) { 3703 error_msg(gettext("Failed to create timer queue.")); 3704 goto failed; 3705 } 3706 3707 if (uds_init() < 0) 3708 goto failed; 3709 3710 if (method_init() < 0) 3711 goto failed; 3712 3713 /* Initialize auditing session */ 3714 if (adt_start_session(&audit_handle, NULL, ADT_USE_PROC_DATA) != 0) { 3715 error_msg(gettext("Unable to start audit session")); 3716 } 3717 3718 /* 3719 * Initialize signal dispositions/masks 3720 */ 3721 (void) sigset(SIGHUP, sighup_handler); 3722 (void) sigset(SIGTERM, sigterm_handler); 3723 (void) sigignore(SIGINT); 3724 3725 return (0); 3726 3727 failed: 3728 fini(); 3729 return (-1); 3730 } 3731 3732 static int 3733 start_method(void) 3734 { 3735 int i; 3736 int pipe_fds[2]; 3737 int child; 3738 3739 /* Create pipe for child to notify parent of initialization success. */ 3740 if (pipe(pipe_fds) < 0) { 3741 error_msg("pipe: %s", strerror(errno)); 3742 return (SMF_EXIT_ERR_OTHER); 3743 } 3744 3745 if ((child = fork()) == -1) { 3746 error_msg("fork: %s", strerror(errno)); 3747 (void) close(pipe_fds[PE_CONSUMER]); 3748 (void) close(pipe_fds[PE_PRODUCER]); 3749 return (SMF_EXIT_ERR_OTHER); 3750 } else if (child > 0) { /* parent */ 3751 3752 /* Wait on child to return success of initialization. */ 3753 (void) close(pipe_fds[PE_PRODUCER]); 3754 if ((safe_read(pipe_fds[PE_CONSUMER], &i, sizeof (i)) != 0) || 3755 (i < 0)) { 3756 error_msg(gettext( 3757 "Initialization failed, unable to start")); 3758 (void) close(pipe_fds[PE_CONSUMER]); 3759 /* 3760 * Batch all initialization errors as 'other' errors, 3761 * resulting in retries being attempted. 3762 */ 3763 return (SMF_EXIT_ERR_OTHER); 3764 } else { 3765 (void) close(pipe_fds[PE_CONSUMER]); 3766 return (SMF_EXIT_OK); 3767 } 3768 } else { /* child */ 3769 /* 3770 * Perform initialization and return success code down 3771 * the pipe. 3772 */ 3773 (void) close(pipe_fds[PE_CONSUMER]); 3774 i = init(); 3775 if ((safe_write(pipe_fds[PE_PRODUCER], &i, sizeof (i)) < 0) || 3776 (i < 0)) { 3777 error_msg(gettext("pipe write failure: %s"), 3778 strerror(errno)); 3779 exit(1); 3780 } 3781 (void) close(pipe_fds[PE_PRODUCER]); 3782 3783 (void) setsid(); 3784 3785 /* 3786 * Log a message if the configuration file has changed since 3787 * inetconv was last run. 3788 */ 3789 check_conf_file(); 3790 3791 event_loop(); 3792 3793 fini(); 3794 debug_msg("inetd stopped"); 3795 msg_fini(); 3796 exit(0); 3797 } 3798 /* NOTREACHED */ 3799 } 3800 3801 /* 3802 * When inetd is run from outside the SMF, this message is output to provide 3803 * the person invoking inetd with further information that will help them 3804 * understand how to start and stop inetd, and to achieve the other 3805 * behaviors achievable with the legacy inetd command line interface, if 3806 * it is possible. 3807 */ 3808 static void 3809 legacy_usage(void) 3810 { 3811 (void) fprintf(stderr, 3812 "inetd is now an smf(7) managed service and can no longer be run " 3813 "from the\n" 3814 "command line. To enable or disable inetd refer to svcadm(8) on\n" 3815 "how to enable \"%s\", the inetd instance.\n" 3816 "\n" 3817 "The traditional inetd command line option mappings are:\n" 3818 "\t-d : there is no supported debug output\n" 3819 "\t-s : inetd is only runnable from within the SMF\n" 3820 "\t-t : See inetadm(8) on how to enable TCP tracing\n" 3821 "\t-r : See inetadm(8) on how to set a failure rate\n" 3822 "\n" 3823 "To specify an alternative configuration file see svccfg(8)\n" 3824 "for how to modify the \"%s/%s\" string type property of\n" 3825 "the inetd instance, and modify it according to the syntax:\n" 3826 "\"%s [alt_config_file] %%m\".\n" 3827 "\n" 3828 "For further information on inetd see inetd(8).\n", 3829 INETD_INSTANCE_FMRI, START_METHOD_ARG, SCF_PROPERTY_EXEC, 3830 INETD_PATH); 3831 } 3832 3833 /* 3834 * Usage message printed out for usage errors when running under the SMF. 3835 */ 3836 static void 3837 smf_usage(const char *arg0) 3838 { 3839 error_msg("Usage: %s [alt_conf_file] %s|%s|%s", arg0, START_METHOD_ARG, 3840 STOP_METHOD_ARG, REFRESH_METHOD_ARG); 3841 } 3842 3843 /* 3844 * Returns B_TRUE if we're being run from within the SMF, else B_FALSE. 3845 */ 3846 static boolean_t 3847 run_through_smf(void) 3848 { 3849 char *fmri; 3850 3851 /* 3852 * check if the instance fmri environment variable has been set by 3853 * our restarter. 3854 */ 3855 return (((fmri = getenv("SMF_FMRI")) != NULL) && 3856 (strcmp(fmri, INETD_INSTANCE_FMRI) == 0)); 3857 } 3858 3859 int 3860 main(int argc, char *argv[]) 3861 { 3862 char *method; 3863 int ret; 3864 3865 #if !defined(TEXT_DOMAIN) 3866 #define TEXT_DOMAIN "SYS_TEST" 3867 #endif 3868 (void) textdomain(TEXT_DOMAIN); 3869 (void) setlocale(LC_ALL, ""); 3870 3871 if (!run_through_smf()) { 3872 legacy_usage(); 3873 return (SMF_EXIT_ERR_NOSMF); 3874 } 3875 3876 msg_init(); /* setup logging */ 3877 3878 (void) enable_extended_FILE_stdio(-1, -1); 3879 3880 /* inetd invocation syntax is inetd [alt_conf_file] method_name */ 3881 3882 switch (argc) { 3883 case 2: 3884 method = argv[1]; 3885 break; 3886 case 3: 3887 conf_file = argv[1]; 3888 method = argv[2]; 3889 break; 3890 default: 3891 smf_usage(argv[0]); 3892 return (SMF_EXIT_ERR_CONFIG); 3893 3894 } 3895 3896 if (strcmp(method, START_METHOD_ARG) == 0) { 3897 ret = start_method(); 3898 } else if (strcmp(method, STOP_METHOD_ARG) == 0) { 3899 ret = stop_method(); 3900 } else if (strcmp(method, REFRESH_METHOD_ARG) == 0) { 3901 ret = refresh_method(); 3902 } else { 3903 smf_usage(argv[0]); 3904 return (SMF_EXIT_ERR_CONFIG); 3905 } 3906 3907 return (ret); 3908 } 3909