xref: /freebsd/lib/libdevstat/devstat.3 (revision fce1f260f16b8775bc732df5ad1992bd1a80a7db)
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
446is an updated version of
447.Fn compute_stats
448that provides more complete statistics calculation.
449There are four arguments for which values
450.Em must
451be supplied:
452.Fa current ,
453.Fa previous ,
454.Fa etime ,
455and the terminating argument for the varargs list,
456.Dv DSM_NONE .
457For most applications, the user will want to supply valid
458.Vt devstat
459structures for both
460.Fa current
461and
462.Fa previous .
463In some instances, for instance when calculating statistics since system
464boot, the user may pass in a
465.Dv NULL
466pointer for the
467.Fa previous
468argument.
469In that case,
470.Fn devstat_compute_statistics
471will use the total stats in the
472.Fa current
473structure to calculate statistics over
474.Fa etime .
475For each statistics to be calculated, the user should supply the proper
476enumerated type (listed below), and a variable of the indicated type.
477All statistics are either integer values, for which a
478.Vt u_int64_t
479is used,
480or floating point, for which a
481.Vt "long double"
482is used.
483The statistics that may be calculated are:
484.Bl -tag -width ".Dv DSM_TRANSFERS_PER_SECOND_OTHER"
485.It Dv DSM_NONE
486type: N/A
487.Pp
488This
489.Em must
490be the last argument passed to
491.Fn devstat_compute_statistics .
492It is an argument list terminator.
493.It Dv DSM_TOTAL_BYTES
494type:
495.Vt "u_int64_t *"
496.Pp
497The total number of bytes transferred between the acquisition of
498.Fa previous
499and
500.Fa current .
501.It Dv DSM_TOTAL_BYTES_READ
502.It Dv DSM_TOTAL_BYTES_WRITE
503.It Dv DSM_TOTAL_BYTES_FREE
504type:
505.Vt "u_int64_t *"
506.Pp
507The total number of bytes in transactions of the specified type
508between the acquisition of
509.Fa previous
510and
511.Fa current .
512.It Dv DSM_TOTAL_TRANSFERS
513type:
514.Vt "u_int64_t *"
515.Pp
516The total number of transfers between the acquisition of
517.Fa previous
518and
519.Fa current .
520.It Dv DSM_TOTAL_TRANSFERS_OTHER
521.It Dv DSM_TOTAL_TRANSFERS_READ
522.It Dv DSM_TOTAL_TRANSFERS_WRITE
523.It Dv DSM_TOTAL_TRANSFERS_FREE
524type:
525.Vt "u_int64_t *"
526.Pp
527The total number of transactions of the specified type between
528the acquisition of
529.Fa previous
530and
531.Fa current .
532.It Dv DSM_TOTAL_BLOCKS
533type:
534.Vt "u_int64_t *"
535.Pp
536The total number of blocks transferred between the acquisition of
537.Fa previous
538and
539.Fa current .
540This number is in terms of the blocksize reported by the device.
541If no blocksize has been reported (i.e., the block size is 0), a default
542blocksize of 512 bytes will be used in the calculation.
543.It Dv DSM_TOTAL_BLOCKS_READ
544.It Dv DSM_TOTAL_BLOCKS_WRITE
545.It Dv DSM_TOTAL_BLOCKS_FREE
546type:
547.Vt "u_int64_t *"
548.Pp
549The total number of blocks of the specified type between the acquisition of
550.Fa previous
551and
552.Fa current .
553This number is in terms of the blocksize reported by the device.
554If no blocksize has been reported (i.e., the block size is 0), a default
555blocksize of 512 bytes will be used in the calculation.
556.It Dv DSM_KB_PER_TRANSFER
557type:
558.Vt "long double *"
559.Pp
560The average number of kilobytes per transfer between the acquisition of
561.Fa previous
562and
563.Fa current .
564.It Dv DSM_KB_PER_TRANSFER_READ
565.It Dv DSM_KB_PER_TRANSFER_WRITE
566.It Dv DSM_KB_PER_TRANSFER_FREE
567type:
568.Vt "long double *"
569.Pp
570The average number of kilobytes in the specified type transaction between
571the acquisition of
572.Fa previous
573and
574.Fa current .
575.It Dv DSM_TRANSFERS_PER_SECOND
576type:
577.Vt "long double *"
578.Pp
579The average number of transfers per second between the acquisition of
580.Fa previous
581and
582.Fa current .
583.It Dv DSM_TRANSFERS_PER_SECOND_OTHER
584.It Dv DSM_TRANSFERS_PER_SECOND_READ
585.It Dv DSM_TRANSFERS_PER_SECOND_WRITE
586.It Dv DSM_TRANSFERS_PER_SECOND_FREE
587type:
588.Vt "long double *"
589.Pp
590The average number of transactions of the specified type per second
591between the acquisition of
592.Fa previous
593and
594.Fa current .
595.It Dv DSM_MB_PER_SECOND
596type:
597.Vt "long double *"
598.Pp
599The average number of megabytes transferred per second between the
600acquisition of
601.Fa previous
602and
603.Fa current .
604.It Dv DSM_MB_PER_SECOND_READ
605.It Dv DSM_MB_PER_SECOND_WRITE
606.It Dv DSM_MB_PER_SECOND_FREE
607type:
608.Vt "long double *"
609.Pp
610The average number of megabytes per second in the specified type of
611transaction between the acquisition of
612.Fa previous
613and
614.Fa current .
615.It Dv DSM_BLOCKS_PER_SECOND
616type:
617.Vt "long double *"
618.Pp
619The average number of blocks transferred per second between the acquisition of
620.Fa previous
621and
622.Fa current .
623This number is in terms of the blocksize reported by the device.
624If no blocksize has been reported (i.e., the block size is 0), a default
625blocksize of 512 bytes will be used in the calculation.
626.It Dv DSM_BLOCKS_PER_SECOND_READ
627.It Dv DSM_BLOCKS_PER_SECOND_WRITE
628.It Dv DSM_BLOCKS_PER_SECOND_FREE
629type:
630.Vt "long double *"
631.Pp
632The average number of blocks per second in the specificed type of transaction
633between the acquisition of
634.Fa previous
635and
636.Fa current .
637This number is in terms of the blocksize reported by the device.
638If no blocksize has been reported (i.e., the block size is 0), a default
639blocksize of 512 bytes will be used in the calculation.
640.It Dv DSM_MS_PER_TRANSACTION
641type:
642.Vt "long double *"
643.Pp
644The average duration of transactions between the acquisition of
645.Fa previous
646and
647.Fa current .
648.It Dv DSM_MS_PER_TRANSACTION_OTHER
649.It Dv DSM_MS_PER_TRANSACTION_READ
650.It Dv DSM_MS_PER_TRANSACTION_WRITE
651.It Dv DSM_MS_PER_TRANSACTION_FREE
652type:
653.Vt "long double *"
654.Pp
655The average duration of transactions of the specified type between the
656acquisition of
657.Fa previous
658and
659.Fa current .
660.It Dv DSM_BUSY_PCT
661type:
662.Vt "long double *"
663.Pp
664The percentage of time the device had one or more transactions outstanding
665between the acquisition of
666.Fa previous
667and
668.Fa current .
669.It Dv DSM_QUEUE_LENGTH
670type:
671.Vt "u_int64_t *"
672.Pp
673The number of not yet completed transactions at the time when
674.Fa current
675was acquired.
676.It Dv DSM_SKIP
677type: N/A
678.Pp
679If you do not need a result from
680.Fn devstat_compute_statistics ,
681just put
682.Dv DSM_SKIP
683as first (type) parameter and
684.Dv NULL
685as second parameter.
686This can be useful in scenarios where the statistics to be calculated
687are determined at run time.
688.El
689.Pp
690The
691.Fn devstat_compute_etime
692function
693provides an easy way to find the difference in seconds between two
694.Vt bintime
695structures.
696This is most commonly used in conjunction with the time recorded by the
697.Fn devstat_getdevs
698function (in
699.Vt "struct statinfo" )
700each time it fetches the current
701.Nm
702list.
703.Sh RETURN VALUES
704The
705.Fn devstat_getnumdevs ,
706.Fn devstat_getgeneration ,
707and
708.Fn devstat_getversion
709function
710return the indicated sysctl variable, or \-1 if there is an error
711fetching the variable.
712.Pp
713The
714.Fn devstat_checkversion
715function
716returns 0 if the kernel and userland
717.Nm
718versions match.
719If they do not match, it returns \-1.
720.Pp
721The
722.Fn devstat_getdevs
723and
724.Fn devstat_selectdevs
725functions
726return \-1 in case of an error, 0 if there is no error, and 1 if the device
727list or selected devices have changed.
728A return value of 1 from
729.Fn devstat_getdevs
730is usually a hint to re-run
731.Fn devstat_selectdevs
732because the device list has changed.
733.Pp
734The
735.Fn devstat_buildmatch
736function returns \-1 for error, and 0 if there is no error.
737.Pp
738The
739.Fn devstat_compute_etime
740function
741returns the computed elapsed time.
742.Pp
743The
744.Fn devstat_compute_statistics
745function returns \-1 for error, and 0 for success.
746.Pp
747If an error is returned from one of the
748.Nm
749library functions, the reason for the error is generally printed in
750the global string
751.Va devstat_errbuf
752which is
753.Dv DEVSTAT_ERRBUF_SIZE
754characters long.
755.Sh SEE ALSO
756.Xr systat 1 ,
757.Xr kvm 3 ,
758.Xr sysctl 3 ,
759.Xr iostat 8 ,
760.Xr rpc.rstatd 8 ,
761.Xr sysctl 8 ,
762.Xr vmstat 8 ,
763.Xr devstat 9
764.Sh HISTORY
765The
766.Nm
767statistics system first appeared in
768.Fx 3.0 .
769The new interface (the functions prefixed with
770.Li devstat_ )
771first appeared in
772.Fx 5.0 .
773.Sh AUTHORS
774.An Kenneth Merry Aq ken@FreeBSD.org
775.Sh BUGS
776There should probably be an interface to de-allocate memory allocated by
777.Fn devstat_getdevs ,
778.Fn devstat_selectdevs ,
779and
780.Fn devstat_buildmatch .
781.Pp
782The
783.Fn devstat_selectdevs
784function
785should probably not select more than
786.Fa maxshowdevs
787devices in
788.Dq top
789mode when no devices have been selected previously.
790.Pp
791There should probably be functions to perform the statistics buffer
792swapping that goes on in most of the clients of this library.
793.Pp
794The
795.Vt statinfo
796and
797.Vt devinfo
798structures should probably be cleaned up and thought out a little more.
799