summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/proc/prdata.h
blob: 1294421f9f31149b608c375f6e5d1cbdf96d09a2 (plain)
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 */