usr/src/cmd/svc/startd/wait.c
author eschrock
Fri, 26 Oct 2007 13:47:19 -0700
changeset 5345 44060de1d838
parent 111 347ecf011416
child 7219 343338355d03
permissions -rw-r--r--
PSARC 2007/606 nvlist extensions 6608068 typo in ipmi_sdr_refresh() can cause segfault on allocation failure 6608069 libipmi should have support for user management 6608070 nvlist_lookup_nvpair() would be useful 6608094 nvlist_exists() would be useful 6608096 zprop_parse_value() should accept boolean values for boolean types 6608098 startd's fsminimal filesystem checks could be a little more explicit
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
111
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * wait.c - asynchronous monitoring of "wait registered" start methods
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * Use event ports to poll on the set of fds representing the /proc/[pid]/psinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 * files.  If one of these fds returns an event, then we inform the restarter
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * that it has stopped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * The wait_info_list holds the series of processes currently being monitored
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 * for exit.  The wi_fd member, which contains the file descriptor of the psinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 * file being polled upon ("event ported upon"), will be set to -1 if the file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 * descriptor is inactive (already closed or not yet opened).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#ifdef _FILE_OFFSET_BITS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#undef _FILE_OFFSET_BITS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#endif /* _FILE_OFFSET_BITS */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/resource.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/stat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/uio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/wait.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <assert.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <fcntl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include <libuutil.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <poll.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include <port.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <pthread.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <procfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <string.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <stropts.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <unistd.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include "startd.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#define	WAIT_FILES	262144		/* reasonably high maximum */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
static int port_fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
static scf_handle_t *wait_hndl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
static struct rlimit init_fd_rlimit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
static uu_list_pool_t *wait_info_pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
static uu_list_t *wait_info_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
static pthread_mutex_t wait_info_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
 * void wait_remove(wait_info_t *, int)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
 *   Remove the given wait_info structure from our list, performing various
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
 *   cleanup operations along the way.  If the direct flag is false (meaning
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 *   that we are being called with from restarter instance list context), then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 *   notify the restarter that the associated instance has exited.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 *   Since we may no longer be the startd that started this process, we only are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
 *   concerned with a waitpid(3C) failure if the wi_parent field is non-zero.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
