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