mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-11 20:58:50 +03:00
dmstats: add libdm-stats library and 'dmsetup stats' command
Add the libdm-stats module to libdm. This implements a simple interface for creating, managing and interrogating I/O statistics regions and areas on device-mapper devices. The library interface is documented in libdevmapper.h and provides a 'dm_stats' handle that is used to perform statistics operations and obtain data. Methods are provided to return baisc count values and to derive time-based metrics when a suitable interval estimate is provided. The dm_stats handle contains a pointer to a table of one or more dm_stats_region objects representing the regions registered with the @stats_create message. These in turn point to a table of one or more dm_stats_counters objects containing the counter sets for each defined area within the region: dm_stats->dm_stats_region[nr_regions]->dm_stats_counters[nr_areas] This structure is private to the library and may change in future versions: all users should make use of the public interface and treat the dm_stats type as an opaque handle. Regions and counter sets are stored in order of increasing region_id. Public methods are provided to create and destroy handles and to list, create, and destroy, statistics regions as well as to obtain and parse the actual counter data. Linux iostat-style derived performance metrics are provided to return higher-level performance metrics. This commit also adds arguments, report types, and a 'stats' command to dmsetup and implements 'clear', 'create', 'delete', 'list', 'print', and 'report' sub-commands. The dmsetup _display_info_cols() function is adapted to allow reporting of statistics with the DR_STATS report type: since a single object (device) may have many rows of statistics to report the call to dm_report_object() is placed inside a loop over each statistics area present (for non-stats reports or for devices with a single region spanning the entire device the body of the loop will be executed exactly once).
This commit is contained in:
parent
f06d866110
commit
dfb4560e24
11
WHATS_NEW_DM
11
WHATS_NEW_DM
@ -1,5 +1,16 @@
|
||||
Version 1.02.104 -
|
||||
=================================
|
||||
Add dmstats.8 man page
|
||||
Add report stats sub-command to provide repeating stats reports.
|
||||
Add clear, delete, list, and print stats sub-commands.
|
||||
Add create stats sub-command and --start, --length, --areas and --areasize.
|
||||
Add a 'stats' command to dmsetup to configure, manage and report stats data.
|
||||
Add --regionid, --allregions to specify a single stats region or all regions.
|
||||
Add --allprograms for stats commands that filter by program ID.
|
||||
Add --auxdata and --programid arguments to set stats aux data and program ID.
|
||||
Add statistics fields to -o <field>
|
||||
Add libdm-stats library to allow management of device-mapper statistics.
|
||||
Add --units to control report field output units.
|
||||
Add support to redisplay column headings for repeating column reports.
|
||||
Fix report header and row resource leaks.
|
||||
Report timestamps of ioctls with dmsetup -vvv.
|
||||
|
@ -1,5 +1,73 @@
|
||||
dm_report_column_headings
|
||||
dm_size_to_string
|
||||
dm_stats_bind_devno
|
||||
dm_stats_bind_name
|
||||
dm_stats_bind_uuid
|
||||
dm_stats_buffer_destroy
|
||||
dm_stats_clear_region
|
||||
dm_stats_create
|
||||
dm_stats_create_region
|
||||
dm_stats_delete_region
|
||||
dm_stats_destroy
|
||||
dm_stats_get_area_start
|
||||
dm_stats_get_average_queue_size
|
||||
dm_stats_get_average_rd_wait_time
|
||||
dm_stats_get_average_request_size
|
||||
dm_stats_get_average_wait_time
|
||||
dm_stats_get_average_wr_wait_time
|
||||
dm_stats_get_current_area
|
||||
dm_stats_get_current_area_len
|
||||
dm_stats_get_current_area_start
|
||||
dm_stats_get_current_nr_areas
|
||||
dm_stats_get_current_region
|
||||
dm_stats_get_current_region_area_len
|
||||
dm_stats_get_current_region_aux_data
|
||||
dm_stats_get_current_region_len
|
||||
dm_stats_get_current_region_program_id
|
||||
dm_stats_get_current_region_start
|
||||
dm_stats_get_io_in_progress
|
||||
dm_stats_get_io_nsecs
|
||||
dm_stats_get_nr_areas
|
||||
dm_stats_get_nr_regions
|
||||
dm_stats_get_rd_merges_per_sec
|
||||
dm_stats_get_read_nsecs
|
||||
dm_stats_get_reads
|
||||
dm_stats_get_read_sectors
|
||||
dm_stats_get_read_sectors_per_sec
|
||||
dm_stats_get_reads_merged
|
||||
dm_stats_get_reads_per_sec
|
||||
dm_stats_get_region_area_len
|
||||
dm_stats_get_region_aux_data
|
||||
dm_stats_get_region_len
|
||||
dm_stats_get_region_nr_areas
|
||||
dm_stats_get_region_program_id
|
||||
dm_stats_get_region_start
|
||||
dm_stats_get_sampling_interval_ms
|
||||
dm_stats_get_sampling_interval_ns
|
||||
dm_stats_get_service_time
|
||||
dm_stats_get_throughput
|
||||
dm_stats_get_total_read_nsecs
|
||||
dm_stats_get_total_write_nsecs
|
||||
dm_stats_get_utilization
|
||||
dm_stats_get_weighted_io_nsecs
|
||||
dm_stats_get_write_nsecs
|
||||
dm_stats_get_writes
|
||||
dm_stats_get_write_sectors
|
||||
dm_stats_get_write_sectors_per_sec
|
||||
dm_stats_get_writes_merged
|
||||
dm_stats_get_writes_per_sec
|
||||
dm_stats_get_wr_merges_per_sec
|
||||
dm_stats_list
|
||||
dm_stats_populate
|
||||
dm_stats_print_region
|
||||
dm_stats_region_present
|
||||
dm_stats_set_program_id
|
||||
dm_stats_set_sampling_interval_ms
|
||||
dm_stats_set_sampling_interval_ns
|
||||
dm_stats_walk_end
|
||||
dm_stats_walk_next
|
||||
dm_stats_walk_next_region
|
||||
dm_stats_walk_start
|
||||
dm_task_get_ioctl_timestamp
|
||||
dm_task_set_record_timestamp
|
||||
dm_timestamp_alloc
|
||||
|
@ -26,6 +26,7 @@ SOURCES =\
|
||||
libdm-string.c \
|
||||
libdm-report.c \
|
||||
libdm-timestamp.c \
|
||||
libdm-stats.c \
|
||||
libdm-config.c \
|
||||
mm/dbg_malloc.c \
|
||||
mm/pool.c \
|
||||
|
@ -395,6 +395,465 @@ struct dm_status_thin {
|
||||
int dm_get_status_thin(struct dm_pool *mem, const char *params,
|
||||
struct dm_status_thin **status);
|
||||
|
||||
/*
|
||||
* device-mapper statistics support
|
||||
*/
|
||||
|
||||
/*
|
||||
* Statistics handle.
|
||||
*
|
||||
* Operations on dm_stats objects include managing statistics regions
|
||||
* and obtaining and manipulating current counter values from the
|
||||
* kernel.
|
||||
*/
|
||||
struct dm_stats;
|
||||
|
||||
/*
|
||||
* Allocate a dm_stats handle to use for subsequent device-mapper
|
||||
* statistics operations. A program_id may be specified and will be
|
||||
* used by default for subsequent operations on this handle.
|
||||
*
|
||||
* If program_id is NULL or the empty string a program_id will be
|
||||
* automatically set to the value contained in /proc/self/comm.
|
||||
*/
|
||||
struct dm_stats *dm_stats_create(const char *program_id);
|
||||
|
||||
/*
|
||||
* Bind a dm_stats handle to the specified device major and minor
|
||||
* values. Any previous binding is cleared and any preexisting counter
|
||||
* data contained in the handle is released.
|
||||
*/
|
||||
int dm_stats_bind_devno(struct dm_stats *dms, int major, int minor);
|
||||
|
||||
/*
|
||||
* Bind a dm_stats handle to the specified device name.
|
||||
* Any previous binding is cleared and any preexisting counter
|
||||
* data contained in the handle is released.
|
||||
*/
|
||||
int dm_stats_bind_name(struct dm_stats *dms, const char *name);
|
||||
|
||||
/*
|
||||
* Bind a dm_stats handle to the specified device UUID.
|
||||
* Any previous binding is cleared and any preexisting counter
|
||||
* data contained in the handle is released.
|
||||
*/
|
||||
int dm_stats_bind_uuid(struct dm_stats *dms, const char *uuid);
|
||||
|
||||
#define DM_STATS_ALL_PROGRAMS ""
|
||||
/*
|
||||
* Parse the response from a @stats_list message. dm_stats_list will
|
||||
* allocate the necessary dm_stats and dm_stats region structures from
|
||||
* the embedded dm_pool. No counter data will be obtained (the counters
|
||||
* members of dm_stats_region objects are set to NULL).
|
||||
*
|
||||
* A program_id may optionally be supplied; if the argument is non-NULL
|
||||
* only regions with a matching program_id value will be considered. If
|
||||
* the argument is NULL then the default program_id associated with the
|
||||
* dm_stats handle will be used. Passing the special value
|
||||
* DM_STATS_ALL_PROGRAMS will cause all regions to be queried
|
||||
* regardless of region program_id.
|
||||
*/
|
||||
int dm_stats_list(struct dm_stats *dms, const char *program_id);
|
||||
|
||||
#define DM_STATS_REGIONS_ALL UINT64_MAX
|
||||
/*
|
||||
* Populate a dm_stats object with statistics for one or more regions of
|
||||
* the specified device.
|
||||
*
|
||||
* A program_id may optionally be supplied; if the argument is non-NULL
|
||||
* only regions with a matching program_id value will be considered. If
|
||||
* the argument is NULL then the default program_id associated with the
|
||||
* dm_stats handle will be used. Passing the special value
|
||||
* DM_STATS_ALL_PROGRAMS will cause all regions to be queried
|
||||
* regardless of region program_id.
|
||||
*
|
||||
* Passing the special value DM_STATS_REGIONS_ALL as the region_id
|
||||
* argument will attempt to retrieve all regions selected by the
|
||||
* program_id argument.
|
||||
*
|
||||
* If region_id is used to request a single region_id to be populated
|
||||
* the program_id is ignored.
|
||||
*/
|
||||
int dm_stats_populate(struct dm_stats *dms, const char *program_id,
|
||||
uint64_t region_id);
|
||||
|
||||
/*
|
||||
* Create a new statistics region on the device bound to dms.
|
||||
*
|
||||
* start and len specify the region start and length in 512b sectors.
|
||||
* Passing zero for both start and len will create a region spanning
|
||||
* the entire device.
|
||||
*
|
||||
* Step determines how to subdivide the region into discrete counter
|
||||
* sets: a positive value specifies the size of areas into which the
|
||||
* region should be split while a negative value will split the region
|
||||
* into a number of areas equal to the absolute value of step:
|
||||
*
|
||||
* - a region with one area spanning the entire device:
|
||||
*
|
||||
* dm_stats_create_region(dms, 0, 0, -1, p, a);
|
||||
*
|
||||
* - a region with areas of 1MiB:
|
||||
*
|
||||
* dm_stats_create_region(dms, 0, 0, 1 << 11, p, a);
|
||||
*
|
||||
* - one 1MiB region starting at 1024 sectors with two areas:
|
||||
*
|
||||
* dm_stats_create_region(dms, 1024, 1 << 11, -2, p, a);
|
||||
*
|
||||
* program_id is an optional string argument that identifies the
|
||||
* program creating the region. If program_id is NULL or the empty
|
||||
* string the default program_id stored in the handle will be used.
|
||||
*
|
||||
* aux_data is an optional string argument passed to the kernel that is
|
||||
* stored with the statistics region. It is not currently accessed by
|
||||
* the library or kernel and may be used to store arbitrary user data.
|
||||
*
|
||||
* The region_id of the newly-created region is returned in *region_id
|
||||
* if it is non-NULL.
|
||||
*/
|
||||
int dm_stats_create_region(struct dm_stats *dms, uint64_t *region_id,
|
||||
uint64_t start, uint64_t len, int64_t step,
|
||||
const char *program_id, const char *aux_data);
|
||||
|
||||
/*
|
||||
* Delete the specified statistics region. This will also mark the
|
||||
* region as not-present and discard any existing statistics data.
|
||||
*/
|
||||
int dm_stats_delete_region(struct dm_stats *dms, uint64_t region_id);
|
||||
|
||||
/*
|
||||
* Clear the specified statistics region. This requests the kernel to
|
||||
* zero all counter values (except in-flight I/O). Note that this
|
||||
* operation is not atomic with respect to reads of the counters; any IO
|
||||
* events occurring between the last print operation and the clear will
|
||||
* be lost. This can be avoided by using the atomic print-and-clear
|
||||
* function of the dm_stats_print_region() call or by using the higher
|
||||
* level dm_stats_populate() interface.
|
||||
*/
|
||||
int dm_stats_clear_region(struct dm_stats *dms, uint64_t region_id);
|
||||
|
||||
/*
|
||||
* Print the current counter values for the specified statistics region
|
||||
* and return them as a string. The memory for the string buffer will
|
||||
* be allocated from the dm_stats handle's private pool and should be
|
||||
* returned by calling dm_stats_buffer_destroy() when no longer
|
||||
* required. The pointer will become invalid following any call that
|
||||
* clears or reinitializes the handle (destroy, list, populate, bind).
|
||||
*
|
||||
* This allows applications that wish to access the raw message response
|
||||
* to obtain it via a dm_stats handle; no parsing of the textual counter
|
||||
* data is carried out by this function.
|
||||
*
|
||||
* Most users are recommended to use the dm_stats_populate() call
|
||||
* instead since this will automatically parse the statistics data into
|
||||
* numeric form accessible via the dm_stats_get_*() counter access
|
||||
* methods.
|
||||
*
|
||||
* A subset of the data lines may be requested by setting the
|
||||
* start_line and num_lines parameters. If both are zero all data
|
||||
* lines are returned.
|
||||
*
|
||||
* If the clear parameter is non-zero the operation will also
|
||||
* atomically reset all counter values to zero (except in-flight IO).
|
||||
*/
|
||||
char *dm_stats_print_region(struct dm_stats *dms, uint64_t region_id,
|
||||
unsigned start_line, unsigned num_lines,
|
||||
unsigned clear);
|
||||
|
||||
/*
|
||||
* Destroy a statistics response buffer obtained from a call to
|
||||
* dm_stats_print_region().
|
||||
*/
|
||||
void dm_stats_buffer_destroy(struct dm_stats *dms, char *buffer);
|
||||
|
||||
/*
|
||||
* Determine the number of regions contained in a dm_stats handle
|
||||
* following a dm_stats_list() or dm_stats_populate() call.
|
||||
*
|
||||
* The value returned is the number of registered regions visible with the
|
||||
* progam_id value used for the list or populate operation and may not be
|
||||
* equal to the highest present region_id (either due to program_id
|
||||
* filtering or gaps in the sequence of region_id values).
|
||||
*
|
||||
* Always returns zero on an empty handle.
|
||||
*/
|
||||
uint64_t dm_stats_get_nr_regions(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Test whether region_id is present in this dm_stats handle.
|
||||
*/
|
||||
int dm_stats_region_present(struct dm_stats *dms, uint64_t region_id);
|
||||
|
||||
/*
|
||||
* Returns the number of areas (counter sets) contained in the specified
|
||||
* region_id of the supplied dm_stats handle.
|
||||
*/
|
||||
uint64_t dm_stats_get_region_nr_areas(struct dm_stats *dms, uint64_t region_id);
|
||||
|
||||
/*
|
||||
* Returns the total number of areas (counter sets) in all regions of the
|
||||
* given dm_stats object.
|
||||
*/
|
||||
uint64_t dm_stats_get_nr_areas(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Destroy a dm_stats object and all associated regions and counter
|
||||
* sets.
|
||||
*/
|
||||
void dm_stats_destroy(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Counter sampling interval
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set the sampling interval for counter data to the specified value in
|
||||
* either nanoseconds or milliseconds.
|
||||
*
|
||||
* The interval is used to calculate time-based metrics from the basic
|
||||
* counter data: an interval must be set before calling any of the
|
||||
* metric methods.
|
||||
*
|
||||
* For best accuracy the duration should be measured and updated at the
|
||||
* end of each interval.
|
||||
*
|
||||
* All values are stored internally with nanosecond precision and are
|
||||
* converted to or from ms when the millisecond interfaces are used.
|
||||
*/
|
||||
void dm_stats_set_sampling_interval_ns(struct dm_stats *dms, uint64_t interval_ns);
|
||||
void dm_stats_set_sampling_interval_ms(struct dm_stats *dms, uint64_t interval_ms);
|
||||
|
||||
/*
|
||||
* Retrieve the configured sampling interval in either nanoseconds or
|
||||
* milliseconds.
|
||||
*/
|
||||
uint64_t dm_stats_get_sampling_interval_ns(struct dm_stats *dms);
|
||||
uint64_t dm_stats_get_sampling_interval_ms(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Override program_id. This may be used to change the default
|
||||
* program_id value for an existing handle. If the allow_empty argument
|
||||
* is non-zero a NULL or empty program_id is permitted.
|
||||
*
|
||||
* Use with caution! Most users of the library should set a valid,
|
||||
* non-NULL program_id for every statistics region created. Failing to
|
||||
* do so may result in confusing state when multiple programs are
|
||||
* creating and managing statistics regions.
|
||||
*
|
||||
* All users of the library are encouraged to choose an unambiguous,
|
||||
* unique program_id: this could be based on PID (for programs that
|
||||
* create, report, and delete regions in a single process), session id,
|
||||
* executable name, or some other distinguishing string.
|
||||
*
|
||||
* Use of the empty string as a program_id does not simplify use of the
|
||||
* library or the command line tools and use of this value is strongly
|
||||
* discouraged.
|
||||
*/
|
||||
int dm_stats_set_program_id(struct dm_stats *dms, int allow_empty,
|
||||
const char *program_id);
|
||||
|
||||
/*
|
||||
* Region properties: size, length & area_len.
|
||||
*
|
||||
* Region start and length are returned in units of 512b as specified
|
||||
* at region creation time. The area_len value gives the size of areas
|
||||
* into which the region has been subdivided. For regions with a single
|
||||
* area spanning the range this value is equal to the region length.
|
||||
*
|
||||
* For regions created with a specified number of areas the value
|
||||
* represents the size of the areas into which the kernel divided the
|
||||
* region excluding any rounding of the last area size. The number of
|
||||
* areas may be obtained using the dm_stats_nr_areas_region() call.
|
||||
*
|
||||
* All values are returned in units of 512b sectors.
|
||||
*/
|
||||
uint64_t dm_stats_get_region_start(struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id);
|
||||
uint64_t dm_stats_get_region_len(struct dm_stats *dms, uint64_t *len,
|
||||
uint64_t region_id);
|
||||
uint64_t dm_stats_get_region_area_len(struct dm_stats *dms, uint64_t *area_len,
|
||||
uint64_t region_id);
|
||||
|
||||
/*
|
||||
* Area properties: start and length.
|
||||
*
|
||||
* The area length is always equal to the area length of the region
|
||||
* that contains it and is obtained from dm_stats_get_region_area_len().
|
||||
*
|
||||
* The start offset of an area is a function of the area_id and the
|
||||
* containing region's start and area length.
|
||||
*
|
||||
* All values are returned in units of 512b sectors.
|
||||
*/
|
||||
uint64_t dm_stats_get_area_start(struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
/*
|
||||
* Retrieve program_id and aux_data for a specific region. Only valid
|
||||
* following a call to dm_stats_list(). The returned pointer does not
|
||||
* need to be freed separately from the dm_stats handle but will become
|
||||
* invalid after a dm_stats_destroy(), dm_stats_list(),
|
||||
* dm_stats_populate(), or dm_stats_bind*() of the handle from which it
|
||||
* was obtained.
|
||||
*/
|
||||
const char *dm_stats_get_region_program_id(struct dm_stats *dms,
|
||||
uint64_t region_id);
|
||||
|
||||
const char *dm_stats_get_region_aux_data(struct dm_stats *dms,
|
||||
uint64_t region_id);
|
||||
|
||||
/*
|
||||
* Statistics cursor
|
||||
*
|
||||
* A dm_stats handle maintains an optional cursor into the statistics
|
||||
* regions and areas that it stores. Iterators are provided to visit
|
||||
* each region, or each area in a handle and accessor methods are
|
||||
* provided to obtain properties and values for the region or area
|
||||
* at the current cursor position.
|
||||
*
|
||||
* Using the cursor simplifies walking all regions or areas when the
|
||||
* region table is sparse (i.e. contains some present and some
|
||||
* non-present region_id values either due to program_id filtering
|
||||
* or the ordering of region creation and deletion).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialise the cursor of a dm_stats handle to address the first
|
||||
* present region. It is valid to attempt to walk a NULL stats handle
|
||||
* or a handle containing no present regions; in this case any call to
|
||||
* dm_stats_walk_next() becomes a no-op and all calls to
|
||||
* dm_stats_walk_end() return true.
|
||||
*/
|
||||
void dm_stats_walk_start(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Advance the statistics cursor to the next area, or to the next
|
||||
* present region if at the end of the current region.
|
||||
*/
|
||||
void dm_stats_walk_next(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Advance the statistics cursor to the next region.
|
||||
*/
|
||||
void dm_stats_walk_next_region(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Test whether the end of a statistics walk has been reached.
|
||||
*/
|
||||
int dm_stats_walk_end(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Stats iterators
|
||||
*
|
||||
* C 'for' and 'do'/'while' style iterators for dm_stats data.
|
||||
*
|
||||
* It is not safe to call any function that modifies the region table
|
||||
* within the loop body (i.e. dm_stats_list(), dm_stats_populate(),
|
||||
* dm_stats_init(), or dm_stats_destroy()).
|
||||
*
|
||||
* All counter and property (dm_stats_get_*) access methods, as well as
|
||||
* dm_stats_populate_region() can be safely called from loops.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Iterate over the regions table visiting each region.
|
||||
*
|
||||
* If the region table is empty or unpopulated the loop body will not be
|
||||
* executed.
|
||||
*/
|
||||
#define dm_stats_foreach_region(dms) \
|
||||
for (dm_stats_walk_start((dms)); \
|
||||
!dm_stats_walk_end((dms)); dm_stats_walk_next_region((dms)))
|
||||
|
||||
/*
|
||||
* Iterate over the regions table visiting each area.
|
||||
*
|
||||
* If the region table is empty or unpopulated the loop body will not
|
||||
* be executed.
|
||||
*/
|
||||
#define dm_stats_foreach_area(dms) \
|
||||
for (dm_stats_walk_start((dms)); \
|
||||
!dm_stats_walk_end((dms)); dm_stats_walk_next((dms)))
|
||||
|
||||
/*
|
||||
* Start a walk iterating over the regions contained in dm_stats handle
|
||||
* 'dms'.
|
||||
*
|
||||
* The body of the loop should call dm_stats_walk_next() or
|
||||
* dm_stats_walk_next_region() to advance to the next element.
|
||||
*
|
||||
* The loop body is executed at least once even if the stats handle is
|
||||
* empty.
|
||||
*/
|
||||
#define dm_stats_walk_do(dms) \
|
||||
dm_stats_walk_start((dms)); \
|
||||
do
|
||||
|
||||
/*
|
||||
* End a loop iterating over the regions contained in dm_stats handle
|
||||
* 'dms'.
|
||||
*/
|
||||
#define dm_stats_walk_while(dms) \
|
||||
while(!dm_stats_walk_end((dms)))
|
||||
|
||||
/*
|
||||
* Cursor relative property methods
|
||||
*
|
||||
* Calls with the prefix dm_stats_get_current_* operate relative to the
|
||||
* current cursor location, returning properties for the current region
|
||||
* or area of the supplied dm_stats handle.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns the number of areas (counter sets) contained in the current
|
||||
* region of the supplied dm_stats handle.
|
||||
*/
|
||||
uint64_t dm_stats_get_current_nr_areas(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Retrieve the current values of the stats cursor.
|
||||
*/
|
||||
uint64_t dm_stats_get_current_region(struct dm_stats *dms);
|
||||
uint64_t dm_stats_get_current_area(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Current region properties: size, length & area_len.
|
||||
*
|
||||
* See the comments for the equivalent dm_stats_get_* versions for a
|
||||
* complete description of these methods.
|
||||
*
|
||||
* All values are returned in units of 512b sectors.
|
||||
*/
|
||||
uint64_t dm_stats_get_current_region_start(struct dm_stats *dms, uint64_t *start);
|
||||
uint64_t dm_stats_get_current_region_len(struct dm_stats *dms, uint64_t *len);
|
||||
uint64_t dm_stats_get_current_region_area_len(struct dm_stats *dms, uint64_t *area_len);
|
||||
|
||||
/*
|
||||
* Current area properties: start and length.
|
||||
*
|
||||
* See the comments for the equivalent dm_stats_get_* versions for a
|
||||
* complete description of these methods.
|
||||
*
|
||||
* All values are returned in units of 512b sectors.
|
||||
*/
|
||||
uint64_t dm_stats_get_current_area_start(struct dm_stats *dms, uint64_t *start);
|
||||
uint64_t dm_stats_get_current_area_len(struct dm_stats *dms, uint64_t *start);
|
||||
|
||||
/*
|
||||
* Return a pointer to the program_id string for region at the current
|
||||
* cursor location.
|
||||
*/
|
||||
const char *dm_stats_get_current_region_program_id(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Return a pointer to the aux_data string for the region at the current
|
||||
* cursor location.
|
||||
*/
|
||||
const char *dm_stats_get_current_region_aux_data(struct dm_stats *dms);
|
||||
|
||||
/*
|
||||
* Call this to actually run the ioctl.
|
||||
*/
|
||||
@ -1941,6 +2400,148 @@ int dm_report_field_percent(struct dm_report *rh, struct dm_report_field *field,
|
||||
void dm_report_field_set_value(struct dm_report_field *field, const void *value,
|
||||
const void *sortvalue);
|
||||
|
||||
/*
|
||||
* Stats counter access methods
|
||||
*
|
||||
* Each method returns the corresponding stats counter value from the
|
||||
* supplied dm_stats handle for the specified region_id and area_id.
|
||||
* If either region_id or area_id uses one of the special values
|
||||
* DM_STATS_REGION_CURRENT or DM_STATS_AREA_CURRENT then the region
|
||||
* or area is selected according to the current state of the dm_stats
|
||||
* handle's embedded cursor.
|
||||
*
|
||||
* See the kernel documentation for complete descriptions of each
|
||||
* counter field:
|
||||
*
|
||||
* Documentation/device-mapper/statistics.txt
|
||||
* Documentation/iostats.txt
|
||||
*
|
||||
* reads: the number of reads completed
|
||||
* reads_merged: the number of reads merged
|
||||
* read_sectors: the number of sectors read
|
||||
* read_nsecs: the number of nanoseconds spent reading
|
||||
* writes: the number of writes completed
|
||||
* writes_merged: the number of writes merged
|
||||
* write_sectors: the number of sectors written
|
||||
* write_nsecs: the number of nanoseconds spent writing
|
||||
* io_in_progress: the number of I/Os currently in progress
|
||||
* io_nsecs: the number of nanoseconds spent doing I/Os
|
||||
* weighted_io_nsecs: the weighted number of nanoseconds spent doing I/Os
|
||||
* total_read_nsecs: the total time spent reading in nanoseconds
|
||||
* total_write_nsecs: the total time spent writing in nanoseconds
|
||||
*/
|
||||
|
||||
#define DM_STATS_REGION_CURRENT UINT64_MAX
|
||||
#define DM_STATS_AREA_CURRENT UINT64_MAX
|
||||
|
||||
uint64_t dm_stats_get_reads(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_reads_merged(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_read_sectors(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_read_nsecs(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_writes(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_writes_merged(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_write_sectors(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_write_nsecs(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_io_in_progress(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_io_nsecs(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_weighted_io_nsecs(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_total_read_nsecs(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
uint64_t dm_stats_get_total_write_nsecs(struct dm_stats *dms,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
/*
|
||||
* Derived statistics access methods
|
||||
*
|
||||
* Each method returns the corresponding value calculated from the
|
||||
* counters stored in the supplied dm_stats handle for the specified
|
||||
* region_id and area_id. If either region_id or area_id uses one of the
|
||||
* special values DM_STATS_REGION_CURRENT or DM_STATS_AREA_CURRENT then
|
||||
* the region or area is selected according to the current state of the
|
||||
* dm_stats handle's embedded cursor.
|
||||
*
|
||||
* The set of metrics is based on the fields provided by the Linux
|
||||
* iostats program.
|
||||
*
|
||||
* rd_merges_per_sec: the number of reads merged per second
|
||||
* wr_merges_per_sec: the number of writes merged per second
|
||||
* reads_per_sec: the number of reads completed per second
|
||||
* writes_per_sec: the number of writes completed per second
|
||||
* read_sectors_per_sec: the number of sectors read per second
|
||||
* write_sectors_per_sec: the number of sectors written per second
|
||||
* average_request_size: the average size of requests submitted
|
||||
* service_time: the average service time (in ns) for requests issued
|
||||
* average_queue_size: the average queue length
|
||||
* average_wait_time: the average time for requests to be served (in ns)
|
||||
* average_rd_wait_time: the average read wait time
|
||||
* average_wr_wait_time: the average write wait time
|
||||
*/
|
||||
|
||||
int dm_stats_get_rd_merges_per_sec(struct dm_stats *dms, double *rrqm,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_wr_merges_per_sec(struct dm_stats *dms, double *rrqm,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_reads_per_sec(struct dm_stats *dms, double *rd_s,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_writes_per_sec(struct dm_stats *dms, double *wr_s,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_read_sectors_per_sec(struct dm_stats *dms, double *rsec_s,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_write_sectors_per_sec(struct dm_stats *dms, double *wr_s,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_average_request_size(struct dm_stats *dms, double *arqsz,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_service_time(struct dm_stats *dms, double *svctm,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_average_queue_size(struct dm_stats *dms, double *qusz,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_average_wait_time(struct dm_stats *dms, double *await,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_average_rd_wait_time(struct dm_stats *dms, double *await,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_average_wr_wait_time(struct dm_stats *dms, double *await,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_throughput(struct dm_stats *dms, double *tput,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_utilization(struct dm_stats *dms, dm_percent_t *util,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
/*************************
|
||||
* config file parse/print
|
||||
*************************/
|
||||
|
1350
libdm/libdm-stats.c
Normal file
1350
libdm/libdm-stats.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -83,7 +83,7 @@ ifneq ("@THIN@", "none")
|
||||
MAN7+=lvmthin.7
|
||||
endif
|
||||
|
||||
MAN8DM=dmsetup.8 $(DMEVENTDMAN) $(BLKDEACTIVATEMAN)
|
||||
MAN8DM=dmsetup.8 dmstats.8 $(DMEVENTDMAN) $(BLKDEACTIVATEMAN)
|
||||
MAN5DIR=$(mandir)/man5
|
||||
MAN7DIR=$(mandir)/man7
|
||||
MAN8DIR=$(mandir)/man8
|
||||
|
693
man/dmstats.8.in
Normal file
693
man/dmstats.8.in
Normal file
@ -0,0 +1,693 @@
|
||||
.TH DMSTATS 8 "Jul 25 2015" "Linux" "MAINTENANCE COMMANDS"
|
||||
.SH NAME
|
||||
dmstats \(em device-mapper statistics management
|
||||
.SH SYNOPSIS
|
||||
.ad l
|
||||
.B dmsetup stats
|
||||
.I command
|
||||
.RB [ options ]
|
||||
.br
|
||||
|
||||
.B dmstats <command>
|
||||
.RB [[
|
||||
.IR device_name ]
|
||||
.RB |[ \-\-uuid
|
||||
.IR uuid ]
|
||||
.RB |[ \-\-major
|
||||
.IR major
|
||||
.RB \-\-minor
|
||||
.IR minor ]]
|
||||
.br
|
||||
|
||||
.B dmstats clear
|
||||
.I device_name
|
||||
.RB [ \-\-allregions
|
||||
.RB | \-\-regionid
|
||||
.IR id ]
|
||||
.br
|
||||
.B dmstats create
|
||||
.I device_name
|
||||
.RB [[ \-\-areas
|
||||
.IR nr_areas ]
|
||||
.RB |[ \-\-areasize
|
||||
.IR area_size ]]
|
||||
.RB [[ \-\-start
|
||||
.IR start_sector ]
|
||||
.RB [ \-\-length
|
||||
.IR length ]
|
||||
.RB |[ \-\-segments ]]
|
||||
.RB [ \-\-auxdata
|
||||
.IR data ]
|
||||
.RB [ \-\-programid
|
||||
.IR id ]
|
||||
.br
|
||||
.B dmstats delete
|
||||
.I device_name
|
||||
.RB [ \-\-force ]
|
||||
.RB [ \-\-allregions
|
||||
.RB | \-\-regionid
|
||||
.IR id ]
|
||||
.RB [ \-\-allprograms
|
||||
.RB | \-\-programid
|
||||
.IR id ]
|
||||
.br
|
||||
.B dmstats help
|
||||
.RB [ \-c | \-C | \-\-columns ]
|
||||
.br
|
||||
.B dmstats list
|
||||
.RI [ device_name ]
|
||||
.RB [ \-\-allprograms
|
||||
.RB | \-\-programid
|
||||
.IR id ]
|
||||
.RB [ \-\-units
|
||||
.IR units ]
|
||||
.RB [ \-\-nosuffix ]
|
||||
.br
|
||||
.B dmstats print
|
||||
.RI [ device_name ]
|
||||
.RB [ \-\-clear ]
|
||||
.RB [ \-\-allprograms
|
||||
.RB | \-\-programid
|
||||
.IR id ]
|
||||
.RB [ \-\-allregions
|
||||
.RB | \-\-regionid
|
||||
.IR id ]
|
||||
.br
|
||||
.B dmstats report
|
||||
.RI [ device_name ]
|
||||
.RB [ \-\-interval
|
||||
.IR seconds ]
|
||||
.RB [ \-\-count
|
||||
.IR count ]
|
||||
.RB [ \-\-units
|
||||
.IR units ]
|
||||
.RB [ \-\-allprograms ]
|
||||
.RB [ \-\-programid
|
||||
.IR id ]
|
||||
.RB [ \-\-regionid
|
||||
.IR id ]
|
||||
.RB [ \-O | \-\-sort
|
||||
.IR sort_fields ]
|
||||
.RB [ \-S | \-\-select
|
||||
.IR Selection ]
|
||||
.RB [ \-\-units
|
||||
.IR units ]
|
||||
.RB [ \-\-nosuffix ]
|
||||
.br
|
||||
.ad b
|
||||
.SH DESCRIPTION
|
||||
The dmstats program manages IO statistics regions for devices that use
|
||||
the device-mapper driver. Statistics regions may be created, deleted,
|
||||
listed and reported on using the tool.
|
||||
|
||||
The first argument to dmstats is a command.
|
||||
|
||||
The second argument is the device name, uuid, or major and minor
|
||||
numbers.
|
||||
|
||||
Further options permit the selection of regions, output format
|
||||
control, and reporting behaviour.
|
||||
|
||||
When the program is run using the 'dmstats' alias, the command
|
||||
\fBmust\fP be the first argument and any switches and options should be
|
||||
specified following the command itself. This limitation is not present
|
||||
when run as 'dmsetup stats'.
|
||||
|
||||
When no device argument is given dmstats will by default operate on all
|
||||
device-mapper devices present. The \fBcreate\fP and \fBdelete\fP
|
||||
commands require the use of \fB--force\fP when used in this way.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\-allprograms
|
||||
Include regions from all program IDs for list and report operations.
|
||||
.TP
|
||||
.B \-\-allregions
|
||||
Include all present regions for commands that normally accept a single
|
||||
region identifier.
|
||||
.TP
|
||||
.B \-\-areas \fInr_areas
|
||||
Specify the number of statistics areas to create within a new region.
|
||||
.TP
|
||||
.B \-\-areasize \fIarea_size
|
||||
Specify the size of areas into which a new region should be divided. An
|
||||
optional suffix selects units of bBsSkKmMgGtTpPeE: (b)ytes,
|
||||
(s)ectors, (k)ilobytes, (m)egabytes, (g)igabytes, (t)erabytes,
|
||||
(p)etabytes, (e)xabytes. Capitalise to use multiples of 1000 (S.I.)
|
||||
instead of 1024.
|
||||
.TP
|
||||
.B \-\-auxdata \fIaux_data
|
||||
Specify auxilliary data (a string) to be stored with a new region.
|
||||
.TP
|
||||
.B \-\-clear
|
||||
When printing statistics counters, also atomically reset them to zero.
|
||||
.TP
|
||||
.B \-\-count \fIcount
|
||||
Specify the iteration count for repeating reports. If the count
|
||||
argument is zero reports will continue to repeat until interrupted.
|
||||
.TP
|
||||
.B \-\-interval \fIseconds
|
||||
Specify the interval in seconds between successive iterations for
|
||||
repeating reports. If \-\-interval is specified but \-\-count is not,
|
||||
reports will continue to repeat until interrupted.
|
||||
.TP
|
||||
.B \-\-length \fIlength
|
||||
Specify the length of a new statistics region in sectors. An optional
|
||||
suffix selects units of bBsSkKmMgGtTpPeE: (b)ytes, (s)ectors,
|
||||
(k)ilobytes, (m)egabytes, (g)igabytes, (t)erabytes, (p)etabytes,
|
||||
(e)xabytes. Capitalise to use multiples of 1000 (S.I.) instead of 1024.
|
||||
.TP
|
||||
.BR \-j | \-\-major\ \fImajor
|
||||
Specify the major number.
|
||||
.TP
|
||||
.BR \-m | \-\-minor\ \fIminor
|
||||
Specify the minor number.
|
||||
.TP
|
||||
.B \-\-nosuffix
|
||||
Suppress the suffix on output sizes. Use with \fB\-\-units\fP
|
||||
(except h and H) if processing the output.
|
||||
.TP
|
||||
.BR \-o | \-\-options
|
||||
Specify which report fields to display.
|
||||
.TP
|
||||
.BR \-O | \-\-sort\ \fIsort_fields
|
||||
Sort output according to the list of fields given. Precede any
|
||||
sort_field with - for a reverse sort on that column.
|
||||
.TP
|
||||
.B \-\-programid \fIid
|
||||
Specify a program ID string. When creating new statistics regions this
|
||||
string is stored with the region. Subsequent operations may supply a
|
||||
program ID in order to select only regions with a matching value. The
|
||||
default program ID for dmstats-managed regions is "dmstats".
|
||||
.TP
|
||||
.BR \-S | \-\-select \ \fIselection
|
||||
Display only rows that match selection criteria. All rows with the
|
||||
additional "selected" column (-o selected) showing 1 if the row matches
|
||||
the selection and 0 otherwise. The selection criteria are defined by
|
||||
specifying column names and their valid values while making use of
|
||||
supported comparison operators.
|
||||
.TP
|
||||
.B \-\-start \fIstart
|
||||
Specify the start offset of a new statistics region in sectors. An
|
||||
optional suffix selects units of bBsSkKmMgGtTpPeE: (b)ytes,
|
||||
(s)ectors, (k)ilobytes, (m)egabytes, (g)igabytes, (t)erabytes,
|
||||
(p)etabytes, (e)xabytes. Capitalise to use multiples of 1000 (S.I.)
|
||||
instead of 1024.
|
||||
.TP
|
||||
.B \-\-segments
|
||||
Create a new statistics region for each target contained in the target
|
||||
device. This causes a separate region to be allocated for each segment
|
||||
of the device.
|
||||
.TP
|
||||
.BR \-\-units \ hHbBsSkKmMgGtTpPeE
|
||||
Set the display units for report output. All sizes are output in these
|
||||
units: (h)uman-readable, (b)ytes, (s)ectors, (k)ilobytes, (m)egabytes,
|
||||
(g)igabytes, (t)erabytes, (p)etabytes, (e)xabytes. Capitalise to use
|
||||
multiples of 1000 (S.I.) instead of 1024. Can also specify custom units
|
||||
e.g. \fB\-\-units 3M\fP
|
||||
.TP
|
||||
.BR \-u | \-\-uuid
|
||||
Specify the uuid.
|
||||
.TP
|
||||
.BR \-v | \-\-verbose \ [ \-v | \-\-verbose ]
|
||||
Produce additional output.
|
||||
.br
|
||||
.SH COMMANDS
|
||||
.TP
|
||||
.B clear
|
||||
.I device_name
|
||||
.RB [ \-\-allregions
|
||||
.RB | \-\-regionid
|
||||
.IR id ]
|
||||
.RB [ \-\-allprograms
|
||||
.RB | \-\-programid
|
||||
.IR id ]
|
||||
.br
|
||||
Instructs the kernel to clear statistics counters for the speficied
|
||||
regions (with the exception of in-flight IO counters).
|
||||
.br
|
||||
.TP
|
||||
.B create
|
||||
.I device_name
|
||||
.RB [ \-\-areas
|
||||
.IR nr_areas ]
|
||||
.RB [ \-\-areasize
|
||||
.IR area_size ]
|
||||
.RB [[ \-\-start
|
||||
.IR start_sector ]
|
||||
.RB [ \-\-length
|
||||
.IR length ]
|
||||
.RB |[ \-\-segments ]]
|
||||
.RB [ \-\-auxdata
|
||||
.IR data ]
|
||||
.RB [ \-\-programid
|
||||
.IR id ]
|
||||
.br
|
||||
Creates one or more new statistics regions on the specified device(s).
|
||||
|
||||
The region will span the entire device unless \fB\-\-start\fP and
|
||||
\fB\-\-length\fP or \fB\-\-target\fP are given. The \fB\-\-start\fP and
|
||||
\fB\-\-length\fP options allow a region of arbitrary length to be placed
|
||||
at an arbitrary offset into the device. The \fB\-\-segments\fP option
|
||||
causes a new region to be created for each target in the corresponding
|
||||
device-mapper device's table.
|
||||
|
||||
An optional \fBprogram_id\fP or \fBaux_data\fP string may be associated
|
||||
with the region. A \fBprogram_id\fP may then be used to select regions
|
||||
for subsequent list, print, and report operations. The \fBaux_data\fP
|
||||
stores an arbitrary string and is not used by dmstats or the
|
||||
device-mapper kernel statistics subsystem.
|
||||
|
||||
By default dmstats creates regions with a \fBprogram_id\fP of
|
||||
"DMSTATS1".
|
||||
|
||||
On success the \fBregion_id\fP of the newly created region is printed to
|
||||
stdout.
|
||||
.br
|
||||
.TP
|
||||
.B delete
|
||||
.I [ device_name ]
|
||||
.RB [ \-\-force ]
|
||||
.RB [ \-\-allregions
|
||||
.RB | \-\-regionid
|
||||
.IR id ]
|
||||
.RB [ \-\-allprograms
|
||||
.RB | \-\-programid
|
||||
.IR id ]
|
||||
.br
|
||||
Delete the specified statistics region. All counters and resources used
|
||||
by the region are released and the region will not appear in the output
|
||||
of subsequent list, print, or report operations.
|
||||
|
||||
All regions registered on a device may be removed using
|
||||
\fB\-\-allregions\fP.
|
||||
|
||||
To remove all regions on all devices \fB\-\-force\fP must be used.
|
||||
.br
|
||||
.TP
|
||||
.B help
|
||||
.RB [ \-c | \-C | \-\-columns ]
|
||||
.br
|
||||
Outputs a summary of the commands available, optionally including
|
||||
the list of report fields.
|
||||
.br
|
||||
.TP
|
||||
.B list
|
||||
.RI [ device_name ]
|
||||
.RB [ \-\-allprograms ]
|
||||
.RB [ \-\-programid
|
||||
.IR id ]
|
||||
.br
|
||||
List the statistics regions registered on the device. If the
|
||||
\fB\-\-allprograms\fP switch is given all regions will be listed
|
||||
regardless of region program ID values.
|
||||
.br
|
||||
.TP
|
||||
.B print
|
||||
.RB [ \-\-clear ]
|
||||
.IR
|
||||
.RB [ \-\-allregions
|
||||
.RB | \-\-regionid
|
||||
.IR id ]
|
||||
.RB [ \-\-allprograms
|
||||
.RB | \-\-programid
|
||||
.IR id ]
|
||||
.br
|
||||
Print raw statistics counters for the specified region or for all
|
||||
present regions.
|
||||
.br
|
||||
.TP
|
||||
.B report
|
||||
.RB [ \-\-allprograms ]
|
||||
.RB [ \-\-interval
|
||||
.IR seconds ]
|
||||
.RB [ \-\-count
|
||||
.IR count ]
|
||||
.RB [ \-\-units
|
||||
.IR unit ]
|
||||
.RB [ \-\-regionid
|
||||
.IR id ]
|
||||
.RB [ \-\-programid
|
||||
.IR id ]
|
||||
.RB [ \-O | \-\-sort
|
||||
.IR sort_fields ]
|
||||
.RB [ \-S | \-\-select
|
||||
.IR Selection ]
|
||||
.RB [ \-\-units
|
||||
.IR units ]
|
||||
.br
|
||||
Start a report for the specified region or for all present regions. If
|
||||
the count argument is specified, the report will repeat at a fixed
|
||||
interval set by the \fB\-\-interval\fP option. The default interval is
|
||||
one second.
|
||||
|
||||
If the \fB\-\-allprograms\fP switch is given, all regions will be
|
||||
listed, regardless of region program ID values.
|
||||
.br
|
||||
.SH REGIONS AND AREAS
|
||||
The device-mapper statistics facility allows separate performance
|
||||
counters to be maintained for arbitrary regions of devices. A region may
|
||||
span any range: from a single sector to the whole device. A region may
|
||||
be further sub-divided into a number of distinct areas (one or more),
|
||||
each with its own counter set.
|
||||
|
||||
By default new regions span the entire device. The \fB\-\-start\fP and
|
||||
\fB\-\-length\fP options allows a region of any size to be placed at any
|
||||
location on the device.
|
||||
|
||||
A region may be either divided into the specified number of equal-sized
|
||||
areas, or into areas of the given size by specifying one of
|
||||
\fB\-\-areas\fP or \fB\-\-areasize\fP when creating a region with the
|
||||
\fBcreate\fP command. Depending on the size of the areas and the device
|
||||
region the final area within the region may be smaller than requested.
|
||||
|
||||
.SS Region identifiers
|
||||
Each region is assigned an identifier when it is created that is used to
|
||||
reference the region in subsequent operations. Region identifiers are
|
||||
unique within a given device (including across different \fBprogram_id\fP
|
||||
values).
|
||||
.br
|
||||
Depending on the sequence of create and delete operations, gaps may
|
||||
exist in the sequence of \fBregion_id\fP values for a particular device.
|
||||
|
||||
.SH REPORT FIELDS
|
||||
The dmstats report provides several types of field that may be added to
|
||||
the default field set, or used to create custom reports.
|
||||
.br
|
||||
All performance counters and metrics are calculated per-area.
|
||||
.br
|
||||
.SS Derived metrics
|
||||
A number of metrics fields are included that provide high level
|
||||
performance indicators. These are based on the fields provided by the
|
||||
conventional Linux iostat program and are derived from the basic counter
|
||||
values provided by the kernel for each area.
|
||||
.br
|
||||
.HP
|
||||
.B rrqm
|
||||
.br
|
||||
Read requests merged per second.
|
||||
.HP
|
||||
.B wrqm
|
||||
.br
|
||||
Write requests merged per second.
|
||||
.HP
|
||||
.B rs
|
||||
.br
|
||||
Read requests per second.
|
||||
.HP
|
||||
.B ws
|
||||
.br
|
||||
Write requests per second.
|
||||
.HP
|
||||
.B rsec
|
||||
.br
|
||||
Sectors read per second.
|
||||
.HP
|
||||
.B wsec
|
||||
.br
|
||||
Sectors written per second.
|
||||
.HP
|
||||
.B arqsz
|
||||
.br
|
||||
The average size of requests submitted to the area.
|
||||
.HP
|
||||
.B qusz
|
||||
.br
|
||||
The average queue length.
|
||||
.HP
|
||||
.B await
|
||||
.br
|
||||
The average wait time for read and write requests.
|
||||
.HP
|
||||
.B r_await
|
||||
.br
|
||||
The average wait time for read requests.
|
||||
.HP
|
||||
.B w_await
|
||||
.br
|
||||
The average wait time for write requests.
|
||||
.HP
|
||||
.B tput
|
||||
.br
|
||||
The device throughput in requests per second.
|
||||
.HP
|
||||
.B svctm
|
||||
.br
|
||||
The average service time (in milliseconds) for I/O requests that
|
||||
were issued to the device.
|
||||
.HP
|
||||
.B util
|
||||
.br
|
||||
Percentage of CPU time during which I/O requests were issued to the
|
||||
device (bandwidth utilization for the device). Device saturation occurs
|
||||
when this value is close to 100%.
|
||||
.br
|
||||
.SS Region and area meta fields
|
||||
Meta fields provide information about the region or area that the
|
||||
statistics values relate to. This includes the region and area
|
||||
identifier, start, length, and counts, as well as the program ID and
|
||||
auxiliary data values.
|
||||
.br
|
||||
.HP
|
||||
.B region_id
|
||||
.br
|
||||
Region identifier. This is a non-negative integer returned by the kernel
|
||||
when a statistics region is created.
|
||||
.HP
|
||||
.B region_start
|
||||
.br
|
||||
.br
|
||||
The region start sector in units of 512 byte sectors.
|
||||
.HP
|
||||
.B region_len
|
||||
.br
|
||||
The length of the region in units of 512 byte sectors.
|
||||
.HP
|
||||
.B area_id
|
||||
.br
|
||||
Area identifier. Area identifiers are assigned by the device-mapper
|
||||
statistics library and uniquely identify each area within a region. Each
|
||||
ID corresponds to a distinct set of performance counters for that area
|
||||
of the statistics region. Area identifiers are always monotonically
|
||||
increasing within a region so that higher ID values correspond to
|
||||
greater sector addresses within the region and no gaps in the sequence
|
||||
of identifiers exist. Sorting a report by device, region start, and area
|
||||
ID (the default) will then produce rows in order of ascending region and
|
||||
area address.
|
||||
.HP
|
||||
.B area_start
|
||||
.br
|
||||
The area start sector in units of 512 byte sectors.
|
||||
.HP
|
||||
.B area_len
|
||||
.br
|
||||
The length of the area in units of 512 byte sectors.
|
||||
.HP
|
||||
.B area_count
|
||||
.br
|
||||
The number of areas in this region.
|
||||
.HP
|
||||
.B program_id
|
||||
.br
|
||||
The program ID value associated with this region.
|
||||
.HP
|
||||
.B aux_data
|
||||
.br
|
||||
The auxiliary data value associated with this region.
|
||||
.br
|
||||
.SS Basic counters
|
||||
Basic counters provide access to the raw counter data from the kernel,
|
||||
allowing further processing to be carried out by another program.
|
||||
|
||||
The kernel provides thirteen separate counters for each statistics
|
||||
area. The first eleven of these match the counters provided in
|
||||
/proc/diskstats or /sys/block/*/*/stat. The final pair provide separate
|
||||
counters for read and write time.
|
||||
.P
|
||||
.HP
|
||||
.B reads
|
||||
.br
|
||||
The number of reads successfully completed this interval.
|
||||
.HP
|
||||
.B read_merges
|
||||
.br
|
||||
The number of read requests merged this interval. This field is
|
||||
incremented every time a pair of requests are merged to create a single
|
||||
request to be issued to the device.
|
||||
.HP
|
||||
.B read_sectors
|
||||
.br
|
||||
The number of 512 byte sectors read this interval.
|
||||
.HP
|
||||
.B read_nsecs
|
||||
.br
|
||||
The number of nanoseconds spent reading during this interval.
|
||||
.HP
|
||||
.B writes
|
||||
.br
|
||||
The number of writes successfully completed this interval.
|
||||
.HP
|
||||
.B write_merges
|
||||
.br
|
||||
The number of write requests merged this interval. This field is
|
||||
incremented every time a pair of requests are merged to create a single
|
||||
request to be issued to the device.
|
||||
.HP
|
||||
.B write_sectors
|
||||
.br
|
||||
The number of 512 byte sectors written this interval.
|
||||
.HP
|
||||
.B write_nsecs
|
||||
.br
|
||||
The number of nanoseconds spent writing during this interval.
|
||||
.HP
|
||||
.B in_progress
|
||||
.br
|
||||
The number of reads and writes currently in progress.
|
||||
.HP
|
||||
.B io_nsecs
|
||||
.br
|
||||
The number of nanoseconds spent reading and writing.
|
||||
.HP
|
||||
.B weighted_io_nsecs
|
||||
.br
|
||||
This field is incremented at each I/O start, I/O completion, I/O merge,
|
||||
or read of these stats by the number of I/Os in progress multiplied by
|
||||
the number of milliseconds spent doing I/O since the last update of this
|
||||
field. This can provide an easy measure of both I/O completion time and
|
||||
the backlog that may be accumulating.
|
||||
.br
|
||||
.br
|
||||
.P
|
||||
.SH EXAMPLES
|
||||
Create a whole-device region with one area on vg00/lvol1
|
||||
.br
|
||||
.br
|
||||
# dmstats create vg00/lvol1
|
||||
.br
|
||||
Created region: 0
|
||||
.br
|
||||
.br
|
||||
|
||||
|
||||
Create a 32M region 1G into device d0
|
||||
.br
|
||||
.br
|
||||
# dmstats create --start 1G --length 32M d0
|
||||
.br
|
||||
Created region: 2
|
||||
.br
|
||||
|
||||
|
||||
Create a whole-device region with 8 areas on every device
|
||||
.br
|
||||
.br
|
||||
# dmstats create --areas 8
|
||||
.br
|
||||
Created region: 0
|
||||
.br
|
||||
Created region: 0
|
||||
.br
|
||||
Created region: 0
|
||||
.br
|
||||
Created region: 2
|
||||
.br
|
||||
Created region: 0
|
||||
.br
|
||||
Created region: 0
|
||||
.br
|
||||
.br
|
||||
|
||||
Delete all regions on all devices
|
||||
.br
|
||||
.br
|
||||
# dmstats delete --allregions --force
|
||||
.br
|
||||
.br
|
||||
|
||||
Create a whole-device region with areas 10GiB in size on vg00/lvol1
|
||||
using dmsetup
|
||||
.br
|
||||
.br
|
||||
# dmsetup stats create --areasize 10G vg00/lvol1
|
||||
.br
|
||||
Created region: 1
|
||||
.br
|
||||
.br
|
||||
|
||||
Create a 1GiB region with 16 areas at the start of vg00/lvol1
|
||||
.br
|
||||
# dmstats create --start 0 --len 1G --areas=16 vg00/lvol1
|
||||
.br
|
||||
Created region: 2
|
||||
.br
|
||||
.br
|
||||
|
||||
List the statistics regions registered on vg00/lvol1
|
||||
.br
|
||||
# dmstats list vg00/lvol1
|
||||
.br
|
||||
RegionID RegStart RegLen AreaSize ProgramID AuxData
|
||||
.br
|
||||
0 0 104857600 20971520 dmstats
|
||||
.br
|
||||
1 0 104857600 20971520 dmstats
|
||||
.br
|
||||
2 0 2097152 131072 dmstats
|
||||
.br
|
||||
.br
|
||||
|
||||
Display five statistics reports for vg00/lvol1 at an interval of one second
|
||||
.br
|
||||
.br
|
||||
# dmstats report --interval 1 --count 5 vg00/lvol1
|
||||
.br
|
||||
Name RgID ArID RRqM/s WRqM/s R/s W/s RSz/s WSz/s AvRqSz QSize SvcTm Util% AWait
|
||||
.br
|
||||
vg00-lvol1 0 0 0.00 0.00 8.00 0.00 48.00k 0 6.00k 0.00 5.50 4.40 6.62
|
||||
.br
|
||||
vg00-lvol1 0 1 0.00 0.00 22.00 0.00 624.00k 0 28.00k 0.00 5.23 11.50 5.36
|
||||
.br
|
||||
vg00/lvol1 0 2 0.00 0.00 353.00 0.00 1.84m 0 5.00k 0.00 1.34 47.40 1.33
|
||||
.br
|
||||
vg00/lvol1 0 3 0.00 0.00 73.00 0.00 592.00k 0 8.00k 0.00 2.10 15.30 2.10
|
||||
.br
|
||||
vg00/lvol1 0 4 0.00 0.00 5.00 0.00 52.00k 0 10.00k 0.00 4.00 2.00 4.00
|
||||
.br
|
||||
[...]
|
||||
.br
|
||||
.br
|
||||
|
||||
Create one region for reach target contained in device vg00/lvol1
|
||||
.br
|
||||
.br
|
||||
# dmstats create --segments vg00/lvol1
|
||||
.br
|
||||
Created region: 0
|
||||
.br
|
||||
Created region: 1
|
||||
.br
|
||||
Created region: 2
|
||||
.br
|
||||
.br
|
||||
|
||||
Print raw counters for region 4 on device d0
|
||||
.br
|
||||
.br
|
||||
# dmstats print --regionid 4 d0
|
||||
.br
|
||||
2097152+65536 0 0 0 0 29 0 264 701 0 41 701 0 41
|
||||
.br
|
||||
.br
|
||||
.SH AUTHORS
|
||||
Bryn M. Reeves <bmr@redhat.com>
|
||||
|
||||
.SH SEE ALSO
|
||||
LVM2 resource page https://www.sourceware.org/lvm2/
|
||||
.br
|
||||
Device-mapper resource page: http://sources.redhat.com/dm/
|
||||
.br
|
||||
|
||||
Device-mapper statistics kernel documentation
|
||||
.br
|
||||
Documentation/device-mapper/statistics.txt
|
1585
tools/dmsetup.c
1585
tools/dmsetup.c
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user