Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/proc/prvnops.c
+++ new/usr/src/uts/common/fs/proc/prvnops.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 - * Copyright (c) 2017, Joyent, Inc.
24 + * Copyright (c) 2018, Joyent, Inc.
25 25 * Copyright (c) 2017 by Delphix. All rights reserved.
26 26 */
27 27
28 28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 -/* All Rights Reserved */
29 +/* All Rights Reserved */
30 30
31 31 #include <sys/types.h>
32 32 #include <sys/param.h>
33 33 #include <sys/time.h>
34 34 #include <sys/cred.h>
35 35 #include <sys/policy.h>
36 36 #include <sys/debug.h>
37 37 #include <sys/dirent.h>
38 38 #include <sys/errno.h>
39 39 #include <sys/file.h>
40 40 #include <sys/inline.h>
41 41 #include <sys/kmem.h>
42 42 #include <sys/pathname.h>
43 43 #include <sys/proc.h>
44 44 #include <sys/brand.h>
45 45 #include <sys/signal.h>
46 46 #include <sys/stat.h>
47 47 #include <sys/sysmacros.h>
48 48 #include <sys/systm.h>
49 49 #include <sys/zone.h>
50 50 #include <sys/uio.h>
51 51 #include <sys/var.h>
52 52 #include <sys/mode.h>
53 53 #include <sys/poll.h>
54 54 #include <sys/user.h>
55 55 #include <sys/vfs.h>
56 56 #include <sys/vfs_opreg.h>
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
57 57 #include <sys/gfs.h>
58 58 #include <sys/vnode.h>
59 59 #include <sys/fault.h>
60 60 #include <sys/syscall.h>
61 61 #include <sys/procfs.h>
62 62 #include <sys/atomic.h>
63 63 #include <sys/cmn_err.h>
64 64 #include <sys/contract_impl.h>
65 65 #include <sys/ctfs.h>
66 66 #include <sys/avl.h>
67 +#include <sys/ctype.h>
67 68 #include <fs/fs_subr.h>
68 69 #include <vm/rm.h>
69 70 #include <vm/as.h>
70 71 #include <vm/seg.h>
71 72 #include <vm/seg_vn.h>
72 73 #include <vm/hat.h>
73 74 #include <fs/proc/prdata.h>
74 75 #if defined(__sparc)
75 76 #include <sys/regset.h>
76 77 #endif
77 78 #if defined(__x86)
78 79 #include <sys/sysi86.h>
79 80 #endif
80 81
81 82 /*
82 83 * Created by prinit.
83 84 */
84 85 vnodeops_t *prvnodeops;
85 86
86 87 /*
87 88 * Directory characteristics (patterned after the s5 file system).
88 89 */
89 90 #define PRROOTINO 2
90 91
91 92 #define PRDIRSIZE 14
92 93 struct prdirect {
93 94 ushort_t d_ino;
94 95 char d_name[PRDIRSIZE];
95 96 };
96 97
97 98 #define PRSDSIZE (sizeof (struct prdirect))
98 99
99 100 /*
100 101 * Directory characteristics.
101 102 */
102 103 typedef struct prdirent {
103 104 ino64_t d_ino; /* "inode number" of entry */
104 105 off64_t d_off; /* offset of disk directory entry */
105 106 unsigned short d_reclen; /* length of this record */
106 107 char d_name[14]; /* name of file */
107 108 } prdirent_t;
108 109
109 110 /*
110 111 * Contents of a /proc/<pid> directory.
111 112 * Reuse d_ino field for the /proc file type.
112 113 */
113 114 static prdirent_t piddir[] = {
114 115 { PR_PIDDIR, 1 * sizeof (prdirent_t), sizeof (prdirent_t),
115 116 "." },
116 117 { PR_PROCDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t),
117 118 ".." },
118 119 { PR_AS, 3 * sizeof (prdirent_t), sizeof (prdirent_t),
119 120 "as" },
120 121 { PR_CTL, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
121 122 "ctl" },
122 123 { PR_STATUS, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
123 124 "status" },
124 125 { PR_LSTATUS, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
125 126 "lstatus" },
126 127 { PR_PSINFO, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
127 128 "psinfo" },
128 129 { PR_LPSINFO, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
129 130 "lpsinfo" },
130 131 { PR_MAP, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
131 132 "map" },
132 133 { PR_RMAP, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
133 134 "rmap" },
134 135 { PR_XMAP, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
135 136 "xmap" },
136 137 { PR_CRED, 12 * sizeof (prdirent_t), sizeof (prdirent_t),
137 138 "cred" },
138 139 { PR_SIGACT, 13 * sizeof (prdirent_t), sizeof (prdirent_t),
139 140 "sigact" },
140 141 { PR_AUXV, 14 * sizeof (prdirent_t), sizeof (prdirent_t),
141 142 "auxv" },
142 143 { PR_USAGE, 15 * sizeof (prdirent_t), sizeof (prdirent_t),
143 144 "usage" },
144 145 { PR_LUSAGE, 16 * sizeof (prdirent_t), sizeof (prdirent_t),
145 146 "lusage" },
146 147 { PR_PAGEDATA, 17 * sizeof (prdirent_t), sizeof (prdirent_t),
147 148 "pagedata" },
148 149 { PR_WATCH, 18 * sizeof (prdirent_t), sizeof (prdirent_t),
149 150 "watch" },
150 151 { PR_CURDIR, 19 * sizeof (prdirent_t), sizeof (prdirent_t),
151 152 "cwd" },
152 153 { PR_ROOTDIR, 20 * sizeof (prdirent_t), sizeof (prdirent_t),
153 154 "root" },
154 155 { PR_FDDIR, 21 * sizeof (prdirent_t), sizeof (prdirent_t),
155 156 "fd" },
156 157 { PR_OBJECTDIR, 22 * sizeof (prdirent_t), sizeof (prdirent_t),
157 158 "object" },
158 159 { PR_LWPDIR, 23 * sizeof (prdirent_t), sizeof (prdirent_t),
159 160 "lwp" },
160 161 { PR_PRIV, 24 * sizeof (prdirent_t), sizeof (prdirent_t),
161 162 "priv" },
162 163 { PR_PATHDIR, 25 * sizeof (prdirent_t), sizeof (prdirent_t),
163 164 "path" },
164 165 { PR_CTDIR, 26 * sizeof (prdirent_t), sizeof (prdirent_t),
165 166 "contracts" },
166 167 { PR_SECFLAGS, 27 * sizeof (prdirent_t), sizeof (prdirent_t),
167 168 "secflags" },
168 169 #if defined(__x86)
169 170 { PR_LDT, 28 * sizeof (prdirent_t), sizeof (prdirent_t),
170 171 "ldt" },
171 172 #endif
172 173 };
173 174
174 175 #define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2)
175 176
↓ open down ↓ |
99 lines elided |
↑ open up ↑ |
176 177 /*
177 178 * Contents of a /proc/<pid>/lwp/<lwpid> directory.
178 179 */
179 180 static prdirent_t lwpiddir[] = {
180 181 { PR_LWPIDDIR, 1 * sizeof (prdirent_t), sizeof (prdirent_t),
181 182 "." },
182 183 { PR_LWPDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t),
183 184 ".." },
184 185 { PR_LWPCTL, 3 * sizeof (prdirent_t), sizeof (prdirent_t),
185 186 "lwpctl" },
186 - { PR_LWPSTATUS, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
187 + { PR_LWPNAME, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
188 + "lwpname" },
189 + { PR_LWPSTATUS, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
187 190 "lwpstatus" },
188 - { PR_LWPSINFO, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
191 + { PR_LWPSINFO, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
189 192 "lwpsinfo" },
190 - { PR_LWPUSAGE, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
193 + { PR_LWPUSAGE, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
191 194 "lwpusage" },
192 - { PR_XREGS, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
195 + { PR_XREGS, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
193 196 "xregs" },
194 - { PR_TMPLDIR, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
197 + { PR_TMPLDIR, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
195 198 "templates" },
196 - { PR_SPYMASTER, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
199 + { PR_SPYMASTER, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
197 200 "spymaster" },
198 201 #if defined(__sparc)
199 - { PR_GWINDOWS, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
202 + { PR_GWINDOWS, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
200 203 "gwindows" },
201 - { PR_ASRS, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
204 + { PR_ASRS, 12 * sizeof (prdirent_t), sizeof (prdirent_t),
202 205 "asrs" },
203 206 #endif
204 207 };
205 208
206 209 #define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
207 210
208 211 /*
209 212 * Span of entries in the array files (lstatus, lpsinfo, lusage).
210 213 * We make the span larger than the size of the structure on purpose,
211 214 * to make sure that programs cannot use the structure size by mistake.
212 215 * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
213 216 */
214 217 #ifdef _LP64
215 218 #define LSPAN(type) (round16(sizeof (type)) + 16)
216 219 #define LSPAN32(type) (round8(sizeof (type)) + 8)
217 220 #else
218 221 #define LSPAN(type) (round8(sizeof (type)) + 8)
219 222 #endif
220 223
221 224 static void rebuild_objdir(struct as *);
222 225 static void prfreecommon(prcommon_t *);
223 226 static int praccess(vnode_t *, int, int, cred_t *, caller_context_t *);
224 227
225 228 static int
226 229 propen(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
227 230 {
228 231 vnode_t *vp = *vpp;
229 232 prnode_t *pnp = VTOP(vp);
230 233 prcommon_t *pcp = pnp->pr_pcommon;
231 234 prnodetype_t type = pnp->pr_type;
232 235 vnode_t *rvp;
233 236 vtype_t vtype;
234 237 proc_t *p;
235 238 int error = 0;
236 239 prnode_t *npnp = NULL;
237 240
238 241 /*
239 242 * Nothing to do for the /proc directory itself.
240 243 */
241 244 if (type == PR_PROCDIR)
242 245 return (0);
243 246
244 247 /*
245 248 * If we are opening an underlying mapped object, reject opens
246 249 * for writing regardless of the objects's access modes.
247 250 * If we are opening a file in the /proc/pid/fd directory,
248 251 * reject the open for any but a regular file or directory.
249 252 * Just do it if we are opening the current or root directory.
250 253 */
251 254 switch (type) {
252 255 case PR_OBJECT:
253 256 case PR_FD:
254 257 case PR_CURDIR:
255 258 case PR_ROOTDIR:
256 259 rvp = pnp->pr_realvp;
257 260 vtype = rvp->v_type;
258 261 if ((type == PR_OBJECT && (flag & FWRITE)) ||
259 262 (type == PR_FD && vtype != VREG && vtype != VDIR))
260 263 error = EACCES;
261 264 else {
262 265 /*
263 266 * Need to hold rvp since VOP_OPEN() may release it.
264 267 */
265 268 VN_HOLD(rvp);
266 269 error = VOP_OPEN(&rvp, flag, cr, ct);
267 270 if (error) {
268 271 VN_RELE(rvp);
269 272 } else {
270 273 *vpp = rvp;
271 274 VN_RELE(vp);
272 275 }
273 276 }
274 277 return (error);
275 278 default:
276 279 break;
277 280 }
278 281
279 282 /*
280 283 * If we are opening the pagedata file, allocate a prnode now
281 284 * to avoid calling kmem_alloc() while holding p->p_lock.
282 285 */
283 286 if (type == PR_PAGEDATA || type == PR_OPAGEDATA)
284 287 npnp = prgetnode(vp, type);
285 288
286 289 /*
287 290 * If the process exists, lock it now.
288 291 * Otherwise we have a race condition with prclose().
289 292 */
290 293 p = pr_p_lock(pnp);
291 294 mutex_exit(&pr_pidlock);
292 295 if (p == NULL) {
293 296 if (npnp != NULL)
294 297 prfreenode(npnp);
295 298 return (ENOENT);
296 299 }
297 300 ASSERT(p == pcp->prc_proc);
298 301 ASSERT(p->p_proc_flag & P_PR_LOCK);
299 302
300 303 /*
301 304 * Maintain a count of opens for write. Allow exactly one
302 305 * O_WRITE|O_EXCL request and fail subsequent ones.
303 306 * Don't fail opens of old (bletch!) /proc lwp files.
304 307 * Special case for open by the process itself:
305 308 * Always allow the open by self and discount this
306 309 * open for other opens for writing.
307 310 */
308 311 if (flag & FWRITE) {
309 312 if (p == curproc) {
310 313 pcp->prc_selfopens++;
311 314 pnp->pr_flags |= PR_ISSELF;
312 315 } else if (type == PR_LWPIDFILE) {
313 316 /* EMPTY */;
314 317 } else if (flag & FEXCL) {
315 318 if (pcp->prc_writers > pcp->prc_selfopens) {
316 319 error = EBUSY;
317 320 goto out;
318 321 }
319 322 /* semantic for old /proc interface */
320 323 if (type == PR_PIDDIR)
321 324 pcp->prc_flags |= PRC_EXCL;
322 325 } else if (pcp->prc_flags & PRC_EXCL) {
323 326 ASSERT(pcp->prc_writers > pcp->prc_selfopens);
324 327 error = secpolicy_proc_excl_open(cr);
325 328 if (error)
326 329 goto out;
327 330 }
328 331 pcp->prc_writers++;
329 332 /*
330 333 * The vnode may have become invalid between the
331 334 * VOP_LOOKUP() of the /proc vnode and the VOP_OPEN().
332 335 * If so, do now what prinvalidate() should have done.
333 336 */
334 337 if ((pnp->pr_flags & PR_INVAL) ||
335 338 (type == PR_PIDDIR &&
336 339 (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
337 340 if (p != curproc)
338 341 pcp->prc_selfopens++;
339 342 ASSERT(pcp->prc_selfopens <= pcp->prc_writers);
340 343 if (pcp->prc_selfopens == pcp->prc_writers)
341 344 pcp->prc_flags &= ~PRC_EXCL;
342 345 }
343 346 }
344 347
345 348 /*
346 349 * If this is a large file open, indicate that in our flags -- some
347 350 * procfs structures are not off_t-neutral (e.g., priovec_t), and
348 351 * the open will need to be differentiated where 32-bit processes
349 352 * pass these structures across the user/kernel boundary.
350 353 */
351 354 if (flag & FOFFMAX)
352 355 pnp->pr_flags |= PR_OFFMAX;
353 356
354 357 /*
355 358 * Do file-specific things.
356 359 */
357 360 switch (type) {
358 361 default:
359 362 break;
360 363 case PR_PAGEDATA:
361 364 case PR_OPAGEDATA:
362 365 /*
363 366 * Enable data collection for page data file;
364 367 * get unique id from the hat layer.
365 368 */
366 369 {
367 370 int id;
368 371
369 372 /*
370 373 * Drop p->p_lock to call hat_startstat()
371 374 */
372 375 mutex_exit(&p->p_lock);
373 376 if ((p->p_flag & SSYS) || p->p_as == &kas ||
374 377 (id = hat_startstat(p->p_as)) == -1) {
375 378 mutex_enter(&p->p_lock);
376 379 error = ENOMEM;
377 380 } else if (pnp->pr_hatid == 0) {
378 381 mutex_enter(&p->p_lock);
379 382 pnp->pr_hatid = (uint_t)id;
380 383 } else {
381 384 mutex_enter(&p->p_lock);
382 385 /*
383 386 * Use our newly allocated prnode.
384 387 */
385 388 npnp->pr_hatid = (uint_t)id;
386 389 /*
387 390 * prgetnode() initialized most of the prnode.
388 391 * Duplicate the remainder.
389 392 */
390 393 npnp->pr_ino = pnp->pr_ino;
391 394 npnp->pr_common = pnp->pr_common;
392 395 npnp->pr_pcommon = pnp->pr_pcommon;
393 396 npnp->pr_parent = pnp->pr_parent;
394 397 VN_HOLD(npnp->pr_parent);
395 398 npnp->pr_index = pnp->pr_index;
396 399
397 400 npnp->pr_next = p->p_plist;
398 401 p->p_plist = PTOV(npnp);
399 402
400 403 VN_RELE(PTOV(pnp));
401 404 pnp = npnp;
402 405 npnp = NULL;
403 406 *vpp = PTOV(pnp);
404 407 }
405 408 }
406 409 break;
407 410 }
408 411
409 412 out:
410 413 prunlock(pnp);
411 414
412 415 if (npnp != NULL)
413 416 prfreenode(npnp);
414 417 return (error);
415 418 }
416 419
417 420 /* ARGSUSED */
418 421 static int
419 422 prclose(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
420 423 caller_context_t *ct)
421 424 {
422 425 prnode_t *pnp = VTOP(vp);
423 426 prcommon_t *pcp = pnp->pr_pcommon;
424 427 prnodetype_t type = pnp->pr_type;
425 428 proc_t *p;
426 429 kthread_t *t;
427 430 user_t *up;
428 431
429 432 /*
430 433 * Nothing to do for the /proc directory itself.
431 434 */
432 435 if (type == PR_PROCDIR)
433 436 return (0);
434 437
435 438 ASSERT(type != PR_OBJECT && type != PR_FD &&
436 439 type != PR_CURDIR && type != PR_ROOTDIR);
437 440
438 441 /*
439 442 * If the process exists, lock it now.
440 443 * Otherwise we have a race condition with propen().
441 444 * Hold pr_pidlock across the reference to prc_selfopens,
442 445 * and prc_writers in case there is no process anymore,
443 446 * to cover the case of concurrent calls to prclose()
444 447 * after the process has been reaped by freeproc().
445 448 */
446 449 p = pr_p_lock(pnp);
447 450
448 451 /*
449 452 * There is nothing more to do until the last close of
450 453 * the file table entry except to clear the pr_owner
451 454 * field of the prnode and notify any waiters
452 455 * (their file descriptor may have just been closed).
453 456 */
454 457 if (count > 1) {
455 458 mutex_exit(&pr_pidlock);
456 459 if (pnp->pr_owner == curproc && !fisopen(vp))
457 460 pnp->pr_owner = NULL;
458 461 if (p != NULL) {
459 462 prnotify(vp);
460 463 prunlock(pnp);
461 464 }
462 465 return (0);
463 466 }
464 467
465 468 /*
466 469 * Decrement the count of self-opens for writing.
467 470 * Decrement the total count of opens for writing.
468 471 * Cancel exclusive opens when only self-opens remain.
469 472 */
470 473 if (flag & FWRITE) {
471 474 /*
472 475 * prc_selfopens also contains the count of
473 476 * invalid writers. See prinvalidate().
474 477 */
475 478 if ((pnp->pr_flags & (PR_ISSELF|PR_INVAL)) ||
476 479 (type == PR_PIDDIR &&
477 480 (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
478 481 ASSERT(pcp->prc_selfopens != 0);
479 482 --pcp->prc_selfopens;
480 483 }
481 484 ASSERT(pcp->prc_writers != 0);
482 485 if (--pcp->prc_writers == pcp->prc_selfopens)
483 486 pcp->prc_flags &= ~PRC_EXCL;
484 487 }
485 488 ASSERT(pcp->prc_writers >= pcp->prc_selfopens);
486 489 mutex_exit(&pr_pidlock);
487 490 if (pnp->pr_owner == curproc && !fisopen(vp))
488 491 pnp->pr_owner = NULL;
489 492
490 493 /*
491 494 * If there is no process, there is nothing more to do.
492 495 */
493 496 if (p == NULL)
494 497 return (0);
495 498
496 499 ASSERT(p == pcp->prc_proc);
497 500 prnotify(vp); /* notify waiters */
498 501
499 502 /*
500 503 * Do file-specific things.
501 504 */
502 505 switch (type) {
503 506 default:
504 507 break;
505 508 case PR_PAGEDATA:
506 509 case PR_OPAGEDATA:
507 510 /*
508 511 * This is a page data file.
509 512 * Free the hat level statistics.
510 513 * Drop p->p_lock before calling hat_freestat().
511 514 */
512 515 mutex_exit(&p->p_lock);
513 516 if (p->p_as != &kas && pnp->pr_hatid != 0)
514 517 hat_freestat(p->p_as, pnp->pr_hatid);
515 518 mutex_enter(&p->p_lock);
516 519 pnp->pr_hatid = 0;
517 520 break;
518 521 }
519 522
520 523 /*
521 524 * On last close of all writable file descriptors,
522 525 * perform run-on-last-close and/or kill-on-last-close logic.
523 526 * Can't do this is the /proc agent lwp still exists.
524 527 */
525 528 if (pcp->prc_writers == 0 &&
526 529 p->p_agenttp == NULL &&
527 530 !(pcp->prc_flags & PRC_DESTROY) &&
528 531 p->p_stat != SZOMB &&
529 532 (p->p_proc_flag & (P_PR_RUNLCL|P_PR_KILLCL))) {
530 533 int killproc;
531 534
532 535 /*
533 536 * Cancel any watchpoints currently in effect.
534 537 * The process might disappear during this operation.
535 538 */
536 539 if (pr_cancel_watch(pnp) == NULL)
537 540 return (0);
538 541 /*
539 542 * If any tracing flags are set, clear them.
540 543 */
541 544 if (p->p_proc_flag & P_PR_TRACE) {
542 545 up = PTOU(p);
543 546 premptyset(&up->u_entrymask);
544 547 premptyset(&up->u_exitmask);
545 548 up->u_systrap = 0;
546 549 }
547 550 premptyset(&p->p_sigmask);
548 551 premptyset(&p->p_fltmask);
549 552 killproc = (p->p_proc_flag & P_PR_KILLCL);
550 553 p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE);
551 554 /*
552 555 * Cancel any outstanding single-step requests.
553 556 */
554 557 if ((t = p->p_tlist) != NULL) {
555 558 /*
556 559 * Drop p_lock because prnostep() touches the stack.
557 560 * The loop is safe because the process is P_PR_LOCK'd.
558 561 */
559 562 mutex_exit(&p->p_lock);
560 563 do {
561 564 prnostep(ttolwp(t));
562 565 } while ((t = t->t_forw) != p->p_tlist);
563 566 mutex_enter(&p->p_lock);
564 567 }
565 568 /*
566 569 * Set runnable all lwps stopped by /proc.
567 570 */
568 571 if (killproc)
569 572 sigtoproc(p, NULL, SIGKILL);
570 573 else
571 574 allsetrun(p);
572 575 }
573 576
574 577 prunlock(pnp);
575 578 return (0);
576 579 }
577 580
578 581 /*
579 582 * Array of read functions, indexed by /proc file type.
↓ open down ↓ |
368 lines elided |
↑ open up ↑ |
580 583 */
581 584 static int pr_read_inval(), pr_read_as(), pr_read_status(),
582 585 pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
583 586 pr_read_map(), pr_read_rmap(), pr_read_xmap(),
584 587 pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
585 588 #if defined(__x86)
586 589 pr_read_ldt(),
587 590 #endif
588 591 pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
589 592 pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
590 - pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
593 + pr_read_lwpusage(), pr_read_lwpname(),
594 + pr_read_xregs(), pr_read_priv(),
591 595 pr_read_spymaster(), pr_read_secflags(),
592 596 #if defined(__sparc)
593 597 pr_read_gwindows(), pr_read_asrs(),
594 598 #endif
595 599 pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
596 600
597 601 static int (*pr_read_function[PR_NFILES])() = {
598 602 pr_read_inval, /* /proc */
599 603 pr_read_inval, /* /proc/self */
600 604 pr_read_piddir, /* /proc/<pid> (old /proc read()) */
601 605 pr_read_as, /* /proc/<pid>/as */
602 606 pr_read_inval, /* /proc/<pid>/ctl */
603 607 pr_read_status, /* /proc/<pid>/status */
604 608 pr_read_lstatus, /* /proc/<pid>/lstatus */
605 609 pr_read_psinfo, /* /proc/<pid>/psinfo */
606 610 pr_read_lpsinfo, /* /proc/<pid>/lpsinfo */
607 611 pr_read_map, /* /proc/<pid>/map */
608 612 pr_read_rmap, /* /proc/<pid>/rmap */
609 613 pr_read_xmap, /* /proc/<pid>/xmap */
610 614 pr_read_cred, /* /proc/<pid>/cred */
611 615 pr_read_sigact, /* /proc/<pid>/sigact */
612 616 pr_read_auxv, /* /proc/<pid>/auxv */
613 617 #if defined(__x86)
614 618 pr_read_ldt, /* /proc/<pid>/ldt */
615 619 #endif
616 620 pr_read_usage, /* /proc/<pid>/usage */
617 621 pr_read_lusage, /* /proc/<pid>/lusage */
618 622 pr_read_pagedata, /* /proc/<pid>/pagedata */
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
619 623 pr_read_watch, /* /proc/<pid>/watch */
620 624 pr_read_inval, /* /proc/<pid>/cwd */
621 625 pr_read_inval, /* /proc/<pid>/root */
622 626 pr_read_inval, /* /proc/<pid>/fd */
623 627 pr_read_inval, /* /proc/<pid>/fd/nn */
624 628 pr_read_inval, /* /proc/<pid>/object */
625 629 pr_read_inval, /* /proc/<pid>/object/xxx */
626 630 pr_read_inval, /* /proc/<pid>/lwp */
627 631 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
628 632 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
633 + pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */
629 634 pr_read_lwpstatus, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
630 635 pr_read_lwpsinfo, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
631 636 pr_read_lwpusage, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
632 637 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
633 638 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
634 639 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
635 640 pr_read_spymaster, /* /proc/<pid>/lwp/<lwpid>/spymaster */
636 641 #if defined(__sparc)
637 642 pr_read_gwindows, /* /proc/<pid>/lwp/<lwpid>/gwindows */
638 643 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */
639 644 #endif
640 645 pr_read_priv, /* /proc/<pid>/priv */
641 646 pr_read_inval, /* /proc/<pid>/path */
642 647 pr_read_inval, /* /proc/<pid>/path/xxx */
643 648 pr_read_inval, /* /proc/<pid>/contracts */
644 649 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */
645 650 pr_read_secflags, /* /proc/<pid>/secflags */
646 651 pr_read_pidfile, /* old process file */
647 652 pr_read_pidfile, /* old lwp file */
648 653 pr_read_opagedata, /* old pagedata file */
649 654 };
650 655
651 656 /* ARGSUSED */
652 657 static int
653 658 pr_read_inval(prnode_t *pnp, uio_t *uiop)
654 659 {
655 660 /*
656 661 * No read() on any /proc directory, use getdents(2) instead.
657 662 * Cannot read a control file either.
658 663 * An underlying mapped object file cannot get here.
659 664 */
660 665 return (EINVAL);
661 666 }
662 667
663 668 static int
664 669 pr_uioread(void *base, long count, uio_t *uiop)
665 670 {
666 671 int error = 0;
667 672
668 673 ASSERT(count >= 0);
669 674 count -= uiop->uio_offset;
670 675 if (count > 0 && uiop->uio_offset >= 0) {
671 676 error = uiomove((char *)base + uiop->uio_offset,
672 677 count, UIO_READ, uiop);
673 678 }
674 679
675 680 return (error);
676 681 }
677 682
678 683 static int
679 684 pr_read_as(prnode_t *pnp, uio_t *uiop)
680 685 {
681 686 int error;
682 687
683 688 ASSERT(pnp->pr_type == PR_AS);
684 689
685 690 if ((error = prlock(pnp, ZNO)) == 0) {
686 691 proc_t *p = pnp->pr_common->prc_proc;
687 692 struct as *as = p->p_as;
688 693
689 694 /*
690 695 * /proc I/O cannot be done to a system process.
691 696 * A 32-bit process cannot read a 64-bit process.
692 697 */
693 698 if ((p->p_flag & SSYS) || as == &kas) {
694 699 error = 0;
695 700 #ifdef _SYSCALL32_IMPL
696 701 } else if (curproc->p_model == DATAMODEL_ILP32 &&
697 702 PROCESS_NOT_32BIT(p)) {
698 703 error = EOVERFLOW;
699 704 #endif
700 705 } else {
701 706 /*
702 707 * We don't hold p_lock over an i/o operation because
703 708 * that could lead to deadlock with the clock thread.
704 709 */
705 710 mutex_exit(&p->p_lock);
706 711 error = prusrio(p, UIO_READ, uiop, 0);
707 712 mutex_enter(&p->p_lock);
708 713 }
709 714 prunlock(pnp);
710 715 }
711 716
712 717 return (error);
713 718 }
714 719
715 720 static int
716 721 pr_read_status(prnode_t *pnp, uio_t *uiop)
717 722 {
718 723 pstatus_t *sp;
719 724 int error;
720 725
721 726 ASSERT(pnp->pr_type == PR_STATUS);
722 727
723 728 /*
724 729 * We kmem_alloc() the pstatus structure because
725 730 * it is so big it might blow the kernel stack.
726 731 */
727 732 sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
728 733 if ((error = prlock(pnp, ZNO)) == 0) {
729 734 prgetstatus(pnp->pr_common->prc_proc, sp, VTOZONE(PTOV(pnp)));
730 735 prunlock(pnp);
731 736 error = pr_uioread(sp, sizeof (*sp), uiop);
732 737 }
733 738 kmem_free(sp, sizeof (*sp));
734 739 return (error);
735 740 }
736 741
737 742 static int
738 743 pr_read_lstatus(prnode_t *pnp, uio_t *uiop)
739 744 {
740 745 proc_t *p;
741 746 kthread_t *t;
742 747 lwpdir_t *ldp;
743 748 size_t size;
744 749 prheader_t *php;
745 750 lwpstatus_t *sp;
746 751 int error;
747 752 int nlwp;
748 753 int i;
749 754
750 755 ASSERT(pnp->pr_type == PR_LSTATUS);
751 756
752 757 if ((error = prlock(pnp, ZNO)) != 0)
753 758 return (error);
754 759 p = pnp->pr_common->prc_proc;
755 760 nlwp = p->p_lwpcnt;
756 761 size = sizeof (prheader_t) + nlwp * LSPAN(lwpstatus_t);
757 762
758 763 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
759 764 mutex_exit(&p->p_lock);
760 765 php = kmem_zalloc(size, KM_SLEEP);
761 766 mutex_enter(&p->p_lock);
762 767 /* p->p_lwpcnt can't change while process is locked */
763 768 ASSERT(nlwp == p->p_lwpcnt);
764 769
765 770 php->pr_nent = nlwp;
766 771 php->pr_entsize = LSPAN(lwpstatus_t);
767 772
768 773 sp = (lwpstatus_t *)(php + 1);
769 774 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
770 775 if (ldp->ld_entry == NULL ||
771 776 (t = ldp->ld_entry->le_thread) == NULL)
772 777 continue;
773 778 prgetlwpstatus(t, sp, VTOZONE(PTOV(pnp)));
774 779 sp = (lwpstatus_t *)((caddr_t)sp + LSPAN(lwpstatus_t));
775 780 }
776 781 prunlock(pnp);
777 782
778 783 error = pr_uioread(php, size, uiop);
779 784 kmem_free(php, size);
780 785 return (error);
781 786 }
782 787
783 788 static int
784 789 pr_read_psinfo(prnode_t *pnp, uio_t *uiop)
785 790 {
786 791 psinfo_t psinfo;
787 792 proc_t *p;
788 793 int error = 0;
789 794
790 795 ASSERT(pnp->pr_type == PR_PSINFO);
791 796
792 797 /*
793 798 * We don't want the full treatment of prlock(pnp) here.
794 799 * This file is world-readable and never goes invalid.
795 800 * It doesn't matter if we are in the middle of an exec().
796 801 */
797 802 p = pr_p_lock(pnp);
798 803 mutex_exit(&pr_pidlock);
799 804 if (p == NULL)
800 805 error = ENOENT;
801 806 else {
802 807 ASSERT(p == pnp->pr_common->prc_proc);
803 808 prgetpsinfo(p, &psinfo);
804 809 prunlock(pnp);
805 810 error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
806 811 }
807 812 return (error);
808 813 }
809 814
810 815 static int
811 816 pr_read_lpsinfo(prnode_t *pnp, uio_t *uiop)
812 817 {
813 818 proc_t *p;
814 819 kthread_t *t;
815 820 lwpdir_t *ldp;
816 821 lwpent_t *lep;
817 822 size_t size;
818 823 prheader_t *php;
819 824 lwpsinfo_t *sp;
820 825 int error;
821 826 int nlwp;
822 827 int i;
823 828
824 829 ASSERT(pnp->pr_type == PR_LPSINFO);
825 830
826 831 /*
827 832 * We don't want the full treatment of prlock(pnp) here.
828 833 * This file is world-readable and never goes invalid.
829 834 * It doesn't matter if we are in the middle of an exec().
830 835 */
831 836 p = pr_p_lock(pnp);
832 837 mutex_exit(&pr_pidlock);
833 838 if (p == NULL)
834 839 return (ENOENT);
835 840 ASSERT(p == pnp->pr_common->prc_proc);
836 841 if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
837 842 prunlock(pnp);
838 843 return (ENOENT);
839 844 }
840 845 size = sizeof (prheader_t) + nlwp * LSPAN(lwpsinfo_t);
841 846
842 847 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
843 848 mutex_exit(&p->p_lock);
844 849 php = kmem_zalloc(size, KM_SLEEP);
845 850 mutex_enter(&p->p_lock);
846 851 /* p->p_lwpcnt can't change while process is locked */
847 852 ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
848 853
849 854 php->pr_nent = nlwp;
850 855 php->pr_entsize = LSPAN(lwpsinfo_t);
851 856
852 857 sp = (lwpsinfo_t *)(php + 1);
853 858 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
854 859 if ((lep = ldp->ld_entry) == NULL)
855 860 continue;
856 861 if ((t = lep->le_thread) != NULL)
857 862 prgetlwpsinfo(t, sp);
858 863 else {
859 864 bzero(sp, sizeof (*sp));
860 865 sp->pr_lwpid = lep->le_lwpid;
861 866 sp->pr_state = SZOMB;
862 867 sp->pr_sname = 'Z';
863 868 sp->pr_start.tv_sec = lep->le_start;
864 869 sp->pr_bindpro = PBIND_NONE;
865 870 sp->pr_bindpset = PS_NONE;
866 871 }
867 872 sp = (lwpsinfo_t *)((caddr_t)sp + LSPAN(lwpsinfo_t));
868 873 }
869 874 prunlock(pnp);
870 875
871 876 error = pr_uioread(php, size, uiop);
872 877 kmem_free(php, size);
873 878 return (error);
874 879 }
875 880
876 881 static int
877 882 pr_read_map_common(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
878 883 {
879 884 proc_t *p;
880 885 struct as *as;
881 886 list_t iolhead;
882 887 int error;
883 888
884 889 readmap_common:
885 890 if ((error = prlock(pnp, ZNO)) != 0)
886 891 return (error);
887 892
888 893 p = pnp->pr_common->prc_proc;
889 894 as = p->p_as;
890 895
891 896 if ((p->p_flag & SSYS) || as == &kas) {
892 897 prunlock(pnp);
893 898 return (0);
894 899 }
895 900
896 901 if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
897 902 prunlock(pnp);
898 903 delay(1);
899 904 goto readmap_common;
900 905 }
901 906 mutex_exit(&p->p_lock);
902 907
903 908 switch (type) {
904 909 case PR_XMAP:
905 910 error = prgetxmap(p, &iolhead);
906 911 break;
907 912 case PR_RMAP:
908 913 error = prgetmap(p, 1, &iolhead);
909 914 break;
910 915 case PR_MAP:
911 916 error = prgetmap(p, 0, &iolhead);
912 917 break;
913 918 }
914 919
915 920 AS_LOCK_EXIT(as);
916 921 mutex_enter(&p->p_lock);
917 922 prunlock(pnp);
918 923
919 924 error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
920 925
921 926 return (error);
922 927 }
923 928
924 929 static int
925 930 pr_read_map(prnode_t *pnp, uio_t *uiop)
926 931 {
927 932 ASSERT(pnp->pr_type == PR_MAP);
928 933 return (pr_read_map_common(pnp, uiop, pnp->pr_type));
929 934 }
930 935
931 936 static int
932 937 pr_read_rmap(prnode_t *pnp, uio_t *uiop)
933 938 {
934 939 ASSERT(pnp->pr_type == PR_RMAP);
935 940 return (pr_read_map_common(pnp, uiop, pnp->pr_type));
936 941 }
937 942
938 943 static int
939 944 pr_read_xmap(prnode_t *pnp, uio_t *uiop)
940 945 {
941 946 ASSERT(pnp->pr_type == PR_XMAP);
942 947 return (pr_read_map_common(pnp, uiop, pnp->pr_type));
943 948 }
944 949
945 950 static int
946 951 pr_read_cred(prnode_t *pnp, uio_t *uiop)
947 952 {
948 953 proc_t *p;
949 954 prcred_t *pcrp;
950 955 int error;
951 956 size_t count;
952 957
953 958 ASSERT(pnp->pr_type == PR_CRED);
954 959
955 960 /*
956 961 * We kmem_alloc() the prcred_t structure because
957 962 * the number of supplementary groups is variable.
958 963 */
959 964 pcrp =
960 965 kmem_alloc(sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1),
961 966 KM_SLEEP);
962 967
963 968 if ((error = prlock(pnp, ZNO)) != 0)
964 969 goto out;
965 970 p = pnp->pr_common->prc_proc;
966 971 ASSERT(p != NULL);
967 972
968 973 prgetcred(p, pcrp);
969 974 prunlock(pnp);
970 975
971 976 count = sizeof (prcred_t);
972 977 if (pcrp->pr_ngroups > 1)
973 978 count += sizeof (gid_t) * (pcrp->pr_ngroups - 1);
974 979 error = pr_uioread(pcrp, count, uiop);
975 980 out:
976 981 kmem_free(pcrp, sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1));
977 982 return (error);
978 983 }
979 984
980 985 static int
981 986 pr_read_priv(prnode_t *pnp, uio_t *uiop)
982 987 {
983 988 proc_t *p;
984 989 size_t psize = prgetprivsize();
985 990 prpriv_t *ppriv = kmem_alloc(psize, KM_SLEEP);
986 991 int error;
987 992
988 993 ASSERT(pnp->pr_type == PR_PRIV);
989 994
990 995 if ((error = prlock(pnp, ZNO)) != 0)
991 996 goto out;
992 997 p = pnp->pr_common->prc_proc;
993 998 ASSERT(p != NULL);
994 999
995 1000 prgetpriv(p, ppriv);
996 1001 prunlock(pnp);
997 1002
998 1003 error = pr_uioread(ppriv, psize, uiop);
999 1004 out:
1000 1005 kmem_free(ppriv, psize);
1001 1006 return (error);
1002 1007 }
1003 1008
1004 1009 static int
1005 1010 pr_read_sigact(prnode_t *pnp, uio_t *uiop)
1006 1011 {
1007 1012 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1008 1013 proc_t *p;
1009 1014 struct sigaction *sap;
1010 1015 int sig;
1011 1016 int error;
1012 1017 user_t *up;
1013 1018
1014 1019 ASSERT(pnp->pr_type == PR_SIGACT);
1015 1020
1016 1021 /*
1017 1022 * We kmem_alloc() the sigaction array because
1018 1023 * it is so big it might blow the kernel stack.
1019 1024 */
1020 1025 sap = kmem_alloc((nsig-1) * sizeof (struct sigaction), KM_SLEEP);
1021 1026
1022 1027 if ((error = prlock(pnp, ZNO)) != 0)
1023 1028 goto out;
1024 1029 p = pnp->pr_common->prc_proc;
1025 1030 ASSERT(p != NULL);
1026 1031
1027 1032 if (uiop->uio_offset >= (nsig-1)*sizeof (struct sigaction)) {
1028 1033 prunlock(pnp);
1029 1034 goto out;
1030 1035 }
1031 1036
1032 1037 up = PTOU(p);
1033 1038 for (sig = 1; sig < nsig; sig++)
1034 1039 prgetaction(p, up, sig, &sap[sig-1]);
1035 1040 prunlock(pnp);
1036 1041
1037 1042 error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction), uiop);
1038 1043 out:
1039 1044 kmem_free(sap, (nsig-1) * sizeof (struct sigaction));
1040 1045 return (error);
1041 1046 }
1042 1047
1043 1048 static int
1044 1049 pr_read_auxv(prnode_t *pnp, uio_t *uiop)
1045 1050 {
1046 1051 auxv_t auxv[__KERN_NAUXV_IMPL];
1047 1052 proc_t *p;
1048 1053 user_t *up;
1049 1054 int error;
1050 1055
1051 1056 ASSERT(pnp->pr_type == PR_AUXV);
1052 1057
1053 1058 if ((error = prlock(pnp, ZNO)) != 0)
1054 1059 return (error);
1055 1060
1056 1061 if (uiop->uio_offset >= sizeof (auxv)) {
1057 1062 prunlock(pnp);
1058 1063 return (0);
1059 1064 }
1060 1065
1061 1066 p = pnp->pr_common->prc_proc;
1062 1067 up = PTOU(p);
1063 1068 bcopy(up->u_auxv, auxv, sizeof (auxv));
1064 1069 prunlock(pnp);
1065 1070
↓ open down ↓ |
427 lines elided |
↑ open up ↑ |
1066 1071 return (pr_uioread(auxv, sizeof (auxv), uiop));
1067 1072 }
1068 1073
1069 1074 #if defined(__x86)
1070 1075 /*
1071 1076 * XX64
1072 1077 * This is almost certainly broken for the amd64 kernel, because
1073 1078 * we have two kinds of LDT structures to export -- one for compatibility
1074 1079 * mode, and one for long mode, sigh.
1075 1080 *
1076 - * For now lets just have a ldt of size 0 for 64-bit processes.
1081 + * For now let's just have a ldt of size 0 for 64-bit processes.
1077 1082 */
1078 1083 static int
1079 1084 pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1080 1085 {
1081 1086 proc_t *p;
1082 1087 struct ssd *ssd;
1083 1088 size_t size;
1084 1089 int error;
1085 1090
1086 1091 ASSERT(pnp->pr_type == PR_LDT);
1087 1092
1088 1093 if ((error = prlock(pnp, ZNO)) != 0)
1089 1094 return (error);
1090 1095 p = pnp->pr_common->prc_proc;
1091 1096
1092 1097 mutex_exit(&p->p_lock);
1093 1098 mutex_enter(&p->p_ldtlock);
1094 1099 size = prnldt(p) * sizeof (struct ssd);
1095 1100 if (uiop->uio_offset >= size) {
1096 1101 mutex_exit(&p->p_ldtlock);
1097 1102 mutex_enter(&p->p_lock);
1098 1103 prunlock(pnp);
1099 1104 return (0);
1100 1105 }
1101 1106
1102 1107 ssd = kmem_alloc(size, KM_SLEEP);
1103 1108 prgetldt(p, ssd);
1104 1109 mutex_exit(&p->p_ldtlock);
1105 1110 mutex_enter(&p->p_lock);
1106 1111 prunlock(pnp);
1107 1112
1108 1113 error = pr_uioread(ssd, size, uiop);
1109 1114 kmem_free(ssd, size);
1110 1115 return (error);
1111 1116 }
1112 1117 #endif /* __x86 */
1113 1118
1114 1119 static int
1115 1120 pr_read_usage(prnode_t *pnp, uio_t *uiop)
1116 1121 {
1117 1122 prhusage_t *pup;
1118 1123 prusage_t *upup;
1119 1124 proc_t *p;
1120 1125 kthread_t *t;
1121 1126 int error;
1122 1127
1123 1128 ASSERT(pnp->pr_type == PR_USAGE);
1124 1129
1125 1130 /* allocate now, before locking the process */
1126 1131 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1127 1132 upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1128 1133
1129 1134 /*
1130 1135 * We don't want the full treatment of prlock(pnp) here.
1131 1136 * This file is world-readable and never goes invalid.
1132 1137 * It doesn't matter if we are in the middle of an exec().
1133 1138 */
1134 1139 p = pr_p_lock(pnp);
1135 1140 mutex_exit(&pr_pidlock);
1136 1141 if (p == NULL) {
1137 1142 error = ENOENT;
1138 1143 goto out;
1139 1144 }
1140 1145 ASSERT(p == pnp->pr_common->prc_proc);
1141 1146
1142 1147 if (uiop->uio_offset >= sizeof (prusage_t)) {
1143 1148 prunlock(pnp);
1144 1149 error = 0;
1145 1150 goto out;
1146 1151 }
1147 1152
1148 1153 pup->pr_tstamp = gethrtime();
1149 1154
1150 1155 pup->pr_count = p->p_defunct;
1151 1156 pup->pr_create = p->p_mstart;
1152 1157 pup->pr_term = p->p_mterm;
1153 1158
1154 1159 pup->pr_rtime = p->p_mlreal;
1155 1160 pup->pr_utime = p->p_acct[LMS_USER];
1156 1161 pup->pr_stime = p->p_acct[LMS_SYSTEM];
1157 1162 pup->pr_ttime = p->p_acct[LMS_TRAP];
1158 1163 pup->pr_tftime = p->p_acct[LMS_TFAULT];
1159 1164 pup->pr_dftime = p->p_acct[LMS_DFAULT];
1160 1165 pup->pr_kftime = p->p_acct[LMS_KFAULT];
1161 1166 pup->pr_ltime = p->p_acct[LMS_USER_LOCK];
1162 1167 pup->pr_slptime = p->p_acct[LMS_SLEEP];
1163 1168 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU];
1164 1169 pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1165 1170
1166 1171 pup->pr_minf = p->p_ru.minflt;
1167 1172 pup->pr_majf = p->p_ru.majflt;
1168 1173 pup->pr_nswap = p->p_ru.nswap;
1169 1174 pup->pr_inblk = p->p_ru.inblock;
1170 1175 pup->pr_oublk = p->p_ru.oublock;
1171 1176 pup->pr_msnd = p->p_ru.msgsnd;
1172 1177 pup->pr_mrcv = p->p_ru.msgrcv;
1173 1178 pup->pr_sigs = p->p_ru.nsignals;
1174 1179 pup->pr_vctx = p->p_ru.nvcsw;
1175 1180 pup->pr_ictx = p->p_ru.nivcsw;
1176 1181 pup->pr_sysc = p->p_ru.sysc;
1177 1182 pup->pr_ioch = p->p_ru.ioch;
1178 1183
1179 1184 /*
1180 1185 * Add the usage information for each active lwp.
1181 1186 */
1182 1187 if ((t = p->p_tlist) != NULL &&
1183 1188 !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
1184 1189 do {
1185 1190 if (t->t_proc_flag & TP_LWPEXIT)
1186 1191 continue;
1187 1192 pup->pr_count++;
1188 1193 praddusage(t, pup);
1189 1194 } while ((t = t->t_forw) != p->p_tlist);
1190 1195 }
1191 1196
1192 1197 prunlock(pnp);
1193 1198
1194 1199 prcvtusage(pup, upup);
1195 1200
1196 1201 error = pr_uioread(upup, sizeof (prusage_t), uiop);
1197 1202 out:
1198 1203 kmem_free(pup, sizeof (*pup));
1199 1204 kmem_free(upup, sizeof (*upup));
1200 1205 return (error);
1201 1206 }
1202 1207
1203 1208 static int
1204 1209 pr_read_lusage(prnode_t *pnp, uio_t *uiop)
1205 1210 {
1206 1211 int nlwp;
1207 1212 prhusage_t *pup;
1208 1213 prheader_t *php;
1209 1214 prusage_t *upup;
1210 1215 size_t size;
1211 1216 hrtime_t curtime;
1212 1217 proc_t *p;
1213 1218 kthread_t *t;
1214 1219 lwpdir_t *ldp;
1215 1220 int error;
1216 1221 int i;
1217 1222
1218 1223 ASSERT(pnp->pr_type == PR_LUSAGE);
1219 1224
1220 1225 /*
1221 1226 * We don't want the full treatment of prlock(pnp) here.
1222 1227 * This file is world-readable and never goes invalid.
1223 1228 * It doesn't matter if we are in the middle of an exec().
1224 1229 */
1225 1230 p = pr_p_lock(pnp);
1226 1231 mutex_exit(&pr_pidlock);
1227 1232 if (p == NULL)
1228 1233 return (ENOENT);
1229 1234 ASSERT(p == pnp->pr_common->prc_proc);
1230 1235 if ((nlwp = p->p_lwpcnt) == 0) {
1231 1236 prunlock(pnp);
1232 1237 return (ENOENT);
1233 1238 }
1234 1239
1235 1240 size = sizeof (prheader_t) + (nlwp + 1) * LSPAN(prusage_t);
1236 1241 if (uiop->uio_offset >= size) {
1237 1242 prunlock(pnp);
1238 1243 return (0);
1239 1244 }
1240 1245
1241 1246 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1242 1247 mutex_exit(&p->p_lock);
1243 1248 pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
1244 1249 mutex_enter(&p->p_lock);
1245 1250 /* p->p_lwpcnt can't change while process is locked */
1246 1251 ASSERT(nlwp == p->p_lwpcnt);
1247 1252
1248 1253 php = (prheader_t *)(pup + 1);
1249 1254 upup = (prusage_t *)(php + 1);
1250 1255
1251 1256 php->pr_nent = nlwp + 1;
1252 1257 php->pr_entsize = LSPAN(prusage_t);
1253 1258
1254 1259 curtime = gethrtime();
1255 1260
1256 1261 /*
1257 1262 * First the summation over defunct lwps.
1258 1263 */
1259 1264 pup->pr_count = p->p_defunct;
1260 1265 pup->pr_tstamp = curtime;
1261 1266 pup->pr_create = p->p_mstart;
1262 1267 pup->pr_term = p->p_mterm;
1263 1268
1264 1269 pup->pr_rtime = p->p_mlreal;
1265 1270 pup->pr_utime = p->p_acct[LMS_USER];
1266 1271 pup->pr_stime = p->p_acct[LMS_SYSTEM];
1267 1272 pup->pr_ttime = p->p_acct[LMS_TRAP];
1268 1273 pup->pr_tftime = p->p_acct[LMS_TFAULT];
1269 1274 pup->pr_dftime = p->p_acct[LMS_DFAULT];
1270 1275 pup->pr_kftime = p->p_acct[LMS_KFAULT];
1271 1276 pup->pr_ltime = p->p_acct[LMS_USER_LOCK];
1272 1277 pup->pr_slptime = p->p_acct[LMS_SLEEP];
1273 1278 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU];
1274 1279 pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1275 1280
1276 1281 pup->pr_minf = p->p_ru.minflt;
1277 1282 pup->pr_majf = p->p_ru.majflt;
1278 1283 pup->pr_nswap = p->p_ru.nswap;
1279 1284 pup->pr_inblk = p->p_ru.inblock;
1280 1285 pup->pr_oublk = p->p_ru.oublock;
1281 1286 pup->pr_msnd = p->p_ru.msgsnd;
1282 1287 pup->pr_mrcv = p->p_ru.msgrcv;
1283 1288 pup->pr_sigs = p->p_ru.nsignals;
1284 1289 pup->pr_vctx = p->p_ru.nvcsw;
1285 1290 pup->pr_ictx = p->p_ru.nivcsw;
1286 1291 pup->pr_sysc = p->p_ru.sysc;
1287 1292 pup->pr_ioch = p->p_ru.ioch;
1288 1293
1289 1294 prcvtusage(pup, upup);
1290 1295
1291 1296 /*
1292 1297 * Fill one prusage struct for each active lwp.
1293 1298 */
1294 1299 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1295 1300 if (ldp->ld_entry == NULL ||
1296 1301 (t = ldp->ld_entry->le_thread) == NULL)
1297 1302 continue;
1298 1303 ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
1299 1304 ASSERT(nlwp > 0);
1300 1305 --nlwp;
1301 1306 upup = (prusage_t *)((caddr_t)upup + LSPAN(prusage_t));
1302 1307 prgetusage(t, pup);
1303 1308 prcvtusage(pup, upup);
1304 1309 }
1305 1310 ASSERT(nlwp == 0);
1306 1311
1307 1312 prunlock(pnp);
1308 1313
1309 1314 error = pr_uioread(php, size, uiop);
1310 1315 kmem_free(pup, size + sizeof (prhusage_t));
1311 1316 return (error);
1312 1317 }
1313 1318
1314 1319 static int
1315 1320 pr_read_pagedata(prnode_t *pnp, uio_t *uiop)
1316 1321 {
1317 1322 proc_t *p;
1318 1323 int error;
1319 1324
1320 1325 ASSERT(pnp->pr_type == PR_PAGEDATA);
1321 1326
1322 1327 if ((error = prlock(pnp, ZNO)) != 0)
1323 1328 return (error);
1324 1329
1325 1330 p = pnp->pr_common->prc_proc;
1326 1331 if ((p->p_flag & SSYS) || p->p_as == &kas) {
1327 1332 prunlock(pnp);
1328 1333 return (0);
1329 1334 }
1330 1335
1331 1336 mutex_exit(&p->p_lock);
1332 1337 error = prpdread(p, pnp->pr_hatid, uiop);
1333 1338 mutex_enter(&p->p_lock);
1334 1339
1335 1340 prunlock(pnp);
1336 1341 return (error);
1337 1342 }
1338 1343
1339 1344 static int
1340 1345 pr_read_opagedata(prnode_t *pnp, uio_t *uiop)
1341 1346 {
1342 1347 proc_t *p;
1343 1348 struct as *as;
1344 1349 int error;
1345 1350
1346 1351 ASSERT(pnp->pr_type == PR_OPAGEDATA);
1347 1352
1348 1353 if ((error = prlock(pnp, ZNO)) != 0)
1349 1354 return (error);
1350 1355
1351 1356 p = pnp->pr_common->prc_proc;
1352 1357 as = p->p_as;
1353 1358 if ((p->p_flag & SSYS) || as == &kas) {
1354 1359 prunlock(pnp);
1355 1360 return (0);
1356 1361 }
1357 1362
1358 1363 mutex_exit(&p->p_lock);
1359 1364 error = oprpdread(as, pnp->pr_hatid, uiop);
1360 1365 mutex_enter(&p->p_lock);
1361 1366
1362 1367 prunlock(pnp);
1363 1368 return (error);
1364 1369 }
1365 1370
1366 1371 static int
1367 1372 pr_read_watch(prnode_t *pnp, uio_t *uiop)
1368 1373 {
1369 1374 proc_t *p;
1370 1375 int error;
1371 1376 prwatch_t *Bpwp;
1372 1377 size_t size;
1373 1378 prwatch_t *pwp;
1374 1379 int nwarea;
1375 1380 struct watched_area *pwarea;
1376 1381
1377 1382 ASSERT(pnp->pr_type == PR_WATCH);
1378 1383
1379 1384 if ((error = prlock(pnp, ZNO)) != 0)
1380 1385 return (error);
1381 1386
1382 1387 p = pnp->pr_common->prc_proc;
1383 1388 nwarea = avl_numnodes(&p->p_warea);
1384 1389 size = nwarea * sizeof (prwatch_t);
1385 1390 if (uiop->uio_offset >= size) {
1386 1391 prunlock(pnp);
1387 1392 return (0);
1388 1393 }
1389 1394
1390 1395 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1391 1396 mutex_exit(&p->p_lock);
1392 1397 Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
1393 1398 mutex_enter(&p->p_lock);
1394 1399 /* p->p_nwarea can't change while process is locked */
1395 1400 ASSERT(nwarea == avl_numnodes(&p->p_warea));
1396 1401
1397 1402 /* gather the watched areas */
1398 1403 for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
1399 1404 pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
1400 1405 pwp->pr_vaddr = (uintptr_t)pwarea->wa_vaddr;
1401 1406 pwp->pr_size = pwarea->wa_eaddr - pwarea->wa_vaddr;
1402 1407 pwp->pr_wflags = (int)pwarea->wa_flags;
1403 1408 }
1404 1409
1405 1410 prunlock(pnp);
1406 1411
1407 1412 error = pr_uioread(Bpwp, size, uiop);
1408 1413 kmem_free(Bpwp, size);
1409 1414 return (error);
1410 1415 }
1411 1416
1412 1417 static int
1413 1418 pr_read_lwpstatus(prnode_t *pnp, uio_t *uiop)
1414 1419 {
1415 1420 lwpstatus_t *sp;
1416 1421 int error;
1417 1422
1418 1423 ASSERT(pnp->pr_type == PR_LWPSTATUS);
1419 1424
1420 1425 /*
1421 1426 * We kmem_alloc() the lwpstatus structure because
1422 1427 * it is so big it might blow the kernel stack.
1423 1428 */
1424 1429 sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1425 1430
1426 1431 if ((error = prlock(pnp, ZNO)) != 0)
1427 1432 goto out;
1428 1433
1429 1434 if (uiop->uio_offset >= sizeof (*sp)) {
1430 1435 prunlock(pnp);
1431 1436 goto out;
1432 1437 }
1433 1438
1434 1439 prgetlwpstatus(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
1435 1440 prunlock(pnp);
1436 1441
1437 1442 error = pr_uioread(sp, sizeof (*sp), uiop);
1438 1443 out:
1439 1444 kmem_free(sp, sizeof (*sp));
1440 1445 return (error);
1441 1446 }
1442 1447
1443 1448 static int
1444 1449 pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop)
1445 1450 {
1446 1451 lwpsinfo_t lwpsinfo;
1447 1452 proc_t *p;
1448 1453 kthread_t *t;
1449 1454 lwpent_t *lep;
1450 1455
1451 1456 ASSERT(pnp->pr_type == PR_LWPSINFO);
1452 1457
1453 1458 /*
1454 1459 * We don't want the full treatment of prlock(pnp) here.
1455 1460 * This file is world-readable and never goes invalid.
1456 1461 * It doesn't matter if we are in the middle of an exec().
1457 1462 */
1458 1463 p = pr_p_lock(pnp);
1459 1464 mutex_exit(&pr_pidlock);
1460 1465 if (p == NULL)
1461 1466 return (ENOENT);
1462 1467 ASSERT(p == pnp->pr_common->prc_proc);
1463 1468 if (pnp->pr_common->prc_tslot == -1) {
1464 1469 prunlock(pnp);
1465 1470 return (ENOENT);
1466 1471 }
1467 1472
1468 1473 if (uiop->uio_offset >= sizeof (lwpsinfo)) {
1469 1474 prunlock(pnp);
1470 1475 return (0);
1471 1476 }
1472 1477
1473 1478 if ((t = pnp->pr_common->prc_thread) != NULL)
1474 1479 prgetlwpsinfo(t, &lwpsinfo);
1475 1480 else {
1476 1481 lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
1477 1482 bzero(&lwpsinfo, sizeof (lwpsinfo));
1478 1483 lwpsinfo.pr_lwpid = lep->le_lwpid;
1479 1484 lwpsinfo.pr_state = SZOMB;
1480 1485 lwpsinfo.pr_sname = 'Z';
1481 1486 lwpsinfo.pr_start.tv_sec = lep->le_start;
1482 1487 lwpsinfo.pr_bindpro = PBIND_NONE;
1483 1488 lwpsinfo.pr_bindpset = PS_NONE;
1484 1489 }
1485 1490 prunlock(pnp);
1486 1491
1487 1492 return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
1488 1493 }
1489 1494
1490 1495 static int
1491 1496 pr_read_lwpusage(prnode_t *pnp, uio_t *uiop)
1492 1497 {
1493 1498 prhusage_t *pup;
1494 1499 prusage_t *upup;
1495 1500 proc_t *p;
1496 1501 int error;
1497 1502
1498 1503 ASSERT(pnp->pr_type == PR_LWPUSAGE);
1499 1504
1500 1505 /* allocate now, before locking the process */
1501 1506 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1502 1507 upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1503 1508
1504 1509 /*
1505 1510 * We don't want the full treatment of prlock(pnp) here.
1506 1511 * This file is world-readable and never goes invalid.
1507 1512 * It doesn't matter if we are in the middle of an exec().
1508 1513 */
1509 1514 p = pr_p_lock(pnp);
1510 1515 mutex_exit(&pr_pidlock);
1511 1516 if (p == NULL) {
1512 1517 error = ENOENT;
1513 1518 goto out;
1514 1519 }
1515 1520 ASSERT(p == pnp->pr_common->prc_proc);
1516 1521 if (pnp->pr_common->prc_thread == NULL) {
1517 1522 prunlock(pnp);
1518 1523 error = ENOENT;
1519 1524 goto out;
1520 1525 }
1521 1526 if (uiop->uio_offset >= sizeof (prusage_t)) {
1522 1527 prunlock(pnp);
1523 1528 error = 0;
1524 1529 goto out;
1525 1530 }
1526 1531
1527 1532 pup->pr_tstamp = gethrtime();
1528 1533 prgetusage(pnp->pr_common->prc_thread, pup);
1529 1534
1530 1535 prunlock(pnp);
↓ open down ↓ |
444 lines elided |
↑ open up ↑ |
1531 1536
1532 1537 prcvtusage(pup, upup);
1533 1538
1534 1539 error = pr_uioread(upup, sizeof (prusage_t), uiop);
1535 1540 out:
1536 1541 kmem_free(pup, sizeof (*pup));
1537 1542 kmem_free(upup, sizeof (*upup));
1538 1543 return (error);
1539 1544 }
1540 1545
1546 +static int
1547 +pr_read_lwpname(prnode_t *pnp, uio_t *uiop)
1548 +{
1549 + char lwpname[THREAD_NAME_MAX];
1550 + kthread_t *t;
1551 + int error;
1552 +
1553 + ASSERT(pnp->pr_type == PR_LWPNAME);
1554 +
1555 + if (uiop->uio_offset >= THREAD_NAME_MAX)
1556 + return (0);
1557 +
1558 + if ((error = prlock(pnp, ZNO)) != 0)
1559 + return (error);
1560 +
1561 + bzero(lwpname, sizeof (lwpname));
1562 +
1563 + t = pnp->pr_common->prc_thread;
1564 +
1565 + if (t->t_name != NULL)
1566 + (void) strlcpy(lwpname, t->t_name, sizeof (lwpname));
1567 +
1568 + prunlock(pnp);
1569 +
1570 + return (pr_uioread(lwpname, sizeof (lwpname), uiop));
1571 +}
1572 +
1541 1573 /* ARGSUSED */
1542 1574 static int
1543 1575 pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1544 1576 {
1545 1577 #if defined(__sparc)
1546 1578 proc_t *p;
1547 1579 kthread_t *t;
1548 1580 int error;
1549 1581 char *xreg;
1550 1582 size_t size;
1551 1583
1552 1584 ASSERT(pnp->pr_type == PR_XREGS);
1553 1585
1554 1586 xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP);
1555 1587
1556 1588 if ((error = prlock(pnp, ZNO)) != 0)
1557 1589 goto out;
1558 1590
1559 1591 p = pnp->pr_common->prc_proc;
1560 1592 t = pnp->pr_common->prc_thread;
1561 1593
1562 1594 size = prhasx(p)? prgetprxregsize(p) : 0;
1563 1595 if (uiop->uio_offset >= size) {
1564 1596 prunlock(pnp);
1565 1597 goto out;
1566 1598 }
1567 1599
1568 1600 /* drop p->p_lock while (possibly) touching the stack */
1569 1601 mutex_exit(&p->p_lock);
1570 1602 prgetprxregs(ttolwp(t), xreg);
1571 1603 mutex_enter(&p->p_lock);
1572 1604 prunlock(pnp);
1573 1605
1574 1606 error = pr_uioread(xreg, size, uiop);
1575 1607 out:
1576 1608 kmem_free(xreg, sizeof (prxregset_t));
1577 1609 return (error);
1578 1610 #else
1579 1611 return (0);
1580 1612 #endif
1581 1613 }
1582 1614
1583 1615 static int
1584 1616 pr_read_spymaster(prnode_t *pnp, uio_t *uiop)
1585 1617 {
1586 1618 psinfo_t psinfo;
1587 1619 int error;
1588 1620 klwp_t *lwp;
1589 1621
1590 1622 ASSERT(pnp->pr_type == PR_SPYMASTER);
1591 1623
1592 1624 if ((error = prlock(pnp, ZNO)) != 0)
1593 1625 return (error);
1594 1626
1595 1627 if (pnp->pr_common->prc_thread == NULL) {
1596 1628 prunlock(pnp);
1597 1629 return (0);
1598 1630 }
1599 1631
1600 1632 lwp = pnp->pr_common->prc_thread->t_lwp;
1601 1633
1602 1634 if (lwp->lwp_spymaster == NULL) {
1603 1635 prunlock(pnp);
1604 1636 return (0);
1605 1637 }
1606 1638
1607 1639 bcopy(lwp->lwp_spymaster, &psinfo, sizeof (psinfo_t));
1608 1640 prunlock(pnp);
1609 1641
1610 1642 return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
1611 1643 }
1612 1644
1613 1645 static int
1614 1646 pr_read_secflags(prnode_t *pnp, uio_t *uiop)
1615 1647 {
1616 1648 prsecflags_t ret;
1617 1649 int error;
1618 1650 proc_t *p;
1619 1651
1620 1652 ASSERT(pnp->pr_type == PR_SECFLAGS);
1621 1653
1622 1654 if ((error = prlock(pnp, ZNO)) != 0)
1623 1655 return (error);
1624 1656
1625 1657 p = pnp->pr_common->prc_proc;
1626 1658 prgetsecflags(p, &ret);
1627 1659 prunlock(pnp);
1628 1660
1629 1661 return (pr_uioread(&ret, sizeof (ret), uiop));
1630 1662 }
1631 1663
1632 1664 #if defined(__sparc)
1633 1665
1634 1666 static int
1635 1667 pr_read_gwindows(prnode_t *pnp, uio_t *uiop)
1636 1668 {
1637 1669 proc_t *p;
1638 1670 kthread_t *t;
1639 1671 gwindows_t *gwp;
1640 1672 int error;
1641 1673 size_t size;
1642 1674
1643 1675 ASSERT(pnp->pr_type == PR_GWINDOWS);
1644 1676
1645 1677 gwp = kmem_zalloc(sizeof (gwindows_t), KM_SLEEP);
1646 1678
1647 1679 if ((error = prlock(pnp, ZNO)) != 0)
1648 1680 goto out;
1649 1681
1650 1682 p = pnp->pr_common->prc_proc;
1651 1683 t = pnp->pr_common->prc_thread;
1652 1684
1653 1685 /*
1654 1686 * Drop p->p_lock while touching the stack.
1655 1687 * The P_PR_LOCK flag prevents the lwp from
1656 1688 * disappearing while we do this.
1657 1689 */
1658 1690 mutex_exit(&p->p_lock);
1659 1691 if ((size = prnwindows(ttolwp(t))) != 0)
1660 1692 size = sizeof (gwindows_t) -
1661 1693 (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow);
1662 1694 if (uiop->uio_offset >= size) {
1663 1695 mutex_enter(&p->p_lock);
1664 1696 prunlock(pnp);
1665 1697 goto out;
1666 1698 }
1667 1699 prgetwindows(ttolwp(t), gwp);
1668 1700 mutex_enter(&p->p_lock);
1669 1701 prunlock(pnp);
1670 1702
1671 1703 error = pr_uioread(gwp, size, uiop);
1672 1704 out:
1673 1705 kmem_free(gwp, sizeof (gwindows_t));
1674 1706 return (error);
1675 1707 }
1676 1708
1677 1709 /* ARGSUSED */
1678 1710 static int
1679 1711 pr_read_asrs(prnode_t *pnp, uio_t *uiop)
1680 1712 {
1681 1713 int error;
1682 1714
1683 1715 ASSERT(pnp->pr_type == PR_ASRS);
1684 1716
1685 1717 /* the asrs file exists only for sparc v9 _LP64 processes */
1686 1718 if ((error = prlock(pnp, ZNO)) == 0) {
1687 1719 proc_t *p = pnp->pr_common->prc_proc;
1688 1720 kthread_t *t = pnp->pr_common->prc_thread;
1689 1721 asrset_t asrset;
1690 1722
1691 1723 if (p->p_model != DATAMODEL_LP64 ||
1692 1724 uiop->uio_offset >= sizeof (asrset_t)) {
1693 1725 prunlock(pnp);
1694 1726 return (0);
1695 1727 }
1696 1728
1697 1729 /*
1698 1730 * Drop p->p_lock while touching the stack.
1699 1731 * The P_PR_LOCK flag prevents the lwp from
1700 1732 * disappearing while we do this.
1701 1733 */
1702 1734 mutex_exit(&p->p_lock);
1703 1735 prgetasregs(ttolwp(t), asrset);
1704 1736 mutex_enter(&p->p_lock);
1705 1737 prunlock(pnp);
1706 1738
1707 1739 error = pr_uioread(&asrset[0], sizeof (asrset_t), uiop);
1708 1740 }
1709 1741
1710 1742 return (error);
1711 1743 }
1712 1744
1713 1745 #endif /* __sparc */
1714 1746
1715 1747 static int
1716 1748 pr_read_piddir(prnode_t *pnp, uio_t *uiop)
1717 1749 {
1718 1750 ASSERT(pnp->pr_type == PR_PIDDIR);
1719 1751 ASSERT(pnp->pr_pidfile != NULL);
1720 1752
1721 1753 /* use the underlying PR_PIDFILE to read the process */
1722 1754 pnp = VTOP(pnp->pr_pidfile);
1723 1755 ASSERT(pnp->pr_type == PR_PIDFILE);
1724 1756
1725 1757 return (pr_read_pidfile(pnp, uiop));
1726 1758 }
1727 1759
1728 1760 static int
1729 1761 pr_read_pidfile(prnode_t *pnp, uio_t *uiop)
1730 1762 {
1731 1763 int error;
1732 1764
1733 1765 ASSERT(pnp->pr_type == PR_PIDFILE || pnp->pr_type == PR_LWPIDFILE);
1734 1766
1735 1767 if ((error = prlock(pnp, ZNO)) == 0) {
1736 1768 proc_t *p = pnp->pr_common->prc_proc;
1737 1769 struct as *as = p->p_as;
1738 1770
1739 1771 if ((p->p_flag & SSYS) || as == &kas) {
1740 1772 /*
1741 1773 * /proc I/O cannot be done to a system process.
1742 1774 */
1743 1775 error = EIO; /* old /proc semantics */
1744 1776 } else {
1745 1777 /*
1746 1778 * We drop p_lock because we don't want to hold
1747 1779 * it over an I/O operation because that could
1748 1780 * lead to deadlock with the clock thread.
1749 1781 * The process will not disappear and its address
1750 1782 * space will not change because it is marked P_PR_LOCK.
1751 1783 */
1752 1784 mutex_exit(&p->p_lock);
1753 1785 error = prusrio(p, UIO_READ, uiop, 1);
1754 1786 mutex_enter(&p->p_lock);
1755 1787 }
1756 1788 prunlock(pnp);
1757 1789 }
1758 1790
1759 1791 return (error);
1760 1792 }
1761 1793
1762 1794 #ifdef _SYSCALL32_IMPL
1763 1795
1764 1796 /*
1765 1797 * Array of ILP32 read functions, indexed by /proc file type.
1766 1798 */
1767 1799 static int pr_read_status_32(),
1768 1800 pr_read_lstatus_32(), pr_read_psinfo_32(), pr_read_lpsinfo_32(),
1769 1801 pr_read_map_32(), pr_read_rmap_32(), pr_read_xmap_32(),
1770 1802 pr_read_sigact_32(), pr_read_auxv_32(),
1771 1803 pr_read_usage_32(), pr_read_lusage_32(), pr_read_pagedata_32(),
1772 1804 pr_read_watch_32(), pr_read_lwpstatus_32(), pr_read_lwpsinfo_32(),
1773 1805 pr_read_lwpusage_32(), pr_read_spymaster_32(),
1774 1806 #if defined(__sparc)
1775 1807 pr_read_gwindows_32(),
1776 1808 #endif
1777 1809 pr_read_opagedata_32();
1778 1810
1779 1811 static int (*pr_read_function_32[PR_NFILES])() = {
1780 1812 pr_read_inval, /* /proc */
1781 1813 pr_read_inval, /* /proc/self */
1782 1814 pr_read_piddir, /* /proc/<pid> (old /proc read()) */
1783 1815 pr_read_as, /* /proc/<pid>/as */
1784 1816 pr_read_inval, /* /proc/<pid>/ctl */
1785 1817 pr_read_status_32, /* /proc/<pid>/status */
1786 1818 pr_read_lstatus_32, /* /proc/<pid>/lstatus */
1787 1819 pr_read_psinfo_32, /* /proc/<pid>/psinfo */
1788 1820 pr_read_lpsinfo_32, /* /proc/<pid>/lpsinfo */
1789 1821 pr_read_map_32, /* /proc/<pid>/map */
1790 1822 pr_read_rmap_32, /* /proc/<pid>/rmap */
1791 1823 pr_read_xmap_32, /* /proc/<pid>/xmap */
1792 1824 pr_read_cred, /* /proc/<pid>/cred */
1793 1825 pr_read_sigact_32, /* /proc/<pid>/sigact */
1794 1826 pr_read_auxv_32, /* /proc/<pid>/auxv */
1795 1827 #if defined(__x86)
1796 1828 pr_read_ldt, /* /proc/<pid>/ldt */
1797 1829 #endif
1798 1830 pr_read_usage_32, /* /proc/<pid>/usage */
1799 1831 pr_read_lusage_32, /* /proc/<pid>/lusage */
1800 1832 pr_read_pagedata_32, /* /proc/<pid>/pagedata */
↓ open down ↓ |
250 lines elided |
↑ open up ↑ |
1801 1833 pr_read_watch_32, /* /proc/<pid>/watch */
1802 1834 pr_read_inval, /* /proc/<pid>/cwd */
1803 1835 pr_read_inval, /* /proc/<pid>/root */
1804 1836 pr_read_inval, /* /proc/<pid>/fd */
1805 1837 pr_read_inval, /* /proc/<pid>/fd/nn */
1806 1838 pr_read_inval, /* /proc/<pid>/object */
1807 1839 pr_read_inval, /* /proc/<pid>/object/xxx */
1808 1840 pr_read_inval, /* /proc/<pid>/lwp */
1809 1841 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
1810 1842 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
1843 + pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */
1811 1844 pr_read_lwpstatus_32, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
1812 1845 pr_read_lwpsinfo_32, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1813 1846 pr_read_lwpusage_32, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1814 1847 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
1815 1848 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
1816 1849 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1817 1850 pr_read_spymaster_32, /* /proc/<pid>/lwp/<lwpid>/spymaster */
1818 1851 #if defined(__sparc)
1819 1852 pr_read_gwindows_32, /* /proc/<pid>/lwp/<lwpid>/gwindows */
1820 1853 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */
1821 1854 #endif
1822 1855 pr_read_priv, /* /proc/<pid>/priv */
1823 1856 pr_read_inval, /* /proc/<pid>/path */
1824 1857 pr_read_inval, /* /proc/<pid>/path/xxx */
1825 1858 pr_read_inval, /* /proc/<pid>/contracts */
1826 1859 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */
1827 1860 pr_read_secflags, /* /proc/<pid>/secflags */
1828 1861 pr_read_pidfile, /* old process file */
1829 1862 pr_read_pidfile, /* old lwp file */
1830 1863 pr_read_opagedata_32, /* old pagedata file */
1831 1864 };
1832 1865
1833 1866 static int
1834 1867 pr_read_status_32(prnode_t *pnp, uio_t *uiop)
1835 1868 {
1836 1869 pstatus32_t *sp;
1837 1870 proc_t *p;
1838 1871 int error;
1839 1872
1840 1873 ASSERT(pnp->pr_type == PR_STATUS);
1841 1874
1842 1875 /*
1843 1876 * We kmem_alloc() the pstatus structure because
1844 1877 * it is so big it might blow the kernel stack.
1845 1878 */
1846 1879 sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1847 1880 if ((error = prlock(pnp, ZNO)) == 0) {
1848 1881 /*
1849 1882 * A 32-bit process cannot get the status of a 64-bit process.
1850 1883 * The fields for the 64-bit quantities are not large enough.
1851 1884 */
1852 1885 p = pnp->pr_common->prc_proc;
1853 1886 if (PROCESS_NOT_32BIT(p)) {
1854 1887 prunlock(pnp);
1855 1888 error = EOVERFLOW;
1856 1889 } else {
1857 1890 prgetstatus32(pnp->pr_common->prc_proc, sp,
1858 1891 VTOZONE(PTOV(pnp)));
1859 1892 prunlock(pnp);
1860 1893 error = pr_uioread(sp, sizeof (*sp), uiop);
1861 1894 }
1862 1895 }
1863 1896 kmem_free((caddr_t)sp, sizeof (*sp));
1864 1897 return (error);
1865 1898 }
1866 1899
1867 1900 static int
1868 1901 pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop)
1869 1902 {
1870 1903 proc_t *p;
1871 1904 kthread_t *t;
1872 1905 lwpdir_t *ldp;
1873 1906 size_t size;
1874 1907 prheader32_t *php;
1875 1908 lwpstatus32_t *sp;
1876 1909 int error;
1877 1910 int nlwp;
1878 1911 int i;
1879 1912
1880 1913 ASSERT(pnp->pr_type == PR_LSTATUS);
1881 1914
1882 1915 if ((error = prlock(pnp, ZNO)) != 0)
1883 1916 return (error);
1884 1917 p = pnp->pr_common->prc_proc;
1885 1918 /*
1886 1919 * A 32-bit process cannot get the status of a 64-bit process.
1887 1920 * The fields for the 64-bit quantities are not large enough.
1888 1921 */
1889 1922 if (PROCESS_NOT_32BIT(p)) {
1890 1923 prunlock(pnp);
1891 1924 return (EOVERFLOW);
1892 1925 }
1893 1926 nlwp = p->p_lwpcnt;
1894 1927 size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpstatus32_t);
1895 1928
1896 1929 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1897 1930 mutex_exit(&p->p_lock);
1898 1931 php = kmem_zalloc(size, KM_SLEEP);
1899 1932 mutex_enter(&p->p_lock);
1900 1933 /* p->p_lwpcnt can't change while process is locked */
1901 1934 ASSERT(nlwp == p->p_lwpcnt);
1902 1935
1903 1936 php->pr_nent = nlwp;
1904 1937 php->pr_entsize = LSPAN32(lwpstatus32_t);
1905 1938
1906 1939 sp = (lwpstatus32_t *)(php + 1);
1907 1940 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1908 1941 if (ldp->ld_entry == NULL ||
1909 1942 (t = ldp->ld_entry->le_thread) == NULL)
1910 1943 continue;
1911 1944 prgetlwpstatus32(t, sp, VTOZONE(PTOV(pnp)));
1912 1945 sp = (lwpstatus32_t *)((caddr_t)sp + LSPAN32(lwpstatus32_t));
1913 1946 }
1914 1947 prunlock(pnp);
1915 1948
1916 1949 error = pr_uioread(php, size, uiop);
1917 1950 kmem_free(php, size);
1918 1951 return (error);
1919 1952 }
1920 1953
1921 1954 static int
1922 1955 pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop)
1923 1956 {
1924 1957 psinfo32_t psinfo;
1925 1958 proc_t *p;
1926 1959 int error = 0;
1927 1960
1928 1961 ASSERT(pnp->pr_type == PR_PSINFO);
1929 1962
1930 1963 /*
1931 1964 * We don't want the full treatment of prlock(pnp) here.
1932 1965 * This file is world-readable and never goes invalid.
1933 1966 * It doesn't matter if we are in the middle of an exec().
1934 1967 */
1935 1968 p = pr_p_lock(pnp);
1936 1969 mutex_exit(&pr_pidlock);
1937 1970 if (p == NULL)
1938 1971 error = ENOENT;
1939 1972 else {
1940 1973 ASSERT(p == pnp->pr_common->prc_proc);
1941 1974 prgetpsinfo32(p, &psinfo);
1942 1975 prunlock(pnp);
1943 1976 error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
1944 1977 }
1945 1978 return (error);
1946 1979 }
1947 1980
1948 1981 static int
1949 1982 pr_read_lpsinfo_32(prnode_t *pnp, uio_t *uiop)
1950 1983 {
1951 1984 proc_t *p;
1952 1985 kthread_t *t;
1953 1986 lwpdir_t *ldp;
1954 1987 lwpent_t *lep;
1955 1988 size_t size;
1956 1989 prheader32_t *php;
1957 1990 lwpsinfo32_t *sp;
1958 1991 int error;
1959 1992 int nlwp;
1960 1993 int i;
1961 1994
1962 1995 ASSERT(pnp->pr_type == PR_LPSINFO);
1963 1996
1964 1997 /*
1965 1998 * We don't want the full treatment of prlock(pnp) here.
1966 1999 * This file is world-readable and never goes invalid.
1967 2000 * It doesn't matter if we are in the middle of an exec().
1968 2001 */
1969 2002 p = pr_p_lock(pnp);
1970 2003 mutex_exit(&pr_pidlock);
1971 2004 if (p == NULL)
1972 2005 return (ENOENT);
1973 2006 ASSERT(p == pnp->pr_common->prc_proc);
1974 2007 if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
1975 2008 prunlock(pnp);
1976 2009 return (ENOENT);
1977 2010 }
1978 2011 size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpsinfo32_t);
1979 2012
1980 2013 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1981 2014 mutex_exit(&p->p_lock);
1982 2015 php = kmem_zalloc(size, KM_SLEEP);
1983 2016 mutex_enter(&p->p_lock);
1984 2017 /* p->p_lwpcnt can't change while process is locked */
1985 2018 ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
1986 2019
1987 2020 php->pr_nent = nlwp;
1988 2021 php->pr_entsize = LSPAN32(lwpsinfo32_t);
1989 2022
1990 2023 sp = (lwpsinfo32_t *)(php + 1);
1991 2024 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1992 2025 if ((lep = ldp->ld_entry) == NULL)
1993 2026 continue;
1994 2027 if ((t = lep->le_thread) != NULL)
1995 2028 prgetlwpsinfo32(t, sp);
1996 2029 else {
1997 2030 bzero(sp, sizeof (*sp));
1998 2031 sp->pr_lwpid = lep->le_lwpid;
1999 2032 sp->pr_state = SZOMB;
2000 2033 sp->pr_sname = 'Z';
2001 2034 sp->pr_start.tv_sec = (time32_t)lep->le_start;
2002 2035 }
2003 2036 sp = (lwpsinfo32_t *)((caddr_t)sp + LSPAN32(lwpsinfo32_t));
2004 2037 }
2005 2038 prunlock(pnp);
2006 2039
2007 2040 error = pr_uioread(php, size, uiop);
2008 2041 kmem_free(php, size);
2009 2042 return (error);
2010 2043 }
2011 2044
2012 2045 static int
2013 2046 pr_read_map_common_32(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
2014 2047 {
2015 2048 proc_t *p;
2016 2049 struct as *as;
2017 2050 list_t iolhead;
2018 2051 int error;
2019 2052
2020 2053 readmap32_common:
2021 2054 if ((error = prlock(pnp, ZNO)) != 0)
2022 2055 return (error);
2023 2056
2024 2057 p = pnp->pr_common->prc_proc;
2025 2058 as = p->p_as;
2026 2059
2027 2060 if ((p->p_flag & SSYS) || as == &kas) {
2028 2061 prunlock(pnp);
2029 2062 return (0);
2030 2063 }
2031 2064
2032 2065 if (PROCESS_NOT_32BIT(p)) {
2033 2066 prunlock(pnp);
2034 2067 return (EOVERFLOW);
2035 2068 }
2036 2069
2037 2070 if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
2038 2071 prunlock(pnp);
2039 2072 delay(1);
2040 2073 goto readmap32_common;
2041 2074 }
2042 2075 mutex_exit(&p->p_lock);
2043 2076
2044 2077 switch (type) {
2045 2078 case PR_XMAP:
2046 2079 error = prgetxmap32(p, &iolhead);
2047 2080 break;
2048 2081 case PR_RMAP:
2049 2082 error = prgetmap32(p, 1, &iolhead);
2050 2083 break;
2051 2084 case PR_MAP:
2052 2085 error = prgetmap32(p, 0, &iolhead);
2053 2086 break;
2054 2087 }
2055 2088 AS_LOCK_EXIT(as);
2056 2089 mutex_enter(&p->p_lock);
2057 2090 prunlock(pnp);
2058 2091
2059 2092 error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
2060 2093
2061 2094 return (error);
2062 2095 }
2063 2096
2064 2097 static int
2065 2098 pr_read_map_32(prnode_t *pnp, uio_t *uiop)
2066 2099 {
2067 2100 ASSERT(pnp->pr_type == PR_MAP);
2068 2101 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2069 2102 }
2070 2103
2071 2104 static int
2072 2105 pr_read_rmap_32(prnode_t *pnp, uio_t *uiop)
2073 2106 {
2074 2107 ASSERT(pnp->pr_type == PR_RMAP);
2075 2108 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2076 2109 }
2077 2110
2078 2111 static int
2079 2112 pr_read_xmap_32(prnode_t *pnp, uio_t *uiop)
2080 2113 {
2081 2114 ASSERT(pnp->pr_type == PR_XMAP);
2082 2115 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2083 2116 }
2084 2117
2085 2118 static int
2086 2119 pr_read_sigact_32(prnode_t *pnp, uio_t *uiop)
2087 2120 {
2088 2121 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
2089 2122 proc_t *p;
2090 2123 struct sigaction32 *sap;
2091 2124 int sig;
2092 2125 int error;
2093 2126 user_t *up;
2094 2127
2095 2128 ASSERT(pnp->pr_type == PR_SIGACT);
2096 2129
2097 2130 /*
2098 2131 * We kmem_alloc() the sigaction32 array because
2099 2132 * it is so big it might blow the kernel stack.
2100 2133 */
2101 2134 sap = kmem_alloc((nsig-1) * sizeof (struct sigaction32), KM_SLEEP);
2102 2135
2103 2136 if ((error = prlock(pnp, ZNO)) != 0)
2104 2137 goto out;
2105 2138 p = pnp->pr_common->prc_proc;
2106 2139
2107 2140 if (PROCESS_NOT_32BIT(p)) {
2108 2141 prunlock(pnp);
2109 2142 error = EOVERFLOW;
2110 2143 goto out;
2111 2144 }
2112 2145
2113 2146 if (uiop->uio_offset >= (nsig-1) * sizeof (struct sigaction32)) {
2114 2147 prunlock(pnp);
2115 2148 goto out;
2116 2149 }
2117 2150
2118 2151 up = PTOU(p);
2119 2152 for (sig = 1; sig < nsig; sig++)
2120 2153 prgetaction32(p, up, sig, &sap[sig-1]);
2121 2154 prunlock(pnp);
2122 2155
2123 2156 error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction32), uiop);
2124 2157 out:
2125 2158 kmem_free(sap, (nsig-1) * sizeof (struct sigaction32));
2126 2159 return (error);
2127 2160 }
2128 2161
2129 2162 static int
2130 2163 pr_read_auxv_32(prnode_t *pnp, uio_t *uiop)
2131 2164 {
2132 2165 auxv32_t auxv[__KERN_NAUXV_IMPL];
2133 2166 proc_t *p;
2134 2167 user_t *up;
2135 2168 int error;
2136 2169 int i;
2137 2170
2138 2171 ASSERT(pnp->pr_type == PR_AUXV);
2139 2172
2140 2173 if ((error = prlock(pnp, ZNO)) != 0)
2141 2174 return (error);
2142 2175 p = pnp->pr_common->prc_proc;
2143 2176
2144 2177 if (PROCESS_NOT_32BIT(p)) {
2145 2178 prunlock(pnp);
2146 2179 return (EOVERFLOW);
2147 2180 }
2148 2181
2149 2182 if (uiop->uio_offset >= sizeof (auxv)) {
2150 2183 prunlock(pnp);
2151 2184 return (0);
2152 2185 }
2153 2186
2154 2187 up = PTOU(p);
2155 2188 for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
2156 2189 auxv[i].a_type = (int32_t)up->u_auxv[i].a_type;
2157 2190 auxv[i].a_un.a_val = (int32_t)up->u_auxv[i].a_un.a_val;
2158 2191 }
2159 2192 prunlock(pnp);
2160 2193
2161 2194 return (pr_uioread(auxv, sizeof (auxv), uiop));
2162 2195 }
2163 2196
2164 2197 static int
2165 2198 pr_read_usage_32(prnode_t *pnp, uio_t *uiop)
2166 2199 {
2167 2200 prhusage_t *pup;
2168 2201 prusage32_t *upup;
2169 2202 proc_t *p;
2170 2203 kthread_t *t;
2171 2204 int error;
2172 2205
2173 2206 ASSERT(pnp->pr_type == PR_USAGE);
2174 2207
2175 2208 /* allocate now, before locking the process */
2176 2209 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2177 2210 upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2178 2211
2179 2212 /*
2180 2213 * We don't want the full treatment of prlock(pnp) here.
2181 2214 * This file is world-readable and never goes invalid.
2182 2215 * It doesn't matter if we are in the middle of an exec().
2183 2216 */
2184 2217 p = pr_p_lock(pnp);
2185 2218 mutex_exit(&pr_pidlock);
2186 2219 if (p == NULL) {
2187 2220 error = ENOENT;
2188 2221 goto out;
2189 2222 }
2190 2223 ASSERT(p == pnp->pr_common->prc_proc);
2191 2224
2192 2225 if (uiop->uio_offset >= sizeof (prusage32_t)) {
2193 2226 prunlock(pnp);
2194 2227 error = 0;
2195 2228 goto out;
2196 2229 }
2197 2230
2198 2231 pup->pr_tstamp = gethrtime();
2199 2232
2200 2233 pup->pr_count = p->p_defunct;
2201 2234 pup->pr_create = p->p_mstart;
2202 2235 pup->pr_term = p->p_mterm;
2203 2236
2204 2237 pup->pr_rtime = p->p_mlreal;
2205 2238 pup->pr_utime = p->p_acct[LMS_USER];
2206 2239 pup->pr_stime = p->p_acct[LMS_SYSTEM];
2207 2240 pup->pr_ttime = p->p_acct[LMS_TRAP];
2208 2241 pup->pr_tftime = p->p_acct[LMS_TFAULT];
2209 2242 pup->pr_dftime = p->p_acct[LMS_DFAULT];
2210 2243 pup->pr_kftime = p->p_acct[LMS_KFAULT];
2211 2244 pup->pr_ltime = p->p_acct[LMS_USER_LOCK];
2212 2245 pup->pr_slptime = p->p_acct[LMS_SLEEP];
2213 2246 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU];
2214 2247 pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2215 2248
2216 2249 pup->pr_minf = p->p_ru.minflt;
2217 2250 pup->pr_majf = p->p_ru.majflt;
2218 2251 pup->pr_nswap = p->p_ru.nswap;
2219 2252 pup->pr_inblk = p->p_ru.inblock;
2220 2253 pup->pr_oublk = p->p_ru.oublock;
2221 2254 pup->pr_msnd = p->p_ru.msgsnd;
2222 2255 pup->pr_mrcv = p->p_ru.msgrcv;
2223 2256 pup->pr_sigs = p->p_ru.nsignals;
2224 2257 pup->pr_vctx = p->p_ru.nvcsw;
2225 2258 pup->pr_ictx = p->p_ru.nivcsw;
2226 2259 pup->pr_sysc = p->p_ru.sysc;
2227 2260 pup->pr_ioch = p->p_ru.ioch;
2228 2261
2229 2262 /*
2230 2263 * Add the usage information for each active lwp.
2231 2264 */
2232 2265 if ((t = p->p_tlist) != NULL &&
2233 2266 !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
2234 2267 do {
2235 2268 if (t->t_proc_flag & TP_LWPEXIT)
2236 2269 continue;
2237 2270 pup->pr_count++;
2238 2271 praddusage(t, pup);
2239 2272 } while ((t = t->t_forw) != p->p_tlist);
2240 2273 }
2241 2274
2242 2275 prunlock(pnp);
2243 2276
2244 2277 prcvtusage32(pup, upup);
2245 2278
2246 2279 error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2247 2280 out:
2248 2281 kmem_free(pup, sizeof (*pup));
2249 2282 kmem_free(upup, sizeof (*upup));
2250 2283 return (error);
2251 2284 }
2252 2285
2253 2286 static int
2254 2287 pr_read_lusage_32(prnode_t *pnp, uio_t *uiop)
2255 2288 {
2256 2289 int nlwp;
2257 2290 prhusage_t *pup;
2258 2291 prheader32_t *php;
2259 2292 prusage32_t *upup;
2260 2293 size_t size;
2261 2294 hrtime_t curtime;
2262 2295 proc_t *p;
2263 2296 kthread_t *t;
2264 2297 lwpdir_t *ldp;
2265 2298 int error;
2266 2299 int i;
2267 2300
2268 2301 ASSERT(pnp->pr_type == PR_LUSAGE);
2269 2302
2270 2303 /*
2271 2304 * We don't want the full treatment of prlock(pnp) here.
2272 2305 * This file is world-readable and never goes invalid.
2273 2306 * It doesn't matter if we are in the middle of an exec().
2274 2307 */
2275 2308 p = pr_p_lock(pnp);
2276 2309 mutex_exit(&pr_pidlock);
2277 2310 if (p == NULL)
2278 2311 return (ENOENT);
2279 2312 ASSERT(p == pnp->pr_common->prc_proc);
2280 2313 if ((nlwp = p->p_lwpcnt) == 0) {
2281 2314 prunlock(pnp);
2282 2315 return (ENOENT);
2283 2316 }
2284 2317
2285 2318 size = sizeof (prheader32_t) + (nlwp + 1) * LSPAN32(prusage32_t);
2286 2319 if (uiop->uio_offset >= size) {
2287 2320 prunlock(pnp);
2288 2321 return (0);
2289 2322 }
2290 2323
2291 2324 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2292 2325 mutex_exit(&p->p_lock);
2293 2326 pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
2294 2327 mutex_enter(&p->p_lock);
2295 2328 /* p->p_lwpcnt can't change while process is locked */
2296 2329 ASSERT(nlwp == p->p_lwpcnt);
2297 2330
2298 2331 php = (prheader32_t *)(pup + 1);
2299 2332 upup = (prusage32_t *)(php + 1);
2300 2333
2301 2334 php->pr_nent = nlwp + 1;
2302 2335 php->pr_entsize = LSPAN32(prusage32_t);
2303 2336
2304 2337 curtime = gethrtime();
2305 2338
2306 2339 /*
2307 2340 * First the summation over defunct lwps.
2308 2341 */
2309 2342 pup->pr_count = p->p_defunct;
2310 2343 pup->pr_tstamp = curtime;
2311 2344 pup->pr_create = p->p_mstart;
2312 2345 pup->pr_term = p->p_mterm;
2313 2346
2314 2347 pup->pr_rtime = p->p_mlreal;
2315 2348 pup->pr_utime = p->p_acct[LMS_USER];
2316 2349 pup->pr_stime = p->p_acct[LMS_SYSTEM];
2317 2350 pup->pr_ttime = p->p_acct[LMS_TRAP];
2318 2351 pup->pr_tftime = p->p_acct[LMS_TFAULT];
2319 2352 pup->pr_dftime = p->p_acct[LMS_DFAULT];
2320 2353 pup->pr_kftime = p->p_acct[LMS_KFAULT];
2321 2354 pup->pr_ltime = p->p_acct[LMS_USER_LOCK];
2322 2355 pup->pr_slptime = p->p_acct[LMS_SLEEP];
2323 2356 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU];
2324 2357 pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2325 2358
2326 2359 pup->pr_minf = p->p_ru.minflt;
2327 2360 pup->pr_majf = p->p_ru.majflt;
2328 2361 pup->pr_nswap = p->p_ru.nswap;
2329 2362 pup->pr_inblk = p->p_ru.inblock;
2330 2363 pup->pr_oublk = p->p_ru.oublock;
2331 2364 pup->pr_msnd = p->p_ru.msgsnd;
2332 2365 pup->pr_mrcv = p->p_ru.msgrcv;
2333 2366 pup->pr_sigs = p->p_ru.nsignals;
2334 2367 pup->pr_vctx = p->p_ru.nvcsw;
2335 2368 pup->pr_ictx = p->p_ru.nivcsw;
2336 2369 pup->pr_sysc = p->p_ru.sysc;
2337 2370 pup->pr_ioch = p->p_ru.ioch;
2338 2371
2339 2372 prcvtusage32(pup, upup);
2340 2373
2341 2374 /*
2342 2375 * Fill one prusage struct for each active lwp.
2343 2376 */
2344 2377 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
2345 2378 if (ldp->ld_entry == NULL ||
2346 2379 (t = ldp->ld_entry->le_thread) == NULL)
2347 2380 continue;
2348 2381 ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
2349 2382 ASSERT(nlwp > 0);
2350 2383 --nlwp;
2351 2384 upup = (prusage32_t *)
2352 2385 ((caddr_t)upup + LSPAN32(prusage32_t));
2353 2386 prgetusage(t, pup);
2354 2387 prcvtusage32(pup, upup);
2355 2388 }
2356 2389 ASSERT(nlwp == 0);
2357 2390
2358 2391 prunlock(pnp);
2359 2392
2360 2393 error = pr_uioread(php, size, uiop);
2361 2394 kmem_free(pup, size + sizeof (prhusage_t));
2362 2395 return (error);
2363 2396 }
2364 2397
2365 2398 static int
2366 2399 pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop)
2367 2400 {
2368 2401 proc_t *p;
2369 2402 int error;
2370 2403
2371 2404 ASSERT(pnp->pr_type == PR_PAGEDATA);
2372 2405
2373 2406 if ((error = prlock(pnp, ZNO)) != 0)
2374 2407 return (error);
2375 2408
2376 2409 p = pnp->pr_common->prc_proc;
2377 2410 if ((p->p_flag & SSYS) || p->p_as == &kas) {
2378 2411 prunlock(pnp);
2379 2412 return (0);
2380 2413 }
2381 2414
2382 2415 if (PROCESS_NOT_32BIT(p)) {
2383 2416 prunlock(pnp);
2384 2417 return (EOVERFLOW);
2385 2418 }
2386 2419
2387 2420 mutex_exit(&p->p_lock);
2388 2421 error = prpdread32(p, pnp->pr_hatid, uiop);
2389 2422 mutex_enter(&p->p_lock);
2390 2423
2391 2424 prunlock(pnp);
2392 2425 return (error);
2393 2426 }
2394 2427
2395 2428 static int
2396 2429 pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop)
2397 2430 {
2398 2431 proc_t *p;
2399 2432 struct as *as;
2400 2433 int error;
2401 2434
2402 2435 ASSERT(pnp->pr_type == PR_OPAGEDATA);
2403 2436
2404 2437 if ((error = prlock(pnp, ZNO)) != 0)
2405 2438 return (error);
2406 2439
2407 2440 p = pnp->pr_common->prc_proc;
2408 2441 as = p->p_as;
2409 2442
2410 2443 if ((p->p_flag & SSYS) || as == &kas) {
2411 2444 prunlock(pnp);
2412 2445 return (0);
2413 2446 }
2414 2447
2415 2448 if (PROCESS_NOT_32BIT(p)) {
2416 2449 prunlock(pnp);
2417 2450 return (EOVERFLOW);
2418 2451 }
2419 2452
2420 2453 mutex_exit(&p->p_lock);
2421 2454 error = oprpdread32(as, pnp->pr_hatid, uiop);
2422 2455 mutex_enter(&p->p_lock);
2423 2456
2424 2457 prunlock(pnp);
2425 2458 return (error);
2426 2459 }
2427 2460
2428 2461 static int
2429 2462 pr_read_watch_32(prnode_t *pnp, uio_t *uiop)
2430 2463 {
2431 2464 proc_t *p;
2432 2465 int error;
2433 2466 prwatch32_t *Bpwp;
2434 2467 size_t size;
2435 2468 prwatch32_t *pwp;
2436 2469 int nwarea;
2437 2470 struct watched_area *pwarea;
2438 2471
2439 2472 ASSERT(pnp->pr_type == PR_WATCH);
2440 2473
2441 2474 if ((error = prlock(pnp, ZNO)) != 0)
2442 2475 return (error);
2443 2476
2444 2477 p = pnp->pr_common->prc_proc;
2445 2478 if (PROCESS_NOT_32BIT(p)) {
2446 2479 prunlock(pnp);
2447 2480 return (EOVERFLOW);
2448 2481 }
2449 2482 nwarea = avl_numnodes(&p->p_warea);
2450 2483 size = nwarea * sizeof (prwatch32_t);
2451 2484 if (uiop->uio_offset >= size) {
2452 2485 prunlock(pnp);
2453 2486 return (0);
2454 2487 }
2455 2488
2456 2489 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2457 2490 mutex_exit(&p->p_lock);
2458 2491 Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
2459 2492 mutex_enter(&p->p_lock);
2460 2493 /* p->p_nwarea can't change while process is locked */
2461 2494 ASSERT(nwarea == avl_numnodes(&p->p_warea));
2462 2495
2463 2496 /* gather the watched areas */
2464 2497 for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
2465 2498 pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
2466 2499 pwp->pr_vaddr = (caddr32_t)(uintptr_t)pwarea->wa_vaddr;
2467 2500 pwp->pr_size = (size32_t)(pwarea->wa_eaddr - pwarea->wa_vaddr);
2468 2501 pwp->pr_wflags = (int)pwarea->wa_flags;
2469 2502 }
2470 2503
2471 2504 prunlock(pnp);
2472 2505
2473 2506 error = pr_uioread(Bpwp, size, uiop);
2474 2507 kmem_free(Bpwp, size);
2475 2508 return (error);
2476 2509 }
2477 2510
2478 2511 static int
2479 2512 pr_read_lwpstatus_32(prnode_t *pnp, uio_t *uiop)
2480 2513 {
2481 2514 lwpstatus32_t *sp;
2482 2515 proc_t *p;
2483 2516 int error;
2484 2517
2485 2518 ASSERT(pnp->pr_type == PR_LWPSTATUS);
2486 2519
2487 2520 /*
2488 2521 * We kmem_alloc() the lwpstatus structure because
2489 2522 * it is so big it might blow the kernel stack.
2490 2523 */
2491 2524 sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
2492 2525
2493 2526 if ((error = prlock(pnp, ZNO)) != 0)
2494 2527 goto out;
2495 2528
2496 2529 /*
2497 2530 * A 32-bit process cannot get the status of a 64-bit process.
2498 2531 * The fields for the 64-bit quantities are not large enough.
2499 2532 */
2500 2533 p = pnp->pr_common->prc_proc;
2501 2534 if (PROCESS_NOT_32BIT(p)) {
2502 2535 prunlock(pnp);
2503 2536 error = EOVERFLOW;
2504 2537 goto out;
2505 2538 }
2506 2539
2507 2540 if (uiop->uio_offset >= sizeof (*sp)) {
2508 2541 prunlock(pnp);
2509 2542 goto out;
2510 2543 }
2511 2544
2512 2545 prgetlwpstatus32(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
2513 2546 prunlock(pnp);
2514 2547
2515 2548 error = pr_uioread(sp, sizeof (*sp), uiop);
2516 2549 out:
2517 2550 kmem_free(sp, sizeof (*sp));
2518 2551 return (error);
2519 2552 }
2520 2553
2521 2554 static int
2522 2555 pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop)
2523 2556 {
2524 2557 lwpsinfo32_t lwpsinfo;
2525 2558 proc_t *p;
2526 2559 kthread_t *t;
2527 2560 lwpent_t *lep;
2528 2561
2529 2562 ASSERT(pnp->pr_type == PR_LWPSINFO);
2530 2563
2531 2564 /*
2532 2565 * We don't want the full treatment of prlock(pnp) here.
2533 2566 * This file is world-readable and never goes invalid.
2534 2567 * It doesn't matter if we are in the middle of an exec().
2535 2568 */
2536 2569 p = pr_p_lock(pnp);
2537 2570 mutex_exit(&pr_pidlock);
2538 2571 if (p == NULL)
2539 2572 return (ENOENT);
2540 2573 ASSERT(p == pnp->pr_common->prc_proc);
2541 2574 if (pnp->pr_common->prc_tslot == -1) {
2542 2575 prunlock(pnp);
2543 2576 return (ENOENT);
2544 2577 }
2545 2578
2546 2579 if (uiop->uio_offset >= sizeof (lwpsinfo)) {
2547 2580 prunlock(pnp);
2548 2581 return (0);
2549 2582 }
2550 2583
2551 2584 if ((t = pnp->pr_common->prc_thread) != NULL)
2552 2585 prgetlwpsinfo32(t, &lwpsinfo);
2553 2586 else {
2554 2587 lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
2555 2588 bzero(&lwpsinfo, sizeof (lwpsinfo));
2556 2589 lwpsinfo.pr_lwpid = lep->le_lwpid;
2557 2590 lwpsinfo.pr_state = SZOMB;
2558 2591 lwpsinfo.pr_sname = 'Z';
2559 2592 lwpsinfo.pr_start.tv_sec = (time32_t)lep->le_start;
2560 2593 }
2561 2594 prunlock(pnp);
2562 2595
2563 2596 return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
2564 2597 }
2565 2598
2566 2599 static int
2567 2600 pr_read_lwpusage_32(prnode_t *pnp, uio_t *uiop)
2568 2601 {
2569 2602 prhusage_t *pup;
2570 2603 prusage32_t *upup;
2571 2604 proc_t *p;
2572 2605 int error;
2573 2606
2574 2607 ASSERT(pnp->pr_type == PR_LWPUSAGE);
2575 2608
2576 2609 /* allocate now, before locking the process */
2577 2610 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2578 2611 upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2579 2612
2580 2613 /*
2581 2614 * We don't want the full treatment of prlock(pnp) here.
2582 2615 * This file is world-readable and never goes invalid.
2583 2616 * It doesn't matter if we are in the middle of an exec().
2584 2617 */
2585 2618 p = pr_p_lock(pnp);
2586 2619 mutex_exit(&pr_pidlock);
2587 2620 if (p == NULL) {
2588 2621 error = ENOENT;
2589 2622 goto out;
2590 2623 }
2591 2624 ASSERT(p == pnp->pr_common->prc_proc);
2592 2625 if (pnp->pr_common->prc_thread == NULL) {
2593 2626 prunlock(pnp);
2594 2627 error = ENOENT;
2595 2628 goto out;
2596 2629 }
2597 2630 if (uiop->uio_offset >= sizeof (prusage32_t)) {
2598 2631 prunlock(pnp);
2599 2632 error = 0;
2600 2633 goto out;
2601 2634 }
2602 2635
2603 2636 pup->pr_tstamp = gethrtime();
2604 2637 prgetusage(pnp->pr_common->prc_thread, pup);
2605 2638
2606 2639 prunlock(pnp);
2607 2640
2608 2641 prcvtusage32(pup, upup);
2609 2642
2610 2643 error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2611 2644 out:
2612 2645 kmem_free(pup, sizeof (*pup));
2613 2646 kmem_free(upup, sizeof (*upup));
2614 2647 return (error);
2615 2648 }
2616 2649
2617 2650 static int
2618 2651 pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop)
2619 2652 {
2620 2653 psinfo32_t psinfo;
2621 2654 int error;
2622 2655 klwp_t *lwp;
2623 2656
2624 2657 ASSERT(pnp->pr_type == PR_SPYMASTER);
2625 2658
2626 2659 if ((error = prlock(pnp, ZNO)) != 0)
2627 2660 return (error);
2628 2661
2629 2662 if (pnp->pr_common->prc_thread == NULL) {
2630 2663 prunlock(pnp);
2631 2664 return (0);
2632 2665 }
2633 2666
2634 2667 lwp = pnp->pr_common->prc_thread->t_lwp;
2635 2668
2636 2669 if (lwp->lwp_spymaster == NULL) {
2637 2670 prunlock(pnp);
2638 2671 return (0);
2639 2672 }
2640 2673
2641 2674 psinfo_kto32(lwp->lwp_spymaster, &psinfo);
2642 2675 prunlock(pnp);
2643 2676
2644 2677 return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
2645 2678 }
2646 2679
2647 2680 #if defined(__sparc)
2648 2681 static int
2649 2682 pr_read_gwindows_32(prnode_t *pnp, uio_t *uiop)
2650 2683 {
2651 2684 proc_t *p;
2652 2685 kthread_t *t;
2653 2686 gwindows32_t *gwp;
2654 2687 int error;
2655 2688 size_t size;
2656 2689
2657 2690 ASSERT(pnp->pr_type == PR_GWINDOWS);
2658 2691
2659 2692 gwp = kmem_zalloc(sizeof (gwindows32_t), KM_SLEEP);
2660 2693
2661 2694 if ((error = prlock(pnp, ZNO)) != 0)
2662 2695 goto out;
2663 2696
2664 2697 p = pnp->pr_common->prc_proc;
2665 2698 t = pnp->pr_common->prc_thread;
2666 2699
2667 2700 if (PROCESS_NOT_32BIT(p)) {
2668 2701 prunlock(pnp);
2669 2702 error = EOVERFLOW;
2670 2703 goto out;
2671 2704 }
2672 2705
2673 2706 /*
2674 2707 * Drop p->p_lock while touching the stack.
2675 2708 * The P_PR_LOCK flag prevents the lwp from
2676 2709 * disappearing while we do this.
2677 2710 */
2678 2711 mutex_exit(&p->p_lock);
2679 2712 if ((size = prnwindows(ttolwp(t))) != 0)
2680 2713 size = sizeof (gwindows32_t) -
2681 2714 (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow32);
2682 2715 if (uiop->uio_offset >= size) {
2683 2716 mutex_enter(&p->p_lock);
2684 2717 prunlock(pnp);
2685 2718 goto out;
2686 2719 }
2687 2720 prgetwindows32(ttolwp(t), gwp);
2688 2721 mutex_enter(&p->p_lock);
2689 2722 prunlock(pnp);
2690 2723
2691 2724 error = pr_uioread(gwp, size, uiop);
2692 2725 out:
2693 2726 kmem_free(gwp, sizeof (gwindows32_t));
2694 2727 return (error);
2695 2728 }
2696 2729 #endif /* __sparc */
2697 2730
2698 2731 #endif /* _SYSCALL32_IMPL */
2699 2732
2700 2733 /* ARGSUSED */
2701 2734 static int
2702 2735 prread(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2703 2736 {
2704 2737 prnode_t *pnp = VTOP(vp);
2705 2738
2706 2739 ASSERT(pnp->pr_type < PR_NFILES);
2707 2740
2708 2741 #ifdef _SYSCALL32_IMPL
2709 2742 /*
2710 2743 * What is read from the /proc files depends on the data
2711 2744 * model of the caller. An LP64 process will see LP64
2712 2745 * data. An ILP32 process will see ILP32 data.
↓ open down ↓ |
892 lines elided |
↑ open up ↑ |
2713 2746 */
2714 2747 if (curproc->p_model == DATAMODEL_LP64)
2715 2748 return (pr_read_function[pnp->pr_type](pnp, uiop));
2716 2749 else
2717 2750 return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2718 2751 #else
2719 2752 return (pr_read_function[pnp->pr_type](pnp, uiop));
2720 2753 #endif
2721 2754 }
2722 2755
2756 +/* Note we intentionally don't handle partial writes/updates. */
2757 +static int
2758 +pr_write_lwpname(prnode_t *pnp, uio_t *uiop)
2759 +{
2760 + kthread_t *t = NULL;
2761 + char *lwpname;
2762 + int error;
2763 +
2764 + lwpname = kmem_zalloc(THREAD_NAME_MAX, KM_SLEEP);
2765 +
2766 + if ((error = uiomove(lwpname, THREAD_NAME_MAX, UIO_WRITE, uiop)) != 0) {
2767 + kmem_free(lwpname, THREAD_NAME_MAX);
2768 + return (error);
2769 + }
2770 +
2771 + /* Somebody tried to write too long a thread name... */
2772 + if (lwpname[THREAD_NAME_MAX - 1] != '\0' || uiop->uio_resid > 0) {
2773 + kmem_free(lwpname, THREAD_NAME_MAX);
2774 + return (EIO);
2775 + }
2776 +
2777 + VERIFY3U(lwpname[THREAD_NAME_MAX - 1], ==, '\0');
2778 +
2779 + for (size_t i = 0; lwpname[i] != '\0'; i++) {
2780 + if (!ISPRINT(lwpname[i])) {
2781 + kmem_free(lwpname, THREAD_NAME_MAX);
2782 + return (EINVAL);
2783 + }
2784 + }
2785 +
2786 + /* Equivalent of thread_setname(), but with the ZNO magic. */
2787 + if ((error = prlock(pnp, ZNO)) != 0) {
2788 + kmem_free(lwpname, THREAD_NAME_MAX);
2789 + return (error);
2790 + }
2791 +
2792 + t = pnp->pr_common->prc_thread;
2793 + if (t->t_name == NULL) {
2794 + t->t_name = lwpname;
2795 + } else {
2796 + (void) strlcpy(t->t_name, lwpname, THREAD_NAME_MAX);
2797 + kmem_free(lwpname, THREAD_NAME_MAX);
2798 + }
2799 +
2800 + prunlock(pnp);
2801 + return (0);
2802 +}
2803 +
2723 2804 /* ARGSUSED */
2724 2805 static int
2725 2806 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2726 2807 {
2727 2808 prnode_t *pnp = VTOP(vp);
2728 2809 int old = 0;
2729 2810 int error;
2730 2811 ssize_t resid;
2731 2812
2732 2813 ASSERT(pnp->pr_type < PR_NFILES);
2733 2814
2734 2815 /*
2735 2816 * Only a handful of /proc files are writable, enumerate them here.
2736 2817 */
2737 2818 switch (pnp->pr_type) {
2738 2819 case PR_PIDDIR: /* directory write()s: visceral revulsion. */
2739 2820 ASSERT(pnp->pr_pidfile != NULL);
2740 2821 /* use the underlying PR_PIDFILE to write the process */
2741 2822 vp = pnp->pr_pidfile;
2742 2823 pnp = VTOP(vp);
2743 2824 ASSERT(pnp->pr_type == PR_PIDFILE);
2744 2825 /* FALLTHROUGH */
2745 2826 case PR_PIDFILE:
2746 2827 case PR_LWPIDFILE:
2747 2828 old = 1;
2748 2829 /* FALLTHROUGH */
2749 2830 case PR_AS:
2750 2831 if ((error = prlock(pnp, ZNO)) == 0) {
2751 2832 proc_t *p = pnp->pr_common->prc_proc;
2752 2833 struct as *as = p->p_as;
2753 2834
2754 2835 if ((p->p_flag & SSYS) || as == &kas) {
2755 2836 /*
2756 2837 * /proc I/O cannot be done to a system process.
2757 2838 */
2758 2839 error = EIO;
2759 2840 #ifdef _SYSCALL32_IMPL
2760 2841 } else if (curproc->p_model == DATAMODEL_ILP32 &&
2761 2842 PROCESS_NOT_32BIT(p)) {
2762 2843 error = EOVERFLOW;
2763 2844 #endif
2764 2845 } else {
2765 2846 /*
2766 2847 * See comments above (pr_read_pidfile)
2767 2848 * about this locking dance.
2768 2849 */
2769 2850 mutex_exit(&p->p_lock);
2770 2851 error = prusrio(p, UIO_WRITE, uiop, old);
2771 2852 mutex_enter(&p->p_lock);
2772 2853 }
2773 2854 prunlock(pnp);
2774 2855 }
2775 2856 return (error);
2776 2857
2777 2858 case PR_CTL:
2778 2859 case PR_LWPCTL:
2779 2860 resid = uiop->uio_resid;
2780 2861 /*
2781 2862 * Perform the action on the control file
2782 2863 * by passing curthreads credentials
2783 2864 * and not target process's credentials.
2784 2865 */
2785 2866 #ifdef _SYSCALL32_IMPL
2786 2867 if (curproc->p_model == DATAMODEL_ILP32)
2787 2868 error = prwritectl32(vp, uiop, CRED());
2788 2869 else
2789 2870 error = prwritectl(vp, uiop, CRED());
2790 2871 #else
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
2791 2872 error = prwritectl(vp, uiop, CRED());
2792 2873 #endif
2793 2874 /*
2794 2875 * This hack makes sure that the EINTR is passed
2795 2876 * all the way back to the caller's write() call.
2796 2877 */
2797 2878 if (error == EINTR)
2798 2879 uiop->uio_resid = resid;
2799 2880 return (error);
2800 2881
2882 + case PR_LWPNAME:
2883 + return (pr_write_lwpname(pnp, uiop));
2884 +
2801 2885 default:
2802 2886 return ((vp->v_type == VDIR)? EISDIR : EBADF);
2803 2887 }
2804 2888 /* NOTREACHED */
2805 2889 }
2806 2890
2807 2891 static int
2808 2892 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2809 2893 caller_context_t *ct)
2810 2894 {
2811 2895 prnode_t *pnp = VTOP(vp);
2812 2896 prnodetype_t type = pnp->pr_type;
2813 2897 prcommon_t *pcp;
2814 2898 proc_t *p;
2815 2899 struct as *as;
2816 2900 int error;
2817 2901 vnode_t *rvp;
2818 2902 timestruc_t now;
2819 2903 extern uint_t nproc;
2820 2904 int ngroups;
2821 2905 int nsig;
2822 2906
2823 2907 /*
2824 2908 * This ugly bit of code allows us to keep both versions of this
2825 2909 * function from the same source.
2826 2910 */
2827 2911 #ifdef _LP64
2828 2912 int iam32bit = (curproc->p_model == DATAMODEL_ILP32);
2829 2913 #define PR_OBJSIZE(obj32, obj64) \
2830 2914 (iam32bit ? sizeof (obj32) : sizeof (obj64))
2831 2915 #define PR_OBJSPAN(obj32, obj64) \
2832 2916 (iam32bit ? LSPAN32(obj32) : LSPAN(obj64))
2833 2917 #else
2834 2918 #define PR_OBJSIZE(obj32, obj64) \
2835 2919 (sizeof (obj64))
2836 2920 #define PR_OBJSPAN(obj32, obj64) \
2837 2921 (LSPAN(obj64))
2838 2922 #endif
2839 2923
2840 2924 /*
2841 2925 * Return all the attributes. Should be refined
2842 2926 * so that it returns only those asked for.
2843 2927 * Most of this is complete fakery anyway.
2844 2928 */
2845 2929
2846 2930 /*
2847 2931 * For files in the /proc/<pid>/object directory,
2848 2932 * return the attributes of the underlying object.
2849 2933 * For files in the /proc/<pid>/fd directory,
2850 2934 * return the attributes of the underlying file, but
2851 2935 * make it look inaccessible if it is not a regular file.
2852 2936 * Make directories look like symlinks.
2853 2937 */
2854 2938 switch (type) {
2855 2939 case PR_CURDIR:
2856 2940 case PR_ROOTDIR:
2857 2941 if (!(flags & ATTR_REAL))
2858 2942 break;
2859 2943 /* restrict full knowledge of the attributes to owner or root */
2860 2944 if ((error = praccess(vp, 0, 0, cr, ct)) != 0)
2861 2945 return (error);
2862 2946 /* FALLTHROUGH */
2863 2947 case PR_OBJECT:
2864 2948 case PR_FD:
2865 2949 rvp = pnp->pr_realvp;
2866 2950 error = VOP_GETATTR(rvp, vap, flags, cr, ct);
2867 2951 if (error)
2868 2952 return (error);
2869 2953 if (type == PR_FD) {
2870 2954 if (rvp->v_type != VREG && rvp->v_type != VDIR)
2871 2955 vap->va_mode = 0;
2872 2956 else
2873 2957 vap->va_mode &= pnp->pr_mode;
2874 2958 }
2875 2959 if (type == PR_OBJECT)
2876 2960 vap->va_mode &= 07555;
2877 2961 if (rvp->v_type == VDIR && !(flags & ATTR_REAL)) {
2878 2962 vap->va_type = VLNK;
2879 2963 vap->va_size = 0;
2880 2964 vap->va_nlink = 1;
2881 2965 }
2882 2966 return (0);
2883 2967 default:
2884 2968 break;
2885 2969 }
2886 2970
2887 2971 bzero(vap, sizeof (*vap));
2888 2972 /*
2889 2973 * Large Files: Internally proc now uses VPROC to indicate
2890 2974 * a proc file. Since we have been returning VREG through
2891 2975 * VOP_GETATTR() until now, we continue to do this so as
2892 2976 * not to break apps depending on this return value.
2893 2977 */
2894 2978 vap->va_type = (vp->v_type == VPROC) ? VREG : vp->v_type;
2895 2979 vap->va_mode = pnp->pr_mode;
2896 2980 vap->va_fsid = vp->v_vfsp->vfs_dev;
2897 2981 vap->va_blksize = DEV_BSIZE;
2898 2982 vap->va_rdev = 0;
2899 2983 vap->va_seq = 0;
2900 2984
2901 2985 if (type == PR_PROCDIR) {
2902 2986 vap->va_uid = 0;
2903 2987 vap->va_gid = 0;
2904 2988 vap->va_nlink = nproc + 2;
2905 2989 vap->va_nodeid = (ino64_t)PRROOTINO;
2906 2990 gethrestime(&now);
2907 2991 vap->va_atime = vap->va_mtime = vap->va_ctime = now;
2908 2992 vap->va_size = (v.v_proc + 2) * PRSDSIZE;
2909 2993 vap->va_nblocks = btod(vap->va_size);
2910 2994 return (0);
2911 2995 }
2912 2996
2913 2997 /*
2914 2998 * /proc/<pid>/self is a symbolic link, and has no prcommon member
2915 2999 */
2916 3000 if (type == PR_SELF) {
2917 3001 vap->va_uid = crgetruid(CRED());
2918 3002 vap->va_gid = crgetrgid(CRED());
2919 3003 vap->va_nodeid = (ino64_t)PR_SELF;
2920 3004 gethrestime(&now);
2921 3005 vap->va_atime = vap->va_mtime = vap->va_ctime = now;
2922 3006 vap->va_nlink = 1;
2923 3007 vap->va_type = VLNK;
2924 3008 vap->va_size = 0;
2925 3009 return (0);
2926 3010 }
2927 3011
2928 3012 p = pr_p_lock(pnp);
2929 3013 mutex_exit(&pr_pidlock);
2930 3014 if (p == NULL)
2931 3015 return (ENOENT);
2932 3016 pcp = pnp->pr_common;
2933 3017
2934 3018 mutex_enter(&p->p_crlock);
2935 3019 vap->va_uid = crgetruid(p->p_cred);
2936 3020 vap->va_gid = crgetrgid(p->p_cred);
2937 3021 mutex_exit(&p->p_crlock);
2938 3022
2939 3023 vap->va_nlink = 1;
2940 3024 vap->va_nodeid = pnp->pr_ino? pnp->pr_ino :
2941 3025 pmkino(pcp->prc_tslot, pcp->prc_slot, pnp->pr_type);
2942 3026 if ((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot != -1) {
2943 3027 vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
2944 3028 vap->va_ctime.tv_sec =
2945 3029 p->p_lwpdir[pcp->prc_tslot].ld_entry->le_start;
2946 3030 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
2947 3031 vap->va_ctime.tv_nsec = 0;
2948 3032 } else {
2949 3033 user_t *up = PTOU(p);
2950 3034 vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
2951 3035 vap->va_ctime.tv_sec = up->u_start.tv_sec;
2952 3036 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
2953 3037 vap->va_ctime.tv_nsec = up->u_start.tv_nsec;
2954 3038 }
2955 3039
2956 3040 switch (type) {
2957 3041 case PR_PIDDIR:
2958 3042 /* va_nlink: count 'lwp', 'object' and 'fd' directory links */
2959 3043 vap->va_nlink = 5;
2960 3044 vap->va_size = sizeof (piddir);
2961 3045 break;
2962 3046 case PR_OBJECTDIR:
2963 3047 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2964 3048 vap->va_size = 2 * PRSDSIZE;
2965 3049 else {
2966 3050 mutex_exit(&p->p_lock);
2967 3051 AS_LOCK_ENTER(as, RW_WRITER);
2968 3052 if (as->a_updatedir)
2969 3053 rebuild_objdir(as);
2970 3054 vap->va_size = (as->a_sizedir + 2) * PRSDSIZE;
2971 3055 AS_LOCK_EXIT(as);
2972 3056 mutex_enter(&p->p_lock);
2973 3057 }
2974 3058 vap->va_nlink = 2;
2975 3059 break;
2976 3060 case PR_PATHDIR:
2977 3061 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2978 3062 vap->va_size = (P_FINFO(p)->fi_nfiles + 4) * PRSDSIZE;
2979 3063 else {
2980 3064 mutex_exit(&p->p_lock);
2981 3065 AS_LOCK_ENTER(as, RW_WRITER);
2982 3066 if (as->a_updatedir)
2983 3067 rebuild_objdir(as);
2984 3068 vap->va_size = (as->a_sizedir + 4 +
2985 3069 P_FINFO(p)->fi_nfiles) * PRSDSIZE;
2986 3070 AS_LOCK_EXIT(as);
2987 3071 mutex_enter(&p->p_lock);
2988 3072 }
2989 3073 vap->va_nlink = 2;
2990 3074 break;
2991 3075 case PR_PATH:
2992 3076 case PR_CURDIR:
2993 3077 case PR_ROOTDIR:
2994 3078 case PR_CT:
2995 3079 vap->va_type = VLNK;
2996 3080 vap->va_size = 0;
2997 3081 break;
2998 3082 case PR_FDDIR:
2999 3083 vap->va_nlink = 2;
3000 3084 vap->va_size = (P_FINFO(p)->fi_nfiles + 2) * PRSDSIZE;
3001 3085 break;
3002 3086 case PR_LWPDIR:
3003 3087 /*
3004 3088 * va_nlink: count each lwp as a directory link.
3005 3089 * va_size: size of p_lwpdir + 2
3006 3090 */
3007 3091 vap->va_nlink = p->p_lwpcnt + p->p_zombcnt + 2;
3008 3092 vap->va_size = (p->p_lwpdir_sz + 2) * PRSDSIZE;
3009 3093 break;
3010 3094 case PR_LWPIDDIR:
3011 3095 vap->va_nlink = 2;
3012 3096 vap->va_size = sizeof (lwpiddir);
3013 3097 break;
3014 3098 case PR_CTDIR:
3015 3099 vap->va_nlink = 2;
3016 3100 vap->va_size = (avl_numnodes(&p->p_ct_held) + 2) * PRSDSIZE;
3017 3101 break;
3018 3102 case PR_TMPLDIR:
3019 3103 vap->va_nlink = 2;
3020 3104 vap->va_size = (ct_ntypes + 2) * PRSDSIZE;
3021 3105 break;
3022 3106 case PR_AS:
3023 3107 case PR_PIDFILE:
3024 3108 case PR_LWPIDFILE:
3025 3109 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3026 3110 vap->va_size = 0;
3027 3111 else
3028 3112 vap->va_size = as->a_resvsize;
3029 3113 break;
3030 3114 case PR_STATUS:
3031 3115 vap->va_size = PR_OBJSIZE(pstatus32_t, pstatus_t);
3032 3116 break;
3033 3117 case PR_LSTATUS:
3034 3118 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3035 3119 p->p_lwpcnt * PR_OBJSPAN(lwpstatus32_t, lwpstatus_t);
3036 3120 break;
3037 3121 case PR_PSINFO:
3038 3122 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3039 3123 break;
3040 3124 case PR_LPSINFO:
3041 3125 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3042 3126 (p->p_lwpcnt + p->p_zombcnt) *
3043 3127 PR_OBJSPAN(lwpsinfo32_t, lwpsinfo_t);
3044 3128 break;
3045 3129 case PR_MAP:
3046 3130 case PR_RMAP:
3047 3131 case PR_XMAP:
3048 3132 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3049 3133 vap->va_size = 0;
3050 3134 else {
3051 3135 mutex_exit(&p->p_lock);
3052 3136 AS_LOCK_ENTER(as, RW_WRITER);
3053 3137 if (type == PR_MAP)
3054 3138 vap->va_mtime = as->a_updatetime;
3055 3139 if (type == PR_XMAP)
3056 3140 vap->va_size = prnsegs(as, 0) *
3057 3141 PR_OBJSIZE(prxmap32_t, prxmap_t);
3058 3142 else
3059 3143 vap->va_size = prnsegs(as, type == PR_RMAP) *
3060 3144 PR_OBJSIZE(prmap32_t, prmap_t);
3061 3145 AS_LOCK_EXIT(as);
3062 3146 mutex_enter(&p->p_lock);
3063 3147 }
3064 3148 break;
3065 3149 case PR_CRED:
3066 3150 mutex_enter(&p->p_crlock);
3067 3151 vap->va_size = sizeof (prcred_t);
3068 3152 ngroups = crgetngroups(p->p_cred);
3069 3153 if (ngroups > 1)
3070 3154 vap->va_size += (ngroups - 1) * sizeof (gid_t);
3071 3155 mutex_exit(&p->p_crlock);
3072 3156 break;
3073 3157 case PR_PRIV:
3074 3158 vap->va_size = prgetprivsize();
3075 3159 break;
3076 3160 case PR_SECFLAGS:
3077 3161 vap->va_size = sizeof (prsecflags_t);
3078 3162 break;
3079 3163 case PR_SIGACT:
3080 3164 nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3081 3165 vap->va_size = (nsig-1) *
3082 3166 PR_OBJSIZE(struct sigaction32, struct sigaction);
3083 3167 break;
3084 3168 case PR_AUXV:
3085 3169 vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
3086 3170 break;
3087 3171 #if defined(__x86)
3088 3172 case PR_LDT:
3089 3173 mutex_exit(&p->p_lock);
3090 3174 mutex_enter(&p->p_ldtlock);
3091 3175 vap->va_size = prnldt(p) * sizeof (struct ssd);
3092 3176 mutex_exit(&p->p_ldtlock);
3093 3177 mutex_enter(&p->p_lock);
3094 3178 break;
3095 3179 #endif
3096 3180 case PR_USAGE:
3097 3181 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3098 3182 break;
3099 3183 case PR_LUSAGE:
3100 3184 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3101 3185 (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3102 3186 break;
3103 3187 case PR_PAGEDATA:
3104 3188 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3105 3189 vap->va_size = 0;
3106 3190 else {
3107 3191 /*
3108 3192 * We can drop p->p_lock before grabbing the
3109 3193 * address space lock because p->p_as will not
3110 3194 * change while the process is marked P_PR_LOCK.
3111 3195 */
3112 3196 mutex_exit(&p->p_lock);
3113 3197 AS_LOCK_ENTER(as, RW_WRITER);
3114 3198 #ifdef _LP64
3115 3199 vap->va_size = iam32bit?
3116 3200 prpdsize32(as) : prpdsize(as);
3117 3201 #else
3118 3202 vap->va_size = prpdsize(as);
3119 3203 #endif
3120 3204 AS_LOCK_EXIT(as);
3121 3205 mutex_enter(&p->p_lock);
3122 3206 }
3123 3207 break;
3124 3208 case PR_OPAGEDATA:
3125 3209 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3126 3210 vap->va_size = 0;
3127 3211 else {
3128 3212 mutex_exit(&p->p_lock);
3129 3213 AS_LOCK_ENTER(as, RW_WRITER);
3130 3214 #ifdef _LP64
3131 3215 vap->va_size = iam32bit?
3132 3216 oprpdsize32(as) : oprpdsize(as);
3133 3217 #else
3134 3218 vap->va_size = oprpdsize(as);
3135 3219 #endif
3136 3220 AS_LOCK_EXIT(as);
3137 3221 mutex_enter(&p->p_lock);
3138 3222 }
3139 3223 break;
3140 3224 case PR_WATCH:
3141 3225 vap->va_size = avl_numnodes(&p->p_warea) *
3142 3226 PR_OBJSIZE(prwatch32_t, prwatch_t);
3143 3227 break;
3144 3228 case PR_LWPSTATUS:
3145 3229 vap->va_size = PR_OBJSIZE(lwpstatus32_t, lwpstatus_t);
3146 3230 break;
3147 3231 case PR_LWPSINFO:
3148 3232 vap->va_size = PR_OBJSIZE(lwpsinfo32_t, lwpsinfo_t);
3149 3233 break;
3150 3234 case PR_LWPUSAGE:
3151 3235 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3152 3236 break;
3153 3237 case PR_XREGS:
3154 3238 if (prhasx(p))
3155 3239 vap->va_size = prgetprxregsize(p);
3156 3240 else
3157 3241 vap->va_size = 0;
3158 3242 break;
3159 3243 case PR_SPYMASTER:
3160 3244 if (pnp->pr_common->prc_thread != NULL &&
3161 3245 pnp->pr_common->prc_thread->t_lwp->lwp_spymaster != NULL) {
3162 3246 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3163 3247 } else {
3164 3248 vap->va_size = 0;
3165 3249 }
3166 3250 break;
3167 3251 #if defined(__sparc)
3168 3252 case PR_GWINDOWS:
3169 3253 {
3170 3254 kthread_t *t;
3171 3255 int n;
3172 3256
3173 3257 /*
3174 3258 * If there is no lwp then just make the size zero.
3175 3259 * This can happen if the lwp exits between the VOP_LOOKUP()
3176 3260 * of the /proc/<pid>/lwp/<lwpid>/gwindows file and the
3177 3261 * VOP_GETATTR() of the resulting vnode.
3178 3262 */
3179 3263 if ((t = pcp->prc_thread) == NULL) {
3180 3264 vap->va_size = 0;
3181 3265 break;
3182 3266 }
3183 3267 /*
3184 3268 * Drop p->p_lock while touching the stack.
3185 3269 * The P_PR_LOCK flag prevents the lwp from
3186 3270 * disappearing while we do this.
3187 3271 */
3188 3272 mutex_exit(&p->p_lock);
3189 3273 if ((n = prnwindows(ttolwp(t))) == 0)
3190 3274 vap->va_size = 0;
3191 3275 else
3192 3276 vap->va_size = PR_OBJSIZE(gwindows32_t, gwindows_t) -
3193 3277 (SPARC_MAXREGWINDOW - n) *
3194 3278 PR_OBJSIZE(struct rwindow32, struct rwindow);
3195 3279 mutex_enter(&p->p_lock);
3196 3280 break;
3197 3281 }
3198 3282 case PR_ASRS:
3199 3283 #ifdef _LP64
3200 3284 if (p->p_model == DATAMODEL_LP64)
3201 3285 vap->va_size = sizeof (asrset_t);
3202 3286 else
3203 3287 #endif
3204 3288 vap->va_size = 0;
3205 3289 break;
3206 3290 #endif
3207 3291 case PR_CTL:
3208 3292 case PR_LWPCTL:
3209 3293 default:
3210 3294 vap->va_size = 0;
3211 3295 break;
3212 3296 }
3213 3297
3214 3298 prunlock(pnp);
3215 3299 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
3216 3300 return (0);
3217 3301 }
3218 3302
3219 3303 static int
3220 3304 praccess(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct)
3221 3305 {
3222 3306 prnode_t *pnp = VTOP(vp);
3223 3307 prnodetype_t type = pnp->pr_type;
3224 3308 int vmode;
3225 3309 vtype_t vtype;
3226 3310 proc_t *p;
3227 3311 int error = 0;
3228 3312 vnode_t *rvp;
3229 3313 vnode_t *xvp;
3230 3314
3231 3315 if ((mode & VWRITE) && vn_is_readonly(vp))
3232 3316 return (EROFS);
3233 3317
3234 3318 switch (type) {
3235 3319 case PR_PROCDIR:
3236 3320 break;
3237 3321
3238 3322 case PR_OBJECT:
3239 3323 case PR_FD:
3240 3324 /*
3241 3325 * Disallow write access to the underlying objects.
3242 3326 * Disallow access to underlying non-regular-file fds.
3243 3327 * Disallow access to fds with other than existing open modes.
3244 3328 */
3245 3329 rvp = pnp->pr_realvp;
3246 3330 vtype = rvp->v_type;
3247 3331 vmode = pnp->pr_mode;
3248 3332 if ((type == PR_OBJECT && (mode & VWRITE)) ||
3249 3333 (type == PR_FD && vtype != VREG && vtype != VDIR) ||
3250 3334 (type == PR_FD && (vmode & mode) != mode &&
3251 3335 secpolicy_proc_access(cr) != 0))
3252 3336 return (EACCES);
3253 3337 return (VOP_ACCESS(rvp, mode, flags, cr, ct));
3254 3338
3255 3339 case PR_PSINFO: /* these files can be read by anyone */
3256 3340 case PR_LPSINFO:
3257 3341 case PR_LWPSINFO:
3258 3342 case PR_LWPDIR:
3259 3343 case PR_LWPIDDIR:
3260 3344 case PR_USAGE:
3261 3345 case PR_LUSAGE:
3262 3346 case PR_LWPUSAGE:
3263 3347 p = pr_p_lock(pnp);
3264 3348 mutex_exit(&pr_pidlock);
3265 3349 if (p == NULL)
3266 3350 return (ENOENT);
3267 3351 prunlock(pnp);
3268 3352 break;
3269 3353
3270 3354 default:
3271 3355 /*
3272 3356 * Except for the world-readable files above,
3273 3357 * only /proc/pid exists if the process is a zombie.
3274 3358 */
3275 3359 if ((error = prlock(pnp,
3276 3360 (type == PR_PIDDIR)? ZYES : ZNO)) != 0)
3277 3361 return (error);
3278 3362 p = pnp->pr_common->prc_proc;
3279 3363 if (p != curproc)
3280 3364 error = priv_proc_cred_perm(cr, p, NULL, mode);
3281 3365
3282 3366 if (error != 0 || p == curproc || (p->p_flag & SSYS) ||
3283 3367 p->p_as == &kas || (xvp = p->p_exec) == NULL) {
3284 3368 prunlock(pnp);
3285 3369 } else {
3286 3370 /*
3287 3371 * Determine if the process's executable is readable.
3288 3372 * We have to drop p->p_lock before the secpolicy
3289 3373 * and VOP operation.
3290 3374 */
3291 3375 VN_HOLD(xvp);
3292 3376 prunlock(pnp);
3293 3377 if (secpolicy_proc_access(cr) != 0)
3294 3378 error = VOP_ACCESS(xvp, VREAD, 0, cr, ct);
3295 3379 VN_RELE(xvp);
3296 3380 }
3297 3381 if (error)
3298 3382 return (error);
3299 3383 break;
3300 3384 }
3301 3385
3302 3386 if (type == PR_CURDIR || type == PR_ROOTDIR) {
3303 3387 /*
3304 3388 * Final access check on the underlying directory vnode.
3305 3389 */
3306 3390 return (VOP_ACCESS(pnp->pr_realvp, mode, flags, cr, ct));
3307 3391 }
3308 3392
3309 3393 /*
3310 3394 * Visceral revulsion: For compatibility with old /proc,
3311 3395 * allow the /proc/<pid> directory to be opened for writing.
3312 3396 */
3313 3397 vmode = pnp->pr_mode;
3314 3398 if (type == PR_PIDDIR)
3315 3399 vmode |= VWRITE;
3316 3400 if ((vmode & mode) != mode)
3317 3401 error = secpolicy_proc_access(cr);
3318 3402 return (error);
3319 3403 }
3320 3404
3321 3405 /*
3322 3406 * Array of lookup functions, indexed by /proc file type.
3323 3407 */
3324 3408 static vnode_t *pr_lookup_notdir(), *pr_lookup_procdir(), *pr_lookup_piddir(),
3325 3409 *pr_lookup_objectdir(), *pr_lookup_lwpdir(), *pr_lookup_lwpiddir(),
3326 3410 *pr_lookup_fddir(), *pr_lookup_pathdir(), *pr_lookup_tmpldir(),
3327 3411 *pr_lookup_ctdir();
3328 3412
3329 3413 static vnode_t *(*pr_lookup_function[PR_NFILES])() = {
3330 3414 pr_lookup_procdir, /* /proc */
3331 3415 pr_lookup_notdir, /* /proc/self */
3332 3416 pr_lookup_piddir, /* /proc/<pid> */
3333 3417 pr_lookup_notdir, /* /proc/<pid>/as */
3334 3418 pr_lookup_notdir, /* /proc/<pid>/ctl */
3335 3419 pr_lookup_notdir, /* /proc/<pid>/status */
3336 3420 pr_lookup_notdir, /* /proc/<pid>/lstatus */
3337 3421 pr_lookup_notdir, /* /proc/<pid>/psinfo */
3338 3422 pr_lookup_notdir, /* /proc/<pid>/lpsinfo */
3339 3423 pr_lookup_notdir, /* /proc/<pid>/map */
3340 3424 pr_lookup_notdir, /* /proc/<pid>/rmap */
3341 3425 pr_lookup_notdir, /* /proc/<pid>/xmap */
3342 3426 pr_lookup_notdir, /* /proc/<pid>/cred */
3343 3427 pr_lookup_notdir, /* /proc/<pid>/sigact */
3344 3428 pr_lookup_notdir, /* /proc/<pid>/auxv */
3345 3429 #if defined(__x86)
3346 3430 pr_lookup_notdir, /* /proc/<pid>/ldt */
3347 3431 #endif
3348 3432 pr_lookup_notdir, /* /proc/<pid>/usage */
3349 3433 pr_lookup_notdir, /* /proc/<pid>/lusage */
3350 3434 pr_lookup_notdir, /* /proc/<pid>/pagedata */
↓ open down ↓ |
540 lines elided |
↑ open up ↑ |
3351 3435 pr_lookup_notdir, /* /proc/<pid>/watch */
3352 3436 pr_lookup_notdir, /* /proc/<pid>/cwd */
3353 3437 pr_lookup_notdir, /* /proc/<pid>/root */
3354 3438 pr_lookup_fddir, /* /proc/<pid>/fd */
3355 3439 pr_lookup_notdir, /* /proc/<pid>/fd/nn */
3356 3440 pr_lookup_objectdir, /* /proc/<pid>/object */
3357 3441 pr_lookup_notdir, /* /proc/<pid>/object/xxx */
3358 3442 pr_lookup_lwpdir, /* /proc/<pid>/lwp */
3359 3443 pr_lookup_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
3360 3444 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
3445 + pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */
3361 3446 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
3362 3447 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3363 3448 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3364 3449 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
3365 3450 pr_lookup_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
3366 3451 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3367 3452 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */
3368 3453 #if defined(__sparc)
3369 3454 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */
3370 3455 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */
3371 3456 #endif
3372 3457 pr_lookup_notdir, /* /proc/<pid>/priv */
3373 3458 pr_lookup_pathdir, /* /proc/<pid>/path */
3374 3459 pr_lookup_notdir, /* /proc/<pid>/path/xxx */
3375 3460 pr_lookup_ctdir, /* /proc/<pid>/contracts */
3376 3461 pr_lookup_notdir, /* /proc/<pid>/contracts/<ctid> */
3377 3462 pr_lookup_notdir, /* /proc/<pid>/secflags */
3378 3463 pr_lookup_notdir, /* old process file */
3379 3464 pr_lookup_notdir, /* old lwp file */
3380 3465 pr_lookup_notdir, /* old pagedata file */
3381 3466 };
3382 3467
3383 3468 static int
3384 3469 prlookup(vnode_t *dp, char *comp, vnode_t **vpp, pathname_t *pathp,
3385 3470 int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
3386 3471 int *direntflags, pathname_t *realpnp)
3387 3472 {
3388 3473 prnode_t *pnp = VTOP(dp);
3389 3474 prnodetype_t type = pnp->pr_type;
3390 3475 int error;
3391 3476
3392 3477 ASSERT(dp->v_type == VDIR);
3393 3478 ASSERT(type < PR_NFILES);
3394 3479
3395 3480 if (type != PR_PROCDIR && strcmp(comp, "..") == 0) {
3396 3481 VN_HOLD(pnp->pr_parent);
3397 3482 *vpp = pnp->pr_parent;
3398 3483 return (0);
3399 3484 }
3400 3485
3401 3486 if (*comp == '\0' ||
3402 3487 strcmp(comp, ".") == 0 || strcmp(comp, "..") == 0) {
3403 3488 VN_HOLD(dp);
3404 3489 *vpp = dp;
3405 3490 return (0);
3406 3491 }
3407 3492
3408 3493 switch (type) {
3409 3494 case PR_CURDIR:
3410 3495 case PR_ROOTDIR:
3411 3496 /* restrict lookup permission to owner or root */
3412 3497 if ((error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3413 3498 return (error);
3414 3499 /* FALLTHROUGH */
3415 3500 case PR_FD:
3416 3501 /*
3417 3502 * Performing a VOP_LOOKUP on the underlying vnode and emitting
3418 3503 * the resulting vnode, without encapsulation, as our own is a
3419 3504 * very special case when it comes to the assumptions built
3420 3505 * into VFS.
3421 3506 *
3422 3507 * Since the resulting vnode is highly likely to be at some
3423 3508 * abitrary position in another filesystem, we insist that the
3424 3509 * VTRAVERSE flag is set on the parent. This prevents things
3425 3510 * such as the v_path freshness logic from mistaking the
3426 3511 * resulting vnode as a "real" child of the parent, rather than
3427 3512 * a consequence of this "procfs wormhole".
3428 3513 *
3429 3514 * Failure to establish such protections can lead to
3430 3515 * incorrectly calculated v_paths being set on nodes reached
3431 3516 * through these lookups.
3432 3517 */
3433 3518 ASSERT((dp->v_flag & VTRAVERSE) != 0);
3434 3519
3435 3520 dp = pnp->pr_realvp;
3436 3521 return (VOP_LOOKUP(dp, comp, vpp, pathp, flags, rdir, cr, ct,
3437 3522 direntflags, realpnp));
3438 3523 default:
3439 3524 break;
3440 3525 }
3441 3526
3442 3527 if ((type == PR_OBJECTDIR || type == PR_FDDIR || type == PR_PATHDIR) &&
3443 3528 (error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3444 3529 return (error);
3445 3530
3446 3531 /* XXX - Do we need to pass ct, direntflags, or realpnp? */
3447 3532 *vpp = (pr_lookup_function[type](dp, comp));
3448 3533
3449 3534 return ((*vpp == NULL) ? ENOENT : 0);
3450 3535 }
3451 3536
3452 3537 /* ARGSUSED */
3453 3538 static int
3454 3539 prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl,
3455 3540 int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
3456 3541 vsecattr_t *vsecp)
3457 3542 {
3458 3543 int error;
3459 3544
3460 3545 if ((error = prlookup(dp, comp, vpp, NULL, 0, NULL, cr,
3461 3546 ct, NULL, NULL)) != 0) {
3462 3547 if (error == ENOENT) {
3463 3548 /* One can't O_CREAT nonexistent files in /proc. */
3464 3549 error = EACCES;
3465 3550 }
3466 3551 return (error);
3467 3552 }
3468 3553
3469 3554 if (excl == EXCL) {
3470 3555 /* Disallow the O_EXCL case */
3471 3556 error = EEXIST;
3472 3557 } else if ((error = praccess(*vpp, mode, 0, cr, ct)) == 0) {
3473 3558 /* Before proceeding, handle O_TRUNC if necessary. */
3474 3559 if (vap->va_mask & AT_SIZE) {
3475 3560 vnode_t *vp = *vpp;
3476 3561
3477 3562 if (vp->v_type == VDIR) {
3478 3563 /* Only allow O_TRUNC on files */
3479 3564 error = EISDIR;
3480 3565 } else if (vp->v_type != VPROC ||
3481 3566 VTOP(vp)->pr_type != PR_FD) {
3482 3567 /*
3483 3568 * Disallow for files outside of the
3484 3569 * /proc/<pid>/fd/<n> entries
3485 3570 */
3486 3571 error = EACCES;
3487 3572 } else {
3488 3573 uint_t mask;
3489 3574
3490 3575 vp = VTOP(vp)->pr_realvp;
3491 3576 mask = vap->va_mask;
3492 3577 vap->va_mask = AT_SIZE;
3493 3578 error = VOP_SETATTR(vp, vap, 0, cr, ct);
3494 3579 vap->va_mask = mask;
3495 3580 }
3496 3581 }
3497 3582 }
3498 3583
3499 3584 if (error) {
3500 3585 VN_RELE(*vpp);
3501 3586 *vpp = NULL;
3502 3587 }
3503 3588 return (error);
3504 3589 }
3505 3590
3506 3591 /* ARGSUSED */
3507 3592 static vnode_t *
3508 3593 pr_lookup_notdir(vnode_t *dp, char *comp)
3509 3594 {
3510 3595 return (NULL);
3511 3596 }
3512 3597
3513 3598 /*
3514 3599 * Find or construct a process vnode for the given pid.
3515 3600 */
3516 3601 static vnode_t *
3517 3602 pr_lookup_procdir(vnode_t *dp, char *comp)
3518 3603 {
3519 3604 pid_t pid;
3520 3605 prnode_t *pnp;
3521 3606 prcommon_t *pcp;
3522 3607 vnode_t *vp;
3523 3608 proc_t *p;
3524 3609 int c;
3525 3610
3526 3611 ASSERT(VTOP(dp)->pr_type == PR_PROCDIR);
3527 3612
3528 3613 if (strcmp(comp, "self") == 0) {
3529 3614 pnp = prgetnode(dp, PR_SELF);
3530 3615 return (PTOV(pnp));
3531 3616 } else {
3532 3617 pid = 0;
3533 3618 while ((c = *comp++) != '\0') {
3534 3619 if (c < '0' || c > '9')
3535 3620 return (NULL);
3536 3621 pid = 10*pid + c - '0';
3537 3622 if (pid > maxpid)
3538 3623 return (NULL);
3539 3624 }
3540 3625 }
3541 3626
3542 3627 pnp = prgetnode(dp, PR_PIDDIR);
3543 3628
3544 3629 mutex_enter(&pidlock);
3545 3630 if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
3546 3631 mutex_exit(&pidlock);
3547 3632 prfreenode(pnp);
3548 3633 return (NULL);
3549 3634 }
3550 3635 ASSERT(p->p_stat != 0);
3551 3636
3552 3637 /* NOTE: we're holding pidlock across the policy call. */
3553 3638 if (secpolicy_basic_procinfo(CRED(), p, curproc) != 0) {
3554 3639 mutex_exit(&pidlock);
3555 3640 prfreenode(pnp);
3556 3641 return (NULL);
3557 3642 }
3558 3643
3559 3644 mutex_enter(&p->p_lock);
3560 3645 mutex_exit(&pidlock);
3561 3646
3562 3647 /*
3563 3648 * If a process vnode already exists and it is not invalid
3564 3649 * and it was created by the current process and it belongs
3565 3650 * to the same /proc mount point as our parent vnode, then
3566 3651 * just use it and discard the newly-allocated prnode.
3567 3652 */
3568 3653 for (vp = p->p_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3569 3654 if (!(VTOP(VTOP(vp)->pr_pidfile)->pr_flags & PR_INVAL) &&
3570 3655 VTOP(vp)->pr_owner == curproc &&
3571 3656 vp->v_vfsp == dp->v_vfsp) {
3572 3657 ASSERT(!(VTOP(vp)->pr_flags & PR_INVAL));
3573 3658 VN_HOLD(vp);
3574 3659 prfreenode(pnp);
3575 3660 mutex_exit(&p->p_lock);
3576 3661 return (vp);
3577 3662 }
3578 3663 }
3579 3664 pnp->pr_owner = curproc;
3580 3665
3581 3666 /*
3582 3667 * prgetnode() initialized most of the prnode.
3583 3668 * Finish the job.
3584 3669 */
3585 3670 pcp = pnp->pr_common; /* the newly-allocated prcommon struct */
3586 3671 if ((vp = p->p_trace) != NULL) {
3587 3672 /* discard the new prcommon and use the existing prcommon */
3588 3673 prfreecommon(pcp);
3589 3674 pcp = VTOP(vp)->pr_common;
3590 3675 mutex_enter(&pcp->prc_mutex);
3591 3676 ASSERT(pcp->prc_refcnt > 0);
3592 3677 pcp->prc_refcnt++;
3593 3678 mutex_exit(&pcp->prc_mutex);
3594 3679 pnp->pr_common = pcp;
3595 3680 } else {
3596 3681 /* initialize the new prcommon struct */
3597 3682 if ((p->p_flag & SSYS) || p->p_as == &kas)
3598 3683 pcp->prc_flags |= PRC_SYS;
3599 3684 if (p->p_stat == SZOMB || (p->p_flag & SEXITING) != 0)
3600 3685 pcp->prc_flags |= PRC_DESTROY;
3601 3686 pcp->prc_proc = p;
3602 3687 pcp->prc_datamodel = p->p_model;
3603 3688 pcp->prc_pid = p->p_pid;
3604 3689 pcp->prc_slot = p->p_slot;
3605 3690 }
3606 3691 pnp->pr_pcommon = pcp;
3607 3692 pnp->pr_parent = dp;
3608 3693 VN_HOLD(dp);
3609 3694 /*
3610 3695 * Link in the old, invalid directory vnode so we
3611 3696 * can later determine the last close of the file.
3612 3697 */
3613 3698 pnp->pr_next = p->p_trace;
3614 3699 p->p_trace = dp = PTOV(pnp);
3615 3700
3616 3701 /*
3617 3702 * Kludge for old /proc: initialize the PR_PIDFILE as well.
3618 3703 */
3619 3704 vp = pnp->pr_pidfile;
3620 3705 pnp = VTOP(vp);
3621 3706 pnp->pr_ino = ptoi(pcp->prc_pid);
3622 3707 pnp->pr_common = pcp;
3623 3708 pnp->pr_pcommon = pcp;
3624 3709 pnp->pr_parent = dp;
3625 3710 pnp->pr_next = p->p_plist;
3626 3711 p->p_plist = vp;
3627 3712
3628 3713 mutex_exit(&p->p_lock);
3629 3714 return (dp);
3630 3715 }
3631 3716
3632 3717 static vnode_t *
3633 3718 pr_lookup_piddir(vnode_t *dp, char *comp)
3634 3719 {
3635 3720 prnode_t *dpnp = VTOP(dp);
3636 3721 vnode_t *vp;
3637 3722 prnode_t *pnp;
3638 3723 proc_t *p;
3639 3724 user_t *up;
3640 3725 prdirent_t *dirp;
3641 3726 int i;
3642 3727 enum prnodetype type;
3643 3728
3644 3729 ASSERT(dpnp->pr_type == PR_PIDDIR);
3645 3730
3646 3731 for (i = 0; i < NPIDDIRFILES; i++) {
3647 3732 /* Skip "." and ".." */
3648 3733 dirp = &piddir[i+2];
3649 3734 if (strcmp(comp, dirp->d_name) == 0)
3650 3735 break;
3651 3736 }
3652 3737
3653 3738 if (i >= NPIDDIRFILES)
3654 3739 return (NULL);
3655 3740
3656 3741 type = (int)dirp->d_ino;
3657 3742 pnp = prgetnode(dp, type);
3658 3743
3659 3744 p = pr_p_lock(dpnp);
3660 3745 mutex_exit(&pr_pidlock);
3661 3746 if (p == NULL) {
3662 3747 prfreenode(pnp);
3663 3748 return (NULL);
3664 3749 }
3665 3750 if (dpnp->pr_pcommon->prc_flags & PRC_DESTROY) {
3666 3751 switch (type) {
3667 3752 case PR_PSINFO:
3668 3753 case PR_USAGE:
3669 3754 break;
3670 3755 default:
3671 3756 prunlock(dpnp);
3672 3757 prfreenode(pnp);
3673 3758 return (NULL);
3674 3759 }
3675 3760 }
3676 3761
3677 3762 switch (type) {
3678 3763 case PR_CURDIR:
3679 3764 case PR_ROOTDIR:
3680 3765 up = PTOU(p);
3681 3766 vp = (type == PR_CURDIR)? up->u_cdir :
3682 3767 (up->u_rdir? up->u_rdir : rootdir);
3683 3768
3684 3769 if (vp == NULL) {
3685 3770 /* can't happen(?) */
3686 3771 prunlock(dpnp);
3687 3772 prfreenode(pnp);
3688 3773 return (NULL);
3689 3774 }
3690 3775 /*
3691 3776 * Fill in the prnode so future references will
3692 3777 * be able to find the underlying object's vnode.
3693 3778 */
3694 3779 VN_HOLD(vp);
3695 3780 pnp->pr_realvp = vp;
3696 3781 PTOV(pnp)->v_flag |= VTRAVERSE;
3697 3782 break;
3698 3783 default:
3699 3784 break;
3700 3785 }
3701 3786
3702 3787 mutex_enter(&dpnp->pr_mutex);
3703 3788
3704 3789 if ((vp = dpnp->pr_files[i]) != NULL &&
3705 3790 !(VTOP(vp)->pr_flags & PR_INVAL)) {
3706 3791 VN_HOLD(vp);
3707 3792 mutex_exit(&dpnp->pr_mutex);
3708 3793 prunlock(dpnp);
3709 3794 prfreenode(pnp);
3710 3795 return (vp);
3711 3796 }
3712 3797
3713 3798 /*
3714 3799 * prgetnode() initialized most of the prnode.
3715 3800 * Finish the job.
3716 3801 */
3717 3802 pnp->pr_common = dpnp->pr_common;
3718 3803 pnp->pr_pcommon = dpnp->pr_pcommon;
3719 3804 pnp->pr_parent = dp;
3720 3805 VN_HOLD(dp);
3721 3806 pnp->pr_index = i;
3722 3807
3723 3808 dpnp->pr_files[i] = vp = PTOV(pnp);
3724 3809
3725 3810 /*
3726 3811 * Link new vnode into list of all /proc vnodes for the process.
3727 3812 */
3728 3813 if (vp->v_type == VPROC) {
3729 3814 pnp->pr_next = p->p_plist;
3730 3815 p->p_plist = vp;
3731 3816 }
3732 3817 mutex_exit(&dpnp->pr_mutex);
3733 3818 prunlock(dpnp);
3734 3819 return (vp);
3735 3820 }
3736 3821
3737 3822 static vnode_t *
3738 3823 pr_lookup_objectdir(vnode_t *dp, char *comp)
3739 3824 {
3740 3825 prnode_t *dpnp = VTOP(dp);
3741 3826 prnode_t *pnp;
3742 3827 proc_t *p;
3743 3828 struct seg *seg;
3744 3829 struct as *as;
3745 3830 vnode_t *vp;
3746 3831 vattr_t vattr;
3747 3832
3748 3833 ASSERT(dpnp->pr_type == PR_OBJECTDIR);
3749 3834
3750 3835 pnp = prgetnode(dp, PR_OBJECT);
3751 3836
3752 3837 if (prlock(dpnp, ZNO) != 0) {
3753 3838 prfreenode(pnp);
3754 3839 return (NULL);
3755 3840 }
3756 3841 p = dpnp->pr_common->prc_proc;
3757 3842 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3758 3843 prunlock(dpnp);
3759 3844 prfreenode(pnp);
3760 3845 return (NULL);
3761 3846 }
3762 3847
3763 3848 /*
3764 3849 * We drop p_lock before grabbing the address space lock
3765 3850 * in order to avoid a deadlock with the clock thread.
3766 3851 * The process will not disappear and its address space
3767 3852 * will not change because it is marked P_PR_LOCK.
3768 3853 */
3769 3854 mutex_exit(&p->p_lock);
3770 3855 AS_LOCK_ENTER(as, RW_READER);
3771 3856 if ((seg = AS_SEGFIRST(as)) == NULL) {
3772 3857 vp = NULL;
3773 3858 goto out;
3774 3859 }
3775 3860 if (strcmp(comp, "a.out") == 0) {
3776 3861 vp = p->p_exec;
3777 3862 goto out;
3778 3863 }
3779 3864 do {
3780 3865 /*
3781 3866 * Manufacture a filename for the "object" directory.
3782 3867 */
3783 3868 vattr.va_mask = AT_FSID|AT_NODEID;
3784 3869 if (seg->s_ops == &segvn_ops &&
3785 3870 SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3786 3871 vp != NULL && vp->v_type == VREG &&
3787 3872 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3788 3873 char name[64];
3789 3874
3790 3875 if (vp == p->p_exec) /* "a.out" */
3791 3876 continue;
3792 3877 pr_object_name(name, vp, &vattr);
3793 3878 if (strcmp(name, comp) == 0)
3794 3879 goto out;
3795 3880 }
3796 3881 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3797 3882
3798 3883 vp = NULL;
3799 3884 out:
3800 3885 if (vp != NULL) {
3801 3886 VN_HOLD(vp);
3802 3887 }
3803 3888 AS_LOCK_EXIT(as);
3804 3889 mutex_enter(&p->p_lock);
3805 3890 prunlock(dpnp);
3806 3891
3807 3892 if (vp == NULL)
3808 3893 prfreenode(pnp);
3809 3894 else {
3810 3895 /*
3811 3896 * Fill in the prnode so future references will
3812 3897 * be able to find the underlying object's vnode.
3813 3898 * Don't link this prnode into the list of all
3814 3899 * prnodes for the process; this is a one-use node.
3815 3900 * Its use is entirely to catch and fail opens for writing.
3816 3901 */
3817 3902 pnp->pr_realvp = vp;
3818 3903 vp = PTOV(pnp);
3819 3904 }
3820 3905
3821 3906 return (vp);
3822 3907 }
3823 3908
3824 3909 /*
3825 3910 * Find or construct an lwp vnode for the given lwpid.
3826 3911 */
3827 3912 static vnode_t *
3828 3913 pr_lookup_lwpdir(vnode_t *dp, char *comp)
3829 3914 {
3830 3915 id_t tid; /* same type as t->t_tid */
3831 3916 int want_agent;
3832 3917 prnode_t *dpnp = VTOP(dp);
3833 3918 prnode_t *pnp;
3834 3919 prcommon_t *pcp;
3835 3920 vnode_t *vp;
3836 3921 proc_t *p;
3837 3922 kthread_t *t;
3838 3923 lwpdir_t *ldp;
3839 3924 lwpent_t *lep;
3840 3925 int tslot;
3841 3926 int c;
3842 3927
3843 3928 ASSERT(dpnp->pr_type == PR_LWPDIR);
3844 3929
3845 3930 tid = 0;
3846 3931 if (strcmp(comp, "agent") == 0)
3847 3932 want_agent = 1;
3848 3933 else {
3849 3934 want_agent = 0;
3850 3935 while ((c = *comp++) != '\0') {
3851 3936 id_t otid;
3852 3937
3853 3938 if (c < '0' || c > '9')
3854 3939 return (NULL);
3855 3940 otid = tid;
3856 3941 tid = 10*tid + c - '0';
3857 3942 if (tid/10 != otid) /* integer overflow */
3858 3943 return (NULL);
3859 3944 }
3860 3945 }
3861 3946
3862 3947 pnp = prgetnode(dp, PR_LWPIDDIR);
3863 3948
3864 3949 p = pr_p_lock(dpnp);
3865 3950 mutex_exit(&pr_pidlock);
3866 3951 if (p == NULL) {
3867 3952 prfreenode(pnp);
3868 3953 return (NULL);
3869 3954 }
3870 3955
3871 3956 if (want_agent) {
3872 3957 if ((t = p->p_agenttp) == NULL)
3873 3958 lep = NULL;
3874 3959 else {
3875 3960 tid = t->t_tid;
3876 3961 tslot = t->t_dslot;
3877 3962 lep = p->p_lwpdir[tslot].ld_entry;
3878 3963 }
3879 3964 } else {
3880 3965 if ((ldp = lwp_hash_lookup(p, tid)) == NULL)
3881 3966 lep = NULL;
3882 3967 else {
3883 3968 tslot = (int)(ldp - p->p_lwpdir);
3884 3969 lep = ldp->ld_entry;
3885 3970 }
3886 3971 }
3887 3972
3888 3973 if (lep == NULL) {
3889 3974 prunlock(dpnp);
3890 3975 prfreenode(pnp);
3891 3976 return (NULL);
3892 3977 }
3893 3978
3894 3979 /*
3895 3980 * If an lwp vnode already exists and it is not invalid
3896 3981 * and it was created by the current process and it belongs
3897 3982 * to the same /proc mount point as our parent vnode, then
3898 3983 * just use it and discard the newly-allocated prnode.
3899 3984 */
3900 3985 for (vp = lep->le_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3901 3986 if (!(VTOP(vp)->pr_flags & PR_INVAL) &&
3902 3987 VTOP(vp)->pr_owner == curproc &&
3903 3988 vp->v_vfsp == dp->v_vfsp) {
3904 3989 VN_HOLD(vp);
3905 3990 prunlock(dpnp);
3906 3991 prfreenode(pnp);
3907 3992 return (vp);
3908 3993 }
3909 3994 }
3910 3995 pnp->pr_owner = curproc;
3911 3996
3912 3997 /*
3913 3998 * prgetnode() initialized most of the prnode.
3914 3999 * Finish the job.
3915 4000 */
3916 4001 pcp = pnp->pr_common; /* the newly-allocated prcommon struct */
3917 4002 if ((vp = lep->le_trace) != NULL) {
3918 4003 /* discard the new prcommon and use the existing prcommon */
3919 4004 prfreecommon(pcp);
3920 4005 pcp = VTOP(vp)->pr_common;
3921 4006 mutex_enter(&pcp->prc_mutex);
3922 4007 ASSERT(pcp->prc_refcnt > 0);
3923 4008 pcp->prc_refcnt++;
3924 4009 mutex_exit(&pcp->prc_mutex);
3925 4010 pnp->pr_common = pcp;
3926 4011 } else {
3927 4012 /* initialize the new prcommon struct */
3928 4013 pcp->prc_flags |= PRC_LWP;
3929 4014 if ((p->p_flag & SSYS) || p->p_as == &kas)
3930 4015 pcp->prc_flags |= PRC_SYS;
3931 4016 if ((t = lep->le_thread) == NULL)
3932 4017 pcp->prc_flags |= PRC_DESTROY;
3933 4018 pcp->prc_proc = p;
3934 4019 pcp->prc_datamodel = dpnp->pr_pcommon->prc_datamodel;
3935 4020 pcp->prc_pid = p->p_pid;
3936 4021 pcp->prc_slot = p->p_slot;
3937 4022 pcp->prc_thread = t;
3938 4023 pcp->prc_tid = tid;
3939 4024 pcp->prc_tslot = tslot;
3940 4025 }
3941 4026 pnp->pr_pcommon = dpnp->pr_pcommon;
3942 4027 pnp->pr_parent = dp;
3943 4028 VN_HOLD(dp);
3944 4029 /*
3945 4030 * Link in the old, invalid directory vnode so we
3946 4031 * can later determine the last close of the file.
3947 4032 */
3948 4033 pnp->pr_next = lep->le_trace;
3949 4034 lep->le_trace = vp = PTOV(pnp);
3950 4035 prunlock(dpnp);
3951 4036 return (vp);
3952 4037 }
3953 4038
3954 4039 static vnode_t *
3955 4040 pr_lookup_lwpiddir(vnode_t *dp, char *comp)
3956 4041 {
3957 4042 prnode_t *dpnp = VTOP(dp);
3958 4043 vnode_t *vp;
3959 4044 prnode_t *pnp;
3960 4045 proc_t *p;
3961 4046 prdirent_t *dirp;
3962 4047 int i;
3963 4048 enum prnodetype type;
3964 4049
3965 4050 ASSERT(dpnp->pr_type == PR_LWPIDDIR);
3966 4051
3967 4052 for (i = 0; i < NLWPIDDIRFILES; i++) {
3968 4053 /* Skip "." and ".." */
3969 4054 dirp = &lwpiddir[i+2];
3970 4055 if (strcmp(comp, dirp->d_name) == 0)
3971 4056 break;
3972 4057 }
3973 4058
3974 4059 if (i >= NLWPIDDIRFILES)
3975 4060 return (NULL);
3976 4061
3977 4062 type = (int)dirp->d_ino;
3978 4063 pnp = prgetnode(dp, type);
3979 4064
3980 4065 p = pr_p_lock(dpnp);
3981 4066 mutex_exit(&pr_pidlock);
3982 4067 if (p == NULL) {
3983 4068 prfreenode(pnp);
3984 4069 return (NULL);
3985 4070 }
3986 4071 if (dpnp->pr_common->prc_flags & PRC_DESTROY) {
3987 4072 /*
3988 4073 * Only the lwpsinfo file is present for zombie lwps.
3989 4074 * Nothing is present if the lwp has been reaped.
3990 4075 */
3991 4076 if (dpnp->pr_common->prc_tslot == -1 ||
3992 4077 type != PR_LWPSINFO) {
3993 4078 prunlock(dpnp);
3994 4079 prfreenode(pnp);
3995 4080 return (NULL);
3996 4081 }
3997 4082 }
3998 4083
3999 4084 #if defined(__sparc)
4000 4085 /* the asrs file exists only for sparc v9 _LP64 processes */
4001 4086 if (type == PR_ASRS && p->p_model != DATAMODEL_LP64) {
4002 4087 prunlock(dpnp);
4003 4088 prfreenode(pnp);
4004 4089 return (NULL);
4005 4090 }
4006 4091 #endif
4007 4092
4008 4093 mutex_enter(&dpnp->pr_mutex);
4009 4094
4010 4095 if ((vp = dpnp->pr_files[i]) != NULL &&
4011 4096 !(VTOP(vp)->pr_flags & PR_INVAL)) {
4012 4097 VN_HOLD(vp);
4013 4098 mutex_exit(&dpnp->pr_mutex);
4014 4099 prunlock(dpnp);
4015 4100 prfreenode(pnp);
4016 4101 return (vp);
4017 4102 }
4018 4103
4019 4104 /*
4020 4105 * prgetnode() initialized most of the prnode.
4021 4106 * Finish the job.
4022 4107 */
4023 4108 pnp->pr_common = dpnp->pr_common;
4024 4109 pnp->pr_pcommon = dpnp->pr_pcommon;
4025 4110 pnp->pr_parent = dp;
4026 4111 VN_HOLD(dp);
4027 4112 pnp->pr_index = i;
4028 4113
4029 4114 dpnp->pr_files[i] = vp = PTOV(pnp);
4030 4115
4031 4116 /*
4032 4117 * Link new vnode into list of all /proc vnodes for the process.
4033 4118 */
4034 4119 if (vp->v_type == VPROC) {
4035 4120 pnp->pr_next = p->p_plist;
4036 4121 p->p_plist = vp;
4037 4122 }
4038 4123 mutex_exit(&dpnp->pr_mutex);
4039 4124 prunlock(dpnp);
4040 4125 return (vp);
4041 4126 }
4042 4127
4043 4128 /*
4044 4129 * Lookup one of the process's open files.
4045 4130 */
4046 4131 static vnode_t *
4047 4132 pr_lookup_fddir(vnode_t *dp, char *comp)
4048 4133 {
4049 4134 prnode_t *dpnp = VTOP(dp);
4050 4135 prnode_t *pnp;
4051 4136 vnode_t *vp = NULL;
4052 4137 proc_t *p;
4053 4138 file_t *fp;
4054 4139 uint_t fd;
4055 4140 int c;
4056 4141 uf_entry_t *ufp;
4057 4142 uf_info_t *fip;
4058 4143
4059 4144 ASSERT(dpnp->pr_type == PR_FDDIR);
4060 4145
4061 4146 fd = 0;
4062 4147 while ((c = *comp++) != '\0') {
4063 4148 int ofd;
4064 4149 if (c < '0' || c > '9')
4065 4150 return (NULL);
4066 4151 ofd = fd;
4067 4152 fd = 10*fd + c - '0';
4068 4153 if (fd/10 != ofd) /* integer overflow */
4069 4154 return (NULL);
4070 4155 }
4071 4156
4072 4157 pnp = prgetnode(dp, PR_FD);
4073 4158
4074 4159 if (prlock(dpnp, ZNO) != 0) {
4075 4160 prfreenode(pnp);
4076 4161 return (NULL);
4077 4162 }
4078 4163 p = dpnp->pr_common->prc_proc;
4079 4164 if ((p->p_flag & SSYS) || p->p_as == &kas) {
4080 4165 prunlock(dpnp);
4081 4166 prfreenode(pnp);
4082 4167 return (NULL);
4083 4168 }
4084 4169
4085 4170 fip = P_FINFO(p);
4086 4171 mutex_exit(&p->p_lock);
4087 4172 mutex_enter(&fip->fi_lock);
4088 4173 if (fd < fip->fi_nfiles) {
4089 4174 UF_ENTER(ufp, fip, fd);
4090 4175 if ((fp = ufp->uf_file) != NULL) {
4091 4176 pnp->pr_mode = 07111;
4092 4177 if (fp->f_flag & FREAD)
4093 4178 pnp->pr_mode |= 0444;
4094 4179 if (fp->f_flag & FWRITE)
4095 4180 pnp->pr_mode |= 0222;
4096 4181 vp = fp->f_vnode;
4097 4182 VN_HOLD(vp);
4098 4183 }
4099 4184 UF_EXIT(ufp);
4100 4185 }
4101 4186 mutex_exit(&fip->fi_lock);
4102 4187 mutex_enter(&p->p_lock);
4103 4188 prunlock(dpnp);
4104 4189
4105 4190 if (vp == NULL)
4106 4191 prfreenode(pnp);
4107 4192 else {
4108 4193 /*
4109 4194 * Fill in the prnode so future references will
4110 4195 * be able to find the underlying object's vnode.
4111 4196 * Don't link this prnode into the list of all
4112 4197 * prnodes for the process; this is a one-use node.
4113 4198 */
4114 4199 pnp->pr_realvp = vp;
4115 4200 pnp->pr_parent = dp; /* needed for prlookup */
4116 4201 VN_HOLD(dp);
4117 4202 vp = PTOV(pnp);
4118 4203 if (pnp->pr_realvp->v_type == VDIR) {
4119 4204 vp->v_type = VDIR;
4120 4205 vp->v_flag |= VTRAVERSE;
4121 4206 }
4122 4207 }
4123 4208
4124 4209 return (vp);
4125 4210 }
4126 4211
4127 4212 static vnode_t *
4128 4213 pr_lookup_pathdir(vnode_t *dp, char *comp)
4129 4214 {
4130 4215 prnode_t *dpnp = VTOP(dp);
4131 4216 prnode_t *pnp;
4132 4217 vnode_t *vp = NULL;
4133 4218 proc_t *p;
4134 4219 uint_t fd, flags = 0;
4135 4220 int c;
4136 4221 uf_entry_t *ufp;
4137 4222 uf_info_t *fip;
4138 4223 enum { NAME_FD, NAME_OBJECT, NAME_ROOT, NAME_CWD, NAME_UNKNOWN } type;
4139 4224 char *tmp;
4140 4225 int idx;
4141 4226 struct seg *seg;
4142 4227 struct as *as = NULL;
4143 4228 vattr_t vattr;
4144 4229
4145 4230 ASSERT(dpnp->pr_type == PR_PATHDIR);
4146 4231
4147 4232 /*
4148 4233 * First, check if this is a numeric entry, in which case we have a
4149 4234 * file descriptor.
4150 4235 */
4151 4236 fd = 0;
4152 4237 type = NAME_FD;
4153 4238 tmp = comp;
4154 4239 while ((c = *tmp++) != '\0') {
4155 4240 int ofd;
4156 4241 if (c < '0' || c > '9') {
4157 4242 type = NAME_UNKNOWN;
4158 4243 break;
4159 4244 }
4160 4245 ofd = fd;
4161 4246 fd = 10*fd + c - '0';
4162 4247 if (fd/10 != ofd) { /* integer overflow */
4163 4248 type = NAME_UNKNOWN;
4164 4249 break;
4165 4250 }
4166 4251 }
4167 4252
4168 4253 /*
4169 4254 * Next, see if it is one of the special values {root, cwd}.
4170 4255 */
4171 4256 if (type == NAME_UNKNOWN) {
4172 4257 if (strcmp(comp, "root") == 0)
4173 4258 type = NAME_ROOT;
4174 4259 else if (strcmp(comp, "cwd") == 0)
4175 4260 type = NAME_CWD;
4176 4261 }
4177 4262
4178 4263 /*
4179 4264 * Grab the necessary data from the process
4180 4265 */
4181 4266 if (prlock(dpnp, ZNO) != 0)
4182 4267 return (NULL);
4183 4268 p = dpnp->pr_common->prc_proc;
4184 4269
4185 4270 fip = P_FINFO(p);
4186 4271
4187 4272 switch (type) {
4188 4273 case NAME_ROOT:
4189 4274 if ((vp = PTOU(p)->u_rdir) == NULL)
4190 4275 vp = p->p_zone->zone_rootvp;
4191 4276 VN_HOLD(vp);
4192 4277 break;
4193 4278 case NAME_CWD:
4194 4279 vp = PTOU(p)->u_cdir;
4195 4280 VN_HOLD(vp);
4196 4281 break;
4197 4282 default:
4198 4283 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
4199 4284 prunlock(dpnp);
4200 4285 return (NULL);
4201 4286 }
4202 4287 }
4203 4288 mutex_exit(&p->p_lock);
4204 4289
4205 4290 /*
4206 4291 * Determine if this is an object entry
4207 4292 */
4208 4293 if (type == NAME_UNKNOWN) {
4209 4294 /*
4210 4295 * Start with the inode index immediately after the number of
4211 4296 * files.
4212 4297 */
4213 4298 mutex_enter(&fip->fi_lock);
4214 4299 idx = fip->fi_nfiles + 4;
4215 4300 mutex_exit(&fip->fi_lock);
4216 4301
4217 4302 if (strcmp(comp, "a.out") == 0) {
4218 4303 if (p->p_execdir != NULL) {
4219 4304 vp = p->p_execdir;
4220 4305 VN_HOLD(vp);
4221 4306 type = NAME_OBJECT;
4222 4307 flags |= PR_AOUT;
4223 4308 } else {
4224 4309 vp = p->p_exec;
4225 4310 VN_HOLD(vp);
4226 4311 type = NAME_OBJECT;
4227 4312 }
4228 4313 } else {
4229 4314 AS_LOCK_ENTER(as, RW_READER);
4230 4315 if ((seg = AS_SEGFIRST(as)) != NULL) {
4231 4316 do {
4232 4317 /*
4233 4318 * Manufacture a filename for the
4234 4319 * "object" directory.
4235 4320 */
4236 4321 vattr.va_mask = AT_FSID|AT_NODEID;
4237 4322 if (seg->s_ops == &segvn_ops &&
4238 4323 SEGOP_GETVP(seg, seg->s_base, &vp)
4239 4324 == 0 &&
4240 4325 vp != NULL && vp->v_type == VREG &&
4241 4326 VOP_GETATTR(vp, &vattr, 0, CRED(),
4242 4327 NULL) == 0) {
4243 4328 char name[64];
4244 4329
4245 4330 if (vp == p->p_exec)
4246 4331 continue;
4247 4332 idx++;
4248 4333 pr_object_name(name, vp,
4249 4334 &vattr);
4250 4335 if (strcmp(name, comp) == 0)
4251 4336 break;
4252 4337 }
4253 4338 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4254 4339 }
4255 4340
4256 4341 if (seg == NULL) {
4257 4342 vp = NULL;
4258 4343 } else {
4259 4344 VN_HOLD(vp);
4260 4345 type = NAME_OBJECT;
4261 4346 }
4262 4347
4263 4348 AS_LOCK_EXIT(as);
4264 4349 }
4265 4350 }
4266 4351
4267 4352
4268 4353 switch (type) {
4269 4354 case NAME_FD:
4270 4355 mutex_enter(&fip->fi_lock);
4271 4356 if (fd < fip->fi_nfiles) {
4272 4357 UF_ENTER(ufp, fip, fd);
4273 4358 if (ufp->uf_file != NULL) {
4274 4359 vp = ufp->uf_file->f_vnode;
4275 4360 VN_HOLD(vp);
4276 4361 }
4277 4362 UF_EXIT(ufp);
4278 4363 }
4279 4364 mutex_exit(&fip->fi_lock);
4280 4365 idx = fd + 4;
4281 4366 break;
4282 4367 case NAME_ROOT:
4283 4368 idx = 2;
4284 4369 break;
4285 4370 case NAME_CWD:
4286 4371 idx = 3;
4287 4372 break;
4288 4373 case NAME_OBJECT:
4289 4374 case NAME_UNKNOWN:
4290 4375 /* Nothing to do */
4291 4376 break;
4292 4377 }
4293 4378
4294 4379 mutex_enter(&p->p_lock);
4295 4380 prunlock(dpnp);
4296 4381
4297 4382 if (vp != NULL) {
4298 4383 pnp = prgetnode(dp, PR_PATH);
4299 4384
4300 4385 pnp->pr_flags |= flags;
4301 4386 pnp->pr_common = dpnp->pr_common;
4302 4387 pnp->pr_pcommon = dpnp->pr_pcommon;
4303 4388 pnp->pr_realvp = vp;
4304 4389 pnp->pr_parent = dp; /* needed for prlookup */
4305 4390 pnp->pr_ino = pmkino(idx, dpnp->pr_common->prc_slot, PR_PATH);
4306 4391 VN_HOLD(dp);
4307 4392 vp = PTOV(pnp);
4308 4393 vp->v_type = VLNK;
4309 4394 }
4310 4395
4311 4396 return (vp);
4312 4397 }
4313 4398
4314 4399 /*
4315 4400 * Look up one of the process's active templates.
4316 4401 */
4317 4402 static vnode_t *
4318 4403 pr_lookup_tmpldir(vnode_t *dp, char *comp)
4319 4404 {
4320 4405 prnode_t *dpnp = VTOP(dp);
4321 4406 prnode_t *pnp;
4322 4407 vnode_t *vp = NULL;
4323 4408 proc_t *p;
4324 4409 int i;
4325 4410
4326 4411 ASSERT(dpnp->pr_type == PR_TMPLDIR);
4327 4412
4328 4413 for (i = 0; i < ct_ntypes; i++)
4329 4414 if (strcmp(comp, ct_types[i]->ct_type_name) == 0)
4330 4415 break;
4331 4416 if (i == ct_ntypes)
4332 4417 return (NULL);
4333 4418
4334 4419 pnp = prgetnode(dp, PR_TMPL);
4335 4420
4336 4421 if (prlock(dpnp, ZNO) != 0) {
4337 4422 prfreenode(pnp);
4338 4423 return (NULL);
4339 4424 }
4340 4425 p = dpnp->pr_common->prc_proc;
4341 4426 if ((p->p_flag & SSYS) || p->p_as == &kas ||
4342 4427 (dpnp->pr_common->prc_flags & (PRC_DESTROY | PRC_LWP)) != PRC_LWP) {
4343 4428 prunlock(dpnp);
4344 4429 prfreenode(pnp);
4345 4430 return (NULL);
4346 4431 }
4347 4432 if (ttolwp(dpnp->pr_common->prc_thread)->lwp_ct_active[i] != NULL) {
4348 4433 pnp->pr_common = dpnp->pr_common;
4349 4434 pnp->pr_pcommon = dpnp->pr_pcommon;
4350 4435 pnp->pr_parent = dp;
4351 4436 pnp->pr_cttype = i;
4352 4437 VN_HOLD(dp);
4353 4438 vp = PTOV(pnp);
4354 4439 } else {
4355 4440 prfreenode(pnp);
4356 4441 }
4357 4442 prunlock(dpnp);
4358 4443
4359 4444 return (vp);
4360 4445 }
4361 4446
4362 4447 /*
4363 4448 * Look up one of the contracts owned by the process.
4364 4449 */
4365 4450 static vnode_t *
4366 4451 pr_lookup_ctdir(vnode_t *dp, char *comp)
4367 4452 {
4368 4453 prnode_t *dpnp = VTOP(dp);
4369 4454 prnode_t *pnp;
4370 4455 vnode_t *vp = NULL;
4371 4456 proc_t *p;
4372 4457 id_t id = 0;
4373 4458 contract_t *ct;
4374 4459 int c;
4375 4460
4376 4461 ASSERT(dpnp->pr_type == PR_CTDIR);
4377 4462
4378 4463 while ((c = *comp++) != '\0') {
4379 4464 id_t oid;
4380 4465 if (c < '0' || c > '9')
4381 4466 return (NULL);
4382 4467 oid = id;
4383 4468 id = 10 * id + c - '0';
4384 4469 if (id / 10 != oid) /* integer overflow */
4385 4470 return (NULL);
4386 4471 }
4387 4472
4388 4473 /*
4389 4474 * Search all contracts; we'll filter below.
4390 4475 */
4391 4476 ct = contract_ptr(id, GLOBAL_ZONEUNIQID);
4392 4477 if (ct == NULL)
4393 4478 return (NULL);
4394 4479
4395 4480 pnp = prgetnode(dp, PR_CT);
4396 4481
4397 4482 if (prlock(dpnp, ZNO) != 0) {
4398 4483 prfreenode(pnp);
4399 4484 contract_rele(ct);
4400 4485 return (NULL);
4401 4486 }
4402 4487 p = dpnp->pr_common->prc_proc;
4403 4488 /*
4404 4489 * We only allow lookups of contracts owned by this process, or,
4405 4490 * if we are zsched and this is a zone's procfs, contracts on
4406 4491 * stuff in the zone which are held by processes or contracts
4407 4492 * outside the zone. (see logic in contract_status_common)
4408 4493 */
4409 4494 if ((ct->ct_owner != p) &&
4410 4495 !(p == VTOZONE(dp)->zone_zsched && ct->ct_state < CTS_ORPHAN &&
4411 4496 VTOZONE(dp)->zone_uniqid == contract_getzuniqid(ct) &&
4412 4497 VTOZONE(dp)->zone_uniqid != GLOBAL_ZONEUNIQID &&
4413 4498 ct->ct_czuniqid == GLOBAL_ZONEUNIQID)) {
4414 4499 prunlock(dpnp);
4415 4500 prfreenode(pnp);
4416 4501 contract_rele(ct);
4417 4502 return (NULL);
4418 4503 }
4419 4504 pnp->pr_common = dpnp->pr_common;
4420 4505 pnp->pr_pcommon = dpnp->pr_pcommon;
4421 4506 pnp->pr_contract = ct;
4422 4507 pnp->pr_parent = dp;
4423 4508 pnp->pr_ino = pmkino(id, pnp->pr_common->prc_slot, PR_CT);
4424 4509 VN_HOLD(dp);
4425 4510 prunlock(dpnp);
4426 4511 vp = PTOV(pnp);
4427 4512
4428 4513 return (vp);
4429 4514 }
4430 4515
4431 4516 /*
4432 4517 * Construct an lwp vnode for the old /proc interface.
4433 4518 * We stand on our head to make the /proc plumbing correct.
4434 4519 */
4435 4520 vnode_t *
4436 4521 prlwpnode(prnode_t *pnp, uint_t tid)
4437 4522 {
4438 4523 char comp[12];
4439 4524 vnode_t *dp;
4440 4525 vnode_t *vp;
4441 4526 prcommon_t *pcp;
4442 4527 proc_t *p;
4443 4528
4444 4529 /*
4445 4530 * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode.
4446 4531 */
4447 4532 if (pnp->pr_type == PR_PIDFILE) {
4448 4533 dp = pnp->pr_parent; /* /proc/<pid> */
4449 4534 VN_HOLD(dp);
4450 4535 vp = pr_lookup_piddir(dp, "lwp");
4451 4536 VN_RELE(dp);
4452 4537 if ((dp = vp) == NULL) /* /proc/<pid>/lwp */
4453 4538 return (NULL);
4454 4539 } else if (pnp->pr_type == PR_LWPIDFILE) {
4455 4540 dp = pnp->pr_parent; /* /proc/<pid>/lwp/<lwpid> */
4456 4541 dp = VTOP(dp)->pr_parent; /* /proc/<pid>/lwp */
4457 4542 VN_HOLD(dp);
4458 4543 } else {
4459 4544 return (NULL);
4460 4545 }
4461 4546
4462 4547 (void) pr_u32tos(tid, comp, sizeof (comp));
4463 4548 vp = pr_lookup_lwpdir(dp, comp);
4464 4549 VN_RELE(dp);
4465 4550 if ((dp = vp) == NULL)
4466 4551 return (NULL);
4467 4552
4468 4553 pnp = prgetnode(dp, PR_LWPIDFILE);
4469 4554 vp = PTOV(pnp);
4470 4555
4471 4556 /*
4472 4557 * prgetnode() initialized most of the prnode.
4473 4558 * Finish the job.
4474 4559 */
4475 4560 pcp = VTOP(dp)->pr_common;
4476 4561 pnp->pr_ino = ptoi(pcp->prc_pid);
4477 4562 pnp->pr_common = pcp;
4478 4563 pnp->pr_pcommon = VTOP(dp)->pr_pcommon;
4479 4564 pnp->pr_parent = dp;
4480 4565 /*
4481 4566 * Link new vnode into list of all /proc vnodes for the process.
4482 4567 */
4483 4568 p = pr_p_lock(pnp);
4484 4569 mutex_exit(&pr_pidlock);
4485 4570 if (p == NULL) {
4486 4571 VN_RELE(dp);
4487 4572 prfreenode(pnp);
4488 4573 vp = NULL;
4489 4574 } else if (pcp->prc_thread == NULL) {
4490 4575 prunlock(pnp);
4491 4576 VN_RELE(dp);
4492 4577 prfreenode(pnp);
4493 4578 vp = NULL;
4494 4579 } else {
4495 4580 pnp->pr_next = p->p_plist;
4496 4581 p->p_plist = vp;
4497 4582 prunlock(pnp);
4498 4583 }
4499 4584
4500 4585 return (vp);
4501 4586 }
4502 4587
4503 4588 #if defined(DEBUG)
4504 4589
4505 4590 static uint32_t nprnode;
4506 4591 static uint32_t nprcommon;
4507 4592
4508 4593 #define INCREMENT(x) atomic_inc_32(&x);
4509 4594 #define DECREMENT(x) atomic_dec_32(&x);
4510 4595
4511 4596 #else
4512 4597
4513 4598 #define INCREMENT(x)
4514 4599 #define DECREMENT(x)
4515 4600
4516 4601 #endif /* DEBUG */
4517 4602
4518 4603 /*
4519 4604 * New /proc vnode required; allocate it and fill in most of the fields.
4520 4605 */
4521 4606 prnode_t *
4522 4607 prgetnode(vnode_t *dp, prnodetype_t type)
4523 4608 {
4524 4609 prnode_t *pnp;
4525 4610 prcommon_t *pcp;
4526 4611 vnode_t *vp;
4527 4612 ulong_t nfiles;
4528 4613
4529 4614 INCREMENT(nprnode);
4530 4615 pnp = kmem_zalloc(sizeof (prnode_t), KM_SLEEP);
4531 4616
4532 4617 mutex_init(&pnp->pr_mutex, NULL, MUTEX_DEFAULT, NULL);
4533 4618 pnp->pr_type = type;
4534 4619
4535 4620 pnp->pr_vnode = vn_alloc(KM_SLEEP);
4536 4621
4537 4622 vp = PTOV(pnp);
4538 4623 vp->v_flag = VNOCACHE|VNOMAP|VNOSWAP|VNOMOUNT;
4539 4624 vn_setops(vp, prvnodeops);
4540 4625 vp->v_vfsp = dp->v_vfsp;
4541 4626 vp->v_type = VPROC;
4542 4627 vp->v_data = (caddr_t)pnp;
4543 4628
4544 4629 switch (type) {
4545 4630 case PR_PIDDIR:
4546 4631 case PR_LWPIDDIR:
4547 4632 /*
4548 4633 * We need a prcommon and a files array for each of these.
4549 4634 */
4550 4635 INCREMENT(nprcommon);
4551 4636
4552 4637 pcp = kmem_zalloc(sizeof (prcommon_t), KM_SLEEP);
4553 4638 pcp->prc_refcnt = 1;
4554 4639 pnp->pr_common = pcp;
4555 4640 mutex_init(&pcp->prc_mutex, NULL, MUTEX_DEFAULT, NULL);
4556 4641 cv_init(&pcp->prc_wait, NULL, CV_DEFAULT, NULL);
4557 4642
4558 4643 nfiles = (type == PR_PIDDIR)? NPIDDIRFILES : NLWPIDDIRFILES;
4559 4644 pnp->pr_files =
4560 4645 kmem_zalloc(nfiles * sizeof (vnode_t *), KM_SLEEP);
4561 4646
4562 4647 vp->v_type = VDIR;
4563 4648 /*
4564 4649 * Mode should be read-search by all, but we cannot so long
4565 4650 * as we must support compatibility mode with old /proc.
4566 4651 * Make /proc/<pid> be read by owner only, search by all.
4567 4652 * Make /proc/<pid>/lwp/<lwpid> read-search by all. Also,
4568 4653 * set VDIROPEN on /proc/<pid> so it can be opened for writing.
4569 4654 */
4570 4655 if (type == PR_PIDDIR) {
4571 4656 /* kludge for old /proc interface */
4572 4657 prnode_t *xpnp = prgetnode(dp, PR_PIDFILE);
4573 4658 pnp->pr_pidfile = PTOV(xpnp);
4574 4659 pnp->pr_mode = 0511;
4575 4660 vp->v_flag |= VDIROPEN;
4576 4661 } else {
4577 4662 pnp->pr_mode = 0555;
4578 4663 }
4579 4664
4580 4665 break;
4581 4666
4582 4667 case PR_CURDIR:
4583 4668 case PR_ROOTDIR:
4584 4669 case PR_FDDIR:
4585 4670 case PR_OBJECTDIR:
4586 4671 case PR_PATHDIR:
4587 4672 case PR_CTDIR:
4588 4673 case PR_TMPLDIR:
4589 4674 vp->v_type = VDIR;
4590 4675 pnp->pr_mode = 0500; /* read-search by owner only */
4591 4676 break;
4592 4677
4593 4678 case PR_CT:
4594 4679 vp->v_type = VLNK;
4595 4680 pnp->pr_mode = 0500; /* read-search by owner only */
4596 4681 break;
4597 4682
4598 4683 case PR_PATH:
4599 4684 case PR_SELF:
4600 4685 vp->v_type = VLNK;
4601 4686 pnp->pr_mode = 0777;
4602 4687 break;
4603 4688
4604 4689 case PR_LWPDIR:
4605 4690 vp->v_type = VDIR;
4606 4691 pnp->pr_mode = 0555; /* read-search by all */
4607 4692 break;
4608 4693
4609 4694 case PR_AS:
4610 4695 case PR_TMPL:
4611 4696 pnp->pr_mode = 0600; /* read-write by owner only */
4612 4697 break;
4613 4698
↓ open down ↓ |
1243 lines elided |
↑ open up ↑ |
4614 4699 case PR_CTL:
4615 4700 case PR_LWPCTL:
4616 4701 pnp->pr_mode = 0200; /* write-only by owner only */
4617 4702 break;
4618 4703
4619 4704 case PR_PIDFILE:
4620 4705 case PR_LWPIDFILE:
4621 4706 pnp->pr_mode = 0600; /* read-write by owner only */
4622 4707 break;
4623 4708
4709 + case PR_LWPNAME:
4710 + pnp->pr_mode = 0644; /* readable by all + owner can write */
4711 + break;
4712 +
4624 4713 case PR_PSINFO:
4625 4714 case PR_LPSINFO:
4626 4715 case PR_LWPSINFO:
4627 4716 case PR_USAGE:
4628 4717 case PR_LUSAGE:
4629 4718 case PR_LWPUSAGE:
4630 4719 pnp->pr_mode = 0444; /* read-only by all */
4631 4720 break;
4632 4721
4633 4722 default:
4634 4723 pnp->pr_mode = 0400; /* read-only by owner only */
4635 4724 break;
4636 4725 }
4637 4726 vn_exists(vp);
4638 4727 return (pnp);
4639 4728 }
4640 4729
4641 4730 /*
4642 4731 * Free the storage obtained from prgetnode().
4643 4732 */
4644 4733 void
4645 4734 prfreenode(prnode_t *pnp)
4646 4735 {
4647 4736 vnode_t *vp;
4648 4737 ulong_t nfiles;
4649 4738
4650 4739 vn_invalid(PTOV(pnp));
4651 4740 vn_free(PTOV(pnp));
4652 4741 mutex_destroy(&pnp->pr_mutex);
4653 4742
4654 4743 switch (pnp->pr_type) {
4655 4744 case PR_PIDDIR:
4656 4745 /* kludge for old /proc interface */
4657 4746 if (pnp->pr_pidfile != NULL) {
4658 4747 prfreenode(VTOP(pnp->pr_pidfile));
4659 4748 pnp->pr_pidfile = NULL;
4660 4749 }
4661 4750 /* FALLTHROUGH */
4662 4751 case PR_LWPIDDIR:
4663 4752 /*
4664 4753 * We allocated a prcommon and a files array for each of these.
4665 4754 */
4666 4755 prfreecommon(pnp->pr_common);
4667 4756 nfiles = (pnp->pr_type == PR_PIDDIR)?
4668 4757 NPIDDIRFILES : NLWPIDDIRFILES;
4669 4758 kmem_free(pnp->pr_files, nfiles * sizeof (vnode_t *));
4670 4759 break;
4671 4760 default:
4672 4761 break;
4673 4762 }
4674 4763 /*
4675 4764 * If there is an underlying vnode, be sure
4676 4765 * to release it after freeing the prnode.
4677 4766 */
4678 4767 vp = pnp->pr_realvp;
4679 4768 kmem_free(pnp, sizeof (*pnp));
4680 4769 DECREMENT(nprnode);
4681 4770 if (vp != NULL) {
4682 4771 VN_RELE(vp);
4683 4772 }
4684 4773 }
4685 4774
4686 4775 /*
4687 4776 * Free a prcommon structure, if the reference count reaches zero.
4688 4777 */
4689 4778 static void
4690 4779 prfreecommon(prcommon_t *pcp)
4691 4780 {
4692 4781 mutex_enter(&pcp->prc_mutex);
4693 4782 ASSERT(pcp->prc_refcnt > 0);
4694 4783 if (--pcp->prc_refcnt != 0)
4695 4784 mutex_exit(&pcp->prc_mutex);
4696 4785 else {
4697 4786 mutex_exit(&pcp->prc_mutex);
4698 4787 ASSERT(pcp->prc_pollhead.ph_list == NULL);
4699 4788 ASSERT(pcp->prc_refcnt == 0);
4700 4789 ASSERT(pcp->prc_selfopens == 0 && pcp->prc_writers == 0);
4701 4790 mutex_destroy(&pcp->prc_mutex);
4702 4791 cv_destroy(&pcp->prc_wait);
4703 4792 kmem_free(pcp, sizeof (prcommon_t));
4704 4793 DECREMENT(nprcommon);
4705 4794 }
4706 4795 }
4707 4796
4708 4797 /*
4709 4798 * Array of readdir functions, indexed by /proc file type.
4710 4799 */
4711 4800 static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(),
4712 4801 pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(),
4713 4802 pr_readdir_fddir(), pr_readdir_pathdir(), pr_readdir_tmpldir(),
4714 4803 pr_readdir_ctdir();
4715 4804
4716 4805 static int (*pr_readdir_function[PR_NFILES])() = {
4717 4806 pr_readdir_procdir, /* /proc */
4718 4807 pr_readdir_notdir, /* /proc/self */
4719 4808 pr_readdir_piddir, /* /proc/<pid> */
4720 4809 pr_readdir_notdir, /* /proc/<pid>/as */
4721 4810 pr_readdir_notdir, /* /proc/<pid>/ctl */
4722 4811 pr_readdir_notdir, /* /proc/<pid>/status */
4723 4812 pr_readdir_notdir, /* /proc/<pid>/lstatus */
4724 4813 pr_readdir_notdir, /* /proc/<pid>/psinfo */
4725 4814 pr_readdir_notdir, /* /proc/<pid>/lpsinfo */
4726 4815 pr_readdir_notdir, /* /proc/<pid>/map */
4727 4816 pr_readdir_notdir, /* /proc/<pid>/rmap */
4728 4817 pr_readdir_notdir, /* /proc/<pid>/xmap */
4729 4818 pr_readdir_notdir, /* /proc/<pid>/cred */
4730 4819 pr_readdir_notdir, /* /proc/<pid>/sigact */
4731 4820 pr_readdir_notdir, /* /proc/<pid>/auxv */
4732 4821 #if defined(__x86)
4733 4822 pr_readdir_notdir, /* /proc/<pid>/ldt */
4734 4823 #endif
4735 4824 pr_readdir_notdir, /* /proc/<pid>/usage */
4736 4825 pr_readdir_notdir, /* /proc/<pid>/lusage */
4737 4826 pr_readdir_notdir, /* /proc/<pid>/pagedata */
↓ open down ↓ |
104 lines elided |
↑ open up ↑ |
4738 4827 pr_readdir_notdir, /* /proc/<pid>/watch */
4739 4828 pr_readdir_notdir, /* /proc/<pid>/cwd */
4740 4829 pr_readdir_notdir, /* /proc/<pid>/root */
4741 4830 pr_readdir_fddir, /* /proc/<pid>/fd */
4742 4831 pr_readdir_notdir, /* /proc/<pid>/fd/nn */
4743 4832 pr_readdir_objectdir, /* /proc/<pid>/object */
4744 4833 pr_readdir_notdir, /* /proc/<pid>/object/xxx */
4745 4834 pr_readdir_lwpdir, /* /proc/<pid>/lwp */
4746 4835 pr_readdir_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
4747 4836 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
4837 + pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */
4748 4838 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
4749 4839 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4750 4840 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4751 4841 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
4752 4842 pr_readdir_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
4753 4843 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4754 4844 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */
4755 4845 #if defined(__sparc)
4756 4846 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */
4757 4847 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */
4758 4848 #endif
4759 4849 pr_readdir_notdir, /* /proc/<pid>/priv */
4760 4850 pr_readdir_pathdir, /* /proc/<pid>/path */
4761 4851 pr_readdir_notdir, /* /proc/<pid>/path/xxx */
4762 4852 pr_readdir_ctdir, /* /proc/<pid>/contracts */
4763 4853 pr_readdir_notdir, /* /proc/<pid>/contracts/<ctid> */
4764 4854 pr_readdir_notdir, /* /proc/<pid>/secflags */
4765 4855 pr_readdir_notdir, /* old process file */
4766 4856 pr_readdir_notdir, /* old lwp file */
4767 4857 pr_readdir_notdir, /* old pagedata file */
4768 4858 };
4769 4859
4770 4860 /* ARGSUSED */
4771 4861 static int
4772 4862 prreaddir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
4773 4863 caller_context_t *ct, int flags)
4774 4864 {
4775 4865 prnode_t *pnp = VTOP(vp);
4776 4866
4777 4867 ASSERT(pnp->pr_type < PR_NFILES);
4778 4868
4779 4869 /* XXX - Do we need to pass ct and flags? */
4780 4870 return (pr_readdir_function[pnp->pr_type](pnp, uiop, eofp));
4781 4871 }
4782 4872
4783 4873 /* ARGSUSED */
4784 4874 static int
4785 4875 pr_readdir_notdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4786 4876 {
4787 4877 return (ENOTDIR);
4788 4878 }
4789 4879
4790 4880 /* ARGSUSED */
4791 4881 static int
4792 4882 pr_readdir_procdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4793 4883 {
4794 4884 zoneid_t zoneid;
4795 4885 gfs_readdir_state_t gstate;
4796 4886 int error, eof = 0;
4797 4887 offset_t n;
4798 4888
4799 4889 ASSERT(pnp->pr_type == PR_PROCDIR);
4800 4890
4801 4891 zoneid = VTOZONE(PTOV(pnp))->zone_id;
4802 4892
4803 4893 if ((error = gfs_readdir_init(&gstate, PNSIZ, PRSDSIZE, uiop,
4804 4894 PRROOTINO, PRROOTINO, 0)) != 0)
4805 4895 return (error);
4806 4896
4807 4897 /*
4808 4898 * Loop until user's request is satisfied or until all processes
4809 4899 * have been examined.
4810 4900 */
4811 4901 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
4812 4902 uint_t pid;
4813 4903 int pslot;
4814 4904 proc_t *p;
4815 4905
4816 4906 /*
4817 4907 * Find next entry. Skip processes not visible where
4818 4908 * this /proc was mounted.
4819 4909 */
4820 4910 mutex_enter(&pidlock);
4821 4911 while (n < v.v_proc &&
4822 4912 ((p = pid_entry(n)) == NULL || p->p_stat == SIDL ||
4823 4913 (zoneid != GLOBAL_ZONEID && p->p_zone->zone_id != zoneid) ||
4824 4914 secpolicy_basic_procinfo(CRED(), p, curproc) != 0))
4825 4915 n++;
4826 4916
4827 4917 /*
4828 4918 * Stop when entire proc table has been examined.
4829 4919 */
4830 4920 if (n >= v.v_proc) {
4831 4921 mutex_exit(&pidlock);
4832 4922 eof = 1;
4833 4923 break;
4834 4924 }
4835 4925
4836 4926 ASSERT(p->p_stat != 0);
4837 4927 pid = p->p_pid;
4838 4928 pslot = p->p_slot;
4839 4929 mutex_exit(&pidlock);
4840 4930 error = gfs_readdir_emitn(&gstate, uiop, n,
4841 4931 pmkino(0, pslot, PR_PIDDIR), pid);
4842 4932 if (error)
4843 4933 break;
4844 4934 }
4845 4935
4846 4936 return (gfs_readdir_fini(&gstate, error, eofp, eof));
4847 4937 }
4848 4938
4849 4939 /* ARGSUSED */
4850 4940 static int
4851 4941 pr_readdir_piddir(prnode_t *pnp, uio_t *uiop, int *eofp)
4852 4942 {
4853 4943 int zombie = ((pnp->pr_pcommon->prc_flags & PRC_DESTROY) != 0);
4854 4944 prdirent_t dirent;
4855 4945 prdirent_t *dirp;
4856 4946 offset_t off;
4857 4947 int error;
4858 4948
4859 4949 ASSERT(pnp->pr_type == PR_PIDDIR);
4860 4950
4861 4951 if (uiop->uio_offset < 0 ||
4862 4952 uiop->uio_offset % sizeof (prdirent_t) != 0 ||
4863 4953 uiop->uio_resid < sizeof (prdirent_t))
4864 4954 return (EINVAL);
4865 4955 if (pnp->pr_pcommon->prc_proc == NULL)
4866 4956 return (ENOENT);
4867 4957 if (uiop->uio_offset >= sizeof (piddir))
4868 4958 goto out;
4869 4959
4870 4960 /*
4871 4961 * Loop until user's request is satisfied, omitting some
4872 4962 * files along the way if the process is a zombie.
4873 4963 */
4874 4964 for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)];
4875 4965 uiop->uio_resid >= sizeof (prdirent_t) &&
4876 4966 dirp < &piddir[NPIDDIRFILES+2];
4877 4967 uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
4878 4968 off = uiop->uio_offset;
4879 4969 if (zombie) {
4880 4970 switch (dirp->d_ino) {
4881 4971 case PR_PIDDIR:
4882 4972 case PR_PROCDIR:
4883 4973 case PR_PSINFO:
4884 4974 case PR_USAGE:
4885 4975 break;
4886 4976 default:
4887 4977 continue;
4888 4978 }
4889 4979 }
4890 4980 bcopy(dirp, &dirent, sizeof (prdirent_t));
4891 4981 if (dirent.d_ino == PR_PROCDIR)
4892 4982 dirent.d_ino = PRROOTINO;
4893 4983 else
4894 4984 dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot,
4895 4985 dirent.d_ino);
4896 4986 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
4897 4987 UIO_READ, uiop)) != 0)
4898 4988 return (error);
4899 4989 }
4900 4990 out:
4901 4991 if (eofp)
4902 4992 *eofp = (uiop->uio_offset >= sizeof (piddir));
4903 4993 return (0);
4904 4994 }
4905 4995
4906 4996 static void
4907 4997 rebuild_objdir(struct as *as)
4908 4998 {
4909 4999 struct seg *seg;
4910 5000 vnode_t *vp;
4911 5001 vattr_t vattr;
4912 5002 vnode_t **dir;
4913 5003 ulong_t nalloc;
4914 5004 ulong_t nentries;
4915 5005 int i, j;
4916 5006 ulong_t nold, nnew;
4917 5007
4918 5008 ASSERT(AS_WRITE_HELD(as));
4919 5009
4920 5010 if (as->a_updatedir == 0 && as->a_objectdir != NULL)
4921 5011 return;
4922 5012 as->a_updatedir = 0;
4923 5013
4924 5014 if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 ||
4925 5015 (seg = AS_SEGFIRST(as)) == NULL) /* can't happen? */
4926 5016 return;
4927 5017
4928 5018 /*
4929 5019 * Allocate space for the new object directory.
4930 5020 * (This is usually about two times too many entries.)
4931 5021 */
4932 5022 nalloc = (nalloc + 0xf) & ~0xf; /* multiple of 16 */
4933 5023 dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP);
4934 5024
4935 5025 /* fill in the new directory with desired entries */
4936 5026 nentries = 0;
4937 5027 do {
4938 5028 vattr.va_mask = AT_FSID|AT_NODEID;
4939 5029 if (seg->s_ops == &segvn_ops &&
4940 5030 SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
4941 5031 vp != NULL && vp->v_type == VREG &&
4942 5032 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
4943 5033 for (i = 0; i < nentries; i++)
4944 5034 if (vp == dir[i])
4945 5035 break;
4946 5036 if (i == nentries) {
4947 5037 ASSERT(nentries < nalloc);
4948 5038 dir[nentries++] = vp;
4949 5039 }
4950 5040 }
4951 5041 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4952 5042
4953 5043 if (as->a_objectdir == NULL) { /* first time */
4954 5044 as->a_objectdir = dir;
4955 5045 as->a_sizedir = nalloc;
4956 5046 return;
4957 5047 }
4958 5048
4959 5049 /*
4960 5050 * Null out all of the defunct entries in the old directory.
4961 5051 */
4962 5052 nold = 0;
4963 5053 nnew = nentries;
4964 5054 for (i = 0; i < as->a_sizedir; i++) {
4965 5055 if ((vp = as->a_objectdir[i]) != NULL) {
4966 5056 for (j = 0; j < nentries; j++) {
4967 5057 if (vp == dir[j]) {
4968 5058 dir[j] = NULL;
4969 5059 nnew--;
4970 5060 break;
4971 5061 }
4972 5062 }
4973 5063 if (j == nentries)
4974 5064 as->a_objectdir[i] = NULL;
4975 5065 else
4976 5066 nold++;
4977 5067 }
4978 5068 }
4979 5069
4980 5070 if (nold + nnew > as->a_sizedir) {
4981 5071 /*
4982 5072 * Reallocate the old directory to have enough
4983 5073 * space for the old and new entries combined.
4984 5074 * Round up to the next multiple of 16.
4985 5075 */
4986 5076 ulong_t newsize = (nold + nnew + 0xf) & ~0xf;
4987 5077 vnode_t **newdir = kmem_zalloc(newsize * sizeof (vnode_t *),
4988 5078 KM_SLEEP);
4989 5079 bcopy(as->a_objectdir, newdir,
4990 5080 as->a_sizedir * sizeof (vnode_t *));
4991 5081 kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *));
4992 5082 as->a_objectdir = newdir;
4993 5083 as->a_sizedir = newsize;
4994 5084 }
4995 5085
4996 5086 /*
4997 5087 * Move all new entries to the old directory and
4998 5088 * deallocate the space used by the new directory.
4999 5089 */
5000 5090 if (nnew) {
5001 5091 for (i = 0, j = 0; i < nentries; i++) {
5002 5092 if ((vp = dir[i]) == NULL)
5003 5093 continue;
5004 5094 for (; j < as->a_sizedir; j++) {
5005 5095 if (as->a_objectdir[j] != NULL)
5006 5096 continue;
5007 5097 as->a_objectdir[j++] = vp;
5008 5098 break;
5009 5099 }
5010 5100 }
5011 5101 }
5012 5102 kmem_free(dir, nalloc * sizeof (vnode_t *));
5013 5103 }
5014 5104
5015 5105 /*
5016 5106 * Return the vnode from a slot in the process's object directory.
5017 5107 * The caller must have locked the process's address space.
5018 5108 * The only caller is below, in pr_readdir_objectdir().
5019 5109 */
5020 5110 static vnode_t *
5021 5111 obj_entry(struct as *as, int slot)
5022 5112 {
5023 5113 ASSERT(AS_LOCK_HELD(as));
5024 5114 if (as->a_objectdir == NULL)
5025 5115 return (NULL);
5026 5116 ASSERT(slot < as->a_sizedir);
5027 5117 return (as->a_objectdir[slot]);
5028 5118 }
5029 5119
5030 5120 /* ARGSUSED */
5031 5121 static int
5032 5122 pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5033 5123 {
5034 5124 gfs_readdir_state_t gstate;
5035 5125 int error, eof = 0;
5036 5126 offset_t n;
5037 5127 int pslot;
5038 5128 size_t objdirsize;
5039 5129 proc_t *p;
5040 5130 struct as *as;
5041 5131 vnode_t *vp;
5042 5132
5043 5133 ASSERT(pnp->pr_type == PR_OBJECTDIR);
5044 5134
5045 5135 if ((error = prlock(pnp, ZNO)) != 0)
5046 5136 return (error);
5047 5137 p = pnp->pr_common->prc_proc;
5048 5138 pslot = p->p_slot;
5049 5139
5050 5140 /*
5051 5141 * We drop p_lock before grabbing the address space lock
5052 5142 * in order to avoid a deadlock with the clock thread.
5053 5143 * The process will not disappear and its address space
5054 5144 * will not change because it is marked P_PR_LOCK.
5055 5145 */
5056 5146 mutex_exit(&p->p_lock);
5057 5147
5058 5148 if ((error = gfs_readdir_init(&gstate, 64, PRSDSIZE, uiop,
5059 5149 pmkino(0, pslot, PR_PIDDIR),
5060 5150 pmkino(0, pslot, PR_OBJECTDIR), 0)) != 0) {
5061 5151 mutex_enter(&p->p_lock);
5062 5152 prunlock(pnp);
5063 5153 return (error);
5064 5154 }
5065 5155
5066 5156 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5067 5157 as = NULL;
5068 5158 objdirsize = 0;
5069 5159 }
5070 5160
5071 5161 /*
5072 5162 * Loop until user's request is satisfied or until
5073 5163 * all mapped objects have been examined. Cannot hold
5074 5164 * the address space lock for the following call as
5075 5165 * gfs_readdir_pred() utimately causes a call to uiomove().
5076 5166 */
5077 5167 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5078 5168 vattr_t vattr;
5079 5169 char str[64];
5080 5170
5081 5171 /*
5082 5172 * Set the correct size of the directory just
5083 5173 * in case the process has changed it's address
5084 5174 * space via mmap/munmap calls.
5085 5175 */
5086 5176 if (as != NULL) {
5087 5177 AS_LOCK_ENTER(as, RW_WRITER);
5088 5178 if (as->a_updatedir)
5089 5179 rebuild_objdir(as);
5090 5180 objdirsize = as->a_sizedir;
5091 5181 }
5092 5182
5093 5183 /*
5094 5184 * Find next object.
5095 5185 */
5096 5186 vattr.va_mask = AT_FSID | AT_NODEID;
5097 5187 while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) ||
5098 5188 (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL)
5099 5189 != 0))) {
5100 5190 vattr.va_mask = AT_FSID | AT_NODEID;
5101 5191 n++;
5102 5192 }
5103 5193
5104 5194 if (as != NULL)
5105 5195 AS_LOCK_EXIT(as);
5106 5196
5107 5197 /*
5108 5198 * Stop when all objects have been reported.
5109 5199 */
5110 5200 if (n >= objdirsize) {
5111 5201 eof = 1;
5112 5202 break;
5113 5203 }
5114 5204
5115 5205 if (vp == p->p_exec)
5116 5206 (void) strcpy(str, "a.out");
5117 5207 else
5118 5208 pr_object_name(str, vp, &vattr);
5119 5209
5120 5210 error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
5121 5211 str, 0);
5122 5212
5123 5213 if (error)
5124 5214 break;
5125 5215 }
5126 5216
5127 5217 mutex_enter(&p->p_lock);
5128 5218 prunlock(pnp);
5129 5219
5130 5220 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5131 5221 }
5132 5222
5133 5223 /* ARGSUSED */
5134 5224 static int
5135 5225 pr_readdir_lwpdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5136 5226 {
5137 5227 gfs_readdir_state_t gstate;
5138 5228 int error, eof = 0;
5139 5229 offset_t tslot;
5140 5230 proc_t *p;
5141 5231 int pslot;
5142 5232 lwpdir_t *lwpdir;
5143 5233 int lwpdirsize;
5144 5234
5145 5235 ASSERT(pnp->pr_type == PR_LWPDIR);
5146 5236
5147 5237 p = pr_p_lock(pnp);
5148 5238 mutex_exit(&pr_pidlock);
5149 5239 if (p == NULL)
5150 5240 return (ENOENT);
5151 5241 ASSERT(p == pnp->pr_common->prc_proc);
5152 5242 pslot = p->p_slot;
5153 5243 lwpdir = p->p_lwpdir;
5154 5244 lwpdirsize = p->p_lwpdir_sz;
5155 5245
5156 5246 /*
5157 5247 * Drop p->p_lock so we can safely do uiomove().
5158 5248 * The lwp directory will not change because
5159 5249 * we have the process locked with P_PR_LOCK.
5160 5250 */
5161 5251 mutex_exit(&p->p_lock);
5162 5252
5163 5253
5164 5254 if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5165 5255 pmkino(0, pslot, PR_PIDDIR),
5166 5256 pmkino(0, pslot, PR_LWPDIR), 0)) != 0) {
5167 5257 mutex_enter(&p->p_lock);
5168 5258 prunlock(pnp);
5169 5259 return (error);
5170 5260 }
5171 5261
5172 5262 /*
5173 5263 * Loop until user's request is satisfied or until all lwps
5174 5264 * have been examined.
5175 5265 */
5176 5266 while ((error = gfs_readdir_pred(&gstate, uiop, &tslot)) == 0) {
5177 5267 lwpent_t *lep;
5178 5268 uint_t tid;
5179 5269
5180 5270 /*
5181 5271 * Find next LWP.
5182 5272 */
5183 5273 while (tslot < lwpdirsize &&
5184 5274 ((lep = lwpdir[tslot].ld_entry) == NULL))
5185 5275 tslot++;
5186 5276 /*
5187 5277 * Stop when all lwps have been reported.
5188 5278 */
5189 5279 if (tslot >= lwpdirsize) {
5190 5280 eof = 1;
5191 5281 break;
5192 5282 }
5193 5283
5194 5284 tid = lep->le_lwpid;
5195 5285 error = gfs_readdir_emitn(&gstate, uiop, tslot,
5196 5286 pmkino(tslot, pslot, PR_LWPIDDIR), tid);
5197 5287 if (error)
5198 5288 break;
5199 5289 }
5200 5290
5201 5291 mutex_enter(&p->p_lock);
5202 5292 prunlock(pnp);
5203 5293
5204 5294 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5205 5295 }
5206 5296
5207 5297 /* ARGSUSED */
5208 5298 static int
5209 5299 pr_readdir_lwpiddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5210 5300 {
5211 5301 prcommon_t *pcp = pnp->pr_common;
5212 5302 int zombie = ((pcp->prc_flags & PRC_DESTROY) != 0);
5213 5303 prdirent_t dirent;
5214 5304 prdirent_t *dirp;
5215 5305 offset_t off;
5216 5306 int error;
5217 5307 int pslot;
5218 5308 int tslot;
5219 5309
5220 5310 ASSERT(pnp->pr_type == PR_LWPIDDIR);
5221 5311
5222 5312 if (uiop->uio_offset < 0 ||
5223 5313 uiop->uio_offset % sizeof (prdirent_t) != 0 ||
5224 5314 uiop->uio_resid < sizeof (prdirent_t))
5225 5315 return (EINVAL);
5226 5316 if (pcp->prc_proc == NULL || pcp->prc_tslot == -1)
5227 5317 return (ENOENT);
5228 5318 if (uiop->uio_offset >= sizeof (lwpiddir))
5229 5319 goto out;
5230 5320
5231 5321 /*
5232 5322 * Loop until user's request is satisfied, omitting some files
5233 5323 * along the way if the lwp is a zombie and also depending
5234 5324 * on the data model of the process.
5235 5325 */
5236 5326 pslot = pcp->prc_slot;
5237 5327 tslot = pcp->prc_tslot;
5238 5328 for (dirp = &lwpiddir[uiop->uio_offset / sizeof (prdirent_t)];
5239 5329 uiop->uio_resid >= sizeof (prdirent_t) &&
5240 5330 dirp < &lwpiddir[NLWPIDDIRFILES+2];
5241 5331 uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
5242 5332 off = uiop->uio_offset;
5243 5333 if (zombie) {
5244 5334 switch (dirp->d_ino) {
5245 5335 case PR_LWPIDDIR:
5246 5336 case PR_LWPDIR:
5247 5337 case PR_LWPSINFO:
5248 5338 break;
5249 5339 default:
5250 5340 continue;
5251 5341 }
5252 5342 }
5253 5343 #if defined(__sparc)
5254 5344 /* the asrs file exists only for sparc v9 _LP64 processes */
5255 5345 if (dirp->d_ino == PR_ASRS &&
5256 5346 pcp->prc_datamodel != DATAMODEL_LP64)
5257 5347 continue;
5258 5348 #endif
5259 5349 bcopy(dirp, &dirent, sizeof (prdirent_t));
5260 5350 if (dirent.d_ino == PR_LWPDIR)
5261 5351 dirent.d_ino = pmkino(0, pslot, dirp->d_ino);
5262 5352 else
5263 5353 dirent.d_ino = pmkino(tslot, pslot, dirp->d_ino);
5264 5354 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
5265 5355 UIO_READ, uiop)) != 0)
5266 5356 return (error);
5267 5357 }
5268 5358 out:
5269 5359 if (eofp)
5270 5360 *eofp = (uiop->uio_offset >= sizeof (lwpiddir));
5271 5361 return (0);
5272 5362 }
5273 5363
5274 5364 /* ARGSUSED */
5275 5365 static int
5276 5366 pr_readdir_fddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5277 5367 {
5278 5368 gfs_readdir_state_t gstate;
5279 5369 int error, eof = 0;
5280 5370 offset_t n;
5281 5371 proc_t *p;
5282 5372 int pslot;
5283 5373 int fddirsize;
5284 5374 uf_info_t *fip;
5285 5375
5286 5376 ASSERT(pnp->pr_type == PR_FDDIR);
5287 5377
5288 5378 if ((error = prlock(pnp, ZNO)) != 0)
5289 5379 return (error);
5290 5380 p = pnp->pr_common->prc_proc;
5291 5381 pslot = p->p_slot;
5292 5382 fip = P_FINFO(p);
5293 5383 mutex_exit(&p->p_lock);
5294 5384
5295 5385 if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5296 5386 pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_FDDIR), 0)) != 0) {
5297 5387 mutex_enter(&p->p_lock);
5298 5388 prunlock(pnp);
5299 5389 return (error);
5300 5390 }
5301 5391
5302 5392 mutex_enter(&fip->fi_lock);
5303 5393 if ((p->p_flag & SSYS) || p->p_as == &kas)
5304 5394 fddirsize = 0;
5305 5395 else
5306 5396 fddirsize = fip->fi_nfiles;
5307 5397
5308 5398 /*
5309 5399 * Loop until user's request is satisfied or until
5310 5400 * all file descriptors have been examined.
5311 5401 */
5312 5402 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5313 5403 /*
5314 5404 * Find next fd.
5315 5405 */
5316 5406 while (n < fddirsize && fip->fi_list[n].uf_file == NULL)
5317 5407 n++;
5318 5408 /*
5319 5409 * Stop when all fds have been reported.
5320 5410 */
5321 5411 if (n >= fddirsize) {
5322 5412 eof = 1;
5323 5413 break;
5324 5414 }
5325 5415
5326 5416 error = gfs_readdir_emitn(&gstate, uiop, n,
5327 5417 pmkino(n, pslot, PR_FD), n);
5328 5418 if (error)
5329 5419 break;
5330 5420 }
5331 5421
5332 5422 mutex_exit(&fip->fi_lock);
5333 5423 mutex_enter(&p->p_lock);
5334 5424 prunlock(pnp);
5335 5425
5336 5426 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5337 5427 }
5338 5428
5339 5429 /* ARGSUSED */
5340 5430 static int
5341 5431 pr_readdir_pathdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5342 5432 {
5343 5433 longlong_t bp[DIRENT64_RECLEN(64) / sizeof (longlong_t)];
5344 5434 dirent64_t *dirent = (dirent64_t *)bp;
5345 5435 int reclen;
5346 5436 ssize_t oresid;
5347 5437 offset_t off, idx;
5348 5438 int error = 0;
5349 5439 proc_t *p;
5350 5440 int fd, obj;
5351 5441 int pslot;
5352 5442 int fddirsize;
5353 5443 uf_info_t *fip;
5354 5444 struct as *as = NULL;
5355 5445 size_t objdirsize;
5356 5446 vattr_t vattr;
5357 5447 vnode_t *vp;
5358 5448
5359 5449 ASSERT(pnp->pr_type == PR_PATHDIR);
5360 5450
5361 5451 if (uiop->uio_offset < 0 ||
5362 5452 uiop->uio_resid <= 0 ||
5363 5453 (uiop->uio_offset % PRSDSIZE) != 0)
5364 5454 return (EINVAL);
5365 5455 oresid = uiop->uio_resid;
5366 5456 bzero(bp, sizeof (bp));
5367 5457
5368 5458 if ((error = prlock(pnp, ZNO)) != 0)
5369 5459 return (error);
5370 5460 p = pnp->pr_common->prc_proc;
5371 5461 fip = P_FINFO(p);
5372 5462 pslot = p->p_slot;
5373 5463 mutex_exit(&p->p_lock);
5374 5464
5375 5465 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5376 5466 as = NULL;
5377 5467 objdirsize = 0;
5378 5468 } else {
5379 5469 AS_LOCK_ENTER(as, RW_WRITER);
5380 5470 if (as->a_updatedir)
5381 5471 rebuild_objdir(as);
5382 5472 objdirsize = as->a_sizedir;
5383 5473 AS_LOCK_EXIT(as);
5384 5474 as = NULL;
5385 5475 }
5386 5476
5387 5477 mutex_enter(&fip->fi_lock);
5388 5478 if ((p->p_flag & SSYS) || p->p_as == &kas)
5389 5479 fddirsize = 0;
5390 5480 else
5391 5481 fddirsize = fip->fi_nfiles;
5392 5482
5393 5483 for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) {
5394 5484 /*
5395 5485 * There are 4 special files in the path directory: ".", "..",
5396 5486 * "root", and "cwd". We handle those specially here.
5397 5487 */
5398 5488 off = uiop->uio_offset;
5399 5489 idx = off / PRSDSIZE;
5400 5490 if (off == 0) { /* "." */
5401 5491 dirent->d_ino = pmkino(0, pslot, PR_PATHDIR);
5402 5492 dirent->d_name[0] = '.';
5403 5493 dirent->d_name[1] = '\0';
5404 5494 reclen = DIRENT64_RECLEN(1);
5405 5495 } else if (idx == 1) { /* ".." */
5406 5496 dirent->d_ino = pmkino(0, pslot, PR_PIDDIR);
5407 5497 dirent->d_name[0] = '.';
5408 5498 dirent->d_name[1] = '.';
5409 5499 dirent->d_name[2] = '\0';
5410 5500 reclen = DIRENT64_RECLEN(2);
5411 5501 } else if (idx == 2) { /* "root" */
5412 5502 dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5413 5503 (void) strcpy(dirent->d_name, "root");
5414 5504 reclen = DIRENT64_RECLEN(4);
5415 5505 } else if (idx == 3) { /* "cwd" */
5416 5506 dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5417 5507 (void) strcpy(dirent->d_name, "cwd");
5418 5508 reclen = DIRENT64_RECLEN(3);
5419 5509 } else if (idx < 4 + fddirsize) {
5420 5510 /*
5421 5511 * In this case, we have one of the file descriptors.
5422 5512 */
5423 5513 fd = idx - 4;
5424 5514 if (fip->fi_list[fd].uf_file == NULL)
5425 5515 continue;
5426 5516 dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5427 5517 (void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1);
5428 5518 reclen = DIRENT64_RECLEN(PLNSIZ);
5429 5519 } else if (idx < 4 + fddirsize + objdirsize) {
5430 5520 if (fip != NULL) {
5431 5521 mutex_exit(&fip->fi_lock);
5432 5522 fip = NULL;
5433 5523 }
5434 5524
5435 5525 /*
5436 5526 * We drop p_lock before grabbing the address space lock
5437 5527 * in order to avoid a deadlock with the clock thread.
5438 5528 * The process will not disappear and its address space
5439 5529 * will not change because it is marked P_PR_LOCK.
5440 5530 */
5441 5531 if (as == NULL) {
5442 5532 as = p->p_as;
5443 5533 AS_LOCK_ENTER(as, RW_WRITER);
5444 5534 }
5445 5535
5446 5536 if (as->a_updatedir) {
5447 5537 rebuild_objdir(as);
5448 5538 objdirsize = as->a_sizedir;
5449 5539 }
5450 5540
5451 5541 obj = idx - 4 - fddirsize;
5452 5542 if ((vp = obj_entry(as, obj)) == NULL)
5453 5543 continue;
5454 5544 vattr.va_mask = AT_FSID|AT_NODEID;
5455 5545 if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0)
5456 5546 continue;
5457 5547 if (vp == p->p_exec)
5458 5548 (void) strcpy(dirent->d_name, "a.out");
5459 5549 else
5460 5550 pr_object_name(dirent->d_name, vp, &vattr);
5461 5551 dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5462 5552 reclen = DIRENT64_RECLEN(strlen(dirent->d_name));
5463 5553 } else {
5464 5554 break;
5465 5555 }
5466 5556
5467 5557 dirent->d_off = uiop->uio_offset + PRSDSIZE;
5468 5558 dirent->d_reclen = (ushort_t)reclen;
5469 5559 if (reclen > uiop->uio_resid) {
5470 5560 /*
5471 5561 * Error if no entries have been returned yet.
5472 5562 */
5473 5563 if (uiop->uio_resid == oresid)
5474 5564 error = EINVAL;
5475 5565 break;
5476 5566 }
5477 5567 /*
5478 5568 * Drop the address space lock to do the uiomove().
5479 5569 */
5480 5570 if (as != NULL)
5481 5571 AS_LOCK_EXIT(as);
5482 5572
5483 5573 error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop);
5484 5574 if (as != NULL)
5485 5575 AS_LOCK_ENTER(as, RW_WRITER);
5486 5576
5487 5577 if (error)
5488 5578 break;
5489 5579 }
5490 5580
5491 5581 if (error == 0 && eofp)
5492 5582 *eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE);
5493 5583
5494 5584 if (fip != NULL)
5495 5585 mutex_exit(&fip->fi_lock);
5496 5586 if (as != NULL)
5497 5587 AS_LOCK_EXIT(as);
5498 5588 mutex_enter(&p->p_lock);
5499 5589 prunlock(pnp);
5500 5590 return (error);
5501 5591 }
5502 5592
5503 5593 static int
5504 5594 pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp)
5505 5595 {
5506 5596 proc_t *p;
5507 5597 int pslot, tslot;
5508 5598 gfs_readdir_state_t gstate;
5509 5599 int error, eof = 0;
5510 5600 offset_t n;
5511 5601
5512 5602 ASSERT(pnp->pr_type == PR_TMPLDIR);
5513 5603
5514 5604 if ((error = prlock(pnp, ZNO)) != 0)
5515 5605 return (error);
5516 5606 p = pnp->pr_common->prc_proc;
5517 5607 pslot = pnp->pr_common->prc_slot;
5518 5608 tslot = pnp->pr_common->prc_tslot;
5519 5609 mutex_exit(&p->p_lock);
5520 5610
5521 5611 if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5522 5612 pmkino(tslot, pslot, PR_LWPDIR),
5523 5613 pmkino(tslot, pslot, PR_TMPLDIR), 0)) != 0) {
5524 5614 mutex_enter(&p->p_lock);
5525 5615 prunlock(pnp);
5526 5616 return (error);
5527 5617 }
5528 5618
5529 5619 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5530 5620 /*
5531 5621 * Check for an active template. Reading a directory's
5532 5622 * contents is already racy, so we don't bother taking
5533 5623 * any locks.
5534 5624 */
5535 5625 while (n < ct_ntypes &&
5536 5626 pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[n] == NULL)
5537 5627 n++;
5538 5628 /*
5539 5629 * Stop when all types have been reported.
5540 5630 */
5541 5631 if (n >= ct_ntypes) {
5542 5632 eof = 1;
5543 5633 break;
5544 5634 }
5545 5635 /*
5546 5636 * The pmkino invocation below will need to be updated
5547 5637 * when we create our fifth contract type.
5548 5638 */
5549 5639 ASSERT(ct_ntypes <= 4);
5550 5640 error = gfs_readdir_emit(&gstate, uiop, n,
5551 5641 pmkino((tslot << 2) | n, pslot, PR_TMPL),
5552 5642 ct_types[n]->ct_type_name, 0);
5553 5643 if (error)
5554 5644 break;
5555 5645 }
5556 5646
5557 5647 mutex_enter(&p->p_lock);
5558 5648 prunlock(pnp);
5559 5649
5560 5650 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5561 5651 }
5562 5652
5563 5653 static int
5564 5654 pr_readdir_ctdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5565 5655 {
5566 5656 proc_t *p;
5567 5657 int pslot;
5568 5658 gfs_readdir_state_t gstate;
5569 5659 int error, eof = 0;
5570 5660 offset_t n;
5571 5661 uint64_t zid;
5572 5662
5573 5663 ASSERT(pnp->pr_type == PR_CTDIR);
5574 5664
5575 5665 if ((error = prlock(pnp, ZNO)) != 0)
5576 5666 return (error);
5577 5667 p = pnp->pr_common->prc_proc;
5578 5668 pslot = p->p_slot;
5579 5669 mutex_exit(&p->p_lock);
5580 5670
5581 5671 if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5582 5672 pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_CTDIR), 0)) != 0) {
5583 5673 mutex_enter(&p->p_lock);
5584 5674 prunlock(pnp);
5585 5675 return (error);
5586 5676 }
5587 5677
5588 5678 zid = VTOZONE(pnp->pr_vnode)->zone_uniqid;
5589 5679 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5590 5680 id_t next = contract_plookup(p, n, zid);
5591 5681 if (next == -1) {
5592 5682 eof = 1;
5593 5683 break;
5594 5684 }
5595 5685 error = gfs_readdir_emitn(&gstate, uiop, next,
5596 5686 pmkino(next, pslot, PR_CT), next);
5597 5687 if (error)
5598 5688 break;
5599 5689 }
5600 5690
5601 5691 mutex_enter(&p->p_lock);
5602 5692 prunlock(pnp);
5603 5693
5604 5694 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5605 5695 }
5606 5696
5607 5697 /* ARGSUSED */
5608 5698 static int
5609 5699 prfsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
5610 5700 {
5611 5701 return (0);
5612 5702 }
5613 5703
5614 5704 /*
5615 5705 * Utility: remove a /proc vnode from a linked list, threaded through pr_next.
5616 5706 */
5617 5707 static void
5618 5708 pr_list_unlink(vnode_t *pvp, vnode_t **listp)
5619 5709 {
5620 5710 vnode_t *vp;
5621 5711 prnode_t *pnp;
5622 5712
5623 5713 while ((vp = *listp) != NULL) {
5624 5714 pnp = VTOP(vp);
5625 5715 if (vp == pvp) {
5626 5716 *listp = pnp->pr_next;
5627 5717 pnp->pr_next = NULL;
5628 5718 break;
5629 5719 }
5630 5720 listp = &pnp->pr_next;
5631 5721 }
5632 5722 }
5633 5723
5634 5724 /* ARGSUSED */
5635 5725 static void
5636 5726 prinactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
5637 5727 {
5638 5728 prnode_t *pnp = VTOP(vp);
5639 5729 prnodetype_t type = pnp->pr_type;
5640 5730 proc_t *p;
5641 5731 vnode_t *dp;
5642 5732 vnode_t *ovp = NULL;
5643 5733 prnode_t *opnp = NULL;
5644 5734
5645 5735 switch (type) {
5646 5736 case PR_OBJECT:
5647 5737 case PR_FD:
5648 5738 case PR_SELF:
5649 5739 case PR_PATH:
5650 5740 /* These are not linked into the usual lists */
5651 5741 ASSERT(vp->v_count == 1);
5652 5742 if ((dp = pnp->pr_parent) != NULL)
5653 5743 VN_RELE(dp);
5654 5744 prfreenode(pnp);
5655 5745 return;
5656 5746 default:
5657 5747 break;
5658 5748 }
5659 5749
5660 5750 mutex_enter(&pr_pidlock);
5661 5751 if (pnp->pr_pcommon == NULL)
5662 5752 p = NULL;
5663 5753 else if ((p = pnp->pr_pcommon->prc_proc) != NULL)
5664 5754 mutex_enter(&p->p_lock);
5665 5755 mutex_enter(&vp->v_lock);
5666 5756
5667 5757 if (type == PR_PROCDIR || vp->v_count > 1) {
5668 5758 VN_RELE_LOCKED(vp);
5669 5759 mutex_exit(&vp->v_lock);
5670 5760 if (p != NULL)
5671 5761 mutex_exit(&p->p_lock);
5672 5762 mutex_exit(&pr_pidlock);
5673 5763 return;
5674 5764 }
5675 5765
5676 5766 if ((dp = pnp->pr_parent) != NULL) {
5677 5767 prnode_t *dpnp;
5678 5768
5679 5769 switch (type) {
5680 5770 case PR_PIDFILE:
5681 5771 case PR_LWPIDFILE:
5682 5772 case PR_OPAGEDATA:
5683 5773 break;
5684 5774 default:
5685 5775 dpnp = VTOP(dp);
5686 5776 mutex_enter(&dpnp->pr_mutex);
5687 5777 if (dpnp->pr_files != NULL &&
5688 5778 dpnp->pr_files[pnp->pr_index] == vp)
5689 5779 dpnp->pr_files[pnp->pr_index] = NULL;
5690 5780 mutex_exit(&dpnp->pr_mutex);
5691 5781 break;
5692 5782 }
5693 5783 pnp->pr_parent = NULL;
5694 5784 }
5695 5785
5696 5786 ASSERT(vp->v_count == 1);
5697 5787
5698 5788 /*
5699 5789 * If we allocated an old /proc/pid node, free it too.
5700 5790 */
5701 5791 if (pnp->pr_pidfile != NULL) {
5702 5792 ASSERT(type == PR_PIDDIR);
5703 5793 ovp = pnp->pr_pidfile;
5704 5794 opnp = VTOP(ovp);
5705 5795 ASSERT(opnp->pr_type == PR_PIDFILE);
5706 5796 pnp->pr_pidfile = NULL;
5707 5797 }
5708 5798
5709 5799 mutex_exit(&pr_pidlock);
5710 5800
5711 5801 if (p != NULL) {
5712 5802 /*
5713 5803 * Remove the vnodes from the lists of
5714 5804 * /proc vnodes for the process.
5715 5805 */
5716 5806 int slot;
5717 5807
5718 5808 switch (type) {
5719 5809 case PR_PIDDIR:
5720 5810 pr_list_unlink(vp, &p->p_trace);
5721 5811 break;
5722 5812 case PR_LWPIDDIR:
5723 5813 if ((slot = pnp->pr_common->prc_tslot) != -1) {
5724 5814 lwpent_t *lep = p->p_lwpdir[slot].ld_entry;
5725 5815 pr_list_unlink(vp, &lep->le_trace);
5726 5816 }
5727 5817 break;
5728 5818 default:
5729 5819 pr_list_unlink(vp, &p->p_plist);
5730 5820 break;
5731 5821 }
5732 5822 if (ovp != NULL)
5733 5823 pr_list_unlink(ovp, &p->p_plist);
5734 5824 mutex_exit(&p->p_lock);
5735 5825 }
5736 5826
5737 5827 mutex_exit(&vp->v_lock);
5738 5828
5739 5829 if (type == PR_CT && pnp->pr_contract != NULL) {
5740 5830 contract_rele(pnp->pr_contract);
5741 5831 pnp->pr_contract = NULL;
5742 5832 }
5743 5833
5744 5834 if (opnp != NULL)
5745 5835 prfreenode(opnp);
5746 5836 prfreenode(pnp);
5747 5837 if (dp != NULL) {
5748 5838 VN_RELE(dp);
5749 5839 }
5750 5840 }
5751 5841
5752 5842 /* ARGSUSED */
5753 5843 static int
5754 5844 prseek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
5755 5845 {
5756 5846 return (0);
5757 5847 }
5758 5848
5759 5849 /*
5760 5850 * We use the p_execdir member of proc_t to expand the %d token in core file
5761 5851 * paths (the directory path for the executable that dumped core; see
5762 5852 * coreadm(1M) for details). We'd like gcore(1) to be able to expand %d in
5763 5853 * the same way as core dumping from the kernel, but there's no convenient
5764 5854 * and comprehensible way to export the path name for p_execdir. To solve
5765 5855 * this, we try to find the actual path to the executable that was used. In
5766 5856 * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT
5767 5857 * flag, and use that here to indicate that more work is needed beyond the
5768 5858 * call to vnodetopath().
5769 5859 */
5770 5860 static int
5771 5861 prreadlink_lookup(prnode_t *pnp, char *buf, size_t size, cred_t *cr)
5772 5862 {
5773 5863 proc_t *p;
5774 5864 vnode_t *vp, *execvp, *vrootp;
5775 5865 int ret;
5776 5866 size_t len;
5777 5867 dirent64_t *dp;
5778 5868 size_t dlen = DIRENT64_RECLEN(MAXPATHLEN);
5779 5869 char *dbuf;
5780 5870
5781 5871 p = curproc;
5782 5872 mutex_enter(&p->p_lock);
5783 5873 if ((vrootp = PTOU(p)->u_rdir) == NULL)
5784 5874 vrootp = rootdir;
5785 5875 VN_HOLD(vrootp);
5786 5876 mutex_exit(&p->p_lock);
5787 5877
5788 5878 ret = vnodetopath(vrootp, pnp->pr_realvp, buf, size, cr);
5789 5879
5790 5880 /*
5791 5881 * If PR_AOUT isn't set, then we looked up the path for the vnode;
5792 5882 * otherwise, we looked up the path for (what we believe to be) the
5793 5883 * containing directory.
5794 5884 */
5795 5885 if ((pnp->pr_flags & PR_AOUT) == 0) {
5796 5886 VN_RELE(vrootp);
5797 5887 return (ret);
5798 5888 }
5799 5889
5800 5890 /*
5801 5891 * Fail if there's a problem locking the process. This will only
5802 5892 * occur if the process is changing so the information we would
5803 5893 * report would already be invalid.
5804 5894 */
5805 5895 if (prlock(pnp, ZNO) != 0) {
5806 5896 VN_RELE(vrootp);
5807 5897 return (EIO);
5808 5898 }
5809 5899
5810 5900 p = pnp->pr_common->prc_proc;
5811 5901 mutex_exit(&p->p_lock);
5812 5902
5813 5903 execvp = p->p_exec;
5814 5904 VN_HOLD(execvp);
5815 5905
5816 5906 /*
5817 5907 * If our initial lookup of the directory failed, fall back to
5818 5908 * the path name information for p_exec.
5819 5909 */
5820 5910 if (ret != 0) {
5821 5911 mutex_enter(&p->p_lock);
5822 5912 prunlock(pnp);
5823 5913 ret = vnodetopath(vrootp, execvp, buf, size, cr);
5824 5914 VN_RELE(execvp);
5825 5915 VN_RELE(vrootp);
5826 5916 return (ret);
5827 5917 }
5828 5918
5829 5919 len = strlen(buf);
5830 5920
5831 5921 /*
5832 5922 * We use u_comm as a guess for the last component of the full
5833 5923 * executable path name. If there isn't going to be enough space
5834 5924 * we fall back to using the p_exec so that we can have _an_
5835 5925 * answer even if it's not perfect.
5836 5926 */
5837 5927 if (strlen(PTOU(p)->u_comm) + len + 1 < size) {
5838 5928 buf[len] = '/';
5839 5929 (void) strcpy(buf + len + 1, PTOU(p)->u_comm);
5840 5930 mutex_enter(&p->p_lock);
5841 5931 prunlock(pnp);
5842 5932
5843 5933 /*
5844 5934 * Do a forward lookup of our u_comm guess.
5845 5935 */
5846 5936 if (lookupnameat(buf + len + 1, UIO_SYSSPACE, FOLLOW, NULLVPP,
5847 5937 &vp, pnp->pr_realvp) == 0) {
5848 5938 if (vn_compare(vp, execvp)) {
5849 5939 VN_RELE(vp);
5850 5940 VN_RELE(execvp);
5851 5941 VN_RELE(vrootp);
5852 5942 return (0);
5853 5943 }
5854 5944
5855 5945 VN_RELE(vp);
5856 5946 }
5857 5947 } else {
5858 5948 mutex_enter(&p->p_lock);
5859 5949 prunlock(pnp);
5860 5950 }
5861 5951
5862 5952 dbuf = kmem_alloc(dlen, KM_SLEEP);
5863 5953
5864 5954 /*
5865 5955 * Try to find a matching vnode by iterating through the directory's
5866 5956 * entries. If that fails, fall back to the path information for
5867 5957 * p_exec.
5868 5958 */
5869 5959 if ((ret = dirfindvp(vrootp, pnp->pr_realvp, execvp, cr, dbuf,
5870 5960 dlen, &dp)) == 0 && strlen(dp->d_name) + len + 1 < size) {
5871 5961 buf[len] = '/';
5872 5962 (void) strcpy(buf + len + 1, dp->d_name);
5873 5963 } else {
5874 5964 ret = vnodetopath(vrootp, execvp, buf, size, cr);
5875 5965 }
5876 5966
5877 5967 kmem_free(dbuf, dlen);
5878 5968 VN_RELE(execvp);
5879 5969 VN_RELE(vrootp);
5880 5970
5881 5971 return (ret);
5882 5972 }
5883 5973
5884 5974 /* ARGSUSED */
5885 5975 static int
5886 5976 prreadlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ctp)
5887 5977 {
5888 5978 prnode_t *pnp = VTOP(vp);
5889 5979 char *buf;
5890 5980 int ret = EINVAL;
5891 5981 char idbuf[16];
5892 5982 int length, rlength;
5893 5983 contract_t *ct;
5894 5984
5895 5985 switch (pnp->pr_type) {
5896 5986 case PR_SELF:
5897 5987 (void) snprintf(idbuf, sizeof (idbuf), "%d", curproc->p_pid);
5898 5988 ret = uiomove(idbuf, strlen(idbuf), UIO_READ, uiop);
5899 5989 break;
5900 5990 case PR_OBJECT:
5901 5991 case PR_FD:
5902 5992 case PR_CURDIR:
5903 5993 case PR_ROOTDIR:
5904 5994 if (pnp->pr_realvp->v_type == VDIR)
5905 5995 ret = 0;
5906 5996 break;
5907 5997 case PR_PATH:
5908 5998 buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
5909 5999
5910 6000 if ((ret = prreadlink_lookup(pnp, buf, MAXPATHLEN, cr)) == 0)
5911 6001 ret = uiomove(buf, strlen(buf), UIO_READ, uiop);
5912 6002
5913 6003 kmem_free(buf, MAXPATHLEN);
5914 6004 break;
5915 6005 case PR_CT:
5916 6006 ASSERT(pnp->pr_contract != NULL);
5917 6007 ct = pnp->pr_contract;
5918 6008 length = sizeof (CTFS_ROOT "//") + sizeof (idbuf) +
5919 6009 strlen(ct->ct_type->ct_type_name);
5920 6010 buf = kmem_alloc(length, KM_SLEEP);
5921 6011 rlength = snprintf(buf, length, CTFS_ROOT "/%s/%d",
5922 6012 ct->ct_type->ct_type_name, ct->ct_id);
5923 6013 ASSERT(rlength < length);
5924 6014 ret = uiomove(buf, rlength, UIO_READ, uiop);
5925 6015 kmem_free(buf, length);
5926 6016 break;
5927 6017 default:
5928 6018 break;
5929 6019 }
5930 6020
5931 6021 return (ret);
5932 6022 }
5933 6023
5934 6024 /*ARGSUSED2*/
5935 6025 static int
5936 6026 prcmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct)
5937 6027 {
5938 6028 prnode_t *pp1, *pp2;
5939 6029
5940 6030 if (vp1 == vp2)
5941 6031 return (1);
5942 6032
5943 6033 if (!vn_matchops(vp1, prvnodeops) || !vn_matchops(vp2, prvnodeops))
5944 6034 return (0);
5945 6035
5946 6036 pp1 = VTOP(vp1);
5947 6037 pp2 = VTOP(vp2);
5948 6038
5949 6039 if (pp1->pr_type != pp2->pr_type)
5950 6040 return (0);
5951 6041 if (pp1->pr_type == PR_PROCDIR)
5952 6042 return (1);
5953 6043 if (pp1->pr_ino || pp2->pr_ino)
5954 6044 return (pp2->pr_ino == pp1->pr_ino);
5955 6045
5956 6046 if (pp1->pr_common == NULL || pp2->pr_common == NULL)
5957 6047 return (0);
5958 6048
5959 6049 return (pp1->pr_common->prc_slot == pp2->pr_common->prc_slot &&
5960 6050 pp1->pr_common->prc_tslot == pp2->pr_common->prc_tslot);
5961 6051 }
5962 6052
5963 6053 static int
5964 6054 prrealvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
5965 6055 {
5966 6056 vnode_t *rvp;
5967 6057
5968 6058 if ((rvp = VTOP(vp)->pr_realvp) != NULL) {
5969 6059 vp = rvp;
5970 6060 if (VOP_REALVP(vp, &rvp, ct) == 0)
5971 6061 vp = rvp;
5972 6062 }
5973 6063
5974 6064 *vpp = vp;
5975 6065 return (0);
5976 6066 }
5977 6067
5978 6068 /*
5979 6069 * Return the answer requested to poll().
5980 6070 * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
5981 6071 * In addition, these have special meaning for /proc files:
5982 6072 * POLLPRI process or lwp stopped on an event of interest
5983 6073 * POLLERR /proc file descriptor is invalid
5984 6074 * POLLHUP process or lwp has terminated
5985 6075 */
5986 6076 /*ARGSUSED5*/
5987 6077 static int
5988 6078 prpoll(vnode_t *vp, short events, int anyyet, short *reventsp,
5989 6079 pollhead_t **phpp, caller_context_t *ct)
5990 6080 {
5991 6081 prnode_t *pnp = VTOP(vp);
5992 6082 prcommon_t *pcp = pnp->pr_common;
5993 6083 pollhead_t *php = &pcp->prc_pollhead;
5994 6084 proc_t *p;
5995 6085 short revents;
5996 6086 int error;
5997 6087 int lockstate;
5998 6088
5999 6089 ASSERT(pnp->pr_type < PR_NFILES);
6000 6090
6001 6091 /*
6002 6092 * Support for old /proc interface.
6003 6093 */
6004 6094 if (pnp->pr_pidfile != NULL) {
6005 6095 vp = pnp->pr_pidfile;
6006 6096 pnp = VTOP(vp);
6007 6097 ASSERT(pnp->pr_type == PR_PIDFILE);
6008 6098 ASSERT(pnp->pr_common == pcp);
6009 6099 }
6010 6100
6011 6101 *reventsp = revents = 0;
6012 6102 *phpp = (pollhead_t *)NULL;
6013 6103
6014 6104 if (vp->v_type == VDIR) {
6015 6105 *reventsp |= POLLNVAL;
6016 6106 return (0);
6017 6107 }
6018 6108
6019 6109 /* avoid deadlock with prnotify() */
6020 6110 if (pollunlock(&lockstate) != 0) {
6021 6111 *reventsp = POLLNVAL;
6022 6112 return (0);
6023 6113 }
6024 6114
6025 6115 if ((error = prlock(pnp, ZNO)) != 0) {
6026 6116 pollrelock(lockstate);
6027 6117 switch (error) {
6028 6118 case ENOENT: /* process or lwp died */
6029 6119 *reventsp = POLLHUP;
6030 6120 error = 0;
6031 6121 break;
6032 6122 case EAGAIN: /* invalidated */
6033 6123 *reventsp = POLLERR;
6034 6124 error = 0;
6035 6125 break;
6036 6126 }
6037 6127 return (error);
6038 6128 }
6039 6129
6040 6130 /*
6041 6131 * We have the process marked locked (P_PR_LOCK) and we are holding
6042 6132 * its p->p_lock. We want to unmark the process but retain
6043 6133 * exclusive control w.r.t. other /proc controlling processes
6044 6134 * before reacquiring the polling locks.
6045 6135 *
6046 6136 * prunmark() does this for us. It unmarks the process
6047 6137 * but retains p->p_lock so we still have exclusive control.
6048 6138 * We will drop p->p_lock at the end to relinquish control.
6049 6139 *
6050 6140 * We cannot call prunlock() at the end to relinquish control
6051 6141 * because prunlock(), like prunmark(), may drop and reacquire
6052 6142 * p->p_lock and that would lead to a lock order violation
6053 6143 * w.r.t. the polling locks we are about to reacquire.
6054 6144 */
6055 6145 p = pcp->prc_proc;
6056 6146 ASSERT(p != NULL);
6057 6147 prunmark(p);
6058 6148
6059 6149 pollrelock(lockstate); /* reacquire dropped poll locks */
6060 6150
6061 6151 if ((p->p_flag & SSYS) || p->p_as == &kas)
6062 6152 revents = POLLNVAL;
6063 6153 else {
6064 6154 short ev;
6065 6155
6066 6156 if ((ev = (events & (POLLIN|POLLRDNORM))) != 0)
6067 6157 revents |= ev;
6068 6158 /*
6069 6159 * POLLWRNORM (same as POLLOUT) really should not be
6070 6160 * used to indicate that the process or lwp stopped.
6071 6161 * However, USL chose to use POLLWRNORM rather than
6072 6162 * POLLPRI to indicate this, so we just accept either
6073 6163 * requested event to indicate stopped. (grr...)
6074 6164 */
6075 6165 if ((ev = (events & (POLLPRI|POLLOUT|POLLWRNORM))) != 0) {
6076 6166 kthread_t *t;
6077 6167
6078 6168 if (pcp->prc_flags & PRC_LWP) {
6079 6169 t = pcp->prc_thread;
6080 6170 ASSERT(t != NULL);
6081 6171 thread_lock(t);
6082 6172 } else {
6083 6173 t = prchoose(p); /* returns locked t */
6084 6174 ASSERT(t != NULL);
6085 6175 }
6086 6176
6087 6177 if (ISTOPPED(t) || VSTOPPED(t))
6088 6178 revents |= ev;
6089 6179 thread_unlock(t);
6090 6180 }
6091 6181 }
6092 6182
6093 6183 *reventsp = revents;
6094 6184 if ((!anyyet && revents == 0) || (events & POLLET)) {
6095 6185 /*
6096 6186 * Arrange to wake up the polling lwp when
6097 6187 * the target process/lwp stops or terminates
6098 6188 * or when the file descriptor becomes invalid.
6099 6189 */
6100 6190 pcp->prc_flags |= PRC_POLL;
6101 6191 *phpp = php;
6102 6192 }
6103 6193 mutex_exit(&p->p_lock);
6104 6194 return (0);
6105 6195 }
6106 6196
6107 6197 /* in prioctl.c */
6108 6198 extern int prioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
6109 6199 caller_context_t *);
6110 6200
6111 6201 /*
6112 6202 * /proc vnode operations vector
6113 6203 */
6114 6204 const fs_operation_def_t pr_vnodeops_template[] = {
6115 6205 VOPNAME_OPEN, { .vop_open = propen },
6116 6206 VOPNAME_CLOSE, { .vop_close = prclose },
6117 6207 VOPNAME_READ, { .vop_read = prread },
6118 6208 VOPNAME_WRITE, { .vop_write = prwrite },
6119 6209 VOPNAME_IOCTL, { .vop_ioctl = prioctl },
6120 6210 VOPNAME_GETATTR, { .vop_getattr = prgetattr },
6121 6211 VOPNAME_ACCESS, { .vop_access = praccess },
6122 6212 VOPNAME_LOOKUP, { .vop_lookup = prlookup },
6123 6213 VOPNAME_CREATE, { .vop_create = prcreate },
6124 6214 VOPNAME_READDIR, { .vop_readdir = prreaddir },
6125 6215 VOPNAME_READLINK, { .vop_readlink = prreadlink },
6126 6216 VOPNAME_FSYNC, { .vop_fsync = prfsync },
6127 6217 VOPNAME_INACTIVE, { .vop_inactive = prinactive },
6128 6218 VOPNAME_SEEK, { .vop_seek = prseek },
6129 6219 VOPNAME_CMP, { .vop_cmp = prcmp },
6130 6220 VOPNAME_FRLOCK, { .error = fs_error },
6131 6221 VOPNAME_REALVP, { .vop_realvp = prrealvp },
6132 6222 VOPNAME_POLL, { .vop_poll = prpoll },
6133 6223 VOPNAME_DISPOSE, { .error = fs_error },
6134 6224 VOPNAME_SHRLOCK, { .error = fs_error },
6135 6225 NULL, NULL
6136 6226 };
↓ open down ↓ |
1379 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX