xref: /freebsd/lib/libdevstat/devstat.3 (revision e267a66620d8787cb1e738dbee193cfddc66bd3b)
1.\"
2.\" Copyright (c) 1998 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 ahead of time.  The
153.Va dinfo
154subelement contains the following elements:
155.Bd -literal -offset indent
156struct devinfo {
157	struct devstat	*devices;
158	u_int8_t	*mem_ptr;
159	long		generation;
160	int		numdevs;
161};
162.Ed
163.Pp
164The
165.Va kern.devstat.all
166.Nm sysctl
167variable contains an array of
168.Nm devstat
169structures, but at the head of the array is the current
170.Nm devstat
171generation.  The reason the generation is at the head of the buffer is so
172that userland software accessing the devstat statistics information can
173atomically get both the statistics information and the corresponding
174generation number.  If client software were forced to get the generation
175number via a separate
176.Nm sysctl
177variable (which is available for convenience), the list of devices could
178change between the time the client gets the generation and the time the
179client gets the device list.
180.Pp
181The
182.Va mem_ptr
183subelement of the
184.Va devinfo
185structure is a pointer to memory that is allocated, and resized if
186necessary, by
187.Fn getdevs .
188The devices subelement of the
189.Va devinfo
190structure is basically a pointer to the beginning of the array of devstat
191structures from the
192.Va kern.devstat.all
193.Nm sysctl
194variable.  The generation subelement of the
195.Nm devinfo
196structure contains the generation number from the
197.Va kern.devstat.all
198.Nm sysctl
199variable.
200The
201.Va numdevs
202subelement of the
203.Va devinfo
204structure contains the current
205number of devices registered with the kernel
206.Nm devstat
207subsystem.
208.Pp
209.Fn selectdevs
210selects devices to display based upon a number of criteria:
211.Bl -tag -width flag
212.It specified devices
213Specified devices are the first selection priority.  These are generally
214devices specified by name by the user.  e.g. da0, da1, cd0.
215.It match patterns
216These are pattern matching expressions generated by
217.Fn buildmatch
218from user input.
219.It performance
220If performance mode is enabled, devices will be sorted based on the
221.Va bytes
222field in the
223.Va device_selection
224structure passed in to
225.Fn selectdevs .
226The
227.Va bytes
228value currently must be maintained by the user.  In the future,
229this may be done for him in a
230.Nm
231library routine.
232If no devices have been selected by name or by pattern, the performance
233tracking code will select every device in the system, and sort them by
234performance.  If devices have been selected by name or pattern, the
235performance tracking code will honor those selections and will only sort
236among the selected devices.
237.It order in the devstat list
238If the selection mode is set to DS_SELECT_ADD, and if there are still less
239than
240.Va maxshowdevs
241devices selected,
242.Fn selectdevs
243will automatically select up to
244.Va maxshowdevs
245devices.
246.El
247.Pp
248.Fn selectdevs
249performs selections in four different modes:
250.Bl -tag -width DS_SELECT_ADDONLY
251.It DS_SELECT_ADD
252In add mode,
253.Fn selectdevs
254will select any unselected devices specified by name or matching pattern.
255It will also select more devices, in devstat list order, until the number
256of selected devices is equal to
257.Va maxshowdevs
258or until all devices are
259selected.
260.It DS_SELECT_ONLY
261In only mode,
262.Fn selectdevs
263will clear all current selections, and will only select devices specified
264by name or by matching pattern.
265.It DS_SELECT_REMOVE
266In remove mode,
267.Fn selectdevs
268will remove devices specified by name or by matching pattern.  It will not
269select any additional devices.
270.It DS_SELECT_ADDONLY
271In add only mode,
272.Fn selectdevs
273will select any unselected devices specified by name or matching pattern.
274In this respect it is identical to add mode.  It will not, however, select
275any devices other than those specified.
276.El
277.Pp
278In all selection modes,
279.Fn selectdevs
280will not select any more than
281.Va maxshowdevs
282devices.  One exception to
283this is when you are in
284.Dq top
285mode and no devices have been selected.  In
286this case,
287.Fn selectdevs
288will select every device in the system.  Client programs must pay attention
289to selection order when deciding whether to pay attention to a particular
290device.  This may be the wrong behavior, and probably requires additional
291thought.
292.Pp
293.Fn selectdevs
294handles allocation and resizing of the
295.Va dev_select
296structure passed in
297by the client.
298.Fn selectdevs
299uses the
300.Va numdevs
301and
302.Va current_generation
303fields to track the
304current
305.Nm
306generation and number of devices.  If
307.Va num_selections
308is not the same
309as
310.Va numdevs
311or if
312.Va select_generation
313is not the same as
314.Va current_generation ,
315.Fn selectdevs
316will resize the selection list as necessary, and re-initialize the
317selection array.
318.Pp
319.Fn buildmatch
320takes a comma separated match string and compiles it into a
321\fBdevstat_match\fR structure that is understood by
322.Fn selectdevs .
323Match strings have the following format:
324.Pp
325.Bd -literal -offset indent
326device,type,if
327.Ed
328.Pp
329.Fn buildmatch
330takes care of allocating and reallocating the match list as necessary.
331Currently known match types include:
332.Pp
333.Bl -tag -width indent -compact
334.It device type:
335.Bl -tag -width 123456789 -compact
336.It da
337Direct Access devices
338.It sa
339Sequential Access devices
340.It printer
341Printers
342.It proc
343Processor devices
344.It worm
345Write Once Read Multiple devices
346.It cd
347CD devices
348.It scanner
349Scanner devices
350.It optical
351Optical Memory devices
352.It changer
353Medium Changer devices
354.It comm
355Communication devices
356.It array
357Storage Array devices
358.It enclosure
359Enclosure Services devices
360.It floppy
361Floppy devices
362.El
363.Pp
364.It interface:
365.Bl -tag -width 123456789 -compact
366.It IDE
367Integrated Drive Electronics devices
368.It SCSI
369Small Computer System Interface devices
370.It other
371Any other device interface
372.El
373.Pp
374.It passthrough:
375.Bl -tag -width 123456789 -compact
376.It pass
377Passthrough devices
378.El
379.El
380.Pp
381.Fn compute_stats
382provides an easy way to obtain various device statistics.  Only two
383arguments are mandatory:
384.Va current
385and
386.Va etime .
387Every other argument is optional.  For most applications, the user will
388want to supply both
389.Va current
390and
391.Va previous
392devstat structures so that statistics may be calculated over a given period
393of time.  In some instances, for instance when calculating statistics since
394system boot, the user may pass in a NULL pointer for the
395.Va previous
396argument.  In that case,
397.Fn compute_stats
398will use the total stats in the
399.Va current
400structure to calculate statistics over
401.Va etime .
402The various statistics that may be calculated by
403.Fn compute_stats
404should be mostly explained by the function declaration itself, but for
405completeness here is a list of variable names and the statistics that will
406be put in them:
407.Bl -tag -width transfers_per_second
408.It total_bytes
409This is the total number of bytes transferred on the given device, both
410reads and writes, between the acquisition of
411.Va previous
412and the acquisition of
413.Va current .
414If
415.Va previous
416is NULL, the result will be the total reads and writes given in
417.Va current .
418.It total_transfers
419This is the total number of transfers completed between the
420acquisition of
421.Va previous
422and the acquisition of
423.Va current .
424If
425.Va previous
426is NULL, the result will be the total number of transactions listed in
427.Va current .
428.It total_blocks
429This is basically
430.Va total_bytes
431divided by the device blocksize.  If the device blocksize is listed as
432.Sq 0 ,
433the device blocksize will default to 512 bytes.
434.It kb_per_transfer
435This is the average number of kilobytes per transfer during the measurement
436period.
437.It transfers_per_second
438This is the average number of transfers per second.
439.It mb_per_second
440This is average megabytes per second.
441.It blocks_per_second
442This is average blocks per second.  If the device blocksize is
443.Sq 0 ,
444a default blocksize of 512 bytes will be used instead.
445.It ms_per_transaction
446The average number of milliseconds per transaction.
447.El
448.Pp
449.Fn compute_etime
450provides an easy way to find the difference in seconds between two
451.Va timeval
452structures.  This is most commonly used in conjunction with the time
453recorded by the
454.Fn getdevs
455function (in struct
456.Va statinfo )
457each time it fetches the current
458.Nm
459list.
460.Sh RETURN VALUES
461.Fn getnumdevs ,
462.Fn getgeneration ,
463and
464.Fn getversion
465return the indicated \fBsysctl\fR variable, or -1 if there is an error
466fetching the variable.
467.Pp
468.Fn checkversion
469returns 0 if the kernel and userland
470.Nm devstat
471versions match.  If they do not match, it returns -1.
472.Pp
473.Fn getdevs
474and
475.Fn selectdevs
476return -1 in case of an error, 0 if there is no error and 1 if the device
477list or selected devices have changed.  A return value of 1 from
478.Fn getdevs
479is usually a hint to re-run
480.Fn selectdevs
481because the device list has changed.
482.Pp
483.Fn buildmatch
484returns -1 for error, and 0 if there is no error.
485.Pp
486.Fn compute_stats
487returns -1 for error, and 0 for success.
488.Pp
489.Fn compute_etime
490returns the computed elapsed time.
491.Pp
492If an error is returned from one of the
493.Nm
494library functions, the reason for the error is generally printed in
495the global string
496.Va devstat_errbuf
497which is
498.Dv DEVSTAT_ERRBUF_SIZE
499characters long.
500.Sh SEE ALSO
501.Xr systat 1 ,
502.Xr iostat 8 ,
503.Xr rpc.rstatd 8 ,
504.Xr vmstat 8 ,
505.Xr devstat 9
506.Sh HISTORY
507The
508.Nm
509statistics system first appeared in
510.Fx 3.0 .
511.Sh AUTHORS
512.An Kenneth Merry Aq ken@FreeBSD.ORG
513.Sh BUGS
514There should probably be an interface to de-allocate memory allocated by
515.Fn getdevs ,
516.Fn selectdevs ,
517and
518.Fn buildmatch .
519.Pp
520.Fn selectdevs
521should probably not select more than
522.Va maxshowdevs
523devices in
524.Dq top
525mode when no devices have been selected previously.
526.Pp
527There should probably be functions to perform the statistics buffer
528swapping that goes on in most of the clients of this library.
529.Pp
530The
531.Va statinfo
532and
533.Va devinfo
534structures should probably be cleaned up and thought out a little more.
535