Thu Jan 26 03:54:54 2017 UTC ()
always compile in the COMPAT32 code; it is tiny and if we don't it breaks
the modules.


(christos)
diff -r1.199 -r1.200 src/sys/kern/kern_proc.c

cvs diff -r1.199 -r1.200 src/sys/kern/kern_proc.c (switch to unified diff)

--- src/sys/kern/kern_proc.c 2016/11/14 08:55:51 1.199
+++ src/sys/kern/kern_proc.c 2017/01/26 03:54:54 1.200
@@ -1,1105 +1,1108 @@ @@ -1,1105 +1,1108 @@
1/* $NetBSD: kern_proc.c,v 1.199 2016/11/14 08:55:51 kre Exp $ */ 1/* $NetBSD: kern_proc.c,v 1.200 2017/01/26 03:54:54 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, and by Andrew Doran. 9 * NASA Ames Research Center, and by Andrew Doran.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Copyright (c) 1982, 1986, 1989, 1991, 1993 34 * Copyright (c) 1982, 1986, 1989, 1991, 1993
35 * The Regents of the University of California. All rights reserved. 35 * The Regents of the University of California. All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright 42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the 43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution. 44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors 45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software 46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission. 47 * without specific prior written permission.
48 * 48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95 61 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.199 2016/11/14 08:55:51 kre Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.200 2017/01/26 03:54:54 christos Exp $");
66 66
67#ifdef _KERNEL_OPT 67#ifdef _KERNEL_OPT
68#include "opt_kstack.h" 68#include "opt_kstack.h"
69#include "opt_maxuprc.h" 69#include "opt_maxuprc.h"
70#include "opt_dtrace.h" 70#include "opt_dtrace.h"
71#include "opt_compat_netbsd32.h" 71#include "opt_compat_netbsd32.h"
72#endif 72#endif
73 73
74#include <sys/param.h> 74#include <sys/param.h>
75#include <sys/systm.h> 75#include <sys/systm.h>
76#include <sys/kernel.h> 76#include <sys/kernel.h>
77#include <sys/proc.h> 77#include <sys/proc.h>
78#include <sys/resourcevar.h> 78#include <sys/resourcevar.h>
79#include <sys/buf.h> 79#include <sys/buf.h>
80#include <sys/acct.h> 80#include <sys/acct.h>
81#include <sys/wait.h> 81#include <sys/wait.h>
82#include <sys/file.h> 82#include <sys/file.h>
83#include <ufs/ufs/quota.h> 83#include <ufs/ufs/quota.h>
84#include <sys/uio.h> 84#include <sys/uio.h>
85#include <sys/pool.h> 85#include <sys/pool.h>
86#include <sys/pset.h> 86#include <sys/pset.h>
87#include <sys/mbuf.h> 87#include <sys/mbuf.h>
88#include <sys/ioctl.h> 88#include <sys/ioctl.h>
89#include <sys/tty.h> 89#include <sys/tty.h>
90#include <sys/signalvar.h> 90#include <sys/signalvar.h>
91#include <sys/ras.h> 91#include <sys/ras.h>
92#include <sys/filedesc.h> 92#include <sys/filedesc.h>
93#include <sys/syscall_stats.h> 93#include <sys/syscall_stats.h>
94#include <sys/kauth.h> 94#include <sys/kauth.h>
95#include <sys/sleepq.h> 95#include <sys/sleepq.h>
96#include <sys/atomic.h> 96#include <sys/atomic.h>
97#include <sys/kmem.h> 97#include <sys/kmem.h>
98#include <sys/namei.h> 98#include <sys/namei.h>
99#include <sys/dtrace_bsd.h> 99#include <sys/dtrace_bsd.h>
100#include <sys/sysctl.h> 100#include <sys/sysctl.h>
101#include <sys/exec.h> 101#include <sys/exec.h>
102#include <sys/cpu.h> 102#include <sys/cpu.h>
103 103
104#include <uvm/uvm_extern.h> 104#include <uvm/uvm_extern.h>
105#include <uvm/uvm.h> 105#include <uvm/uvm.h>
106 106
 107#ifndef COMPAT_NETBSD32
 108#define COMPAT_NETBSD32
 109#endif
107#ifdef COMPAT_NETBSD32 110#ifdef COMPAT_NETBSD32
108#include <compat/netbsd32/netbsd32.h> 111#include <compat/netbsd32/netbsd32.h>
109#endif 112#endif
110 113
111/* 114/*
112 * Process lists. 115 * Process lists.
113 */ 116 */
114 117
115struct proclist allproc __cacheline_aligned; 118struct proclist allproc __cacheline_aligned;
116struct proclist zombproc __cacheline_aligned; 119struct proclist zombproc __cacheline_aligned;
117 120
118kmutex_t * proc_lock __cacheline_aligned; 121kmutex_t * proc_lock __cacheline_aligned;
119 122
120/* 123/*
121 * pid to proc lookup is done by indexing the pid_table array. 124 * pid to proc lookup is done by indexing the pid_table array.
122 * Since pid numbers are only allocated when an empty slot 125 * Since pid numbers are only allocated when an empty slot
123 * has been found, there is no need to search any lists ever. 126 * has been found, there is no need to search any lists ever.
124 * (an orphaned pgrp will lock the slot, a session will lock 127 * (an orphaned pgrp will lock the slot, a session will lock
125 * the pgrp with the same number.) 128 * the pgrp with the same number.)
126 * If the table is too small it is reallocated with twice the 129 * If the table is too small it is reallocated with twice the
127 * previous size and the entries 'unzipped' into the two halves. 130 * previous size and the entries 'unzipped' into the two halves.
128 * A linked list of free entries is passed through the pt_proc 131 * A linked list of free entries is passed through the pt_proc
129 * field of 'free' items - set odd to be an invalid ptr. 132 * field of 'free' items - set odd to be an invalid ptr.
130 */ 133 */
131 134
132struct pid_table { 135struct pid_table {
133 struct proc *pt_proc; 136 struct proc *pt_proc;
134 struct pgrp *pt_pgrp; 137 struct pgrp *pt_pgrp;
135 pid_t pt_pid; 138 pid_t pt_pid;
136}; 139};
137#if 1 /* strongly typed cast - should be a noop */ 140#if 1 /* strongly typed cast - should be a noop */
138static inline uint p2u(struct proc *p) { return (uint)(uintptr_t)p; } 141static inline uint p2u(struct proc *p) { return (uint)(uintptr_t)p; }
139#else 142#else
140#define p2u(p) ((uint)p) 143#define p2u(p) ((uint)p)
141#endif 144#endif
142#define P_VALID(p) (!(p2u(p) & 1)) 145#define P_VALID(p) (!(p2u(p) & 1))
143#define P_NEXT(p) (p2u(p) >> 1) 146#define P_NEXT(p) (p2u(p) >> 1)
144#define P_FREE(pid) ((struct proc *)(uintptr_t)((pid) << 1 | 1)) 147#define P_FREE(pid) ((struct proc *)(uintptr_t)((pid) << 1 | 1))
145 148
146/* 149/*
147 * Table of process IDs (PIDs). 150 * Table of process IDs (PIDs).
148 */ 151 */
149static struct pid_table *pid_table __read_mostly; 152static struct pid_table *pid_table __read_mostly;
150 153
151#define INITIAL_PID_TABLE_SIZE (1 << 5) 154#define INITIAL_PID_TABLE_SIZE (1 << 5)
152 155
153/* Table mask, threshold for growing and number of allocated PIDs. */ 156/* Table mask, threshold for growing and number of allocated PIDs. */
154static u_int pid_tbl_mask __read_mostly; 157static u_int pid_tbl_mask __read_mostly;
155static u_int pid_alloc_lim __read_mostly; 158static u_int pid_alloc_lim __read_mostly;
156static u_int pid_alloc_cnt __cacheline_aligned; 159static u_int pid_alloc_cnt __cacheline_aligned;
157 160
158/* Next free, last free and maximum PIDs. */ 161/* Next free, last free and maximum PIDs. */
159static u_int next_free_pt __cacheline_aligned; 162static u_int next_free_pt __cacheline_aligned;
160static u_int last_free_pt __cacheline_aligned; 163static u_int last_free_pt __cacheline_aligned;
161static pid_t pid_max __read_mostly; 164static pid_t pid_max __read_mostly;
162 165
163/* Components of the first process -- never freed. */ 166/* Components of the first process -- never freed. */
164 167
165extern struct emul emul_netbsd; /* defined in kern_exec.c */ 168extern struct emul emul_netbsd; /* defined in kern_exec.c */
166 169
167struct session session0 = { 170struct session session0 = {
168 .s_count = 1, 171 .s_count = 1,
169 .s_sid = 0, 172 .s_sid = 0,
170}; 173};
171struct pgrp pgrp0 = { 174struct pgrp pgrp0 = {
172 .pg_members = LIST_HEAD_INITIALIZER(&pgrp0.pg_members), 175 .pg_members = LIST_HEAD_INITIALIZER(&pgrp0.pg_members),
173 .pg_session = &session0, 176 .pg_session = &session0,
174}; 177};
175filedesc_t filedesc0; 178filedesc_t filedesc0;
176struct cwdinfo cwdi0 = { 179struct cwdinfo cwdi0 = {
177 .cwdi_cmask = CMASK, 180 .cwdi_cmask = CMASK,
178 .cwdi_refcnt = 1, 181 .cwdi_refcnt = 1,
179}; 182};
180struct plimit limit0; 183struct plimit limit0;
181struct pstats pstat0; 184struct pstats pstat0;
182struct vmspace vmspace0; 185struct vmspace vmspace0;
183struct sigacts sigacts0; 186struct sigacts sigacts0;
184struct proc proc0 = { 187struct proc proc0 = {
185 .p_lwps = LIST_HEAD_INITIALIZER(&proc0.p_lwps), 188 .p_lwps = LIST_HEAD_INITIALIZER(&proc0.p_lwps),
186 .p_sigwaiters = LIST_HEAD_INITIALIZER(&proc0.p_sigwaiters), 189 .p_sigwaiters = LIST_HEAD_INITIALIZER(&proc0.p_sigwaiters),
187 .p_nlwps = 1, 190 .p_nlwps = 1,
188 .p_nrlwps = 1, 191 .p_nrlwps = 1,
189 .p_nlwpid = 1, /* must match lwp0.l_lid */ 192 .p_nlwpid = 1, /* must match lwp0.l_lid */
190 .p_pgrp = &pgrp0, 193 .p_pgrp = &pgrp0,
191 .p_comm = "system", 194 .p_comm = "system",
192 /* 195 /*
193 * Set P_NOCLDWAIT so that kernel threads are reparented to init(8) 196 * Set P_NOCLDWAIT so that kernel threads are reparented to init(8)
194 * when they exit. init(8) can easily wait them out for us. 197 * when they exit. init(8) can easily wait them out for us.
195 */ 198 */
196 .p_flag = PK_SYSTEM | PK_NOCLDWAIT, 199 .p_flag = PK_SYSTEM | PK_NOCLDWAIT,
197 .p_stat = SACTIVE, 200 .p_stat = SACTIVE,
198 .p_nice = NZERO, 201 .p_nice = NZERO,
199 .p_emul = &emul_netbsd, 202 .p_emul = &emul_netbsd,
200 .p_cwdi = &cwdi0, 203 .p_cwdi = &cwdi0,
201 .p_limit = &limit0, 204 .p_limit = &limit0,
202 .p_fd = &filedesc0, 205 .p_fd = &filedesc0,
203 .p_vmspace = &vmspace0, 206 .p_vmspace = &vmspace0,
204 .p_stats = &pstat0, 207 .p_stats = &pstat0,
205 .p_sigacts = &sigacts0, 208 .p_sigacts = &sigacts0,
206#ifdef PROC0_MD_INITIALIZERS 209#ifdef PROC0_MD_INITIALIZERS
207 PROC0_MD_INITIALIZERS 210 PROC0_MD_INITIALIZERS
208#endif 211#endif
209}; 212};
210kauth_cred_t cred0; 213kauth_cred_t cred0;
211 214
212static const int nofile = NOFILE; 215static const int nofile = NOFILE;
213static const int maxuprc = MAXUPRC; 216static const int maxuprc = MAXUPRC;
214 217
215static int sysctl_doeproc(SYSCTLFN_PROTO); 218static int sysctl_doeproc(SYSCTLFN_PROTO);
216static int sysctl_kern_proc_args(SYSCTLFN_PROTO); 219static int sysctl_kern_proc_args(SYSCTLFN_PROTO);
217 220
218/* 221/*
219 * The process list descriptors, used during pid allocation and 222 * The process list descriptors, used during pid allocation and
220 * by sysctl. No locking on this data structure is needed since 223 * by sysctl. No locking on this data structure is needed since
221 * it is completely static. 224 * it is completely static.
222 */ 225 */
223const struct proclist_desc proclists[] = { 226const struct proclist_desc proclists[] = {
224 { &allproc }, 227 { &allproc },
225 { &zombproc }, 228 { &zombproc },
226 { NULL }, 229 { NULL },
227}; 230};
228 231
229static struct pgrp * pg_remove(pid_t); 232static struct pgrp * pg_remove(pid_t);
230static void pg_delete(pid_t); 233static void pg_delete(pid_t);
231static void orphanpg(struct pgrp *); 234static void orphanpg(struct pgrp *);
232 235
233static specificdata_domain_t proc_specificdata_domain; 236static specificdata_domain_t proc_specificdata_domain;
234 237
235static pool_cache_t proc_cache; 238static pool_cache_t proc_cache;
236 239
237static kauth_listener_t proc_listener; 240static kauth_listener_t proc_listener;
238 241
239static int fill_pathname(struct lwp *, pid_t, void *, size_t *); 242static int fill_pathname(struct lwp *, pid_t, void *, size_t *);
240 243
241static int 244static int
242proc_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, 245proc_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
243 void *arg0, void *arg1, void *arg2, void *arg3) 246 void *arg0, void *arg1, void *arg2, void *arg3)
244{ 247{
245 struct proc *p; 248 struct proc *p;
246 int result; 249 int result;
247 250
248 result = KAUTH_RESULT_DEFER; 251 result = KAUTH_RESULT_DEFER;
249 p = arg0; 252 p = arg0;
250 253
251 switch (action) { 254 switch (action) {
252 case KAUTH_PROCESS_CANSEE: { 255 case KAUTH_PROCESS_CANSEE: {
253 enum kauth_process_req req; 256 enum kauth_process_req req;
254 257
255 req = (enum kauth_process_req)arg1; 258 req = (enum kauth_process_req)arg1;
256 259
257 switch (req) { 260 switch (req) {
258 case KAUTH_REQ_PROCESS_CANSEE_ARGS: 261 case KAUTH_REQ_PROCESS_CANSEE_ARGS:
259 case KAUTH_REQ_PROCESS_CANSEE_ENTRY: 262 case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
260 case KAUTH_REQ_PROCESS_CANSEE_OPENFILES: 263 case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
261 result = KAUTH_RESULT_ALLOW; 264 result = KAUTH_RESULT_ALLOW;
262 265
263 break; 266 break;
264 267
265 case KAUTH_REQ_PROCESS_CANSEE_ENV: 268 case KAUTH_REQ_PROCESS_CANSEE_ENV:
266 if (kauth_cred_getuid(cred) != 269 if (kauth_cred_getuid(cred) !=
267 kauth_cred_getuid(p->p_cred) || 270 kauth_cred_getuid(p->p_cred) ||
268 kauth_cred_getuid(cred) != 271 kauth_cred_getuid(cred) !=
269 kauth_cred_getsvuid(p->p_cred)) 272 kauth_cred_getsvuid(p->p_cred))
270 break; 273 break;
271 274
272 result = KAUTH_RESULT_ALLOW; 275 result = KAUTH_RESULT_ALLOW;
273 276
274 break; 277 break;
275 278
276 default: 279 default:
277 break; 280 break;
278 } 281 }
279 282
280 break; 283 break;
281 } 284 }
282 285
283 case KAUTH_PROCESS_FORK: { 286 case KAUTH_PROCESS_FORK: {
284 int lnprocs = (int)(unsigned long)arg2; 287 int lnprocs = (int)(unsigned long)arg2;
285 288
286 /* 289 /*
287 * Don't allow a nonprivileged user to use the last few 290 * Don't allow a nonprivileged user to use the last few
288 * processes. The variable lnprocs is the current number of 291 * processes. The variable lnprocs is the current number of
289 * processes, maxproc is the limit. 292 * processes, maxproc is the limit.
290 */ 293 */
291 if (__predict_false((lnprocs >= maxproc - 5))) 294 if (__predict_false((lnprocs >= maxproc - 5)))
292 break; 295 break;
293 296
294 result = KAUTH_RESULT_ALLOW; 297 result = KAUTH_RESULT_ALLOW;
295 298
296 break; 299 break;
297 } 300 }
298 301
299 case KAUTH_PROCESS_CORENAME: 302 case KAUTH_PROCESS_CORENAME:
300 case KAUTH_PROCESS_STOPFLAG: 303 case KAUTH_PROCESS_STOPFLAG:
301 if (proc_uidmatch(cred, p->p_cred) == 0) 304 if (proc_uidmatch(cred, p->p_cred) == 0)
302 result = KAUTH_RESULT_ALLOW; 305 result = KAUTH_RESULT_ALLOW;
303 306
304 break; 307 break;
305 308
306 default: 309 default:
307 break; 310 break;
308 } 311 }
309 312
310 return result; 313 return result;
311} 314}
312 315
313/* 316/*
314 * Initialize global process hashing structures. 317 * Initialize global process hashing structures.
315 */ 318 */
316void 319void
317procinit(void) 320procinit(void)
318{ 321{
319 const struct proclist_desc *pd; 322 const struct proclist_desc *pd;
320 u_int i; 323 u_int i;
321#define LINK_EMPTY ((PID_MAX + INITIAL_PID_TABLE_SIZE) & ~(INITIAL_PID_TABLE_SIZE - 1)) 324#define LINK_EMPTY ((PID_MAX + INITIAL_PID_TABLE_SIZE) & ~(INITIAL_PID_TABLE_SIZE - 1))
322 325
323 for (pd = proclists; pd->pd_list != NULL; pd++) 326 for (pd = proclists; pd->pd_list != NULL; pd++)
324 LIST_INIT(pd->pd_list); 327 LIST_INIT(pd->pd_list);
325 328
326 proc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 329 proc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
327 pid_table = kmem_alloc(INITIAL_PID_TABLE_SIZE 330 pid_table = kmem_alloc(INITIAL_PID_TABLE_SIZE
328 * sizeof(struct pid_table), KM_SLEEP); 331 * sizeof(struct pid_table), KM_SLEEP);
329 pid_tbl_mask = INITIAL_PID_TABLE_SIZE - 1; 332 pid_tbl_mask = INITIAL_PID_TABLE_SIZE - 1;
330 pid_max = PID_MAX; 333 pid_max = PID_MAX;
331 334
332 /* Set free list running through table... 335 /* Set free list running through table...
333 Preset 'use count' above PID_MAX so we allocate pid 1 next. */ 336 Preset 'use count' above PID_MAX so we allocate pid 1 next. */
334 for (i = 0; i <= pid_tbl_mask; i++) { 337 for (i = 0; i <= pid_tbl_mask; i++) {
335 pid_table[i].pt_proc = P_FREE(LINK_EMPTY + i + 1); 338 pid_table[i].pt_proc = P_FREE(LINK_EMPTY + i + 1);
336 pid_table[i].pt_pgrp = 0; 339 pid_table[i].pt_pgrp = 0;
337 pid_table[i].pt_pid = 0; 340 pid_table[i].pt_pid = 0;
338 } 341 }
339 /* slot 0 is just grabbed */ 342 /* slot 0 is just grabbed */
340 next_free_pt = 1; 343 next_free_pt = 1;
341 /* Need to fix last entry. */ 344 /* Need to fix last entry. */
342 last_free_pt = pid_tbl_mask; 345 last_free_pt = pid_tbl_mask;
343 pid_table[last_free_pt].pt_proc = P_FREE(LINK_EMPTY); 346 pid_table[last_free_pt].pt_proc = P_FREE(LINK_EMPTY);
344 /* point at which we grow table - to avoid reusing pids too often */ 347 /* point at which we grow table - to avoid reusing pids too often */
345 pid_alloc_lim = pid_tbl_mask - 1; 348 pid_alloc_lim = pid_tbl_mask - 1;
346#undef LINK_EMPTY 349#undef LINK_EMPTY
347 350
348 proc_specificdata_domain = specificdata_domain_create(); 351 proc_specificdata_domain = specificdata_domain_create();
349 KASSERT(proc_specificdata_domain != NULL); 352 KASSERT(proc_specificdata_domain != NULL);
350 353
351 proc_cache = pool_cache_init(sizeof(struct proc), 0, 0, 0, 354 proc_cache = pool_cache_init(sizeof(struct proc), 0, 0, 0,
352 "procpl", NULL, IPL_NONE, NULL, NULL, NULL); 355 "procpl", NULL, IPL_NONE, NULL, NULL, NULL);
353 356
354 proc_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS, 357 proc_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
355 proc_listener_cb, NULL); 358 proc_listener_cb, NULL);
356} 359}
357 360
358void 361void
359procinit_sysctl(void) 362procinit_sysctl(void)
360{ 363{
361 static struct sysctllog *clog; 364 static struct sysctllog *clog;
362 365
363 sysctl_createv(&clog, 0, NULL, NULL, 366 sysctl_createv(&clog, 0, NULL, NULL,
364 CTLFLAG_PERMANENT, 367 CTLFLAG_PERMANENT,
365 CTLTYPE_NODE, "proc", 368 CTLTYPE_NODE, "proc",
366 SYSCTL_DESCR("System-wide process information"), 369 SYSCTL_DESCR("System-wide process information"),
367 sysctl_doeproc, 0, NULL, 0, 370 sysctl_doeproc, 0, NULL, 0,
368 CTL_KERN, KERN_PROC, CTL_EOL); 371 CTL_KERN, KERN_PROC, CTL_EOL);
369 sysctl_createv(&clog, 0, NULL, NULL, 372 sysctl_createv(&clog, 0, NULL, NULL,
370 CTLFLAG_PERMANENT, 373 CTLFLAG_PERMANENT,
371 CTLTYPE_NODE, "proc2", 374 CTLTYPE_NODE, "proc2",
372 SYSCTL_DESCR("Machine-independent process information"), 375 SYSCTL_DESCR("Machine-independent process information"),
373 sysctl_doeproc, 0, NULL, 0, 376 sysctl_doeproc, 0, NULL, 0,
374 CTL_KERN, KERN_PROC2, CTL_EOL); 377 CTL_KERN, KERN_PROC2, CTL_EOL);
375 sysctl_createv(&clog, 0, NULL, NULL, 378 sysctl_createv(&clog, 0, NULL, NULL,
376 CTLFLAG_PERMANENT, 379 CTLFLAG_PERMANENT,
377 CTLTYPE_NODE, "proc_args", 380 CTLTYPE_NODE, "proc_args",
378 SYSCTL_DESCR("Process argument information"), 381 SYSCTL_DESCR("Process argument information"),
379 sysctl_kern_proc_args, 0, NULL, 0, 382 sysctl_kern_proc_args, 0, NULL, 0,
380 CTL_KERN, KERN_PROC_ARGS, CTL_EOL); 383 CTL_KERN, KERN_PROC_ARGS, CTL_EOL);
381 384
382 /* 385 /*
383 "nodes" under these: 386 "nodes" under these:
384 387
385 KERN_PROC_ALL 388 KERN_PROC_ALL
386 KERN_PROC_PID pid 389 KERN_PROC_PID pid
387 KERN_PROC_PGRP pgrp 390 KERN_PROC_PGRP pgrp
388 KERN_PROC_SESSION sess 391 KERN_PROC_SESSION sess
389 KERN_PROC_TTY tty 392 KERN_PROC_TTY tty
390 KERN_PROC_UID uid 393 KERN_PROC_UID uid
391 KERN_PROC_RUID uid 394 KERN_PROC_RUID uid
392 KERN_PROC_GID gid 395 KERN_PROC_GID gid
393 KERN_PROC_RGID gid 396 KERN_PROC_RGID gid
394 397
395 all in all, probably not worth the effort... 398 all in all, probably not worth the effort...
396 */ 399 */
397} 400}
398 401
399/* 402/*
400 * Initialize process 0. 403 * Initialize process 0.
401 */ 404 */
402void 405void
403proc0_init(void) 406proc0_init(void)
404{ 407{
405 struct proc *p; 408 struct proc *p;
406 struct pgrp *pg; 409 struct pgrp *pg;
407 struct rlimit *rlim; 410 struct rlimit *rlim;
408 rlim_t lim; 411 rlim_t lim;
409 int i; 412 int i;
410 413
411 p = &proc0; 414 p = &proc0;
412 pg = &pgrp0; 415 pg = &pgrp0;
413 416
414 mutex_init(&p->p_stmutex, MUTEX_DEFAULT, IPL_HIGH); 417 mutex_init(&p->p_stmutex, MUTEX_DEFAULT, IPL_HIGH);
415 mutex_init(&p->p_auxlock, MUTEX_DEFAULT, IPL_NONE); 418 mutex_init(&p->p_auxlock, MUTEX_DEFAULT, IPL_NONE);
416 p->p_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 419 p->p_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
417 420
418 rw_init(&p->p_reflock); 421 rw_init(&p->p_reflock);
419 cv_init(&p->p_waitcv, "wait"); 422 cv_init(&p->p_waitcv, "wait");
420 cv_init(&p->p_lwpcv, "lwpwait"); 423 cv_init(&p->p_lwpcv, "lwpwait");
421 424
422 LIST_INSERT_HEAD(&p->p_lwps, &lwp0, l_sibling); 425 LIST_INSERT_HEAD(&p->p_lwps, &lwp0, l_sibling);
423 426
424 pid_table[0].pt_proc = p; 427 pid_table[0].pt_proc = p;
425 LIST_INSERT_HEAD(&allproc, p, p_list); 428 LIST_INSERT_HEAD(&allproc, p, p_list);
426 429
427 pid_table[0].pt_pgrp = pg; 430 pid_table[0].pt_pgrp = pg;
428 LIST_INSERT_HEAD(&pg->pg_members, p, p_pglist); 431 LIST_INSERT_HEAD(&pg->pg_members, p, p_pglist);
429 432
430#ifdef __HAVE_SYSCALL_INTERN 433#ifdef __HAVE_SYSCALL_INTERN
431 (*p->p_emul->e_syscall_intern)(p); 434 (*p->p_emul->e_syscall_intern)(p);
432#endif 435#endif
433 436
434 /* Create credentials. */ 437 /* Create credentials. */
435 cred0 = kauth_cred_alloc(); 438 cred0 = kauth_cred_alloc();
436 p->p_cred = cred0; 439 p->p_cred = cred0;
437 440
438 /* Create the CWD info. */ 441 /* Create the CWD info. */
439 rw_init(&cwdi0.cwdi_lock); 442 rw_init(&cwdi0.cwdi_lock);
440 443
441 /* Create the limits structures. */ 444 /* Create the limits structures. */
442 mutex_init(&limit0.pl_lock, MUTEX_DEFAULT, IPL_NONE); 445 mutex_init(&limit0.pl_lock, MUTEX_DEFAULT, IPL_NONE);
443 446
444 rlim = limit0.pl_rlimit; 447 rlim = limit0.pl_rlimit;
445 for (i = 0; i < __arraycount(limit0.pl_rlimit); i++) { 448 for (i = 0; i < __arraycount(limit0.pl_rlimit); i++) {
446 rlim[i].rlim_cur = RLIM_INFINITY; 449 rlim[i].rlim_cur = RLIM_INFINITY;
447 rlim[i].rlim_max = RLIM_INFINITY; 450 rlim[i].rlim_max = RLIM_INFINITY;
448 } 451 }
449 452
450 rlim[RLIMIT_NOFILE].rlim_max = maxfiles; 453 rlim[RLIMIT_NOFILE].rlim_max = maxfiles;
451 rlim[RLIMIT_NOFILE].rlim_cur = maxfiles < nofile ? maxfiles : nofile; 454 rlim[RLIMIT_NOFILE].rlim_cur = maxfiles < nofile ? maxfiles : nofile;
452 455
453 rlim[RLIMIT_NPROC].rlim_max = maxproc; 456 rlim[RLIMIT_NPROC].rlim_max = maxproc;
454 rlim[RLIMIT_NPROC].rlim_cur = maxproc < maxuprc ? maxproc : maxuprc; 457 rlim[RLIMIT_NPROC].rlim_cur = maxproc < maxuprc ? maxproc : maxuprc;
455 458
456 lim = MIN(VM_MAXUSER_ADDRESS, ctob((rlim_t)uvmexp.free)); 459 lim = MIN(VM_MAXUSER_ADDRESS, ctob((rlim_t)uvmexp.free));
457 rlim[RLIMIT_RSS].rlim_max = lim; 460 rlim[RLIMIT_RSS].rlim_max = lim;
458 rlim[RLIMIT_MEMLOCK].rlim_max = lim; 461 rlim[RLIMIT_MEMLOCK].rlim_max = lim;
459 rlim[RLIMIT_MEMLOCK].rlim_cur = lim / 3; 462 rlim[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
460 463
461 rlim[RLIMIT_NTHR].rlim_max = maxlwp; 464 rlim[RLIMIT_NTHR].rlim_max = maxlwp;
462 rlim[RLIMIT_NTHR].rlim_cur = maxlwp < maxuprc ? maxlwp : maxuprc; 465 rlim[RLIMIT_NTHR].rlim_cur = maxlwp < maxuprc ? maxlwp : maxuprc;
463 466
464 /* Note that default core name has zero length. */ 467 /* Note that default core name has zero length. */
465 limit0.pl_corename = defcorename; 468 limit0.pl_corename = defcorename;
466 limit0.pl_cnlen = 0; 469 limit0.pl_cnlen = 0;
467 limit0.pl_refcnt = 1; 470 limit0.pl_refcnt = 1;
468 limit0.pl_writeable = false; 471 limit0.pl_writeable = false;
469 limit0.pl_sv_limit = NULL; 472 limit0.pl_sv_limit = NULL;
470 473
471 /* Configure virtual memory system, set vm rlimits. */ 474 /* Configure virtual memory system, set vm rlimits. */
472 uvm_init_limits(p); 475 uvm_init_limits(p);
473 476
474 /* Initialize file descriptor table for proc0. */ 477 /* Initialize file descriptor table for proc0. */
475 fd_init(&filedesc0); 478 fd_init(&filedesc0);
476 479
477 /* 480 /*
478 * Initialize proc0's vmspace, which uses the kernel pmap. 481 * Initialize proc0's vmspace, which uses the kernel pmap.
479 * All kernel processes (which never have user space mappings) 482 * All kernel processes (which never have user space mappings)
480 * share proc0's vmspace, and thus, the kernel pmap. 483 * share proc0's vmspace, and thus, the kernel pmap.
481 */ 484 */
482 uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS), 485 uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
483 trunc_page(VM_MAXUSER_ADDRESS), 486 trunc_page(VM_MAXUSER_ADDRESS),
484#ifdef __USE_TOPDOWN_VM 487#ifdef __USE_TOPDOWN_VM
485 true 488 true
486#else 489#else
487 false 490 false
488#endif 491#endif
489 ); 492 );
490 493
491 /* Initialize signal state for proc0. XXX IPL_SCHED */ 494 /* Initialize signal state for proc0. XXX IPL_SCHED */
492 mutex_init(&p->p_sigacts->sa_mutex, MUTEX_DEFAULT, IPL_SCHED); 495 mutex_init(&p->p_sigacts->sa_mutex, MUTEX_DEFAULT, IPL_SCHED);
493 siginit(p); 496 siginit(p);
494 497
495 proc_initspecific(p); 498 proc_initspecific(p);
496 kdtrace_proc_ctor(NULL, p); 499 kdtrace_proc_ctor(NULL, p);
497} 500}
498 501
499/* 502/*
500 * Session reference counting. 503 * Session reference counting.
501 */ 504 */
502 505
503void 506void
504proc_sesshold(struct session *ss) 507proc_sesshold(struct session *ss)
505{ 508{
506 509
507 KASSERT(mutex_owned(proc_lock)); 510 KASSERT(mutex_owned(proc_lock));
508 ss->s_count++; 511 ss->s_count++;
509} 512}
510 513
511void 514void
512proc_sessrele(struct session *ss) 515proc_sessrele(struct session *ss)
513{ 516{
514 517
515 KASSERT(mutex_owned(proc_lock)); 518 KASSERT(mutex_owned(proc_lock));
516 /* 519 /*
517 * We keep the pgrp with the same id as the session in order to 520 * We keep the pgrp with the same id as the session in order to
518 * stop a process being given the same pid. Since the pgrp holds 521 * stop a process being given the same pid. Since the pgrp holds
519 * a reference to the session, it must be a 'zombie' pgrp by now. 522 * a reference to the session, it must be a 'zombie' pgrp by now.
520 */ 523 */
521 if (--ss->s_count == 0) { 524 if (--ss->s_count == 0) {
522 struct pgrp *pg; 525 struct pgrp *pg;
523 526
524 pg = pg_remove(ss->s_sid); 527 pg = pg_remove(ss->s_sid);
525 mutex_exit(proc_lock); 528 mutex_exit(proc_lock);
526 529
527 kmem_free(pg, sizeof(struct pgrp)); 530 kmem_free(pg, sizeof(struct pgrp));
528 kmem_free(ss, sizeof(struct session)); 531 kmem_free(ss, sizeof(struct session));
529 } else { 532 } else {
530 mutex_exit(proc_lock); 533 mutex_exit(proc_lock);
531 } 534 }
532} 535}
533 536
534/* 537/*
535 * Check that the specified process group is in the session of the 538 * Check that the specified process group is in the session of the
536 * specified process. 539 * specified process.
537 * Treats -ve ids as process ids. 540 * Treats -ve ids as process ids.
538 * Used to validate TIOCSPGRP requests. 541 * Used to validate TIOCSPGRP requests.
539 */ 542 */
540int 543int
541pgid_in_session(struct proc *p, pid_t pg_id) 544pgid_in_session(struct proc *p, pid_t pg_id)
542{ 545{
543 struct pgrp *pgrp; 546 struct pgrp *pgrp;
544 struct session *session; 547 struct session *session;
545 int error; 548 int error;
546 549
547 mutex_enter(proc_lock); 550 mutex_enter(proc_lock);
548 if (pg_id < 0) { 551 if (pg_id < 0) {
549 struct proc *p1 = proc_find(-pg_id); 552 struct proc *p1 = proc_find(-pg_id);
550 if (p1 == NULL) { 553 if (p1 == NULL) {
551 error = EINVAL; 554 error = EINVAL;
552 goto fail; 555 goto fail;
553 } 556 }
554 pgrp = p1->p_pgrp; 557 pgrp = p1->p_pgrp;
555 } else { 558 } else {
556 pgrp = pgrp_find(pg_id); 559 pgrp = pgrp_find(pg_id);
557 if (pgrp == NULL) { 560 if (pgrp == NULL) {
558 error = EINVAL; 561 error = EINVAL;
559 goto fail; 562 goto fail;
560 } 563 }
561 } 564 }
562 session = pgrp->pg_session; 565 session = pgrp->pg_session;
563 error = (session != p->p_pgrp->pg_session) ? EPERM : 0; 566 error = (session != p->p_pgrp->pg_session) ? EPERM : 0;
564fail: 567fail:
565 mutex_exit(proc_lock); 568 mutex_exit(proc_lock);
566 return error; 569 return error;
567} 570}
568 571
569/* 572/*
570 * p_inferior: is p an inferior of q? 573 * p_inferior: is p an inferior of q?
571 */ 574 */
572static inline bool 575static inline bool
573p_inferior(struct proc *p, struct proc *q) 576p_inferior(struct proc *p, struct proc *q)
574{ 577{
575 578
576 KASSERT(mutex_owned(proc_lock)); 579 KASSERT(mutex_owned(proc_lock));
577 580
578 for (; p != q; p = p->p_pptr) 581 for (; p != q; p = p->p_pptr)
579 if (p->p_pid == 0) 582 if (p->p_pid == 0)
580 return false; 583 return false;
581 return true; 584 return true;
582} 585}
583 586
584/* 587/*
585 * proc_find: locate a process by the ID. 588 * proc_find: locate a process by the ID.
586 * 589 *
587 * => Must be called with proc_lock held. 590 * => Must be called with proc_lock held.
588 */ 591 */
589proc_t * 592proc_t *
590proc_find_raw(pid_t pid) 593proc_find_raw(pid_t pid)
591{ 594{
592 struct pid_table *pt; 595 struct pid_table *pt;
593 proc_t *p; 596 proc_t *p;
594 597
595 KASSERT(mutex_owned(proc_lock)); 598 KASSERT(mutex_owned(proc_lock));
596 pt = &pid_table[pid & pid_tbl_mask]; 599 pt = &pid_table[pid & pid_tbl_mask];
597 p = pt->pt_proc; 600 p = pt->pt_proc;
598 if (__predict_false(!P_VALID(p) || pt->pt_pid != pid)) { 601 if (__predict_false(!P_VALID(p) || pt->pt_pid != pid)) {
599 return NULL; 602 return NULL;
600 } 603 }
601 return p; 604 return p;
602} 605}
603 606
604proc_t * 607proc_t *
605proc_find(pid_t pid) 608proc_find(pid_t pid)
606{ 609{
607 proc_t *p; 610 proc_t *p;
608 611
609 p = proc_find_raw(pid); 612 p = proc_find_raw(pid);
610 if (__predict_false(p == NULL)) { 613 if (__predict_false(p == NULL)) {
611 return NULL; 614 return NULL;
612 } 615 }
613 616
614 /* 617 /*
615 * Only allow live processes to be found by PID. 618 * Only allow live processes to be found by PID.
616 * XXX: p_stat might change, since unlocked. 619 * XXX: p_stat might change, since unlocked.
617 */ 620 */
618 if (__predict_true(p->p_stat == SACTIVE || p->p_stat == SSTOP)) { 621 if (__predict_true(p->p_stat == SACTIVE || p->p_stat == SSTOP)) {
619 return p; 622 return p;
620 } 623 }
621 return NULL; 624 return NULL;
622} 625}
623 626
624/* 627/*
625 * pgrp_find: locate a process group by the ID. 628 * pgrp_find: locate a process group by the ID.
626 * 629 *
627 * => Must be called with proc_lock held. 630 * => Must be called with proc_lock held.
628 */ 631 */
629struct pgrp * 632struct pgrp *
630pgrp_find(pid_t pgid) 633pgrp_find(pid_t pgid)
631{ 634{
632 struct pgrp *pg; 635 struct pgrp *pg;
633 636
634 KASSERT(mutex_owned(proc_lock)); 637 KASSERT(mutex_owned(proc_lock));
635 638
636 pg = pid_table[pgid & pid_tbl_mask].pt_pgrp; 639 pg = pid_table[pgid & pid_tbl_mask].pt_pgrp;
637 640
638 /* 641 /*
639 * Cannot look up a process group that only exists because the 642 * Cannot look up a process group that only exists because the
640 * session has not died yet (traditional). 643 * session has not died yet (traditional).
641 */ 644 */
642 if (pg == NULL || pg->pg_id != pgid || LIST_EMPTY(&pg->pg_members)) { 645 if (pg == NULL || pg->pg_id != pgid || LIST_EMPTY(&pg->pg_members)) {
643 return NULL; 646 return NULL;
644 } 647 }
645 return pg; 648 return pg;
646} 649}
647 650
648static void 651static void
649expand_pid_table(void) 652expand_pid_table(void)
650{ 653{
651 size_t pt_size, tsz; 654 size_t pt_size, tsz;
652 struct pid_table *n_pt, *new_pt; 655 struct pid_table *n_pt, *new_pt;
653 struct proc *proc; 656 struct proc *proc;
654 struct pgrp *pgrp; 657 struct pgrp *pgrp;
655 pid_t pid, rpid; 658 pid_t pid, rpid;
656 u_int i; 659 u_int i;
657 uint new_pt_mask; 660 uint new_pt_mask;
658 661
659 pt_size = pid_tbl_mask + 1; 662 pt_size = pid_tbl_mask + 1;
660 tsz = pt_size * 2 * sizeof(struct pid_table); 663 tsz = pt_size * 2 * sizeof(struct pid_table);
661 new_pt = kmem_alloc(tsz, KM_SLEEP); 664 new_pt = kmem_alloc(tsz, KM_SLEEP);
662 new_pt_mask = pt_size * 2 - 1; 665 new_pt_mask = pt_size * 2 - 1;
663 666
664 mutex_enter(proc_lock); 667 mutex_enter(proc_lock);
665 if (pt_size != pid_tbl_mask + 1) { 668 if (pt_size != pid_tbl_mask + 1) {
666 /* Another process beat us to it... */ 669 /* Another process beat us to it... */
667 mutex_exit(proc_lock); 670 mutex_exit(proc_lock);
668 kmem_free(new_pt, tsz); 671 kmem_free(new_pt, tsz);
669 return; 672 return;
670 } 673 }
671 674
672 /* 675 /*
673 * Copy entries from old table into new one. 676 * Copy entries from old table into new one.
674 * If 'pid' is 'odd' we need to place in the upper half, 677 * If 'pid' is 'odd' we need to place in the upper half,
675 * even pid's to the lower half. 678 * even pid's to the lower half.
676 * Free items stay in the low half so we don't have to 679 * Free items stay in the low half so we don't have to
677 * fixup the reference to them. 680 * fixup the reference to them.
678 * We stuff free items on the front of the freelist 681 * We stuff free items on the front of the freelist
679 * because we can't write to unmodified entries. 682 * because we can't write to unmodified entries.
680 * Processing the table backwards maintains a semblance 683 * Processing the table backwards maintains a semblance
681 * of issuing pid numbers that increase with time. 684 * of issuing pid numbers that increase with time.
682 */ 685 */
683 i = pt_size - 1; 686 i = pt_size - 1;
684 n_pt = new_pt + i; 687 n_pt = new_pt + i;
685 for (; ; i--, n_pt--) { 688 for (; ; i--, n_pt--) {
686 proc = pid_table[i].pt_proc; 689 proc = pid_table[i].pt_proc;
687 pgrp = pid_table[i].pt_pgrp; 690 pgrp = pid_table[i].pt_pgrp;
688 if (!P_VALID(proc)) { 691 if (!P_VALID(proc)) {
689 /* Up 'use count' so that link is valid */ 692 /* Up 'use count' so that link is valid */
690 pid = (P_NEXT(proc) + pt_size) & ~pt_size; 693 pid = (P_NEXT(proc) + pt_size) & ~pt_size;
691 rpid = 0; 694 rpid = 0;
692 proc = P_FREE(pid); 695 proc = P_FREE(pid);
693 if (pgrp) 696 if (pgrp)
694 pid = pgrp->pg_id; 697 pid = pgrp->pg_id;
695 } else { 698 } else {
696 pid = pid_table[i].pt_pid; 699 pid = pid_table[i].pt_pid;
697 rpid = pid; 700 rpid = pid;
698 } 701 }
699 702
700 /* Save entry in appropriate half of table */ 703 /* Save entry in appropriate half of table */
701 n_pt[pid & pt_size].pt_proc = proc; 704 n_pt[pid & pt_size].pt_proc = proc;
702 n_pt[pid & pt_size].pt_pgrp = pgrp; 705 n_pt[pid & pt_size].pt_pgrp = pgrp;
703 n_pt[pid & pt_size].pt_pid = rpid; 706 n_pt[pid & pt_size].pt_pid = rpid;
704 707
705 /* Put other piece on start of free list */ 708 /* Put other piece on start of free list */
706 pid = (pid ^ pt_size) & ~pid_tbl_mask; 709 pid = (pid ^ pt_size) & ~pid_tbl_mask;
707 n_pt[pid & pt_size].pt_proc = 710 n_pt[pid & pt_size].pt_proc =
708 P_FREE((pid & ~pt_size) | next_free_pt); 711 P_FREE((pid & ~pt_size) | next_free_pt);
709 n_pt[pid & pt_size].pt_pgrp = 0; 712 n_pt[pid & pt_size].pt_pgrp = 0;
710 n_pt[pid & pt_size].pt_pid = 0; 713 n_pt[pid & pt_size].pt_pid = 0;
711 714
712 next_free_pt = i | (pid & pt_size); 715 next_free_pt = i | (pid & pt_size);
713 if (i == 0) 716 if (i == 0)
714 break; 717 break;
715 } 718 }
716 719
717 /* Save old table size and switch tables */ 720 /* Save old table size and switch tables */
718 tsz = pt_size * sizeof(struct pid_table); 721 tsz = pt_size * sizeof(struct pid_table);
719 n_pt = pid_table; 722 n_pt = pid_table;
720 pid_table = new_pt; 723 pid_table = new_pt;
721 pid_tbl_mask = new_pt_mask; 724 pid_tbl_mask = new_pt_mask;
722 725
723 /* 726 /*
724 * pid_max starts as PID_MAX (= 30000), once we have 16384 727 * pid_max starts as PID_MAX (= 30000), once we have 16384
725 * allocated pids we need it to be larger! 728 * allocated pids we need it to be larger!
726 */ 729 */
727 if (pid_tbl_mask > PID_MAX) { 730 if (pid_tbl_mask > PID_MAX) {
728 pid_max = pid_tbl_mask * 2 + 1; 731 pid_max = pid_tbl_mask * 2 + 1;
729 pid_alloc_lim |= pid_alloc_lim << 1; 732 pid_alloc_lim |= pid_alloc_lim << 1;
730 } else 733 } else
731 pid_alloc_lim <<= 1; /* doubles number of free slots... */ 734 pid_alloc_lim <<= 1; /* doubles number of free slots... */
732 735
733 mutex_exit(proc_lock); 736 mutex_exit(proc_lock);
734 kmem_free(n_pt, tsz); 737 kmem_free(n_pt, tsz);
735} 738}
736 739
737struct proc * 740struct proc *
738proc_alloc(void) 741proc_alloc(void)
739{ 742{
740 struct proc *p; 743 struct proc *p;
741 744
742 p = pool_cache_get(proc_cache, PR_WAITOK); 745 p = pool_cache_get(proc_cache, PR_WAITOK);
743 p->p_stat = SIDL; /* protect against others */ 746 p->p_stat = SIDL; /* protect against others */
744 proc_initspecific(p); 747 proc_initspecific(p);
745 kdtrace_proc_ctor(NULL, p); 748 kdtrace_proc_ctor(NULL, p);
746 p->p_pid = -1; 749 p->p_pid = -1;
747 proc_alloc_pid(p); 750 proc_alloc_pid(p);
748 return p; 751 return p;
749} 752}
750 753
751/* 754/*
752 * proc_alloc_pid: allocate PID and record the given proc 'p' so that 755 * proc_alloc_pid: allocate PID and record the given proc 'p' so that
753 * proc_find_raw() can find it by the PID. 756 * proc_find_raw() can find it by the PID.
754 */ 757 */
755 758
756pid_t 759pid_t
757proc_alloc_pid(struct proc *p) 760proc_alloc_pid(struct proc *p)
758{ 761{
759 struct pid_table *pt; 762 struct pid_table *pt;
760 pid_t pid; 763 pid_t pid;
761 int nxt; 764 int nxt;
762 765
763 for (;;expand_pid_table()) { 766 for (;;expand_pid_table()) {
764 if (__predict_false(pid_alloc_cnt >= pid_alloc_lim)) 767 if (__predict_false(pid_alloc_cnt >= pid_alloc_lim))
765 /* ensure pids cycle through 2000+ values */ 768 /* ensure pids cycle through 2000+ values */
766 continue; 769 continue;
767 mutex_enter(proc_lock); 770 mutex_enter(proc_lock);
768 pt = &pid_table[next_free_pt]; 771 pt = &pid_table[next_free_pt];
769#ifdef DIAGNOSTIC 772#ifdef DIAGNOSTIC
770 if (__predict_false(P_VALID(pt->pt_proc) || pt->pt_pgrp)) 773 if (__predict_false(P_VALID(pt->pt_proc) || pt->pt_pgrp))
771 panic("proc_alloc: slot busy"); 774 panic("proc_alloc: slot busy");
772#endif 775#endif
773 nxt = P_NEXT(pt->pt_proc); 776 nxt = P_NEXT(pt->pt_proc);
774 if (nxt & pid_tbl_mask) 777 if (nxt & pid_tbl_mask)
775 break; 778 break;
776 /* Table full - expand (NB last entry not used....) */ 779 /* Table full - expand (NB last entry not used....) */
777 mutex_exit(proc_lock); 780 mutex_exit(proc_lock);
778 } 781 }
779 782
780 /* pid is 'saved use count' + 'size' + entry */ 783 /* pid is 'saved use count' + 'size' + entry */
781 pid = (nxt & ~pid_tbl_mask) + pid_tbl_mask + 1 + next_free_pt; 784 pid = (nxt & ~pid_tbl_mask) + pid_tbl_mask + 1 + next_free_pt;
782 if ((uint)pid > (uint)pid_max) 785 if ((uint)pid > (uint)pid_max)
783 pid &= pid_tbl_mask; 786 pid &= pid_tbl_mask;
784 next_free_pt = nxt & pid_tbl_mask; 787 next_free_pt = nxt & pid_tbl_mask;
785 788
786 /* Grab table slot */ 789 /* Grab table slot */
787 pt->pt_proc = p; 790 pt->pt_proc = p;
788 791
789 KASSERT(pt->pt_pid == 0); 792 KASSERT(pt->pt_pid == 0);
790 pt->pt_pid = pid; 793 pt->pt_pid = pid;
791 if (p->p_pid == -1) { 794 if (p->p_pid == -1) {
792 p->p_pid = pid; 795 p->p_pid = pid;
793 } 796 }
794 pid_alloc_cnt++; 797 pid_alloc_cnt++;
795 mutex_exit(proc_lock); 798 mutex_exit(proc_lock);
796 799
797 return pid; 800 return pid;
798} 801}
799 802
800/* 803/*
801 * Free a process id - called from proc_free (in kern_exit.c) 804 * Free a process id - called from proc_free (in kern_exit.c)
802 * 805 *
803 * Called with the proc_lock held. 806 * Called with the proc_lock held.
804 */ 807 */
805void 808void
806proc_free_pid(pid_t pid) 809proc_free_pid(pid_t pid)
807{ 810{
808 struct pid_table *pt; 811 struct pid_table *pt;
809 812
810 KASSERT(mutex_owned(proc_lock)); 813 KASSERT(mutex_owned(proc_lock));
811 814
812 pt = &pid_table[pid & pid_tbl_mask]; 815 pt = &pid_table[pid & pid_tbl_mask];
813 816
814 /* save pid use count in slot */ 817 /* save pid use count in slot */
815 pt->pt_proc = P_FREE(pid & ~pid_tbl_mask); 818 pt->pt_proc = P_FREE(pid & ~pid_tbl_mask);
816 KASSERT(pt->pt_pid == pid); 819 KASSERT(pt->pt_pid == pid);
817 pt->pt_pid = 0; 820 pt->pt_pid = 0;
818 821
819 if (pt->pt_pgrp == NULL) { 822 if (pt->pt_pgrp == NULL) {
820 /* link last freed entry onto ours */ 823 /* link last freed entry onto ours */
821 pid &= pid_tbl_mask; 824 pid &= pid_tbl_mask;
822 pt = &pid_table[last_free_pt]; 825 pt = &pid_table[last_free_pt];
823 pt->pt_proc = P_FREE(P_NEXT(pt->pt_proc) | pid); 826 pt->pt_proc = P_FREE(P_NEXT(pt->pt_proc) | pid);
824 pt->pt_pid = 0; 827 pt->pt_pid = 0;
825 last_free_pt = pid; 828 last_free_pt = pid;
826 pid_alloc_cnt--; 829 pid_alloc_cnt--;
827 } 830 }
828 831
829 atomic_dec_uint(&nprocs); 832 atomic_dec_uint(&nprocs);
830} 833}
831 834
832void 835void
833proc_free_mem(struct proc *p) 836proc_free_mem(struct proc *p)
834{ 837{
835 838
836 kdtrace_proc_dtor(NULL, p); 839 kdtrace_proc_dtor(NULL, p);
837 pool_cache_put(proc_cache, p); 840 pool_cache_put(proc_cache, p);
838} 841}
839 842
840/* 843/*
841 * proc_enterpgrp: move p to a new or existing process group (and session). 844 * proc_enterpgrp: move p to a new or existing process group (and session).
842 * 845 *
843 * If we are creating a new pgrp, the pgid should equal 846 * If we are creating a new pgrp, the pgid should equal
844 * the calling process' pid. 847 * the calling process' pid.
845 * If is only valid to enter a process group that is in the session 848 * If is only valid to enter a process group that is in the session
846 * of the process. 849 * of the process.
847 * Also mksess should only be set if we are creating a process group 850 * Also mksess should only be set if we are creating a process group
848 * 851 *
849 * Only called from sys_setsid, sys_setpgid and posix_spawn/spawn_return. 852 * Only called from sys_setsid, sys_setpgid and posix_spawn/spawn_return.
850 */ 853 */
851int 854int
852proc_enterpgrp(struct proc *curp, pid_t pid, pid_t pgid, bool mksess) 855proc_enterpgrp(struct proc *curp, pid_t pid, pid_t pgid, bool mksess)
853{ 856{
854 struct pgrp *new_pgrp, *pgrp; 857 struct pgrp *new_pgrp, *pgrp;
855 struct session *sess; 858 struct session *sess;
856 struct proc *p; 859 struct proc *p;
857 int rval; 860 int rval;
858 pid_t pg_id = NO_PGID; 861 pid_t pg_id = NO_PGID;
859 862
860 sess = mksess ? kmem_alloc(sizeof(*sess), KM_SLEEP) : NULL; 863 sess = mksess ? kmem_alloc(sizeof(*sess), KM_SLEEP) : NULL;
861 864
862 /* Allocate data areas we might need before doing any validity checks */ 865 /* Allocate data areas we might need before doing any validity checks */
863 mutex_enter(proc_lock); /* Because pid_table might change */ 866 mutex_enter(proc_lock); /* Because pid_table might change */
864 if (pid_table[pgid & pid_tbl_mask].pt_pgrp == 0) { 867 if (pid_table[pgid & pid_tbl_mask].pt_pgrp == 0) {
865 mutex_exit(proc_lock); 868 mutex_exit(proc_lock);
866 new_pgrp = kmem_alloc(sizeof(*new_pgrp), KM_SLEEP); 869 new_pgrp = kmem_alloc(sizeof(*new_pgrp), KM_SLEEP);
867 mutex_enter(proc_lock); 870 mutex_enter(proc_lock);
868 } else 871 } else
869 new_pgrp = NULL; 872 new_pgrp = NULL;
870 rval = EPERM; /* most common error (to save typing) */ 873 rval = EPERM; /* most common error (to save typing) */
871 874
872 /* Check pgrp exists or can be created */ 875 /* Check pgrp exists or can be created */
873 pgrp = pid_table[pgid & pid_tbl_mask].pt_pgrp; 876 pgrp = pid_table[pgid & pid_tbl_mask].pt_pgrp;
874 if (pgrp != NULL && pgrp->pg_id != pgid) 877 if (pgrp != NULL && pgrp->pg_id != pgid)
875 goto done; 878 goto done;
876 879
877 /* Can only set another process under restricted circumstances. */ 880 /* Can only set another process under restricted circumstances. */
878 if (pid != curp->p_pid) { 881 if (pid != curp->p_pid) {
879 /* Must exist and be one of our children... */ 882 /* Must exist and be one of our children... */
880 p = proc_find(pid); 883 p = proc_find(pid);
881 if (p == NULL || !p_inferior(p, curp)) { 884 if (p == NULL || !p_inferior(p, curp)) {
882 rval = ESRCH; 885 rval = ESRCH;
883 goto done; 886 goto done;
884 } 887 }
885 /* ... in the same session... */ 888 /* ... in the same session... */
886 if (sess != NULL || p->p_session != curp->p_session) 889 if (sess != NULL || p->p_session != curp->p_session)
887 goto done; 890 goto done;
888 /* ... existing pgid must be in same session ... */ 891 /* ... existing pgid must be in same session ... */
889 if (pgrp != NULL && pgrp->pg_session != p->p_session) 892 if (pgrp != NULL && pgrp->pg_session != p->p_session)
890 goto done; 893 goto done;
891 /* ... and not done an exec. */ 894 /* ... and not done an exec. */
892 if (p->p_flag & PK_EXEC) { 895 if (p->p_flag & PK_EXEC) {
893 rval = EACCES; 896 rval = EACCES;
894 goto done; 897 goto done;
895 } 898 }
896 } else { 899 } else {
897 /* ... setsid() cannot re-enter a pgrp */ 900 /* ... setsid() cannot re-enter a pgrp */
898 if (mksess && (curp->p_pgid == curp->p_pid || 901 if (mksess && (curp->p_pgid == curp->p_pid ||
899 pgrp_find(curp->p_pid))) 902 pgrp_find(curp->p_pid)))
900 goto done; 903 goto done;
901 p = curp; 904 p = curp;
902 } 905 }
903 906
904 /* Changing the process group/session of a session 907 /* Changing the process group/session of a session
905 leader is definitely off limits. */ 908 leader is definitely off limits. */
906 if (SESS_LEADER(p)) { 909 if (SESS_LEADER(p)) {
907 if (sess == NULL && p->p_pgrp == pgrp) 910 if (sess == NULL && p->p_pgrp == pgrp)
908 /* unless it's a definite noop */ 911 /* unless it's a definite noop */
909 rval = 0; 912 rval = 0;
910 goto done; 913 goto done;
911 } 914 }
912 915
913 /* Can only create a process group with id of process */ 916 /* Can only create a process group with id of process */
914 if (pgrp == NULL && pgid != pid) 917 if (pgrp == NULL && pgid != pid)
915 goto done; 918 goto done;
916 919
917 /* Can only create a session if creating pgrp */ 920 /* Can only create a session if creating pgrp */
918 if (sess != NULL && pgrp != NULL) 921 if (sess != NULL && pgrp != NULL)
919 goto done; 922 goto done;
920 923
921 /* Check we allocated memory for a pgrp... */ 924 /* Check we allocated memory for a pgrp... */
922 if (pgrp == NULL && new_pgrp == NULL) 925 if (pgrp == NULL && new_pgrp == NULL)
923 goto done; 926 goto done;
924 927
925 /* Don't attach to 'zombie' pgrp */ 928 /* Don't attach to 'zombie' pgrp */
926 if (pgrp != NULL && LIST_EMPTY(&pgrp->pg_members)) 929 if (pgrp != NULL && LIST_EMPTY(&pgrp->pg_members))
927 goto done; 930 goto done;
928 931
929 /* Expect to succeed now */ 932 /* Expect to succeed now */
930 rval = 0; 933 rval = 0;
931 934
932 if (pgrp == p->p_pgrp) 935 if (pgrp == p->p_pgrp)
933 /* nothing to do */ 936 /* nothing to do */
934 goto done; 937 goto done;
935 938
936 /* Ok all setup, link up required structures */ 939 /* Ok all setup, link up required structures */
937 940
938 if (pgrp == NULL) { 941 if (pgrp == NULL) {
939 pgrp = new_pgrp; 942 pgrp = new_pgrp;
940 new_pgrp = NULL; 943 new_pgrp = NULL;
941 if (sess != NULL) { 944 if (sess != NULL) {
942 sess->s_sid = p->p_pid; 945 sess->s_sid = p->p_pid;
943 sess->s_leader = p; 946 sess->s_leader = p;
944 sess->s_count = 1; 947 sess->s_count = 1;
945 sess->s_ttyvp = NULL; 948 sess->s_ttyvp = NULL;
946 sess->s_ttyp = NULL; 949 sess->s_ttyp = NULL;
947 sess->s_flags = p->p_session->s_flags & ~S_LOGIN_SET; 950 sess->s_flags = p->p_session->s_flags & ~S_LOGIN_SET;
948 memcpy(sess->s_login, p->p_session->s_login, 951 memcpy(sess->s_login, p->p_session->s_login,
949 sizeof(sess->s_login)); 952 sizeof(sess->s_login));
950 p->p_lflag &= ~PL_CONTROLT; 953 p->p_lflag &= ~PL_CONTROLT;
951 } else { 954 } else {
952 sess = p->p_pgrp->pg_session; 955 sess = p->p_pgrp->pg_session;
953 proc_sesshold(sess); 956 proc_sesshold(sess);
954 } 957 }
955 pgrp->pg_session = sess; 958 pgrp->pg_session = sess;
956 sess = NULL; 959 sess = NULL;
957 960
958 pgrp->pg_id = pgid; 961 pgrp->pg_id = pgid;
959 LIST_INIT(&pgrp->pg_members); 962 LIST_INIT(&pgrp->pg_members);
960#ifdef DIAGNOSTIC 963#ifdef DIAGNOSTIC
961 if (__predict_false(pid_table[pgid & pid_tbl_mask].pt_pgrp)) 964 if (__predict_false(pid_table[pgid & pid_tbl_mask].pt_pgrp))
962 panic("enterpgrp: pgrp table slot in use"); 965 panic("enterpgrp: pgrp table slot in use");
963 if (__predict_false(mksess && p != curp)) 966 if (__predict_false(mksess && p != curp))
964 panic("enterpgrp: mksession and p != curproc"); 967 panic("enterpgrp: mksession and p != curproc");
965#endif 968#endif
966 pid_table[pgid & pid_tbl_mask].pt_pgrp = pgrp; 969 pid_table[pgid & pid_tbl_mask].pt_pgrp = pgrp;
967 pgrp->pg_jobc = 0; 970 pgrp->pg_jobc = 0;
968 } 971 }
969 972
970 /* 973 /*
971 * Adjust eligibility of affected pgrps to participate in job control. 974 * Adjust eligibility of affected pgrps to participate in job control.
972 * Increment eligibility counts before decrementing, otherwise we 975 * Increment eligibility counts before decrementing, otherwise we
973 * could reach 0 spuriously during the first call. 976 * could reach 0 spuriously during the first call.
974 */ 977 */
975 fixjobc(p, pgrp, 1); 978 fixjobc(p, pgrp, 1);
976 fixjobc(p, p->p_pgrp, 0); 979 fixjobc(p, p->p_pgrp, 0);
977 980
978 /* Interlock with ttread(). */ 981 /* Interlock with ttread(). */
979 mutex_spin_enter(&tty_lock); 982 mutex_spin_enter(&tty_lock);
980 983
981 /* Move process to requested group. */ 984 /* Move process to requested group. */
982 LIST_REMOVE(p, p_pglist); 985 LIST_REMOVE(p, p_pglist);
983 if (LIST_EMPTY(&p->p_pgrp->pg_members)) 986 if (LIST_EMPTY(&p->p_pgrp->pg_members))
984 /* defer delete until we've dumped the lock */ 987 /* defer delete until we've dumped the lock */
985 pg_id = p->p_pgrp->pg_id; 988 pg_id = p->p_pgrp->pg_id;
986 p->p_pgrp = pgrp; 989 p->p_pgrp = pgrp;
987 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); 990 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
988 991
989 /* Done with the swap; we can release the tty mutex. */ 992 /* Done with the swap; we can release the tty mutex. */
990 mutex_spin_exit(&tty_lock); 993 mutex_spin_exit(&tty_lock);
991 994
992 done: 995 done:
993 if (pg_id != NO_PGID) { 996 if (pg_id != NO_PGID) {
994 /* Releases proc_lock. */ 997 /* Releases proc_lock. */
995 pg_delete(pg_id); 998 pg_delete(pg_id);
996 } else { 999 } else {
997 mutex_exit(proc_lock); 1000 mutex_exit(proc_lock);
998 } 1001 }
999 if (sess != NULL) 1002 if (sess != NULL)
1000 kmem_free(sess, sizeof(*sess)); 1003 kmem_free(sess, sizeof(*sess));
1001 if (new_pgrp != NULL) 1004 if (new_pgrp != NULL)
1002 kmem_free(new_pgrp, sizeof(*new_pgrp)); 1005 kmem_free(new_pgrp, sizeof(*new_pgrp));
1003#ifdef DEBUG_PGRP 1006#ifdef DEBUG_PGRP
1004 if (__predict_false(rval)) 1007 if (__predict_false(rval))
1005 printf("enterpgrp(%d,%d,%d), curproc %d, rval %d\n", 1008 printf("enterpgrp(%d,%d,%d), curproc %d, rval %d\n",
1006 pid, pgid, mksess, curp->p_pid, rval); 1009 pid, pgid, mksess, curp->p_pid, rval);
1007#endif 1010#endif
1008 return rval; 1011 return rval;
1009} 1012}
1010 1013
1011/* 1014/*
1012 * proc_leavepgrp: remove a process from its process group. 1015 * proc_leavepgrp: remove a process from its process group.
1013 * => must be called with the proc_lock held, which will be released; 1016 * => must be called with the proc_lock held, which will be released;
1014 */ 1017 */
1015void 1018void
1016proc_leavepgrp(struct proc *p) 1019proc_leavepgrp(struct proc *p)
1017{ 1020{
1018 struct pgrp *pgrp; 1021 struct pgrp *pgrp;
1019 1022
1020 KASSERT(mutex_owned(proc_lock)); 1023 KASSERT(mutex_owned(proc_lock));
1021 1024
1022 /* Interlock with ttread() */ 1025 /* Interlock with ttread() */
1023 mutex_spin_enter(&tty_lock); 1026 mutex_spin_enter(&tty_lock);
1024 pgrp = p->p_pgrp; 1027 pgrp = p->p_pgrp;
1025 LIST_REMOVE(p, p_pglist); 1028 LIST_REMOVE(p, p_pglist);
1026 p->p_pgrp = NULL; 1029 p->p_pgrp = NULL;
1027 mutex_spin_exit(&tty_lock); 1030 mutex_spin_exit(&tty_lock);
1028 1031
1029 if (LIST_EMPTY(&pgrp->pg_members)) { 1032 if (LIST_EMPTY(&pgrp->pg_members)) {
1030 /* Releases proc_lock. */ 1033 /* Releases proc_lock. */
1031 pg_delete(pgrp->pg_id); 1034 pg_delete(pgrp->pg_id);
1032 } else { 1035 } else {
1033 mutex_exit(proc_lock); 1036 mutex_exit(proc_lock);
1034 } 1037 }
1035} 1038}
1036 1039
1037/* 1040/*
1038 * pg_remove: remove a process group from the table. 1041 * pg_remove: remove a process group from the table.
1039 * => must be called with the proc_lock held; 1042 * => must be called with the proc_lock held;
1040 * => returns process group to free; 1043 * => returns process group to free;
1041 */ 1044 */
1042static struct pgrp * 1045static struct pgrp *
1043pg_remove(pid_t pg_id) 1046pg_remove(pid_t pg_id)
1044{ 1047{
1045 struct pgrp *pgrp; 1048 struct pgrp *pgrp;
1046 struct pid_table *pt; 1049 struct pid_table *pt;
1047 1050
1048 KASSERT(mutex_owned(proc_lock)); 1051 KASSERT(mutex_owned(proc_lock));
1049 1052
1050 pt = &pid_table[pg_id & pid_tbl_mask]; 1053 pt = &pid_table[pg_id & pid_tbl_mask];
1051 pgrp = pt->pt_pgrp; 1054 pgrp = pt->pt_pgrp;
1052 1055
1053 KASSERT(pgrp != NULL); 1056 KASSERT(pgrp != NULL);
1054 KASSERT(pgrp->pg_id == pg_id); 1057 KASSERT(pgrp->pg_id == pg_id);
1055 KASSERT(LIST_EMPTY(&pgrp->pg_members)); 1058 KASSERT(LIST_EMPTY(&pgrp->pg_members));
1056 1059
1057 pt->pt_pgrp = NULL; 1060 pt->pt_pgrp = NULL;
1058 1061
1059 if (!P_VALID(pt->pt_proc)) { 1062 if (!P_VALID(pt->pt_proc)) {
1060 /* Orphaned pgrp, put slot onto free list. */ 1063 /* Orphaned pgrp, put slot onto free list. */
1061 KASSERT((P_NEXT(pt->pt_proc) & pid_tbl_mask) == 0); 1064 KASSERT((P_NEXT(pt->pt_proc) & pid_tbl_mask) == 0);
1062 pg_id &= pid_tbl_mask; 1065 pg_id &= pid_tbl_mask;
1063 pt = &pid_table[last_free_pt]; 1066 pt = &pid_table[last_free_pt];
1064 pt->pt_proc = P_FREE(P_NEXT(pt->pt_proc) | pg_id); 1067 pt->pt_proc = P_FREE(P_NEXT(pt->pt_proc) | pg_id);
1065 KASSERT(pt->pt_pid == 0); 1068 KASSERT(pt->pt_pid == 0);
1066 last_free_pt = pg_id; 1069 last_free_pt = pg_id;
1067 pid_alloc_cnt--; 1070 pid_alloc_cnt--;
1068 } 1071 }
1069 return pgrp; 1072 return pgrp;
1070} 1073}
1071 1074
1072/* 1075/*
1073 * pg_delete: delete and free a process group. 1076 * pg_delete: delete and free a process group.
1074 * => must be called with the proc_lock held, which will be released. 1077 * => must be called with the proc_lock held, which will be released.
1075 */ 1078 */
1076static void 1079static void
1077pg_delete(pid_t pg_id) 1080pg_delete(pid_t pg_id)
1078{ 1081{
1079 struct pgrp *pg; 1082 struct pgrp *pg;
1080 struct tty *ttyp; 1083 struct tty *ttyp;
1081 struct session *ss; 1084 struct session *ss;
1082 1085
1083 KASSERT(mutex_owned(proc_lock)); 1086 KASSERT(mutex_owned(proc_lock));
1084 1087
1085 pg = pid_table[pg_id & pid_tbl_mask].pt_pgrp; 1088 pg = pid_table[pg_id & pid_tbl_mask].pt_pgrp;
1086 if (pg == NULL || pg->pg_id != pg_id || !LIST_EMPTY(&pg->pg_members)) { 1089 if (pg == NULL || pg->pg_id != pg_id || !LIST_EMPTY(&pg->pg_members)) {
1087 mutex_exit(proc_lock); 1090 mutex_exit(proc_lock);
1088 return; 1091 return;
1089 } 1092 }
1090 1093
1091 ss = pg->pg_session; 1094 ss = pg->pg_session;
1092 1095
1093 /* Remove reference (if any) from tty to this process group */ 1096 /* Remove reference (if any) from tty to this process group */
1094 mutex_spin_enter(&tty_lock); 1097 mutex_spin_enter(&tty_lock);
1095 ttyp = ss->s_ttyp; 1098 ttyp = ss->s_ttyp;
1096 if (ttyp != NULL && ttyp->t_pgrp == pg) { 1099 if (ttyp != NULL && ttyp->t_pgrp == pg) {
1097 ttyp->t_pgrp = NULL; 1100 ttyp->t_pgrp = NULL;
1098 KASSERT(ttyp->t_session == ss); 1101 KASSERT(ttyp->t_session == ss);
1099 } 1102 }
1100 mutex_spin_exit(&tty_lock); 1103 mutex_spin_exit(&tty_lock);
1101 1104
1102 /* 1105 /*
1103 * The leading process group in a session is freed by proc_sessrele(), 1106 * The leading process group in a session is freed by proc_sessrele(),
1104 * if last reference. Note: proc_sessrele() releases proc_lock. 1107 * if last reference. Note: proc_sessrele() releases proc_lock.
1105 */ 1108 */