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) 2014, Joyent, Inc. All rights reserved.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #include <sys/types.h>
31 #include <sys/param.h>
34 #include <sys/policy.h>
35 #include <sys/debug.h>
36 #include <sys/dirent.h>
37 #include <sys/errno.h>
39 #include <sys/inline.h>
41 #include <sys/pathname.h>
43 #include <sys/brand.h>
44 #include <sys/signal.h>
46 #include <sys/sysmacros.h>
47 #include <sys/systm.h>
55 #include <sys/vfs_opreg.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 <fs/fs_subr.h>
70 #include <vm/seg_vn.h>
72 #include <fs/proc/prdata.h>
74 #include <sys/regset.h>
77 #include <sys/sysi86.h>
83 vnodeops_t
*prvnodeops
;
86 * Directory characteristics (patterned after the s5 file system).
93 char d_name
[PRDIRSIZE
];
96 #define PRSDSIZE (sizeof (struct prdirect))
99 * Directory characteristics.
101 typedef struct prdirent
{
102 ino64_t d_ino
; /* "inode number" of entry */
103 off64_t d_off
; /* offset of disk directory entry */
104 unsigned short d_reclen
; /* length of this record */
105 char d_name
[14]; /* name of file */
109 * Contents of a /proc/<pid> directory.
110 * Reuse d_ino field for the /proc file type.
112 static prdirent_t piddir
[] = {
113 { PR_PIDDIR
, 1 * sizeof (prdirent_t
), sizeof (prdirent_t
),
115 { PR_PROCDIR
, 2 * sizeof (prdirent_t
), sizeof (prdirent_t
),
117 { PR_AS
, 3 * sizeof (prdirent_t
), sizeof (prdirent_t
),
119 { PR_CTL
, 4 * sizeof (prdirent_t
), sizeof (prdirent_t
),
121 { PR_STATUS
, 5 * sizeof (prdirent_t
), sizeof (prdirent_t
),
123 { PR_LSTATUS
, 6 * sizeof (prdirent_t
), sizeof (prdirent_t
),
125 { PR_PSINFO
, 7 * sizeof (prdirent_t
), sizeof (prdirent_t
),
127 { PR_LPSINFO
, 8 * sizeof (prdirent_t
), sizeof (prdirent_t
),
129 { PR_MAP
, 9 * sizeof (prdirent_t
), sizeof (prdirent_t
),
131 { PR_RMAP
, 10 * sizeof (prdirent_t
), sizeof (prdirent_t
),
133 { PR_XMAP
, 11 * sizeof (prdirent_t
), sizeof (prdirent_t
),
135 { PR_CRED
, 12 * sizeof (prdirent_t
), sizeof (prdirent_t
),
137 { PR_SIGACT
, 13 * sizeof (prdirent_t
), sizeof (prdirent_t
),
139 { PR_AUXV
, 14 * sizeof (prdirent_t
), sizeof (prdirent_t
),
141 { PR_USAGE
, 15 * sizeof (prdirent_t
), sizeof (prdirent_t
),
143 { PR_LUSAGE
, 16 * sizeof (prdirent_t
), sizeof (prdirent_t
),
145 { PR_PAGEDATA
, 17 * sizeof (prdirent_t
), sizeof (prdirent_t
),
147 { PR_WATCH
, 18 * sizeof (prdirent_t
), sizeof (prdirent_t
),
149 { PR_CURDIR
, 19 * sizeof (prdirent_t
), sizeof (prdirent_t
),
151 { PR_ROOTDIR
, 20 * sizeof (prdirent_t
), sizeof (prdirent_t
),
153 { PR_FDDIR
, 21 * sizeof (prdirent_t
), sizeof (prdirent_t
),
155 { PR_OBJECTDIR
, 22 * sizeof (prdirent_t
), sizeof (prdirent_t
),
157 { PR_LWPDIR
, 23 * sizeof (prdirent_t
), sizeof (prdirent_t
),
159 { PR_PRIV
, 24 * sizeof (prdirent_t
), sizeof (prdirent_t
),
161 { PR_PATHDIR
, 25 * sizeof (prdirent_t
), sizeof (prdirent_t
),
163 { PR_CTDIR
, 26 * sizeof (prdirent_t
), sizeof (prdirent_t
),
166 { PR_LDT
, 27 * sizeof (prdirent_t
), sizeof (prdirent_t
),
171 #define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2)
174 * Contents of a /proc/<pid>/lwp/<lwpid> directory.
176 static prdirent_t lwpiddir
[] = {
177 { PR_LWPIDDIR
, 1 * sizeof (prdirent_t
), sizeof (prdirent_t
),
179 { PR_LWPDIR
, 2 * sizeof (prdirent_t
), sizeof (prdirent_t
),
181 { PR_LWPCTL
, 3 * sizeof (prdirent_t
), sizeof (prdirent_t
),
183 { PR_LWPSTATUS
, 4 * sizeof (prdirent_t
), sizeof (prdirent_t
),
185 { PR_LWPSINFO
, 5 * sizeof (prdirent_t
), sizeof (prdirent_t
),
187 { PR_LWPUSAGE
, 6 * sizeof (prdirent_t
), sizeof (prdirent_t
),
189 { PR_XREGS
, 7 * sizeof (prdirent_t
), sizeof (prdirent_t
),
191 { PR_TMPLDIR
, 8 * sizeof (prdirent_t
), sizeof (prdirent_t
),
193 { PR_SPYMASTER
, 9 * sizeof (prdirent_t
), sizeof (prdirent_t
),
196 { PR_GWINDOWS
, 10 * sizeof (prdirent_t
), sizeof (prdirent_t
),
198 { PR_ASRS
, 11 * sizeof (prdirent_t
), sizeof (prdirent_t
),
203 #define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
206 * Span of entries in the array files (lstatus, lpsinfo, lusage).
207 * We make the span larger than the size of the structure on purpose,
208 * to make sure that programs cannot use the structure size by mistake.
209 * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
212 #define LSPAN(type) (round16(sizeof (type)) + 16)
213 #define LSPAN32(type) (round8(sizeof (type)) + 8)
215 #define LSPAN(type) (round8(sizeof (type)) + 8)
218 static void rebuild_objdir(struct as
*);
219 static void prfreecommon(prcommon_t
*);
220 static int praccess(vnode_t
*, int, int, cred_t
*, caller_context_t
*);
223 propen(vnode_t
**vpp
, int flag
, cred_t
*cr
, caller_context_t
*ct
)
226 prnode_t
*pnp
= VTOP(vp
);
227 prcommon_t
*pcp
= pnp
->pr_pcommon
;
228 prnodetype_t type
= pnp
->pr_type
;
233 prnode_t
*npnp
= NULL
;
236 * Nothing to do for the /proc directory itself.
238 if (type
== PR_PROCDIR
)
242 * If we are opening an underlying mapped object, reject opens
243 * for writing regardless of the objects's access modes.
244 * If we are opening a file in the /proc/pid/fd directory,
245 * reject the open for any but a regular file or directory.
246 * Just do it if we are opening the current or root directory.
253 rvp
= pnp
->pr_realvp
;
255 if ((type
== PR_OBJECT
&& (flag
& FWRITE
)) ||
256 (type
== PR_FD
&& vtype
!= VREG
&& vtype
!= VDIR
))
260 * Need to hold rvp since VOP_OPEN() may release it.
263 error
= VOP_OPEN(&rvp
, flag
, cr
, ct
);
277 * If we are opening the pagedata file, allocate a prnode now
278 * to avoid calling kmem_alloc() while holding p->p_lock.
280 if (type
== PR_PAGEDATA
|| type
== PR_OPAGEDATA
)
281 npnp
= prgetnode(vp
, type
);
284 * If the process exists, lock it now.
285 * Otherwise we have a race condition with prclose().
288 mutex_exit(&pr_pidlock
);
294 ASSERT(p
== pcp
->prc_proc
);
295 ASSERT(p
->p_proc_flag
& P_PR_LOCK
);
298 * Maintain a count of opens for write. Allow exactly one
299 * O_WRITE|O_EXCL request and fail subsequent ones.
300 * Don't fail opens of old (bletch!) /proc lwp files.
301 * Special case for open by the process itself:
302 * Always allow the open by self and discount this
303 * open for other opens for writing.
307 pcp
->prc_selfopens
++;
308 pnp
->pr_flags
|= PR_ISSELF
;
309 } else if (type
== PR_LWPIDFILE
) {
311 } else if (flag
& FEXCL
) {
312 if (pcp
->prc_writers
> pcp
->prc_selfopens
) {
316 /* semantic for old /proc interface */
317 if (type
== PR_PIDDIR
)
318 pcp
->prc_flags
|= PRC_EXCL
;
319 } else if (pcp
->prc_flags
& PRC_EXCL
) {
320 ASSERT(pcp
->prc_writers
> pcp
->prc_selfopens
);
321 error
= secpolicy_proc_excl_open(cr
);
327 * The vnode may have become invalid between the
328 * VOP_LOOKUP() of the /proc vnode and the VOP_OPEN().
329 * If so, do now what prinvalidate() should have done.
331 if ((pnp
->pr_flags
& PR_INVAL
) ||
332 (type
== PR_PIDDIR
&&
333 (VTOP(pnp
->pr_pidfile
)->pr_flags
& PR_INVAL
))) {
335 pcp
->prc_selfopens
++;
336 ASSERT(pcp
->prc_selfopens
<= pcp
->prc_writers
);
337 if (pcp
->prc_selfopens
== pcp
->prc_writers
)
338 pcp
->prc_flags
&= ~PRC_EXCL
;
343 * If this is a large file open, indicate that in our flags -- some
344 * procfs structures are not off_t-neutral (e.g., priovec_t), and
345 * the open will need to be differentiated where 32-bit processes
346 * pass these structures across the user/kernel boundary.
349 pnp
->pr_flags
|= PR_OFFMAX
;
352 * Do file-specific things.
360 * Enable data collection for page data file;
361 * get unique id from the hat layer.
367 * Drop p->p_lock to call hat_startstat()
369 mutex_exit(&p
->p_lock
);
370 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
||
371 (id
= hat_startstat(p
->p_as
)) == -1) {
372 mutex_enter(&p
->p_lock
);
374 } else if (pnp
->pr_hatid
== 0) {
375 mutex_enter(&p
->p_lock
);
376 pnp
->pr_hatid
= (uint_t
)id
;
378 mutex_enter(&p
->p_lock
);
380 * Use our newly allocated prnode.
382 npnp
->pr_hatid
= (uint_t
)id
;
384 * prgetnode() initialized most of the prnode.
385 * Duplicate the remainder.
387 npnp
->pr_ino
= pnp
->pr_ino
;
388 npnp
->pr_common
= pnp
->pr_common
;
389 npnp
->pr_pcommon
= pnp
->pr_pcommon
;
390 npnp
->pr_parent
= pnp
->pr_parent
;
391 VN_HOLD(npnp
->pr_parent
);
392 npnp
->pr_index
= pnp
->pr_index
;
394 npnp
->pr_next
= p
->p_plist
;
395 p
->p_plist
= PTOV(npnp
);
416 prclose(vnode_t
*vp
, int flag
, int count
, offset_t offset
, cred_t
*cr
,
417 caller_context_t
*ct
)
419 prnode_t
*pnp
= VTOP(vp
);
420 prcommon_t
*pcp
= pnp
->pr_pcommon
;
421 prnodetype_t type
= pnp
->pr_type
;
427 * Nothing to do for the /proc directory itself.
429 if (type
== PR_PROCDIR
)
432 ASSERT(type
!= PR_OBJECT
&& type
!= PR_FD
&&
433 type
!= PR_CURDIR
&& type
!= PR_ROOTDIR
);
436 * If the process exists, lock it now.
437 * Otherwise we have a race condition with propen().
438 * Hold pr_pidlock across the reference to prc_selfopens,
439 * and prc_writers in case there is no process anymore,
440 * to cover the case of concurrent calls to prclose()
441 * after the process has been reaped by freeproc().
446 * There is nothing more to do until the last close of
447 * the file table entry except to clear the pr_owner
448 * field of the prnode and notify any waiters
449 * (their file descriptor may have just been closed).
452 mutex_exit(&pr_pidlock
);
453 if (pnp
->pr_owner
== curproc
&& !fisopen(vp
))
454 pnp
->pr_owner
= NULL
;
463 * Decrement the count of self-opens for writing.
464 * Decrement the total count of opens for writing.
465 * Cancel exclusive opens when only self-opens remain.
469 * prc_selfopens also contains the count of
470 * invalid writers. See prinvalidate().
472 if ((pnp
->pr_flags
& (PR_ISSELF
|PR_INVAL
)) ||
473 (type
== PR_PIDDIR
&&
474 (VTOP(pnp
->pr_pidfile
)->pr_flags
& PR_INVAL
))) {
475 ASSERT(pcp
->prc_selfopens
!= 0);
476 --pcp
->prc_selfopens
;
478 ASSERT(pcp
->prc_writers
!= 0);
479 if (--pcp
->prc_writers
== pcp
->prc_selfopens
)
480 pcp
->prc_flags
&= ~PRC_EXCL
;
482 ASSERT(pcp
->prc_writers
>= pcp
->prc_selfopens
);
483 mutex_exit(&pr_pidlock
);
484 if (pnp
->pr_owner
== curproc
&& !fisopen(vp
))
485 pnp
->pr_owner
= NULL
;
488 * If there is no process, there is nothing more to do.
493 ASSERT(p
== pcp
->prc_proc
);
494 prnotify(vp
); /* notify waiters */
497 * Do file-specific things.
505 * This is a page data file.
506 * Free the hat level statistics.
507 * Drop p->p_lock before calling hat_freestat().
509 mutex_exit(&p
->p_lock
);
510 if (p
->p_as
!= &kas
&& pnp
->pr_hatid
!= 0)
511 hat_freestat(p
->p_as
, pnp
->pr_hatid
);
512 mutex_enter(&p
->p_lock
);
518 * On last close of all writable file descriptors,
519 * perform run-on-last-close and/or kill-on-last-close logic.
520 * Can't do this is the /proc agent lwp still exists.
522 if (pcp
->prc_writers
== 0 &&
523 p
->p_agenttp
== NULL
&&
524 !(pcp
->prc_flags
& PRC_DESTROY
) &&
525 p
->p_stat
!= SZOMB
&&
526 (p
->p_proc_flag
& (P_PR_RUNLCL
|P_PR_KILLCL
))) {
530 * Cancel any watchpoints currently in effect.
531 * The process might disappear during this operation.
533 if (pr_cancel_watch(pnp
) == NULL
)
536 * If any tracing flags are set, clear them.
538 if (p
->p_proc_flag
& P_PR_TRACE
) {
540 premptyset(&up
->u_entrymask
);
541 premptyset(&up
->u_exitmask
);
544 premptyset(&p
->p_sigmask
);
545 premptyset(&p
->p_fltmask
);
546 killproc
= (p
->p_proc_flag
& P_PR_KILLCL
);
547 p
->p_proc_flag
&= ~(P_PR_RUNLCL
|P_PR_KILLCL
|P_PR_TRACE
);
549 * Cancel any outstanding single-step requests.
551 if ((t
= p
->p_tlist
) != NULL
) {
553 * Drop p_lock because prnostep() touches the stack.
554 * The loop is safe because the process is P_PR_LOCK'd.
556 mutex_exit(&p
->p_lock
);
559 } while ((t
= t
->t_forw
) != p
->p_tlist
);
560 mutex_enter(&p
->p_lock
);
563 * Set runnable all lwps stopped by /proc.
566 sigtoproc(p
, NULL
, SIGKILL
);
576 * Array of read functions, indexed by /proc file type.
578 static int pr_read_inval(), pr_read_as(), pr_read_status(),
579 pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
580 pr_read_map(), pr_read_rmap(), pr_read_xmap(),
581 pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
585 pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
586 pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
587 pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
590 pr_read_gwindows(), pr_read_asrs(),
592 pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
594 static int (*pr_read_function
[PR_NFILES
])() = {
595 pr_read_inval
, /* /proc */
596 pr_read_inval
, /* /proc/self */
597 pr_read_piddir
, /* /proc/<pid> (old /proc read()) */
598 pr_read_as
, /* /proc/<pid>/as */
599 pr_read_inval
, /* /proc/<pid>/ctl */
600 pr_read_status
, /* /proc/<pid>/status */
601 pr_read_lstatus
, /* /proc/<pid>/lstatus */
602 pr_read_psinfo
, /* /proc/<pid>/psinfo */
603 pr_read_lpsinfo
, /* /proc/<pid>/lpsinfo */
604 pr_read_map
, /* /proc/<pid>/map */
605 pr_read_rmap
, /* /proc/<pid>/rmap */
606 pr_read_xmap
, /* /proc/<pid>/xmap */
607 pr_read_cred
, /* /proc/<pid>/cred */
608 pr_read_sigact
, /* /proc/<pid>/sigact */
609 pr_read_auxv
, /* /proc/<pid>/auxv */
611 pr_read_ldt
, /* /proc/<pid>/ldt */
613 pr_read_usage
, /* /proc/<pid>/usage */
614 pr_read_lusage
, /* /proc/<pid>/lusage */
615 pr_read_pagedata
, /* /proc/<pid>/pagedata */
616 pr_read_watch
, /* /proc/<pid>/watch */
617 pr_read_inval
, /* /proc/<pid>/cwd */
618 pr_read_inval
, /* /proc/<pid>/root */
619 pr_read_inval
, /* /proc/<pid>/fd */
620 pr_read_inval
, /* /proc/<pid>/fd/nn */
621 pr_read_inval
, /* /proc/<pid>/object */
622 pr_read_inval
, /* /proc/<pid>/object/xxx */
623 pr_read_inval
, /* /proc/<pid>/lwp */
624 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid> */
625 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
626 pr_read_lwpstatus
, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
627 pr_read_lwpsinfo
, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
628 pr_read_lwpusage
, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
629 pr_read_xregs
, /* /proc/<pid>/lwp/<lwpid>/xregs */
630 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/templates */
631 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
632 pr_read_spymaster
, /* /proc/<pid>/lwp/<lwpid>/spymaster */
634 pr_read_gwindows
, /* /proc/<pid>/lwp/<lwpid>/gwindows */
635 pr_read_asrs
, /* /proc/<pid>/lwp/<lwpid>/asrs */
637 pr_read_priv
, /* /proc/<pid>/priv */
638 pr_read_inval
, /* /proc/<pid>/path */
639 pr_read_inval
, /* /proc/<pid>/path/xxx */
640 pr_read_inval
, /* /proc/<pid>/contracts */
641 pr_read_inval
, /* /proc/<pid>/contracts/<ctid> */
642 pr_read_pidfile
, /* old process file */
643 pr_read_pidfile
, /* old lwp file */
644 pr_read_opagedata
, /* old pagedata file */
649 pr_read_inval(prnode_t
*pnp
, uio_t
*uiop
)
652 * No read() on any /proc directory, use getdents(2) instead.
653 * Cannot read a control file either.
654 * An underlying mapped object file cannot get here.
660 pr_uioread(void *base
, long count
, uio_t
*uiop
)
665 count
-= uiop
->uio_offset
;
666 if (count
> 0 && uiop
->uio_offset
>= 0) {
667 error
= uiomove((char *)base
+ uiop
->uio_offset
,
668 count
, UIO_READ
, uiop
);
675 pr_read_as(prnode_t
*pnp
, uio_t
*uiop
)
679 ASSERT(pnp
->pr_type
== PR_AS
);
681 if ((error
= prlock(pnp
, ZNO
)) == 0) {
682 proc_t
*p
= pnp
->pr_common
->prc_proc
;
683 struct as
*as
= p
->p_as
;
686 * /proc I/O cannot be done to a system process.
687 * A 32-bit process cannot read a 64-bit process.
689 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
691 #ifdef _SYSCALL32_IMPL
692 } else if (curproc
->p_model
== DATAMODEL_ILP32
&&
693 PROCESS_NOT_32BIT(p
)) {
698 * We don't hold p_lock over an i/o operation because
699 * that could lead to deadlock with the clock thread.
701 mutex_exit(&p
->p_lock
);
702 error
= prusrio(p
, UIO_READ
, uiop
, 0);
703 mutex_enter(&p
->p_lock
);
712 pr_read_status(prnode_t
*pnp
, uio_t
*uiop
)
717 ASSERT(pnp
->pr_type
== PR_STATUS
);
720 * We kmem_alloc() the pstatus structure because
721 * it is so big it might blow the kernel stack.
723 sp
= kmem_alloc(sizeof (*sp
), KM_SLEEP
);
724 if ((error
= prlock(pnp
, ZNO
)) == 0) {
725 prgetstatus(pnp
->pr_common
->prc_proc
, sp
, VTOZONE(PTOV(pnp
)));
727 error
= pr_uioread(sp
, sizeof (*sp
), uiop
);
729 kmem_free(sp
, sizeof (*sp
));
734 pr_read_lstatus(prnode_t
*pnp
, uio_t
*uiop
)
746 ASSERT(pnp
->pr_type
== PR_LSTATUS
);
748 if ((error
= prlock(pnp
, ZNO
)) != 0)
750 p
= pnp
->pr_common
->prc_proc
;
752 size
= sizeof (prheader_t
) + nlwp
* LSPAN(lwpstatus_t
);
754 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
755 mutex_exit(&p
->p_lock
);
756 php
= kmem_zalloc(size
, KM_SLEEP
);
757 mutex_enter(&p
->p_lock
);
758 /* p->p_lwpcnt can't change while process is locked */
759 ASSERT(nlwp
== p
->p_lwpcnt
);
762 php
->pr_entsize
= LSPAN(lwpstatus_t
);
764 sp
= (lwpstatus_t
*)(php
+ 1);
765 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
766 if (ldp
->ld_entry
== NULL
||
767 (t
= ldp
->ld_entry
->le_thread
) == NULL
)
769 prgetlwpstatus(t
, sp
, VTOZONE(PTOV(pnp
)));
770 sp
= (lwpstatus_t
*)((caddr_t
)sp
+ LSPAN(lwpstatus_t
));
774 error
= pr_uioread(php
, size
, uiop
);
775 kmem_free(php
, size
);
780 pr_read_psinfo(prnode_t
*pnp
, uio_t
*uiop
)
786 ASSERT(pnp
->pr_type
== PR_PSINFO
);
789 * We don't want the full treatment of prlock(pnp) here.
790 * This file is world-readable and never goes invalid.
791 * It doesn't matter if we are in the middle of an exec().
794 mutex_exit(&pr_pidlock
);
798 ASSERT(p
== pnp
->pr_common
->prc_proc
);
799 prgetpsinfo(p
, &psinfo
);
801 error
= pr_uioread(&psinfo
, sizeof (psinfo
), uiop
);
807 pr_read_lpsinfo(prnode_t
*pnp
, uio_t
*uiop
)
820 ASSERT(pnp
->pr_type
== PR_LPSINFO
);
823 * We don't want the full treatment of prlock(pnp) here.
824 * This file is world-readable and never goes invalid.
825 * It doesn't matter if we are in the middle of an exec().
828 mutex_exit(&pr_pidlock
);
831 ASSERT(p
== pnp
->pr_common
->prc_proc
);
832 if ((nlwp
= p
->p_lwpcnt
+ p
->p_zombcnt
) == 0) {
836 size
= sizeof (prheader_t
) + nlwp
* LSPAN(lwpsinfo_t
);
838 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
839 mutex_exit(&p
->p_lock
);
840 php
= kmem_zalloc(size
, KM_SLEEP
);
841 mutex_enter(&p
->p_lock
);
842 /* p->p_lwpcnt can't change while process is locked */
843 ASSERT(nlwp
== p
->p_lwpcnt
+ p
->p_zombcnt
);
846 php
->pr_entsize
= LSPAN(lwpsinfo_t
);
848 sp
= (lwpsinfo_t
*)(php
+ 1);
849 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
850 if ((lep
= ldp
->ld_entry
) == NULL
)
852 if ((t
= lep
->le_thread
) != NULL
)
853 prgetlwpsinfo(t
, sp
);
855 bzero(sp
, sizeof (*sp
));
856 sp
->pr_lwpid
= lep
->le_lwpid
;
857 sp
->pr_state
= SZOMB
;
859 sp
->pr_start
.tv_sec
= lep
->le_start
;
860 sp
->pr_bindpro
= PBIND_NONE
;
861 sp
->pr_bindpset
= PS_NONE
;
863 sp
= (lwpsinfo_t
*)((caddr_t
)sp
+ LSPAN(lwpsinfo_t
));
867 error
= pr_uioread(php
, size
, uiop
);
868 kmem_free(php
, size
);
873 pr_read_map_common(prnode_t
*pnp
, uio_t
*uiop
, prnodetype_t type
)
881 if ((error
= prlock(pnp
, ZNO
)) != 0)
884 p
= pnp
->pr_common
->prc_proc
;
887 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
892 if (!AS_LOCK_TRYENTER(as
, RW_WRITER
)) {
897 mutex_exit(&p
->p_lock
);
901 error
= prgetxmap(p
, &iolhead
);
904 error
= prgetmap(p
, 1, &iolhead
);
907 error
= prgetmap(p
, 0, &iolhead
);
912 mutex_enter(&p
->p_lock
);
915 error
= pr_iol_uiomove_and_free(&iolhead
, uiop
, error
);
921 pr_read_map(prnode_t
*pnp
, uio_t
*uiop
)
923 ASSERT(pnp
->pr_type
== PR_MAP
);
924 return (pr_read_map_common(pnp
, uiop
, pnp
->pr_type
));
928 pr_read_rmap(prnode_t
*pnp
, uio_t
*uiop
)
930 ASSERT(pnp
->pr_type
== PR_RMAP
);
931 return (pr_read_map_common(pnp
, uiop
, pnp
->pr_type
));
935 pr_read_xmap(prnode_t
*pnp
, uio_t
*uiop
)
937 ASSERT(pnp
->pr_type
== PR_XMAP
);
938 return (pr_read_map_common(pnp
, uiop
, pnp
->pr_type
));
942 pr_read_cred(prnode_t
*pnp
, uio_t
*uiop
)
949 ASSERT(pnp
->pr_type
== PR_CRED
);
952 * We kmem_alloc() the prcred_t structure because
953 * the number of supplementary groups is variable.
956 kmem_alloc(sizeof (prcred_t
) + sizeof (gid_t
) * (ngroups_max
- 1),
959 if ((error
= prlock(pnp
, ZNO
)) != 0)
961 p
= pnp
->pr_common
->prc_proc
;
967 count
= sizeof (prcred_t
);
968 if (pcrp
->pr_ngroups
> 1)
969 count
+= sizeof (gid_t
) * (pcrp
->pr_ngroups
- 1);
970 error
= pr_uioread(pcrp
, count
, uiop
);
972 kmem_free(pcrp
, sizeof (prcred_t
) + sizeof (gid_t
) * (ngroups_max
- 1));
977 pr_read_priv(prnode_t
*pnp
, uio_t
*uiop
)
980 size_t psize
= prgetprivsize();
981 prpriv_t
*ppriv
= kmem_alloc(psize
, KM_SLEEP
);
984 ASSERT(pnp
->pr_type
== PR_PRIV
);
986 if ((error
= prlock(pnp
, ZNO
)) != 0)
988 p
= pnp
->pr_common
->prc_proc
;
994 error
= pr_uioread(ppriv
, psize
, uiop
);
996 kmem_free(ppriv
, psize
);
1001 pr_read_sigact(prnode_t
*pnp
, uio_t
*uiop
)
1003 int nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
1005 struct sigaction
*sap
;
1010 ASSERT(pnp
->pr_type
== PR_SIGACT
);
1013 * We kmem_alloc() the sigaction array because
1014 * it is so big it might blow the kernel stack.
1016 sap
= kmem_alloc((nsig
-1) * sizeof (struct sigaction
), KM_SLEEP
);
1018 if ((error
= prlock(pnp
, ZNO
)) != 0)
1020 p
= pnp
->pr_common
->prc_proc
;
1023 if (uiop
->uio_offset
>= (nsig
-1)*sizeof (struct sigaction
)) {
1029 for (sig
= 1; sig
< nsig
; sig
++)
1030 prgetaction(p
, up
, sig
, &sap
[sig
-1]);
1033 error
= pr_uioread(sap
, (nsig
- 1) * sizeof (struct sigaction
), uiop
);
1035 kmem_free(sap
, (nsig
-1) * sizeof (struct sigaction
));
1040 pr_read_auxv(prnode_t
*pnp
, uio_t
*uiop
)
1042 auxv_t auxv
[__KERN_NAUXV_IMPL
];
1047 ASSERT(pnp
->pr_type
== PR_AUXV
);
1049 if ((error
= prlock(pnp
, ZNO
)) != 0)
1052 if (uiop
->uio_offset
>= sizeof (auxv
)) {
1057 p
= pnp
->pr_common
->prc_proc
;
1059 bcopy(up
->u_auxv
, auxv
, sizeof (auxv
));
1062 return (pr_uioread(auxv
, sizeof (auxv
), uiop
));
1068 * This is almost certainly broken for the amd64 kernel, because
1069 * we have two kinds of LDT structures to export -- one for compatibility
1070 * mode, and one for long mode, sigh.
1072 * For now lets just have a ldt of size 0 for 64-bit processes.
1075 pr_read_ldt(prnode_t
*pnp
, uio_t
*uiop
)
1082 ASSERT(pnp
->pr_type
== PR_LDT
);
1084 if ((error
= prlock(pnp
, ZNO
)) != 0)
1086 p
= pnp
->pr_common
->prc_proc
;
1088 mutex_exit(&p
->p_lock
);
1089 mutex_enter(&p
->p_ldtlock
);
1090 size
= prnldt(p
) * sizeof (struct ssd
);
1091 if (uiop
->uio_offset
>= size
) {
1092 mutex_exit(&p
->p_ldtlock
);
1093 mutex_enter(&p
->p_lock
);
1098 ssd
= kmem_alloc(size
, KM_SLEEP
);
1100 mutex_exit(&p
->p_ldtlock
);
1101 mutex_enter(&p
->p_lock
);
1104 error
= pr_uioread(ssd
, size
, uiop
);
1105 kmem_free(ssd
, size
);
1111 pr_read_usage(prnode_t
*pnp
, uio_t
*uiop
)
1119 ASSERT(pnp
->pr_type
== PR_USAGE
);
1121 /* allocate now, before locking the process */
1122 pup
= kmem_zalloc(sizeof (*pup
), KM_SLEEP
);
1123 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
1126 * We don't want the full treatment of prlock(pnp) here.
1127 * This file is world-readable and never goes invalid.
1128 * It doesn't matter if we are in the middle of an exec().
1131 mutex_exit(&pr_pidlock
);
1136 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1138 if (uiop
->uio_offset
>= sizeof (prusage_t
)) {
1144 pup
->pr_tstamp
= gethrtime();
1146 pup
->pr_count
= p
->p_defunct
;
1147 pup
->pr_create
= p
->p_mstart
;
1148 pup
->pr_term
= p
->p_mterm
;
1150 pup
->pr_rtime
= p
->p_mlreal
;
1151 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
1152 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
1153 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
1154 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
1155 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
1156 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
1157 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
1158 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
1159 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
1160 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
1162 pup
->pr_minf
= p
->p_ru
.minflt
;
1163 pup
->pr_majf
= p
->p_ru
.majflt
;
1164 pup
->pr_nswap
= p
->p_ru
.nswap
;
1165 pup
->pr_inblk
= p
->p_ru
.inblock
;
1166 pup
->pr_oublk
= p
->p_ru
.oublock
;
1167 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
1168 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
1169 pup
->pr_sigs
= p
->p_ru
.nsignals
;
1170 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
1171 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
1172 pup
->pr_sysc
= p
->p_ru
.sysc
;
1173 pup
->pr_ioch
= p
->p_ru
.ioch
;
1176 * Add the usage information for each active lwp.
1178 if ((t
= p
->p_tlist
) != NULL
&&
1179 !(pnp
->pr_pcommon
->prc_flags
& PRC_DESTROY
)) {
1181 if (t
->t_proc_flag
& TP_LWPEXIT
)
1185 } while ((t
= t
->t_forw
) != p
->p_tlist
);
1190 prcvtusage(pup
, upup
);
1192 error
= pr_uioread(upup
, sizeof (prusage_t
), uiop
);
1194 kmem_free(pup
, sizeof (*pup
));
1195 kmem_free(upup
, sizeof (*upup
));
1200 pr_read_lusage(prnode_t
*pnp
, uio_t
*uiop
)
1214 ASSERT(pnp
->pr_type
== PR_LUSAGE
);
1217 * We don't want the full treatment of prlock(pnp) here.
1218 * This file is world-readable and never goes invalid.
1219 * It doesn't matter if we are in the middle of an exec().
1222 mutex_exit(&pr_pidlock
);
1225 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1226 if ((nlwp
= p
->p_lwpcnt
) == 0) {
1231 size
= sizeof (prheader_t
) + (nlwp
+ 1) * LSPAN(prusage_t
);
1232 if (uiop
->uio_offset
>= size
) {
1237 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1238 mutex_exit(&p
->p_lock
);
1239 pup
= kmem_zalloc(size
+ sizeof (prhusage_t
), KM_SLEEP
);
1240 mutex_enter(&p
->p_lock
);
1241 /* p->p_lwpcnt can't change while process is locked */
1242 ASSERT(nlwp
== p
->p_lwpcnt
);
1244 php
= (prheader_t
*)(pup
+ 1);
1245 upup
= (prusage_t
*)(php
+ 1);
1247 php
->pr_nent
= nlwp
+ 1;
1248 php
->pr_entsize
= LSPAN(prusage_t
);
1250 curtime
= gethrtime();
1253 * First the summation over defunct lwps.
1255 pup
->pr_count
= p
->p_defunct
;
1256 pup
->pr_tstamp
= curtime
;
1257 pup
->pr_create
= p
->p_mstart
;
1258 pup
->pr_term
= p
->p_mterm
;
1260 pup
->pr_rtime
= p
->p_mlreal
;
1261 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
1262 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
1263 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
1264 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
1265 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
1266 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
1267 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
1268 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
1269 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
1270 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
1272 pup
->pr_minf
= p
->p_ru
.minflt
;
1273 pup
->pr_majf
= p
->p_ru
.majflt
;
1274 pup
->pr_nswap
= p
->p_ru
.nswap
;
1275 pup
->pr_inblk
= p
->p_ru
.inblock
;
1276 pup
->pr_oublk
= p
->p_ru
.oublock
;
1277 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
1278 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
1279 pup
->pr_sigs
= p
->p_ru
.nsignals
;
1280 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
1281 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
1282 pup
->pr_sysc
= p
->p_ru
.sysc
;
1283 pup
->pr_ioch
= p
->p_ru
.ioch
;
1285 prcvtusage(pup
, upup
);
1288 * Fill one prusage struct for each active lwp.
1290 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
1291 if (ldp
->ld_entry
== NULL
||
1292 (t
= ldp
->ld_entry
->le_thread
) == NULL
)
1294 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
1297 upup
= (prusage_t
*)((caddr_t
)upup
+ LSPAN(prusage_t
));
1299 prcvtusage(pup
, upup
);
1305 error
= pr_uioread(php
, size
, uiop
);
1306 kmem_free(pup
, size
+ sizeof (prhusage_t
));
1311 pr_read_pagedata(prnode_t
*pnp
, uio_t
*uiop
)
1316 ASSERT(pnp
->pr_type
== PR_PAGEDATA
);
1318 if ((error
= prlock(pnp
, ZNO
)) != 0)
1321 p
= pnp
->pr_common
->prc_proc
;
1322 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
1327 mutex_exit(&p
->p_lock
);
1328 error
= prpdread(p
, pnp
->pr_hatid
, uiop
);
1329 mutex_enter(&p
->p_lock
);
1336 pr_read_opagedata(prnode_t
*pnp
, uio_t
*uiop
)
1342 ASSERT(pnp
->pr_type
== PR_OPAGEDATA
);
1344 if ((error
= prlock(pnp
, ZNO
)) != 0)
1347 p
= pnp
->pr_common
->prc_proc
;
1349 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
1354 mutex_exit(&p
->p_lock
);
1355 error
= oprpdread(as
, pnp
->pr_hatid
, uiop
);
1356 mutex_enter(&p
->p_lock
);
1363 pr_read_watch(prnode_t
*pnp
, uio_t
*uiop
)
1371 struct watched_area
*pwarea
;
1373 ASSERT(pnp
->pr_type
== PR_WATCH
);
1375 if ((error
= prlock(pnp
, ZNO
)) != 0)
1378 p
= pnp
->pr_common
->prc_proc
;
1379 nwarea
= avl_numnodes(&p
->p_warea
);
1380 size
= nwarea
* sizeof (prwatch_t
);
1381 if (uiop
->uio_offset
>= size
) {
1386 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1387 mutex_exit(&p
->p_lock
);
1388 Bpwp
= pwp
= kmem_zalloc(size
, KM_SLEEP
);
1389 mutex_enter(&p
->p_lock
);
1390 /* p->p_nwarea can't change while process is locked */
1391 ASSERT(nwarea
== avl_numnodes(&p
->p_warea
));
1393 /* gather the watched areas */
1394 for (pwarea
= avl_first(&p
->p_warea
); pwarea
!= NULL
;
1395 pwarea
= AVL_NEXT(&p
->p_warea
, pwarea
), pwp
++) {
1396 pwp
->pr_vaddr
= (uintptr_t)pwarea
->wa_vaddr
;
1397 pwp
->pr_size
= pwarea
->wa_eaddr
- pwarea
->wa_vaddr
;
1398 pwp
->pr_wflags
= (int)pwarea
->wa_flags
;
1403 error
= pr_uioread(Bpwp
, size
, uiop
);
1404 kmem_free(Bpwp
, size
);
1409 pr_read_lwpstatus(prnode_t
*pnp
, uio_t
*uiop
)
1414 ASSERT(pnp
->pr_type
== PR_LWPSTATUS
);
1417 * We kmem_alloc() the lwpstatus structure because
1418 * it is so big it might blow the kernel stack.
1420 sp
= kmem_alloc(sizeof (*sp
), KM_SLEEP
);
1422 if ((error
= prlock(pnp
, ZNO
)) != 0)
1425 if (uiop
->uio_offset
>= sizeof (*sp
)) {
1430 prgetlwpstatus(pnp
->pr_common
->prc_thread
, sp
, VTOZONE(PTOV(pnp
)));
1433 error
= pr_uioread(sp
, sizeof (*sp
), uiop
);
1435 kmem_free(sp
, sizeof (*sp
));
1440 pr_read_lwpsinfo(prnode_t
*pnp
, uio_t
*uiop
)
1442 lwpsinfo_t lwpsinfo
;
1447 ASSERT(pnp
->pr_type
== PR_LWPSINFO
);
1450 * We don't want the full treatment of prlock(pnp) here.
1451 * This file is world-readable and never goes invalid.
1452 * It doesn't matter if we are in the middle of an exec().
1455 mutex_exit(&pr_pidlock
);
1458 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1459 if (pnp
->pr_common
->prc_tslot
== -1) {
1464 if (uiop
->uio_offset
>= sizeof (lwpsinfo
)) {
1469 if ((t
= pnp
->pr_common
->prc_thread
) != NULL
)
1470 prgetlwpsinfo(t
, &lwpsinfo
);
1472 lep
= p
->p_lwpdir
[pnp
->pr_common
->prc_tslot
].ld_entry
;
1473 bzero(&lwpsinfo
, sizeof (lwpsinfo
));
1474 lwpsinfo
.pr_lwpid
= lep
->le_lwpid
;
1475 lwpsinfo
.pr_state
= SZOMB
;
1476 lwpsinfo
.pr_sname
= 'Z';
1477 lwpsinfo
.pr_start
.tv_sec
= lep
->le_start
;
1478 lwpsinfo
.pr_bindpro
= PBIND_NONE
;
1479 lwpsinfo
.pr_bindpset
= PS_NONE
;
1483 return (pr_uioread(&lwpsinfo
, sizeof (lwpsinfo
), uiop
));
1487 pr_read_lwpusage(prnode_t
*pnp
, uio_t
*uiop
)
1494 ASSERT(pnp
->pr_type
== PR_LWPUSAGE
);
1496 /* allocate now, before locking the process */
1497 pup
= kmem_zalloc(sizeof (*pup
), KM_SLEEP
);
1498 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
1501 * We don't want the full treatment of prlock(pnp) here.
1502 * This file is world-readable and never goes invalid.
1503 * It doesn't matter if we are in the middle of an exec().
1506 mutex_exit(&pr_pidlock
);
1511 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1512 if (pnp
->pr_common
->prc_thread
== NULL
) {
1517 if (uiop
->uio_offset
>= sizeof (prusage_t
)) {
1523 pup
->pr_tstamp
= gethrtime();
1524 prgetusage(pnp
->pr_common
->prc_thread
, pup
);
1528 prcvtusage(pup
, upup
);
1530 error
= pr_uioread(upup
, sizeof (prusage_t
), uiop
);
1532 kmem_free(pup
, sizeof (*pup
));
1533 kmem_free(upup
, sizeof (*upup
));
1539 pr_read_xregs(prnode_t
*pnp
, uio_t
*uiop
)
1541 #if defined(__sparc)
1548 ASSERT(pnp
->pr_type
== PR_XREGS
);
1550 xreg
= kmem_zalloc(sizeof (prxregset_t
), KM_SLEEP
);
1552 if ((error
= prlock(pnp
, ZNO
)) != 0)
1555 p
= pnp
->pr_common
->prc_proc
;
1556 t
= pnp
->pr_common
->prc_thread
;
1558 size
= prhasx(p
)? prgetprxregsize(p
) : 0;
1559 if (uiop
->uio_offset
>= size
) {
1564 /* drop p->p_lock while (possibly) touching the stack */
1565 mutex_exit(&p
->p_lock
);
1566 prgetprxregs(ttolwp(t
), xreg
);
1567 mutex_enter(&p
->p_lock
);
1570 error
= pr_uioread(xreg
, size
, uiop
);
1572 kmem_free(xreg
, sizeof (prxregset_t
));
1580 pr_read_spymaster(prnode_t
*pnp
, uio_t
*uiop
)
1586 ASSERT(pnp
->pr_type
== PR_SPYMASTER
);
1588 if ((error
= prlock(pnp
, ZNO
)) != 0)
1591 lwp
= pnp
->pr_common
->prc_thread
->t_lwp
;
1593 if (lwp
->lwp_spymaster
== NULL
) {
1598 bcopy(lwp
->lwp_spymaster
, &psinfo
, sizeof (psinfo_t
));
1601 return (pr_uioread(&psinfo
, sizeof (psinfo
), uiop
));
1604 #if defined(__sparc)
1607 pr_read_gwindows(prnode_t
*pnp
, uio_t
*uiop
)
1615 ASSERT(pnp
->pr_type
== PR_GWINDOWS
);
1617 gwp
= kmem_zalloc(sizeof (gwindows_t
), KM_SLEEP
);
1619 if ((error
= prlock(pnp
, ZNO
)) != 0)
1622 p
= pnp
->pr_common
->prc_proc
;
1623 t
= pnp
->pr_common
->prc_thread
;
1626 * Drop p->p_lock while touching the stack.
1627 * The P_PR_LOCK flag prevents the lwp from
1628 * disappearing while we do this.
1630 mutex_exit(&p
->p_lock
);
1631 if ((size
= prnwindows(ttolwp(t
))) != 0)
1632 size
= sizeof (gwindows_t
) -
1633 (SPARC_MAXREGWINDOW
- size
) * sizeof (struct rwindow
);
1634 if (uiop
->uio_offset
>= size
) {
1635 mutex_enter(&p
->p_lock
);
1639 prgetwindows(ttolwp(t
), gwp
);
1640 mutex_enter(&p
->p_lock
);
1643 error
= pr_uioread(gwp
, size
, uiop
);
1645 kmem_free(gwp
, sizeof (gwindows_t
));
1651 pr_read_asrs(prnode_t
*pnp
, uio_t
*uiop
)
1655 ASSERT(pnp
->pr_type
== PR_ASRS
);
1657 /* the asrs file exists only for sparc v9 _LP64 processes */
1658 if ((error
= prlock(pnp
, ZNO
)) == 0) {
1659 proc_t
*p
= pnp
->pr_common
->prc_proc
;
1660 kthread_t
*t
= pnp
->pr_common
->prc_thread
;
1663 if (p
->p_model
!= DATAMODEL_LP64
||
1664 uiop
->uio_offset
>= sizeof (asrset_t
)) {
1670 * Drop p->p_lock while touching the stack.
1671 * The P_PR_LOCK flag prevents the lwp from
1672 * disappearing while we do this.
1674 mutex_exit(&p
->p_lock
);
1675 prgetasregs(ttolwp(t
), asrset
);
1676 mutex_enter(&p
->p_lock
);
1679 error
= pr_uioread(&asrset
[0], sizeof (asrset_t
), uiop
);
1685 #endif /* __sparc */
1688 pr_read_piddir(prnode_t
*pnp
, uio_t
*uiop
)
1690 ASSERT(pnp
->pr_type
== PR_PIDDIR
);
1691 ASSERT(pnp
->pr_pidfile
!= NULL
);
1693 /* use the underlying PR_PIDFILE to read the process */
1694 pnp
= VTOP(pnp
->pr_pidfile
);
1695 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
1697 return (pr_read_pidfile(pnp
, uiop
));
1701 pr_read_pidfile(prnode_t
*pnp
, uio_t
*uiop
)
1705 ASSERT(pnp
->pr_type
== PR_PIDFILE
|| pnp
->pr_type
== PR_LWPIDFILE
);
1707 if ((error
= prlock(pnp
, ZNO
)) == 0) {
1708 proc_t
*p
= pnp
->pr_common
->prc_proc
;
1709 struct as
*as
= p
->p_as
;
1711 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
1713 * /proc I/O cannot be done to a system process.
1715 error
= EIO
; /* old /proc semantics */
1718 * We drop p_lock because we don't want to hold
1719 * it over an I/O operation because that could
1720 * lead to deadlock with the clock thread.
1721 * The process will not disappear and its address
1722 * space will not change because it is marked P_PR_LOCK.
1724 mutex_exit(&p
->p_lock
);
1725 error
= prusrio(p
, UIO_READ
, uiop
, 1);
1726 mutex_enter(&p
->p_lock
);
1734 #ifdef _SYSCALL32_IMPL
1737 * Array of ILP32 read functions, indexed by /proc file type.
1739 static int pr_read_status_32(),
1740 pr_read_lstatus_32(), pr_read_psinfo_32(), pr_read_lpsinfo_32(),
1741 pr_read_map_32(), pr_read_rmap_32(), pr_read_xmap_32(),
1742 pr_read_sigact_32(), pr_read_auxv_32(),
1743 pr_read_usage_32(), pr_read_lusage_32(), pr_read_pagedata_32(),
1744 pr_read_watch_32(), pr_read_lwpstatus_32(), pr_read_lwpsinfo_32(),
1745 pr_read_lwpusage_32(), pr_read_spymaster_32(),
1746 #if defined(__sparc)
1747 pr_read_gwindows_32(),
1749 pr_read_opagedata_32();
1751 static int (*pr_read_function_32
[PR_NFILES
])() = {
1752 pr_read_inval
, /* /proc */
1753 pr_read_inval
, /* /proc/self */
1754 pr_read_piddir
, /* /proc/<pid> (old /proc read()) */
1755 pr_read_as
, /* /proc/<pid>/as */
1756 pr_read_inval
, /* /proc/<pid>/ctl */
1757 pr_read_status_32
, /* /proc/<pid>/status */
1758 pr_read_lstatus_32
, /* /proc/<pid>/lstatus */
1759 pr_read_psinfo_32
, /* /proc/<pid>/psinfo */
1760 pr_read_lpsinfo_32
, /* /proc/<pid>/lpsinfo */
1761 pr_read_map_32
, /* /proc/<pid>/map */
1762 pr_read_rmap_32
, /* /proc/<pid>/rmap */
1763 pr_read_xmap_32
, /* /proc/<pid>/xmap */
1764 pr_read_cred
, /* /proc/<pid>/cred */
1765 pr_read_sigact_32
, /* /proc/<pid>/sigact */
1766 pr_read_auxv_32
, /* /proc/<pid>/auxv */
1768 pr_read_ldt
, /* /proc/<pid>/ldt */
1770 pr_read_usage_32
, /* /proc/<pid>/usage */
1771 pr_read_lusage_32
, /* /proc/<pid>/lusage */
1772 pr_read_pagedata_32
, /* /proc/<pid>/pagedata */
1773 pr_read_watch_32
, /* /proc/<pid>/watch */
1774 pr_read_inval
, /* /proc/<pid>/cwd */
1775 pr_read_inval
, /* /proc/<pid>/root */
1776 pr_read_inval
, /* /proc/<pid>/fd */
1777 pr_read_inval
, /* /proc/<pid>/fd/nn */
1778 pr_read_inval
, /* /proc/<pid>/object */
1779 pr_read_inval
, /* /proc/<pid>/object/xxx */
1780 pr_read_inval
, /* /proc/<pid>/lwp */
1781 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid> */
1782 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
1783 pr_read_lwpstatus_32
, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
1784 pr_read_lwpsinfo_32
, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1785 pr_read_lwpusage_32
, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1786 pr_read_xregs
, /* /proc/<pid>/lwp/<lwpid>/xregs */
1787 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/templates */
1788 pr_read_inval
, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1789 pr_read_spymaster_32
, /* /proc/<pid>/lwp/<lwpid>/spymaster */
1790 #if defined(__sparc)
1791 pr_read_gwindows_32
, /* /proc/<pid>/lwp/<lwpid>/gwindows */
1792 pr_read_asrs
, /* /proc/<pid>/lwp/<lwpid>/asrs */
1794 pr_read_priv
, /* /proc/<pid>/priv */
1795 pr_read_inval
, /* /proc/<pid>/path */
1796 pr_read_inval
, /* /proc/<pid>/path/xxx */
1797 pr_read_inval
, /* /proc/<pid>/contracts */
1798 pr_read_inval
, /* /proc/<pid>/contracts/<ctid> */
1799 pr_read_pidfile
, /* old process file */
1800 pr_read_pidfile
, /* old lwp file */
1801 pr_read_opagedata_32
, /* old pagedata file */
1805 pr_read_status_32(prnode_t
*pnp
, uio_t
*uiop
)
1811 ASSERT(pnp
->pr_type
== PR_STATUS
);
1814 * We kmem_alloc() the pstatus structure because
1815 * it is so big it might blow the kernel stack.
1817 sp
= kmem_alloc(sizeof (*sp
), KM_SLEEP
);
1818 if ((error
= prlock(pnp
, ZNO
)) == 0) {
1820 * A 32-bit process cannot get the status of a 64-bit process.
1821 * The fields for the 64-bit quantities are not large enough.
1823 p
= pnp
->pr_common
->prc_proc
;
1824 if (PROCESS_NOT_32BIT(p
)) {
1828 prgetstatus32(pnp
->pr_common
->prc_proc
, sp
,
1829 VTOZONE(PTOV(pnp
)));
1831 error
= pr_uioread(sp
, sizeof (*sp
), uiop
);
1834 kmem_free((caddr_t
)sp
, sizeof (*sp
));
1839 pr_read_lstatus_32(prnode_t
*pnp
, uio_t
*uiop
)
1851 ASSERT(pnp
->pr_type
== PR_LSTATUS
);
1853 if ((error
= prlock(pnp
, ZNO
)) != 0)
1855 p
= pnp
->pr_common
->prc_proc
;
1857 * A 32-bit process cannot get the status of a 64-bit process.
1858 * The fields for the 64-bit quantities are not large enough.
1860 if (PROCESS_NOT_32BIT(p
)) {
1865 size
= sizeof (prheader32_t
) + nlwp
* LSPAN32(lwpstatus32_t
);
1867 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1868 mutex_exit(&p
->p_lock
);
1869 php
= kmem_zalloc(size
, KM_SLEEP
);
1870 mutex_enter(&p
->p_lock
);
1871 /* p->p_lwpcnt can't change while process is locked */
1872 ASSERT(nlwp
== p
->p_lwpcnt
);
1874 php
->pr_nent
= nlwp
;
1875 php
->pr_entsize
= LSPAN32(lwpstatus32_t
);
1877 sp
= (lwpstatus32_t
*)(php
+ 1);
1878 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
1879 if (ldp
->ld_entry
== NULL
||
1880 (t
= ldp
->ld_entry
->le_thread
) == NULL
)
1882 prgetlwpstatus32(t
, sp
, VTOZONE(PTOV(pnp
)));
1883 sp
= (lwpstatus32_t
*)((caddr_t
)sp
+ LSPAN32(lwpstatus32_t
));
1887 error
= pr_uioread(php
, size
, uiop
);
1888 kmem_free(php
, size
);
1893 pr_read_psinfo_32(prnode_t
*pnp
, uio_t
*uiop
)
1899 ASSERT(pnp
->pr_type
== PR_PSINFO
);
1902 * We don't want the full treatment of prlock(pnp) here.
1903 * This file is world-readable and never goes invalid.
1904 * It doesn't matter if we are in the middle of an exec().
1907 mutex_exit(&pr_pidlock
);
1911 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1912 prgetpsinfo32(p
, &psinfo
);
1914 error
= pr_uioread(&psinfo
, sizeof (psinfo
), uiop
);
1920 pr_read_lpsinfo_32(prnode_t
*pnp
, uio_t
*uiop
)
1933 ASSERT(pnp
->pr_type
== PR_LPSINFO
);
1936 * We don't want the full treatment of prlock(pnp) here.
1937 * This file is world-readable and never goes invalid.
1938 * It doesn't matter if we are in the middle of an exec().
1941 mutex_exit(&pr_pidlock
);
1944 ASSERT(p
== pnp
->pr_common
->prc_proc
);
1945 if ((nlwp
= p
->p_lwpcnt
+ p
->p_zombcnt
) == 0) {
1949 size
= sizeof (prheader32_t
) + nlwp
* LSPAN32(lwpsinfo32_t
);
1951 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1952 mutex_exit(&p
->p_lock
);
1953 php
= kmem_zalloc(size
, KM_SLEEP
);
1954 mutex_enter(&p
->p_lock
);
1955 /* p->p_lwpcnt can't change while process is locked */
1956 ASSERT(nlwp
== p
->p_lwpcnt
+ p
->p_zombcnt
);
1958 php
->pr_nent
= nlwp
;
1959 php
->pr_entsize
= LSPAN32(lwpsinfo32_t
);
1961 sp
= (lwpsinfo32_t
*)(php
+ 1);
1962 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
1963 if ((lep
= ldp
->ld_entry
) == NULL
)
1965 if ((t
= lep
->le_thread
) != NULL
)
1966 prgetlwpsinfo32(t
, sp
);
1968 bzero(sp
, sizeof (*sp
));
1969 sp
->pr_lwpid
= lep
->le_lwpid
;
1970 sp
->pr_state
= SZOMB
;
1972 sp
->pr_start
.tv_sec
= (time32_t
)lep
->le_start
;
1974 sp
= (lwpsinfo32_t
*)((caddr_t
)sp
+ LSPAN32(lwpsinfo32_t
));
1978 error
= pr_uioread(php
, size
, uiop
);
1979 kmem_free(php
, size
);
1984 pr_read_map_common_32(prnode_t
*pnp
, uio_t
*uiop
, prnodetype_t type
)
1992 if ((error
= prlock(pnp
, ZNO
)) != 0)
1995 p
= pnp
->pr_common
->prc_proc
;
1998 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
2003 if (PROCESS_NOT_32BIT(p
)) {
2008 if (!AS_LOCK_TRYENTER(as
, RW_WRITER
)) {
2011 goto readmap32_common
;
2013 mutex_exit(&p
->p_lock
);
2017 error
= prgetxmap32(p
, &iolhead
);
2020 error
= prgetmap32(p
, 1, &iolhead
);
2023 error
= prgetmap32(p
, 0, &iolhead
);
2027 mutex_enter(&p
->p_lock
);
2030 error
= pr_iol_uiomove_and_free(&iolhead
, uiop
, error
);
2036 pr_read_map_32(prnode_t
*pnp
, uio_t
*uiop
)
2038 ASSERT(pnp
->pr_type
== PR_MAP
);
2039 return (pr_read_map_common_32(pnp
, uiop
, pnp
->pr_type
));
2043 pr_read_rmap_32(prnode_t
*pnp
, uio_t
*uiop
)
2045 ASSERT(pnp
->pr_type
== PR_RMAP
);
2046 return (pr_read_map_common_32(pnp
, uiop
, pnp
->pr_type
));
2050 pr_read_xmap_32(prnode_t
*pnp
, uio_t
*uiop
)
2052 ASSERT(pnp
->pr_type
== PR_XMAP
);
2053 return (pr_read_map_common_32(pnp
, uiop
, pnp
->pr_type
));
2057 pr_read_sigact_32(prnode_t
*pnp
, uio_t
*uiop
)
2059 int nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
2061 struct sigaction32
*sap
;
2066 ASSERT(pnp
->pr_type
== PR_SIGACT
);
2069 * We kmem_alloc() the sigaction32 array because
2070 * it is so big it might blow the kernel stack.
2072 sap
= kmem_alloc((nsig
-1) * sizeof (struct sigaction32
), KM_SLEEP
);
2074 if ((error
= prlock(pnp
, ZNO
)) != 0)
2076 p
= pnp
->pr_common
->prc_proc
;
2078 if (PROCESS_NOT_32BIT(p
)) {
2084 if (uiop
->uio_offset
>= (nsig
-1) * sizeof (struct sigaction32
)) {
2090 for (sig
= 1; sig
< nsig
; sig
++)
2091 prgetaction32(p
, up
, sig
, &sap
[sig
-1]);
2094 error
= pr_uioread(sap
, (nsig
- 1) * sizeof (struct sigaction32
), uiop
);
2096 kmem_free(sap
, (nsig
-1) * sizeof (struct sigaction32
));
2101 pr_read_auxv_32(prnode_t
*pnp
, uio_t
*uiop
)
2103 auxv32_t auxv
[__KERN_NAUXV_IMPL
];
2109 ASSERT(pnp
->pr_type
== PR_AUXV
);
2111 if ((error
= prlock(pnp
, ZNO
)) != 0)
2113 p
= pnp
->pr_common
->prc_proc
;
2115 if (PROCESS_NOT_32BIT(p
)) {
2120 if (uiop
->uio_offset
>= sizeof (auxv
)) {
2126 for (i
= 0; i
< __KERN_NAUXV_IMPL
; i
++) {
2127 auxv
[i
].a_type
= (int32_t)up
->u_auxv
[i
].a_type
;
2128 auxv
[i
].a_un
.a_val
= (int32_t)up
->u_auxv
[i
].a_un
.a_val
;
2132 return (pr_uioread(auxv
, sizeof (auxv
), uiop
));
2136 pr_read_usage_32(prnode_t
*pnp
, uio_t
*uiop
)
2144 ASSERT(pnp
->pr_type
== PR_USAGE
);
2146 /* allocate now, before locking the process */
2147 pup
= kmem_zalloc(sizeof (*pup
), KM_SLEEP
);
2148 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
2151 * We don't want the full treatment of prlock(pnp) here.
2152 * This file is world-readable and never goes invalid.
2153 * It doesn't matter if we are in the middle of an exec().
2156 mutex_exit(&pr_pidlock
);
2161 ASSERT(p
== pnp
->pr_common
->prc_proc
);
2163 if (uiop
->uio_offset
>= sizeof (prusage32_t
)) {
2169 pup
->pr_tstamp
= gethrtime();
2171 pup
->pr_count
= p
->p_defunct
;
2172 pup
->pr_create
= p
->p_mstart
;
2173 pup
->pr_term
= p
->p_mterm
;
2175 pup
->pr_rtime
= p
->p_mlreal
;
2176 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
2177 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
2178 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
2179 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
2180 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
2181 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
2182 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
2183 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
2184 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
2185 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
2187 pup
->pr_minf
= p
->p_ru
.minflt
;
2188 pup
->pr_majf
= p
->p_ru
.majflt
;
2189 pup
->pr_nswap
= p
->p_ru
.nswap
;
2190 pup
->pr_inblk
= p
->p_ru
.inblock
;
2191 pup
->pr_oublk
= p
->p_ru
.oublock
;
2192 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
2193 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
2194 pup
->pr_sigs
= p
->p_ru
.nsignals
;
2195 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
2196 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
2197 pup
->pr_sysc
= p
->p_ru
.sysc
;
2198 pup
->pr_ioch
= p
->p_ru
.ioch
;
2201 * Add the usage information for each active lwp.
2203 if ((t
= p
->p_tlist
) != NULL
&&
2204 !(pnp
->pr_pcommon
->prc_flags
& PRC_DESTROY
)) {
2206 if (t
->t_proc_flag
& TP_LWPEXIT
)
2210 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2215 prcvtusage32(pup
, upup
);
2217 error
= pr_uioread(upup
, sizeof (prusage32_t
), uiop
);
2219 kmem_free(pup
, sizeof (*pup
));
2220 kmem_free(upup
, sizeof (*upup
));
2225 pr_read_lusage_32(prnode_t
*pnp
, uio_t
*uiop
)
2239 ASSERT(pnp
->pr_type
== PR_LUSAGE
);
2242 * We don't want the full treatment of prlock(pnp) here.
2243 * This file is world-readable and never goes invalid.
2244 * It doesn't matter if we are in the middle of an exec().
2247 mutex_exit(&pr_pidlock
);
2250 ASSERT(p
== pnp
->pr_common
->prc_proc
);
2251 if ((nlwp
= p
->p_lwpcnt
) == 0) {
2256 size
= sizeof (prheader32_t
) + (nlwp
+ 1) * LSPAN32(prusage32_t
);
2257 if (uiop
->uio_offset
>= size
) {
2262 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2263 mutex_exit(&p
->p_lock
);
2264 pup
= kmem_zalloc(size
+ sizeof (prhusage_t
), KM_SLEEP
);
2265 mutex_enter(&p
->p_lock
);
2266 /* p->p_lwpcnt can't change while process is locked */
2267 ASSERT(nlwp
== p
->p_lwpcnt
);
2269 php
= (prheader32_t
*)(pup
+ 1);
2270 upup
= (prusage32_t
*)(php
+ 1);
2272 php
->pr_nent
= nlwp
+ 1;
2273 php
->pr_entsize
= LSPAN32(prusage32_t
);
2275 curtime
= gethrtime();
2278 * First the summation over defunct lwps.
2280 pup
->pr_count
= p
->p_defunct
;
2281 pup
->pr_tstamp
= curtime
;
2282 pup
->pr_create
= p
->p_mstart
;
2283 pup
->pr_term
= p
->p_mterm
;
2285 pup
->pr_rtime
= p
->p_mlreal
;
2286 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
2287 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
2288 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
2289 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
2290 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
2291 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
2292 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
2293 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
2294 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
2295 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
2297 pup
->pr_minf
= p
->p_ru
.minflt
;
2298 pup
->pr_majf
= p
->p_ru
.majflt
;
2299 pup
->pr_nswap
= p
->p_ru
.nswap
;
2300 pup
->pr_inblk
= p
->p_ru
.inblock
;
2301 pup
->pr_oublk
= p
->p_ru
.oublock
;
2302 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
2303 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
2304 pup
->pr_sigs
= p
->p_ru
.nsignals
;
2305 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
2306 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
2307 pup
->pr_sysc
= p
->p_ru
.sysc
;
2308 pup
->pr_ioch
= p
->p_ru
.ioch
;
2310 prcvtusage32(pup
, upup
);
2313 * Fill one prusage struct for each active lwp.
2315 for (ldp
= p
->p_lwpdir
, i
= 0; i
< p
->p_lwpdir_sz
; i
++, ldp
++) {
2316 if (ldp
->ld_entry
== NULL
||
2317 (t
= ldp
->ld_entry
->le_thread
) == NULL
)
2319 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2322 upup
= (prusage32_t
*)
2323 ((caddr_t
)upup
+ LSPAN32(prusage32_t
));
2325 prcvtusage32(pup
, upup
);
2331 error
= pr_uioread(php
, size
, uiop
);
2332 kmem_free(pup
, size
+ sizeof (prhusage_t
));
2337 pr_read_pagedata_32(prnode_t
*pnp
, uio_t
*uiop
)
2342 ASSERT(pnp
->pr_type
== PR_PAGEDATA
);
2344 if ((error
= prlock(pnp
, ZNO
)) != 0)
2347 p
= pnp
->pr_common
->prc_proc
;
2348 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
2353 if (PROCESS_NOT_32BIT(p
)) {
2358 mutex_exit(&p
->p_lock
);
2359 error
= prpdread32(p
, pnp
->pr_hatid
, uiop
);
2360 mutex_enter(&p
->p_lock
);
2367 pr_read_opagedata_32(prnode_t
*pnp
, uio_t
*uiop
)
2373 ASSERT(pnp
->pr_type
== PR_OPAGEDATA
);
2375 if ((error
= prlock(pnp
, ZNO
)) != 0)
2378 p
= pnp
->pr_common
->prc_proc
;
2381 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
2386 if (PROCESS_NOT_32BIT(p
)) {
2391 mutex_exit(&p
->p_lock
);
2392 error
= oprpdread32(as
, pnp
->pr_hatid
, uiop
);
2393 mutex_enter(&p
->p_lock
);
2400 pr_read_watch_32(prnode_t
*pnp
, uio_t
*uiop
)
2408 struct watched_area
*pwarea
;
2410 ASSERT(pnp
->pr_type
== PR_WATCH
);
2412 if ((error
= prlock(pnp
, ZNO
)) != 0)
2415 p
= pnp
->pr_common
->prc_proc
;
2416 if (PROCESS_NOT_32BIT(p
)) {
2420 nwarea
= avl_numnodes(&p
->p_warea
);
2421 size
= nwarea
* sizeof (prwatch32_t
);
2422 if (uiop
->uio_offset
>= size
) {
2427 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2428 mutex_exit(&p
->p_lock
);
2429 Bpwp
= pwp
= kmem_zalloc(size
, KM_SLEEP
);
2430 mutex_enter(&p
->p_lock
);
2431 /* p->p_nwarea can't change while process is locked */
2432 ASSERT(nwarea
== avl_numnodes(&p
->p_warea
));
2434 /* gather the watched areas */
2435 for (pwarea
= avl_first(&p
->p_warea
); pwarea
!= NULL
;
2436 pwarea
= AVL_NEXT(&p
->p_warea
, pwarea
), pwp
++) {
2437 pwp
->pr_vaddr
= (caddr32_t
)(uintptr_t)pwarea
->wa_vaddr
;
2438 pwp
->pr_size
= (size32_t
)(pwarea
->wa_eaddr
- pwarea
->wa_vaddr
);
2439 pwp
->pr_wflags
= (int)pwarea
->wa_flags
;
2444 error
= pr_uioread(Bpwp
, size
, uiop
);
2445 kmem_free(Bpwp
, size
);
2450 pr_read_lwpstatus_32(prnode_t
*pnp
, uio_t
*uiop
)
2456 ASSERT(pnp
->pr_type
== PR_LWPSTATUS
);
2459 * We kmem_alloc() the lwpstatus structure because
2460 * it is so big it might blow the kernel stack.
2462 sp
= kmem_alloc(sizeof (*sp
), KM_SLEEP
);
2464 if ((error
= prlock(pnp
, ZNO
)) != 0)
2468 * A 32-bit process cannot get the status of a 64-bit process.
2469 * The fields for the 64-bit quantities are not large enough.
2471 p
= pnp
->pr_common
->prc_proc
;
2472 if (PROCESS_NOT_32BIT(p
)) {
2478 if (uiop
->uio_offset
>= sizeof (*sp
)) {
2483 prgetlwpstatus32(pnp
->pr_common
->prc_thread
, sp
, VTOZONE(PTOV(pnp
)));
2486 error
= pr_uioread(sp
, sizeof (*sp
), uiop
);
2488 kmem_free(sp
, sizeof (*sp
));
2493 pr_read_lwpsinfo_32(prnode_t
*pnp
, uio_t
*uiop
)
2495 lwpsinfo32_t lwpsinfo
;
2500 ASSERT(pnp
->pr_type
== PR_LWPSINFO
);
2503 * We don't want the full treatment of prlock(pnp) here.
2504 * This file is world-readable and never goes invalid.
2505 * It doesn't matter if we are in the middle of an exec().
2508 mutex_exit(&pr_pidlock
);
2511 ASSERT(p
== pnp
->pr_common
->prc_proc
);
2512 if (pnp
->pr_common
->prc_tslot
== -1) {
2517 if (uiop
->uio_offset
>= sizeof (lwpsinfo
)) {
2522 if ((t
= pnp
->pr_common
->prc_thread
) != NULL
)
2523 prgetlwpsinfo32(t
, &lwpsinfo
);
2525 lep
= p
->p_lwpdir
[pnp
->pr_common
->prc_tslot
].ld_entry
;
2526 bzero(&lwpsinfo
, sizeof (lwpsinfo
));
2527 lwpsinfo
.pr_lwpid
= lep
->le_lwpid
;
2528 lwpsinfo
.pr_state
= SZOMB
;
2529 lwpsinfo
.pr_sname
= 'Z';
2530 lwpsinfo
.pr_start
.tv_sec
= (time32_t
)lep
->le_start
;
2534 return (pr_uioread(&lwpsinfo
, sizeof (lwpsinfo
), uiop
));
2538 pr_read_lwpusage_32(prnode_t
*pnp
, uio_t
*uiop
)
2545 ASSERT(pnp
->pr_type
== PR_LWPUSAGE
);
2547 /* allocate now, before locking the process */
2548 pup
= kmem_zalloc(sizeof (*pup
), KM_SLEEP
);
2549 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
2552 * We don't want the full treatment of prlock(pnp) here.
2553 * This file is world-readable and never goes invalid.
2554 * It doesn't matter if we are in the middle of an exec().
2557 mutex_exit(&pr_pidlock
);
2562 ASSERT(p
== pnp
->pr_common
->prc_proc
);
2563 if (pnp
->pr_common
->prc_thread
== NULL
) {
2568 if (uiop
->uio_offset
>= sizeof (prusage32_t
)) {
2574 pup
->pr_tstamp
= gethrtime();
2575 prgetusage(pnp
->pr_common
->prc_thread
, pup
);
2579 prcvtusage32(pup
, upup
);
2581 error
= pr_uioread(upup
, sizeof (prusage32_t
), uiop
);
2583 kmem_free(pup
, sizeof (*pup
));
2584 kmem_free(upup
, sizeof (*upup
));
2589 pr_read_spymaster_32(prnode_t
*pnp
, uio_t
*uiop
)
2595 ASSERT(pnp
->pr_type
== PR_SPYMASTER
);
2597 if ((error
= prlock(pnp
, ZNO
)) != 0)
2600 lwp
= pnp
->pr_common
->prc_thread
->t_lwp
;
2602 if (lwp
->lwp_spymaster
== NULL
) {
2607 psinfo_kto32(lwp
->lwp_spymaster
, &psinfo
);
2610 return (pr_uioread(&psinfo
, sizeof (psinfo
), uiop
));
2613 #if defined(__sparc)
2615 pr_read_gwindows_32(prnode_t
*pnp
, uio_t
*uiop
)
2623 ASSERT(pnp
->pr_type
== PR_GWINDOWS
);
2625 gwp
= kmem_zalloc(sizeof (gwindows32_t
), KM_SLEEP
);
2627 if ((error
= prlock(pnp
, ZNO
)) != 0)
2630 p
= pnp
->pr_common
->prc_proc
;
2631 t
= pnp
->pr_common
->prc_thread
;
2633 if (PROCESS_NOT_32BIT(p
)) {
2640 * Drop p->p_lock while touching the stack.
2641 * The P_PR_LOCK flag prevents the lwp from
2642 * disappearing while we do this.
2644 mutex_exit(&p
->p_lock
);
2645 if ((size
= prnwindows(ttolwp(t
))) != 0)
2646 size
= sizeof (gwindows32_t
) -
2647 (SPARC_MAXREGWINDOW
- size
) * sizeof (struct rwindow32
);
2648 if (uiop
->uio_offset
>= size
) {
2649 mutex_enter(&p
->p_lock
);
2653 prgetwindows32(ttolwp(t
), gwp
);
2654 mutex_enter(&p
->p_lock
);
2657 error
= pr_uioread(gwp
, size
, uiop
);
2659 kmem_free(gwp
, sizeof (gwindows32_t
));
2662 #endif /* __sparc */
2664 #endif /* _SYSCALL32_IMPL */
2668 prread(vnode_t
*vp
, uio_t
*uiop
, int ioflag
, cred_t
*cr
, caller_context_t
*ct
)
2670 prnode_t
*pnp
= VTOP(vp
);
2672 ASSERT(pnp
->pr_type
< PR_NFILES
);
2674 #ifdef _SYSCALL32_IMPL
2676 * What is read from the /proc files depends on the data
2677 * model of the caller. An LP64 process will see LP64
2678 * data. An ILP32 process will see ILP32 data.
2680 if (curproc
->p_model
== DATAMODEL_LP64
)
2681 return (pr_read_function
[pnp
->pr_type
](pnp
, uiop
));
2683 return (pr_read_function_32
[pnp
->pr_type
](pnp
, uiop
));
2685 return (pr_read_function
[pnp
->pr_type
](pnp
, uiop
));
2691 prwrite(vnode_t
*vp
, uio_t
*uiop
, int ioflag
, cred_t
*cr
, caller_context_t
*ct
)
2693 prnode_t
*pnp
= VTOP(vp
);
2698 ASSERT(pnp
->pr_type
< PR_NFILES
);
2701 * Only a handful of /proc files are writable, enumerate them here.
2703 switch (pnp
->pr_type
) {
2704 case PR_PIDDIR
: /* directory write()s: visceral revulsion. */
2705 ASSERT(pnp
->pr_pidfile
!= NULL
);
2706 /* use the underlying PR_PIDFILE to write the process */
2707 vp
= pnp
->pr_pidfile
;
2709 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
2716 if ((error
= prlock(pnp
, ZNO
)) == 0) {
2717 proc_t
*p
= pnp
->pr_common
->prc_proc
;
2718 struct as
*as
= p
->p_as
;
2720 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
2722 * /proc I/O cannot be done to a system process.
2725 #ifdef _SYSCALL32_IMPL
2726 } else if (curproc
->p_model
== DATAMODEL_ILP32
&&
2727 PROCESS_NOT_32BIT(p
)) {
2732 * See comments above (pr_read_pidfile)
2733 * about this locking dance.
2735 mutex_exit(&p
->p_lock
);
2736 error
= prusrio(p
, UIO_WRITE
, uiop
, old
);
2737 mutex_enter(&p
->p_lock
);
2745 resid
= uiop
->uio_resid
;
2747 * Perform the action on the control file
2748 * by passing curthreads credentials
2749 * and not target process's credentials.
2751 #ifdef _SYSCALL32_IMPL
2752 if (curproc
->p_model
== DATAMODEL_ILP32
)
2753 error
= prwritectl32(vp
, uiop
, CRED());
2755 error
= prwritectl(vp
, uiop
, CRED());
2757 error
= prwritectl(vp
, uiop
, CRED());
2760 * This hack makes sure that the EINTR is passed
2761 * all the way back to the caller's write() call.
2764 uiop
->uio_resid
= resid
;
2768 return ((vp
->v_type
== VDIR
)? EISDIR
: EBADF
);
2774 prgetattr(vnode_t
*vp
, vattr_t
*vap
, int flags
, cred_t
*cr
,
2775 caller_context_t
*ct
)
2777 prnode_t
*pnp
= VTOP(vp
);
2778 prnodetype_t type
= pnp
->pr_type
;
2785 extern uint_t nproc
;
2790 * This ugly bit of code allows us to keep both versions of this
2791 * function from the same source.
2794 int iam32bit
= (curproc
->p_model
== DATAMODEL_ILP32
);
2795 #define PR_OBJSIZE(obj32, obj64) \
2796 (iam32bit ? sizeof (obj32) : sizeof (obj64))
2797 #define PR_OBJSPAN(obj32, obj64) \
2798 (iam32bit ? LSPAN32(obj32) : LSPAN(obj64))
2800 #define PR_OBJSIZE(obj32, obj64) \
2802 #define PR_OBJSPAN(obj32, obj64) \
2807 * Return all the attributes. Should be refined
2808 * so that it returns only those asked for.
2809 * Most of this is complete fakery anyway.
2813 * For files in the /proc/<pid>/object directory,
2814 * return the attributes of the underlying object.
2815 * For files in the /proc/<pid>/fd directory,
2816 * return the attributes of the underlying file, but
2817 * make it look inaccessible if it is not a regular file.
2818 * Make directories look like symlinks.
2823 if (!(flags
& ATTR_REAL
))
2825 /* restrict full knowledge of the attributes to owner or root */
2826 if ((error
= praccess(vp
, 0, 0, cr
, ct
)) != 0)
2831 rvp
= pnp
->pr_realvp
;
2832 error
= VOP_GETATTR(rvp
, vap
, flags
, cr
, ct
);
2835 if (type
== PR_FD
) {
2836 if (rvp
->v_type
!= VREG
&& rvp
->v_type
!= VDIR
)
2839 vap
->va_mode
&= pnp
->pr_mode
;
2841 if (type
== PR_OBJECT
)
2842 vap
->va_mode
&= 07555;
2843 if (rvp
->v_type
== VDIR
&& !(flags
& ATTR_REAL
)) {
2844 vap
->va_type
= VLNK
;
2853 bzero(vap
, sizeof (*vap
));
2855 * Large Files: Internally proc now uses VPROC to indicate
2856 * a proc file. Since we have been returning VREG through
2857 * VOP_GETATTR() until now, we continue to do this so as
2858 * not to break apps depending on this return value.
2860 vap
->va_type
= (vp
->v_type
== VPROC
) ? VREG
: vp
->v_type
;
2861 vap
->va_mode
= pnp
->pr_mode
;
2862 vap
->va_fsid
= vp
->v_vfsp
->vfs_dev
;
2863 vap
->va_blksize
= DEV_BSIZE
;
2867 if (type
== PR_PROCDIR
) {
2870 vap
->va_nlink
= nproc
+ 2;
2871 vap
->va_nodeid
= (ino64_t
)PRROOTINO
;
2873 vap
->va_atime
= vap
->va_mtime
= vap
->va_ctime
= now
;
2874 vap
->va_size
= (v
.v_proc
+ 2) * PRSDSIZE
;
2875 vap
->va_nblocks
= btod(vap
->va_size
);
2880 * /proc/<pid>/self is a symbolic link, and has no prcommon member
2882 if (type
== PR_SELF
) {
2883 vap
->va_uid
= crgetruid(CRED());
2884 vap
->va_gid
= crgetrgid(CRED());
2885 vap
->va_nodeid
= (ino64_t
)PR_SELF
;
2887 vap
->va_atime
= vap
->va_mtime
= vap
->va_ctime
= now
;
2889 vap
->va_type
= VLNK
;
2895 mutex_exit(&pr_pidlock
);
2898 pcp
= pnp
->pr_common
;
2900 mutex_enter(&p
->p_crlock
);
2901 vap
->va_uid
= crgetruid(p
->p_cred
);
2902 vap
->va_gid
= crgetrgid(p
->p_cred
);
2903 mutex_exit(&p
->p_crlock
);
2906 vap
->va_nodeid
= pnp
->pr_ino
? pnp
->pr_ino
:
2907 pmkino(pcp
->prc_tslot
, pcp
->prc_slot
, pnp
->pr_type
);
2908 if ((pcp
->prc_flags
& PRC_LWP
) && pcp
->prc_tslot
!= -1) {
2909 vap
->va_atime
.tv_sec
= vap
->va_mtime
.tv_sec
=
2910 vap
->va_ctime
.tv_sec
=
2911 p
->p_lwpdir
[pcp
->prc_tslot
].ld_entry
->le_start
;
2912 vap
->va_atime
.tv_nsec
= vap
->va_mtime
.tv_nsec
=
2913 vap
->va_ctime
.tv_nsec
= 0;
2915 user_t
*up
= PTOU(p
);
2916 vap
->va_atime
.tv_sec
= vap
->va_mtime
.tv_sec
=
2917 vap
->va_ctime
.tv_sec
= up
->u_start
.tv_sec
;
2918 vap
->va_atime
.tv_nsec
= vap
->va_mtime
.tv_nsec
=
2919 vap
->va_ctime
.tv_nsec
= up
->u_start
.tv_nsec
;
2924 /* va_nlink: count 'lwp', 'object' and 'fd' directory links */
2926 vap
->va_size
= sizeof (piddir
);
2929 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2930 vap
->va_size
= 2 * PRSDSIZE
;
2932 mutex_exit(&p
->p_lock
);
2933 AS_LOCK_ENTER(as
, RW_WRITER
);
2934 if (as
->a_updatedir
)
2936 vap
->va_size
= (as
->a_sizedir
+ 2) * PRSDSIZE
;
2938 mutex_enter(&p
->p_lock
);
2943 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2944 vap
->va_size
= (P_FINFO(p
)->fi_nfiles
+ 4) * PRSDSIZE
;
2946 mutex_exit(&p
->p_lock
);
2947 AS_LOCK_ENTER(as
, RW_WRITER
);
2948 if (as
->a_updatedir
)
2950 vap
->va_size
= (as
->a_sizedir
+ 4 +
2951 P_FINFO(p
)->fi_nfiles
) * PRSDSIZE
;
2953 mutex_enter(&p
->p_lock
);
2961 vap
->va_type
= VLNK
;
2966 vap
->va_size
= (P_FINFO(p
)->fi_nfiles
+ 2) * PRSDSIZE
;
2970 * va_nlink: count each lwp as a directory link.
2971 * va_size: size of p_lwpdir + 2
2973 vap
->va_nlink
= p
->p_lwpcnt
+ p
->p_zombcnt
+ 2;
2974 vap
->va_size
= (p
->p_lwpdir_sz
+ 2) * PRSDSIZE
;
2978 vap
->va_size
= sizeof (lwpiddir
);
2982 vap
->va_size
= (avl_numnodes(&p
->p_ct_held
) + 2) * PRSDSIZE
;
2986 vap
->va_size
= (ct_ntypes
+ 2) * PRSDSIZE
;
2991 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
2994 vap
->va_size
= as
->a_resvsize
;
2997 vap
->va_size
= PR_OBJSIZE(pstatus32_t
, pstatus_t
);
3000 vap
->va_size
= PR_OBJSIZE(prheader32_t
, prheader_t
) +
3001 p
->p_lwpcnt
* PR_OBJSPAN(lwpstatus32_t
, lwpstatus_t
);
3004 vap
->va_size
= PR_OBJSIZE(psinfo32_t
, psinfo_t
);
3007 vap
->va_size
= PR_OBJSIZE(prheader32_t
, prheader_t
) +
3008 (p
->p_lwpcnt
+ p
->p_zombcnt
) *
3009 PR_OBJSPAN(lwpsinfo32_t
, lwpsinfo_t
);
3014 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
3017 mutex_exit(&p
->p_lock
);
3018 AS_LOCK_ENTER(as
, RW_WRITER
);
3020 vap
->va_mtime
= as
->a_updatetime
;
3021 if (type
== PR_XMAP
)
3022 vap
->va_size
= prnsegs(as
, 0) *
3023 PR_OBJSIZE(prxmap32_t
, prxmap_t
);
3025 vap
->va_size
= prnsegs(as
, type
== PR_RMAP
) *
3026 PR_OBJSIZE(prmap32_t
, prmap_t
);
3028 mutex_enter(&p
->p_lock
);
3032 mutex_enter(&p
->p_crlock
);
3033 vap
->va_size
= sizeof (prcred_t
);
3034 ngroups
= crgetngroups(p
->p_cred
);
3036 vap
->va_size
+= (ngroups
- 1) * sizeof (gid_t
);
3037 mutex_exit(&p
->p_crlock
);
3040 vap
->va_size
= prgetprivsize();
3043 nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
3044 vap
->va_size
= (nsig
-1) *
3045 PR_OBJSIZE(struct sigaction32
, struct sigaction
);
3048 vap
->va_size
= __KERN_NAUXV_IMPL
* PR_OBJSIZE(auxv32_t
, auxv_t
);
3052 mutex_exit(&p
->p_lock
);
3053 mutex_enter(&p
->p_ldtlock
);
3054 vap
->va_size
= prnldt(p
) * sizeof (struct ssd
);
3055 mutex_exit(&p
->p_ldtlock
);
3056 mutex_enter(&p
->p_lock
);
3060 vap
->va_size
= PR_OBJSIZE(prusage32_t
, prusage_t
);
3063 vap
->va_size
= PR_OBJSIZE(prheader32_t
, prheader_t
) +
3064 (p
->p_lwpcnt
+ 1) * PR_OBJSPAN(prusage32_t
, prusage_t
);
3067 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
3071 * We can drop p->p_lock before grabbing the
3072 * address space lock because p->p_as will not
3073 * change while the process is marked P_PR_LOCK.
3075 mutex_exit(&p
->p_lock
);
3076 AS_LOCK_ENTER(as
, RW_WRITER
);
3078 vap
->va_size
= iam32bit
?
3079 prpdsize32(as
) : prpdsize(as
);
3081 vap
->va_size
= prpdsize(as
);
3084 mutex_enter(&p
->p_lock
);
3088 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
)
3091 mutex_exit(&p
->p_lock
);
3092 AS_LOCK_ENTER(as
, RW_WRITER
);
3094 vap
->va_size
= iam32bit
?
3095 oprpdsize32(as
) : oprpdsize(as
);
3097 vap
->va_size
= oprpdsize(as
);
3100 mutex_enter(&p
->p_lock
);
3104 vap
->va_size
= avl_numnodes(&p
->p_warea
) *
3105 PR_OBJSIZE(prwatch32_t
, prwatch_t
);
3108 vap
->va_size
= PR_OBJSIZE(lwpstatus32_t
, lwpstatus_t
);
3111 vap
->va_size
= PR_OBJSIZE(lwpsinfo32_t
, lwpsinfo_t
);
3114 vap
->va_size
= PR_OBJSIZE(prusage32_t
, prusage_t
);
3118 vap
->va_size
= prgetprxregsize(p
);
3123 if (pnp
->pr_common
->prc_thread
->t_lwp
->lwp_spymaster
!= NULL
) {
3124 vap
->va_size
= PR_OBJSIZE(psinfo32_t
, psinfo_t
);
3129 #if defined(__sparc)
3136 * If there is no lwp then just make the size zero.
3137 * This can happen if the lwp exits between the VOP_LOOKUP()
3138 * of the /proc/<pid>/lwp/<lwpid>/gwindows file and the
3139 * VOP_GETATTR() of the resulting vnode.
3141 if ((t
= pcp
->prc_thread
) == NULL
) {
3146 * Drop p->p_lock while touching the stack.
3147 * The P_PR_LOCK flag prevents the lwp from
3148 * disappearing while we do this.
3150 mutex_exit(&p
->p_lock
);
3151 if ((n
= prnwindows(ttolwp(t
))) == 0)
3154 vap
->va_size
= PR_OBJSIZE(gwindows32_t
, gwindows_t
) -
3155 (SPARC_MAXREGWINDOW
- n
) *
3156 PR_OBJSIZE(struct rwindow32
, struct rwindow
);
3157 mutex_enter(&p
->p_lock
);
3162 if (p
->p_model
== DATAMODEL_LP64
)
3163 vap
->va_size
= sizeof (asrset_t
);
3177 vap
->va_nblocks
= (fsblkcnt64_t
)btod(vap
->va_size
);
3182 praccess(vnode_t
*vp
, int mode
, int flags
, cred_t
*cr
, caller_context_t
*ct
)
3184 prnode_t
*pnp
= VTOP(vp
);
3185 prnodetype_t type
= pnp
->pr_type
;
3193 if ((mode
& VWRITE
) && vn_is_readonly(vp
))
3203 * Disallow write access to the underlying objects.
3204 * Disallow access to underlying non-regular-file fds.
3205 * Disallow access to fds with other than existing open modes.
3207 rvp
= pnp
->pr_realvp
;
3208 vtype
= rvp
->v_type
;
3209 vmode
= pnp
->pr_mode
;
3210 if ((type
== PR_OBJECT
&& (mode
& VWRITE
)) ||
3211 (type
== PR_FD
&& vtype
!= VREG
&& vtype
!= VDIR
) ||
3212 (type
== PR_FD
&& (vmode
& mode
) != mode
&&
3213 secpolicy_proc_access(cr
) != 0))
3215 return (VOP_ACCESS(rvp
, mode
, flags
, cr
, ct
));
3217 case PR_PSINFO
: /* these files can be read by anyone */
3226 mutex_exit(&pr_pidlock
);
3234 * Except for the world-readable files above,
3235 * only /proc/pid exists if the process is a zombie.
3237 if ((error
= prlock(pnp
,
3238 (type
== PR_PIDDIR
)? ZYES
: ZNO
)) != 0)
3240 p
= pnp
->pr_common
->prc_proc
;
3242 error
= priv_proc_cred_perm(cr
, p
, NULL
, mode
);
3244 if (error
!= 0 || p
== curproc
|| (p
->p_flag
& SSYS
) ||
3245 p
->p_as
== &kas
|| (xvp
= p
->p_exec
) == NULL
) {
3249 * Determine if the process's executable is readable.
3250 * We have to drop p->p_lock before the secpolicy
3251 * and VOP operation.
3255 if (secpolicy_proc_access(cr
) != 0)
3256 error
= VOP_ACCESS(xvp
, VREAD
, 0, cr
, ct
);
3264 if (type
== PR_CURDIR
|| type
== PR_ROOTDIR
) {
3266 * Final access check on the underlying directory vnode.
3268 return (VOP_ACCESS(pnp
->pr_realvp
, mode
, flags
, cr
, ct
));
3272 * Visceral revulsion: For compatibility with old /proc,
3273 * allow the /proc/<pid> directory to be opened for writing.
3275 vmode
= pnp
->pr_mode
;
3276 if (type
== PR_PIDDIR
)
3278 if ((vmode
& mode
) != mode
)
3279 error
= secpolicy_proc_access(cr
);
3284 * Array of lookup functions, indexed by /proc file type.
3286 static vnode_t
*pr_lookup_notdir(), *pr_lookup_procdir(), *pr_lookup_piddir(),
3287 *pr_lookup_objectdir(), *pr_lookup_lwpdir(), *pr_lookup_lwpiddir(),
3288 *pr_lookup_fddir(), *pr_lookup_pathdir(), *pr_lookup_tmpldir(),
3291 static vnode_t
*(*pr_lookup_function
[PR_NFILES
])() = {
3292 pr_lookup_procdir
, /* /proc */
3293 pr_lookup_notdir
, /* /proc/self */
3294 pr_lookup_piddir
, /* /proc/<pid> */
3295 pr_lookup_notdir
, /* /proc/<pid>/as */
3296 pr_lookup_notdir
, /* /proc/<pid>/ctl */
3297 pr_lookup_notdir
, /* /proc/<pid>/status */
3298 pr_lookup_notdir
, /* /proc/<pid>/lstatus */
3299 pr_lookup_notdir
, /* /proc/<pid>/psinfo */
3300 pr_lookup_notdir
, /* /proc/<pid>/lpsinfo */
3301 pr_lookup_notdir
, /* /proc/<pid>/map */
3302 pr_lookup_notdir
, /* /proc/<pid>/rmap */
3303 pr_lookup_notdir
, /* /proc/<pid>/xmap */
3304 pr_lookup_notdir
, /* /proc/<pid>/cred */
3305 pr_lookup_notdir
, /* /proc/<pid>/sigact */
3306 pr_lookup_notdir
, /* /proc/<pid>/auxv */
3308 pr_lookup_notdir
, /* /proc/<pid>/ldt */
3310 pr_lookup_notdir
, /* /proc/<pid>/usage */
3311 pr_lookup_notdir
, /* /proc/<pid>/lusage */
3312 pr_lookup_notdir
, /* /proc/<pid>/pagedata */
3313 pr_lookup_notdir
, /* /proc/<pid>/watch */
3314 pr_lookup_notdir
, /* /proc/<pid>/cwd */
3315 pr_lookup_notdir
, /* /proc/<pid>/root */
3316 pr_lookup_fddir
, /* /proc/<pid>/fd */
3317 pr_lookup_notdir
, /* /proc/<pid>/fd/nn */
3318 pr_lookup_objectdir
, /* /proc/<pid>/object */
3319 pr_lookup_notdir
, /* /proc/<pid>/object/xxx */
3320 pr_lookup_lwpdir
, /* /proc/<pid>/lwp */
3321 pr_lookup_lwpiddir
, /* /proc/<pid>/lwp/<lwpid> */
3322 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
3323 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
3324 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3325 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3326 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/xregs */
3327 pr_lookup_tmpldir
, /* /proc/<pid>/lwp/<lwpid>/templates */
3328 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3329 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/spymaster */
3330 #if defined(__sparc)
3331 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/gwindows */
3332 pr_lookup_notdir
, /* /proc/<pid>/lwp/<lwpid>/asrs */
3334 pr_lookup_notdir
, /* /proc/<pid>/priv */
3335 pr_lookup_pathdir
, /* /proc/<pid>/path */
3336 pr_lookup_notdir
, /* /proc/<pid>/path/xxx */
3337 pr_lookup_ctdir
, /* /proc/<pid>/contracts */
3338 pr_lookup_notdir
, /* /proc/<pid>/contracts/<ctid> */
3339 pr_lookup_notdir
, /* old process file */
3340 pr_lookup_notdir
, /* old lwp file */
3341 pr_lookup_notdir
, /* old pagedata file */
3345 prlookup(vnode_t
*dp
, char *comp
, vnode_t
**vpp
, pathname_t
*pathp
,
3346 int flags
, vnode_t
*rdir
, cred_t
*cr
, caller_context_t
*ct
,
3347 int *direntflags
, pathname_t
*realpnp
)
3349 prnode_t
*pnp
= VTOP(dp
);
3350 prnodetype_t type
= pnp
->pr_type
;
3353 ASSERT(dp
->v_type
== VDIR
);
3354 ASSERT(type
< PR_NFILES
);
3356 if (type
!= PR_PROCDIR
&& strcmp(comp
, "..") == 0) {
3357 VN_HOLD(pnp
->pr_parent
);
3358 *vpp
= pnp
->pr_parent
;
3362 if (*comp
== '\0' ||
3363 strcmp(comp
, ".") == 0 || strcmp(comp
, "..") == 0) {
3372 /* restrict lookup permission to owner or root */
3373 if ((error
= praccess(dp
, VEXEC
, 0, cr
, ct
)) != 0)
3377 dp
= pnp
->pr_realvp
;
3378 return (VOP_LOOKUP(dp
, comp
, vpp
, pathp
, flags
, rdir
, cr
, ct
,
3379 direntflags
, realpnp
));
3384 if ((type
== PR_OBJECTDIR
|| type
== PR_FDDIR
|| type
== PR_PATHDIR
) &&
3385 (error
= praccess(dp
, VEXEC
, 0, cr
, ct
)) != 0)
3388 /* XXX - Do we need to pass ct, direntflags, or realpnp? */
3389 *vpp
= (pr_lookup_function
[type
](dp
, comp
));
3391 return ((*vpp
== NULL
) ? ENOENT
: 0);
3396 prcreate(vnode_t
*dp
, char *comp
, vattr_t
*vap
, vcexcl_t excl
,
3397 int mode
, vnode_t
**vpp
, cred_t
*cr
, int flag
, caller_context_t
*ct
,
3402 if ((error
= prlookup(dp
, comp
, vpp
, NULL
, 0, NULL
, cr
,
3403 ct
, NULL
, NULL
)) != 0) {
3404 if (error
== ENOENT
) /* can't O_CREAT nonexistent files */
3405 error
= EACCES
; /* unwriteable directories */
3407 if (excl
== EXCL
) /* O_EXCL */
3409 else if (vap
->va_mask
& AT_SIZE
) { /* O_TRUNC */
3413 if (vp
->v_type
== VDIR
)
3415 else if (vp
->v_type
!= VPROC
||
3416 VTOP(vp
)->pr_type
!= PR_FD
)
3418 else { /* /proc/<pid>/fd/<n> */
3419 vp
= VTOP(vp
)->pr_realvp
;
3420 mask
= vap
->va_mask
;
3421 vap
->va_mask
= AT_SIZE
;
3422 error
= VOP_SETATTR(vp
, vap
, 0, cr
, ct
);
3423 vap
->va_mask
= mask
;
3436 pr_lookup_notdir(vnode_t
*dp
, char *comp
)
3442 * Find or construct a process vnode for the given pid.
3445 pr_lookup_procdir(vnode_t
*dp
, char *comp
)
3454 ASSERT(VTOP(dp
)->pr_type
== PR_PROCDIR
);
3456 if (strcmp(comp
, "self") == 0) {
3457 pnp
= prgetnode(dp
, PR_SELF
);
3461 while ((c
= *comp
++) != '\0') {
3462 if (c
< '0' || c
> '9')
3464 pid
= 10*pid
+ c
- '0';
3470 pnp
= prgetnode(dp
, PR_PIDDIR
);
3472 mutex_enter(&pidlock
);
3473 if ((p
= prfind(pid
)) == NULL
|| p
->p_stat
== SIDL
) {
3474 mutex_exit(&pidlock
);
3478 ASSERT(p
->p_stat
!= 0);
3480 /* NOTE: we're holding pidlock across the policy call. */
3481 if (secpolicy_basic_procinfo(CRED(), p
, curproc
) != 0) {
3482 mutex_exit(&pidlock
);
3487 mutex_enter(&p
->p_lock
);
3488 mutex_exit(&pidlock
);
3491 * If a process vnode already exists and it is not invalid
3492 * and it was created by the current process and it belongs
3493 * to the same /proc mount point as our parent vnode, then
3494 * just use it and discard the newly-allocated prnode.
3496 for (vp
= p
->p_trace
; vp
!= NULL
; vp
= VTOP(vp
)->pr_next
) {
3497 if (!(VTOP(VTOP(vp
)->pr_pidfile
)->pr_flags
& PR_INVAL
) &&
3498 VTOP(vp
)->pr_owner
== curproc
&&
3499 vp
->v_vfsp
== dp
->v_vfsp
) {
3500 ASSERT(!(VTOP(vp
)->pr_flags
& PR_INVAL
));
3503 mutex_exit(&p
->p_lock
);
3507 pnp
->pr_owner
= curproc
;
3510 * prgetnode() initialized most of the prnode.
3513 pcp
= pnp
->pr_common
; /* the newly-allocated prcommon struct */
3514 if ((vp
= p
->p_trace
) != NULL
) {
3515 /* discard the new prcommon and use the existing prcommon */
3517 pcp
= VTOP(vp
)->pr_common
;
3518 mutex_enter(&pcp
->prc_mutex
);
3519 ASSERT(pcp
->prc_refcnt
> 0);
3521 mutex_exit(&pcp
->prc_mutex
);
3522 pnp
->pr_common
= pcp
;
3524 /* initialize the new prcommon struct */
3525 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
3526 pcp
->prc_flags
|= PRC_SYS
;
3527 if (p
->p_stat
== SZOMB
)
3528 pcp
->prc_flags
|= PRC_DESTROY
;
3530 pcp
->prc_datamodel
= p
->p_model
;
3531 pcp
->prc_pid
= p
->p_pid
;
3532 pcp
->prc_slot
= p
->p_slot
;
3534 pnp
->pr_pcommon
= pcp
;
3535 pnp
->pr_parent
= dp
;
3538 * Link in the old, invalid directory vnode so we
3539 * can later determine the last close of the file.
3541 pnp
->pr_next
= p
->p_trace
;
3542 p
->p_trace
= dp
= PTOV(pnp
);
3545 * Kludge for old /proc: initialize the PR_PIDFILE as well.
3547 vp
= pnp
->pr_pidfile
;
3549 pnp
->pr_ino
= ptoi(pcp
->prc_pid
);
3550 pnp
->pr_common
= pcp
;
3551 pnp
->pr_pcommon
= pcp
;
3552 pnp
->pr_parent
= dp
;
3553 pnp
->pr_next
= p
->p_plist
;
3556 mutex_exit(&p
->p_lock
);
3561 pr_lookup_piddir(vnode_t
*dp
, char *comp
)
3563 prnode_t
*dpnp
= VTOP(dp
);
3570 enum prnodetype type
;
3572 ASSERT(dpnp
->pr_type
== PR_PIDDIR
);
3574 for (i
= 0; i
< NPIDDIRFILES
; i
++) {
3575 /* Skip "." and ".." */
3576 dirp
= &piddir
[i
+2];
3577 if (strcmp(comp
, dirp
->d_name
) == 0)
3581 if (i
>= NPIDDIRFILES
)
3584 type
= (int)dirp
->d_ino
;
3585 pnp
= prgetnode(dp
, type
);
3587 p
= pr_p_lock(dpnp
);
3588 mutex_exit(&pr_pidlock
);
3593 if (dpnp
->pr_pcommon
->prc_flags
& PRC_DESTROY
) {
3609 vp
= (type
== PR_CURDIR
)? up
->u_cdir
:
3610 (up
->u_rdir
? up
->u_rdir
: rootdir
);
3612 if (vp
== NULL
) { /* can't happen? */
3618 * Fill in the prnode so future references will
3619 * be able to find the underlying object's vnode.
3622 pnp
->pr_realvp
= vp
;
3628 mutex_enter(&dpnp
->pr_mutex
);
3630 if ((vp
= dpnp
->pr_files
[i
]) != NULL
&&
3631 !(VTOP(vp
)->pr_flags
& PR_INVAL
)) {
3633 mutex_exit(&dpnp
->pr_mutex
);
3640 * prgetnode() initialized most of the prnode.
3643 pnp
->pr_common
= dpnp
->pr_common
;
3644 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
3645 pnp
->pr_parent
= dp
;
3649 dpnp
->pr_files
[i
] = vp
= PTOV(pnp
);
3652 * Link new vnode into list of all /proc vnodes for the process.
3654 if (vp
->v_type
== VPROC
) {
3655 pnp
->pr_next
= p
->p_plist
;
3658 mutex_exit(&dpnp
->pr_mutex
);
3664 pr_lookup_objectdir(vnode_t
*dp
, char *comp
)
3666 prnode_t
*dpnp
= VTOP(dp
);
3674 ASSERT(dpnp
->pr_type
== PR_OBJECTDIR
);
3676 pnp
= prgetnode(dp
, PR_OBJECT
);
3678 if (prlock(dpnp
, ZNO
) != 0) {
3682 p
= dpnp
->pr_common
->prc_proc
;
3683 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
3690 * We drop p_lock before grabbing the address space lock
3691 * in order to avoid a deadlock with the clock thread.
3692 * The process will not disappear and its address space
3693 * will not change because it is marked P_PR_LOCK.
3695 mutex_exit(&p
->p_lock
);
3696 AS_LOCK_ENTER(as
, RW_READER
);
3697 if ((seg
= AS_SEGFIRST(as
)) == NULL
) {
3701 if (strcmp(comp
, "a.out") == 0) {
3707 * Manufacture a filename for the "object" directory.
3709 vattr
.va_mask
= AT_FSID
|AT_NODEID
;
3710 if (seg
->s_ops
== &segvn_ops
&&
3711 SEGOP_GETVP(seg
, seg
->s_base
, &vp
) == 0 &&
3712 vp
!= NULL
&& vp
->v_type
== VREG
&&
3713 VOP_GETATTR(vp
, &vattr
, 0, CRED(), NULL
) == 0) {
3716 if (vp
== p
->p_exec
) /* "a.out" */
3718 pr_object_name(name
, vp
, &vattr
);
3719 if (strcmp(name
, comp
) == 0)
3722 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3730 mutex_enter(&p
->p_lock
);
3737 * Fill in the prnode so future references will
3738 * be able to find the underlying object's vnode.
3739 * Don't link this prnode into the list of all
3740 * prnodes for the process; this is a one-use node.
3741 * Its use is entirely to catch and fail opens for writing.
3743 pnp
->pr_realvp
= vp
;
3751 * Find or construct an lwp vnode for the given lwpid.
3754 pr_lookup_lwpdir(vnode_t
*dp
, char *comp
)
3756 id_t tid
; /* same type as t->t_tid */
3758 prnode_t
*dpnp
= VTOP(dp
);
3769 ASSERT(dpnp
->pr_type
== PR_LWPDIR
);
3772 if (strcmp(comp
, "agent") == 0)
3776 while ((c
= *comp
++) != '\0') {
3779 if (c
< '0' || c
> '9')
3782 tid
= 10*tid
+ c
- '0';
3783 if (tid
/10 != otid
) /* integer overflow */
3788 pnp
= prgetnode(dp
, PR_LWPIDDIR
);
3790 p
= pr_p_lock(dpnp
);
3791 mutex_exit(&pr_pidlock
);
3798 if ((t
= p
->p_agenttp
) == NULL
)
3803 lep
= p
->p_lwpdir
[tslot
].ld_entry
;
3806 if ((ldp
= lwp_hash_lookup(p
, tid
)) == NULL
)
3809 tslot
= (int)(ldp
- p
->p_lwpdir
);
3810 lep
= ldp
->ld_entry
;
3821 * If an lwp vnode already exists and it is not invalid
3822 * and it was created by the current process and it belongs
3823 * to the same /proc mount point as our parent vnode, then
3824 * just use it and discard the newly-allocated prnode.
3826 for (vp
= lep
->le_trace
; vp
!= NULL
; vp
= VTOP(vp
)->pr_next
) {
3827 if (!(VTOP(vp
)->pr_flags
& PR_INVAL
) &&
3828 VTOP(vp
)->pr_owner
== curproc
&&
3829 vp
->v_vfsp
== dp
->v_vfsp
) {
3836 pnp
->pr_owner
= curproc
;
3839 * prgetnode() initialized most of the prnode.
3842 pcp
= pnp
->pr_common
; /* the newly-allocated prcommon struct */
3843 if ((vp
= lep
->le_trace
) != NULL
) {
3844 /* discard the new prcommon and use the existing prcommon */
3846 pcp
= VTOP(vp
)->pr_common
;
3847 mutex_enter(&pcp
->prc_mutex
);
3848 ASSERT(pcp
->prc_refcnt
> 0);
3850 mutex_exit(&pcp
->prc_mutex
);
3851 pnp
->pr_common
= pcp
;
3853 /* initialize the new prcommon struct */
3854 pcp
->prc_flags
|= PRC_LWP
;
3855 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
3856 pcp
->prc_flags
|= PRC_SYS
;
3857 if ((t
= lep
->le_thread
) == NULL
)
3858 pcp
->prc_flags
|= PRC_DESTROY
;
3860 pcp
->prc_datamodel
= dpnp
->pr_pcommon
->prc_datamodel
;
3861 pcp
->prc_pid
= p
->p_pid
;
3862 pcp
->prc_slot
= p
->p_slot
;
3863 pcp
->prc_thread
= t
;
3865 pcp
->prc_tslot
= tslot
;
3867 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
3868 pnp
->pr_parent
= dp
;
3871 * Link in the old, invalid directory vnode so we
3872 * can later determine the last close of the file.
3874 pnp
->pr_next
= lep
->le_trace
;
3875 lep
->le_trace
= vp
= PTOV(pnp
);
3881 pr_lookup_lwpiddir(vnode_t
*dp
, char *comp
)
3883 prnode_t
*dpnp
= VTOP(dp
);
3889 enum prnodetype type
;
3891 ASSERT(dpnp
->pr_type
== PR_LWPIDDIR
);
3893 for (i
= 0; i
< NLWPIDDIRFILES
; i
++) {
3894 /* Skip "." and ".." */
3895 dirp
= &lwpiddir
[i
+2];
3896 if (strcmp(comp
, dirp
->d_name
) == 0)
3900 if (i
>= NLWPIDDIRFILES
)
3903 type
= (int)dirp
->d_ino
;
3904 pnp
= prgetnode(dp
, type
);
3906 p
= pr_p_lock(dpnp
);
3907 mutex_exit(&pr_pidlock
);
3912 if (dpnp
->pr_common
->prc_flags
& PRC_DESTROY
) {
3914 * Only the lwpsinfo file is present for zombie lwps.
3915 * Nothing is present if the lwp has been reaped.
3917 if (dpnp
->pr_common
->prc_tslot
== -1 ||
3918 type
!= PR_LWPSINFO
) {
3925 #if defined(__sparc)
3926 /* the asrs file exists only for sparc v9 _LP64 processes */
3927 if (type
== PR_ASRS
&& p
->p_model
!= DATAMODEL_LP64
) {
3934 mutex_enter(&dpnp
->pr_mutex
);
3936 if ((vp
= dpnp
->pr_files
[i
]) != NULL
&&
3937 !(VTOP(vp
)->pr_flags
& PR_INVAL
)) {
3939 mutex_exit(&dpnp
->pr_mutex
);
3946 * prgetnode() initialized most of the prnode.
3949 pnp
->pr_common
= dpnp
->pr_common
;
3950 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
3951 pnp
->pr_parent
= dp
;
3955 dpnp
->pr_files
[i
] = vp
= PTOV(pnp
);
3958 * Link new vnode into list of all /proc vnodes for the process.
3960 if (vp
->v_type
== VPROC
) {
3961 pnp
->pr_next
= p
->p_plist
;
3964 mutex_exit(&dpnp
->pr_mutex
);
3970 * Lookup one of the process's open files.
3973 pr_lookup_fddir(vnode_t
*dp
, char *comp
)
3975 prnode_t
*dpnp
= VTOP(dp
);
3985 ASSERT(dpnp
->pr_type
== PR_FDDIR
);
3988 while ((c
= *comp
++) != '\0') {
3990 if (c
< '0' || c
> '9')
3993 fd
= 10*fd
+ c
- '0';
3994 if (fd
/10 != ofd
) /* integer overflow */
3998 pnp
= prgetnode(dp
, PR_FD
);
4000 if (prlock(dpnp
, ZNO
) != 0) {
4004 p
= dpnp
->pr_common
->prc_proc
;
4005 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
4012 mutex_exit(&p
->p_lock
);
4013 mutex_enter(&fip
->fi_lock
);
4014 if (fd
< fip
->fi_nfiles
) {
4015 UF_ENTER(ufp
, fip
, fd
);
4016 if ((fp
= ufp
->uf_file
) != NULL
) {
4017 pnp
->pr_mode
= 07111;
4018 if (fp
->f_flag
& FREAD
)
4019 pnp
->pr_mode
|= 0444;
4020 if (fp
->f_flag
& FWRITE
)
4021 pnp
->pr_mode
|= 0222;
4027 mutex_exit(&fip
->fi_lock
);
4028 mutex_enter(&p
->p_lock
);
4035 * Fill in the prnode so future references will
4036 * be able to find the underlying object's vnode.
4037 * Don't link this prnode into the list of all
4038 * prnodes for the process; this is a one-use node.
4040 pnp
->pr_realvp
= vp
;
4041 pnp
->pr_parent
= dp
; /* needed for prlookup */
4044 if (pnp
->pr_realvp
->v_type
== VDIR
)
4052 pr_lookup_pathdir(vnode_t
*dp
, char *comp
)
4054 prnode_t
*dpnp
= VTOP(dp
);
4058 uint_t fd
, flags
= 0;
4062 enum { NAME_FD
, NAME_OBJECT
, NAME_ROOT
, NAME_CWD
, NAME_UNKNOWN
} type
;
4066 struct as
*as
= NULL
;
4069 ASSERT(dpnp
->pr_type
== PR_PATHDIR
);
4072 * First, check if this is a numeric entry, in which case we have a
4078 while ((c
= *tmp
++) != '\0') {
4080 if (c
< '0' || c
> '9') {
4081 type
= NAME_UNKNOWN
;
4085 fd
= 10*fd
+ c
- '0';
4086 if (fd
/10 != ofd
) { /* integer overflow */
4087 type
= NAME_UNKNOWN
;
4093 * Next, see if it is one of the special values {root, cwd}.
4095 if (type
== NAME_UNKNOWN
) {
4096 if (strcmp(comp
, "root") == 0)
4098 else if (strcmp(comp
, "cwd") == 0)
4103 * Grab the necessary data from the process
4105 if (prlock(dpnp
, ZNO
) != 0)
4107 p
= dpnp
->pr_common
->prc_proc
;
4113 if ((vp
= PTOU(p
)->u_rdir
) == NULL
)
4114 vp
= p
->p_zone
->zone_rootvp
;
4118 vp
= PTOU(p
)->u_cdir
;
4122 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
4127 mutex_exit(&p
->p_lock
);
4130 * Determine if this is an object entry
4132 if (type
== NAME_UNKNOWN
) {
4134 * Start with the inode index immediately after the number of
4137 mutex_enter(&fip
->fi_lock
);
4138 idx
= fip
->fi_nfiles
+ 4;
4139 mutex_exit(&fip
->fi_lock
);
4141 if (strcmp(comp
, "a.out") == 0) {
4142 if (p
->p_execdir
!= NULL
) {
4153 AS_LOCK_ENTER(as
, RW_READER
);
4154 if ((seg
= AS_SEGFIRST(as
)) != NULL
) {
4157 * Manufacture a filename for the
4158 * "object" directory.
4160 vattr
.va_mask
= AT_FSID
|AT_NODEID
;
4161 if (seg
->s_ops
== &segvn_ops
&&
4162 SEGOP_GETVP(seg
, seg
->s_base
, &vp
)
4164 vp
!= NULL
&& vp
->v_type
== VREG
&&
4165 VOP_GETATTR(vp
, &vattr
, 0, CRED(),
4169 if (vp
== p
->p_exec
)
4172 pr_object_name(name
, vp
,
4174 if (strcmp(name
, comp
) == 0)
4177 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
4194 mutex_enter(&fip
->fi_lock
);
4195 if (fd
< fip
->fi_nfiles
) {
4196 UF_ENTER(ufp
, fip
, fd
);
4197 if (ufp
->uf_file
!= NULL
) {
4198 vp
= ufp
->uf_file
->f_vnode
;
4203 mutex_exit(&fip
->fi_lock
);
4218 mutex_enter(&p
->p_lock
);
4222 pnp
= prgetnode(dp
, PR_PATH
);
4224 pnp
->pr_flags
|= flags
;
4225 pnp
->pr_common
= dpnp
->pr_common
;
4226 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
4227 pnp
->pr_realvp
= vp
;
4228 pnp
->pr_parent
= dp
; /* needed for prlookup */
4229 pnp
->pr_ino
= pmkino(idx
, dpnp
->pr_common
->prc_slot
, PR_PATH
);
4239 * Look up one of the process's active templates.
4242 pr_lookup_tmpldir(vnode_t
*dp
, char *comp
)
4244 prnode_t
*dpnp
= VTOP(dp
);
4250 ASSERT(dpnp
->pr_type
== PR_TMPLDIR
);
4252 for (i
= 0; i
< ct_ntypes
; i
++)
4253 if (strcmp(comp
, ct_types
[i
]->ct_type_name
) == 0)
4258 pnp
= prgetnode(dp
, PR_TMPL
);
4260 if (prlock(dpnp
, ZNO
) != 0) {
4264 p
= dpnp
->pr_common
->prc_proc
;
4265 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
||
4266 (dpnp
->pr_common
->prc_flags
& (PRC_DESTROY
| PRC_LWP
)) != PRC_LWP
) {
4271 if (ttolwp(dpnp
->pr_common
->prc_thread
)->lwp_ct_active
[i
] != NULL
) {
4272 pnp
->pr_common
= dpnp
->pr_common
;
4273 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
4274 pnp
->pr_parent
= dp
;
4287 * Look up one of the contracts owned by the process.
4290 pr_lookup_ctdir(vnode_t
*dp
, char *comp
)
4292 prnode_t
*dpnp
= VTOP(dp
);
4300 ASSERT(dpnp
->pr_type
== PR_CTDIR
);
4302 while ((c
= *comp
++) != '\0') {
4304 if (c
< '0' || c
> '9')
4307 id
= 10 * id
+ c
- '0';
4308 if (id
/ 10 != oid
) /* integer overflow */
4313 * Search all contracts; we'll filter below.
4315 ct
= contract_ptr(id
, GLOBAL_ZONEUNIQID
);
4319 pnp
= prgetnode(dp
, PR_CT
);
4321 if (prlock(dpnp
, ZNO
) != 0) {
4326 p
= dpnp
->pr_common
->prc_proc
;
4328 * We only allow lookups of contracts owned by this process, or,
4329 * if we are zsched and this is a zone's procfs, contracts on
4330 * stuff in the zone which are held by processes or contracts
4331 * outside the zone. (see logic in contract_status_common)
4333 if ((ct
->ct_owner
!= p
) &&
4334 !(p
== VTOZONE(dp
)->zone_zsched
&& ct
->ct_state
< CTS_ORPHAN
&&
4335 VTOZONE(dp
)->zone_uniqid
== contract_getzuniqid(ct
) &&
4336 VTOZONE(dp
)->zone_uniqid
!= GLOBAL_ZONEUNIQID
&&
4337 ct
->ct_czuniqid
== GLOBAL_ZONEUNIQID
)) {
4343 pnp
->pr_common
= dpnp
->pr_common
;
4344 pnp
->pr_pcommon
= dpnp
->pr_pcommon
;
4345 pnp
->pr_contract
= ct
;
4346 pnp
->pr_parent
= dp
;
4347 pnp
->pr_ino
= pmkino(id
, pnp
->pr_common
->prc_slot
, PR_CT
);
4356 * Construct an lwp vnode for the old /proc interface.
4357 * We stand on our head to make the /proc plumbing correct.
4360 prlwpnode(prnode_t
*pnp
, uint_t tid
)
4369 * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode.
4371 if (pnp
->pr_type
== PR_PIDFILE
) {
4372 dp
= pnp
->pr_parent
; /* /proc/<pid> */
4374 vp
= pr_lookup_piddir(dp
, "lwp");
4376 if ((dp
= vp
) == NULL
) /* /proc/<pid>/lwp */
4378 } else if (pnp
->pr_type
== PR_LWPIDFILE
) {
4379 dp
= pnp
->pr_parent
; /* /proc/<pid>/lwp/<lwpid> */
4380 dp
= VTOP(dp
)->pr_parent
; /* /proc/<pid>/lwp */
4386 (void) pr_u32tos(tid
, comp
, sizeof (comp
));
4387 vp
= pr_lookup_lwpdir(dp
, comp
);
4389 if ((dp
= vp
) == NULL
)
4392 pnp
= prgetnode(dp
, PR_LWPIDFILE
);
4396 * prgetnode() initialized most of the prnode.
4399 pcp
= VTOP(dp
)->pr_common
;
4400 pnp
->pr_ino
= ptoi(pcp
->prc_pid
);
4401 pnp
->pr_common
= pcp
;
4402 pnp
->pr_pcommon
= VTOP(dp
)->pr_pcommon
;
4403 pnp
->pr_parent
= dp
;
4405 * Link new vnode into list of all /proc vnodes for the process.
4408 mutex_exit(&pr_pidlock
);
4413 } else if (pcp
->prc_thread
== NULL
) {
4419 pnp
->pr_next
= p
->p_plist
;
4429 static uint32_t nprnode
;
4430 static uint32_t nprcommon
;
4432 #define INCREMENT(x) atomic_inc_32(&x);
4433 #define DECREMENT(x) atomic_dec_32(&x);
4437 #define INCREMENT(x)
4438 #define DECREMENT(x)
4443 * New /proc vnode required; allocate it and fill in most of the fields.
4446 prgetnode(vnode_t
*dp
, prnodetype_t type
)
4454 pnp
= kmem_zalloc(sizeof (prnode_t
), KM_SLEEP
);
4456 mutex_init(&pnp
->pr_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
4457 pnp
->pr_type
= type
;
4459 pnp
->pr_vnode
= vn_alloc(KM_SLEEP
);
4462 vp
->v_flag
= VNOCACHE
|VNOMAP
|VNOSWAP
|VNOMOUNT
;
4463 vn_setops(vp
, prvnodeops
);
4464 vp
->v_vfsp
= dp
->v_vfsp
;
4466 vp
->v_data
= (caddr_t
)pnp
;
4472 * We need a prcommon and a files array for each of these.
4474 INCREMENT(nprcommon
);
4476 pcp
= kmem_zalloc(sizeof (prcommon_t
), KM_SLEEP
);
4477 pcp
->prc_refcnt
= 1;
4478 pnp
->pr_common
= pcp
;
4479 mutex_init(&pcp
->prc_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
4480 cv_init(&pcp
->prc_wait
, NULL
, CV_DEFAULT
, NULL
);
4482 nfiles
= (type
== PR_PIDDIR
)? NPIDDIRFILES
: NLWPIDDIRFILES
;
4484 kmem_zalloc(nfiles
* sizeof (vnode_t
*), KM_SLEEP
);
4488 * Mode should be read-search by all, but we cannot so long
4489 * as we must support compatibility mode with old /proc.
4490 * Make /proc/<pid> be read by owner only, search by all.
4491 * Make /proc/<pid>/lwp/<lwpid> read-search by all. Also,
4492 * set VDIROPEN on /proc/<pid> so it can be opened for writing.
4494 if (type
== PR_PIDDIR
) {
4495 /* kludge for old /proc interface */
4496 prnode_t
*xpnp
= prgetnode(dp
, PR_PIDFILE
);
4497 pnp
->pr_pidfile
= PTOV(xpnp
);
4498 pnp
->pr_mode
= 0511;
4499 vp
->v_flag
|= VDIROPEN
;
4501 pnp
->pr_mode
= 0555;
4514 pnp
->pr_mode
= 0500; /* read-search by owner only */
4519 pnp
->pr_mode
= 0500; /* read-search by owner only */
4525 pnp
->pr_mode
= 0777;
4530 pnp
->pr_mode
= 0555; /* read-search by all */
4535 pnp
->pr_mode
= 0600; /* read-write by owner only */
4540 pnp
->pr_mode
= 0200; /* write-only by owner only */
4545 pnp
->pr_mode
= 0600; /* read-write by owner only */
4554 pnp
->pr_mode
= 0444; /* read-only by all */
4558 pnp
->pr_mode
= 0400; /* read-only by owner only */
4566 * Free the storage obtained from prgetnode().
4569 prfreenode(prnode_t
*pnp
)
4574 vn_invalid(PTOV(pnp
));
4576 mutex_destroy(&pnp
->pr_mutex
);
4578 switch (pnp
->pr_type
) {
4580 /* kludge for old /proc interface */
4581 if (pnp
->pr_pidfile
!= NULL
) {
4582 prfreenode(VTOP(pnp
->pr_pidfile
));
4583 pnp
->pr_pidfile
= NULL
;
4588 * We allocated a prcommon and a files array for each of these.
4590 prfreecommon(pnp
->pr_common
);
4591 nfiles
= (pnp
->pr_type
== PR_PIDDIR
)?
4592 NPIDDIRFILES
: NLWPIDDIRFILES
;
4593 kmem_free(pnp
->pr_files
, nfiles
* sizeof (vnode_t
*));
4599 * If there is an underlying vnode, be sure
4600 * to release it after freeing the prnode.
4602 vp
= pnp
->pr_realvp
;
4603 kmem_free(pnp
, sizeof (*pnp
));
4611 * Free a prcommon structure, if the reference count reaches zero.
4614 prfreecommon(prcommon_t
*pcp
)
4616 mutex_enter(&pcp
->prc_mutex
);
4617 ASSERT(pcp
->prc_refcnt
> 0);
4618 if (--pcp
->prc_refcnt
!= 0)
4619 mutex_exit(&pcp
->prc_mutex
);
4621 mutex_exit(&pcp
->prc_mutex
);
4622 ASSERT(pcp
->prc_pollhead
.ph_list
== NULL
);
4623 ASSERT(pcp
->prc_refcnt
== 0);
4624 ASSERT(pcp
->prc_selfopens
== 0 && pcp
->prc_writers
== 0);
4625 mutex_destroy(&pcp
->prc_mutex
);
4626 cv_destroy(&pcp
->prc_wait
);
4627 kmem_free(pcp
, sizeof (prcommon_t
));
4628 DECREMENT(nprcommon
);
4633 * Array of readdir functions, indexed by /proc file type.
4635 static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(),
4636 pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(),
4637 pr_readdir_fddir(), pr_readdir_pathdir(), pr_readdir_tmpldir(),
4640 static int (*pr_readdir_function
[PR_NFILES
])() = {
4641 pr_readdir_procdir
, /* /proc */
4642 pr_readdir_notdir
, /* /proc/self */
4643 pr_readdir_piddir
, /* /proc/<pid> */
4644 pr_readdir_notdir
, /* /proc/<pid>/as */
4645 pr_readdir_notdir
, /* /proc/<pid>/ctl */
4646 pr_readdir_notdir
, /* /proc/<pid>/status */
4647 pr_readdir_notdir
, /* /proc/<pid>/lstatus */
4648 pr_readdir_notdir
, /* /proc/<pid>/psinfo */
4649 pr_readdir_notdir
, /* /proc/<pid>/lpsinfo */
4650 pr_readdir_notdir
, /* /proc/<pid>/map */
4651 pr_readdir_notdir
, /* /proc/<pid>/rmap */
4652 pr_readdir_notdir
, /* /proc/<pid>/xmap */
4653 pr_readdir_notdir
, /* /proc/<pid>/cred */
4654 pr_readdir_notdir
, /* /proc/<pid>/sigact */
4655 pr_readdir_notdir
, /* /proc/<pid>/auxv */
4657 pr_readdir_notdir
, /* /proc/<pid>/ldt */
4659 pr_readdir_notdir
, /* /proc/<pid>/usage */
4660 pr_readdir_notdir
, /* /proc/<pid>/lusage */
4661 pr_readdir_notdir
, /* /proc/<pid>/pagedata */
4662 pr_readdir_notdir
, /* /proc/<pid>/watch */
4663 pr_readdir_notdir
, /* /proc/<pid>/cwd */
4664 pr_readdir_notdir
, /* /proc/<pid>/root */
4665 pr_readdir_fddir
, /* /proc/<pid>/fd */
4666 pr_readdir_notdir
, /* /proc/<pid>/fd/nn */
4667 pr_readdir_objectdir
, /* /proc/<pid>/object */
4668 pr_readdir_notdir
, /* /proc/<pid>/object/xxx */
4669 pr_readdir_lwpdir
, /* /proc/<pid>/lwp */
4670 pr_readdir_lwpiddir
, /* /proc/<pid>/lwp/<lwpid> */
4671 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
4672 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
4673 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4674 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4675 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/xregs */
4676 pr_readdir_tmpldir
, /* /proc/<pid>/lwp/<lwpid>/templates */
4677 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4678 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/spymaster */
4679 #if defined(__sparc)
4680 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/gwindows */
4681 pr_readdir_notdir
, /* /proc/<pid>/lwp/<lwpid>/asrs */
4683 pr_readdir_notdir
, /* /proc/<pid>/priv */
4684 pr_readdir_pathdir
, /* /proc/<pid>/path */
4685 pr_readdir_notdir
, /* /proc/<pid>/path/xxx */
4686 pr_readdir_ctdir
, /* /proc/<pid>/contracts */
4687 pr_readdir_notdir
, /* /proc/<pid>/contracts/<ctid> */
4688 pr_readdir_notdir
, /* old process file */
4689 pr_readdir_notdir
, /* old lwp file */
4690 pr_readdir_notdir
, /* old pagedata file */
4695 prreaddir(vnode_t
*vp
, uio_t
*uiop
, cred_t
*cr
, int *eofp
,
4696 caller_context_t
*ct
, int flags
)
4698 prnode_t
*pnp
= VTOP(vp
);
4700 ASSERT(pnp
->pr_type
< PR_NFILES
);
4702 /* XXX - Do we need to pass ct and flags? */
4703 return (pr_readdir_function
[pnp
->pr_type
](pnp
, uiop
, eofp
));
4708 pr_readdir_notdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4715 pr_readdir_procdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4718 gfs_readdir_state_t gstate
;
4722 ASSERT(pnp
->pr_type
== PR_PROCDIR
);
4724 zoneid
= VTOZONE(PTOV(pnp
))->zone_id
;
4726 if ((error
= gfs_readdir_init(&gstate
, PNSIZ
, PRSDSIZE
, uiop
,
4727 PRROOTINO
, PRROOTINO
, 0)) != 0)
4731 * Loop until user's request is satisfied or until all processes
4732 * have been examined.
4734 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
4740 * Find next entry. Skip processes not visible where
4741 * this /proc was mounted.
4743 mutex_enter(&pidlock
);
4744 while (n
< v
.v_proc
&&
4745 ((p
= pid_entry(n
)) == NULL
|| p
->p_stat
== SIDL
||
4746 (zoneid
!= GLOBAL_ZONEID
&& p
->p_zone
->zone_id
!= zoneid
) ||
4747 secpolicy_basic_procinfo(CRED(), p
, curproc
) != 0))
4751 * Stop when entire proc table has been examined.
4753 if (n
>= v
.v_proc
) {
4754 mutex_exit(&pidlock
);
4759 ASSERT(p
->p_stat
!= 0);
4762 mutex_exit(&pidlock
);
4763 error
= gfs_readdir_emitn(&gstate
, uiop
, n
,
4764 pmkino(0, pslot
, PR_PIDDIR
), pid
);
4769 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
4774 pr_readdir_piddir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4776 int zombie
= ((pnp
->pr_pcommon
->prc_flags
& PRC_DESTROY
) != 0);
4782 ASSERT(pnp
->pr_type
== PR_PIDDIR
);
4784 if (uiop
->uio_offset
< 0 ||
4785 uiop
->uio_offset
% sizeof (prdirent_t
) != 0 ||
4786 uiop
->uio_resid
< sizeof (prdirent_t
))
4788 if (pnp
->pr_pcommon
->prc_proc
== NULL
)
4790 if (uiop
->uio_offset
>= sizeof (piddir
))
4794 * Loop until user's request is satisfied, omitting some
4795 * files along the way if the process is a zombie.
4797 for (dirp
= &piddir
[uiop
->uio_offset
/ sizeof (prdirent_t
)];
4798 uiop
->uio_resid
>= sizeof (prdirent_t
) &&
4799 dirp
< &piddir
[NPIDDIRFILES
+2];
4800 uiop
->uio_offset
= off
+ sizeof (prdirent_t
), dirp
++) {
4801 off
= uiop
->uio_offset
;
4803 switch (dirp
->d_ino
) {
4813 bcopy(dirp
, &dirent
, sizeof (prdirent_t
));
4814 if (dirent
.d_ino
== PR_PROCDIR
)
4815 dirent
.d_ino
= PRROOTINO
;
4817 dirent
.d_ino
= pmkino(0, pnp
->pr_pcommon
->prc_slot
,
4819 if ((error
= uiomove((caddr_t
)&dirent
, sizeof (prdirent_t
),
4820 UIO_READ
, uiop
)) != 0)
4825 *eofp
= (uiop
->uio_offset
>= sizeof (piddir
));
4830 rebuild_objdir(struct as
*as
)
4841 ASSERT(AS_WRITE_HELD(as
));
4843 if (as
->a_updatedir
== 0 && as
->a_objectdir
!= NULL
)
4845 as
->a_updatedir
= 0;
4847 if ((nalloc
= avl_numnodes(&as
->a_segtree
)) == 0 ||
4848 (seg
= AS_SEGFIRST(as
)) == NULL
) /* can't happen? */
4852 * Allocate space for the new object directory.
4853 * (This is usually about two times too many entries.)
4855 nalloc
= (nalloc
+ 0xf) & ~0xf; /* multiple of 16 */
4856 dir
= kmem_zalloc(nalloc
* sizeof (vnode_t
*), KM_SLEEP
);
4858 /* fill in the new directory with desired entries */
4861 vattr
.va_mask
= AT_FSID
|AT_NODEID
;
4862 if (seg
->s_ops
== &segvn_ops
&&
4863 SEGOP_GETVP(seg
, seg
->s_base
, &vp
) == 0 &&
4864 vp
!= NULL
&& vp
->v_type
== VREG
&&
4865 VOP_GETATTR(vp
, &vattr
, 0, CRED(), NULL
) == 0) {
4866 for (i
= 0; i
< nentries
; i
++)
4869 if (i
== nentries
) {
4870 ASSERT(nentries
< nalloc
);
4871 dir
[nentries
++] = vp
;
4874 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
4876 if (as
->a_objectdir
== NULL
) { /* first time */
4877 as
->a_objectdir
= dir
;
4878 as
->a_sizedir
= nalloc
;
4883 * Null out all of the defunct entries in the old directory.
4887 for (i
= 0; i
< as
->a_sizedir
; i
++) {
4888 if ((vp
= as
->a_objectdir
[i
]) != NULL
) {
4889 for (j
= 0; j
< nentries
; j
++) {
4897 as
->a_objectdir
[i
] = NULL
;
4903 if (nold
+ nnew
> as
->a_sizedir
) {
4905 * Reallocate the old directory to have enough
4906 * space for the old and new entries combined.
4907 * Round up to the next multiple of 16.
4909 ulong_t newsize
= (nold
+ nnew
+ 0xf) & ~0xf;
4910 vnode_t
**newdir
= kmem_zalloc(newsize
* sizeof (vnode_t
*),
4912 bcopy(as
->a_objectdir
, newdir
,
4913 as
->a_sizedir
* sizeof (vnode_t
*));
4914 kmem_free(as
->a_objectdir
, as
->a_sizedir
* sizeof (vnode_t
*));
4915 as
->a_objectdir
= newdir
;
4916 as
->a_sizedir
= newsize
;
4920 * Move all new entries to the old directory and
4921 * deallocate the space used by the new directory.
4924 for (i
= 0, j
= 0; i
< nentries
; i
++) {
4925 if ((vp
= dir
[i
]) == NULL
)
4927 for (; j
< as
->a_sizedir
; j
++) {
4928 if (as
->a_objectdir
[j
] != NULL
)
4930 as
->a_objectdir
[j
++] = vp
;
4935 kmem_free(dir
, nalloc
* sizeof (vnode_t
*));
4939 * Return the vnode from a slot in the process's object directory.
4940 * The caller must have locked the process's address space.
4941 * The only caller is below, in pr_readdir_objectdir().
4944 obj_entry(struct as
*as
, int slot
)
4946 ASSERT(AS_LOCK_HELD(as
));
4947 if (as
->a_objectdir
== NULL
)
4949 ASSERT(slot
< as
->a_sizedir
);
4950 return (as
->a_objectdir
[slot
]);
4955 pr_readdir_objectdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
4957 gfs_readdir_state_t gstate
;
4966 ASSERT(pnp
->pr_type
== PR_OBJECTDIR
);
4968 if ((error
= prlock(pnp
, ZNO
)) != 0)
4970 p
= pnp
->pr_common
->prc_proc
;
4974 * We drop p_lock before grabbing the address space lock
4975 * in order to avoid a deadlock with the clock thread.
4976 * The process will not disappear and its address space
4977 * will not change because it is marked P_PR_LOCK.
4979 mutex_exit(&p
->p_lock
);
4981 if ((error
= gfs_readdir_init(&gstate
, 64, PRSDSIZE
, uiop
,
4982 pmkino(0, pslot
, PR_PIDDIR
),
4983 pmkino(0, pslot
, PR_OBJECTDIR
), 0)) != 0) {
4984 mutex_enter(&p
->p_lock
);
4989 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
4995 * Loop until user's request is satisfied or until
4996 * all mapped objects have been examined. Cannot hold
4997 * the address space lock for the following call as
4998 * gfs_readdir_pred() utimately causes a call to uiomove().
5000 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
5005 * Set the correct size of the directory just
5006 * in case the process has changed it's address
5007 * space via mmap/munmap calls.
5010 AS_LOCK_ENTER(as
, RW_WRITER
);
5011 if (as
->a_updatedir
)
5013 objdirsize
= as
->a_sizedir
;
5019 vattr
.va_mask
= AT_FSID
| AT_NODEID
;
5020 while (n
< objdirsize
&& (((vp
= obj_entry(as
, n
)) == NULL
) ||
5021 (VOP_GETATTR(vp
, &vattr
, 0, CRED(), NULL
)
5023 vattr
.va_mask
= AT_FSID
| AT_NODEID
;
5031 * Stop when all objects have been reported.
5033 if (n
>= objdirsize
) {
5038 if (vp
== p
->p_exec
)
5039 (void) strcpy(str
, "a.out");
5041 pr_object_name(str
, vp
, &vattr
);
5043 error
= gfs_readdir_emit(&gstate
, uiop
, n
, vattr
.va_nodeid
,
5050 mutex_enter(&p
->p_lock
);
5053 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5058 pr_readdir_lwpdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5060 gfs_readdir_state_t gstate
;
5068 ASSERT(pnp
->pr_type
== PR_LWPDIR
);
5071 mutex_exit(&pr_pidlock
);
5074 ASSERT(p
== pnp
->pr_common
->prc_proc
);
5076 lwpdir
= p
->p_lwpdir
;
5077 lwpdirsize
= p
->p_lwpdir_sz
;
5080 * Drop p->p_lock so we can safely do uiomove().
5081 * The lwp directory will not change because
5082 * we have the process locked with P_PR_LOCK.
5084 mutex_exit(&p
->p_lock
);
5087 if ((error
= gfs_readdir_init(&gstate
, PLNSIZ
, PRSDSIZE
, uiop
,
5088 pmkino(0, pslot
, PR_PIDDIR
),
5089 pmkino(0, pslot
, PR_LWPDIR
), 0)) != 0) {
5090 mutex_enter(&p
->p_lock
);
5096 * Loop until user's request is satisfied or until all lwps
5097 * have been examined.
5099 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &tslot
)) == 0) {
5106 while (tslot
< lwpdirsize
&&
5107 ((lep
= lwpdir
[tslot
].ld_entry
) == NULL
))
5110 * Stop when all lwps have been reported.
5112 if (tslot
>= lwpdirsize
) {
5117 tid
= lep
->le_lwpid
;
5118 error
= gfs_readdir_emitn(&gstate
, uiop
, tslot
,
5119 pmkino(tslot
, pslot
, PR_LWPIDDIR
), tid
);
5124 mutex_enter(&p
->p_lock
);
5127 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5132 pr_readdir_lwpiddir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5134 prcommon_t
*pcp
= pnp
->pr_common
;
5135 int zombie
= ((pcp
->prc_flags
& PRC_DESTROY
) != 0);
5143 ASSERT(pnp
->pr_type
== PR_LWPIDDIR
);
5145 if (uiop
->uio_offset
< 0 ||
5146 uiop
->uio_offset
% sizeof (prdirent_t
) != 0 ||
5147 uiop
->uio_resid
< sizeof (prdirent_t
))
5149 if (pcp
->prc_proc
== NULL
|| pcp
->prc_tslot
== -1)
5151 if (uiop
->uio_offset
>= sizeof (lwpiddir
))
5155 * Loop until user's request is satisfied, omitting some files
5156 * along the way if the lwp is a zombie and also depending
5157 * on the data model of the process.
5159 pslot
= pcp
->prc_slot
;
5160 tslot
= pcp
->prc_tslot
;
5161 for (dirp
= &lwpiddir
[uiop
->uio_offset
/ sizeof (prdirent_t
)];
5162 uiop
->uio_resid
>= sizeof (prdirent_t
) &&
5163 dirp
< &lwpiddir
[NLWPIDDIRFILES
+2];
5164 uiop
->uio_offset
= off
+ sizeof (prdirent_t
), dirp
++) {
5165 off
= uiop
->uio_offset
;
5167 switch (dirp
->d_ino
) {
5176 #if defined(__sparc)
5177 /* the asrs file exists only for sparc v9 _LP64 processes */
5178 if (dirp
->d_ino
== PR_ASRS
&&
5179 pcp
->prc_datamodel
!= DATAMODEL_LP64
)
5182 bcopy(dirp
, &dirent
, sizeof (prdirent_t
));
5183 if (dirent
.d_ino
== PR_LWPDIR
)
5184 dirent
.d_ino
= pmkino(0, pslot
, dirp
->d_ino
);
5186 dirent
.d_ino
= pmkino(tslot
, pslot
, dirp
->d_ino
);
5187 if ((error
= uiomove((caddr_t
)&dirent
, sizeof (prdirent_t
),
5188 UIO_READ
, uiop
)) != 0)
5193 *eofp
= (uiop
->uio_offset
>= sizeof (lwpiddir
));
5199 pr_readdir_fddir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5201 gfs_readdir_state_t gstate
;
5209 ASSERT(pnp
->pr_type
== PR_FDDIR
);
5211 if ((error
= prlock(pnp
, ZNO
)) != 0)
5213 p
= pnp
->pr_common
->prc_proc
;
5216 mutex_exit(&p
->p_lock
);
5218 if ((error
= gfs_readdir_init(&gstate
, PLNSIZ
, PRSDSIZE
, uiop
,
5219 pmkino(0, pslot
, PR_PIDDIR
), pmkino(0, pslot
, PR_FDDIR
), 0)) != 0) {
5220 mutex_enter(&p
->p_lock
);
5225 mutex_enter(&fip
->fi_lock
);
5226 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
5229 fddirsize
= fip
->fi_nfiles
;
5232 * Loop until user's request is satisfied or until
5233 * all file descriptors have been examined.
5235 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
5239 while (n
< fddirsize
&& fip
->fi_list
[n
].uf_file
== NULL
)
5242 * Stop when all fds have been reported.
5244 if (n
>= fddirsize
) {
5249 error
= gfs_readdir_emitn(&gstate
, uiop
, n
,
5250 pmkino(n
, pslot
, PR_FD
), n
);
5255 mutex_exit(&fip
->fi_lock
);
5256 mutex_enter(&p
->p_lock
);
5259 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5264 pr_readdir_pathdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5266 longlong_t bp
[DIRENT64_RECLEN(64) / sizeof (longlong_t
)];
5267 dirent64_t
*dirent
= (dirent64_t
*)bp
;
5277 struct as
*as
= NULL
;
5282 ASSERT(pnp
->pr_type
== PR_PATHDIR
);
5284 if (uiop
->uio_offset
< 0 ||
5285 uiop
->uio_resid
<= 0 ||
5286 (uiop
->uio_offset
% PRSDSIZE
) != 0)
5288 oresid
= uiop
->uio_resid
;
5289 bzero(bp
, sizeof (bp
));
5291 if ((error
= prlock(pnp
, ZNO
)) != 0)
5293 p
= pnp
->pr_common
->prc_proc
;
5296 mutex_exit(&p
->p_lock
);
5298 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
5302 AS_LOCK_ENTER(as
, RW_WRITER
);
5303 if (as
->a_updatedir
)
5305 objdirsize
= as
->a_sizedir
;
5310 mutex_enter(&fip
->fi_lock
);
5311 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
5314 fddirsize
= fip
->fi_nfiles
;
5316 for (; uiop
->uio_resid
> 0; uiop
->uio_offset
= off
+ PRSDSIZE
) {
5318 * There are 4 special files in the path directory: ".", "..",
5319 * "root", and "cwd". We handle those specially here.
5321 off
= uiop
->uio_offset
;
5322 idx
= off
/ PRSDSIZE
;
5323 if (off
== 0) { /* "." */
5324 dirent
->d_ino
= pmkino(0, pslot
, PR_PATHDIR
);
5325 dirent
->d_name
[0] = '.';
5326 dirent
->d_name
[1] = '\0';
5327 reclen
= DIRENT64_RECLEN(1);
5328 } else if (idx
== 1) { /* ".." */
5329 dirent
->d_ino
= pmkino(0, pslot
, PR_PIDDIR
);
5330 dirent
->d_name
[0] = '.';
5331 dirent
->d_name
[1] = '.';
5332 dirent
->d_name
[2] = '\0';
5333 reclen
= DIRENT64_RECLEN(2);
5334 } else if (idx
== 2) { /* "root" */
5335 dirent
->d_ino
= pmkino(idx
, pslot
, PR_PATH
);
5336 (void) strcpy(dirent
->d_name
, "root");
5337 reclen
= DIRENT64_RECLEN(4);
5338 } else if (idx
== 3) { /* "cwd" */
5339 dirent
->d_ino
= pmkino(idx
, pslot
, PR_PATH
);
5340 (void) strcpy(dirent
->d_name
, "cwd");
5341 reclen
= DIRENT64_RECLEN(3);
5342 } else if (idx
< 4 + fddirsize
) {
5344 * In this case, we have one of the file descriptors.
5347 if (fip
->fi_list
[fd
].uf_file
== NULL
)
5349 dirent
->d_ino
= pmkino(idx
, pslot
, PR_PATH
);
5350 (void) pr_u32tos(fd
, dirent
->d_name
, PLNSIZ
+1);
5351 reclen
= DIRENT64_RECLEN(PLNSIZ
);
5352 } else if (idx
< 4 + fddirsize
+ objdirsize
) {
5354 mutex_exit(&fip
->fi_lock
);
5359 * We drop p_lock before grabbing the address space lock
5360 * in order to avoid a deadlock with the clock thread.
5361 * The process will not disappear and its address space
5362 * will not change because it is marked P_PR_LOCK.
5366 AS_LOCK_ENTER(as
, RW_WRITER
);
5369 if (as
->a_updatedir
) {
5371 objdirsize
= as
->a_sizedir
;
5374 obj
= idx
- 4 - fddirsize
;
5375 if ((vp
= obj_entry(as
, obj
)) == NULL
)
5377 vattr
.va_mask
= AT_FSID
|AT_NODEID
;
5378 if (VOP_GETATTR(vp
, &vattr
, 0, CRED(), NULL
) != 0)
5380 if (vp
== p
->p_exec
)
5381 (void) strcpy(dirent
->d_name
, "a.out");
5383 pr_object_name(dirent
->d_name
, vp
, &vattr
);
5384 dirent
->d_ino
= pmkino(idx
, pslot
, PR_PATH
);
5385 reclen
= DIRENT64_RECLEN(strlen(dirent
->d_name
));
5390 dirent
->d_off
= uiop
->uio_offset
+ PRSDSIZE
;
5391 dirent
->d_reclen
= (ushort_t
)reclen
;
5392 if (reclen
> uiop
->uio_resid
) {
5394 * Error if no entries have been returned yet.
5396 if (uiop
->uio_resid
== oresid
)
5401 * Drop the address space lock to do the uiomove().
5406 error
= uiomove((caddr_t
)dirent
, reclen
, UIO_READ
, uiop
);
5408 AS_LOCK_ENTER(as
, RW_WRITER
);
5414 if (error
== 0 && eofp
)
5415 *eofp
= (uiop
->uio_offset
>= (fddirsize
+ 2) * PRSDSIZE
);
5418 mutex_exit(&fip
->fi_lock
);
5421 mutex_enter(&p
->p_lock
);
5427 pr_readdir_tmpldir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5431 gfs_readdir_state_t gstate
;
5435 ASSERT(pnp
->pr_type
== PR_TMPLDIR
);
5437 if ((error
= prlock(pnp
, ZNO
)) != 0)
5439 p
= pnp
->pr_common
->prc_proc
;
5440 pslot
= pnp
->pr_common
->prc_slot
;
5441 tslot
= pnp
->pr_common
->prc_tslot
;
5442 mutex_exit(&p
->p_lock
);
5444 if ((error
= gfs_readdir_init(&gstate
, PRDIRSIZE
, PRSDSIZE
, uiop
,
5445 pmkino(tslot
, pslot
, PR_LWPDIR
),
5446 pmkino(tslot
, pslot
, PR_TMPLDIR
), 0)) != 0) {
5447 mutex_enter(&p
->p_lock
);
5452 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
5454 * Check for an active template. Reading a directory's
5455 * contents is already racy, so we don't bother taking
5458 while (n
< ct_ntypes
&&
5459 pnp
->pr_common
->prc_thread
->t_lwp
->lwp_ct_active
[n
] == NULL
)
5462 * Stop when all types have been reported.
5464 if (n
>= ct_ntypes
) {
5469 * The pmkino invocation below will need to be updated
5470 * when we create our fifth contract type.
5472 ASSERT(ct_ntypes
<= 4);
5473 error
= gfs_readdir_emit(&gstate
, uiop
, n
,
5474 pmkino((tslot
<< 2) | n
, pslot
, PR_TMPL
),
5475 ct_types
[n
]->ct_type_name
, 0);
5480 mutex_enter(&p
->p_lock
);
5483 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5487 pr_readdir_ctdir(prnode_t
*pnp
, uio_t
*uiop
, int *eofp
)
5491 gfs_readdir_state_t gstate
;
5496 ASSERT(pnp
->pr_type
== PR_CTDIR
);
5498 if ((error
= prlock(pnp
, ZNO
)) != 0)
5500 p
= pnp
->pr_common
->prc_proc
;
5502 mutex_exit(&p
->p_lock
);
5504 if ((error
= gfs_readdir_init(&gstate
, PRDIRSIZE
, PRSDSIZE
, uiop
,
5505 pmkino(0, pslot
, PR_PIDDIR
), pmkino(0, pslot
, PR_CTDIR
), 0)) != 0) {
5506 mutex_enter(&p
->p_lock
);
5511 zid
= VTOZONE(pnp
->pr_vnode
)->zone_uniqid
;
5512 while ((error
= gfs_readdir_pred(&gstate
, uiop
, &n
)) == 0) {
5513 id_t next
= contract_plookup(p
, n
, zid
);
5518 error
= gfs_readdir_emitn(&gstate
, uiop
, next
,
5519 pmkino(next
, pslot
, PR_CT
), next
);
5524 mutex_enter(&p
->p_lock
);
5527 return (gfs_readdir_fini(&gstate
, error
, eofp
, eof
));
5532 prfsync(vnode_t
*vp
, int syncflag
, cred_t
*cr
, caller_context_t
*ct
)
5538 * Utility: remove a /proc vnode from a linked list, threaded through pr_next.
5541 pr_list_unlink(vnode_t
*pvp
, vnode_t
**listp
)
5546 while ((vp
= *listp
) != NULL
) {
5549 *listp
= pnp
->pr_next
;
5550 pnp
->pr_next
= NULL
;
5553 listp
= &pnp
->pr_next
;
5559 prinactive(vnode_t
*vp
, cred_t
*cr
, caller_context_t
*ct
)
5561 prnode_t
*pnp
= VTOP(vp
);
5562 prnodetype_t type
= pnp
->pr_type
;
5565 vnode_t
*ovp
= NULL
;
5566 prnode_t
*opnp
= NULL
;
5573 /* These are not linked into the usual lists */
5574 ASSERT(vp
->v_count
== 1);
5575 if ((dp
= pnp
->pr_parent
) != NULL
)
5583 mutex_enter(&pr_pidlock
);
5584 if (pnp
->pr_pcommon
== NULL
)
5586 else if ((p
= pnp
->pr_pcommon
->prc_proc
) != NULL
)
5587 mutex_enter(&p
->p_lock
);
5588 mutex_enter(&vp
->v_lock
);
5590 if (type
== PR_PROCDIR
|| vp
->v_count
> 1) {
5592 mutex_exit(&vp
->v_lock
);
5594 mutex_exit(&p
->p_lock
);
5595 mutex_exit(&pr_pidlock
);
5599 if ((dp
= pnp
->pr_parent
) != NULL
) {
5609 mutex_enter(&dpnp
->pr_mutex
);
5610 if (dpnp
->pr_files
!= NULL
&&
5611 dpnp
->pr_files
[pnp
->pr_index
] == vp
)
5612 dpnp
->pr_files
[pnp
->pr_index
] = NULL
;
5613 mutex_exit(&dpnp
->pr_mutex
);
5616 pnp
->pr_parent
= NULL
;
5619 ASSERT(vp
->v_count
== 1);
5622 * If we allocated an old /proc/pid node, free it too.
5624 if (pnp
->pr_pidfile
!= NULL
) {
5625 ASSERT(type
== PR_PIDDIR
);
5626 ovp
= pnp
->pr_pidfile
;
5628 ASSERT(opnp
->pr_type
== PR_PIDFILE
);
5629 pnp
->pr_pidfile
= NULL
;
5632 mutex_exit(&pr_pidlock
);
5636 * Remove the vnodes from the lists of
5637 * /proc vnodes for the process.
5643 pr_list_unlink(vp
, &p
->p_trace
);
5646 if ((slot
= pnp
->pr_common
->prc_tslot
) != -1) {
5647 lwpent_t
*lep
= p
->p_lwpdir
[slot
].ld_entry
;
5648 pr_list_unlink(vp
, &lep
->le_trace
);
5652 pr_list_unlink(vp
, &p
->p_plist
);
5656 pr_list_unlink(ovp
, &p
->p_plist
);
5657 mutex_exit(&p
->p_lock
);
5660 mutex_exit(&vp
->v_lock
);
5662 if (type
== PR_CT
&& pnp
->pr_contract
!= NULL
) {
5663 contract_rele(pnp
->pr_contract
);
5664 pnp
->pr_contract
= NULL
;
5677 prseek(vnode_t
*vp
, offset_t ooff
, offset_t
*noffp
, caller_context_t
*ct
)
5683 * We use the p_execdir member of proc_t to expand the %d token in core file
5684 * paths (the directory path for the executable that dumped core; see
5685 * coreadm(1M) for details). We'd like gcore(1) to be able to expand %d in
5686 * the same way as core dumping from the kernel, but there's no convenient
5687 * and comprehensible way to export the path name for p_execdir. To solve
5688 * this, we try to find the actual path to the executable that was used. In
5689 * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT
5690 * flag, and use that here to indicate that more work is needed beyond the
5691 * call to vnodetopath().
5694 prreadlink_lookup(prnode_t
*pnp
, char *buf
, size_t size
, cred_t
*cr
)
5697 vnode_t
*vp
, *execvp
, *vrootp
;
5701 size_t dlen
= DIRENT64_RECLEN(MAXPATHLEN
);
5705 mutex_enter(&p
->p_lock
);
5706 if ((vrootp
= PTOU(p
)->u_rdir
) == NULL
)
5709 mutex_exit(&p
->p_lock
);
5711 ret
= vnodetopath(vrootp
, pnp
->pr_realvp
, buf
, size
, cr
);
5714 * If PR_AOUT isn't set, then we looked up the path for the vnode;
5715 * otherwise, we looked up the path for (what we believe to be) the
5716 * containing directory.
5718 if ((pnp
->pr_flags
& PR_AOUT
) == 0) {
5724 * Fail if there's a problem locking the process. This will only
5725 * occur if the process is changing so the information we would
5726 * report would already be invalid.
5728 if (prlock(pnp
, ZNO
) != 0) {
5733 p
= pnp
->pr_common
->prc_proc
;
5734 mutex_exit(&p
->p_lock
);
5740 * If our initial lookup of the directory failed, fall back to
5741 * the path name information for p_exec.
5744 mutex_enter(&p
->p_lock
);
5746 ret
= vnodetopath(vrootp
, execvp
, buf
, size
, cr
);
5755 * We use u_comm as a guess for the last component of the full
5756 * executable path name. If there isn't going to be enough space
5757 * we fall back to using the p_exec so that we can have _an_
5758 * answer even if it's not perfect.
5760 if (strlen(PTOU(p
)->u_comm
) + len
+ 1 < size
) {
5762 (void) strcpy(buf
+ len
+ 1, PTOU(p
)->u_comm
);
5763 mutex_enter(&p
->p_lock
);
5767 * Do a forward lookup of our u_comm guess.
5769 if (lookupnameat(buf
+ len
+ 1, UIO_SYSSPACE
, FOLLOW
, NULLVPP
,
5770 &vp
, pnp
->pr_realvp
) == 0) {
5771 if (vn_compare(vp
, execvp
)) {
5781 mutex_enter(&p
->p_lock
);
5785 dbuf
= kmem_alloc(dlen
, KM_SLEEP
);
5788 * Try to find a matching vnode by iterating through the directory's
5789 * entries. If that fails, fall back to the path information for
5792 if ((ret
= dirfindvp(vrootp
, pnp
->pr_realvp
, execvp
, cr
, dbuf
,
5793 dlen
, &dp
)) == 0 && strlen(dp
->d_name
) + len
+ 1 < size
) {
5795 (void) strcpy(buf
+ len
+ 1, dp
->d_name
);
5797 ret
= vnodetopath(vrootp
, execvp
, buf
, size
, cr
);
5800 kmem_free(dbuf
, dlen
);
5809 prreadlink(vnode_t
*vp
, uio_t
*uiop
, cred_t
*cr
, caller_context_t
*ctp
)
5811 prnode_t
*pnp
= VTOP(vp
);
5815 int length
, rlength
;
5818 switch (pnp
->pr_type
) {
5820 (void) snprintf(idbuf
, sizeof (idbuf
), "%d", curproc
->p_pid
);
5821 ret
= uiomove(idbuf
, strlen(idbuf
), UIO_READ
, uiop
);
5827 if (pnp
->pr_realvp
->v_type
== VDIR
)
5831 buf
= kmem_alloc(MAXPATHLEN
, KM_SLEEP
);
5833 if ((ret
= prreadlink_lookup(pnp
, buf
, MAXPATHLEN
, cr
)) == 0)
5834 ret
= uiomove(buf
, strlen(buf
), UIO_READ
, uiop
);
5836 kmem_free(buf
, MAXPATHLEN
);
5839 ASSERT(pnp
->pr_contract
!= NULL
);
5840 ct
= pnp
->pr_contract
;
5841 length
= sizeof (CTFS_ROOT
"//") + sizeof (idbuf
) +
5842 strlen(ct
->ct_type
->ct_type_name
);
5843 buf
= kmem_alloc(length
, KM_SLEEP
);
5844 rlength
= snprintf(buf
, length
, CTFS_ROOT
"/%s/%d",
5845 ct
->ct_type
->ct_type_name
, ct
->ct_id
);
5846 ASSERT(rlength
< length
);
5847 ret
= uiomove(buf
, rlength
, UIO_READ
, uiop
);
5848 kmem_free(buf
, length
);
5859 prcmp(vnode_t
*vp1
, vnode_t
*vp2
, caller_context_t
*ct
)
5861 prnode_t
*pp1
, *pp2
;
5866 if (!vn_matchops(vp1
, prvnodeops
) || !vn_matchops(vp2
, prvnodeops
))
5872 if (pp1
->pr_type
!= pp2
->pr_type
)
5874 if (pp1
->pr_type
== PR_PROCDIR
)
5876 if (pp1
->pr_ino
|| pp2
->pr_ino
)
5877 return (pp2
->pr_ino
== pp1
->pr_ino
);
5879 if (pp1
->pr_common
== NULL
|| pp2
->pr_common
== NULL
)
5882 return (pp1
->pr_common
->prc_slot
== pp2
->pr_common
->prc_slot
&&
5883 pp1
->pr_common
->prc_tslot
== pp2
->pr_common
->prc_tslot
);
5887 prrealvp(vnode_t
*vp
, vnode_t
**vpp
, caller_context_t
*ct
)
5891 if ((rvp
= VTOP(vp
)->pr_realvp
) != NULL
) {
5893 if (VOP_REALVP(vp
, &rvp
, ct
) == 0)
5902 * Return the answer requested to poll().
5903 * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
5904 * In addition, these have special meaning for /proc files:
5905 * POLLPRI process or lwp stopped on an event of interest
5906 * POLLERR /proc file descriptor is invalid
5907 * POLLHUP process or lwp has terminated
5911 prpoll(vnode_t
*vp
, short events
, int anyyet
, short *reventsp
,
5912 pollhead_t
**phpp
, caller_context_t
*ct
)
5914 prnode_t
*pnp
= VTOP(vp
);
5915 prcommon_t
*pcp
= pnp
->pr_common
;
5916 pollhead_t
*php
= &pcp
->prc_pollhead
;
5922 ASSERT(pnp
->pr_type
< PR_NFILES
);
5925 * Support for old /proc interface.
5927 if (pnp
->pr_pidfile
!= NULL
) {
5928 vp
= pnp
->pr_pidfile
;
5930 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
5931 ASSERT(pnp
->pr_common
== pcp
);
5934 *reventsp
= revents
= 0;
5935 *phpp
= (pollhead_t
*)NULL
;
5937 if (vp
->v_type
== VDIR
) {
5938 *reventsp
|= POLLNVAL
;
5942 /* avoid deadlock with prnotify() */
5943 if (pollunlock(&lockstate
) != 0) {
5944 *reventsp
= POLLNVAL
;
5948 if ((error
= prlock(pnp
, ZNO
)) != 0) {
5949 pollrelock(lockstate
);
5951 case ENOENT
: /* process or lwp died */
5952 *reventsp
= POLLHUP
;
5955 case EAGAIN
: /* invalidated */
5956 *reventsp
= POLLERR
;
5964 * We have the process marked locked (P_PR_LOCK) and we are holding
5965 * its p->p_lock. We want to unmark the process but retain
5966 * exclusive control w.r.t. other /proc controlling processes
5967 * before reacquiring the polling locks.
5969 * prunmark() does this for us. It unmarks the process
5970 * but retains p->p_lock so we still have exclusive control.
5971 * We will drop p->p_lock at the end to relinquish control.
5973 * We cannot call prunlock() at the end to relinquish control
5974 * because prunlock(), like prunmark(), may drop and reacquire
5975 * p->p_lock and that would lead to a lock order violation
5976 * w.r.t. the polling locks we are about to reacquire.
5982 pollrelock(lockstate
); /* reacquire dropped poll locks */
5984 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
5989 if ((ev
= (events
& (POLLIN
|POLLRDNORM
))) != 0)
5992 * POLLWRNORM (same as POLLOUT) really should not be
5993 * used to indicate that the process or lwp stopped.
5994 * However, USL chose to use POLLWRNORM rather than
5995 * POLLPRI to indicate this, so we just accept either
5996 * requested event to indicate stopped. (grr...)
5998 if ((ev
= (events
& (POLLPRI
|POLLOUT
|POLLWRNORM
))) != 0) {
6001 if (pcp
->prc_flags
& PRC_LWP
) {
6002 t
= pcp
->prc_thread
;
6006 t
= prchoose(p
); /* returns locked t */
6010 if (ISTOPPED(t
) || VSTOPPED(t
))
6016 *reventsp
= revents
;
6017 if ((!anyyet
&& revents
== 0) || (events
& POLLET
)) {
6019 * Arrange to wake up the polling lwp when
6020 * the target process/lwp stops or terminates
6021 * or when the file descriptor becomes invalid.
6023 pcp
->prc_flags
|= PRC_POLL
;
6026 mutex_exit(&p
->p_lock
);
6031 extern int prioctl(vnode_t
*, int, intptr_t, int, cred_t
*, int *,
6032 caller_context_t
*);
6035 * /proc vnode operations vector
6037 const fs_operation_def_t pr_vnodeops_template
[] = {
6038 VOPNAME_OPEN
, { .vop_open
= propen
},
6039 VOPNAME_CLOSE
, { .vop_close
= prclose
},
6040 VOPNAME_READ
, { .vop_read
= prread
},
6041 VOPNAME_WRITE
, { .vop_write
= prwrite
},
6042 VOPNAME_IOCTL
, { .vop_ioctl
= prioctl
},
6043 VOPNAME_GETATTR
, { .vop_getattr
= prgetattr
},
6044 VOPNAME_ACCESS
, { .vop_access
= praccess
},
6045 VOPNAME_LOOKUP
, { .vop_lookup
= prlookup
},
6046 VOPNAME_CREATE
, { .vop_create
= prcreate
},
6047 VOPNAME_READDIR
, { .vop_readdir
= prreaddir
},
6048 VOPNAME_READLINK
, { .vop_readlink
= prreadlink
},
6049 VOPNAME_FSYNC
, { .vop_fsync
= prfsync
},
6050 VOPNAME_INACTIVE
, { .vop_inactive
= prinactive
},
6051 VOPNAME_SEEK
, { .vop_seek
= prseek
},
6052 VOPNAME_CMP
, { .vop_cmp
= prcmp
},
6053 VOPNAME_FRLOCK
, { .error
= fs_error
},
6054 VOPNAME_REALVP
, { .vop_realvp
= prrealvp
},
6055 VOPNAME_POLL
, { .vop_poll
= prpoll
},
6056 VOPNAME_DISPOSE
, { .error
= fs_error
},
6057 VOPNAME_SHRLOCK
, { .error
= fs_error
},