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.
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.
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]
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2017, Joyent, Inc.
25 * Copyright (c) 2017 by Delphix. All rights reserved.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
31 #include <sys/types.h>
32 #include <sys/param.h>
35 #include <sys/policy.h>
36 #include <sys/debug.h>
37 #include <sys/dirent.h>
38 #include <sys/errno.h>
40 #include <sys/inline.h>
42 #include <sys/pathname.h>
44 #include <sys/brand.h>
45 #include <sys/signal.h>
47 #include <sys/sysmacros.h>
48 #include <sys/systm.h>
57 #include <sys/vnode.h>
58 #include <sys/fault.h>
59 #include <sys/syscall.h>
60 #include <sys/procfs.h>
61 #include <sys/atomic.h>
62 #include <sys/cmn_err.h>
63 #include <sys/contract_impl.h>
66 #include <sys/fs_subr.h>
70 #include <vm/seg_vn.h>
72 #include <sys/proc/prdata.h>
74 #include <sys/sysi86.h>
78 * Directory characteristics (patterned after the s5 file system).
85 char d_name
[PRDIRSIZE
];
88 #define PRSDSIZE (sizeof (struct prdirect))
91 * Directory characteristics.
93 typedef struct prdirent
{
94 ino64_t d_ino
; /* "inode number" of entry */
95 off64_t d_off
; /* offset of disk directory entry */
96 unsigned short d_reclen
; /* length of this record */
97 char d_name
[14]; /* name of file */
101 * Contents of a /proc/<pid> directory.
102 * Reuse d_ino field for the /proc file type.
104 static prdirent_t piddir
[] = {
105 { PR_PIDDIR
, 1 * sizeof (prdirent_t
), sizeof (prdirent_t
),
107 { PR_PROCDIR
, 2 * sizeof (prdirent_t
), sizeof (prdirent_t
),
109 { PR_AS
, 3 * sizeof (prdirent_t
), sizeof (prdirent_t
),
111 { PR_CTL
, 4 * sizeof (prdirent_t
), sizeof (prdirent_t
),
113 { PR_STATUS
, 5 * sizeof (prdirent_t
), sizeof (prdirent_t
),
115 { PR_LSTATUS
, 6 * sizeof (prdirent_t
), sizeof (prdirent_t
),
117 { PR_PSINFO
, 7 * sizeof (prdirent_t
), sizeof (prdirent_t
),
119 { PR_LPSINFO
, 8 * sizeof (prdirent_t
), sizeof (prdirent_t
),
121 { PR_MAP
, 9 * sizeof (prdirent_t
), sizeof (prdirent_t
),
123 { PR_RMAP
, 10 * sizeof (prdirent_t
), sizeof (prdirent_t
),
125 { PR_XMAP
, 11 * sizeof (prdirent_t
), sizeof (prdirent_t
),
127 { PR_CRED
, 12 * sizeof (prdirent_t
), sizeof (prdirent_t
),
129 { PR_SIGACT
, 13 * sizeof (prdirent_t
), sizeof (prdirent_t
),
131 { PR_AUXV
, 14 * sizeof (prdirent_t
), sizeof (prdirent_t
),
133 { PR_USAGE
, 15 * sizeof (prdirent_t
), sizeof (prdirent_t
),
135 { PR_LUSAGE
, 16 * sizeof (prdirent_t
), sizeof (prdirent_t
),
137 { PR_PAGEDATA
, 17 * sizeof (prdirent_t
), sizeof (prdirent_t
),
139 { PR_WATCH
, 18 * sizeof (prdirent_t
), sizeof (prdirent_t
),
141 { PR_CURDIR
, 19 * sizeof (prdirent_t
), sizeof (prdirent_t
),
143 { PR_ROOTDIR
, 20 * sizeof (prdirent_t
), sizeof (prdirent_t
),
145 { PR_FDDIR
, 21 * sizeof (prdirent_t
), sizeof (prdirent_t
),
147 { PR_OBJECTDIR
, 22 * sizeof (prdirent_t
), sizeof (prdirent_t
),
149 { PR_LWPDIR
, 23 * sizeof (prdirent_t
), sizeof (prdirent_t
),
151 { PR_PRIV
, 24 * sizeof (prdirent_t
), sizeof (prdirent_t
),
153 { PR_PATHDIR
, 25 * sizeof (prdirent_t
), sizeof (prdirent_t
),
155 { PR_CTDIR
, 26 * sizeof (prdirent_t
), sizeof (prdirent_t
),
157 { PR_SECFLAGS
, 27 * sizeof (prdirent_t
), sizeof (prdirent_t
),
160 { PR_LDT
, 28 * sizeof (prdirent_t
), sizeof (prdirent_t
),
165 #define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2)
168 * Contents of a /proc/<pid>/lwp/<lwpid> directory.
170 static prdirent_t lwpiddir
[] = {
171 { PR_LWPIDDIR
, 1 * sizeof (prdirent_t
), sizeof (prdirent_t
),
173 { PR_LWPDIR
, 2 * sizeof (prdirent_t
), sizeof (prdirent_t
),
175 { PR_LWPCTL
, 3 * sizeof (prdirent_t
), sizeof (prdirent_t
),
177 { PR_LWPSTATUS
, 4 * sizeof (prdirent_t
), sizeof (prdirent_t
),
179 { PR_LWPSINFO
, 5 * sizeof (prdirent_t
), sizeof (prdirent_t
),
181 { PR_LWPUSAGE
, 6 * sizeof (prdirent_t
), sizeof (prdirent_t
),
183 { PR_XREGS
, 7 * sizeof (prdirent_t
), sizeof (prdirent_t
),
185 { PR_TMPLDIR
, 8 * sizeof (prdirent_t
), sizeof (prdirent_t
),
187 { PR_SPYMASTER
, 9 * sizeof (prdirent_t
), sizeof (prdirent_t
),
191 #define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
194 * Span of entries in the array files (lstatus, lpsinfo, lusage).
195 * We make the span larger than the size of the structure on purpose,
196 * to make sure that programs cannot use the structure size by mistake.
197 * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
200 #define LSPAN(type) (round16(sizeof (type)) + 16)
201 #define LSPAN32(type) (round8(sizeof (type)) + 8)
203 #define LSPAN(type) (round8(sizeof (type)) + 8)
206 static void rebuild_objdir(struct as
*);
207 static void prfreecommon(prcommon_t
*);
208 static int praccess(vnode_t
*, int, int, cred_t
*, caller_context_t
*);
211 propen(vnode_t
**vpp
, int flag
, cred_t
*cr
, caller_context_t
*ct
)
214 prnode_t
*pnp
= VTOP(vp
);
215 prcommon_t
*pcp
= pnp
->pr_pcommon
;
216 prnodetype_t type
= pnp
->pr_type
;
221 prnode_t
*npnp
= NULL
;
224 * Nothing to do for the /proc directory itself.
226 if (type
== PR_PROCDIR
)
230 * If we are opening an underlying mapped object, reject opens
231 * for writing regardless of the objects's access modes.
232 * If we are opening a file in the /proc/pid/fd directory,
233 * reject the open for any but a regular file or directory.
234 * Just do it if we are opening the current or root directory.
241 rvp
= pnp
->pr_realvp
;
243 if ((type
== PR_OBJECT
&& (flag
& FWRITE
)) ||
244 (type
== PR_FD
&& vtype
!= VREG
&& vtype
!= VDIR
))
248 * Need to hold rvp since fop_open() may release it.
251 error
= fop_open(&rvp
, flag
, cr
, ct
);
265 * If we are opening the pagedata file, allocate a prnode now
266 * to avoid calling kmem_alloc() while holding p->p_lock.
268 if (type
== PR_PAGEDATA
|| type
== PR_OPAGEDATA
)
269 npnp
= prgetnode(vp
, type
);
272 * If the process exists, lock it now.
273 * Otherwise we have a race condition with prclose().
276 mutex_exit(&pr_pidlock
);
282 ASSERT(p
== pcp
->prc_proc
);
283 ASSERT(p
->p_proc_flag
& P_PR_LOCK
);
286 * Maintain a count of opens for write. Allow exactly one
287 * O_WRITE|O_EXCL request and fail subsequent ones.
288 * Don't fail opens of old (bletch!) /proc lwp files.
289 * Special case for open by the process itself:
290 * Always allow the open by self and discount this
291 * open for other opens for writing.
295 pcp
->prc_selfopens
++;
296 pnp
->pr_flags
|= PR_ISSELF
;
297 } else if (type
== PR_LWPIDFILE
) {
299 } else if (flag
& FEXCL
) {
300 if (pcp
->prc_writers
> pcp
->prc_selfopens
) {
304 /* semantic for old /proc interface */
305 if (type
== PR_PIDDIR
)
306 pcp
->prc_flags
|= PRC_EXCL
;
307 } else if (pcp
->prc_flags
& PRC_EXCL
) {
308 ASSERT(pcp
->prc_writers
> pcp
->prc_selfopens
);
309 error
= secpolicy_proc_excl_open(cr
);
315 * The vnode may have become invalid between the
316 * fop_lookup() of the /proc vnode and the fop_open().
317 * If so, do now what prinvalidate() should have done.
319 if ((pnp
->pr_flags
& PR_INVAL
) ||
320 (type
== PR_PIDDIR
&&
321 (VTOP(pnp
->pr_pidfile
)->pr_flags
& PR_INVAL
))) {
323 pcp
->prc_selfopens
++;
324 ASSERT(pcp
->prc_selfopens
<= pcp
->prc_writers
);
325 if (pcp
->prc_selfopens
== pcp
->prc_writers
)
326 pcp
->prc_flags
&= ~PRC_EXCL
;
331 * If this is a large file open, indicate that in our flags -- some
332 * procfs structures are not off_t-neutral (e.g., priovec_t), and
333 * the open will need to be differentiated where 32-bit processes
334 * pass these structures across the user/kernel boundary.
337 pnp
->pr_flags
|= PR_OFFMAX
;
340 * Do file-specific things.
348 * Enable data collection for page data file;
349 * get unique id from the hat layer.
355 * Drop p->p_lock to call hat_startstat()
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
);
362 } else if (pnp
->pr_hatid
== 0) {
363 mutex_enter(&p
->p_lock
);
364 pnp
->pr_hatid
= (uint_t
)id
;
366 mutex_enter(&p
->p_lock
);
368 * Use our newly allocated prnode.
370 npnp
->pr_hatid
= (uint_t
)id
;
372 * prgetnode() initialized most of the prnode.
373 * Duplicate the remainder.
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
;
382 npnp
->pr_next
= p
->p_plist
;
383 p
->p_plist
= PTOV(npnp
);
404 prclose(vnode_t
*vp
, int flag
, int count
, offset_t offset
, cred_t
*cr
,
405 caller_context_t
*ct
)
407 prnode_t
*pnp
= VTOP(vp
);
408 prcommon_t
*pcp
= pnp
->pr_pcommon
;
409 prnodetype_t type
= pnp
->pr_type
;
415 * Nothing to do for the /proc directory itself.
417 if (type
== PR_PROCDIR
)
420 ASSERT(type
!= PR_OBJECT
&& type
!= PR_FD
&&
421 type
!= PR_CURDIR
&& type
!= PR_ROOTDIR
);
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().
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).
440 mutex_exit(&pr_pidlock
);
441 if (pnp
->pr_owner
== curproc
&& !fisopen(vp
))
442 pnp
->pr_owner
= NULL
;
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.
457 * prc_selfopens also contains the count of
458 * invalid writers. See prinvalidate().
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
;
466 ASSERT(pcp
->prc_writers
!= 0);
467 if (--pcp
->prc_writers
== pcp
->prc_selfopens
)
468 pcp
->prc_flags
&= ~PRC_EXCL
;
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
;
476 * If there is no process, there is nothing more to do.
481 ASSERT(p
== pcp
->prc_proc
);
482 prnotify(vp
); /* notify waiters */
485 * Do file-specific things.
493 * This is a page data file.
494 * Free the hat level statistics.
495 * Drop p->p_lock before calling hat_freestat().
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
);
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.
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
))) {
518 * Cancel any watchpoints currently in effect.
519 * The process might disappear during this operation.
521 if (pr_cancel_watch(pnp
) == NULL
)
524 * If any tracing flags are set, clear them.
526 if (p
->p_proc_flag
& P_PR_TRACE
) {
528 premptyset(&up
->u_entrymask
);
529 premptyset(&up
->u_exitmask
);
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
);
537 * Cancel any outstanding single-step requests.
539 if ((t
= p
->p_tlist
) != NULL
) {
541 * Drop p_lock because prnostep() touches the stack.
542 * The loop is safe because the process is P_PR_LOCK'd.
544 mutex_exit(&p
->p_lock
);
547 } while ((t
= t
->t_forw
) != p
->p_tlist
);
548 mutex_enter(&p
->p_lock
);
551 * Set runnable all lwps stopped by /proc.
554 sigtoproc(p
, NULL
, SIGKILL
);
564 * Array of read functions, indexed by /proc file type.
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(),
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 pr_read_spymaster(), pr_read_secflags(),
577 pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
579 static int (*pr_read_function
[PR_NFILES
])() = {
580 pr_read_inval
, /* /proc */
581 pr_read_inval
, /* /proc/self */
582 pr_read_piddir
, /* /proc/<pid> (old /proc read()) */
583 pr_read_as
, /* /proc/<pid>/as */
584 pr_read_inval
, /* /proc/<pid>/ctl */
585 pr_read_status
, /* /proc/<pid>/status */
586 pr_read_lstatus
, /* /proc/<pid>/lstatus */
587 pr_read_psinfo
, /* /proc/<pid>/psinfo */
588 pr_read_lpsinfo
, /* /proc/<pid>/lpsinfo */
589 pr_read_map
, /* /proc/<pid>/map */
590 pr_read_rmap
, /* /proc/<pid>/rmap */
591 pr_read_xmap
, /* /proc/<pid>/xmap */
592 pr_read_cred
, /* /proc/<pid>/cred */
593 pr_read_sigact
, /* /proc/<pid>/sigact */
594 pr_read_auxv
, /* /proc/<pid>/auxv */
596 pr_read_ldt
, /* /proc/<pid>/ldt */
598 pr_read_usage
, /* /proc/<pid>/usage */
599 pr_read_lusage
, /* /proc/<pid>/lusage */
600 pr_read_pagedata
, /* /proc/<pid>/pagedata */
601 pr_read_watch
, /* /proc/<pid>/watch */
602 pr_read_inval
, /* /proc/<pid>/cwd */
603 pr_read_inval
, /* /proc/<pid>/root */
604 pr_read_inval
, /* /proc/<pid>/fd */
605 pr_read_inval
, /* /proc/<pid>/fd/nn */
606 pr_read_inval
, /* /proc/<pid>/object */
607 pr_read_inval
, /* /proc/<pid>/object/xxx */
608 pr_read_inval
, /* /proc/<pid>/lwp */
609 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid> */
610 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
611 pr_read_lwpstatus
, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
612 pr_read_lwpsinfo
, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
613 pr_read_lwpusage
, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
614 pr_read_xregs
, /* /proc/<pid>/lwp/<lwpid>/xregs */
615 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/templates */
616 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
617 pr_read_spymaster
, /* /proc/<pid>/lwp/<lwpid>/spymaster */
618 pr_read_priv
, /* /proc/<pid>/priv */
619 pr_read_inval
, /* /proc/<pid>/path */
620 pr_read_inval
, /* /proc/<pid>/path/xxx */
621 pr_read_inval
, /* /proc/<pid>/contracts */
622 pr_read_inval
, /* /proc/<pid>/contracts/<ctid> */
623 pr_read_secflags
, /* /proc/<pid>/secflags */
624 pr_read_pidfile
, /* old process file */
625 pr_read_pidfile
, /* old lwp file */
626 pr_read_opagedata
, /* old pagedata file */
631 pr_read_inval(prnode_t
*pnp
, uio_t
*uiop
)
634 * No read() on any /proc directory, use getdents(2) instead.
635 * Cannot read a control file either.
636 * An underlying mapped object file cannot get here.
642 pr_uioread(void *base
, long count
, uio_t
*uiop
)
647 count
-= uiop
->uio_offset
;
648 if (count
> 0 && uiop
->uio_offset
>= 0) {
649 error
= uiomove((char *)base
+ uiop
->uio_offset
,
650 count
, UIO_READ
, uiop
);
657 pr_read_as(prnode_t
*pnp
, uio_t
*uiop
)
661 ASSERT(pnp
->pr_type
== PR_AS
);
663 if ((error
= prlock(pnp
, ZNO
)) == 0) {
664 proc_t
*p
= pnp
->pr_common
->prc_proc
;
665 struct as
*as
= p
->p_as
;
668 * /proc I/O cannot be done to a system process.
669 * A 32-bit process cannot read a 64-bit process.
671 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
673 #ifdef _SYSCALL32_IMPL
674 } else if (curproc
->p_model
== DATAMODEL_ILP32
&&
675 PROCESS_NOT_32BIT(p
)) {
680 * We don't hold p_lock over an i/o operation because
681 * that could lead to deadlock with the clock thread.
683 mutex_exit(&p
->p_lock
);
684 error
= prusrio(p
, UIO_READ
, uiop
, 0);
685 mutex_enter(&p
->p_lock
);
694 pr_read_status(prnode_t
*pnp
, uio_t
*uiop
)
699 ASSERT(pnp
->pr_type
== PR_STATUS
);
702 * We kmem_alloc() the pstatus structure because
703 * it is so big it might blow the kernel stack.
705 sp
= kmem_alloc(sizeof (*sp
), KM_SLEEP
);
706 if ((error
= prlock(pnp
, ZNO
)) == 0) {
707 prgetstatus(pnp
->pr_common
->prc_proc
, sp
, VTOZONE(PTOV(pnp
)));
709 error
= pr_uioread(sp
, sizeof (*sp
), uiop
);
711 kmem_free(sp
, sizeof (*sp
));
716 pr_read_lstatus(prnode_t
*pnp
, uio_t
*uiop
)
728 ASSERT(pnp
->pr_type
== PR_LSTATUS
);
730 if ((error
= prlock(pnp
, ZNO
)) != 0)
732 p
= pnp
->pr_common
->prc_proc
;
734 size
= sizeof (prheader_t
) + nlwp
* LSPAN(lwpstatus_t
);
736 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
737 mutex_exit(&p
->p_lock
);
738 php
= kmem_zalloc(size
, KM_SLEEP
);
739 mutex_enter(&p
->p_lock
);
740 /* p->p_lwpcnt can't change while process is locked */
741 ASSERT(nlwp
== p
->p_lwpcnt
);
744 php
->pr_entsize
= LSPAN(lwpstatus_t
);
746 sp
= (lwpstatus_t
*)(php
+ 1);
747 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
748 if (ldp
->ld_entry
== NULL
||
749 (t
= ldp
->ld_entry
->le_thread
) == NULL
)
751 prgetlwpstatus(t
, sp
, VTOZONE(PTOV(pnp
)));
752 sp
= (lwpstatus_t
*)((caddr_t
)sp
+ LSPAN(lwpstatus_t
));
756 error
= pr_uioread(php
, size
, uiop
);
757 kmem_free(php
, size
);
762 pr_read_psinfo(prnode_t
*pnp
, uio_t
*uiop
)
768 ASSERT(pnp
->pr_type
== PR_PSINFO
);
771 * We don't want the full treatment of prlock(pnp) here.
772 * This file is world-readable and never goes invalid.
773 * It doesn't matter if we are in the middle of an exec().
776 mutex_exit(&pr_pidlock
);
780 ASSERT(p
== pnp
->pr_common
->prc_proc
);
781 prgetpsinfo(p
, &psinfo
);
783 error
= pr_uioread(&psinfo
, sizeof (psinfo
), uiop
);
789 pr_read_lpsinfo(prnode_t
*pnp
, uio_t
*uiop
)
802 ASSERT(pnp
->pr_type
== PR_LPSINFO
);
805 * We don't want the full treatment of prlock(pnp) here.
806 * This file is world-readable and never goes invalid.
807 * It doesn't matter if we are in the middle of an exec().
810 mutex_exit(&pr_pidlock
);
813 ASSERT(p
== pnp
->pr_common
->prc_proc
);
814 if ((nlwp
= p
->p_lwpcnt
+ p
->p_zombcnt
) == 0) {
818 size
= sizeof (prheader_t
) + nlwp
* LSPAN(lwpsinfo_t
);
820 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
821 mutex_exit(&p
->p_lock
);
822 php
= kmem_zalloc(size
, KM_SLEEP
);
823 mutex_enter(&p
->p_lock
);
824 /* p->p_lwpcnt can't change while process is locked */
825 ASSERT(nlwp
== p
->p_lwpcnt
+ p
->p_zombcnt
);
828 php
->pr_entsize
= LSPAN(lwpsinfo_t
);
830 sp
= (lwpsinfo_t
*)(php
+ 1);
831 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
832 if ((lep
= ldp
->ld_entry
) == NULL
)
834 if ((t
= lep
->le_thread
) != NULL
)
835 prgetlwpsinfo(t
, sp
);
837 bzero(sp
, sizeof (*sp
));
838 sp
->pr_lwpid
= lep
->le_lwpid
;
839 sp
->pr_state
= SZOMB
;
841 sp
->pr_start
.tv_sec
= lep
->le_start
;
842 sp
->pr_bindpro
= PBIND_NONE
;
843 sp
->pr_bindpset
= PS_NONE
;
845 sp
= (lwpsinfo_t
*)((caddr_t
)sp
+ LSPAN(lwpsinfo_t
));
849 error
= pr_uioread(php
, size
, uiop
);
850 kmem_free(php
, size
);
855 pr_read_map_common(prnode_t
*pnp
, uio_t
*uiop
, prnodetype_t type
)
863 if ((error
= prlock(pnp
, ZNO
)) != 0)
866 p
= pnp
->pr_common
->prc_proc
;
869 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
874 if (!AS_LOCK_TRYENTER(as
, RW_WRITER
)) {
879 mutex_exit(&p
->p_lock
);
883 error
= prgetxmap(p
, &iolhead
);
886 error
= prgetmap(p
, 1, &iolhead
);
889 error
= prgetmap(p
, 0, &iolhead
);
894 mutex_enter(&p
->p_lock
);
897 error
= pr_iol_uiomove_and_free(&iolhead
, uiop
, error
);
903 pr_read_map(prnode_t
*pnp
, uio_t
*uiop
)
905 ASSERT(pnp
->pr_type
== PR_MAP
);
906 return (pr_read_map_common(pnp
, uiop
, pnp
->pr_type
));
910 pr_read_rmap(prnode_t
*pnp
, uio_t
*uiop
)
912 ASSERT(pnp
->pr_type
== PR_RMAP
);
913 return (pr_read_map_common(pnp
, uiop
, pnp
->pr_type
));
917 pr_read_xmap(prnode_t
*pnp
, uio_t
*uiop
)
919 ASSERT(pnp
->pr_type
== PR_XMAP
);
920 return (pr_read_map_common(pnp
, uiop
, pnp
->pr_type
));
924 pr_read_cred(prnode_t
*pnp
, uio_t
*uiop
)
931 ASSERT(pnp
->pr_type
== PR_CRED
);
934 * We kmem_alloc() the prcred_t structure because
935 * the number of supplementary groups is variable.
938 kmem_alloc(sizeof (prcred_t
) + sizeof (gid_t
) * (ngroups_max
- 1),
941 if ((error
= prlock(pnp
, ZNO
)) != 0)
943 p
= pnp
->pr_common
->prc_proc
;
949 count
= sizeof (prcred_t
);
950 if (pcrp
->pr_ngroups
> 1)
951 count
+= sizeof (gid_t
) * (pcrp
->pr_ngroups
- 1);
952 error
= pr_uioread(pcrp
, count
, uiop
);
954 kmem_free(pcrp
, sizeof (prcred_t
) + sizeof (gid_t
) * (ngroups_max
- 1));
959 pr_read_priv(prnode_t
*pnp
, uio_t
*uiop
)
962 size_t psize
= prgetprivsize();
963 prpriv_t
*ppriv
= kmem_alloc(psize
, KM_SLEEP
);
966 ASSERT(pnp
->pr_type
== PR_PRIV
);
968 if ((error
= prlock(pnp
, ZNO
)) != 0)
970 p
= pnp
->pr_common
->prc_proc
;
976 error
= pr_uioread(ppriv
, psize
, uiop
);
978 kmem_free(ppriv
, psize
);
983 pr_read_sigact(prnode_t
*pnp
, uio_t
*uiop
)
985 int nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
987 struct sigaction
*sap
;
992 ASSERT(pnp
->pr_type
== PR_SIGACT
);
995 * We kmem_alloc() the sigaction array because
996 * it is so big it might blow the kernel stack.
998 sap
= kmem_alloc((nsig
-1) * sizeof (struct sigaction
), KM_SLEEP
);
1000 if ((error
= prlock(pnp
, ZNO
)) != 0)
1002 p
= pnp
->pr_common
->prc_proc
;
1005 if (uiop
->uio_offset
>= (nsig
-1)*sizeof (struct sigaction
)) {
1011 for (sig
= 1; sig
< nsig
; sig
++)
1012 prgetaction(p
, up
, sig
, &sap
[sig
-1]);
1015 error
= pr_uioread(sap
, (nsig
- 1) * sizeof (struct sigaction
), uiop
);
1017 kmem_free(sap
, (nsig
-1) * sizeof (struct sigaction
));
1022 pr_read_auxv(prnode_t
*pnp
, uio_t
*uiop
)
1024 auxv_t auxv
[__KERN_NAUXV_IMPL
];
1029 ASSERT(pnp
->pr_type
== PR_AUXV
);
1031 if ((error
= prlock(pnp
, ZNO
)) != 0)
1034 if (uiop
->uio_offset
>= sizeof (auxv
)) {
1039 p
= pnp
->pr_common
->prc_proc
;
1041 bcopy(up
->u_auxv
, auxv
, sizeof (auxv
));
1044 return (pr_uioread(auxv
, sizeof (auxv
), uiop
));
1050 * This is almost certainly broken for the amd64 kernel, because
1051 * we have two kinds of LDT structures to export -- one for compatibility
1052 * mode, and one for long mode, sigh.
1054 * For now lets just have a ldt of size 0 for 64-bit processes.
1057 pr_read_ldt(prnode_t
*pnp
, uio_t
*uiop
)
1064 ASSERT(pnp
->pr_type
== PR_LDT
);
1066 if ((error
= prlock(pnp
, ZNO
)) != 0)
1068 p
= pnp
->pr_common
->prc_proc
;
1070 mutex_exit(&p
->p_lock
);
1071 mutex_enter(&p
->p_ldtlock
);
1072 size
= prnldt(p
) * sizeof (struct ssd
);
1073 if (uiop
->uio_offset
>= size
) {
1074 mutex_exit(&p
->p_ldtlock
);
1075 mutex_enter(&p
->p_lock
);
1080 ssd
= kmem_alloc(size
, KM_SLEEP
);
1082 mutex_exit(&p
->p_ldtlock
);
1083 mutex_enter(&p
->p_lock
);
1086 error
= pr_uioread(ssd
, size
, uiop
);
1087 kmem_free(ssd
, size
);
1093 pr_read_usage(prnode_t
*pnp
, uio_t
*uiop
)
1101 ASSERT(pnp
->pr_type
== PR_USAGE
);
1103 /* allocate now, before locking the process */
1104 pup
= kmem_zalloc(sizeof (*pup
), KM_SLEEP
);
1105 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
1108 * We don't want the full treatment of prlock(pnp) here.
1109 * This file is world-readable and never goes invalid.
1110 * It doesn't matter if we are in the middle of an exec().
1113 mutex_exit(&pr_pidlock
);
1118 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1120 if (uiop
->uio_offset
>= sizeof (prusage_t
)) {
1126 pup
->pr_tstamp
= gethrtime();
1128 pup
->pr_count
= p
->p_defunct
;
1129 pup
->pr_create
= p
->p_mstart
;
1130 pup
->pr_term
= p
->p_mterm
;
1132 pup
->pr_rtime
= p
->p_mlreal
;
1133 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
1134 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
1135 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
1136 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
1137 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
1138 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
1139 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
1140 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
1141 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
1142 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
1144 pup
->pr_minf
= p
->p_ru
.minflt
;
1145 pup
->pr_majf
= p
->p_ru
.majflt
;
1146 pup
->pr_nswap
= p
->p_ru
.nswap
;
1147 pup
->pr_inblk
= p
->p_ru
.inblock
;
1148 pup
->pr_oublk
= p
->p_ru
.oublock
;
1149 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
1150 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
1151 pup
->pr_sigs
= p
->p_ru
.nsignals
;
1152 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
1153 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
1154 pup
->pr_sysc
= p
->p_ru
.sysc
;
1155 pup
->pr_ioch
= p
->p_ru
.ioch
;
1158 * Add the usage information for each active lwp.
1160 if ((t
= p
->p_tlist
) != NULL
&&
1161 !(pnp
->pr_pcommon
->prc_flags
& PRC_DESTROY
)) {
1163 if (t
->t_proc_flag
& TP_LWPEXIT
)
1167 } while ((t
= t
->t_forw
) != p
->p_tlist
);
1172 prcvtusage(pup
, upup
);
1174 error
= pr_uioread(upup
, sizeof (prusage_t
), uiop
);
1176 kmem_free(pup
, sizeof (*pup
));
1177 kmem_free(upup
, sizeof (*upup
));
1182 pr_read_lusage(prnode_t
*pnp
, uio_t
*uiop
)
1196 ASSERT(pnp
->pr_type
== PR_LUSAGE
);
1199 * We don't want the full treatment of prlock(pnp) here.
1200 * This file is world-readable and never goes invalid.
1201 * It doesn't matter if we are in the middle of an exec().
1204 mutex_exit(&pr_pidlock
);
1207 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1208 if ((nlwp
= p
->p_lwpcnt
) == 0) {
1213 size
= sizeof (prheader_t
) + (nlwp
+ 1) * LSPAN(prusage_t
);
1214 if (uiop
->uio_offset
>= size
) {
1219 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1220 mutex_exit(&p
->p_lock
);
1221 pup
= kmem_zalloc(size
+ sizeof (prhusage_t
), KM_SLEEP
);
1222 mutex_enter(&p
->p_lock
);
1223 /* p->p_lwpcnt can't change while process is locked */
1224 ASSERT(nlwp
== p
->p_lwpcnt
);
1226 php
= (prheader_t
*)(pup
+ 1);
1227 upup
= (prusage_t
*)(php
+ 1);
1229 php
->pr_nent
= nlwp
+ 1;
1230 php
->pr_entsize
= LSPAN(prusage_t
);
1232 curtime
= gethrtime();
1235 * First the summation over defunct lwps.
1237 pup
->pr_count
= p
->p_defunct
;
1238 pup
->pr_tstamp
= curtime
;
1239 pup
->pr_create
= p
->p_mstart
;
1240 pup
->pr_term
= p
->p_mterm
;
1242 pup
->pr_rtime
= p
->p_mlreal
;
1243 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
1244 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
1245 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
1246 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
1247 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
1248 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
1249 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
1250 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
1251 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
1252 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
1254 pup
->pr_minf
= p
->p_ru
.minflt
;
1255 pup
->pr_majf
= p
->p_ru
.majflt
;
1256 pup
->pr_nswap
= p
->p_ru
.nswap
;
1257 pup
->pr_inblk
= p
->p_ru
.inblock
;
1258 pup
->pr_oublk
= p
->p_ru
.oublock
;
1259 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
1260 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
1261 pup
->pr_sigs
= p
->p_ru
.nsignals
;
1262 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
1263 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
1264 pup
->pr_sysc
= p
->p_ru
.sysc
;
1265 pup
->pr_ioch
= p
->p_ru
.ioch
;
1267 prcvtusage(pup
, upup
);
1270 * Fill one prusage struct for each active lwp.
1272 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
1273 if (ldp
->ld_entry
== NULL
||
1274 (t
= ldp
->ld_entry
->le_thread
) == NULL
)
1276 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
1279 upup
= (prusage_t
*)((caddr_t
)upup
+ LSPAN(prusage_t
));
1281 prcvtusage(pup
, upup
);
1287 error
= pr_uioread(php
, size
, uiop
);
1288 kmem_free(pup
, size
+ sizeof (prhusage_t
));
1293 pr_read_pagedata(prnode_t
*pnp
, uio_t
*uiop
)
1298 ASSERT(pnp
->pr_type
== PR_PAGEDATA
);
1300 if ((error
= prlock(pnp
, ZNO
)) != 0)
1303 p
= pnp
->pr_common
->prc_proc
;
1304 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
1309 mutex_exit(&p
->p_lock
);
1310 error
= prpdread(p
, pnp
->pr_hatid
, uiop
);
1311 mutex_enter(&p
->p_lock
);
1318 pr_read_opagedata(prnode_t
*pnp
, uio_t
*uiop
)
1324 ASSERT(pnp
->pr_type
== PR_OPAGEDATA
);
1326 if ((error
= prlock(pnp
, ZNO
)) != 0)
1329 p
= pnp
->pr_common
->prc_proc
;
1331 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
1336 mutex_exit(&p
->p_lock
);
1337 error
= oprpdread(as
, pnp
->pr_hatid
, uiop
);
1338 mutex_enter(&p
->p_lock
);
1345 pr_read_watch(prnode_t
*pnp
, uio_t
*uiop
)
1353 struct watched_area
*pwarea
;
1355 ASSERT(pnp
->pr_type
== PR_WATCH
);
1357 if ((error
= prlock(pnp
, ZNO
)) != 0)
1360 p
= pnp
->pr_common
->prc_proc
;
1361 nwarea
= avl_numnodes(&p
->p_warea
);
1362 size
= nwarea
* sizeof (prwatch_t
);
1363 if (uiop
->uio_offset
>= size
) {
1368 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1369 mutex_exit(&p
->p_lock
);
1370 Bpwp
= pwp
= kmem_zalloc(size
, KM_SLEEP
);
1371 mutex_enter(&p
->p_lock
);
1372 /* p->p_nwarea can't change while process is locked */
1373 ASSERT(nwarea
== avl_numnodes(&p
->p_warea
));
1375 /* gather the watched areas */
1376 for (pwarea
= avl_first(&p
->p_warea
); pwarea
!= NULL
;
1377 pwarea
= AVL_NEXT(&p
->p_warea
, pwarea
), pwp
++) {
1378 pwp
->pr_vaddr
= (uintptr_t)pwarea
->wa_vaddr
;
1379 pwp
->pr_size
= pwarea
->wa_eaddr
- pwarea
->wa_vaddr
;
1380 pwp
->pr_wflags
= (int)pwarea
->wa_flags
;
1385 error
= pr_uioread(Bpwp
, size
, uiop
);
1386 kmem_free(Bpwp
, size
);
1391 pr_read_lwpstatus(prnode_t
*pnp
, uio_t
*uiop
)
1396 ASSERT(pnp
->pr_type
== PR_LWPSTATUS
);
1399 * We kmem_alloc() the lwpstatus structure because
1400 * it is so big it might blow the kernel stack.
1402 sp
= kmem_alloc(sizeof (*sp
), KM_SLEEP
);
1404 if ((error
= prlock(pnp
, ZNO
)) != 0)
1407 if (uiop
->uio_offset
>= sizeof (*sp
)) {
1412 prgetlwpstatus(pnp
->pr_common
->prc_thread
, sp
, VTOZONE(PTOV(pnp
)));
1415 error
= pr_uioread(sp
, sizeof (*sp
), uiop
);
1417 kmem_free(sp
, sizeof (*sp
));
1422 pr_read_lwpsinfo(prnode_t
*pnp
, uio_t
*uiop
)
1424 lwpsinfo_t lwpsinfo
;
1429 ASSERT(pnp
->pr_type
== PR_LWPSINFO
);
1432 * We don't want the full treatment of prlock(pnp) here.
1433 * This file is world-readable and never goes invalid.
1434 * It doesn't matter if we are in the middle of an exec().
1437 mutex_exit(&pr_pidlock
);
1440 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1441 if (pnp
->pr_common
->prc_tslot
== -1) {
1446 if (uiop
->uio_offset
>= sizeof (lwpsinfo
)) {
1451 if ((t
= pnp
->pr_common
->prc_thread
) != NULL
)
1452 prgetlwpsinfo(t
, &lwpsinfo
);
1454 lep
= p
->p_lwpdir
[pnp
->pr_common
->prc_tslot
].ld_entry
;
1455 bzero(&lwpsinfo
, sizeof (lwpsinfo
));
1456 lwpsinfo
.pr_lwpid
= lep
->le_lwpid
;
1457 lwpsinfo
.pr_state
= SZOMB
;
1458 lwpsinfo
.pr_sname
= 'Z';
1459 lwpsinfo
.pr_start
.tv_sec
= lep
->le_start
;
1460 lwpsinfo
.pr_bindpro
= PBIND_NONE
;
1461 lwpsinfo
.pr_bindpset
= PS_NONE
;
1465 return (pr_uioread(&lwpsinfo
, sizeof (lwpsinfo
), uiop
));
1469 pr_read_lwpusage(prnode_t
*pnp
, uio_t
*uiop
)
1476 ASSERT(pnp
->pr_type
== PR_LWPUSAGE
);
1478 /* allocate now, before locking the process */
1479 pup
= kmem_zalloc(sizeof (*pup
), KM_SLEEP
);
1480 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
1483 * We don't want the full treatment of prlock(pnp) here.
1484 * This file is world-readable and never goes invalid.
1485 * It doesn't matter if we are in the middle of an exec().
1488 mutex_exit(&pr_pidlock
);
1493 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1494 if (pnp
->pr_common
->prc_thread
== NULL
) {
1499 if (uiop
->uio_offset
>= sizeof (prusage_t
)) {
1505 pup
->pr_tstamp
= gethrtime();
1506 prgetusage(pnp
->pr_common
->prc_thread
, pup
);
1510 prcvtusage(pup
, upup
);
1512 error
= pr_uioread(upup
, sizeof (prusage_t
), uiop
);
1514 kmem_free(pup
, sizeof (*pup
));
1515 kmem_free(upup
, sizeof (*upup
));
1521 pr_read_xregs(prnode_t
*pnp
, uio_t
*uiop
)
1527 pr_read_spymaster(prnode_t
*pnp
, uio_t
*uiop
)
1533 ASSERT(pnp
->pr_type
== PR_SPYMASTER
);
1535 if ((error
= prlock(pnp
, ZNO
)) != 0)
1538 lwp
= pnp
->pr_common
->prc_thread
->t_lwp
;
1540 if (lwp
->lwp_spymaster
== NULL
) {
1545 bcopy(lwp
->lwp_spymaster
, &psinfo
, sizeof (psinfo_t
));
1548 return (pr_uioread(&psinfo
, sizeof (psinfo
), uiop
));
1552 pr_read_secflags(prnode_t
*pnp
, uio_t
*uiop
)
1558 ASSERT(pnp
->pr_type
== PR_SECFLAGS
);
1560 if ((error
= prlock(pnp
, ZNO
)) != 0)
1563 p
= pnp
->pr_common
->prc_proc
;
1564 prgetsecflags(p
, &ret
);
1567 return (pr_uioread(&ret
, sizeof (ret
), uiop
));
1572 pr_read_piddir(prnode_t
*pnp
, uio_t
*uiop
)
1574 ASSERT(pnp
->pr_type
== PR_PIDDIR
);
1575 ASSERT(pnp
->pr_pidfile
!= NULL
);
1577 /* use the underlying PR_PIDFILE to read the process */
1578 pnp
= VTOP(pnp
->pr_pidfile
);
1579 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
1581 return (pr_read_pidfile(pnp
, uiop
));
1585 pr_read_pidfile(prnode_t
*pnp
, uio_t
*uiop
)
1589 ASSERT(pnp
->pr_type
== PR_PIDFILE
|| pnp
->pr_type
== PR_LWPIDFILE
);
1591 if ((error
= prlock(pnp
, ZNO
)) == 0) {
1592 proc_t
*p
= pnp
->pr_common
->prc_proc
;
1593 struct as
*as
= p
->p_as
;
1595 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
1597 * /proc I/O cannot be done to a system process.
1599 error
= EIO
; /* old /proc semantics */
1602 * We drop p_lock because we don't want to hold
1603 * it over an I/O operation because that could
1604 * lead to deadlock with the clock thread.
1605 * The process will not disappear and its address
1606 * space will not change because it is marked P_PR_LOCK.
1608 mutex_exit(&p
->p_lock
);
1609 error
= prusrio(p
, UIO_READ
, uiop
, 1);
1610 mutex_enter(&p
->p_lock
);
1618 #ifdef _SYSCALL32_IMPL
1621 * Array of ILP32 read functions, indexed by /proc file type.
1623 static int pr_read_status_32(),
1624 pr_read_lstatus_32(), pr_read_psinfo_32(), pr_read_lpsinfo_32(),
1625 pr_read_map_32(), pr_read_rmap_32(), pr_read_xmap_32(),
1626 pr_read_sigact_32(), pr_read_auxv_32(),
1627 pr_read_usage_32(), pr_read_lusage_32(), pr_read_pagedata_32(),
1628 pr_read_watch_32(), pr_read_lwpstatus_32(), pr_read_lwpsinfo_32(),
1629 pr_read_lwpusage_32(), pr_read_spymaster_32(),
1630 #if defined(__sparc)
1631 pr_read_gwindows_32(),
1633 pr_read_opagedata_32();
1635 static int (*pr_read_function_32
[PR_NFILES
])() = {
1636 pr_read_inval
, /* /proc */
1637 pr_read_inval
, /* /proc/self */
1638 pr_read_piddir
, /* /proc/<pid> (old /proc read()) */
1639 pr_read_as
, /* /proc/<pid>/as */
1640 pr_read_inval
, /* /proc/<pid>/ctl */
1641 pr_read_status_32
, /* /proc/<pid>/status */
1642 pr_read_lstatus_32
, /* /proc/<pid>/lstatus */
1643 pr_read_psinfo_32
, /* /proc/<pid>/psinfo */
1644 pr_read_lpsinfo_32
, /* /proc/<pid>/lpsinfo */
1645 pr_read_map_32
, /* /proc/<pid>/map */
1646 pr_read_rmap_32
, /* /proc/<pid>/rmap */
1647 pr_read_xmap_32
, /* /proc/<pid>/xmap */
1648 pr_read_cred
, /* /proc/<pid>/cred */
1649 pr_read_sigact_32
, /* /proc/<pid>/sigact */
1650 pr_read_auxv_32
, /* /proc/<pid>/auxv */
1652 pr_read_ldt
, /* /proc/<pid>/ldt */
1654 pr_read_usage_32
, /* /proc/<pid>/usage */
1655 pr_read_lusage_32
, /* /proc/<pid>/lusage */
1656 pr_read_pagedata_32
, /* /proc/<pid>/pagedata */
1657 pr_read_watch_32
, /* /proc/<pid>/watch */
1658 pr_read_inval
, /* /proc/<pid>/cwd */
1659 pr_read_inval
, /* /proc/<pid>/root */
1660 pr_read_inval
, /* /proc/<pid>/fd */
1661 pr_read_inval
, /* /proc/<pid>/fd/nn */
1662 pr_read_inval
, /* /proc/<pid>/object */
1663 pr_read_inval
, /* /proc/<pid>/object/xxx */
1664 pr_read_inval
, /* /proc/<pid>/lwp */
1665 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid> */
1666 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
1667 pr_read_lwpstatus_32
, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
1668 pr_read_lwpsinfo_32
, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1669 pr_read_lwpusage_32
, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1670 pr_read_xregs
, /* /proc/<pid>/lwp/<lwpid>/xregs */
1671 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/templates */
1672 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1673 pr_read_spymaster_32
, /* /proc/<pid>/lwp/<lwpid>/spymaster */
1674 #if defined(__sparc)
1675 pr_read_gwindows_32
, /* /proc/<pid>/lwp/<lwpid>/gwindows */
1676 pr_read_asrs
, /* /proc/<pid>/lwp/<lwpid>/asrs */
1678 pr_read_priv
, /* /proc/<pid>/priv */
1679 pr_read_inval
, /* /proc/<pid>/path */
1680 pr_read_inval
, /* /proc/<pid>/path/xxx */
1681 pr_read_inval
, /* /proc/<pid>/contracts */
1682 pr_read_inval
, /* /proc/<pid>/contracts/<ctid> */
1683 pr_read_secflags
, /* /proc/<pid>/secflags */
1684 pr_read_pidfile
, /* old process file */
1685 pr_read_pidfile
, /* old lwp file */
1686 pr_read_opagedata_32
, /* old pagedata file */
1690 pr_read_status_32(prnode_t
*pnp
, uio_t
*uiop
)
1696 ASSERT(pnp
->pr_type
== PR_STATUS
);
1699 * We kmem_alloc() the pstatus structure because
1700 * it is so big it might blow the kernel stack.
1702 sp
= kmem_alloc(sizeof (*sp
), KM_SLEEP
);
1703 if ((error
= prlock(pnp
, ZNO
)) == 0) {
1705 * A 32-bit process cannot get the status of a 64-bit process.
1706 * The fields for the 64-bit quantities are not large enough.
1708 p
= pnp
->pr_common
->prc_proc
;
1709 if (PROCESS_NOT_32BIT(p
)) {
1713 prgetstatus32(pnp
->pr_common
->prc_proc
, sp
,
1714 VTOZONE(PTOV(pnp
)));
1716 error
= pr_uioread(sp
, sizeof (*sp
), uiop
);
1719 kmem_free((caddr_t
)sp
, sizeof (*sp
));
1724 pr_read_lstatus_32(prnode_t
*pnp
, uio_t
*uiop
)
1736 ASSERT(pnp
->pr_type
== PR_LSTATUS
);
1738 if ((error
= prlock(pnp
, ZNO
)) != 0)
1740 p
= pnp
->pr_common
->prc_proc
;
1742 * A 32-bit process cannot get the status of a 64-bit process.
1743 * The fields for the 64-bit quantities are not large enough.
1745 if (PROCESS_NOT_32BIT(p
)) {
1750 size
= sizeof (prheader32_t
) + nlwp
* LSPAN32(lwpstatus32_t
);
1752 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1753 mutex_exit(&p
->p_lock
);
1754 php
= kmem_zalloc(size
, KM_SLEEP
);
1755 mutex_enter(&p
->p_lock
);
1756 /* p->p_lwpcnt can't change while process is locked */
1757 ASSERT(nlwp
== p
->p_lwpcnt
);
1759 php
->pr_nent
= nlwp
;
1760 php
->pr_entsize
= LSPAN32(lwpstatus32_t
);
1762 sp
= (lwpstatus32_t
*)(php
+ 1);
1763 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
1764 if (ldp
->ld_entry
== NULL
||
1765 (t
= ldp
->ld_entry
->le_thread
) == NULL
)
1767 prgetlwpstatus32(t
, sp
, VTOZONE(PTOV(pnp
)));
1768 sp
= (lwpstatus32_t
*)((caddr_t
)sp
+ LSPAN32(lwpstatus32_t
));
1772 error
= pr_uioread(php
, size
, uiop
);
1773 kmem_free(php
, size
);
1778 pr_read_psinfo_32(prnode_t
*pnp
, uio_t
*uiop
)
1784 ASSERT(pnp
->pr_type
== PR_PSINFO
);
1787 * We don't want the full treatment of prlock(pnp) here.
1788 * This file is world-readable and never goes invalid.
1789 * It doesn't matter if we are in the middle of an exec().
1792 mutex_exit(&pr_pidlock
);
1796 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1797 prgetpsinfo32(p
, &psinfo
);
1799 error
= pr_uioread(&psinfo
, sizeof (psinfo
), uiop
);
1805 pr_read_lpsinfo_32(prnode_t
*pnp
, uio_t
*uiop
)
1818 ASSERT(pnp
->pr_type
== PR_LPSINFO
);
1821 * We don't want the full treatment of prlock(pnp) here.
1822 * This file is world-readable and never goes invalid.
1823 * It doesn't matter if we are in the middle of an exec().
1826 mutex_exit(&pr_pidlock
);
1829 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1830 if ((nlwp
= p
->p_lwpcnt
+ p
->p_zombcnt
) == 0) {
1834 size
= sizeof (prheader32_t
) + nlwp
* LSPAN32(lwpsinfo32_t
);
1836 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1837 mutex_exit(&p
->p_lock
);
1838 php
= kmem_zalloc(size
, KM_SLEEP
);
1839 mutex_enter(&p
->p_lock
);
1840 /* p->p_lwpcnt can't change while process is locked */
1841 ASSERT(nlwp
== p
->p_lwpcnt
+ p
->p_zombcnt
);
1843 php
->pr_nent
= nlwp
;
1844 php
->pr_entsize
= LSPAN32(lwpsinfo32_t
);
1846 sp
= (lwpsinfo32_t
*)(php
+ 1);
1847 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
1848 if ((lep
= ldp
->ld_entry
) == NULL
)
1850 if ((t
= lep
->le_thread
) != NULL
)
1851 prgetlwpsinfo32(t
, sp
);
1853 bzero(sp
, sizeof (*sp
));
1854 sp
->pr_lwpid
= lep
->le_lwpid
;
1855 sp
->pr_state
= SZOMB
;
1857 sp
->pr_start
.tv_sec
= (time32_t
)lep
->le_start
;
1859 sp
= (lwpsinfo32_t
*)((caddr_t
)sp
+ LSPAN32(lwpsinfo32_t
));
1863 error
= pr_uioread(php
, size
, uiop
);
1864 kmem_free(php
, size
);
1869 pr_read_map_common_32(prnode_t
*pnp
, uio_t
*uiop
, prnodetype_t type
)
1877 if ((error
= prlock(pnp
, ZNO
)) != 0)
1880 p
= pnp
->pr_common
->prc_proc
;
1883 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
1888 if (PROCESS_NOT_32BIT(p
)) {
1893 if (!AS_LOCK_TRYENTER(as
, RW_WRITER
)) {
1896 goto readmap32_common
;
1898 mutex_exit(&p
->p_lock
);
1902 error
= prgetxmap32(p
, &iolhead
);
1905 error
= prgetmap32(p
, 1, &iolhead
);
1908 error
= prgetmap32(p
, 0, &iolhead
);
1912 mutex_enter(&p
->p_lock
);
1915 error
= pr_iol_uiomove_and_free(&iolhead
, uiop
, error
);
1921 pr_read_map_32(prnode_t
*pnp
, uio_t
*uiop
)
1923 ASSERT(pnp
->pr_type
== PR_MAP
);
1924 return (pr_read_map_common_32(pnp
, uiop
, pnp
->pr_type
));
1928 pr_read_rmap_32(prnode_t
*pnp
, uio_t
*uiop
)
1930 ASSERT(pnp
->pr_type
== PR_RMAP
);
1931 return (pr_read_map_common_32(pnp
, uiop
, pnp
->pr_type
));
1935 pr_read_xmap_32(prnode_t
*pnp
, uio_t
*uiop
)
1937 ASSERT(pnp
->pr_type
== PR_XMAP
);
1938 return (pr_read_map_common_32(pnp
, uiop
, pnp
->pr_type
));
1942 pr_read_sigact_32(prnode_t
*pnp
, uio_t
*uiop
)
1944 int nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
1946 struct sigaction32
*sap
;
1951 ASSERT(pnp
->pr_type
== PR_SIGACT
);
1954 * We kmem_alloc() the sigaction32 array because
1955 * it is so big it might blow the kernel stack.
1957 sap
= kmem_alloc((nsig
-1) * sizeof (struct sigaction32
), KM_SLEEP
);
1959 if ((error
= prlock(pnp
, ZNO
)) != 0)
1961 p
= pnp
->pr_common
->prc_proc
;
1963 if (PROCESS_NOT_32BIT(p
)) {
1969 if (uiop
->uio_offset
>= (nsig
-1) * sizeof (struct sigaction32
)) {
1975 for (sig
= 1; sig
< nsig
; sig
++)
1976 prgetaction32(p
, up
, sig
, &sap
[sig
-1]);
1979 error
= pr_uioread(sap
, (nsig
- 1) * sizeof (struct sigaction32
), uiop
);
1981 kmem_free(sap
, (nsig
-1) * sizeof (struct sigaction32
));
1986 pr_read_auxv_32(prnode_t
*pnp
, uio_t
*uiop
)
1988 auxv32_t auxv
[__KERN_NAUXV_IMPL
];
1994 ASSERT(pnp
->pr_type
== PR_AUXV
);
1996 if ((error
= prlock(pnp
, ZNO
)) != 0)
1998 p
= pnp
->pr_common
->prc_proc
;
2000 if (PROCESS_NOT_32BIT(p
)) {
2005 if (uiop
->uio_offset
>= sizeof (auxv
)) {
2011 for (i
= 0; i
< __KERN_NAUXV_IMPL
; i
++) {
2012 auxv
[i
].a_type
= (int32_t)up
->u_auxv
[i
].a_type
;
2013 auxv
[i
].a_un
.a_val
= (int32_t)up
->u_auxv
[i
].a_un
.a_val
;
2017 return (pr_uioread(auxv
, sizeof (auxv
), uiop
));
2021 pr_read_usage_32(prnode_t
*pnp
, uio_t
*uiop
)
2029 ASSERT(pnp
->pr_type
== PR_USAGE
);
2031 /* allocate now, before locking the process */
2032 pup
= kmem_zalloc(sizeof (*pup
), KM_SLEEP
);
2033 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
2036 * We don't want the full treatment of prlock(pnp) here.
2037 * This file is world-readable and never goes invalid.
2038 * It doesn't matter if we are in the middle of an exec().
2041 mutex_exit(&pr_pidlock
);
2046 ASSERT(p
== pnp
->pr_common
->prc_proc
);
2048 if (uiop
->uio_offset
>= sizeof (prusage32_t
)) {
2054 pup
->pr_tstamp
= gethrtime();
2056 pup
->pr_count
= p
->p_defunct
;
2057 pup
->pr_create
= p
->p_mstart
;
2058 pup
->pr_term
= p
->p_mterm
;
2060 pup
->pr_rtime
= p
->p_mlreal
;
2061 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
2062 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
2063 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
2064 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
2065 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
2066 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
2067 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
2068 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
2069 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
2070 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
2072 pup
->pr_minf
= p
->p_ru
.minflt
;
2073 pup
->pr_majf
= p
->p_ru
.majflt
;
2074 pup
->pr_nswap
= p
->p_ru
.nswap
;
2075 pup
->pr_inblk
= p
->p_ru
.inblock
;
2076 pup
->pr_oublk
= p
->p_ru
.oublock
;
2077 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
2078 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
2079 pup
->pr_sigs
= p
->p_ru
.nsignals
;
2080 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
2081 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
2082 pup
->pr_sysc
= p
->p_ru
.sysc
;
2083 pup
->pr_ioch
= p
->p_ru
.ioch
;
2086 * Add the usage information for each active lwp.
2088 if ((t
= p
->p_tlist
) != NULL
&&
2089 !(pnp
->pr_pcommon
->prc_flags
& PRC_DESTROY
)) {
2091 if (t
->t_proc_flag
& TP_LWPEXIT
)
2095 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2100 prcvtusage32(pup
, upup
);
2102 error
= pr_uioread(upup
, sizeof (prusage32_t
), uiop
);
2104 kmem_free(pup
, sizeof (*pup
));
2105 kmem_free(upup
, sizeof (*upup
));
2110 pr_read_lusage_32(prnode_t
*pnp
, uio_t
*uiop
)
2124 ASSERT(pnp
->pr_type
== PR_LUSAGE
);
2127 * We don't want the full treatment of prlock(pnp) here.
2128 * This file is world-readable and never goes invalid.
2129 * It doesn't matter if we are in the middle of an exec().
2132 mutex_exit(&pr_pidlock
);
2135 ASSERT(p
== pnp
->pr_common
->prc_proc
);
2136 if ((nlwp
= p
->p_lwpcnt
) == 0) {
2141 size
= sizeof (prheader32_t
) + (nlwp
+ 1) * LSPAN32(prusage32_t
);
2142 if (uiop
->uio_offset
>= size
) {
2147 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2148 mutex_exit(&p
->p_lock
);
2149 pup
= kmem_zalloc(size
+ sizeof (prhusage_t
), KM_SLEEP
);
2150 mutex_enter(&p
->p_lock
);
2151 /* p->p_lwpcnt can't change while process is locked */
2152 ASSERT(nlwp
== p
->p_lwpcnt
);
2154 php
= (prheader32_t
*)(pup
+ 1);
2155 upup
= (prusage32_t
*)(php
+ 1);
2157 php
->pr_nent
= nlwp
+ 1;
2158 php
->pr_entsize
= LSPAN32(prusage32_t
);
2160 curtime
= gethrtime();
2163 * First the summation over defunct lwps.
2165 pup
->pr_count
= p
->p_defunct
;
2166 pup
->pr_tstamp
= curtime
;
2167 pup
->pr_create
= p
->p_mstart
;
2168 pup
->pr_term
= p
->p_mterm
;
2170 pup
->pr_rtime
= p
->p_mlreal
;
2171 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
2172 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
2173 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
2174 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
2175 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
2176 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
2177 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
2178 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
2179 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
2180 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
2182 pup
->pr_minf
= p
->p_ru
.minflt
;
2183 pup
->pr_majf
= p
->p_ru
.majflt
;
2184 pup
->pr_nswap
= p
->p_ru
.nswap
;
2185 pup
->pr_inblk
= p
->p_ru
.inblock
;
2186 pup
->pr_oublk
= p
->p_ru
.oublock
;
2187 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
2188 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
2189 pup
->pr_sigs
= p
->p_ru
.nsignals
;
2190 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
2191 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
2192 pup
->pr_sysc
= p
->p_ru
.sysc
;
2193 pup
->pr_ioch
= p
->p_ru
.ioch
;
2195 prcvtusage32(pup
, upup
);
2198 * Fill one prusage struct for each active lwp.
2200 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
2201 if (ldp
->ld_entry
== NULL
||
2202 (t
= ldp
->ld_entry
->le_thread
) == NULL
)
2204 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2207 upup
= (prusage32_t
*)
2208 ((caddr_t
)upup
+ LSPAN32(prusage32_t
));
2210 prcvtusage32(pup
, upup
);
2216 error
= pr_uioread(php
, size
, uiop
);
2217 kmem_free(pup
, size
+ sizeof (prhusage_t
));
2222 pr_read_pagedata_32(prnode_t
*pnp
, uio_t
*uiop
)
2227 ASSERT(pnp
->pr_type
== PR_PAGEDATA
);
2229 if ((error
= prlock(pnp
, ZNO
)) != 0)
2232 p
= pnp
->pr_common
->prc_proc
;
2233 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
2238 if (PROCESS_NOT_32BIT(p
)) {
2243 mutex_exit(&p
->p_lock
);
2244 error
= prpdread32(p
, pnp
->pr_hatid
, uiop
);
2245 mutex_enter(&p
->p_lock
);
2252 pr_read_opagedata_32(prnode_t
*pnp
, uio_t
*uiop
)
2258 ASSERT(pnp
->pr_type
== PR_OPAGEDATA
);
2260 if ((error
= prlock(pnp
, ZNO
)) != 0)
2263 p
= pnp
->pr_common
->prc_proc
;
2266 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
2271 if (PROCESS_NOT_32BIT(p
)) {
2276 mutex_exit(&p
->p_lock
);
2277 error
= oprpdread32(as
, pnp
->pr_hatid
, uiop
);
2278 mutex_enter(&p
->p_lock
);
2285 pr_read_watch_32(prnode_t
*pnp
, uio_t
*uiop
)
2293 struct watched_area
*pwarea
;
2295 ASSERT(pnp
->pr_type
== PR_WATCH
);
2297 if ((error
= prlock(pnp
, ZNO
)) != 0)
2300 p
= pnp
->pr_common
->prc_proc
;
2301 if (PROCESS_NOT_32BIT(p
)) {
2305 nwarea
= avl_numnodes(&p
->p_warea
);
2306 size
= nwarea
* sizeof (prwatch32_t
);
2307 if (uiop
->uio_offset
>= size
) {
2312 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2313 mutex_exit(&p
->p_lock
);
2314 Bpwp
= pwp
= kmem_zalloc(size
, KM_SLEEP
);
2315 mutex_enter(&p
->p_lock
);
2316 /* p->p_nwarea can't change while process is locked */
2317 ASSERT(nwarea
== avl_numnodes(&p
->p_warea
));
2319 /* gather the watched areas */
2320 for (pwarea
= avl_first(&p
->p_warea
); pwarea
!= NULL
;
2321 pwarea
= AVL_NEXT(&p
->p_warea
, pwarea
), pwp
++) {
2322 pwp
->pr_vaddr
= (caddr32_t
)(uintptr_t)pwarea
->wa_vaddr
;
2323 pwp
->pr_size
= (size32_t
)(pwarea
->wa_eaddr
- pwarea
->wa_vaddr
);
2324 pwp
->pr_wflags
= (int)pwarea
->wa_flags
;
2329 error
= pr_uioread(Bpwp
, size
, uiop
);
2330 kmem_free(Bpwp
, size
);
2335 pr_read_lwpstatus_32(prnode_t
*pnp
, uio_t
*uiop
)
2341 ASSERT(pnp
->pr_type
== PR_LWPSTATUS
);
2344 * We kmem_alloc() the lwpstatus structure because
2345 * it is so big it might blow the kernel stack.
2347 sp
= kmem_alloc(sizeof (*sp
), KM_SLEEP
);
2349 if ((error
= prlock(pnp
, ZNO
)) != 0)
2353 * A 32-bit process cannot get the status of a 64-bit process.
2354 * The fields for the 64-bit quantities are not large enough.
2356 p
= pnp
->pr_common
->prc_proc
;
2357 if (PROCESS_NOT_32BIT(p
)) {
2363 if (uiop
->uio_offset
>= sizeof (*sp
)) {
2368 prgetlwpstatus32(pnp
->pr_common
->prc_thread
, sp
, VTOZONE(PTOV(pnp
)));
2371 error
= pr_uioread(sp
, sizeof (*sp
), uiop
);
2373 kmem_free(sp
, sizeof (*sp
));
2378 pr_read_lwpsinfo_32(prnode_t
*pnp
, uio_t
*uiop
)
2380 lwpsinfo32_t lwpsinfo
;
2385 ASSERT(pnp
->pr_type
== PR_LWPSINFO
);
2388 * We don't want the full treatment of prlock(pnp) here.
2389 * This file is world-readable and never goes invalid.
2390 * It doesn't matter if we are in the middle of an exec().
2393 mutex_exit(&pr_pidlock
);
2396 ASSERT(p
== pnp
->pr_common
->prc_proc
);
2397 if (pnp
->pr_common
->prc_tslot
== -1) {
2402 if (uiop
->uio_offset
>= sizeof (lwpsinfo
)) {
2407 if ((t
= pnp
->pr_common
->prc_thread
) != NULL
)
2408 prgetlwpsinfo32(t
, &lwpsinfo
);
2410 lep
= p
->p_lwpdir
[pnp
->pr_common
->prc_tslot
].ld_entry
;
2411 bzero(&lwpsinfo
, sizeof (lwpsinfo
));
2412 lwpsinfo
.pr_lwpid
= lep
->le_lwpid
;
2413 lwpsinfo
.pr_state
= SZOMB
;
2414 lwpsinfo
.pr_sname
= 'Z';
2415 lwpsinfo
.pr_start
.tv_sec
= (time32_t
)lep
->le_start
;
2419 return (pr_uioread(&lwpsinfo
, sizeof (lwpsinfo
), uiop
));
2423 pr_read_lwpusage_32(prnode_t
*pnp
, uio_t
*uiop
)
2430 ASSERT(pnp
->pr_type
== PR_LWPUSAGE
);
2432 /* allocate now, before locking the process */
2433 pup
= kmem_zalloc(sizeof (*pup
), KM_SLEEP
);
2434 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
2437 * We don't want the full treatment of prlock(pnp) here.
2438 * This file is world-readable and never goes invalid.
2439 * It doesn't matter if we are in the middle of an exec().
2442 mutex_exit(&pr_pidlock
);
2447 ASSERT(p
== pnp
->pr_common
->prc_proc
);
2448 if (pnp
->pr_common
->prc_thread
== NULL
) {
2453 if (uiop
->uio_offset
>= sizeof (prusage32_t
)) {
2459 pup
->pr_tstamp
= gethrtime();
2460 prgetusage(pnp
->pr_common
->prc_thread
, pup
);
2464 prcvtusage32(pup
, upup
);
2466 error
= pr_uioread(upup
, sizeof (prusage32_t
), uiop
);
2468 kmem_free(pup
, sizeof (*pup
));
2469 kmem_free(upup
, sizeof (*upup
));
2474 pr_read_spymaster_32(prnode_t
*pnp
, uio_t
*uiop
)
2480 ASSERT(pnp
->pr_type
== PR_SPYMASTER
);
2482 if ((error
= prlock(pnp
, ZNO
)) != 0)
2485 lwp
= pnp
->pr_common
->prc_thread
->t_lwp
;
2487 if (lwp
->lwp_spymaster
== NULL
) {
2492 psinfo_kto32(lwp
->lwp_spymaster
, &psinfo
);
2495 return (pr_uioread(&psinfo
, sizeof (psinfo
), uiop
));
2498 #if defined(__sparc)
2500 pr_read_gwindows_32(prnode_t
*pnp
, uio_t
*uiop
)
2508 ASSERT(pnp
->pr_type
== PR_GWINDOWS
);
2510 gwp
= kmem_zalloc(sizeof (gwindows32_t
), KM_SLEEP
);
2512 if ((error
= prlock(pnp
, ZNO
)) != 0)
2515 p
= pnp
->pr_common
->prc_proc
;
2516 t
= pnp
->pr_common
->prc_thread
;
2518 if (PROCESS_NOT_32BIT(p
)) {
2525 * Drop p->p_lock while touching the stack.
2526 * The P_PR_LOCK flag prevents the lwp from
2527 * disappearing while we do this.
2529 mutex_exit(&p
->p_lock
);
2530 if ((size
= prnwindows(ttolwp(t
))) != 0)
2531 size
= sizeof (gwindows32_t
) -
2532 (SPARC_MAXREGWINDOW
- size
) * sizeof (struct rwindow32
);
2533 if (uiop
->uio_offset
>= size
) {
2534 mutex_enter(&p
->p_lock
);
2538 prgetwindows32(ttolwp(t
), gwp
);
2539 mutex_enter(&p
->p_lock
);
2542 error
= pr_uioread(gwp
, size
, uiop
);
2544 kmem_free(gwp
, sizeof (gwindows32_t
));
2547 #endif /* __sparc */
2549 #endif /* _SYSCALL32_IMPL */
2553 prread(vnode_t
*vp
, uio_t
*uiop
, int ioflag
, cred_t
*cr
, caller_context_t
*ct
)
2555 prnode_t
*pnp
= VTOP(vp
);
2557 ASSERT(pnp
->pr_type
< PR_NFILES
);
2559 #ifdef _SYSCALL32_IMPL
2561 * What is read from the /proc files depends on the data
2562 * model of the caller. An LP64 process will see LP64
2563 * data. An ILP32 process will see ILP32 data.
2565 if (curproc
->p_model
== DATAMODEL_LP64
)
2566 return (pr_read_function
[pnp
->pr_type
](pnp
, uiop
));
2568 return (pr_read_function_32
[pnp
->pr_type
](pnp
, uiop
));
2570 return (pr_read_function
[pnp
->pr_type
](pnp
, uiop
));
2576 prwrite(vnode_t
*vp
, uio_t
*uiop
, int ioflag
, cred_t
*cr
, caller_context_t
*ct
)
2578 prnode_t
*pnp
= VTOP(vp
);
2583 ASSERT(pnp
->pr_type
< PR_NFILES
);
2586 * Only a handful of /proc files are writable, enumerate them here.
2588 switch (pnp
->pr_type
) {
2589 case PR_PIDDIR
: /* directory write()s: visceral revulsion. */
2590 ASSERT(pnp
->pr_pidfile
!= NULL
);
2591 /* use the underlying PR_PIDFILE to write the process */
2592 vp
= pnp
->pr_pidfile
;
2594 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
2601 if ((error
= prlock(pnp
, ZNO
)) == 0) {
2602 proc_t
*p
= pnp
->pr_common
->prc_proc
;
2603 struct as
*as
= p
->p_as
;
2605 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
2607 * /proc I/O cannot be done to a system process.
2610 #ifdef _SYSCALL32_IMPL
2611 } else if (curproc
->p_model
== DATAMODEL_ILP32
&&
2612 PROCESS_NOT_32BIT(p
)) {
2617 * See comments above (pr_read_pidfile)
2618 * about this locking dance.
2620 mutex_exit(&p
->p_lock
);
2621 error
= prusrio(p
, UIO_WRITE
, uiop
, old
);
2622 mutex_enter(&p
->p_lock
);
2630 resid
= uiop
->uio_resid
;
2632 * Perform the action on the control file
2633 * by passing curthreads credentials
2634 * and not target process's credentials.
2636 #ifdef _SYSCALL32_IMPL
2637 if (curproc
->p_model
== DATAMODEL_ILP32
)
2638 error
= prwritectl32(vp
, uiop
, CRED());
2640 error
= prwritectl(vp
, uiop
, CRED());
2642 error
= prwritectl(vp
, uiop
, CRED());
2645 * This hack makes sure that the EINTR is passed
2646 * all the way back to the caller's write() call.
2649 uiop
->uio_resid
= resid
;
2653 return ((vp
->v_type
== VDIR
)? EISDIR
: EBADF
);
2659 prgetattr(vnode_t
*vp
, vattr_t
*vap
, int flags
, cred_t
*cr
,
2660 caller_context_t
*ct
)
2662 prnode_t
*pnp
= VTOP(vp
);
2663 prnodetype_t type
= pnp
->pr_type
;
2670 extern uint_t nproc
;
2675 * This ugly bit of code allows us to keep both versions of this
2676 * function from the same source.
2679 int iam32bit
= (curproc
->p_model
== DATAMODEL_ILP32
);
2680 #define PR_OBJSIZE(obj32, obj64) \
2681 (iam32bit ? sizeof (obj32) : sizeof (obj64))
2682 #define PR_OBJSPAN(obj32, obj64) \
2683 (iam32bit ? LSPAN32(obj32) : LSPAN(obj64))
2685 #define PR_OBJSIZE(obj32, obj64) \
2687 #define PR_OBJSPAN(obj32, obj64) \
2692 * Return all the attributes. Should be refined
2693 * so that it returns only those asked for.
2694 * Most of this is complete fakery anyway.
2698 * For files in the /proc/<pid>/object directory,
2699 * return the attributes of the underlying object.
2700 * For files in the /proc/<pid>/fd directory,
2701 * return the attributes of the underlying file, but
2702 * make it look inaccessible if it is not a regular file.
2703 * Make directories look like symlinks.
2708 if (!(flags
& ATTR_REAL
))
2710 /* restrict full knowledge of the attributes to owner or root */
2711 if ((error
= praccess(vp
, 0, 0, cr
, ct
)) != 0)
2716 rvp
= pnp
->pr_realvp
;
2717 error
= fop_getattr(rvp
, vap
, flags
, cr
, ct
);
2720 if (type
== PR_FD
) {
2721 if (rvp
->v_type
!= VREG
&& rvp
->v_type
!= VDIR
)
2724 vap
->va_mode
&= pnp
->pr_mode
;
2726 if (type
== PR_OBJECT
)
2727 vap
->va_mode
&= 07555;
2728 if (rvp
->v_type
== VDIR
&& !(flags
& ATTR_REAL
)) {
2729 vap
->va_type
= VLNK
;
2738 bzero(vap
, sizeof (*vap
));
2740 * Large Files: Internally proc now uses VPROC to indicate
2741 * a proc file. Since we have been returning VREG through
2742 * fop_getattr() until now, we continue to do this so as
2743 * not to break apps depending on this return value.
2745 vap
->va_type
= (vp
->v_type
== VPROC
) ? VREG
: vp
->v_type
;
2746 vap
->va_mode
= pnp
->pr_mode
;
2747 vap
->va_fsid
= vp
->v_vfsp
->vfs_dev
;
2748 vap
->va_blksize
= DEV_BSIZE
;
2752 if (type
== PR_PROCDIR
) {
2755 vap
->va_nlink
= nproc
+ 2;
2756 vap
->va_nodeid
= (ino64_t
)PRROOTINO
;
2758 vap
->va_atime
= vap
->va_mtime
= vap
->va_ctime
= now
;
2759 vap
->va_size
= (v
.v_proc
+ 2) * PRSDSIZE
;
2760 vap
->va_nblocks
= btod(vap
->va_size
);
2765 * /proc/<pid>/self is a symbolic link, and has no prcommon member
2767 if (type
== PR_SELF
) {
2768 vap
->va_uid
= crgetruid(CRED());
2769 vap
->va_gid
= crgetrgid(CRED());
2770 vap
->va_nodeid
= (ino64_t
)PR_SELF
;
2772 vap
->va_atime
= vap
->va_mtime
= vap
->va_ctime
= now
;
2774 vap
->va_type
= VLNK
;
2780 mutex_exit(&pr_pidlock
);
2783 pcp
= pnp
->pr_common
;
2785 mutex_enter(&p
->p_crlock
);
2786 vap
->va_uid
= crgetruid(p
->p_cred
);
2787 vap
->va_gid
= crgetrgid(p
->p_cred
);
2788 mutex_exit(&p
->p_crlock
);
2791 vap
->va_nodeid
= pnp
->pr_ino
? pnp
->pr_ino
:
2792 pmkino(pcp
->prc_tslot
, pcp
->prc_slot
, pnp
->pr_type
);
2793 if ((pcp
->prc_flags
& PRC_LWP
) && pcp
->prc_tslot
!= -1) {
2794 vap
->va_atime
.tv_sec
= vap
->va_mtime
.tv_sec
=
2795 vap
->va_ctime
.tv_sec
=
2796 p
->p_lwpdir
[pcp
->prc_tslot
].ld_entry
->le_start
;
2797 vap
->va_atime
.tv_nsec
= vap
->va_mtime
.tv_nsec
=
2798 vap
->va_ctime
.tv_nsec
= 0;
2800 user_t
*up
= PTOU(p
);
2801 vap
->va_atime
.tv_sec
= vap
->va_mtime
.tv_sec
=
2802 vap
->va_ctime
.tv_sec
= up
->u_start
.tv_sec
;
2803 vap
->va_atime
.tv_nsec
= vap
->va_mtime
.tv_nsec
=
2804 vap
->va_ctime
.tv_nsec
= up
->u_start
.tv_nsec
;
2809 /* va_nlink: count 'lwp', 'object' and 'fd' directory links */
2811 vap
->va_size
= sizeof (piddir
);
2814 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2815 vap
->va_size
= 2 * PRSDSIZE
;
2817 mutex_exit(&p
->p_lock
);
2818 AS_LOCK_ENTER(as
, RW_WRITER
);
2819 if (as
->a_updatedir
)
2821 vap
->va_size
= (as
->a_sizedir
+ 2) * PRSDSIZE
;
2823 mutex_enter(&p
->p_lock
);
2828 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2829 vap
->va_size
= (P_FINFO(p
)->fi_nfiles
+ 4) * PRSDSIZE
;
2831 mutex_exit(&p
->p_lock
);
2832 AS_LOCK_ENTER(as
, RW_WRITER
);
2833 if (as
->a_updatedir
)
2835 vap
->va_size
= (as
->a_sizedir
+ 4 +
2836 P_FINFO(p
)->fi_nfiles
) * PRSDSIZE
;
2838 mutex_enter(&p
->p_lock
);
2846 vap
->va_type
= VLNK
;
2851 vap
->va_size
= (P_FINFO(p
)->fi_nfiles
+ 2) * PRSDSIZE
;
2855 * va_nlink: count each lwp as a directory link.
2856 * va_size: size of p_lwpdir + 2
2858 vap
->va_nlink
= p
->p_lwpcnt
+ p
->p_zombcnt
+ 2;
2859 vap
->va_size
= (p
->p_lwpdir_sz
+ 2) * PRSDSIZE
;
2863 vap
->va_size
= sizeof (lwpiddir
);
2867 vap
->va_size
= (avl_numnodes(&p
->p_ct_held
) + 2) * PRSDSIZE
;
2871 vap
->va_size
= (ct_ntypes
+ 2) * PRSDSIZE
;
2876 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2879 vap
->va_size
= as
->a_resvsize
;
2882 vap
->va_size
= PR_OBJSIZE(pstatus32_t
, pstatus_t
);
2885 vap
->va_size
= PR_OBJSIZE(prheader32_t
, prheader_t
) +
2886 p
->p_lwpcnt
* PR_OBJSPAN(lwpstatus32_t
, lwpstatus_t
);
2889 vap
->va_size
= PR_OBJSIZE(psinfo32_t
, psinfo_t
);
2892 vap
->va_size
= PR_OBJSIZE(prheader32_t
, prheader_t
) +
2893 (p
->p_lwpcnt
+ p
->p_zombcnt
) *
2894 PR_OBJSPAN(lwpsinfo32_t
, lwpsinfo_t
);
2899 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2902 mutex_exit(&p
->p_lock
);
2903 AS_LOCK_ENTER(as
, RW_WRITER
);
2905 vap
->va_mtime
= as
->a_updatetime
;
2906 if (type
== PR_XMAP
)
2907 vap
->va_size
= prnsegs(as
, 0) *
2908 PR_OBJSIZE(prxmap32_t
, prxmap_t
);
2910 vap
->va_size
= prnsegs(as
, type
== PR_RMAP
) *
2911 PR_OBJSIZE(prmap32_t
, prmap_t
);
2913 mutex_enter(&p
->p_lock
);
2917 mutex_enter(&p
->p_crlock
);
2918 vap
->va_size
= sizeof (prcred_t
);
2919 ngroups
= crgetngroups(p
->p_cred
);
2921 vap
->va_size
+= (ngroups
- 1) * sizeof (gid_t
);
2922 mutex_exit(&p
->p_crlock
);
2925 vap
->va_size
= prgetprivsize();
2928 vap
->va_size
= sizeof (prsecflags_t
);
2931 nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
2932 vap
->va_size
= (nsig
-1) *
2933 PR_OBJSIZE(struct sigaction32
, struct sigaction
);
2936 vap
->va_size
= __KERN_NAUXV_IMPL
* PR_OBJSIZE(auxv32_t
, auxv_t
);
2940 mutex_exit(&p
->p_lock
);
2941 mutex_enter(&p
->p_ldtlock
);
2942 vap
->va_size
= prnldt(p
) * sizeof (struct ssd
);
2943 mutex_exit(&p
->p_ldtlock
);
2944 mutex_enter(&p
->p_lock
);
2948 vap
->va_size
= PR_OBJSIZE(prusage32_t
, prusage_t
);
2951 vap
->va_size
= PR_OBJSIZE(prheader32_t
, prheader_t
) +
2952 (p
->p_lwpcnt
+ 1) * PR_OBJSPAN(prusage32_t
, prusage_t
);
2955 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2959 * We can drop p->p_lock before grabbing the
2960 * address space lock because p->p_as will not
2961 * change while the process is marked P_PR_LOCK.
2963 mutex_exit(&p
->p_lock
);
2964 AS_LOCK_ENTER(as
, RW_WRITER
);
2966 vap
->va_size
= iam32bit
?
2967 prpdsize32(as
) : prpdsize(as
);
2969 vap
->va_size
= prpdsize(as
);
2972 mutex_enter(&p
->p_lock
);
2976 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2979 mutex_exit(&p
->p_lock
);
2980 AS_LOCK_ENTER(as
, RW_WRITER
);
2982 vap
->va_size
= iam32bit
?
2983 oprpdsize32(as
) : oprpdsize(as
);
2985 vap
->va_size
= oprpdsize(as
);
2988 mutex_enter(&p
->p_lock
);
2992 vap
->va_size
= avl_numnodes(&p
->p_warea
) *
2993 PR_OBJSIZE(prwatch32_t
, prwatch_t
);
2996 vap
->va_size
= PR_OBJSIZE(lwpstatus32_t
, lwpstatus_t
);
2999 vap
->va_size
= PR_OBJSIZE(lwpsinfo32_t
, lwpsinfo_t
);
3002 vap
->va_size
= PR_OBJSIZE(prusage32_t
, prusage_t
);
3006 vap
->va_size
= prgetprxregsize(p
);
3011 if (pnp
->pr_common
->prc_thread
->t_lwp
->lwp_spymaster
!= NULL
) {
3012 vap
->va_size
= PR_OBJSIZE(psinfo32_t
, psinfo_t
);
3025 vap
->va_nblocks
= (fsblkcnt64_t
)btod(vap
->va_size
);
3030 praccess(vnode_t
*vp
, int mode
, int flags
, cred_t
*cr
, caller_context_t
*ct
)
3032 prnode_t
*pnp
= VTOP(vp
);
3033 prnodetype_t type
= pnp
->pr_type
;
3041 if ((mode
& VWRITE
) && vn_is_readonly(vp
))
3051 * Disallow write access to the underlying objects.
3052 * Disallow access to underlying non-regular-file fds.
3053 * Disallow access to fds with other than existing open modes.
3055 rvp
= pnp
->pr_realvp
;
3056 vtype
= rvp
->v_type
;
3057 vmode
= pnp
->pr_mode
;
3058 if ((type
== PR_OBJECT
&& (mode
& VWRITE
)) ||
3059 (type
== PR_FD
&& vtype
!= VREG
&& vtype
!= VDIR
) ||
3060 (type
== PR_FD
&& (vmode
& mode
) != mode
&&
3061 secpolicy_proc_access(cr
) != 0))
3063 return (fop_access(rvp
, mode
, flags
, cr
, ct
));
3065 case PR_PSINFO
: /* these files can be read by anyone */
3074 mutex_exit(&pr_pidlock
);
3082 * Except for the world-readable files above,
3083 * only /proc/pid exists if the process is a zombie.
3085 if ((error
= prlock(pnp
,
3086 (type
== PR_PIDDIR
)? ZYES
: ZNO
)) != 0)
3088 p
= pnp
->pr_common
->prc_proc
;
3090 error
= priv_proc_cred_perm(cr
, p
, NULL
, mode
);
3092 if (error
!= 0 || p
== curproc
|| (p
->p_flag
& SSYS
) ||
3093 p
->p_as
== &kas
|| (xvp
= p
->p_exec
) == NULL
) {
3097 * Determine if the process's executable is readable.
3098 * We have to drop p->p_lock before the secpolicy
3099 * and VOP operation.
3103 if (secpolicy_proc_access(cr
) != 0)
3104 error
= fop_access(xvp
, VREAD
, 0, cr
, ct
);
3112 if (type
== PR_CURDIR
|| type
== PR_ROOTDIR
) {
3114 * Final access check on the underlying directory vnode.
3116 return (fop_access(pnp
->pr_realvp
, mode
, flags
, cr
, ct
));
3120 * Visceral revulsion: For compatibility with old /proc,
3121 * allow the /proc/<pid> directory to be opened for writing.
3123 vmode
= pnp
->pr_mode
;
3124 if (type
== PR_PIDDIR
)
3126 if ((vmode
& mode
) != mode
)
3127 error
= secpolicy_proc_access(cr
);
3132 * Array of lookup functions, indexed by /proc file type.
3134 static vnode_t
*pr_lookup_notdir(), *pr_lookup_procdir(), *pr_lookup_piddir(),
3135 *pr_lookup_objectdir(), *pr_lookup_lwpdir(), *pr_lookup_lwpiddir(),
3136 *pr_lookup_fddir(), *pr_lookup_pathdir(), *pr_lookup_tmpldir(),
3139 static vnode_t
*(*pr_lookup_function
[PR_NFILES
])() = {
3140 pr_lookup_procdir
, /* /proc */
3141 pr_lookup_notdir
, /* /proc/self */
3142 pr_lookup_piddir
, /* /proc/<pid> */
3143 pr_lookup_notdir
, /* /proc/<pid>/as */
3144 pr_lookup_notdir
, /* /proc/<pid>/ctl */
3145 pr_lookup_notdir
, /* /proc/<pid>/status */
3146 pr_lookup_notdir
, /* /proc/<pid>/lstatus */
3147 pr_lookup_notdir
, /* /proc/<pid>/psinfo */
3148 pr_lookup_notdir
, /* /proc/<pid>/lpsinfo */
3149 pr_lookup_notdir
, /* /proc/<pid>/map */
3150 pr_lookup_notdir
, /* /proc/<pid>/rmap */
3151 pr_lookup_notdir
, /* /proc/<pid>/xmap */
3152 pr_lookup_notdir
, /* /proc/<pid>/cred */
3153 pr_lookup_notdir
, /* /proc/<pid>/sigact */
3154 pr_lookup_notdir
, /* /proc/<pid>/auxv */
3156 pr_lookup_notdir
, /* /proc/<pid>/ldt */
3158 pr_lookup_notdir
, /* /proc/<pid>/usage */
3159 pr_lookup_notdir
, /* /proc/<pid>/lusage */
3160 pr_lookup_notdir
, /* /proc/<pid>/pagedata */
3161 pr_lookup_notdir
, /* /proc/<pid>/watch */
3162 pr_lookup_notdir
, /* /proc/<pid>/cwd */
3163 pr_lookup_notdir
, /* /proc/<pid>/root */
3164 pr_lookup_fddir
, /* /proc/<pid>/fd */
3165 pr_lookup_notdir
, /* /proc/<pid>/fd/nn */
3166 pr_lookup_objectdir
, /* /proc/<pid>/object */
3167 pr_lookup_notdir
, /* /proc/<pid>/object/xxx */
3168 pr_lookup_lwpdir
, /* /proc/<pid>/lwp */
3169 pr_lookup_lwpiddir
, /* /proc/<pid>/lwp/<lwpid> */
3170 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
3171 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
3172 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3173 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3174 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/xregs */
3175 pr_lookup_tmpldir
, /* /proc/<pid>/lwp/<lwpid>/templates */
3176 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3177 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/spymaster */
3178 pr_lookup_notdir
, /* /proc/<pid>/priv */
3179 pr_lookup_pathdir
, /* /proc/<pid>/path */
3180 pr_lookup_notdir
, /* /proc/<pid>/path/xxx */
3181 pr_lookup_ctdir
, /* /proc/<pid>/contracts */
3182 pr_lookup_notdir
, /* /proc/<pid>/contracts/<ctid> */
3183 pr_lookup_notdir
, /* /proc/<pid>/secflags */
3184 pr_lookup_notdir
, /* old process file */
3185 pr_lookup_notdir
, /* old lwp file */
3186 pr_lookup_notdir
, /* old pagedata file */
3190 prlookup(vnode_t
*dp
, char *comp
, vnode_t
**vpp
, pathname_t
*pathp
,
3191 int flags
, vnode_t
*rdir
, cred_t
*cr
, caller_context_t
*ct
,
3192 int *direntflags
, pathname_t
*realpnp
)
3194 prnode_t
*pnp
= VTOP(dp
);
3195 prnodetype_t type
= pnp
->pr_type
;
3198 ASSERT(dp
->v_type
== VDIR
);
3199 ASSERT(type
< PR_NFILES
);
3201 if (type
!= PR_PROCDIR
&& strcmp(comp
, "..") == 0) {
3202 VN_HOLD(pnp
->pr_parent
);
3203 *vpp
= pnp
->pr_parent
;
3207 if (*comp
== '\0' ||
3208 strcmp(comp
, ".") == 0 || strcmp(comp
, "..") == 0) {
3217 /* restrict lookup permission to owner or root */
3218 if ((error
= praccess(dp
, VEXEC
, 0, cr
, ct
)) != 0)
3223 * Performing a VOP_LOOKUP on the underlying vnode and emitting
3224 * the resulting vnode, without encapsulation, as our own is a
3225 * very special case when it comes to the assumptions built
3228 * Since the resulting vnode is highly likely to be at some
3229 * abitrary position in another filesystem, we insist that the
3230 * VTRAVERSE flag is set on the parent. This prevents things
3231 * such as the v_path freshness logic from mistaking the
3232 * resulting vnode as a "real" child of the parent, rather than
3233 * a consequence of this "procfs wormhole".
3235 * Failure to establish such protections can lead to
3236 * incorrectly calculated v_paths being set on nodes reached
3237 * through these lookups.
3239 ASSERT((dp
->v_flag
& VTRAVERSE
) != 0);
3241 dp
= pnp
->pr_realvp
;
3242 return (fop_lookup(dp
, comp
, vpp
, pathp
, flags
, rdir
, cr
, ct
,
3243 direntflags
, realpnp
));
3248 if ((type
== PR_OBJECTDIR
|| type
== PR_FDDIR
|| type
== PR_PATHDIR
) &&
3249 (error
= praccess(dp
, VEXEC
, 0, cr
, ct
)) != 0)
3252 /* XXX - Do we need to pass ct, direntflags, or realpnp? */
3253 *vpp
= (pr_lookup_function
[type
](dp
, comp
));
3255 return ((*vpp
== NULL
) ? ENOENT
: 0);
3260 prcreate(vnode_t
*dp
, char *comp
, vattr_t
*vap
, vcexcl_t excl
,
3261 int mode
, vnode_t
**vpp
, cred_t
*cr
, int flag
, caller_context_t
*ct
,
3266 if ((error
= prlookup(dp
, comp
, vpp
, NULL
, 0, NULL
, cr
,
3267 ct
, NULL
, NULL
)) != 0) {
3268 if (error
== ENOENT
) {
3269 /* One can't O_CREAT nonexistent files in /proc. */
3276 /* Disallow the O_EXCL case */
3278 } else if ((error
= praccess(*vpp
, mode
, 0, cr
, ct
)) == 0) {
3279 /* Before proceeding, handle O_TRUNC if necessary. */
3280 if (vap
->va_mask
& AT_SIZE
) {
3283 if (vp
->v_type
== VDIR
) {
3284 /* Only allow O_TRUNC on files */
3286 } else if (vp
->v_type
!= VPROC
||
3287 VTOP(vp
)->pr_type
!= PR_FD
) {
3289 * Disallow for files outside of the
3290 * /proc/<pid>/fd/<n> entries
3296 vp
= VTOP(vp
)->pr_realvp
;
3297 mask
= vap
->va_mask
;
3298 vap
->va_mask
= AT_SIZE
;
3299 error
= fop_setattr(vp
, vap
, 0, cr
, ct
);
3300 vap
->va_mask
= mask
;
3314 pr_lookup_notdir(vnode_t
*dp
, char *comp
)
3320 * Find or construct a process vnode for the given pid.
3323 pr_lookup_procdir(vnode_t
*dp
, char *comp
)
3332 ASSERT(VTOP(dp
)->pr_type
== PR_PROCDIR
);
3334 if (strcmp(comp
, "self") == 0) {
3335 pnp
= prgetnode(dp
, PR_SELF
);
3339 while ((c
= *comp
++) != '\0') {
3340 if (c
< '0' || c
> '9')
3342 pid
= 10*pid
+ c
- '0';
3348 pnp
= prgetnode(dp
, PR_PIDDIR
);
3350 mutex_enter(&pidlock
);
3351 if ((p
= prfind(pid
)) == NULL
|| p
->p_stat
== SIDL
) {
3352 mutex_exit(&pidlock
);
3356 ASSERT(p
->p_stat
!= 0);
3358 /* NOTE: we're holding pidlock across the policy call. */
3359 if (secpolicy_basic_procinfo(CRED(), p
, curproc
) != 0) {
3360 mutex_exit(&pidlock
);
3365 mutex_enter(&p
->p_lock
);
3366 mutex_exit(&pidlock
);
3369 * If a process vnode already exists and it is not invalid
3370 * and it was created by the current process and it belongs
3371 * to the same /proc mount point as our parent vnode, then
3372 * just use it and discard the newly-allocated prnode.
3374 for (vp
= p
->p_trace
; vp
!= NULL
; vp
= VTOP(vp
)->pr_next
) {
3375 if (!(VTOP(VTOP(vp
)->pr_pidfile
)->pr_flags
& PR_INVAL
) &&
3376 VTOP(vp
)->pr_owner
== curproc
&&
3377 vp
->v_vfsp
== dp
->v_vfsp
) {
3378 ASSERT(!(VTOP(vp
)->pr_flags
& PR_INVAL
));
3381 mutex_exit(&p
->p_lock
);
3385 pnp
->pr_owner
= curproc
;
3388 * prgetnode() initialized most of the prnode.
3391 pcp
= pnp
->pr_common
; /* the newly-allocated prcommon struct */
3392 if ((vp
= p
->p_trace
) != NULL
) {
3393 /* discard the new prcommon and use the existing prcommon */
3395 pcp
= VTOP(vp
)->pr_common
;
3396 mutex_enter(&pcp
->prc_mutex
);
3397 ASSERT(pcp
->prc_refcnt
> 0);
3399 mutex_exit(&pcp
->prc_mutex
);
3400 pnp
->pr_common
= pcp
;
3402 /* initialize the new prcommon struct */
3403 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
3404 pcp
->prc_flags
|= PRC_SYS
;
3405 if (p
->p_stat
== SZOMB
)
3406 pcp
->prc_flags
|= PRC_DESTROY
;
3408 pcp
->prc_datamodel
= p
->p_model
;
3409 pcp
->prc_pid
= p
->p_pid
;
3410 pcp
->prc_slot
= p
->p_slot
;
3412 pnp
->pr_pcommon
= pcp
;
3413 pnp
->pr_parent
= dp
;
3416 * Link in the old, invalid directory vnode so we
3417 * can later determine the last close of the file.
3419 pnp
->pr_next
= p
->p_trace
;
3420 p
->p_trace
= dp
= PTOV(pnp
);
3423 * Kludge for old /proc: initialize the PR_PIDFILE as well.
3425 vp
= pnp
->pr_pidfile
;
3427 pnp
->pr_ino
= ptoi(pcp
->prc_pid
);
3428 pnp
->pr_common
= pcp
;
3429 pnp
->pr_pcommon
= pcp
;
3430 pnp
->pr_parent
= dp
;
3431 pnp
->pr_next
= p
->p_plist
;
3434 mutex_exit(&p
->p_lock
);
3439 pr_lookup_piddir(vnode_t
*dp
, char *comp
)
3441 prnode_t
*dpnp
= VTOP(dp
);
3448 enum prnodetype type
;
3450 ASSERT(dpnp
->pr_type
== PR_PIDDIR
);
3452 for (i
= 0; i
< NPIDDIRFILES
; i
++) {
3453 /* Skip "." and ".." */
3454 dirp
= &piddir
[i
+2];
3455 if (strcmp(comp
, dirp
->d_name
) == 0)
3459 if (i
>= NPIDDIRFILES
)
3462 type
= (int)dirp
->d_ino
;
3463 pnp
= prgetnode(dp
, type
);
3465 p
= pr_p_lock(dpnp
);
3466 mutex_exit(&pr_pidlock
);
3471 if (dpnp
->pr_pcommon
->prc_flags
& PRC_DESTROY
) {
3487 vp
= (type
== PR_CURDIR
)? up
->u_cdir
:
3488 (up
->u_rdir
? up
->u_rdir
: rootdir
);
3491 /* can't happen(?) */
3497 * Fill in the prnode so future references will
3498 * be able to find the underlying object's vnode.
3501 pnp
->pr_realvp
= vp
;
3502 PTOV(pnp
)->v_flag
|= VTRAVERSE
;
3508 mutex_enter(&dpnp
->pr_mutex
);
3510 if ((vp
= dpnp
->pr_files
[i
]) != NULL
&&
3511 !(VTOP(vp
)->pr_flags
& PR_INVAL
)) {
3513 mutex_exit(&dpnp
->pr_mutex
);
3520 * prgetnode() initialized most of the prnode.
3523 pnp
->pr_common
= dpnp
->pr_common
;
3524 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
3525 pnp
->pr_parent
= dp
;
3529 dpnp
->pr_files
[i
] = vp
= PTOV(pnp
);
3532 * Link new vnode into list of all /proc vnodes for the process.
3534 if (vp
->v_type
== VPROC
) {
3535 pnp
->pr_next
= p
->p_plist
;
3538 mutex_exit(&dpnp
->pr_mutex
);
3544 pr_lookup_objectdir(vnode_t
*dp
, char *comp
)
3546 prnode_t
*dpnp
= VTOP(dp
);
3554 ASSERT(dpnp
->pr_type
== PR_OBJECTDIR
);
3556 pnp
= prgetnode(dp
, PR_OBJECT
);
3558 if (prlock(dpnp
, ZNO
) != 0) {
3562 p
= dpnp
->pr_common
->prc_proc
;
3563 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
3570 * We drop p_lock before grabbing the address space lock
3571 * in order to avoid a deadlock with the clock thread.
3572 * The process will not disappear and its address space
3573 * will not change because it is marked P_PR_LOCK.
3575 mutex_exit(&p
->p_lock
);
3576 AS_LOCK_ENTER(as
, RW_READER
);
3577 if ((seg
= AS_SEGFIRST(as
)) == NULL
) {
3581 if (strcmp(comp
, "a.out") == 0) {
3587 * Manufacture a filename for the "object" directory.
3589 vattr
.va_mask
= AT_FSID
|AT_NODEID
;
3590 if (seg
->s_ops
== &segvn_ops
&&
3591 segop_getvp(seg
, seg
->s_base
, &vp
) == 0 &&
3592 vp
!= NULL
&& vp
->v_type
== VREG
&&
3593 fop_getattr(vp
, &vattr
, 0, CRED(), NULL
) == 0) {
3596 if (vp
== p
->p_exec
) /* "a.out" */
3598 pr_object_name(name
, vp
, &vattr
);
3599 if (strcmp(name
, comp
) == 0)
3602 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3610 mutex_enter(&p
->p_lock
);
3617 * Fill in the prnode so future references will
3618 * be able to find the underlying object's vnode.
3619 * Don't link this prnode into the list of all
3620 * prnodes for the process; this is a one-use node.
3621 * Its use is entirely to catch and fail opens for writing.
3623 pnp
->pr_realvp
= vp
;
3631 * Find or construct an lwp vnode for the given lwpid.
3634 pr_lookup_lwpdir(vnode_t
*dp
, char *comp
)
3636 id_t tid
; /* same type as t->t_tid */
3638 prnode_t
*dpnp
= VTOP(dp
);
3649 ASSERT(dpnp
->pr_type
== PR_LWPDIR
);
3652 if (strcmp(comp
, "agent") == 0)
3656 while ((c
= *comp
++) != '\0') {
3659 if (c
< '0' || c
> '9')
3662 tid
= 10*tid
+ c
- '0';
3663 if (tid
/10 != otid
) /* integer overflow */
3668 pnp
= prgetnode(dp
, PR_LWPIDDIR
);
3670 p
= pr_p_lock(dpnp
);
3671 mutex_exit(&pr_pidlock
);
3678 if ((t
= p
->p_agenttp
) == NULL
)
3683 lep
= p
->p_lwpdir
[tslot
].ld_entry
;
3686 if ((ldp
= lwp_hash_lookup(p
, tid
)) == NULL
)
3689 tslot
= (int)(ldp
- p
->p_lwpdir
);
3690 lep
= ldp
->ld_entry
;
3701 * If an lwp vnode already exists and it is not invalid
3702 * and it was created by the current process and it belongs
3703 * to the same /proc mount point as our parent vnode, then
3704 * just use it and discard the newly-allocated prnode.
3706 for (vp
= lep
->le_trace
; vp
!= NULL
; vp
= VTOP(vp
)->pr_next
) {
3707 if (!(VTOP(vp
)->pr_flags
& PR_INVAL
) &&
3708 VTOP(vp
)->pr_owner
== curproc
&&
3709 vp
->v_vfsp
== dp
->v_vfsp
) {
3716 pnp
->pr_owner
= curproc
;
3719 * prgetnode() initialized most of the prnode.
3722 pcp
= pnp
->pr_common
; /* the newly-allocated prcommon struct */
3723 if ((vp
= lep
->le_trace
) != NULL
) {
3724 /* discard the new prcommon and use the existing prcommon */
3726 pcp
= VTOP(vp
)->pr_common
;
3727 mutex_enter(&pcp
->prc_mutex
);
3728 ASSERT(pcp
->prc_refcnt
> 0);
3730 mutex_exit(&pcp
->prc_mutex
);
3731 pnp
->pr_common
= pcp
;
3733 /* initialize the new prcommon struct */
3734 pcp
->prc_flags
|= PRC_LWP
;
3735 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
3736 pcp
->prc_flags
|= PRC_SYS
;
3737 if ((t
= lep
->le_thread
) == NULL
)
3738 pcp
->prc_flags
|= PRC_DESTROY
;
3740 pcp
->prc_datamodel
= dpnp
->pr_pcommon
->prc_datamodel
;
3741 pcp
->prc_pid
= p
->p_pid
;
3742 pcp
->prc_slot
= p
->p_slot
;
3743 pcp
->prc_thread
= t
;
3745 pcp
->prc_tslot
= tslot
;
3747 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
3748 pnp
->pr_parent
= dp
;
3751 * Link in the old, invalid directory vnode so we
3752 * can later determine the last close of the file.
3754 pnp
->pr_next
= lep
->le_trace
;
3755 lep
->le_trace
= vp
= PTOV(pnp
);
3761 pr_lookup_lwpiddir(vnode_t
*dp
, char *comp
)
3763 prnode_t
*dpnp
= VTOP(dp
);
3769 enum prnodetype type
;
3771 ASSERT(dpnp
->pr_type
== PR_LWPIDDIR
);
3773 for (i
= 0; i
< NLWPIDDIRFILES
; i
++) {
3774 /* Skip "." and ".." */
3775 dirp
= &lwpiddir
[i
+2];
3776 if (strcmp(comp
, dirp
->d_name
) == 0)
3780 if (i
>= NLWPIDDIRFILES
)
3783 type
= (int)dirp
->d_ino
;
3784 pnp
= prgetnode(dp
, type
);
3786 p
= pr_p_lock(dpnp
);
3787 mutex_exit(&pr_pidlock
);
3792 if (dpnp
->pr_common
->prc_flags
& PRC_DESTROY
) {
3794 * Only the lwpsinfo file is present for zombie lwps.
3795 * Nothing is present if the lwp has been reaped.
3797 if (dpnp
->pr_common
->prc_tslot
== -1 ||
3798 type
!= PR_LWPSINFO
) {
3806 mutex_enter(&dpnp
->pr_mutex
);
3808 if ((vp
= dpnp
->pr_files
[i
]) != NULL
&&
3809 !(VTOP(vp
)->pr_flags
& PR_INVAL
)) {
3811 mutex_exit(&dpnp
->pr_mutex
);
3818 * prgetnode() initialized most of the prnode.
3821 pnp
->pr_common
= dpnp
->pr_common
;
3822 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
3823 pnp
->pr_parent
= dp
;
3827 dpnp
->pr_files
[i
] = vp
= PTOV(pnp
);
3830 * Link new vnode into list of all /proc vnodes for the process.
3832 if (vp
->v_type
== VPROC
) {
3833 pnp
->pr_next
= p
->p_plist
;
3836 mutex_exit(&dpnp
->pr_mutex
);
3842 * Lookup one of the process's open files.
3845 pr_lookup_fddir(vnode_t
*dp
, char *comp
)
3847 prnode_t
*dpnp
= VTOP(dp
);
3857 ASSERT(dpnp
->pr_type
== PR_FDDIR
);
3860 while ((c
= *comp
++) != '\0') {
3862 if (c
< '0' || c
> '9')
3865 fd
= 10*fd
+ c
- '0';
3866 if (fd
/10 != ofd
) /* integer overflow */
3870 pnp
= prgetnode(dp
, PR_FD
);
3872 if (prlock(dpnp
, ZNO
) != 0) {
3876 p
= dpnp
->pr_common
->prc_proc
;
3877 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
3884 mutex_exit(&p
->p_lock
);
3885 mutex_enter(&fip
->fi_lock
);
3886 if (fd
< fip
->fi_nfiles
) {
3887 UF_ENTER(ufp
, fip
, fd
);
3888 if ((fp
= ufp
->uf_file
) != NULL
) {
3889 pnp
->pr_mode
= 07111;
3890 if (fp
->f_flag
& FREAD
)
3891 pnp
->pr_mode
|= 0444;
3892 if (fp
->f_flag
& FWRITE
)
3893 pnp
->pr_mode
|= 0222;
3899 mutex_exit(&fip
->fi_lock
);
3900 mutex_enter(&p
->p_lock
);
3907 * Fill in the prnode so future references will
3908 * be able to find the underlying object's vnode.
3909 * Don't link this prnode into the list of all
3910 * prnodes for the process; this is a one-use node.
3912 pnp
->pr_realvp
= vp
;
3913 pnp
->pr_parent
= dp
; /* needed for prlookup */
3916 if (pnp
->pr_realvp
->v_type
== VDIR
) {
3918 vp
->v_flag
|= VTRAVERSE
;
3926 pr_lookup_pathdir(vnode_t
*dp
, char *comp
)
3928 prnode_t
*dpnp
= VTOP(dp
);
3932 uint_t fd
, flags
= 0;
3936 enum { NAME_FD
, NAME_OBJECT
, NAME_ROOT
, NAME_CWD
, NAME_UNKNOWN
} type
;
3940 struct as
*as
= NULL
;
3943 ASSERT(dpnp
->pr_type
== PR_PATHDIR
);
3946 * First, check if this is a numeric entry, in which case we have a
3952 while ((c
= *tmp
++) != '\0') {
3954 if (c
< '0' || c
> '9') {
3955 type
= NAME_UNKNOWN
;
3959 fd
= 10*fd
+ c
- '0';
3960 if (fd
/10 != ofd
) { /* integer overflow */
3961 type
= NAME_UNKNOWN
;
3967 * Next, see if it is one of the special values {root, cwd}.
3969 if (type
== NAME_UNKNOWN
) {
3970 if (strcmp(comp
, "root") == 0)
3972 else if (strcmp(comp
, "cwd") == 0)
3977 * Grab the necessary data from the process
3979 if (prlock(dpnp
, ZNO
) != 0)
3981 p
= dpnp
->pr_common
->prc_proc
;
3987 if ((vp
= PTOU(p
)->u_rdir
) == NULL
)
3988 vp
= p
->p_zone
->zone_rootvp
;
3992 vp
= PTOU(p
)->u_cdir
;
3996 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
4001 mutex_exit(&p
->p_lock
);
4004 * Determine if this is an object entry
4006 if (type
== NAME_UNKNOWN
) {
4008 * Start with the inode index immediately after the number of
4011 mutex_enter(&fip
->fi_lock
);
4012 idx
= fip
->fi_nfiles
+ 4;
4013 mutex_exit(&fip
->fi_lock
);
4015 if (strcmp(comp
, "a.out") == 0) {
4016 if (p
->p_execdir
!= NULL
) {
4027 AS_LOCK_ENTER(as
, RW_READER
);
4028 if ((seg
= AS_SEGFIRST(as
)) != NULL
) {
4031 * Manufacture a filename for the
4032 * "object" directory.
4034 vattr
.va_mask
= AT_FSID
|AT_NODEID
;
4035 if (seg
->s_ops
== &segvn_ops
&&
4036 segop_getvp(seg
, seg
->s_base
, &vp
)
4038 vp
!= NULL
&& vp
->v_type
== VREG
&&
4039 fop_getattr(vp
, &vattr
, 0, CRED(),
4043 if (vp
== p
->p_exec
)
4046 pr_object_name(name
, vp
,
4048 if (strcmp(name
, comp
) == 0)
4051 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
4068 mutex_enter(&fip
->fi_lock
);
4069 if (fd
< fip
->fi_nfiles
) {
4070 UF_ENTER(ufp
, fip
, fd
);
4071 if (ufp
->uf_file
!= NULL
) {
4072 vp
= ufp
->uf_file
->f_vnode
;
4077 mutex_exit(&fip
->fi_lock
);
4092 mutex_enter(&p
->p_lock
);
4096 pnp
= prgetnode(dp
, PR_PATH
);
4098 pnp
->pr_flags
|= flags
;
4099 pnp
->pr_common
= dpnp
->pr_common
;
4100 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
4101 pnp
->pr_realvp
= vp
;
4102 pnp
->pr_parent
= dp
; /* needed for prlookup */
4103 pnp
->pr_ino
= pmkino(idx
, dpnp
->pr_common
->prc_slot
, PR_PATH
);
4113 * Look up one of the process's active templates.
4116 pr_lookup_tmpldir(vnode_t
*dp
, char *comp
)
4118 prnode_t
*dpnp
= VTOP(dp
);
4124 ASSERT(dpnp
->pr_type
== PR_TMPLDIR
);
4126 for (i
= 0; i
< ct_ntypes
; i
++)
4127 if (strcmp(comp
, ct_types
[i
]->ct_type_name
) == 0)
4132 pnp
= prgetnode(dp
, PR_TMPL
);
4134 if (prlock(dpnp
, ZNO
) != 0) {
4138 p
= dpnp
->pr_common
->prc_proc
;
4139 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
||
4140 (dpnp
->pr_common
->prc_flags
& (PRC_DESTROY
| PRC_LWP
)) != PRC_LWP
) {
4145 if (ttolwp(dpnp
->pr_common
->prc_thread
)->lwp_ct_active
[i
] != NULL
) {
4146 pnp
->pr_common
= dpnp
->pr_common
;
4147 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
4148 pnp
->pr_parent
= dp
;
4161 * Look up one of the contracts owned by the process.
4164 pr_lookup_ctdir(vnode_t
*dp
, char *comp
)
4166 prnode_t
*dpnp
= VTOP(dp
);
4174 ASSERT(dpnp
->pr_type
== PR_CTDIR
);
4176 while ((c
= *comp
++) != '\0') {
4178 if (c
< '0' || c
> '9')
4181 id
= 10 * id
+ c
- '0';
4182 if (id
/ 10 != oid
) /* integer overflow */
4187 * Search all contracts; we'll filter below.
4189 ct
= contract_ptr(id
, GLOBAL_ZONEUNIQID
);
4193 pnp
= prgetnode(dp
, PR_CT
);
4195 if (prlock(dpnp
, ZNO
) != 0) {
4200 p
= dpnp
->pr_common
->prc_proc
;
4202 * We only allow lookups of contracts owned by this process, or,
4203 * if we are zsched and this is a zone's procfs, contracts on
4204 * stuff in the zone which are held by processes or contracts
4205 * outside the zone. (see logic in contract_status_common)
4207 if ((ct
->ct_owner
!= p
) &&
4208 !(p
== VTOZONE(dp
)->zone_zsched
&& ct
->ct_state
< CTS_ORPHAN
&&
4209 VTOZONE(dp
)->zone_uniqid
== contract_getzuniqid(ct
) &&
4210 VTOZONE(dp
)->zone_uniqid
!= GLOBAL_ZONEUNIQID
&&
4211 ct
->ct_czuniqid
== GLOBAL_ZONEUNIQID
)) {
4217 pnp
->pr_common
= dpnp
->pr_common
;
4218 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
4219 pnp
->pr_contract
= ct
;
4220 pnp
->pr_parent
= dp
;
4221 pnp
->pr_ino
= pmkino(id
, pnp
->pr_common
->prc_slot
, PR_CT
);
4230 * Construct an lwp vnode for the old /proc interface.
4231 * We stand on our head to make the /proc plumbing correct.
4234 prlwpnode(prnode_t
*pnp
, uint_t tid
)
4243 * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode.
4245 if (pnp
->pr_type
== PR_PIDFILE
) {
4246 dp
= pnp
->pr_parent
; /* /proc/<pid> */
4248 vp
= pr_lookup_piddir(dp
, "lwp");
4250 if ((dp
= vp
) == NULL
) /* /proc/<pid>/lwp */
4252 } else if (pnp
->pr_type
== PR_LWPIDFILE
) {
4253 dp
= pnp
->pr_parent
; /* /proc/<pid>/lwp/<lwpid> */
4254 dp
= VTOP(dp
)->pr_parent
; /* /proc/<pid>/lwp */
4260 (void) pr_u32tos(tid
, comp
, sizeof (comp
));
4261 vp
= pr_lookup_lwpdir(dp
, comp
);
4263 if ((dp
= vp
) == NULL
)
4266 pnp
= prgetnode(dp
, PR_LWPIDFILE
);
4270 * prgetnode() initialized most of the prnode.
4273 pcp
= VTOP(dp
)->pr_common
;
4274 pnp
->pr_ino
= ptoi(pcp
->prc_pid
);
4275 pnp
->pr_common
= pcp
;
4276 pnp
->pr_pcommon
= VTOP(dp
)->pr_pcommon
;
4277 pnp
->pr_parent
= dp
;
4279 * Link new vnode into list of all /proc vnodes for the process.
4282 mutex_exit(&pr_pidlock
);
4287 } else if (pcp
->prc_thread
== NULL
) {
4293 pnp
->pr_next
= p
->p_plist
;
4303 static uint32_t nprnode
;
4304 static uint32_t nprcommon
;
4306 #define INCREMENT(x) atomic_inc_32(&x);
4307 #define DECREMENT(x) atomic_dec_32(&x);
4311 #define INCREMENT(x)
4312 #define DECREMENT(x)
4317 * New /proc vnode required; allocate it and fill in most of the fields.
4320 prgetnode(vnode_t
*dp
, prnodetype_t type
)
4328 pnp
= kmem_zalloc(sizeof (prnode_t
), KM_SLEEP
);
4330 mutex_init(&pnp
->pr_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
4331 pnp
->pr_type
= type
;
4333 pnp
->pr_vnode
= vn_alloc(KM_SLEEP
);
4336 vp
->v_flag
= VNOCACHE
|VNOMAP
|VNOSWAP
|VNOMOUNT
;
4337 vn_setops(vp
, &prvnodeops
);
4338 vp
->v_vfsp
= dp
->v_vfsp
;
4340 vp
->v_data
= (caddr_t
)pnp
;
4346 * We need a prcommon and a files array for each of these.
4348 INCREMENT(nprcommon
);
4350 pcp
= kmem_zalloc(sizeof (prcommon_t
), KM_SLEEP
);
4351 pcp
->prc_refcnt
= 1;
4352 pnp
->pr_common
= pcp
;
4353 mutex_init(&pcp
->prc_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
4354 cv_init(&pcp
->prc_wait
, NULL
, CV_DEFAULT
, NULL
);
4356 nfiles
= (type
== PR_PIDDIR
)? NPIDDIRFILES
: NLWPIDDIRFILES
;
4358 kmem_zalloc(nfiles
* sizeof (vnode_t
*), KM_SLEEP
);
4362 * Mode should be read-search by all, but we cannot so long
4363 * as we must support compatibility mode with old /proc.
4364 * Make /proc/<pid> be read by owner only, search by all.
4365 * Make /proc/<pid>/lwp/<lwpid> read-search by all. Also,
4366 * set VDIROPEN on /proc/<pid> so it can be opened for writing.
4368 if (type
== PR_PIDDIR
) {
4369 /* kludge for old /proc interface */
4370 prnode_t
*xpnp
= prgetnode(dp
, PR_PIDFILE
);
4371 pnp
->pr_pidfile
= PTOV(xpnp
);
4372 pnp
->pr_mode
= 0511;
4373 vp
->v_flag
|= VDIROPEN
;
4375 pnp
->pr_mode
= 0555;
4388 pnp
->pr_mode
= 0500; /* read-search by owner only */
4393 pnp
->pr_mode
= 0500; /* read-search by owner only */
4399 pnp
->pr_mode
= 0777;
4404 pnp
->pr_mode
= 0555; /* read-search by all */
4409 pnp
->pr_mode
= 0600; /* read-write by owner only */
4414 pnp
->pr_mode
= 0200; /* write-only by owner only */
4419 pnp
->pr_mode
= 0600; /* read-write by owner only */
4428 pnp
->pr_mode
= 0444; /* read-only by all */
4432 pnp
->pr_mode
= 0400; /* read-only by owner only */
4440 * Free the storage obtained from prgetnode().
4443 prfreenode(prnode_t
*pnp
)
4448 vn_invalid(PTOV(pnp
));
4450 mutex_destroy(&pnp
->pr_mutex
);
4452 switch (pnp
->pr_type
) {
4454 /* kludge for old /proc interface */
4455 if (pnp
->pr_pidfile
!= NULL
) {
4456 prfreenode(VTOP(pnp
->pr_pidfile
));
4457 pnp
->pr_pidfile
= NULL
;
4462 * We allocated a prcommon and a files array for each of these.
4464 prfreecommon(pnp
->pr_common
);
4465 nfiles
= (pnp
->pr_type
== PR_PIDDIR
)?
4466 NPIDDIRFILES
: NLWPIDDIRFILES
;
4467 kmem_free(pnp
->pr_files
, nfiles
* sizeof (vnode_t
*));
4473 * If there is an underlying vnode, be sure
4474 * to release it after freeing the prnode.
4476 vp
= pnp
->pr_realvp
;
4477 kmem_free(pnp
, sizeof (*pnp
));
4485 * Free a prcommon structure, if the reference count reaches zero.
4488 prfreecommon(prcommon_t
*pcp
)
4490 mutex_enter(&pcp
->prc_mutex
);
4491 ASSERT(pcp
->prc_refcnt
> 0);
4492 if (--pcp
->prc_refcnt
!= 0)
4493 mutex_exit(&pcp
->prc_mutex
);
4495 mutex_exit(&pcp
->prc_mutex
);
4496 ASSERT(pcp
->prc_pollhead
.ph_list
== NULL
);
4497 ASSERT(pcp
->prc_refcnt
== 0);
4498 ASSERT(pcp
->prc_selfopens
== 0 && pcp
->prc_writers
== 0);
4499 mutex_destroy(&pcp
->prc_mutex
);
4500 cv_destroy(&pcp
->prc_wait
);
4501 kmem_free(pcp
, sizeof (prcommon_t
));
4502 DECREMENT(nprcommon
);
4507 * Array of readdir functions, indexed by /proc file type.
4509 static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(),
4510 pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(),
4511 pr_readdir_fddir(), pr_readdir_pathdir(), pr_readdir_tmpldir(),
4514 static int (*pr_readdir_function
[PR_NFILES
])() = {
4515 pr_readdir_procdir
, /* /proc */
4516 pr_readdir_notdir
, /* /proc/self */
4517 pr_readdir_piddir
, /* /proc/<pid> */
4518 pr_readdir_notdir
, /* /proc/<pid>/as */
4519 pr_readdir_notdir
, /* /proc/<pid>/ctl */
4520 pr_readdir_notdir
, /* /proc/<pid>/status */
4521 pr_readdir_notdir
, /* /proc/<pid>/lstatus */
4522 pr_readdir_notdir
, /* /proc/<pid>/psinfo */
4523 pr_readdir_notdir
, /* /proc/<pid>/lpsinfo */
4524 pr_readdir_notdir
, /* /proc/<pid>/map */
4525 pr_readdir_notdir
, /* /proc/<pid>/rmap */
4526 pr_readdir_notdir
, /* /proc/<pid>/xmap */
4527 pr_readdir_notdir
, /* /proc/<pid>/cred */
4528 pr_readdir_notdir
, /* /proc/<pid>/sigact */
4529 pr_readdir_notdir
, /* /proc/<pid>/auxv */
4531 pr_readdir_notdir
, /* /proc/<pid>/ldt */
4533 pr_readdir_notdir
, /* /proc/<pid>/usage */
4534 pr_readdir_notdir
, /* /proc/<pid>/lusage */
4535 pr_readdir_notdir
, /* /proc/<pid>/pagedata */
4536 pr_readdir_notdir
, /* /proc/<pid>/watch */
4537 pr_readdir_notdir
, /* /proc/<pid>/cwd */
4538 pr_readdir_notdir
, /* /proc/<pid>/root */
4539 pr_readdir_fddir
, /* /proc/<pid>/fd */
4540 pr_readdir_notdir
, /* /proc/<pid>/fd/nn */
4541 pr_readdir_objectdir
, /* /proc/<pid>/object */
4542 pr_readdir_notdir
, /* /proc/<pid>/object/xxx */
4543 pr_readdir_lwpdir
, /* /proc/<pid>/lwp */
4544 pr_readdir_lwpiddir
, /* /proc/<pid>/lwp/<lwpid> */
4545 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
4546 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
4547 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4548 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4549 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/xregs */
4550 pr_readdir_tmpldir
, /* /proc/<pid>/lwp/<lwpid>/templates */
4551 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4552 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/spymaster */
4553 pr_readdir_notdir
, /* /proc/<pid>/priv */
4554 pr_readdir_pathdir
, /* /proc/<pid>/path */
4555 pr_readdir_notdir
, /* /proc/<pid>/path/xxx */
4556 pr_readdir_ctdir
, /* /proc/<pid>/contracts */
4557 pr_readdir_notdir
, /* /proc/<pid>/contracts/<ctid> */
4558 pr_readdir_notdir
, /* /proc/<pid>/secflags */
4559 pr_readdir_notdir
, /* old process file */
4560 pr_readdir_notdir
, /* old lwp file */
4561 pr_readdir_notdir
, /* old pagedata file */
4566 prreaddir(vnode_t
*vp
, uio_t
*uiop
, cred_t
*cr
, int *eofp
,
4567 caller_context_t
*ct
, int flags
)
4569 prnode_t
*pnp
= VTOP(vp
);
4571 ASSERT(pnp
->pr_type
< PR_NFILES
);
4573 /* XXX - Do we need to pass ct and flags? */
4574 return (pr_readdir_function
[pnp
->pr_type
](pnp
, uiop
, eofp
));
4579 pr_readdir_notdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4586 pr_readdir_procdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4589 gfs_readdir_state_t gstate
;
4593 ASSERT(pnp
->pr_type
== PR_PROCDIR
);
4595 zoneid
= VTOZONE(PTOV(pnp
))->zone_id
;
4597 if ((error
= gfs_readdir_init(&gstate
, PNSIZ
, PRSDSIZE
, uiop
,
4598 PRROOTINO
, PRROOTINO
, 0)) != 0)
4602 * Loop until user's request is satisfied or until all processes
4603 * have been examined.
4605 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
4611 * Find next entry. Skip processes not visible where
4612 * this /proc was mounted.
4614 mutex_enter(&pidlock
);
4615 while (n
< v
.v_proc
&&
4616 ((p
= pid_entry(n
)) == NULL
|| p
->p_stat
== SIDL
||
4617 (zoneid
!= GLOBAL_ZONEID
&& p
->p_zone
->zone_id
!= zoneid
) ||
4618 secpolicy_basic_procinfo(CRED(), p
, curproc
) != 0))
4622 * Stop when entire proc table has been examined.
4624 if (n
>= v
.v_proc
) {
4625 mutex_exit(&pidlock
);
4630 ASSERT(p
->p_stat
!= 0);
4633 mutex_exit(&pidlock
);
4634 error
= gfs_readdir_emitn(&gstate
, uiop
, n
,
4635 pmkino(0, pslot
, PR_PIDDIR
), pid
);
4640 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
4645 pr_readdir_piddir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4647 int zombie
= ((pnp
->pr_pcommon
->prc_flags
& PRC_DESTROY
) != 0);
4653 ASSERT(pnp
->pr_type
== PR_PIDDIR
);
4655 if (uiop
->uio_offset
< 0 ||
4656 uiop
->uio_offset
% sizeof (prdirent_t
) != 0 ||
4657 uiop
->uio_resid
< sizeof (prdirent_t
))
4659 if (pnp
->pr_pcommon
->prc_proc
== NULL
)
4661 if (uiop
->uio_offset
>= sizeof (piddir
))
4665 * Loop until user's request is satisfied, omitting some
4666 * files along the way if the process is a zombie.
4668 for (dirp
= &piddir
[uiop
->uio_offset
/ sizeof (prdirent_t
)];
4669 uiop
->uio_resid
>= sizeof (prdirent_t
) &&
4670 dirp
< &piddir
[NPIDDIRFILES
+2];
4671 uiop
->uio_offset
= off
+ sizeof (prdirent_t
), dirp
++) {
4672 off
= uiop
->uio_offset
;
4674 switch (dirp
->d_ino
) {
4684 bcopy(dirp
, &dirent
, sizeof (prdirent_t
));
4685 if (dirent
.d_ino
== PR_PROCDIR
)
4686 dirent
.d_ino
= PRROOTINO
;
4688 dirent
.d_ino
= pmkino(0, pnp
->pr_pcommon
->prc_slot
,
4690 if ((error
= uiomove((caddr_t
)&dirent
, sizeof (prdirent_t
),
4691 UIO_READ
, uiop
)) != 0)
4696 *eofp
= (uiop
->uio_offset
>= sizeof (piddir
));
4701 rebuild_objdir(struct as
*as
)
4712 ASSERT(AS_WRITE_HELD(as
));
4714 if (as
->a_updatedir
== 0 && as
->a_objectdir
!= NULL
)
4716 as
->a_updatedir
= 0;
4718 if ((nalloc
= avl_numnodes(&as
->a_segtree
)) == 0 ||
4719 (seg
= AS_SEGFIRST(as
)) == NULL
) /* can't happen? */
4723 * Allocate space for the new object directory.
4724 * (This is usually about two times too many entries.)
4726 nalloc
= (nalloc
+ 0xf) & ~0xf; /* multiple of 16 */
4727 dir
= kmem_zalloc(nalloc
* sizeof (vnode_t
*), KM_SLEEP
);
4729 /* fill in the new directory with desired entries */
4732 vattr
.va_mask
= AT_FSID
|AT_NODEID
;
4733 if (seg
->s_ops
== &segvn_ops
&&
4734 segop_getvp(seg
, seg
->s_base
, &vp
) == 0 &&
4735 vp
!= NULL
&& vp
->v_type
== VREG
&&
4736 fop_getattr(vp
, &vattr
, 0, CRED(), NULL
) == 0) {
4737 for (i
= 0; i
< nentries
; i
++)
4740 if (i
== nentries
) {
4741 ASSERT(nentries
< nalloc
);
4742 dir
[nentries
++] = vp
;
4745 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
4747 if (as
->a_objectdir
== NULL
) { /* first time */
4748 as
->a_objectdir
= dir
;
4749 as
->a_sizedir
= nalloc
;
4754 * Null out all of the defunct entries in the old directory.
4758 for (i
= 0; i
< as
->a_sizedir
; i
++) {
4759 if ((vp
= as
->a_objectdir
[i
]) != NULL
) {
4760 for (j
= 0; j
< nentries
; j
++) {
4768 as
->a_objectdir
[i
] = NULL
;
4774 if (nold
+ nnew
> as
->a_sizedir
) {
4776 * Reallocate the old directory to have enough
4777 * space for the old and new entries combined.
4778 * Round up to the next multiple of 16.
4780 ulong_t newsize
= (nold
+ nnew
+ 0xf) & ~0xf;
4781 vnode_t
**newdir
= kmem_zalloc(newsize
* sizeof (vnode_t
*),
4783 bcopy(as
->a_objectdir
, newdir
,
4784 as
->a_sizedir
* sizeof (vnode_t
*));
4785 kmem_free(as
->a_objectdir
, as
->a_sizedir
* sizeof (vnode_t
*));
4786 as
->a_objectdir
= newdir
;
4787 as
->a_sizedir
= newsize
;
4791 * Move all new entries to the old directory and
4792 * deallocate the space used by the new directory.
4795 for (i
= 0, j
= 0; i
< nentries
; i
++) {
4796 if ((vp
= dir
[i
]) == NULL
)
4798 for (; j
< as
->a_sizedir
; j
++) {
4799 if (as
->a_objectdir
[j
] != NULL
)
4801 as
->a_objectdir
[j
++] = vp
;
4806 kmem_free(dir
, nalloc
* sizeof (vnode_t
*));
4810 * Return the vnode from a slot in the process's object directory.
4811 * The caller must have locked the process's address space.
4812 * The only caller is below, in pr_readdir_objectdir().
4815 obj_entry(struct as
*as
, int slot
)
4817 ASSERT(AS_LOCK_HELD(as
));
4818 if (as
->a_objectdir
== NULL
)
4820 ASSERT(slot
< as
->a_sizedir
);
4821 return (as
->a_objectdir
[slot
]);
4826 pr_readdir_objectdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4828 gfs_readdir_state_t gstate
;
4837 ASSERT(pnp
->pr_type
== PR_OBJECTDIR
);
4839 if ((error
= prlock(pnp
, ZNO
)) != 0)
4841 p
= pnp
->pr_common
->prc_proc
;
4845 * We drop p_lock before grabbing the address space lock
4846 * in order to avoid a deadlock with the clock thread.
4847 * The process will not disappear and its address space
4848 * will not change because it is marked P_PR_LOCK.
4850 mutex_exit(&p
->p_lock
);
4852 if ((error
= gfs_readdir_init(&gstate
, 64, PRSDSIZE
, uiop
,
4853 pmkino(0, pslot
, PR_PIDDIR
),
4854 pmkino(0, pslot
, PR_OBJECTDIR
), 0)) != 0) {
4855 mutex_enter(&p
->p_lock
);
4860 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
4866 * Loop until user's request is satisfied or until
4867 * all mapped objects have been examined. Cannot hold
4868 * the address space lock for the following call as
4869 * gfs_readdir_pred() utimately causes a call to uiomove().
4871 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
4876 * Set the correct size of the directory just
4877 * in case the process has changed it's address
4878 * space via mmap/munmap calls.
4881 AS_LOCK_ENTER(as
, RW_WRITER
);
4882 if (as
->a_updatedir
)
4884 objdirsize
= as
->a_sizedir
;
4890 vattr
.va_mask
= AT_FSID
| AT_NODEID
;
4891 while (n
< objdirsize
&& (((vp
= obj_entry(as
, n
)) == NULL
) ||
4892 (fop_getattr(vp
, &vattr
, 0, CRED(), NULL
)
4894 vattr
.va_mask
= AT_FSID
| AT_NODEID
;
4902 * Stop when all objects have been reported.
4904 if (n
>= objdirsize
) {
4909 if (vp
== p
->p_exec
)
4910 (void) strcpy(str
, "a.out");
4912 pr_object_name(str
, vp
, &vattr
);
4914 error
= gfs_readdir_emit(&gstate
, uiop
, n
, vattr
.va_nodeid
,
4921 mutex_enter(&p
->p_lock
);
4924 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
4929 pr_readdir_lwpdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4931 gfs_readdir_state_t gstate
;
4939 ASSERT(pnp
->pr_type
== PR_LWPDIR
);
4942 mutex_exit(&pr_pidlock
);
4945 ASSERT(p
== pnp
->pr_common
->prc_proc
);
4947 lwpdir
= p
->p_lwpdir
;
4948 lwpdirsize
= p
->p_lwpdir_sz
;
4951 * Drop p->p_lock so we can safely do uiomove().
4952 * The lwp directory will not change because
4953 * we have the process locked with P_PR_LOCK.
4955 mutex_exit(&p
->p_lock
);
4958 if ((error
= gfs_readdir_init(&gstate
, PLNSIZ
, PRSDSIZE
, uiop
,
4959 pmkino(0, pslot
, PR_PIDDIR
),
4960 pmkino(0, pslot
, PR_LWPDIR
), 0)) != 0) {
4961 mutex_enter(&p
->p_lock
);
4967 * Loop until user's request is satisfied or until all lwps
4968 * have been examined.
4970 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &tslot
)) == 0) {
4977 while (tslot
< lwpdirsize
&&
4978 ((lep
= lwpdir
[tslot
].ld_entry
) == NULL
))
4981 * Stop when all lwps have been reported.
4983 if (tslot
>= lwpdirsize
) {
4988 tid
= lep
->le_lwpid
;
4989 error
= gfs_readdir_emitn(&gstate
, uiop
, tslot
,
4990 pmkino(tslot
, pslot
, PR_LWPIDDIR
), tid
);
4995 mutex_enter(&p
->p_lock
);
4998 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5003 pr_readdir_lwpiddir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5005 prcommon_t
*pcp
= pnp
->pr_common
;
5006 int zombie
= ((pcp
->prc_flags
& PRC_DESTROY
) != 0);
5014 ASSERT(pnp
->pr_type
== PR_LWPIDDIR
);
5016 if (uiop
->uio_offset
< 0 ||
5017 uiop
->uio_offset
% sizeof (prdirent_t
) != 0 ||
5018 uiop
->uio_resid
< sizeof (prdirent_t
))
5020 if (pcp
->prc_proc
== NULL
|| pcp
->prc_tslot
== -1)
5022 if (uiop
->uio_offset
>= sizeof (lwpiddir
))
5026 * Loop until user's request is satisfied, omitting some files
5027 * along the way if the lwp is a zombie and also depending
5028 * on the data model of the process.
5030 pslot
= pcp
->prc_slot
;
5031 tslot
= pcp
->prc_tslot
;
5032 for (dirp
= &lwpiddir
[uiop
->uio_offset
/ sizeof (prdirent_t
)];
5033 uiop
->uio_resid
>= sizeof (prdirent_t
) &&
5034 dirp
< &lwpiddir
[NLWPIDDIRFILES
+2];
5035 uiop
->uio_offset
= off
+ sizeof (prdirent_t
), dirp
++) {
5036 off
= uiop
->uio_offset
;
5038 switch (dirp
->d_ino
) {
5047 bcopy(dirp
, &dirent
, sizeof (prdirent_t
));
5048 if (dirent
.d_ino
== PR_LWPDIR
)
5049 dirent
.d_ino
= pmkino(0, pslot
, dirp
->d_ino
);
5051 dirent
.d_ino
= pmkino(tslot
, pslot
, dirp
->d_ino
);
5052 if ((error
= uiomove((caddr_t
)&dirent
, sizeof (prdirent_t
),
5053 UIO_READ
, uiop
)) != 0)
5058 *eofp
= (uiop
->uio_offset
>= sizeof (lwpiddir
));
5064 pr_readdir_fddir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5066 gfs_readdir_state_t gstate
;
5074 ASSERT(pnp
->pr_type
== PR_FDDIR
);
5076 if ((error
= prlock(pnp
, ZNO
)) != 0)
5078 p
= pnp
->pr_common
->prc_proc
;
5081 mutex_exit(&p
->p_lock
);
5083 if ((error
= gfs_readdir_init(&gstate
, PLNSIZ
, PRSDSIZE
, uiop
,
5084 pmkino(0, pslot
, PR_PIDDIR
), pmkino(0, pslot
, PR_FDDIR
), 0)) != 0) {
5085 mutex_enter(&p
->p_lock
);
5090 mutex_enter(&fip
->fi_lock
);
5091 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
5094 fddirsize
= fip
->fi_nfiles
;
5097 * Loop until user's request is satisfied or until
5098 * all file descriptors have been examined.
5100 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
5104 while (n
< fddirsize
&& fip
->fi_list
[n
].uf_file
== NULL
)
5107 * Stop when all fds have been reported.
5109 if (n
>= fddirsize
) {
5114 error
= gfs_readdir_emitn(&gstate
, uiop
, n
,
5115 pmkino(n
, pslot
, PR_FD
), n
);
5120 mutex_exit(&fip
->fi_lock
);
5121 mutex_enter(&p
->p_lock
);
5124 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5129 pr_readdir_pathdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5131 longlong_t bp
[DIRENT64_RECLEN(64) / sizeof (longlong_t
)];
5132 dirent64_t
*dirent
= (dirent64_t
*)bp
;
5142 struct as
*as
= NULL
;
5147 ASSERT(pnp
->pr_type
== PR_PATHDIR
);
5149 if (uiop
->uio_offset
< 0 ||
5150 uiop
->uio_resid
<= 0 ||
5151 (uiop
->uio_offset
% PRSDSIZE
) != 0)
5153 oresid
= uiop
->uio_resid
;
5154 bzero(bp
, sizeof (bp
));
5156 if ((error
= prlock(pnp
, ZNO
)) != 0)
5158 p
= pnp
->pr_common
->prc_proc
;
5161 mutex_exit(&p
->p_lock
);
5163 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
5167 AS_LOCK_ENTER(as
, RW_WRITER
);
5168 if (as
->a_updatedir
)
5170 objdirsize
= as
->a_sizedir
;
5175 mutex_enter(&fip
->fi_lock
);
5176 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
5179 fddirsize
= fip
->fi_nfiles
;
5181 for (; uiop
->uio_resid
> 0; uiop
->uio_offset
= off
+ PRSDSIZE
) {
5183 * There are 4 special files in the path directory: ".", "..",
5184 * "root", and "cwd". We handle those specially here.
5186 off
= uiop
->uio_offset
;
5187 idx
= off
/ PRSDSIZE
;
5188 if (off
== 0) { /* "." */
5189 dirent
->d_ino
= pmkino(0, pslot
, PR_PATHDIR
);
5190 dirent
->d_name
[0] = '.';
5191 dirent
->d_name
[1] = '\0';
5192 reclen
= DIRENT64_RECLEN(1);
5193 } else if (idx
== 1) { /* ".." */
5194 dirent
->d_ino
= pmkino(0, pslot
, PR_PIDDIR
);
5195 dirent
->d_name
[0] = '.';
5196 dirent
->d_name
[1] = '.';
5197 dirent
->d_name
[2] = '\0';
5198 reclen
= DIRENT64_RECLEN(2);
5199 } else if (idx
== 2) { /* "root" */
5200 dirent
->d_ino
= pmkino(idx
, pslot
, PR_PATH
);
5201 (void) strcpy(dirent
->d_name
, "root");
5202 reclen
= DIRENT64_RECLEN(4);
5203 } else if (idx
== 3) { /* "cwd" */
5204 dirent
->d_ino
= pmkino(idx
, pslot
, PR_PATH
);
5205 (void) strcpy(dirent
->d_name
, "cwd");
5206 reclen
= DIRENT64_RECLEN(3);
5207 } else if (idx
< 4 + fddirsize
) {
5209 * In this case, we have one of the file descriptors.
5212 if (fip
->fi_list
[fd
].uf_file
== NULL
)
5214 dirent
->d_ino
= pmkino(idx
, pslot
, PR_PATH
);
5215 (void) pr_u32tos(fd
, dirent
->d_name
, PLNSIZ
+1);
5216 reclen
= DIRENT64_RECLEN(PLNSIZ
);
5217 } else if (idx
< 4 + fddirsize
+ objdirsize
) {
5219 mutex_exit(&fip
->fi_lock
);
5224 * We drop p_lock before grabbing the address space lock
5225 * in order to avoid a deadlock with the clock thread.
5226 * The process will not disappear and its address space
5227 * will not change because it is marked P_PR_LOCK.
5231 AS_LOCK_ENTER(as
, RW_WRITER
);
5234 if (as
->a_updatedir
) {
5236 objdirsize
= as
->a_sizedir
;
5239 obj
= idx
- 4 - fddirsize
;
5240 if ((vp
= obj_entry(as
, obj
)) == NULL
)
5242 vattr
.va_mask
= AT_FSID
|AT_NODEID
;
5243 if (fop_getattr(vp
, &vattr
, 0, CRED(), NULL
) != 0)
5245 if (vp
== p
->p_exec
)
5246 (void) strcpy(dirent
->d_name
, "a.out");
5248 pr_object_name(dirent
->d_name
, vp
, &vattr
);
5249 dirent
->d_ino
= pmkino(idx
, pslot
, PR_PATH
);
5250 reclen
= DIRENT64_RECLEN(strlen(dirent
->d_name
));
5255 dirent
->d_off
= uiop
->uio_offset
+ PRSDSIZE
;
5256 dirent
->d_reclen
= (ushort_t
)reclen
;
5257 if (reclen
> uiop
->uio_resid
) {
5259 * Error if no entries have been returned yet.
5261 if (uiop
->uio_resid
== oresid
)
5266 * Drop the address space lock to do the uiomove().
5271 error
= uiomove((caddr_t
)dirent
, reclen
, UIO_READ
, uiop
);
5273 AS_LOCK_ENTER(as
, RW_WRITER
);
5279 if (error
== 0 && eofp
)
5280 *eofp
= (uiop
->uio_offset
>= (fddirsize
+ 2) * PRSDSIZE
);
5283 mutex_exit(&fip
->fi_lock
);
5286 mutex_enter(&p
->p_lock
);
5292 pr_readdir_tmpldir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5296 gfs_readdir_state_t gstate
;
5300 ASSERT(pnp
->pr_type
== PR_TMPLDIR
);
5302 if ((error
= prlock(pnp
, ZNO
)) != 0)
5304 p
= pnp
->pr_common
->prc_proc
;
5305 pslot
= pnp
->pr_common
->prc_slot
;
5306 tslot
= pnp
->pr_common
->prc_tslot
;
5307 mutex_exit(&p
->p_lock
);
5309 if ((error
= gfs_readdir_init(&gstate
, PRDIRSIZE
, PRSDSIZE
, uiop
,
5310 pmkino(tslot
, pslot
, PR_LWPDIR
),
5311 pmkino(tslot
, pslot
, PR_TMPLDIR
), 0)) != 0) {
5312 mutex_enter(&p
->p_lock
);
5317 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
5319 * Check for an active template. Reading a directory's
5320 * contents is already racy, so we don't bother taking
5323 while (n
< ct_ntypes
&&
5324 pnp
->pr_common
->prc_thread
->t_lwp
->lwp_ct_active
[n
] == NULL
)
5327 * Stop when all types have been reported.
5329 if (n
>= ct_ntypes
) {
5334 * The pmkino invocation below will need to be updated
5335 * when we create our fifth contract type.
5337 ASSERT(ct_ntypes
<= 4);
5338 error
= gfs_readdir_emit(&gstate
, uiop
, n
,
5339 pmkino((tslot
<< 2) | n
, pslot
, PR_TMPL
),
5340 ct_types
[n
]->ct_type_name
, 0);
5345 mutex_enter(&p
->p_lock
);
5348 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5352 pr_readdir_ctdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5356 gfs_readdir_state_t gstate
;
5361 ASSERT(pnp
->pr_type
== PR_CTDIR
);
5363 if ((error
= prlock(pnp
, ZNO
)) != 0)
5365 p
= pnp
->pr_common
->prc_proc
;
5367 mutex_exit(&p
->p_lock
);
5369 if ((error
= gfs_readdir_init(&gstate
, PRDIRSIZE
, PRSDSIZE
, uiop
,
5370 pmkino(0, pslot
, PR_PIDDIR
), pmkino(0, pslot
, PR_CTDIR
), 0)) != 0) {
5371 mutex_enter(&p
->p_lock
);
5376 zid
= VTOZONE(pnp
->pr_vnode
)->zone_uniqid
;
5377 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
5378 id_t next
= contract_plookup(p
, n
, zid
);
5383 error
= gfs_readdir_emitn(&gstate
, uiop
, next
,
5384 pmkino(next
, pslot
, PR_CT
), next
);
5389 mutex_enter(&p
->p_lock
);
5392 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5397 prfsync(vnode_t
*vp
, int syncflag
, cred_t
*cr
, caller_context_t
*ct
)
5403 * Utility: remove a /proc vnode from a linked list, threaded through pr_next.
5406 pr_list_unlink(vnode_t
*pvp
, vnode_t
**listp
)
5411 while ((vp
= *listp
) != NULL
) {
5414 *listp
= pnp
->pr_next
;
5415 pnp
->pr_next
= NULL
;
5418 listp
= &pnp
->pr_next
;
5424 prinactive(vnode_t
*vp
, cred_t
*cr
, caller_context_t
*ct
)
5426 prnode_t
*pnp
= VTOP(vp
);
5427 prnodetype_t type
= pnp
->pr_type
;
5430 vnode_t
*ovp
= NULL
;
5431 prnode_t
*opnp
= NULL
;
5438 /* These are not linked into the usual lists */
5439 ASSERT(vp
->v_count
== 1);
5440 if ((dp
= pnp
->pr_parent
) != NULL
)
5448 mutex_enter(&pr_pidlock
);
5449 if (pnp
->pr_pcommon
== NULL
)
5451 else if ((p
= pnp
->pr_pcommon
->prc_proc
) != NULL
)
5452 mutex_enter(&p
->p_lock
);
5453 mutex_enter(&vp
->v_lock
);
5455 if (type
== PR_PROCDIR
|| vp
->v_count
> 1) {
5457 mutex_exit(&vp
->v_lock
);
5459 mutex_exit(&p
->p_lock
);
5460 mutex_exit(&pr_pidlock
);
5464 if ((dp
= pnp
->pr_parent
) != NULL
) {
5474 mutex_enter(&dpnp
->pr_mutex
);
5475 if (dpnp
->pr_files
!= NULL
&&
5476 dpnp
->pr_files
[pnp
->pr_index
] == vp
)
5477 dpnp
->pr_files
[pnp
->pr_index
] = NULL
;
5478 mutex_exit(&dpnp
->pr_mutex
);
5481 pnp
->pr_parent
= NULL
;
5484 ASSERT(vp
->v_count
== 1);
5487 * If we allocated an old /proc/pid node, free it too.
5489 if (pnp
->pr_pidfile
!= NULL
) {
5490 ASSERT(type
== PR_PIDDIR
);
5491 ovp
= pnp
->pr_pidfile
;
5493 ASSERT(opnp
->pr_type
== PR_PIDFILE
);
5494 pnp
->pr_pidfile
= NULL
;
5497 mutex_exit(&pr_pidlock
);
5501 * Remove the vnodes from the lists of
5502 * /proc vnodes for the process.
5508 pr_list_unlink(vp
, &p
->p_trace
);
5511 if ((slot
= pnp
->pr_common
->prc_tslot
) != -1) {
5512 lwpent_t
*lep
= p
->p_lwpdir
[slot
].ld_entry
;
5513 pr_list_unlink(vp
, &lep
->le_trace
);
5517 pr_list_unlink(vp
, &p
->p_plist
);
5521 pr_list_unlink(ovp
, &p
->p_plist
);
5522 mutex_exit(&p
->p_lock
);
5525 mutex_exit(&vp
->v_lock
);
5527 if (type
== PR_CT
&& pnp
->pr_contract
!= NULL
) {
5528 contract_rele(pnp
->pr_contract
);
5529 pnp
->pr_contract
= NULL
;
5542 prseek(vnode_t
*vp
, offset_t ooff
, offset_t
*noffp
, caller_context_t
*ct
)
5548 * We use the p_execdir member of proc_t to expand the %d token in core file
5549 * paths (the directory path for the executable that dumped core; see
5550 * coreadm(8) for details). We'd like gcore(1) to be able to expand %d in
5551 * the same way as core dumping from the kernel, but there's no convenient
5552 * and comprehensible way to export the path name for p_execdir. To solve
5553 * this, we try to find the actual path to the executable that was used. In
5554 * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT
5555 * flag, and use that here to indicate that more work is needed beyond the
5556 * call to vnodetopath().
5559 prreadlink_lookup(prnode_t
*pnp
, char *buf
, size_t size
, cred_t
*cr
)
5562 vnode_t
*vp
, *execvp
, *vrootp
;
5566 size_t dlen
= DIRENT64_RECLEN(MAXPATHLEN
);
5570 mutex_enter(&p
->p_lock
);
5571 if ((vrootp
= PTOU(p
)->u_rdir
) == NULL
)
5574 mutex_exit(&p
->p_lock
);
5576 ret
= vnodetopath(vrootp
, pnp
->pr_realvp
, buf
, size
, cr
);
5579 * If PR_AOUT isn't set, then we looked up the path for the vnode;
5580 * otherwise, we looked up the path for (what we believe to be) the
5581 * containing directory.
5583 if ((pnp
->pr_flags
& PR_AOUT
) == 0) {
5589 * Fail if there's a problem locking the process. This will only
5590 * occur if the process is changing so the information we would
5591 * report would already be invalid.
5593 if (prlock(pnp
, ZNO
) != 0) {
5598 p
= pnp
->pr_common
->prc_proc
;
5599 mutex_exit(&p
->p_lock
);
5605 * If our initial lookup of the directory failed, fall back to
5606 * the path name information for p_exec.
5609 mutex_enter(&p
->p_lock
);
5611 ret
= vnodetopath(vrootp
, execvp
, buf
, size
, cr
);
5620 * We use u_comm as a guess for the last component of the full
5621 * executable path name. If there isn't going to be enough space
5622 * we fall back to using the p_exec so that we can have _an_
5623 * answer even if it's not perfect.
5625 if (strlen(PTOU(p
)->u_comm
) + len
+ 1 < size
) {
5627 (void) strcpy(buf
+ len
+ 1, PTOU(p
)->u_comm
);
5628 mutex_enter(&p
->p_lock
);
5632 * Do a forward lookup of our u_comm guess.
5634 if (lookupnameat(buf
+ len
+ 1, UIO_SYSSPACE
, FOLLOW
, NULLVPP
,
5635 &vp
, pnp
->pr_realvp
) == 0) {
5636 if (vn_compare(vp
, execvp
)) {
5646 mutex_enter(&p
->p_lock
);
5650 dbuf
= kmem_alloc(dlen
, KM_SLEEP
);
5653 * Try to find a matching vnode by iterating through the directory's
5654 * entries. If that fails, fall back to the path information for
5657 if ((ret
= dirfindvp(vrootp
, pnp
->pr_realvp
, execvp
, cr
, dbuf
,
5658 dlen
, &dp
)) == 0 && strlen(dp
->d_name
) + len
+ 1 < size
) {
5660 (void) strcpy(buf
+ len
+ 1, dp
->d_name
);
5662 ret
= vnodetopath(vrootp
, execvp
, buf
, size
, cr
);
5665 kmem_free(dbuf
, dlen
);
5674 prreadlink(vnode_t
*vp
, uio_t
*uiop
, cred_t
*cr
, caller_context_t
*ctp
)
5676 prnode_t
*pnp
= VTOP(vp
);
5680 int length
, rlength
;
5683 switch (pnp
->pr_type
) {
5685 (void) snprintf(idbuf
, sizeof (idbuf
), "%d", curproc
->p_pid
);
5686 ret
= uiomove(idbuf
, strlen(idbuf
), UIO_READ
, uiop
);
5692 if (pnp
->pr_realvp
->v_type
== VDIR
)
5696 buf
= kmem_alloc(MAXPATHLEN
, KM_SLEEP
);
5698 if ((ret
= prreadlink_lookup(pnp
, buf
, MAXPATHLEN
, cr
)) == 0)
5699 ret
= uiomove(buf
, strlen(buf
), UIO_READ
, uiop
);
5701 kmem_free(buf
, MAXPATHLEN
);
5704 ASSERT(pnp
->pr_contract
!= NULL
);
5705 ct
= pnp
->pr_contract
;
5706 length
= sizeof (CTFS_ROOT
"//") + sizeof (idbuf
) +
5707 strlen(ct
->ct_type
->ct_type_name
);
5708 buf
= kmem_alloc(length
, KM_SLEEP
);
5709 rlength
= snprintf(buf
, length
, CTFS_ROOT
"/%s/%d",
5710 ct
->ct_type
->ct_type_name
, ct
->ct_id
);
5711 ASSERT(rlength
< length
);
5712 ret
= uiomove(buf
, rlength
, UIO_READ
, uiop
);
5713 kmem_free(buf
, length
);
5724 prcmp(vnode_t
*vp1
, vnode_t
*vp2
, caller_context_t
*ct
)
5726 prnode_t
*pp1
, *pp2
;
5731 if (!vn_matchops(vp1
, &prvnodeops
) || !vn_matchops(vp2
, &prvnodeops
))
5737 if (pp1
->pr_type
!= pp2
->pr_type
)
5739 if (pp1
->pr_type
== PR_PROCDIR
)
5741 if (pp1
->pr_ino
|| pp2
->pr_ino
)
5742 return (pp2
->pr_ino
== pp1
->pr_ino
);
5744 if (pp1
->pr_common
== NULL
|| pp2
->pr_common
== NULL
)
5747 return (pp1
->pr_common
->prc_slot
== pp2
->pr_common
->prc_slot
&&
5748 pp1
->pr_common
->prc_tslot
== pp2
->pr_common
->prc_tslot
);
5752 prrealvp(vnode_t
*vp
, vnode_t
**vpp
, caller_context_t
*ct
)
5756 if ((rvp
= VTOP(vp
)->pr_realvp
) != NULL
) {
5758 if (fop_realvp(vp
, &rvp
, ct
) == 0)
5767 * Return the answer requested to poll().
5768 * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
5769 * In addition, these have special meaning for /proc files:
5770 * POLLPRI process or lwp stopped on an event of interest
5771 * POLLERR /proc file descriptor is invalid
5772 * POLLHUP process or lwp has terminated
5776 prpoll(vnode_t
*vp
, short events
, int anyyet
, short *reventsp
,
5777 pollhead_t
**phpp
, caller_context_t
*ct
)
5779 prnode_t
*pnp
= VTOP(vp
);
5780 prcommon_t
*pcp
= pnp
->pr_common
;
5781 pollhead_t
*php
= &pcp
->prc_pollhead
;
5787 ASSERT(pnp
->pr_type
< PR_NFILES
);
5790 * Support for old /proc interface.
5792 if (pnp
->pr_pidfile
!= NULL
) {
5793 vp
= pnp
->pr_pidfile
;
5795 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
5796 ASSERT(pnp
->pr_common
== pcp
);
5799 *reventsp
= revents
= 0;
5800 *phpp
= (pollhead_t
*)NULL
;
5802 if (vp
->v_type
== VDIR
) {
5803 *reventsp
|= POLLNVAL
;
5807 /* avoid deadlock with prnotify() */
5808 if (pollunlock(&lockstate
) != 0) {
5809 *reventsp
= POLLNVAL
;
5813 if ((error
= prlock(pnp
, ZNO
)) != 0) {
5814 pollrelock(lockstate
);
5816 case ENOENT
: /* process or lwp died */
5817 *reventsp
= POLLHUP
;
5820 case EAGAIN
: /* invalidated */
5821 *reventsp
= POLLERR
;
5829 * We have the process marked locked (P_PR_LOCK) and we are holding
5830 * its p->p_lock. We want to unmark the process but retain
5831 * exclusive control w.r.t. other /proc controlling processes
5832 * before reacquiring the polling locks.
5834 * prunmark() does this for us. It unmarks the process
5835 * but retains p->p_lock so we still have exclusive control.
5836 * We will drop p->p_lock at the end to relinquish control.
5838 * We cannot call prunlock() at the end to relinquish control
5839 * because prunlock(), like prunmark(), may drop and reacquire
5840 * p->p_lock and that would lead to a lock order violation
5841 * w.r.t. the polling locks we are about to reacquire.
5847 pollrelock(lockstate
); /* reacquire dropped poll locks */
5849 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
5854 if ((ev
= (events
& (POLLIN
|POLLRDNORM
))) != 0)
5857 * POLLWRNORM (same as POLLOUT) really should not be
5858 * used to indicate that the process or lwp stopped.
5859 * However, USL chose to use POLLWRNORM rather than
5860 * POLLPRI to indicate this, so we just accept either
5861 * requested event to indicate stopped. (grr...)
5863 if ((ev
= (events
& (POLLPRI
|POLLOUT
|POLLWRNORM
))) != 0) {
5866 if (pcp
->prc_flags
& PRC_LWP
) {
5867 t
= pcp
->prc_thread
;
5871 t
= prchoose(p
); /* returns locked t */
5875 if (ISTOPPED(t
) || VSTOPPED(t
))
5881 *reventsp
= revents
;
5882 if ((!anyyet
&& revents
== 0) || (events
& POLLET
)) {
5884 * Arrange to wake up the polling lwp when
5885 * the target process/lwp stops or terminates
5886 * or when the file descriptor becomes invalid.
5888 pcp
->prc_flags
|= PRC_POLL
;
5891 mutex_exit(&p
->p_lock
);
5896 extern int prioctl(vnode_t
*, int, intptr_t, int, cred_t
*, int *,
5897 caller_context_t
*);
5900 * /proc vnode operations vector
5902 const struct vnodeops prvnodeops
= {
5903 .vnop_name
= "procfs",
5905 .vop_close
= prclose
,
5907 .vop_write
= prwrite
,
5908 .vop_ioctl
= prioctl
,
5909 .vop_getattr
= prgetattr
,
5910 .vop_access
= praccess
,
5911 .vop_lookup
= prlookup
,
5912 .vop_create
= prcreate
,
5913 .vop_readdir
= prreaddir
,
5914 .vop_readlink
= prreadlink
,
5915 .vop_fsync
= prfsync
,
5916 .vop_inactive
= prinactive
,
5919 .vop_frlock
= fs_nosys
,
5920 .vop_realvp
= prrealvp
,
5922 .vop_dispose
= fs_nodispose
,
5923 .vop_shrlock
= fs_nosys
,