wait_remove(wait_info_t *wi, int direct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
	int status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
	if (waitpid(wi->wi_pid, &status, 0) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
		if (wi->wi_parent)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
			log_framework(LOG_INFO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
			    "instance %s waitpid failure: %s\n", wi->wi_fmri,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
			    strerror(errno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
		if (WEXITSTATUS(status) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
			log_framework(LOG_NOTICE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
			    "instance %s exited with status %d\n", wi->wi_fmri,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
			    WEXITSTATUS(status));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
	MUTEX_LOCK(&wait_info_lock);
111
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   106
	if (wi->wi_fd != -1) {
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   107
		startd_close(wi->wi_fd);
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   108
		wi->wi_fd = -1;
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   109
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	uu_list_remove(wait_info_list, wi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
	MUTEX_UNLOCK(&wait_info_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
	 * Make an attempt to clear out any utmpx record associated with this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
	 * PID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
	utmpx_mark_dead(wi->wi_pid, status, B_FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
	if (!direct) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
		 * Bind wait_hndl lazily.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
		if (wait_hndl == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
			for (wait_hndl =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
			    libscf_handle_create_bound(SCF_VERSION);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
			    wait_hndl == NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
			    wait_hndl =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
			    libscf_handle_create_bound(SCF_VERSION)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
				log_error(LOG_INFO, "[wait_remove] Unable to "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
				    "bind a new repository handle: %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
				    scf_strerror(scf_error()));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
				(void) sleep(2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
		log_framework(LOG_DEBUG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
		    "wait_remove requesting stop of %s\n", wi->wi_fmri);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
		(void) stop_instance_fmri(wait_hndl, wi->wi_fmri, RSTOP_EXIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
	uu_list_node_fini(wi, &wi->wi_link, wait_info_pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
	startd_free(wi, sizeof (wait_info_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
 * int wait_register(pid_t, char *, int, int)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
 *   wait_register is called after we have called fork(2), and know which pid we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
 *   wish to monitor.  However, since the child may have already exited by the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
 *   time we are called, we must handle the error cases from open(2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
 *   appropriately.  The am_parent flag is recorded to handle waitpid(2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 *   behaviour on removal; similarly, the direct flag is passed through to a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 *   potential call to wait_remove() to govern its behaviour in different
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
 *   contexts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
 *   Returns 0 if registration successful, 1 if child pid did not exist, and -1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
 *   if a different error occurred.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
wait_register(pid_t pid, const char *inst_fmri, int am_parent, int direct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	char *fname = uu_msprintf("/proc/%ld/psinfo", pid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
	int fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	wait_info_t *wi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	assert(pid != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	if (fname == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	wi = startd_alloc(sizeof (wait_info_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	uu_list_node_init(wi, &wi->wi_link, wait_info_pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	wi->wi_fd = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	wi->wi_pid = pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	wi->wi_fmri = inst_fmri;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	wi->wi_parent = am_parent;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	MUTEX_LOCK(&wait_info_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	(void) uu_list_insert_before(wait_info_list, NULL, wi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	MUTEX_UNLOCK(&wait_info_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	if ((fd = open(fname, O_RDONLY)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
		if (errno == ENOENT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
			 * Child has already exited.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
			wait_remove(wi, direct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
			uu_free(fname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
			log_error(LOG_WARNING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
			    "open %s failed; not monitoring %s: %s\n", fname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
			    inst_fmri, strerror(errno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
			uu_free(fname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	uu_free(fname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	wi->wi_fd = fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	if (port_associate(port_fd, PORT_SOURCE_FD, fd, 0, wi)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
		log_error(LOG_WARNING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
		    "initial port_association of %d / %s failed: %s\n", fd,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
		    inst_fmri, strerror(errno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	log_framework(LOG_DEBUG, "monitoring PID %ld on fd %d (%s)\n", pid, fd,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	    inst_fmri);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
wait_thread(void *args)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
		port_event_t pe;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
		int fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
		wait_info_t *wi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
111
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   226
		if (port_get(port_fd, &pe, NULL) != 0) {
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   227
			if (errno == EINTR)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
				continue;
111
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   229
			else {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
				log_error(LOG_WARNING,
111
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   231
				    "port_get() failed with %s\n",
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   232
				    strerror(errno));
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   233
				bad_error("port_get", errno);
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   234
			}
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   235
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
		fd = pe.portev_object;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
		wi = pe.portev_user;
111
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   239
		assert(wi != NULL);
347ecf011416 6223908 svc.startd dumped core on the B74L2 system
rm88369
parents: 0
diff changeset
   240
		assert(fd == wi->wi_fd);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
		if ((pe.portev_events & POLLHUP) == POLLHUP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
			psinfo_t psi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
			if (lseek(fd, 0, SEEK_SET) != 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
			    read(fd, &psi, sizeof (psinfo_t)) !=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
			    sizeof (psinfo_t)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
				log_framework(LOG_WARNING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
				    "couldn't get psinfo data for %s (%s); "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
				    "assuming failed\n", wi->wi_fmri,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
				    strerror(errno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
				    goto err_remove;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
			if (psi.pr_nlwp != 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
			    psi.pr_nzomb != 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
			    psi.pr_lwp.pr_lwpid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
				 * We have determined, in accordance with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
				 * definition in proc(4), this process is not a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
				 * zombie.  Reassociate.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
				if (port_associate(port_fd, PORT_SOURCE_FD, fd,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
					0, wi))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
					log_error(LOG_WARNING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
					    "port_association of %d / %s "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
					    "failed\n", fd, wi->wi_fmri);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		} else if (
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
		    (pe.portev_events & POLLERR) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
			if (port_associate(port_fd, PORT_SOURCE_FD, fd, 0, wi))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
				log_error(LOG_WARNING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
				    "port_association of %d / %s "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
				    "failed\n", fd, wi->wi_fmri);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
err_remove:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
		wait_remove(wi, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	/*LINTED E_FUNC_HAS_NO_RETURN_STMT*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
wait_prefork()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	MUTEX_LOCK(&wait_info_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
wait_postfork(pid_t pid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	wait_info_t *wi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
	MUTEX_UNLOCK(&wait_info_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
	if (pid != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	 * Close all of the child's wait-related fds.  The wait_thread() is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	 * gone, so no need to worry about returning events.  We always exec(2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	 * after a fork request, so we needn't free the list elements
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	 * themselves.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
	for (wi = uu_list_first(wait_info_list);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
	    wi != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
	    wi = uu_list_next(wait_info_list, wi)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
		if (wi->wi_fd != -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
			startd_close(wi->wi_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
	startd_close(port_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
	(void) setrlimit(RLIMIT_NOFILE, &init_fd_rlimit);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
wait_init()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	struct rlimit fd_new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
	(void) getrlimit(RLIMIT_NOFILE, &init_fd_rlimit);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	(void) getrlimit(RLIMIT_NOFILE, &fd_new);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	fd_new.rlim_max = fd_new.rlim_cur = WAIT_FILES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	(void) setrlimit(RLIMIT_NOFILE, &fd_new);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	if ((port_fd = port_create()) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
		uu_die("wait_init couldn't port_create");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
	wait_info_pool = uu_list_pool_create("wait_info", sizeof (wait_info_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	    offsetof(wait_info_t, wi_link), NULL, UU_LIST_POOL_DEBUG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
	if (wait_info_pool == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
		uu_die("wait_init couldn't create wait_info_pool");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
	wait_info_list = uu_list_create(wait_info_pool, wait_info_list, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
	if (wait_info_list == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
		uu_die("wait_init couldn't create wait_info_list");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	(void) pthread_mutex_init(&wait_info_lock, &mutex_attrs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
}