xref: /freebsd-14.2/lib/libdevstat/devstat.3 (revision 8b7475ed)
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.Fn devstat_compute_etime "struct bintime cur_time" "struct bintime prev_time"
91.Sh DESCRIPTION
92The
93.Nm
94library is a library of helper functions for dealing with the kernel
95.Xr devstat 9
96interface, which is accessible to users via
97.Xr sysctl 3
98and
99.Xr kvm 3 .
100All functions that take a
101.Vt "kvm_t *"
102as first argument can be passed
103.Dv NULL
104instead of a kvm handle as this argument,
105which causes the data to be read via
106.Xr sysctl 3 .
107Otherwise, it is read via
108.Xr kvm 3
109using the supplied handle.
110The
111.Fn devstat_checkversion
112function
113should be called with each kvm handle that is going to be used (or with
114.Dv NULL
115if
116.Xr sysctl 3
117is going to be used).
118.Pp
119The
120.Fn devstat_getnumdevs
121function
122returns the number of devices registered with the
123.Nm
124subsystem in the kernel.
125.Pp
126The
127.Fn devstat_getgeneration
128function
129returns the current generation of the
130.Nm
131list of devices in the kernel.
132.Pp
133The
134.Fn devstat_getversion
135function
136returns the current kernel
137.Nm
138version.
139.Pp
140The
141.Fn devstat_checkversion
142function
143checks the userland
144.Nm
145version against the kernel
146.Nm
147version.
148If the two are identical, it returns zero.
149Otherwise, it prints an appropriate error in
150.Va devstat_errbuf
151and returns \-1.
152.Pp
153The
154.Fn devstat_getdevs
155function
156fetches the current list of devices and statistics into the supplied
157.Vt statinfo
158structure.
159The
160.Vt statinfo
161structure can be found in
162.In devstat.h :
163.Bd -literal -offset indent
164struct statinfo {
165	long            cp_time[CPUSTATES];
166	long            tk_nin;
167	long            tk_nout;
168	struct devinfo  *dinfo;
169	long double     snap_time;
170};
171.Ed
172.Pp
173The
174.Fn devstat_getdevs
175function
176expects the
177.Vt statinfo
178structure to be allocated, and it also expects the
179.Va dinfo
180subelement to be allocated and zeroed prior to the first invocation of
181.Fn devstat_getdevs .
182The
183.Va dinfo
184subelement is used to store state between calls, and should not be modified
185after the first call to
186.Fn devstat_getdevs .
187The
188.Va dinfo
189subelement contains the following elements:
190.Bd -literal -offset indent
191struct devinfo {
192	struct devstat	*devices;
193	u_int8_t	*mem_ptr;
194	long		generation;
195	int		numdevs;
196};
197.Ed
198.Pp
199The
200.Va kern.devstat.all
201.Xr sysctl 8
202variable contains an array of
203.Nm
204structures, but at the head of the array is the current
205.Nm
206generation.
207The reason the generation is at the head of the buffer is so that userland
208software accessing the
209.Nm
210statistics information can atomically get
211both the statistics information and the corresponding generation number.
212If client software were forced to get the generation number via a separate
213.Xr sysctl 8
214variable (which is available for convenience), the list of devices could
215change between the time the client gets the generation and the time the
216client gets the device list.
217.Pp
218The
219.Va mem_ptr
220subelement of the
221.Vt devinfo
222structure is a pointer to memory that is allocated, and resized if
223necessary, by
224.Fn devstat_getdevs .
225The devices subelement of the
226.Vt devinfo
227structure is basically a pointer to the beginning of the array of devstat
228structures from the
229.Va kern.devstat.all
230.Xr sysctl 8
231variable (or the corresponding values read via
232.Xr kvm 3 ) .
233The generation subelement of the
234.Vt devinfo
235structure contains the corresponding generation number.
236The
237.Va numdevs
238subelement of the
239.Vt devinfo
240structure contains the current
241number of devices registered with the kernel
242.Nm
243subsystem.
244.Pp
245The
246.Fn devstat_selectdevs
247function
248selects devices to display based upon a number of criteria:
249.Bl -tag -width indent
250.It specified devices
251Specified devices are the first selection priority.
252These are generally devices specified by name by the user e.g.\&
253.Li da0 , da1 , cd0 .
254.It match patterns
255These are pattern matching expressions generated by
256.Fn devstat_buildmatch
257from user input.
258.It performance
259If performance mode is enabled, devices will be sorted based on the
260.Va bytes
261field in the
262.Vt device_selection
263structure passed in to
264.Fn devstat_selectdevs .
265The
266.Va bytes
267value currently must be maintained by the user.
268In the future, this may be done for him in a
269.Nm
270library routine.
271If no devices have been selected by name or by pattern, the performance
272tracking code will select every device in the system, and sort them by
273performance.
274If devices have been selected by name or pattern, the performance tracking
275code will honor those selections and will only sort among the selected
276devices.
277.It order in the devstat list
278If the selection mode is set to
279.Dv DS_SELECT_ADD ,
280and if there are still less
281than
282.Fa maxshowdevs
283devices selected,
284.Fn devstat_selectdevs
285will automatically select up to
286.Fa maxshowdevs
287devices.
288.El
289.Pp
290The
291.Fn devstat_selectdevs
292function
293performs selections in four different modes:
294.Bl -tag -width ".Dv DS_SELECT_ADDONLY"
295.It Dv DS_SELECT_ADD
296In
297.Dq add
298mode,
299.Fn devstat_selectdevs
300will select any unselected devices specified by name or matching pattern.
301It will also select more devices, in devstat list order, until the number
302of selected devices is equal to
303.Fa maxshowdevs
304or until all devices are
305selected.
306.It Dv DS_SELECT_ONLY
307In
308.Dq only
309mode,
310.Fn devstat_selectdevs
311will clear all current selections, and will only select devices specified
312by name or by matching pattern.
313.It Dv DS_SELECT_REMOVE
314In
315.Dq remove
316mode,
317.Fn devstat_selectdevs
318will remove devices specified by name or by matching pattern.
319It will not select any additional devices.
320.It Dv DS_SELECT_ADDONLY
321In
322.Dq "add only"
323mode,
324.Fn devstat_selectdevs
325will select any unselected devices specified by name or matching pattern.
326In this respect it is identical to
327.Dq add
328mode.
329It will not, however, select any devices other than those specified.
330.El
331.Pp
332In all selection modes,
333.Fn devstat_selectdevs
334will not select any more than
335.Fa maxshowdevs
336devices.
337One exception to this is when you are in
338.Dq top
339mode and no devices have been selected.
340In this case,
341.Fn devstat_selectdevs
342will select every device in the system.
343Client programs must pay attention to selection order when deciding whether
344to pay attention to a particular device.
345This may be the wrong behavior, and probably requires additional thought.
346.Pp
347The
348.Fn devstat_selectdevs
349function
350handles allocation and resizing of the
351.Fa dev_select
352structure passed in
353by the client.
354The
355.Fn devstat_selectdevs
356function
357uses the
358.Fa numdevs
359and
360.Fa current_generation
361fields to track the
362current
363.Nm
364generation and number of devices.
365If
366.Fa num_selections
367is not the same
368as
369.Fa numdevs
370or if
371.Fa select_generation
372is not the same as
373.Fa current_generation ,
374.Fn devstat_selectdevs
375will resize the selection list as necessary, and re-initialize the
376selection array.
377.Pp
378The
379.Fn devstat_buildmatch
380function
381takes a comma separated match string and compiles it into a
382.Vt devstat_match
383structure that is understood by
384.Fn devstat_selectdevs .
385Match strings have the following format:
386.Pp
387.D1 Ar device , Ns Ar type , Ns Ar if
388.Pp
389The
390.Fn devstat_buildmatch
391function
392takes care of allocating and reallocating the match list as necessary.
393Currently known match types include:
394.Bl -tag -width indent
395.It device type:
396.Bl -tag -width ".Li enclosure" -compact
397.It Li da
398Direct Access devices
399.It Li sa
400Sequential Access devices
401.It Li printer
402Printers
403.It Li proc
404Processor devices
405.It Li worm
406Write Once Read Multiple devices
407.It Li cd
408CD devices
409.It Li scanner
410Scanner devices
411.It Li optical
412Optical Memory devices
413.It Li changer
414Medium Changer devices
415.It Li comm
416Communication devices
417.It Li array
418Storage Array devices
419.It Li enclosure
420Enclosure Services devices
421.It Li floppy
422Floppy devices
423.El
424.It interface:
425.Bl -tag -width ".Li enclosure" -compact
426.It Li IDE
427Integrated Drive Electronics devices
428.It Li SCSI
429Small Computer System Interface devices
430.It Li other
431Any other device interface
432.El
433.It passthrough:
434.Bl -tag -width ".Li enclosure" -compact
435.It Li pass
436Passthrough devices
437.El
438.El
439.Pp
440The
441.Fn devstat_compute_statistics
442function
443is an updated version of
444.Fn compute_stats
445that provides more 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
687.Fn devstat_compute_etime
688provides an easy way to find the difference in seconds between two
689.Vt bintime
690structures.
691This is most commonly used in conjunction with the time recorded by the
692.Fn devstat_getdevs
693function (in
694.Vt "struct statinfo" )
695each time it fetches the current
696.Nm
697list.
698.Sh RETURN VALUES
699The
700.Fn devstat_getnumdevs ,
701.Fn devstat_getgeneration ,
702and
703.Fn devstat_getversion
704function
705return the indicated sysctl variable, or \-1 if there is an error
706fetching the variable.
707.Pp
708The
709.Fn devstat_checkversion
710function
711returns 0 if the kernel and userland
712.Nm
713versions match.
714If they do not match, it returns \-1.
715.Pp
716The
717.Fn devstat_getdevs
718and
719.Fn devstat_selectdevs
720functions
721return \-1 in case of an error, 0 if there is no error, and 1 if the device
722list or selected devices have changed.
723A return value of 1 from
724.Fn devstat_getdevs
725is usually a hint to re-run
726.Fn devstat_selectdevs
727because the device list has changed.
728.Pp
729The
730.Fn devstat_buildmatch
731function returns \-1 for error, and 0 if there is no error.
732.Pp
733The
734.Fn devstat_compute_etime
735function
736returns the computed elapsed time.
737.Pp
738The
739.Fn devstat_compute_statistics
740function returns \-1 for error, and 0 for success.
741.Pp
742If an error is returned from one of the
743.Nm
744library functions, the reason for the error is generally printed in
745the global string
746.Va devstat_errbuf
747which is
748.Dv DEVSTAT_ERRBUF_SIZE
749characters long.
750.Sh SEE ALSO
751.Xr systat 1 ,
752.Xr kvm 3 ,
753.Xr sysctl 3 ,
754.Xr iostat 8 ,
755.Xr rpc.rstatd 8 ,
756.Xr sysctl 8 ,
757.Xr vmstat 8 ,
758.Xr devstat 9
759.Sh HISTORY
760The
761.Nm
762statistics system first appeared in
763.Fx 3.0 .
764The new interface (the functions prefixed with
765.Li devstat_ )
766first appeared in
767.Fx 5.0 .
768.Sh AUTHORS
769.An Kenneth Merry Aq [email protected]
770.Sh BUGS
771There should probably be an interface to de-allocate memory allocated by
772.Fn devstat_getdevs ,
773.Fn devstat_selectdevs ,
774and
775.Fn devstat_buildmatch .
776.Pp
777The
778.Fn devstat_selectdevs
779function
780should probably not select more than
781.Fa maxshowdevs
782devices in
783.Dq top
784mode when no devices have been selected previously.
785.Pp
786There should probably be functions to perform the statistics buffer
787swapping that goes on in most of the clients of this library.
788.Pp
789The
790.Vt statinfo
791and
792.Vt devinfo
793structures should probably be cleaned up and thought out a little more.
794