xref: /freebsd/lib/libdevstat/devstat.3 (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1.\"
2.\" Copyright (c) 1998, 1999 Kenneth D. Merry.
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\"    notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\"    notice, this list of conditions and the following disclaimer in the
12.\"    documentation and/or other materials provided with the distribution.
13.\" 3. The name of the author may not be used to endorse or promote products
14.\"    derived from this software without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" $FreeBSD$
29.\"
30.Dd May 21, 1998
31.Dt DEVSTAT 3
32.Os FreeBSD 3.0
33.Sh NAME
34.Nm devstat ,
35.Nm getnumdevs ,
36.Nm getgeneration ,
37.Nm getversion ,
38.Nm checkversion ,
39.Nm getdevs ,
40.Nm selectdevs ,
41.Nm buildmatch ,
42.Nm compute_stats ,
43.Nm compute_etime
44.Nd device statistics utility library
45.Sh SYNOPSIS
46.Fd #include <sys/dkstat.h>
47.Fd #include <devstat.h>
48.Ft int
49.Fn getnumdevs "void"
50.Ft long
51.Fn getgeneration "void"
52.Ft int
53.Fn getversion "void"
54.Ft int
55.Fn checkversion "void"
56.Ft int
57.Fn getdevs "struct statinfo *stats"
58.Ft int
59.Fo selectdevs
60.Fa "struct device_selection **dev_select"
61.Fa "int *num_selected"
62.Fa "int *num_selections"
63.Fa "long *select_generation"
64.Fa "long current_generation"
65.Fa "struct devstat *devices"
66.Fa "int numdevs"
67.Fa "struct devstat_match *matches"
68.Fa "int num_matches"
69.Fa "char **dev_selections"
70.Fa "int num_dev_selections"
71.Fa "devstat_select_mode select_mode"
72.Fa "int maxshowdevs"
73.Fa "int perf_select"
74.Fc
75.Ft int
76.Fo buildmatch
77.Fa "char *match_str"
78.Fa "struct devstat_match **matches"
79.Fa "int *num_matches"
80.Fc
81.Ft int
82.Fo compute_stats
83.Fa "struct devstat *current"
84.Fa "struct devstat *previous"
85.Fa "long double etime"
86.Fa "u_int64_t *total_bytes"
87.Fa "u_int64_t *total_transfers"
88.Fa "u_int64_t *total_blocks"
89.Fa "long double *kb_per_transfer"
90.Fa "long double *transfers_per_second"
91.Fa "long double *mb_per_second"
92.Fa "long double *blocks_per_second"
93.Fa "long double *ms_per_transaction"
94.Fc
95.Ft long double
96.Fo compute_etime
97.Fa "struct timeval cur_time"
98.Fa "struct timeval prev_time"
99.Fc
100.Sh DESCRIPTION
101The
102.Nm
103library is a library of helper functions for dealing with the kernel
104.Xr devstat 9
105interface, which is accessible to users via
106.Xr sysctl 3 .
107.Pp
108.Fn getnumdevs
109returns the number of devices registered with the
110.Nm devstat
111subsystem in the kernel.
112.Pp
113.Fn getgeneration
114returns the current generation of the
115.Nm devstat
116list of devices in the kernel.
117.Pp
118.Fn getversion
119returns the current kernel
120.Nm devstat
121version.
122.Pp
123.Fn checkversion
124checks the userland devstat version against the kernel devstat version.  If
125the two are identical, it returns zero.  Otherwise, it prints an
126appropriate error in
127.Va devstat_errbuf
128and returns -1.
129.Pp
130.Fn getdevs
131fetches the current list of devices and statistics into the supplied
132.Va statinfo
133structure.  The
134.Va statinfo
135structure can be found in
136.Aq Pa devstat.h :
137.Bd -literal -offset indent
138struct statinfo {
139	long            cp_time[CPUSTATES];
140	long            tk_nin;
141	long            tk_nout;
142	struct devinfo  *dinfo;
143	struct timeval  busy_time;
144};
145.Ed
146.Pp
147.Fn getdevs
148expects the
149.Va statinfo
150structure to be allocated, and it also expects the
151.Va dinfo
152subelement to be allocated and zeroed prior to the first invocation of
153.Fn getdevs .
154The
155.Va dinfo
156subelement is used to store state between calls, and should not be modified
157after the first call to
158.Fn getdevs .
159The
160.Va dinfo
161subelement contains the following elements:
162.Bd -literal -offset indent
163struct devinfo {
164	struct devstat	*devices;
165	u_int8_t	*mem_ptr;
166	long		generation;
167	int		numdevs;
168};
169.Ed
170.Pp
171The
172.Va kern.devstat.all
173.Nm sysctl
174variable contains an array of
175.Nm devstat
176structures, but at the head of the array is the current
177.Nm devstat
178generation.  The reason the generation is at the head of the buffer is so
179that userland software accessing the devstat statistics information can
180atomically get both the statistics information and the corresponding
181generation number.  If client software were forced to get the generation
182number via a separate
183.Nm sysctl
184variable (which is available for convenience), the list of devices could
185change between the time the client gets the generation and the time the
186client gets the device list.
187.Pp
188The
189.Va mem_ptr
190subelement of the
191.Va devinfo
192structure is a pointer to memory that is allocated, and resized if
193necessary, by
194.Fn getdevs .
195The devices subelement of the
196.Va devinfo
197structure is basically a pointer to the beginning of the array of devstat
198structures from the
199.Va kern.devstat.all
200.Nm sysctl
201variable.  The generation subelement of the
202.Nm devinfo
203structure contains the generation number from the
204.Va kern.devstat.all
205.Nm sysctl
206variable.
207The
208.Va numdevs
209subelement of the
210.Va devinfo
211structure contains the current
212number of devices registered with the kernel
213.Nm devstat
214subsystem.
215.Pp
216.Fn selectdevs
217selects devices to display based upon a number of criteria:
218.Bl -tag -width flag
219.It specified devices
220Specified devices are the first selection priority.  These are generally
221devices specified by name by the user.  e.g. da0, da1, cd0.
222.It match patterns
223These are pattern matching expressions generated by
224.Fn buildmatch
225from user input.
226.It performance
227If performance mode is enabled, devices will be sorted based on the
228.Va bytes
229field in the
230.Va device_selection
231structure passed in to
232.Fn selectdevs .
233The
234.Va bytes
235value currently must be maintained by the user.  In the future,
236this may be done for him in a
237.Nm
238library routine.
239If no devices have been selected by name or by pattern, the performance
240tracking code will select every device in the system, and sort them by
241performance.  If devices have been selected by name or pattern, the
242performance tracking code will honor those selections and will only sort
243among the selected devices.
244.It order in the devstat list
245If the selection mode is set to DS_SELECT_ADD, and if there are still less
246than
247.Va maxshowdevs
248devices selected,
249.Fn selectdevs
250will automatically select up to
251.Va maxshowdevs
252devices.
253.El
254.Pp
255.Fn selectdevs
256performs selections in four different modes:
257.Bl -tag -width DS_SELECT_ADDONLY
258.It DS_SELECT_ADD
259In add mode,
260.Fn selectdevs
261will select any unselected devices specified by name or matching pattern.
262It will also select more devices, in devstat list order, until the number
263of selected devices is equal to
264.Va maxshowdevs
265or until all devices are
266selected.
267.It DS_SELECT_ONLY
268In only mode,
269.Fn selectdevs
270will clear all current selections, and will only select devices specified
271by name or by matching pattern.
272.It DS_SELECT_REMOVE
273In remove mode,
274.Fn selectdevs
275will remove devices specified by name or by matching pattern.  It will not
276select any additional devices.
277.It DS_SELECT_ADDONLY
278In add only mode,
279.Fn selectdevs
280will select any unselected devices specified by name or matching pattern.
281In this respect it is identical to add mode.  It will not, however, select
282any devices other than those specified.
283.El
284.Pp
285In all selection modes,
286.Fn selectdevs
287will not select any more than
288.Va maxshowdevs
289devices.  One exception to
290this is when you are in
291.Dq top
292mode and no devices have been selected.  In
293this case,
294.Fn selectdevs
295will select every device in the system.  Client programs must pay attention
296to selection order when deciding whether to pay attention to a particular
297device.  This may be the wrong behavior, and probably requires additional
298thought.
299.Pp
300.Fn selectdevs
301handles allocation and resizing of the
302.Va dev_select
303structure passed in
304by the client.
305.Fn selectdevs
306uses the
307.Va numdevs
308and
309.Va current_generation
310fields to track the
311current
312.Nm
313generation and number of devices.  If
314.Va num_selections
315is not the same
316as
317.Va numdevs
318or if
319.Va select_generation
320is not the same as
321.Va current_generation ,
322.Fn selectdevs
323will resize the selection list as necessary, and re-initialize the
324selection array.
325.Pp
326.Fn buildmatch
327takes a comma separated match string and compiles it into a
328\fBdevstat_match\fR structure that is understood by
329.Fn selectdevs .
330Match strings have the following format:
331.Pp
332.Bd -literal -offset indent
333device,type,if
334.Ed
335.Pp
336.Fn buildmatch
337takes care of allocating and reallocating the match list as necessary.
338Currently known match types include:
339.Pp
340.Bl -tag -width indent -compact
341.It device type:
342.Bl -tag -width 123456789 -compact
343.It da
344Direct Access devices
345.It sa
346Sequential Access devices
347.It printer
348Printers
349.It proc
350Processor devices
351.It worm
352Write Once Read Multiple devices
353.It cd
354CD devices
355.It scanner
356Scanner devices
357.It optical
358Optical Memory devices
359.It changer
360Medium Changer devices
361.It comm
362Communication devices
363.It array
364Storage Array devices
365.It enclosure
366Enclosure Services devices
367.It floppy
368Floppy devices
369.El
370.Pp
371.It interface:
372.Bl -tag -width 123456789 -compact
373.It IDE
374Integrated Drive Electronics devices
375.It SCSI
376Small Computer System Interface devices
377.It other
378Any other device interface
379.El
380.Pp
381.It passthrough:
382.Bl -tag -width 123456789 -compact
383.It pass
384Passthrough devices
385.El
386.El
387.Pp
388.Fn compute_stats
389provides an easy way to obtain various device statistics.  Only two
390arguments are mandatory:
391.Va current
392and
393.Va etime .
394Every other argument is optional.  For most applications, the user will
395want to supply both
396.Va current
397and
398.Va previous
399devstat structures so that statistics may be calculated over a given period
400of time.  In some instances, for instance when calculating statistics since
401system boot, the user may pass in a NULL pointer for the
402.Va previous
403argument.  In that case,
404.Fn compute_stats
405will use the total stats in the
406.Va current
407structure to calculate statistics over
408.Va etime .
409The various statistics that may be calculated by
410.Fn compute_stats
411should be mostly explained by the function declaration itself, but for
412completeness here is a list of variable names and the statistics that will
413be put in them:
414.Bl -tag -width transfers_per_second
415.It total_bytes
416This is the total number of bytes transferred on the given device, both
417reads and writes, between the acquisition of
418.Va previous
419and the acquisition of
420.Va current .
421If
422.Va previous
423is NULL, the result will be the total reads and writes given in
424.Va current .
425.It total_transfers
426This is the total number of transfers completed between the
427acquisition of
428.Va previous
429and the acquisition of
430.Va current .
431If
432.Va previous
433is NULL, the result will be the total number of transactions listed in
434.Va current .
435.It total_blocks
436This is basically
437.Va total_bytes
438divided by the device blocksize.  If the device blocksize is listed as
439.Sq 0 ,
440the device blocksize will default to 512 bytes.
441.It kb_per_transfer
442This is the average number of kilobytes per transfer during the measurement
443period.
444.It transfers_per_second
445This is the average number of transfers per second.
446.It mb_per_second
447This is average megabytes per second.
448.It blocks_per_second
449This is average blocks per second.  If the device blocksize is
450.Sq 0 ,
451a default blocksize of 512 bytes will be used instead.
452.It ms_per_transaction
453The average number of milliseconds per transaction.
454.El
455.Pp
456.Fn compute_etime
457provides an easy way to find the difference in seconds between two
458.Va timeval
459structures.  This is most commonly used in conjunction with the time
460recorded by the
461.Fn getdevs
462function (in struct
463.Va statinfo )
464each time it fetches the current
465.Nm
466list.
467.Sh RETURN VALUES
468.Fn getnumdevs ,
469.Fn getgeneration ,
470and
471.Fn getversion
472return the indicated \fBsysctl\fR variable, or -1 if there is an error
473fetching the variable.
474.Pp
475.Fn checkversion
476returns 0 if the kernel and userland
477.Nm devstat
478versions match.  If they do not match, it returns -1.
479.Pp
480.Fn getdevs
481and
482.Fn selectdevs
483return -1 in case of an error, 0 if there is no error and 1 if the device
484list or selected devices have changed.  A return value of 1 from
485.Fn getdevs
486is usually a hint to re-run
487.Fn selectdevs
488because the device list has changed.
489.Pp
490.Fn buildmatch
491returns -1 for error, and 0 if there is no error.
492.Pp
493.Fn compute_stats
494returns -1 for error, and 0 for success.
495.Pp
496.Fn compute_etime
497returns the computed elapsed time.
498.Pp
499If an error is returned from one of the
500.Nm
501library functions, the reason for the error is generally printed in
502the global string
503.Va devstat_errbuf
504which is
505.Dv DEVSTAT_ERRBUF_SIZE
506characters long.
507.Sh SEE ALSO
508.Xr systat 1 ,
509.Xr iostat 8 ,
510.Xr rpc.rstatd 8 ,
511.Xr vmstat 8 ,
512.Xr devstat 9
513.Sh HISTORY
514The
515.Nm
516statistics system first appeared in
517.Fx 3.0 .
518.Sh AUTHORS
519.An Kenneth Merry Aq ken@FreeBSD.ORG
520.Sh BUGS
521There should probably be an interface to de-allocate memory allocated by
522.Fn getdevs ,
523.Fn selectdevs ,
524and
525.Fn buildmatch .
526.Pp
527.Fn selectdevs
528should probably not select more than
529.Va maxshowdevs
530devices in
531.Dq top
532mode when no devices have been selected previously.
533.Pp
534There should probably be functions to perform the statistics buffer
535swapping that goes on in most of the clients of this library.
536.Pp
537The
538.Va statinfo
539and
540.Va devinfo
541structures should probably be cleaned up and thought out a little more.
542