usr/src/uts/common/os/pid.c
author jpk
Fri, 24 Mar 2006 12:29:20 -0800
changeset 1676 37f4a3e2bd99
parent 749 d7f9da43aeb7
child 2712 f74a135872bc
permissions -rw-r--r--
PSARC/2002/762 Layered Trusted Solaris PSARC/2005/060 TSNET: Trusted Networking with Security Labels PSARC/2005/259 Layered Trusted Solaris Label Interfaces PSARC/2005/573 Solaris Trusted Extensions for Printing PSARC/2005/691 Trusted Extensions for Device Allocation PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling PSARC/2006/009 Labeled Auditing PSARC/2006/155 Trusted Extensions RBAC Changes PSARC/2006/191 is_system_labeled 6293271 Zone processes should use zone_kcred instead of kcred 6394554 integrate Solaris Trusted Extensions
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
 */
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 0
diff changeset
    22
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
/*
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 0
diff changeset
    24
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/tuneable.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/var.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/prsystm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/session.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/bitmap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <c2/audit.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/zone.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
/* directory entries for /proc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
union procent {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
	proc_t *pe_proc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
	union procent *pe_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
struct pid pid0 = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
	0,		/* pid_prinactive */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
	1,		/* pid_pgorphaned */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
	0,		/* pid_padding	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
	0,		/* pid_prslot	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
	0,		/* pid_id	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
	NULL,		/* pid_pglink	*/
