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