1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#ifndef _SYS_PROC_PRDATA_H
#define _SYS_PROC_PRDATA_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/isa_defs.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/prsystm.h>
#include <sys/model.h>
#include <sys/poll.h>
#include <sys/list.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Test for thread being stopped, not on an event of interest,
* but with a directed stop in effect.
*/
#define DSTOPPED(t) \
((t)->t_state == TS_STOPPED && \
((t)->t_proc_flag & TP_PRSTOP))
#define round4(r) (((r) + 3) & (~3))
#define round8(r) (((r) + 7) & (~7))
#define round16(r) (((r) + 15) & (~15))
#define roundlong(r) (((r) + sizeof (long) - 1) & (~(sizeof (long) - 1)))
#define PNSIZ 10 /* max size of /proc name entries */
#define PLNSIZ 10 /* max size of /proc lwp name entries */
/*
* Common file object to which all /proc vnodes for a specific process
* or lwp refer. One for the process, one for each lwp.
*/
typedef struct prcommon {
kmutex_t prc_mutex; /* to wait for the proc/lwp to stop */
kcondvar_t prc_wait; /* to wait for the proc/lwp to stop */
ushort_t prc_flags; /* flags */
uint_t prc_writers; /* number of write opens of prnodes */
uint_t prc_selfopens; /* number of write opens by self */
pid_t prc_pid; /* process id */
model_t prc_datamodel; /* data model of the process */
proc_t *prc_proc; /* process being traced */
kthread_t *prc_thread; /* thread (lwp) being traced */
int prc_slot; /* procdir slot number */
id_t prc_tid; /* thread (lwp) id */
int prc_tslot; /* lwpdir slot number, -1 if reaped */
int prc_refcnt; /* this structure's reference count */
struct pollhead prc_pollhead; /* list of all pollers */
} prcommon_t;
/* prc_flags */
#define PRC_DESTROY 0x01 /* process or lwp is being destroyed */
#define PRC_LWP 0x02 /* structure refers to an lwp */
#define PRC_SYS 0x04 /* process is a system process */
#define PRC_POLL 0x08 /* poll() in progress on this process/lwp */
#define PRC_EXCL 0x10 /* exclusive access granted (old /proc) */
/*
* Macros for mapping between i-numbers and pids.
*/
#define pmkino(tslot, pslot, nodetype) \
(((((ino_t)(tslot) << nproc_highbit) | \
(ino_t)(pslot)) << 6) | \
(nodetype) + 2)
/* for old /proc interface */
#define PRBIAS 64
#define ptoi(n) ((int)(((n) + PRBIAS))) /* pid to i-number */
/*
* Node types for /proc files (directories and files contained therein).
*/
typedef enum prnodetype {
PR_PROCDIR, /* /proc */
PR_SELF, /* /proc/self */
PR_PIDDIR, /* /proc/<pid> */
PR_AS, /* /proc/<pid>/as */
PR_CTL, /* /proc/<pid>/ctl */
PR_STATUS, /* /proc/<pid>/status */
PR_LSTATUS, /* /proc/<pid>/lstatus */
PR_PSINFO, /* /proc/<pid>/psinfo */
PR_LPSINFO, /* /proc/<pid>/lpsinfo */
PR_MAP, /* /proc/<pid>/map */
PR_RMAP, /* /proc/<pid>/rmap */
PR_XMAP, /* /proc/<pid>/xmap */
PR_CRED, /* /proc/<pid>/cred */
PR_SIGACT, /* /proc/<pid>/sigact */
PR_AUXV, /* /proc/<pid>/auxv */
#if defined(__i386) || defined(__amd64)
PR_LDT, /* /proc/<pid>/ldt */
#endif
PR_USAGE, /* /proc/<pid>/usage */
PR_LUSAGE, /* /proc/<pid>/lusage */
PR_PAGEDATA, /* /proc/<pid>/pagedata */
PR_WATCH, /* /proc/<pid>/watch */
PR_CURDIR, /* /proc/<pid>/cwd */
PR_ROOTDIR, /* /proc/<pid>/root */
PR_FDDIR, /* /proc/<pid>/fd */
PR_FD, /* /proc/<pid>/fd/nn */
PR_OBJECTDIR, /* /proc/<pid>/object */
PR_OBJECT, /* /proc/<pid>/object/xxx */
PR_LWPDIR, /* /proc/<pid>/lwp */
PR_LWPIDDIR, /* /proc/<pid>/lwp/<lwpid> */
PR_LWPCTL, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
PR_LWPSTATUS, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
PR_LWPSINFO, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
PR_LWPUSAGE, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
PR_XREGS, /* /proc/<pid>/lwp/<lwpid>/xregs */
PR_TMPLDIR, /* /proc/<pid>/lwp/<lwpid>/templates */
PR_TMPL, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
#if defined(__sparc)
PR_GWINDOWS, /* /proc/<pid>/lwp/<lwpid>/gwindows */
PR_ASRS, /* /proc/<pid>/lwp/<lwpid>/asrs */
#endif
PR_PRIV, /* /proc/<pid>/priv */
PR_PATHDIR, /* /proc/<pid>/path */
PR_PATH, /* /proc/<pid>/path/xxx */
PR_CTDIR, /* /proc/<pid>/contracts */
PR_CT, /* /proc/<pid>/contracts/<ctid> */
PR_PIDFILE, /* old process file */
PR_LWPIDFILE, /* old lwp file */
PR_OPAGEDATA, /* old page data file */
PR_NFILES /* number of /proc node types */
} prnodetype_t;
typedef struct prnode {
vnode_t *pr_next; /* list of all vnodes for process */
uint_t pr_flags; /* private flags */
kmutex_t pr_mutex; /* locks pr_files and child pr_flags */
prnodetype_t pr_type; /* node type */
mode_t pr_mode; /* file mode */
ino_t pr_ino; /* node id (for stat(2)) */
uint_t pr_hatid; /* hat layer id for page data files */
prcommon_t *pr_common; /* common data structure */
prcommon_t *pr_pcommon; /* process common data structure */
vnode_t *pr_parent; /* parent directory */
vnode_t **pr_files; /* contained files array (directory) */
uint_t pr_index; /* position within parent */
vnode_t *pr_pidfile; /* substitute vnode for old /proc */
vnode_t *pr_realvp; /* real vnode, file in object,fd dirs */
proc_t *pr_owner; /* the process that created this node */
vnode_t *pr_vnode; /* pointer to vnode */
struct contract *pr_contract; /* contract pointer */
int pr_cttype; /* active template type */
} prnode_t;
/*
* Values for pr_flags.
*/
#define PR_INVAL 0x01 /* vnode is invalidated */
#define PR_ISSELF 0x02 /* vnode is a self-open */
#define PR_AOUT 0x04 /* vnode is for an a.out path */
/*
* Conversion macros.
*/
#define VTOP(vp) ((struct prnode *)(vp)->v_data)
#define PTOV(pnp) ((pnp)->pr_vnode)
/*
* Flags to prlock().
*/
#define ZNO 0 /* Fail on encountering a zombie process. */
#define ZYES 1 /* Allow zombies. */
/*
* Assign one set to another (possible different sizes).
*
* Assigning to a smaller set causes members to be lost.
* Assigning to a larger set causes extra members to be cleared.
*/
#define prassignset(ap, sp) \
{ \
register int _i_ = sizeof (*(ap))/sizeof (uint32_t); \
while (--_i_ >= 0) \
((uint32_t *)(ap))[_i_] = \
(_i_ >= sizeof (*(sp))/sizeof (uint32_t)) ? \
0 : ((uint32_t *)(sp))[_i_]; \
}
/*
* Determine whether or not a set (of arbitrary size) is empty.
*/
#define prisempty(sp) \
setisempty((uint32_t *)(sp), \
(uint_t)(sizeof (*(sp)) / sizeof (uint32_t)))
/*
* Resource usage with times as hrtime_t rather than timestruc_t.
* Each member exactly matches the corresponding member in prusage_t.
* This is for convenience of internal computation.
*/
typedef struct prhusage {
id_t pr_lwpid; /* lwp id. 0: process or defunct */
int pr_count; /* number of contributing lwps */
hrtime_t pr_tstamp; /* current time stamp */
hrtime_t pr_create; /* process/lwp creation time stamp */
hrtime_t pr_term; /* process/lwp termination time stamp */
hrtime_t pr_rtime; /* total lwp real (elapsed) time */
hrtime_t pr_utime; /* user level CPU time */
hrtime_t pr_stime; /* system call CPU time */
hrtime_t pr_ttime; /* other system trap CPU time */
hrtime_t pr_tftime; /* text page fault sleep time */
hrtime_t pr_dftime; /* data page fault sleep time */
hrtime_t pr_kftime; /* kernel page fault sleep time */
hrtime_t pr_ltime; /* user lock wait sleep time */
hrtime_t pr_slptime; /* all other sleep time */
hrtime_t pr_wtime; /* wait-cpu (latency) time */
hrtime_t pr_stoptime; /* stopped time */
hrtime_t filltime[6]; /* filler for future expansion */
uint64_t pr_minf; /* minor page faults */
uint64_t pr_majf; /* major page faults */
uint64_t pr_nswap; /* swaps */
uint64_t pr_inblk; /* input blocks */
uint64_t pr_oublk; /* output blocks */
uint64_t pr_msnd; /* messages sent */
uint64_t pr_mrcv; /* messages received */
uint64_t pr_sigs; /* signals received */
uint64_t pr_vctx; /* voluntary context switches */
uint64_t pr_ictx; /* involuntary context switches */
uint64_t pr_sysc; /* system calls */
uint64_t pr_ioch; /* chars read and written */
uint64_t filler[10]; /* filler for future expansion */
} prhusage_t;
#if defined(_KERNEL)
/* Exclude system processes from this test */
#define PROCESS_NOT_32BIT(p) \
(!((p)->p_flag & SSYS) && (p)->p_as != &kas && \
(p)->p_model != DATAMODEL_ILP32)
extern int prnwatch; /* number of supported watchpoints */
extern int nproc_highbit; /* highbit(v.v_nproc) */
extern struct vnodeops *prvnodeops;
/*
* Generic chained copyout buffers for procfs use.
* In order to prevent procfs from making huge oversize kmem_alloc calls,
* a list of smaller buffers can be concatenated and copied to userspace in
* sequence.
*
* The implementation is opaque.
*
* A user of this will perform the following steps:
*
* list_t listhead;
* struct my *mp;
*
* pr_iol_initlist(&listhead, sizeof (*mp), n);
* while (whatever) {
* mp = pr_iol_newbuf(&listhead, sizeof (*mp);
* ...
* error = ...
* }
*
* When done, depending on whether copyout() or uiomove() is supposed to
* be used for transferring the buffered data to userspace, call either:
*
* error = pr_iol_copyout_and_free(&listhead, &cmaddr, error);
*
* or else:
*
* error = pr_iol_uiomove_and_free(&listhead, uiop, error);
*
* These two functions will in any case kmem_free() all list items, but
* if an error occurred before they will not perform the copyout/uiomove.
* If copyout/uiomove are done, the passed target address / uio_t
* are updated. The error returned will either be the one passed in, or
* the error that occurred during copyout/uiomove.
*/
extern void pr_iol_initlist(list_t *head, size_t itemsize, int nitems);
extern void * pr_iol_newbuf(list_t *head, size_t itemsize);
extern int pr_iol_copyout_and_free(list_t *head, caddr_t *tgt, int errin);
extern int pr_iol_uiomove_and_free(list_t *head, uio_t *uiop, int errin);
#if defined(_SYSCALL32_IMPL)
extern int prwritectl32(vnode_t *, struct uio *, cred_t *);
extern void prgetaction32(proc_t *, user_t *, uint_t, struct sigaction32 *);
extern void prcvtusage32(struct prhusage *, prusage32_t *);
#endif /* _SYSCALL32_IMPL */
/* kludge to support old /proc interface */
#if !defined(_SYS_OLD_PROCFS_H)
extern int prgetmap(proc_t *, int, list_t *);
extern int prgetxmap(proc_t *, list_t *);
#if defined(_SYSCALL32_IMPL)
extern int prgetmap32(proc_t *, int, list_t *);
extern int prgetxmap32(proc_t *, list_t *);
#endif /* _SYSCALL32_IMPL */
#endif /* !_SYS_OLD_PROCFS_H */
extern proc_t *pr_p_lock(prnode_t *);
extern kthread_t *pr_thread(prnode_t *);
extern void pr_stop(prnode_t *);
extern int pr_wait_stop(prnode_t *, time_t);
extern int pr_setrun(prnode_t *, ulong_t);
extern int pr_wait(prcommon_t *, timestruc_t *, int);
extern void pr_wait_die(prnode_t *);
extern int pr_setsig(prnode_t *, siginfo_t *);
extern int pr_kill(prnode_t *, int, cred_t *);
extern int pr_unkill(prnode_t *, int);
extern int pr_nice(proc_t *, int, cred_t *);
extern void pr_setentryexit(proc_t *, sysset_t *, int);
extern int pr_set(proc_t *, long);
extern int pr_unset(proc_t *, long);
extern void pr_sethold(prnode_t *, sigset_t *);
extern void pr_setfault(proc_t *, fltset_t *);
extern int prusrio(proc_t *, enum uio_rw, struct uio *, int);
extern int prwritectl(vnode_t *, struct uio *, cred_t *);
extern int prlock(prnode_t *, int);
extern void prunmark(proc_t *);
extern void prunlock(prnode_t *);
extern size_t prpdsize(struct as *);
extern int prpdread(proc_t *, uint_t, struct uio *);
extern size_t oprpdsize(struct as *);
extern int oprpdread(struct as *, uint_t, struct uio *);
extern void prgetaction(proc_t *, user_t *, uint_t, struct sigaction *);
extern void prgetusage(kthread_t *, struct prhusage *);
extern void praddusage(kthread_t *, struct prhusage *);
extern void prcvtusage(struct prhusage *, prusage_t *);
extern void prscaleusage(prhusage_t *);
extern kthread_t *prchoose(proc_t *);
extern void allsetrun(proc_t *);
extern int setisempty(uint32_t *, uint_t);
extern int pr_u32tos(uint32_t, char *, int);
extern vnode_t *prlwpnode(prnode_t *, uint_t);
extern prnode_t *prgetnode(vnode_t *, prnodetype_t);
extern void prfreenode(prnode_t *);
extern void pr_object_name(char *, vnode_t *, struct vattr *);
extern int set_watched_area(proc_t *, struct watched_area *);
extern int clear_watched_area(proc_t *, struct watched_area *);
extern void pr_free_watchpoints(proc_t *);
extern proc_t *pr_cancel_watch(prnode_t *);
extern struct seg *break_seg(proc_t *);
/*
* Machine-dependent routines (defined in prmachdep.c).
*/
extern void prgetprregs(klwp_t *, prgregset_t);
extern void prsetprregs(klwp_t *, prgregset_t, int);
#if defined(_SYSCALL32_IMPL)
extern void prgetprregs32(klwp_t *, prgregset32_t);
extern void prgregset_32ton(klwp_t *, prgregset32_t, prgregset_t);
extern void prgetprfpregs32(klwp_t *, prfpregset32_t *);
extern void prsetprfpregs32(klwp_t *, prfpregset32_t *);
extern size_t prpdsize32(struct as *);
extern int prpdread32(proc_t *, uint_t, struct uio *);
extern size_t oprpdsize32(struct as *);
extern int oprpdread32(struct as *, uint_t, struct uio *);
#endif /* _SYSCALL32_IMPL */
extern void prpokethread(kthread_t *t);
extern int prgetrvals(klwp_t *, long *, long *);
extern void prgetprfpregs(klwp_t *, prfpregset_t *);
extern void prsetprfpregs(klwp_t *, prfpregset_t *);
extern void prgetprxregs(klwp_t *, caddr_t);
extern void prsetprxregs(klwp_t *, caddr_t);
extern int prgetprxregsize(proc_t *);
extern int prhasfp(void);
extern int prhasx(proc_t *);
extern caddr_t prgetstackbase(proc_t *);
extern caddr_t prgetpsaddr(proc_t *);
extern int prisstep(klwp_t *);
extern void prsvaddr(klwp_t *, caddr_t);
extern int prfetchinstr(klwp_t *, ulong_t *);
extern ushort_t prgetpctcpu(uint64_t);
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_PROC_PRDATA_H */
|