syskstat.h

来自「嵌入式RMON,RMON为Remote monitor的缩写,基于SNMP为网络」· C头文件 代码 · 共 816 行 · 第 1/2 页

H
816
字号
/* * Copyright (c) 1992 by Sun Microsystems, Inc. */#ifndef	_SYS_KSTAT_H#define	_SYS_KSTAT_H#pragma	ident	"@(#)kstat.h	1.4	92/09/04 SMI"/* * Definition of general kernel statistics structures and /dev/kstat ioctls */#include <sys/types.h>#include <sys/t_lock.h>#ifdef	__cplusplusextern "C" {#endiftypedef	longlong_t	kstime_t;	/* kstat timestamp */typedef long		kid_t;		/* unique kstat id *//* * Kernel statistics driver (/dev/kstat) ioctls */#define	KSTAT_IOC_BASE		('K' << 8)#define	KSTAT_IOC_CHAIN_ID	KSTAT_IOC_BASE | 0x01#define	KSTAT_IOC_READ		KSTAT_IOC_BASE | 0x02#define	KSTAT_IOC_WRITE		KSTAT_IOC_BASE | 0x03#define	KSTAT_IOC_TIME		KSTAT_IOC_BASE | 0x04/* * /dev/kstat ioctl usage (kd denotes /dev/kstat descriptor): * *	kcid = ioctl(kd, KSTAT_IOC_CHAIN_ID, NULL); *	kcid = ioctl(kd, KSTAT_IOC_READ, kstat_t *); *	kcid = ioctl(kd, KSTAT_IOC_WRITE, kstat_t *); *	kcid = ioctl(kd, KSTAT_IOC_TIME, kstime_t *); */#define	KSTAT_STRLEN	31	/* 30 chars + NULL; must be 16 * n - 1 *//* * The generic kstat header */typedef struct kstat {	/*	 * Fields relevant to both kernel and user	 */	kstime_t	ks_crtime;	/* creation time (from kstat_time()) */	struct kstat	*ks_next;	/* kstat chain linkage */	kid_t		ks_kid;		/* unique kstat ID */	char		ks_module[KSTAT_STRLEN]; /* creator module name */	uchar_t		ks_resv;	/* reserved, currently just padding */	int		ks_instance;	/* creator module's instance */	char		ks_name[KSTAT_STRLEN]; /* kstat name */	uchar_t		ks_type;	/* kstat data type */	char		ks_class[KSTAT_STRLEN]; /* kstat class */	uchar_t		ks_flags;	/* kstat flags */	void		*ks_data;	/* kstat type-specific data */	ulong_t		ks_ndata;	/* # of type-specific data records */	ulong_t		ks_data_size;	/* total size of kstat data section */	ulong_t		ks_resv2;	/* reserved for future use */	/*	 * Fields relevant to kernel only	 */	kmutex_t	*ks_lock;	/* protects this kstat's data */	int		(*ks_update)(struct kstat *, int); /* dynamic update */	void		*ks_private;	/* arbitrary client-private data */	int		(*ks_copy)(struct kstat *, struct kstat *, int);	ulong_t		ks_resv3;	/* reserved for future use */} kstat_t;/* * kstat structure * * Each kstat consists of a header section (a kstat_t) and a data section. * The data section may be any of the kstat types defined below. *//* * kstat locking * * The system maintains a linked list of kstat structs, protected by * kstat_chain_lock.  kstat_chain_lock protects all additions to/deletions * from this list, as well as all changes to kstat headers.  kstat data * sections are *optionally* protected by the per-kstat ks_lock.  If * ks_lock is non-NULL, /dev/kstat will acquire this lock for all of its * operations on that kstat.  It is up to the driver to decide whether * guaranteeing consistent data to /dev/kstat is sufficiently important. * Note, however, that most statistic updates already occur under some * driver mutex, so if the driver sets ks_lock to point to that mutex, * then kstat locking is free. */#if	defined(_KERNEL)#define	KSTAT_ENTER(x)	if (x != NULL) mutex_enter(x)#define	KSTAT_EXIT(x)	if (x != NULL) mutex_exit(x)#endif	/* defined(_KERNEL) *//* * kstat time * * All times associated with kstats (e.g. creation time, kstat_timer_t * and kstat_io_t timestamps, etc.) are 64-bit nanosecond values, as * returned by kstat_time().  The accuracy of kstat timestamps is machine * dependent, but the precision (units) is the same across all platforms. *//* * kstat identity (KID) * * Each kstat is assigned a unique KID (kstat ID) when it is added to the * global kstat chain.  The KID is used as a cookie by /dev/kstat to * request information about the corresponding kstat.  There is also * an identity associated with the entire kstat chain, kstat_chain_id, * which is bumped each time a kstat is added or deleted.  /dev/kstat * clients can use the kstat chain ID to detect changes in the kstat chain * between ioctls. *//* * kstat module, kstat instance * * ks_module and ks_instance contain the name and instance of the the * module that created the kstat.  In cases where there can only be one * instance, ks_instance is 0.  The "core" kernel (/kernel/unix) uses * "unix" as the module name. *//* * kstat name * * ks_name gives a meaningful name to a kstat.  The full kstat namespace * is module.instance.name, so the name only need be unique within a * module.  kstat_create() will fail if you try to create a kstat with * an already-used (ks_module, ks_instance, ks_name) triplet.  Spaces are * allowed in kstat names, but strongly discouraged, since they hinder * awk-style processing at user level. *//* * kstat type * * The kstat mechanism provides several flavors of kstat data, defined * below.  The "raw" kstat type is just treated as an array of bytes; you * can use this to export any kind of data you want. * * Some kstat types allow multiple data structures per kstat, e.g. * KSTAT_TYPE_NAMED; others do not.  This is a required part of the spec * for all kstat types. * * User-level tools should *not* rely on the #define KSTAT_NUM_TYPES.  To * get this information, read out the standard system kstat "kstat_types". */#define	KSTAT_TYPE_RAW		0	/* can be anything */					/* ks_ndata > 1 OK */#define	KSTAT_TYPE_NAMED	1	/* name/value pair */					/* ks_ndata > 1 OK */#define	KSTAT_TYPE_INTR		2	/* interrupt statistics */					/* ks_ndata == 1 */#define	KSTAT_TYPE_IO		3	/* I/O statistics */					/* ks_ndata == 1 */#define	KSTAT_TYPE_TIMER	4	/* event timer */					/* ks_ndata > 1 OK */#define	KSTAT_NUM_TYPES		5/* * kstat class * * Each kstat can be characterized as belonging to some broad class * of statistics, e.g. disk, tape, net, vm, streams, etc.  This field * can be used as a filter to extract related kstats.  The following * values are currently in use: disk, tape, net, controller, vm, kvm, * hat, streams, kstat, and misc.  (The kstat class encompasses things * like kstat_types.) *//* * kstat flags * * Any combination of the following flags may be passed to kstat_create(): * *	KSTAT_FLAG_VIRTUAL: * *		Tells kstat_create() not to allocate memory for the *		kstat data section; instead, you will set the ks_data *		field to point to the data you wish to export.  This *		provides a convenient way to export existing data *		structures. * *	KSTAT_FLAG_VAR_SIZE: * *		The size of the kstat you are creating will vary over time. *		For example, you may want to use the kstat mechanism to *		export a linked list.  N.B.: The kstat framework does not *		manage the data section, so all VAR_SIZE kstats must be VIRTUAL *		kstats.  See the section on "kstat copy" for further details. * *	KSTAT_FLAG_WRITABLE: * *		Makes the kstat's data section writable by root. *		The ks_copy routine (see below) does not need to check for *		this; permission checking is handled in the kstat driver. */#define	KSTAT_FLAG_VIRTUAL		0x01#define	KSTAT_FLAG_VAR_SIZE		0x02#define	KSTAT_FLAG_WRITABLE		0x04/* * Dynamic update support * * The kstat mechanism allows for an optional ks_update function to update * kstat data.  This is useful for drivers where the underlying device * keeps cheap hardware stats, but extraction is expensive.  Instead of * constantly keeping the kstat data section up to date, you can supply a * ks_update function which updates the kstat's data section on demand. * To take advantage of this feature, simply set the ks_update field before * calling kstat_install(). * * The ks_update function, if supplied, must have the following structure: * *	int *	foo_kstat_update(kstat_t *ksp, int rw) *	{ *		if (rw == KSTAT_WRITE) { *			... update the underlying stats from ksp->ks_data; *				return EACCES if you don't support this *		} else { *			... update ksp->ks_data from the underlying stats *		} *	} * * The ks_update return codes are: 0 for success, EACCES if you don't allow * KSTAT_WRITE, and EIO for any other type of error. * * In general, the ks_update function may need to refer to client-private * data; for example, it may need a pointer to the client's raw statistics. * The ks_private field is available for this purpose.  Its use is entirely * at the client's discretion. * * No kstat locking should be done inside the ks_update routine.  The caller * will already be holding the kstat's ks_lock (to ensure consistent data) * *and* the global kstat_chain_lock (to prevent the kstat from being * deleted by another thread). */#define	KSTAT_READ	0#define	KSTAT_WRITE	1/* * Kstat copy * * Normally, /dev/kstat returns kstat data to the user via the routine * default_kstat_copy().  (The superuser can also write kstat data -- * more on this below).  However, this routine only works for fixed-size * kstats.  If you define a variable-size kstat, or if you have other * special needs, you must set ks_copy to point to a routine to copy * data to/from userland.  The routine you supply must have the following * prototype: * *	int foo_kstat_copy(kstat_t *ksp, kstat_t *user_ksp, int rw); * * foo_kstat_copy() must have the following basic structure: * *	limit = user_ksp->ks_data_size; *	user_ksp->ks_data_size = foo_size; *	if (rw == KSTAT_WRITE) { *		if (limit != foo_size) *			return (ENOMEM); *		if (kstat_copyin(user_ksp->ks_data, ksp->ks_data, limit)) *			return (EFAULT); *		return (0); *	} *	if (foo_size > limit) *		return (ENOMEM); *	if (kstat_copyout(ksp->ks_data, user_ksp->ks_data, foo_size)) *		return (EFAULT); *	return (0); * * You should also set user_ksp->ks_ndata if that is meaningful, as in * the case of copying out a linked list of structures.  For example: * *	ulong_t	limit = user_ksp->ks_data_size; *	char *buf = (char *) user_ksp->ks_data; *	ulong_t	foo_ndata = 0; *	ulong_t	foo_size = 0; * *	if (rw == KSTAT_WRITE) *		return (EACCES);		... See below ... * *	for (foo = first_foo; foo; foo = foo->next) { *		foo_ndata++; *		foo_size += sizeof (struct foo); *	} *	user_ksp->ks_ndata = foo_ndata; *	user_ksp->ks_data_size = foo_size; *	if (foo_size > limit) *		return (ENOMEM); *	for (foo = first_foo; foo; foo = foo->next) { *		if (kstat_copyout((char *) foo, buf, sizeof (struct foo))) *			return (EFAULT); *		buf += sizeof (struct foo); *	} *	return (0); * * In the example above, we have decided that we don't want to allow * KSTAT_WRITE access, so we return EACCES if this is attempted. * * The key points here are: * *	(1) Data gets copied to/from the user-specified buffer, *		user_ksp->ks_data, depending whether rw is KSTAT_READ *		or KSTAT_WRITE, respectively. *	(2) On entry, user_ksp->ks_data_size is the size of the user's *		buffer; on exit, it must be set to current size of the kstat's *		data section. *	(3) *Always* update user_ksp->ks_data_size before returning from *		a KSTAT_READ, even if it's an error return. *	(4) *Never* attempt to copy in/out more bytes than the user's *		buffer size. *	(5) ks_copy return values are: 0 for success, ENOMEM if user's buffer *		is too small (for copyout) or if the buffer sizes don't *		match (for copyin), EFAULT for copyin/copyout errors, *		EACCES if you don't allow KSTAT_WRITE, and EIO for any other *		type of error. * * NOTE: you should always use the wrapper routines kstat_copyin() and * kstat_copyout() wherever you would normally use copyin() and copyout(), * respectively. *//* * Named statistics. * * List of arbitrary name=value statistics. */typedef struct kstat_named {	char	name[KSTAT_STRLEN];	/* name of counter */	uchar_t	data_type;		/* data type */	union {		char		c[16];	/* enough for 128-bit ints */		long		l;		ulong_t		ul;		longlong_t	ll;		u_longlong_t	ull;		float		f;		double		d;	} value;			/* value of counter */} kstat_named_t;#define	KSTAT_DATA_CHAR		0#define	KSTAT_DATA_LONG		1#define	KSTAT_DATA_ULONG	2#define	KSTAT_DATA_LONGLONG	3#define	KSTAT_DATA_ULONGLONG	4#define	KSTAT_DATA_FLOAT	5#define	KSTAT_DATA_DOUBLE	6#define	KSTAT_NAMED_PTR(kptr)	((kstat_named_t *) (kptr)->ks_data)/* * Interrupt statistics. * * An interrupt is a hard interrupt (sourced from the hardware device * itself), a soft interrupt (induced by the system via the use of * some system interrupt source), a watchdog interrupt (induced by * a periodic timer call), spurious (an interrupt entry point was * entered but there was no interrupt condition to service), * or multiple service (an interrupt condition was detected and * serviced just prior to returning from any of the other types). * * Measurement of the spurious class of interrupts is useful for * autovectored devices in order to pinpoint any interrupt latency * problems in a particular system configuration. * * Devices that have more than one interrupt of the same * type should use multiple structures. */#define	KSTAT_INTR_HARD			0#define	KSTAT_INTR_SOFT			1#define	KSTAT_INTR_WATCHDOG		2#define	KSTAT_INTR_SPURIOUS		3#define	KSTAT_INTR_MULTSVC		4#define	KSTAT_NUM_INTRS			5typedef struct kstat_intr {	ulong_t		intrs[KSTAT_NUM_INTRS];	/* interrupt counters */} kstat_intr_t;#define	KSTAT_INTR_PTR(kptr)	((kstat_intr_t *) (kptr)->ks_data)/* * I/O statistics. */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?