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