749
d7f9da43aeb7 6310079 contention for pidlock is a major bottleneck for the kenbus benchmark
susans
parents: 390
diff changeset
    66
	NULL,		/* pid_pgtail	*/
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
	NULL,		/* pid_link	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
	3		/* pid_ref	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
static int pid_hashlen = 4;	/* desired average hash chain length */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
static int pid_hashsz;		/* number of buckets in the hash table */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
#define	HASHPID(pid)	(pidhash[((pid)&(pid_hashsz-1))])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
extern uint_t nproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
extern struct kmem_cache *process_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
static void	upcount_init(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
kmutex_t	pidlock;	/* global process lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
kmutex_t	pr_pidlock;	/* /proc global process lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
kcondvar_t	*pr_pid_cv;	/* for /proc, one per process slot */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
struct plock	*proc_lock;	/* persistent array of p_lock's */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
 * See the comment above pid_getlockslot() for a detailed explanation of this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
 * constant.  Note that a PLOCK_SHIFT of 3 implies 64-byte coherence
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
 * granularity; if the coherence granularity is ever changed, this constant
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 * should be modified to reflect the change to minimize proc_lock false
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 * sharing (correctness, however, is guaranteed regardless of the coherence
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
 * granularity).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
#define	PLOCK_SHIFT	3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
static kmutex_t	pidlinklock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
static struct pid **pidhash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
static pid_t minpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
static pid_t mpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
static union procent *procdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
static union procent *procentfree;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
static struct pid *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
pid_lookup(pid_t pid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
	struct pid *pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
	ASSERT(MUTEX_HELD(&pidlinklock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
	for (pidp = HASHPID(pid); pidp; pidp = pidp->pid_link) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
		if (pidp->pid_id == pid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
			ASSERT(pidp->pid_ref > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
	return (pidp);
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
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
pid_setmin(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
	if (jump_pid && jump_pid > mpid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
		minpid = mpid = jump_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
		minpid = mpid + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
}
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
 * When prslots are simply used as an index to determine a process' p_lock,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
 * adjacent prslots share adjacent p_locks.  On machines where the size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
 * of a mutex is smaller than that of a cache line (which, as of this writing,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
 * is true for all machines on which Solaris runs), this can potentially
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 * induce false sharing.  The standard solution for false sharing is to pad
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 * out one's data structures (in this case, struct plock).  However,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 * given the size and (generally) sparse use of the proc_lock array, this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 * is suboptimal.  We therefore stride through the proc_lock array with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
 * a stride of PLOCK_SHIFT.  PLOCK_SHIFT should be defined as:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 *   log_2 (coherence_granularity / sizeof (kmutex_t))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
 * Under this scheme, false sharing is still possible -- but only when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
 * the number of active processes is very large.  Note that the one-to-one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
 * mapping between prslots and lockslots is maintained.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
pid_getlockslot(int prslot)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	int even = (v.v_proc >> PLOCK_SHIFT) << PLOCK_SHIFT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	int perlap = even >> PLOCK_SHIFT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	if (prslot >= even)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
		return (prslot);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	return (((prslot % perlap) << PLOCK_SHIFT) + (prslot / perlap));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
 * This function assigns a pid for use in a fork request.  It allocates
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
 * a pid structure, tries to find an empty slot in the proc table,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
 * and selects the process id.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
 * pid_assign() returns the new pid on success, -1 on failure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
pid_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
pid_assign(proc_t *prp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
	struct pid *pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	union procent *pep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
	pid_t newpid, startpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	pidp = kmem_zalloc(sizeof (struct pid), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	mutex_enter(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	if ((pep = procentfree) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
		 * ran out of /proc directory entries
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
		goto failed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	 * Allocate a pid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	startpid = mpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
	do  {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
		newpid = (++mpid == maxpid ? mpid = minpid : mpid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	} while (pid_lookup(newpid) && newpid != startpid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	if (newpid == startpid && pid_lookup(newpid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
		/* couldn't find a free pid */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
		goto failed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	procentfree = pep->pe_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	pep->pe_proc = prp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	prp->p_pidp = pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	 * Put pid into the pid hash table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	pidp->pid_link = HASHPID(newpid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	HASHPID(newpid) = pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	pidp->pid_ref = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	pidp->pid_id = newpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	pidp->pid_prslot = pep - procdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	prp->p_lockp = &proc_lock[pid_getlockslot(pidp->pid_prslot)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	mutex_exit(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	return (newpid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
failed:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	mutex_exit(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	kmem_free(pidp, sizeof (struct pid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
}
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
 * decrement the reference count for pid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
pid_rele(struct pid *pidp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	struct pid **pidpp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	mutex_enter(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	ASSERT(pidp != &pid0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	pidpp = &HASHPID(pidp->pid_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
		ASSERT(*pidpp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
		if (*pidpp == pidp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
		pidpp = &(*pidpp)->pid_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	*pidpp = pidp->pid_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	mutex_exit(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	kmem_free(pidp, sizeof (*pidp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
proc_entry_free(struct pid *pidp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	mutex_enter(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	pidp->pid_prinactive = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	procdir[pidp->pid_prslot].pe_next = procentfree;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	procentfree = &procdir[pidp->pid_prslot];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
	mutex_exit(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
pid_exit(proc_t *prp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
	struct pid *pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
	 * Exit process group.  If it is NULL, it's because fork failed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	 * before calling pgjoin().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	ASSERT(prp->p_pgidp != NULL || prp->p_stat == SIDL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	if (prp->p_pgidp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
		pgexit(prp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
	SESS_RELE(prp->p_sessp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
	pidp = prp->p_pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	proc_entry_free(pidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
#ifdef C2_AUDIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	if (audit_active)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
		audit_pfree(prp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	if (practive == prp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
		practive = prp->p_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	if (prp->p_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
		prp->p_next->p_prev = prp->p_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
	if (prp->p_prev) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
		prp->p_prev->p_next = prp->p_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	PID_RELE(pidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	mutex_destroy(&prp->p_crlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	kmem_cache_free(process_cache, prp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
	nproc--;
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
 * Find a process visible from the specified zone given its process ID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
proc_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
prfind_zone(pid_t pid, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
	struct pid *pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	proc_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	mutex_enter(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
	pidp = pid_lookup(pid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
	mutex_exit(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
	if (pidp != NULL && pidp->pid_prinactive == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
		p = procdir[pidp->pid_prslot].pe_proc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
		if (zoneid == ALL_ZONES || p->p_zone->zone_id == zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
			return (p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
}
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
 * Find a process given its process ID.  This obeys zone restrictions,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
 * so if the caller is in a non-global zone it won't find processes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
 * associated with other zones.  Use prfind_zone(pid, ALL_ZONES) to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
 * bypass this restriction.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
proc_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
prfind(pid_t pid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	zoneid_t zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	if (INGLOBALZONE(curproc))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
		zoneid = ALL_ZONES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
		zoneid = getzoneid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	return (prfind_zone(pid, zoneid));
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
proc_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
pgfind_zone(pid_t pgid, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	struct pid *pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
	mutex_enter(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
	pidp = pid_lookup(pgid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	mutex_exit(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	if (pidp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
		proc_t *p = pidp->pid_pglink;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
		if (zoneid == ALL_ZONES || pgid == 0 || p == NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
		    p->p_zone->zone_id == zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
			return (p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
 * return the head of the list of processes whose process group ID is 'pgid',
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
 * or NULL, if no such process group
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
proc_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
pgfind(pid_t pgid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
	zoneid_t zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
	if (INGLOBALZONE(curproc))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
		zoneid = ALL_ZONES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
		zoneid = getzoneid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
	return (pgfind_zone(pgid, zoneid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
 * If pid exists, find its proc, acquire its p_lock and mark it P_PR_LOCK.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
 * Returns the proc pointer on success, NULL on failure.  sprlock() is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
 * really just a stripped-down version of pr_p_lock() to allow practive
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
 * walkers like dofusers() and dumpsys() to synchronize with /proc.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
proc_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
sprlock_zone(pid_t pid, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
	proc_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
	kmutex_t *mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
		mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
		if ((p = prfind_zone(pid, zoneid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
		 * p_lock is persistent, but p itself is not -- it could
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		 * vanish during cv_wait().  Load p->p_lock now so we can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
		 * drop it after cv_wait() without referencing p.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
		mp = &p->p_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
		mutex_enter(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
		 * If the process is in some half-baked state, fail.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
		if (p->p_stat == SZOMB || p->p_stat == SIDL ||
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 0
diff changeset
   402
		    (p->p_flag & (SEXITING | SEXITLWPS))) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
			mutex_exit(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
		if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
			return (p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
		if (!(p->p_proc_flag & P_PR_LOCK))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
		cv_wait(&pr_pid_cv[p->p_slot], mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
		mutex_exit(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
	p->p_proc_flag |= P_PR_LOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	THREAD_KPRI_REQUEST();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
	return (p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
proc_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
sprlock(pid_t pid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
	zoneid_t zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
	if (INGLOBALZONE(curproc))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
		zoneid = ALL_ZONES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
		zoneid = getzoneid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	return (sprlock_zone(pid, zoneid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
sprlock_proc(proc_t *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	while (p->p_proc_flag & P_PR_LOCK) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
		cv_wait(&pr_pid_cv[p->p_slot], &p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	p->p_proc_flag |= P_PR_LOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	THREAD_KPRI_REQUEST();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
sprunlock(proc_t *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	if (panicstr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
	ASSERT(p->p_proc_flag & P_PR_LOCK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	cv_signal(&pr_pid_cv[p->p_slot]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	p->p_proc_flag &= ~P_PR_LOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	THREAD_KPRI_RELEASE();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
pid_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	pid_hashsz = 1 << highbit(v.v_proc / pid_hashlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	pidhash = kmem_zalloc(sizeof (struct pid *) * pid_hashsz, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
	procdir = kmem_alloc(sizeof (union procent) * v.v_proc, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
	pr_pid_cv = kmem_zalloc(sizeof (kcondvar_t) * v.v_proc, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	proc_lock = kmem_zalloc(sizeof (struct plock) * v.v_proc, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
	nproc = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	practive = proc_sched;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
	proc_sched->p_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
	procdir[0].pe_proc = proc_sched;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	procentfree = &procdir[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
	for (i = 1; i < v.v_proc - 1; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
		procdir[i].pe_next = &procdir[i+1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	procdir[i].pe_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	HASHPID(0) = &pid0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	upcount_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
proc_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
pid_entry(int slot)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	union procent *pep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
	proc_t *prp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	ASSERT(slot >= 0 && slot < v.v_proc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	pep = procdir[slot].pe_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
	if (pep >= procdir && pep < &procdir[v.v_proc])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
	prp = procdir[slot].pe_proc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
	if (prp != 0 && prp->p_stat == SIDL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
	return (prp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
 * Send the specified signal to all processes whose process group ID is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
 * equal to 'pgid'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
signal(pid_t pgid, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	struct pid *pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
	proc_t *prp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	mutex_enter(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
	if (pgid == 0 || (pidp = pid_lookup(pgid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
		mutex_exit(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
	mutex_exit(&pidlinklock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	for (prp = pidp->pid_pglink; prp; prp = prp->p_pglink) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
		mutex_enter(&prp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
		sigtoproc(prp, NULL, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
		mutex_exit(&prp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
 * Send the specified signal to the specified process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
prsignal(struct pid *pidp, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
	if (!(pidp->pid_prinactive))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		psignal(procdir[pidp->pid_prslot].pe_proc, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
#include <sys/sunddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
 * DDI/DKI interfaces for drivers to send signals to processes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
 * obtain an opaque reference to a process for signaling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
proc_ref(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
	struct pid *pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
	pidp = curproc->p_pidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
	PID_HOLD(pidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
	return (pidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
 * release a reference to a process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
 * - a process can exit even if a driver has a reference to it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
 * - one proc_unref for every proc_ref
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
proc_unref(void *pref)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	PID_RELE((struct pid *)pref);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
 * send a signal to a process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
 * - send the process the signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
 * - if the process went away, return a -1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
 * - if the process is still there return 0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
proc_signal(void *pref, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
	struct pid *pidp = pref;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
	prsignal(pidp, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
	return (pidp->pid_prinactive ? -1 : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
static struct upcount	**upc_hash;	/* a boot time allocated array */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
static ulong_t		upc_hashmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
#define	UPC_HASH(x, y)	((ulong_t)(x ^ y) & upc_hashmask)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
 * Get us off the ground.  Called once at boot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
upcount_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	ulong_t	upc_hashsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
	 * An entry per MB of memory is our current guess
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
	 * 2^20 is a meg, so shifting right by 20 - PAGESHIFT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
	 * converts pages to megs (without overflowing a u_int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	 * if you have more than 4G of memory, like ptob(physmem)/1M
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
	 * would).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
	upc_hashsize = (1 << highbit(physmem >> (20 - PAGESHIFT)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
	upc_hashmask = upc_hashsize - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
	upc_hash = kmem_zalloc(upc_hashsize * sizeof (struct upcount *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
 * Increment the number of processes associated with a given uid and zoneid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
upcount_inc(uid_t uid, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
	struct upcount	**upc, **hupc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
	struct upcount	*new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
	new = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
	hupc = &upc_hash[UPC_HASH(uid, zoneid)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
top:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
	upc = hupc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
	while ((*upc) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
		if ((*upc)->up_uid == uid && (*upc)->up_zoneid == zoneid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
			(*upc)->up_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
			if (new) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
				 * did not need `new' afterall.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
				kmem_free(new, sizeof (*new));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
		upc = &(*upc)->up_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	 * There is no entry for this <uid,zoneid> pair.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	 * Allocate one.  If we have to drop pidlock, check
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	 * again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
	if (new == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
		new = (struct upcount *)kmem_alloc(sizeof (*new), KM_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
		if (new == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
			new = (struct upcount *)kmem_alloc(sizeof (*new),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
			    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
			mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
			goto top;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	 * On the assumption that a new user is going to do some
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
	 * more forks, put the new upcount structure on the front.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	upc = hupc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	new->up_uid = uid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
	new->up_zoneid = zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	new->up_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
	new->up_next = *upc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
	*upc = new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
 * Decrement the number of processes a given uid and zoneid has.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
upcount_dec(uid_t uid, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
	struct	upcount **upc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	struct	upcount *done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
	upc = &upc_hash[UPC_HASH(uid, zoneid)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
	while ((*upc) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
		if ((*upc)->up_uid == uid && (*upc)->up_zoneid == zoneid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
			(*upc)->up_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
			if ((*upc)->up_count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
				done = *upc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
				*upc = (*upc)->up_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
				kmem_free(done, sizeof (*done));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
		upc = &(*upc)->up_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
	cmn_err(CE_PANIC, "decr_upcount-off the end");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
 * Returns the number of processes a uid has.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
 * Non-existent uid's are assumed to have no processes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
upcount_get(uid_t uid, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	struct	upcount *upc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
	upc = upc_hash[UPC_HASH(uid, zoneid)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
	while (upc != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
		if (upc->up_uid == uid && upc->up_zoneid == zoneid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
			return (upc->up_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
		upc = upc->up_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
}