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