xref: /freebsd/lib/libdevstat/devstat.3 (revision 6b3455a7665208c366849f0b2b3bc916fb97516e)
1.\"
2.\" Copyright (c) 1998, 1999, 2001 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 July 15, 2001
31.Dt DEVSTAT 3
32.Os
33.Sh NAME
34.Nm devstat ,
35.Nm devstat_getnumdevs ,
36.Nm devstat_getgeneration ,
37.Nm devstat_getversion ,
38.Nm devstat_checkversion ,
39.Nm devstat_getdevs ,
40.Nm devstat_selectdevs ,
41.Nm devstat_buildmatch ,
42.Nm devstat_compute_statistics ,
43.Nm devstat_compute_etime
44.Nd device statistics utility library
45.Sh LIBRARY
46.Lb libdevstat
47.Sh SYNOPSIS
48.In devstat.h
49.Ft int
50.Fo devstat_getnumdevs
51.Fa "kvm_t *kd"
52.Fc
53.Ft long
54.Fo devstat_getgeneration
55.Fa "kvm_t *kd"
56.Fc
57.Ft int
58.Fo devstat_getversion
59.Fa "kvm_t *kd"
60.Fc
61.Ft int
62.Fo devstat_checkversion
63.Fa "kvm_t *kd"
64.Fc
65.Ft int
66.Fo devstat_getdevs
67.Fa "kvm_t *kd"
68.Fa "struct statinfo *stats"
69.Fc
70.Ft int
71.Fo devstat_selectdevs
72.Fa "struct device_selection **dev_select"
73.Fa "int *num_selected"
74.Fa "int *num_selections"
75.Fa "long *select_generation"
76.Fa "long current_generation"
77.Fa "struct devstat *devices"
78.Fa "int numdevs"
79.Fa "struct devstat_match *matches"
80.Fa "int num_matches"
81.Fa "char **dev_selections"
82.Fa "int num_dev_selections"
83.Fa "devstat_select_mode select_mode"
84.Fa "int maxshowdevs"
85.Fa "int perf_select"
86.Fc
87.Ft int
88.Fo devstat_buildmatch
89.Fa "char *match_str"
90.Fa "struct devstat_match **matches"
91.Fa "int *num_matches"
92.Fc
93.Ft int
94.Fo devstat_compute_statistics
95.Fa "struct devstat *current"
96.Fa "struct devstat *previous"
97.Fa "long double etime"
98.Fa "..."
99.Fc
100.Ft long double
101.Fo devstat_compute_etime
102.Fa "struct bintime cur_time"
103.Fa "struct bintime prev_time"
104.Fc
105.Sh DESCRIPTION
106The
107.Nm
108library is a library of helper functions for dealing with the kernel
109.Xr devstat 9
110interface, which is accessible to users via
111.Xr sysctl 3
112and
113.Xr kvm 3 .
114All functions that take a
115.Vt kvm_t *
116as first argument can be passed
117.Dv NULL
118instead of a kvm handle as this argument,
119which causes the data to be read via
120.Xr sysctl 3 .
121Otherwise, it is read via
122.Xr kvm 3
123using the supplied handle.
124.Fn devstat_checkversion
125should be called with each kvm handle that is going to be used (or with
126.Dv NULL
127if
128.Xr sysctl 3
129is going to be used).
130.Pp
131.Fn devstat_getnumdevs
132returns the number of devices registered with the
133.Nm
134subsystem in the kernel.
135.Pp
136.Fn devstat_getgeneration
137returns the current generation of the
138.Nm
139list of devices in the kernel.
140.Pp
141.Fn devstat_getversion
142returns the current kernel
143.Nm
144version.
145.Pp
146.Fn devstat_checkversion
147checks the userland devstat version against the kernel devstat version.
148If the two are identical, it returns zero.
149Otherwise, it prints an appropriate error in
150.Va devstat_errbuf
151and returns -1.
152.Pp
153.Fn devstat_getdevs
154fetches the current list of devices and statistics into the supplied
155.Va statinfo
156structure.
157The
158.Va statinfo
159structure can be found in
160.In devstat.h :
161.Bd -literal -offset indent
162struct statinfo {
163	long            cp_time[CPUSTATES];
164	long            tk_nin;
165	long            tk_nout;
166	struct devinfo  *dinfo;
167	long double     snap_time;
168};
169.Ed
170.Pp
171.Fn devstat_getdevs
172expects the
173.Va statinfo
174structure to be allocated, and it also expects the
175.Va dinfo
176subelement to be allocated and zeroed prior to the first invocation of
177.Fn devstat_getdevs .
178The
179.Va dinfo
180subelement is used to store state between calls, and should not be modified
181after the first call to
182.Fn devstat_getdevs .
183The
184.Va dinfo
185subelement contains the following elements:
186.Bd -literal -offset indent
187struct devinfo {
188	struct devstat	*devices;
189	u_int8_t	*mem_ptr;
190	long		generation;
191	int		numdevs;
192};
193.Ed
194.Pp
195The
196.Va kern.devstat.all
197.Nm sysctl
198variable contains an array of
199.Nm
200structures, but at the head of the array is the current
201.Nm
202generation.
203The reason the generation is at the head of the buffer is so that userland
204software accessing the devstat statistics information can atomically get
205both the statistics information and the corresponding generation number.
206If client software were forced to get the generation number via a separate
207.Nm sysctl
208variable (which is available for convenience), the list of devices could
209change between the time the client gets the generation and the time the
210client gets the device list.
211.Pp
212The
213.Va mem_ptr
214subelement of the
215.Va devinfo
216structure is a pointer to memory that is allocated, and resized if
217necessary, by
218.Fn devstat_getdevs .
219The devices subelement of the
220.Va devinfo
221structure is basically a pointer to the beginning of the array of devstat
222structures from the
223.Va kern.devstat.all
224.Nm sysctl
225variable (or the corresponding values read via
226.Xr kvm 3 ) .
227The generation subelement of the
228.Va devinfo
229structure contains the corresponding generation number.
230The
231.Va numdevs
232subelement of the
233.Va devinfo
234structure contains the current
235number of devices registered with the kernel
236.Nm
237subsystem.
238.Pp
239.Fn devstat_selectdevs
240selects devices to display based upon a number of criteria:
241.Bl -tag -width flag
242.It specified devices
243Specified devices are the first selection priority.
244These are generally devices specified by name by the user e.g.\& da0, da1, cd0.
245.It match patterns
246These are pattern matching expressions generated by
247.Fn devstat_buildmatch
248from user input.
249.It performance
250If performance mode is enabled, devices will be sorted based on the
251.Va bytes
252field in the
253.Va device_selection
254structure passed in to
255.Fn devstat_selectdevs .
256The
257.Va bytes
258value currently must be maintained by the user.
259In the future, this may be done for him in a
260.Nm
261library routine.
262If no devices have been selected by name or by pattern, the performance
263tracking code will select every device in the system, and sort them by
264performance.
265If devices have been selected by name or pattern, the performance tracking
266code will honor those selections and will only sort among the selected
267devices.
268.It order in the devstat list
269If the selection mode is set to DS_SELECT_ADD, and if there are still less
270than
271.Va maxshowdevs
272devices selected,
273.Fn devstat_selectdevs
274will automatically select up to
275.Va maxshowdevs
276devices.
277.El
278.Pp
279.Fn devstat_selectdevs
280performs selections in four different modes:
281.Bl -tag -width DS_SELECT_ADDONLY
282.It DS_SELECT_ADD
283In add mode,
284.Fn devstat_selectdevs
285will select any unselected devices specified by name or matching pattern.
286It will also select more devices, in devstat list order, until the number
287of selected devices is equal to
288.Va maxshowdevs
289or until all devices are
290selected.
291.It DS_SELECT_ONLY
292In only mode,
293.Fn devstat_selectdevs
294will clear all current selections, and will only select devices specified
295by name or by matching pattern.
296.It DS_SELECT_REMOVE
297In remove mode,
298.Fn devstat_selectdevs
299will remove devices specified by name or by matching pattern.
300It will not select any additional devices.
301.It DS_SELECT_ADDONLY
302In add only mode,
303.Fn devstat_selectdevs
304will select any unselected devices specified by name or matching pattern.
305In this respect it is identical to add mode.
306It will not, however, select any devices other than those specified.
307.El
308.Pp
309In all selection modes,
310.Fn devstat_selectdevs
311will not select any more than
312.Va maxshowdevs
313devices.
314One exception to this is when you are in
315.Dq top
316mode and no devices have been selected.
317In this case,
318.Fn devstat_selectdevs
319will select every device in the system.
320Client programs must pay attention to selection order when deciding whether
321to pay attention to a particular device.
322This may be the wrong behavior, and probably requires additional thought.
323.Pp
324.Fn devstat_selectdevs
325handles allocation and resizing of the
326.Va dev_select
327structure passed in
328by the client.
329.Fn devstat_selectdevs
330uses the
331.Va numdevs
332and
333.Va current_generation
334fields to track the
335current
336.Nm
337generation and number of devices.
338If
339.Va num_selections
340is not the same
341as
342.Va numdevs
343or if
344.Va select_generation
345is not the same as
346.Va current_generation ,
347.Fn devstat_selectdevs
348will resize the selection list as necessary, and re-initialize the
349selection array.
350.Pp
351.Fn devstat_buildmatch
352take a comma separated match string and compile it into a
353\fBdevstat_match\fR structure that is understood by
354.Fn selectdevs .
355Match strings have the following format:
356.Pp
357.Bd -literal -offset indent
358device,type,if
359.Ed
360.Pp
361.Fn devstat_buildmatch
362takes care of allocating and reallocating the match list as necessary.
363Currently known match types include:
364.Pp
365.Bl -tag -width indent -compact
366.It device type:
367.Bl -tag -width 9n -compact
368.It da
369Direct Access devices
370.It sa
371Sequential Access devices
372.It printer
373Printers
374.It proc
375Processor devices
376.It worm
377Write Once Read Multiple devices
378.It cd
379CD devices
380.It scanner
381Scanner devices
382.It optical
383Optical Memory devices
384.It changer
385Medium Changer devices
386.It comm
387Communication devices
388.It array
389Storage Array devices
390.It enclosure
391Enclosure Services devices
392.It floppy
393Floppy devices
394.El
395.Pp
396.It interface:
397.Bl -tag -width 9n -compact
398.It IDE
399Integrated Drive Electronics devices
400.It SCSI
401Small Computer System Interface devices
402.It other
403Any other device interface
404.El
405.Pp
406.It passthrough:
407.Bl -tag -width 9n -compact
408.It pass
409Passthrough devices
410.El
411.El
412.Pp
413.Fn devstat_compute_statistics
414is an updated version of
415.Fn compute_stats
416that provides more complete statistics calculation.
417There are four arguments for which values \fBmust\fR be supplied:
418.Va current ,
419.Va previous ,
420.Va etime ,
421and the terminating argument for the varargs list,
422.Va DSM_NONE .
423For most applications, the user will want to supply valid devstat
424structures for both
425.Va current
426and
427.Va previous .
428In some instances, for instance when calculating statistics since system
429boot, the user may pass in a NULL pointer for the
430.Va previous
431argument.
432In that case,
433.Fn devstat_compute_statistics
434will use the total stats in the
435.Va current
436structure to calculate statistics over
437.Va etime .
438For each statistic to be calculated, the user should supply the proper
439enumerated type (listed below), and a variable of the indicated type.
440All statistics are either integer values, for which a u_int64_t is used,
441or floating point, for which a long double is used.
442The statistics that may be calculated are:
443.Bl -tag -width DSM_TRANSFERS_PER_SECOND_OTHER
444.It DSM_NONE
445type: N/A
446.Pp
447This \fBmust\fR
448be the last argument passed to
449.Fn devstat_compute_statistics .
450It is an argument list terminator.
451.It DSM_TOTAL_BYTES
452type: u_int64_t *
453.Pp
454The total number of bytes transferred between the acquisition of
455.Va previous
456and
457.Va current .
458.It DSM_TOTAL_BYTES_READ
459.It DSM_TOTAL_BYTES_WRITE
460.It DSM_TOTAL_BYTES_FREE
461type: u_int64_t *
462.Pp
463The total number of bytes in transactions of the specified type
464between the acquisition of
465.Va previous
466and
467.Va current .
468.It DSM_TOTAL_TRANSFERS
469type: u_int64_t *
470.Pp
471The total number of transfers between the acquisition of
472.Va previous
473and
474.Va current .
475.It DSM_TOTAL_TRANSFERS_OTHER
476.It DSM_TOTAL_TRANSFERS_READ
477.It DSM_TOTAL_TRANSFERS_WRITE
478.It DSM_TOTAL_TRANSFERS_FREE
479type: u_int64_t *
480.Pp
481The total number of transactions of the specified type between
482the acquisition of
483.Va previous
484and
485.Va current .
486.It DSM_TOTAL_BLOCKS
487type: u_int64_t *
488.Pp
489The total number of blocks transferred between the acquisition of
490.Va previous
491and
492.Va current .
493This number is in terms of the blocksize reported by the device.
494If no blocksize has been reported (i.e., the block size is 0), a default
495blocksize of 512 bytes will be used in the calculation.
496.It DSM_TOTAL_BLOCKS_READ
497.It DSM_TOTAL_BLOCKS_WRITE
498.It DSM_TOTAL_BLOCKS_FREE
499type: u_int64_t *
500.Pp
501The total number of blocks of the specified type between the acquisition of
502.Va previous
503and
504.Va current .
505This number is in terms of the blocksize reported by the device.
506If no blocksize has been reported (i.e., the block size is 0), a default
507blocksize of 512 bytes will be used in the calculation.
508.It DSM_KB_PER_TRANSFER
509type: long double *
510.Pp
511The average number of kilobytes per transfer between the acquisition of
512.Va previous
513and
514.Va current .
515.It DSM_KB_PER_TRANSFER_READ
516.It DSM_KB_PER_TRANSFER_WRITE
517.It DSM_KB_PER_TRANSFER_FREE
518type: long double *
519.Pp
520The average number of kilobytes in the specified type transaction between
521the acquisition of
522.Va previous
523and
524.Va current .
525.It DSM_TRANSFERS_PER_SECOND
526type: long double *
527.Pp
528The average number of transfers per second between the acquisition of
529.Va previous
530and
531.Va current .
532.It DSM_TRANSFERS_PER_SECOND_OTHER
533.It DSM_TRANSFERS_PER_SECOND_READ
534.It DSM_TRANSFERS_PER_SECOND_WRITE
535.It DSM_TRANSFERS_PER_SECOND_FREE
536type: long double *
537.Pp
538The average number of transactions of the specified type per second
539between the acquisition of
540.Va previous
541and
542.Va current .
543.It DSM_MB_PER_SECOND
544type: long double *
545.Pp
546The average number of megabytes transferred per second between the
547acquisition of
548.Va previous
549and
550.Va current .
551.It DSM_MB_PER_SECOND_READ
552.It DSM_MB_PER_SECOND_WRITE
553.It DSM_MB_PER_SECOND_FREE
554type: long double *
555.Pp
556The average number of megabytes per second in the specified type of
557transaction between the acquisition of
558.Va previous
559and
560.Va current .
561.It DSM_BLOCKS_PER_SECOND
562type: long double *
563.Pp
564The average number of blocks transferred per second between the acquisition of
565.Va previous
566and
567.Va current .
568This number is in terms of the blocksize reported by the device.
569If no blocksize has been reported (i.e., the block size is 0), a default
570blocksize of 512 bytes will be used in the calculation.
571.It DSM_BLOCKS_PER_SECOND_READ
572.It DSM_BLOCKS_PER_SECOND_WRITE
573.It DSM_BLOCKS_PER_SECOND_FREE
574type: long double *
575.Pp
576The average number of blocks per second in the specificed type of transaction
577between the acquisition of
578.Va previous
579and
580.Va current .
581This number is in terms of the blocksize reported by the device.
582If no blocksize has been reported (i.e., the block size is 0), a default
583blocksize of 512 bytes will be used in the calculation.
584.It DSM_MS_PER_TRANSACTION
585type: long double *
586.Pp
587The average duration of transactions between the acquisition of
588.Va previous
589and
590.Va current .
591.It DSM_MS_PER_TRANSACTION_OTHER
592.It DSM_MS_PER_TRANSACTION_READ
593.It DSM_MS_PER_TRANSACTION_WRITE
594.It DSM_MS_PER_TRANSACTION_FREE
595type: long double *
596.Pp
597The average duration of transactions of the specified type between the
598acquisition of
599.Va previous
600and
601.Va current .
602.It DSM_BUSY_PCT
603type: long double *
604.Pp
605The percentage of time the device had one or more transactions outstanding
606between the acquisition of
607.Va previous
608and
609.Va current .
610.It DSM_QUEUE_LENGTH
611type: u_int64_t *
612.Pp
613The number of not yet completed transactions at the time when
614.Va current
615was acquired.
616.It DSM_SKIP
617type: N/A
618.Pp
619If you do not need a result from
620.Fn devstat_compute_statistics ,
621just put
622.Va DSM_SKIP
623as first (type) parameter and
624.Va NULL
625as second parameter.
626This can be useful in scenarios where the statistics to be calculated
627are determined at run time.
628.El
629.Pp
630.Fn devstat_compute_etime
631provides an easy way to find the difference in seconds between two
632.Va bintime
633structures.
634This is most commonly used in conjunction with the time recorded by the
635.Fn devstat_getdevs
636function (in struct
637.Va statinfo )
638each time it fetches the current
639.Nm
640list.
641.Sh RETURN VALUES
642.Fn devstat_getnumdevs ,
643.Fn devstat_getgeneration ,
644and
645.Fn devstat_getversion
646return the indicated \fBsysctl\fR variable, or -1 if there is an error
647fetching the variable.
648.Pp
649.Fn devstat_checkversion
650returns 0 if the kernel and userland
651.Nm
652versions match.
653If they do not match, it returns -1.
654.Pp
655.Fn devstat_getdevs
656and
657.Fn devstat_selectdevs
658return -1 in case of an error, 0 if there is no error and 1 if the device
659list or selected devices have changed.
660A return value of 1 from
661.Fn devstat_getdevs
662is usually a hint to re-run
663.Fn devstat_selectdevs
664because the device list has changed.
665.Pp
666.Fn devstat_buildmatch
667returns -1 for error, and 0 if there is no error.
668.Pp
669.Fn devstat_compute_etime
670returns the computed elapsed time.
671.Pp
672.Fn devstat_compute_statistics
673returns -1 for error, and 0 for success.
674.Pp
675If an error is returned from one of the
676.Nm
677library functions, the reason for the error is generally printed in
678the global string
679.Va devstat_errbuf
680which is
681.Dv DEVSTAT_ERRBUF_SIZE
682characters long.
683.Sh SEE ALSO
684.Xr systat 1 ,
685.Xr kvm 3 ,
686.Xr sysctl 3 ,
687.Xr iostat 8 ,
688.Xr rpc.rstatd 8 ,
689.Xr sysctl 8 ,
690.Xr vmstat 8 ,
691.Xr devstat 9
692.Sh HISTORY
693The
694.Nm
695statistics system first appeared in
696.Fx 3.0 .
697The new interface (the functions prefixed with devstat_) first appeared in
698.Fx 5.0 .
699.Sh AUTHORS
700.An Kenneth Merry Aq ken@FreeBSD.org
701.Sh BUGS
702There should probably be an interface to de-allocate memory allocated by
703.Fn devstat_getdevs ,
704.Fn devstat_selectdevs ,
705and
706.Fn devstat_buildmatch .
707.Pp
708.Fn devstat_selectdevs
709should probably not select more than
710.Va maxshowdevs
711devices in
712.Dq top
713mode when no devices have been selected previously.
714.Pp
715There should probably be functions to perform the statistics buffer
716swapping that goes on in most of the clients of this library.
717.Pp
718The
719.Va statinfo
720and
721.Va devinfo
722structures should probably be cleaned up and thought out a little more.
723