usr/src/cmd/svc/startd/contract.c
author eschrock
Fri, 26 Oct 2007 13:47:19 -0700
changeset 5345 44060de1d838
parent 0 68f95e015346
child 11466 d60272412fb0
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
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
#ifdef _FILE_OFFSET_BITS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#undef _FILE_OFFSET_BITS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#endif /* _FILE_OFFSET_BITS */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include <sys/contract/process.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/ctfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <assert.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <fcntl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <libcontract.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <libcontract_priv.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <libuutil.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <limits.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <procfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <signal.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <string.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <unistd.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include "startd.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
contract_abandon(ctid_t ctid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
	int err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
	assert(ctid != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
	err = contract_abandon_id(ctid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
	if (err)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
		log_framework(LOG_NOTICE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
		    "failed to abandon contract %ld: %s\n", ctid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
		    strerror(err));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
contract_kill(ctid_t ctid, int sig, const char *fmri)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
	if (sigsend(P_CTID, ctid, sig) == -1 && errno != ESRCH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
		log_error(LOG_WARNING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
		    "%s: Could not signal all contract members: %s\n", fmri,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
		    strerror(errno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
	return (0);
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
ctid_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
contract_init()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
	int psfd, csfd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
	ctid_t ctid, configd_ctid = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
	psinfo_t psi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
	ct_stathdl_t s;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
	ctid_t *ctids;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
	uint_t nctids;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
	uint_t n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
	int err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
	 * 2.  Acquire any contracts we should have inherited.  First, find the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
	 * contract we belong to, then get its status.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
	if ((psfd = open("/proc/self/psinfo", O_RDONLY)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
		log_error(LOG_WARNING, "Can not open /proc/self/psinfo; unable "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
		    "to check to adopt contracts: %s\n", strerror(errno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
	if (read(psfd, &psi, sizeof (psinfo_t)) != sizeof (psinfo_t)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
		log_error(LOG_WARNING, "Can not read from /proc/self/psinfo; "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
		    "unable to adopt contracts: %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
		    strerror(errno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
		startd_close(psfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
	ctid = psi.pr_contract;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	startd_close(psfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
	if ((csfd = contract_open(ctid, "process", "status", O_RDONLY)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
		log_error(LOG_WARNING, "Can not open containing contract "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
		    "status; unable to adopt contracts: %s\n", strerror(errno));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
	/* 3.  Go about adopting our member list. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
	err = ct_status_read(csfd, CTD_ALL, &s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
	startd_close(csfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
	if (err) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
		log_error(LOG_WARNING, "Can not read containing contract "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
		    "status; unable to adopt: %s\n", strerror(err));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	if (err = ct_pr_status_get_contracts(s, &ctids, &nctids)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
		log_error(LOG_WARNING, "Can not get my inherited contracts; "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
		    "unable to adopt: %s\n", strerror(err));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
		ct_status_free(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
		return (-1);
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
	if (nctids == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
		 * We're booting, as a svc.startd which managed to fork a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
		 * child will always have a svc.configd contract to adopt.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
		st->st_initial = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
		ct_status_free(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
		return (-1);
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
	 * We're restarting after an interruption of some kind.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	log_framework(LOG_NOTICE, "restarting after interruption\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
	st->st_initial = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
	 * 3'.  Loop through the array, adopting them all where possible, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	 * noting which one contains svc.configd (via a cookie vlaue of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	 * CONFIGD_COOKIE).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
	for (n = 0; n < nctids; n++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
		int ccfd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
		ct_stathdl_t cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
		if ((ccfd = contract_open(ctids[n], "process", "ctl",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
		    O_WRONLY)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
			log_error(LOG_WARNING, "Can not open contract %ld ctl "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
			    "for adoption: %s\n", ctids[n], strerror(err));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		if ((csfd = contract_open(ctids[n], "process", "status",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
		    O_RDONLY)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
			log_error(LOG_WARNING, "Can not open contract %ld "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
			    "status for cookie: %s\n", ctids[n], strerror(err));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
			startd_close(ccfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
		if (err = ct_ctl_adopt(ccfd)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
			log_error(LOG_WARNING, "Can not adopt contract %ld: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
			    "%s\n", ctids[n], strerror(err));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
			startd_close(ccfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
			startd_close(csfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
		startd_close(ccfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
		if (err = ct_status_read(csfd, CTD_COMMON, &cs)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
			log_error(LOG_WARNING, "Can not read contract %ld"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
			    "status; unable to fetch cookie: %s\n", ctids[n],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
			    strerror(err));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
			ct_status_free(cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
			startd_close(csfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
			continue;
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
		if (ct_status_get_cookie(cs) == CONFIGD_COOKIE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
			configd_ctid = ctids[n];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
		ct_status_free(cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
		startd_close(csfd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	ct_status_free(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	return (configd_ctid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
contract_is_empty(ctid_t ctid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	int fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
	ct_stathdl_t ctstat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	pid_t *members;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	uint_t num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	fd = contract_open(ctid, "process", "status", O_RDONLY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	if (fd < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	ret = ct_status_read(fd, CTD_ALL, &ctstat);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	(void) close(fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	if (ret != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	ret = ct_pr_status_get_members(ctstat, &members, &num);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	ct_status_free(ctstat);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	if (ret != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	if (num == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
typedef struct contract_bucket {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
	pthread_mutex_t cb_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
	uu_list_t	*cb_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
} contract_bucket_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
#define	CI_HASH_SIZE	64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
#define	CI_HASH_MASK	(CI_HASH_SIZE - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
 * contract_hash is a hash table of contract ids to restarter instance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
 * IDs.  It can be used for quick lookups when processing contract events,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
 * because the restarter instance lock doesn't need to be held to access
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
 * its entries.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
static contract_bucket_t contract_hash[CI_HASH_SIZE];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
static contract_bucket_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
contract_hold_bucket(ctid_t ctid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
	contract_bucket_t *bp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	int hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	hash = ctid & CI_HASH_MASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	bp = &contract_hash[hash];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	MUTEX_LOCK(&bp->cb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
	return (bp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
contract_release_bucket(contract_bucket_t *bp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	assert(PTHREAD_MUTEX_HELD(&bp->cb_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	MUTEX_UNLOCK(&bp->cb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
static contract_entry_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
contract_lookup(contract_bucket_t *bp, ctid_t ctid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	contract_entry_t *ce;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	assert(PTHREAD_MUTEX_HELD(&bp->cb_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	if (bp->cb_list == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
	for (ce = uu_list_first(bp->cb_list); ce != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	    ce = uu_list_next(bp->cb_list, ce)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
		if (ce->ce_ctid == ctid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
			return (ce);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
contract_insert(contract_bucket_t *bp, contract_entry_t *ce)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
	int r;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	if (bp->cb_list == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
		bp->cb_list = startd_list_create(contract_list_pool, bp, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	uu_list_node_init(ce, &ce->ce_link, contract_list_pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	r = uu_list_insert_before(bp->cb_list, NULL, ce);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	assert(r == 0);
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
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
contract_hash_init()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
	for (i = 0; i < CI_HASH_SIZE; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
		(void) pthread_mutex_init(&contract_hash[i].cb_lock,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
		    &mutex_attrs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
contract_hash_store(ctid_t ctid, int instid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
	contract_bucket_t *bp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
	contract_entry_t *ce;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
	bp = contract_hold_bucket(ctid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
	assert(contract_lookup(bp, ctid) == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	ce = startd_alloc(sizeof (contract_entry_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	ce->ce_ctid = ctid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	ce->ce_instid = instid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	contract_insert(bp, ce);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	contract_release_bucket(bp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
contract_hash_remove(ctid_t ctid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	contract_bucket_t *bp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
	contract_entry_t *ce;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
	bp = contract_hold_bucket(ctid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
	ce = contract_lookup(bp, ctid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	if (ce != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
		uu_list_remove(bp->cb_list, ce);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
		startd_free(ce, sizeof (contract_entry_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	contract_release_bucket(bp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
 * int lookup_inst_by_contract()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
 *   Lookup the instance id in the hash table by the contract id.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
 *   Returns instid if found, -1 if not.  Doesn't do a hold on the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
 *   instance, so a check for continued existence is required.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
lookup_inst_by_contract(ctid_t ctid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
	contract_bucket_t *bp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
	contract_entry_t *ce;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	int id = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
	bp = contract_hold_bucket(ctid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	ce = contract_lookup(bp, ctid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
	if (ce != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
		id = ce->ce_instid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
	contract_release_bucket(bp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	return (id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
}