xref: /freebsd/lib/libdevstat/devstat.3 (revision 9f44a47fd07924afc035991af15d84e6585dea4f)
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 December 15, 2012
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	uint8_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 uint64_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 "uint64_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 "uint64_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 "uint64_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 "uint64_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_DURATION
530type:
531.Vt "long double *"
532.Pp
533The total duration of transactions, in seconds, between the acquisition of
534.Fa previous
535and
536.Fa current .
537.It Dv DSM_TOTAL_DURATION_OTHER
538.It Dv DSM_TOTAL_DURATION_READ
539.It Dv DSM_TOTAL_DURATION_WRITE
540.It Dv DSM_TOTAL_DURATION_FREE
541type:
542.Vt "long double *"
543.Pp
544The total duration of transactions of the specified type between
545the acquisition of
546.Fa previous
547and
548.Fa current .
549.It Dv DSM_TOTAL_BUSY_TIME
550type:
551.Vt "long double *"
552.Pp
553Total time the device had one or more transactions outstanding
554between the acquisition of
555.Fa previous
556and
557.Fa current .
558.It Dv DSM_TOTAL_BLOCKS
559type:
560.Vt "uint64_t *"
561.Pp
562The total number of blocks transferred between the acquisition of
563.Fa previous
564and
565.Fa current .
566This number is in terms of the blocksize reported by the device.
567If no blocksize has been reported (i.e., the block size is 0), a default
568blocksize of 512 bytes will be used in the calculation.
569.It Dv DSM_TOTAL_BLOCKS_READ
570.It Dv DSM_TOTAL_BLOCKS_WRITE
571.It Dv DSM_TOTAL_BLOCKS_FREE
572type:
573.Vt "uint64_t *"
574.Pp
575The total number of blocks of the specified type between the acquisition of
576.Fa previous
577and
578.Fa current .
579This number is in terms of the blocksize reported by the device.
580If no blocksize has been reported (i.e., the block size is 0), a default
581blocksize of 512 bytes will be used in the calculation.
582.It Dv DSM_KB_PER_TRANSFER
583type:
584.Vt "long double *"
585.Pp
586The average number of kilobytes per transfer between the acquisition of
587.Fa previous
588and
589.Fa current .
590.It Dv DSM_KB_PER_TRANSFER_READ
591.It Dv DSM_KB_PER_TRANSFER_WRITE
592.It Dv DSM_KB_PER_TRANSFER_FREE
593type:
594.Vt "long double *"
595.Pp
596The average number of kilobytes in the specified type transaction between
597the acquisition of
598.Fa previous
599and
600.Fa current .
601.It Dv DSM_TRANSFERS_PER_SECOND
602type:
603.Vt "long double *"
604.Pp
605The average number of transfers per second between the acquisition of
606.Fa previous
607and
608.Fa current .
609.It Dv DSM_TRANSFERS_PER_SECOND_OTHER
610.It Dv DSM_TRANSFERS_PER_SECOND_READ
611.It Dv DSM_TRANSFERS_PER_SECOND_WRITE
612.It Dv DSM_TRANSFERS_PER_SECOND_FREE
613type:
614.Vt "long double *"
615.Pp
616The average number of transactions of the specified type per second
617between the acquisition of
618.Fa previous
619and
620.Fa current .
621.It Dv DSM_MB_PER_SECOND
622type:
623.Vt "long double *"
624.Pp
625The average number of megabytes transferred per second between the
626acquisition of
627.Fa previous
628and
629.Fa current .
630.It Dv DSM_MB_PER_SECOND_READ
631.It Dv DSM_MB_PER_SECOND_WRITE
632.It Dv DSM_MB_PER_SECOND_FREE
633type:
634.Vt "long double *"
635.Pp
636The average number of megabytes per second in the specified type of
637transaction between the acquisition of
638.Fa previous
639and
640.Fa current .
641.It Dv DSM_BLOCKS_PER_SECOND
642type:
643.Vt "long double *"
644.Pp
645The average number of blocks transferred per second between the acquisition of
646.Fa previous
647and
648.Fa current .
649This number is in terms of the blocksize reported by the device.
650If no blocksize has been reported (i.e., the block size is 0), a default
651blocksize of 512 bytes will be used in the calculation.
652.It Dv DSM_BLOCKS_PER_SECOND_READ
653.It Dv DSM_BLOCKS_PER_SECOND_WRITE
654.It Dv DSM_BLOCKS_PER_SECOND_FREE
655type:
656.Vt "long double *"
657.Pp
658The average number of blocks per second in the specified type of transaction
659between the acquisition of
660.Fa previous
661and
662.Fa current .
663This number is in terms of the blocksize reported by the device.
664If no blocksize has been reported (i.e., the block size is 0), a default
665blocksize of 512 bytes will be used in the calculation.
666.It Dv DSM_MS_PER_TRANSACTION
667type:
668.Vt "long double *"
669.Pp
670The average duration of transactions between the acquisition of
671.Fa previous
672and
673.Fa current .
674.It Dv DSM_MS_PER_TRANSACTION_OTHER
675.It Dv DSM_MS_PER_TRANSACTION_READ
676.It Dv DSM_MS_PER_TRANSACTION_WRITE
677.It Dv DSM_MS_PER_TRANSACTION_FREE
678type:
679.Vt "long double *"
680.Pp
681The average duration of transactions of the specified type between the
682acquisition of
683.Fa previous
684and
685.Fa current .
686.It Dv DSM_BUSY_PCT
687type:
688.Vt "long double *"
689.Pp
690The percentage of time the device had one or more transactions outstanding
691between the acquisition of
692.Fa previous
693and
694.Fa current .
695.It Dv DSM_QUEUE_LENGTH
696type:
697.Vt "uint64_t *"
698.Pp
699The number of not yet completed transactions at the time when
700.Fa current
701was acquired.
702.It Dv DSM_SKIP
703type: N/A
704.Pp
705If you do not need a result from
706.Fn devstat_compute_statistics ,
707just put
708.Dv DSM_SKIP
709as first (type) parameter and
710.Dv NULL
711as second parameter.
712This can be useful in scenarios where the statistics to be calculated
713are determined at run time.
714.El
715.Pp
716The
717.Fn devstat_compute_etime
718function
719provides an easy way to find the difference in seconds between two
720.Vt bintime
721structures.
722This is most commonly used in conjunction with the time recorded by the
723.Fn devstat_getdevs
724function (in
725.Vt "struct statinfo" )
726each time it fetches the current
727.Nm
728list.
729.Sh RETURN VALUES
730The
731.Fn devstat_getnumdevs ,
732.Fn devstat_getgeneration ,
733and
734.Fn devstat_getversion
735function
736return the indicated sysctl variable, or \-1 if there is an error
737fetching the variable.
738.Pp
739The
740.Fn devstat_checkversion
741function
742returns 0 if the kernel and userland
743.Nm
744versions match.
745If they do not match, it returns \-1.
746.Pp
747The
748.Fn devstat_getdevs
749and
750.Fn devstat_selectdevs
751functions
752return \-1 in case of an error, 0 if there is no error, and 1 if the device
753list or selected devices have changed.
754A return value of 1 from
755.Fn devstat_getdevs
756is usually a hint to re-run
757.Fn devstat_selectdevs
758because the device list has changed.
759.Pp
760The
761.Fn devstat_buildmatch
762function returns \-1 for error, and 0 if there is no error.
763.Pp
764The
765.Fn devstat_compute_etime
766function
767returns the computed elapsed time.
768.Pp
769The
770.Fn devstat_compute_statistics
771function returns \-1 for error, and 0 for success.
772.Pp
773If an error is returned from one of the
774.Nm
775library functions, the reason for the error is generally printed in
776the global string
777.Va devstat_errbuf
778which is
779.Dv DEVSTAT_ERRBUF_SIZE
780characters long.
781.Sh SEE ALSO
782.Xr systat 1 ,
783.Xr kvm 3 ,
784.Xr sysctl 3 ,
785.Xr iostat 8 ,
786.Xr rpc.rstatd 8 ,
787.Xr sysctl 8 ,
788.Xr vmstat 8 ,
789.Xr devstat 9
790.Sh HISTORY
791The
792.Nm
793statistics system first appeared in
794.Fx 3.0 .
795The new interface (the functions prefixed with
796.Li devstat_ )
797first appeared in
798.Fx 5.0 .
799.Sh AUTHORS
800.An Kenneth Merry Aq Mt ken@FreeBSD.org
801.Sh BUGS
802There should probably be an interface to de-allocate memory allocated by
803.Fn devstat_getdevs ,
804.Fn devstat_selectdevs ,
805and
806.Fn devstat_buildmatch .
807.Pp
808The
809.Fn devstat_selectdevs
810function
811should probably not select more than
812.Fa maxshowdevs
813devices in
814.Dq top
815mode when no devices have been selected previously.
816.Pp
817There should probably be functions to perform the statistics buffer
818swapping that goes on in most of the clients of this library.
819.Pp
820The
821.Vt statinfo
822and
823.Vt devinfo
824structures should probably be cleaned up and thought out a little more.
825