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