mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
dmsetup: Report timestamps of ioctls with -vvv.
If enabled, record timestamp immediately after the ioctl() returns.
This commit is contained in:
parent
2f334afb98
commit
559ca8bc65
@ -1,5 +1,6 @@
|
|||||||
Version 1.02.104 -
|
Version 1.02.104 -
|
||||||
=================================
|
=================================
|
||||||
|
Report timestamps of ioctls with dmsetup -vvv.
|
||||||
Recognize report field name variants without any underscores too.
|
Recognize report field name variants without any underscores too.
|
||||||
Add dmsetup --interval and --count to repeat reports at specified intervals.
|
Add dmsetup --interval and --count to repeat reports at specified intervals.
|
||||||
Add report interval and waiting functions to libdevmapper.
|
Add report interval and waiting functions to libdevmapper.
|
||||||
|
@ -4,6 +4,8 @@ dm_report_set_interval_ms
|
|||||||
dm_report_set_interval_ns
|
dm_report_set_interval_ns
|
||||||
dm_report_wait
|
dm_report_wait
|
||||||
dm_size_to_string
|
dm_size_to_string
|
||||||
|
dm_task_get_ioctl_timestamp
|
||||||
|
dm_task_set_record_timestamp
|
||||||
dm_timestamp_alloc
|
dm_timestamp_alloc
|
||||||
dm_timestamp_compare
|
dm_timestamp_compare
|
||||||
dm_timestamp_delta
|
dm_timestamp_delta
|
||||||
|
@ -68,6 +68,7 @@ static unsigned _dm_version = DM_VERSION_MAJOR;
|
|||||||
static unsigned _dm_version_minor = 0;
|
static unsigned _dm_version_minor = 0;
|
||||||
static unsigned _dm_version_patchlevel = 0;
|
static unsigned _dm_version_patchlevel = 0;
|
||||||
static int _log_suppress = 0;
|
static int _log_suppress = 0;
|
||||||
|
static struct dm_timestamp *_dm_ioctl_timestamp = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the kernel dm driver only supports one major number
|
* If the kernel dm driver only supports one major number
|
||||||
@ -919,6 +920,24 @@ int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dm_task_set_record_timestamp(struct dm_task *dmt)
|
||||||
|
{
|
||||||
|
if (!_dm_ioctl_timestamp)
|
||||||
|
_dm_ioctl_timestamp = dm_timestamp_alloc();
|
||||||
|
|
||||||
|
if (!_dm_ioctl_timestamp)
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
dmt->record_timestamp = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dm_timestamp *dm_task_get_ioctl_timestamp(struct dm_task *dmt)
|
||||||
|
{
|
||||||
|
return dmt->record_timestamp ? _dm_ioctl_timestamp : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct target *create_target(uint64_t start, uint64_t len, const char *type,
|
struct target *create_target(uint64_t start, uint64_t len, const char *type,
|
||||||
const char *params)
|
const char *params)
|
||||||
{
|
{
|
||||||
@ -1716,6 +1735,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
|||||||
{
|
{
|
||||||
struct dm_ioctl *dmi;
|
struct dm_ioctl *dmi;
|
||||||
int ioctl_with_uevent;
|
int ioctl_with_uevent;
|
||||||
|
int r;
|
||||||
|
|
||||||
dmt->ioctl_errno = 0;
|
dmt->ioctl_errno = 0;
|
||||||
|
|
||||||
@ -1803,8 +1823,13 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
|||||||
dmt->sector, _sanitise_message(dmt->message),
|
dmt->sector, _sanitise_message(dmt->message),
|
||||||
dmi->data_size, retry_repeat_count);
|
dmi->data_size, retry_repeat_count);
|
||||||
#ifdef DM_IOCTLS
|
#ifdef DM_IOCTLS
|
||||||
if (ioctl(_control_fd, command, dmi) < 0 &&
|
r = ioctl(_control_fd, command, dmi);
|
||||||
dmt->expected_errno != errno) {
|
|
||||||
|
if (dmt->record_timestamp)
|
||||||
|
if (!dm_timestamp_get(_dm_ioctl_timestamp))
|
||||||
|
stack;
|
||||||
|
|
||||||
|
if (r < 0 && dmt->expected_errno != errno) {
|
||||||
dmt->ioctl_errno = errno;
|
dmt->ioctl_errno = errno;
|
||||||
if (dmt->ioctl_errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) ||
|
if (dmt->ioctl_errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) ||
|
||||||
(dmt->type == DM_DEVICE_MKNODES) ||
|
(dmt->type == DM_DEVICE_MKNODES) ||
|
||||||
@ -2049,6 +2074,8 @@ repeat_ioctl:
|
|||||||
void dm_lib_release(void)
|
void dm_lib_release(void)
|
||||||
{
|
{
|
||||||
_close_control_fd();
|
_close_control_fd();
|
||||||
|
dm_timestamp_destroy(_dm_ioctl_timestamp);
|
||||||
|
_dm_ioctl_timestamp = NULL;
|
||||||
update_devs();
|
update_devs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,8 @@ struct dm_task {
|
|||||||
int expected_errno;
|
int expected_errno;
|
||||||
int ioctl_errno;
|
int ioctl_errno;
|
||||||
|
|
||||||
|
int record_timestamp;
|
||||||
|
|
||||||
char *uuid;
|
char *uuid;
|
||||||
char *mangled_uuid;
|
char *mangled_uuid;
|
||||||
};
|
};
|
||||||
|
@ -128,6 +128,7 @@ enum {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct dm_task;
|
struct dm_task;
|
||||||
|
struct dm_timestamp;
|
||||||
|
|
||||||
struct dm_task *dm_task_create(int type);
|
struct dm_task *dm_task_create(int type);
|
||||||
void dm_task_destroy(struct dm_task *dmt);
|
void dm_task_destroy(struct dm_task *dmt);
|
||||||
@ -228,6 +229,12 @@ int dm_task_secure_data(struct dm_task *dmt);
|
|||||||
int dm_task_retry_remove(struct dm_task *dmt);
|
int dm_task_retry_remove(struct dm_task *dmt);
|
||||||
int dm_task_deferred_remove(struct dm_task *dmt);
|
int dm_task_deferred_remove(struct dm_task *dmt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record timestamp immediately after the ioctl returns.
|
||||||
|
*/
|
||||||
|
int dm_task_set_record_timestamp(struct dm_task *dmt);
|
||||||
|
struct dm_timestamp *dm_task_get_ioctl_timestamp(struct dm_task *dmt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable checks for common mistakes such as issuing ioctls in an unsafe order.
|
* Enable checks for common mistakes such as issuing ioctls in an unsafe order.
|
||||||
*/
|
*/
|
||||||
@ -1669,8 +1676,6 @@ dm_percent_t dm_make_percent(uint64_t numerator, uint64_t denominator);
|
|||||||
* timestamp handling
|
* timestamp handling
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
struct dm_timestamp;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a dm_timestamp object to use with dm_timestamp_get.
|
* Create a dm_timestamp object to use with dm_timestamp_get.
|
||||||
*/
|
*/
|
||||||
|
@ -277,6 +277,7 @@ struct dm_task *dm_task_create(int type)
|
|||||||
dmt->query_inactive_table = 0;
|
dmt->query_inactive_table = 0;
|
||||||
dmt->new_uuid = 0;
|
dmt->new_uuid = 0;
|
||||||
dmt->secure_data = 0;
|
dmt->secure_data = 0;
|
||||||
|
dmt->record_timestamp = 0;
|
||||||
|
|
||||||
return dmt;
|
return dmt;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,8 @@ int dm_timestamp_get(struct dm_timestamp *ts)
|
|||||||
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &ts->t)) {
|
if (clock_gettime(CLOCK_MONOTONIC, &ts->t)) {
|
||||||
log_sys_error("clock_gettime", "get_timestamp");
|
log_sys_error("clock_gettime", "get_timestamp");
|
||||||
|
ts->t.tv_sec = 0;
|
||||||
|
ts->t.tv_nsec = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +115,8 @@ int dm_timestamp_get(struct dm_timestamp *ts)
|
|||||||
|
|
||||||
if (gettimeofday(&ts->t, NULL)) {
|
if (gettimeofday(&ts->t, NULL)) {
|
||||||
log_sys_error("gettimeofday", "get_timestamp");
|
log_sys_error("gettimeofday", "get_timestamp");
|
||||||
|
ts->t.tv_sec = 0;
|
||||||
|
ts->t.tv_usec = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ static struct dm_report *_report;
|
|||||||
static report_type_t _report_type;
|
static report_type_t _report_type;
|
||||||
static dev_name_t _dev_name_type;
|
static dev_name_t _dev_name_type;
|
||||||
static uint32_t _count = 1; /* count of repeating reports */
|
static uint32_t _count = 1; /* count of repeating reports */
|
||||||
|
static struct dm_timestamp *_initial_timestamp = NULL;
|
||||||
|
|
||||||
#define NSEC_PER_USEC UINT64_C(1000)
|
#define NSEC_PER_USEC UINT64_C(1000)
|
||||||
#define NSEC_PER_MSEC UINT64_C(1000000)
|
#define NSEC_PER_MSEC UINT64_C(1000000)
|
||||||
@ -309,6 +310,24 @@ struct dmsetup_report_obj {
|
|||||||
struct dm_split_name *split_name;
|
struct dm_split_name *split_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int _task_run(struct dm_task *dmt)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
uint64_t delta;
|
||||||
|
|
||||||
|
if (_initial_timestamp)
|
||||||
|
dm_task_set_record_timestamp(dmt);
|
||||||
|
|
||||||
|
r = dm_task_run(dmt);
|
||||||
|
|
||||||
|
if (_initial_timestamp) {
|
||||||
|
delta = dm_timestamp_delta(dm_task_get_ioctl_timestamp(dmt), _initial_timestamp);
|
||||||
|
log_debug("Timestamp: %7" PRIu64 ".%09" PRIu64 " seconds", delta / NSEC_PER_SEC, delta % NSEC_PER_SEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static struct dm_task *_get_deps_task(int major, int minor)
|
static struct dm_task *_get_deps_task(int major, int minor)
|
||||||
{
|
{
|
||||||
struct dm_task *dmt;
|
struct dm_task *dmt;
|
||||||
@ -330,7 +349,7 @@ static struct dm_task *_get_deps_task(int major, int minor)
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info))
|
if (!dm_task_get_info(dmt, &info))
|
||||||
@ -601,7 +620,7 @@ static int _load(CMD_ARGS)
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
@ -687,7 +706,7 @@ static int _create(CMD_ARGS)
|
|||||||
udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
|
udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
|
||||||
|
|
||||||
if (!dm_task_set_cookie(dmt, &cookie, udev_flags) ||
|
if (!dm_task_set_cookie(dmt, &cookie, udev_flags) ||
|
||||||
!dm_task_run(dmt))
|
!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
@ -743,7 +762,7 @@ static int _do_rename(const char *name, const char *new_name, const char *new_uu
|
|||||||
udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
|
udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
|
||||||
|
|
||||||
if (!dm_task_set_cookie(dmt, &cookie, udev_flags) ||
|
if (!dm_task_set_cookie(dmt, &cookie, udev_flags) ||
|
||||||
!dm_task_run(dmt))
|
!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
@ -833,7 +852,7 @@ static int _message(CMD_ARGS)
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if ((response = dm_task_get_message_response(dmt))) {
|
if ((response = dm_task_get_message_response(dmt))) {
|
||||||
@ -882,7 +901,7 @@ static int _setgeometry(CMD_ARGS)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* run the task */
|
/* run the task */
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
@ -1322,7 +1341,7 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)
|
|||||||
if (_switches[DEFERRED_ARG] && (task == DM_DEVICE_REMOVE || task == DM_DEVICE_REMOVE_ALL))
|
if (_switches[DEFERRED_ARG] && (task == DM_DEVICE_REMOVE || task == DM_DEVICE_REMOVE_ALL))
|
||||||
dm_task_deferred_remove(dmt);
|
dm_task_deferred_remove(dmt);
|
||||||
|
|
||||||
r = dm_task_run(dmt);
|
r = _task_run(dmt);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (!_udev_cookie && udev_wait_flag)
|
if (!_udev_cookie && udev_wait_flag)
|
||||||
@ -1383,7 +1402,7 @@ static int _process_all(const struct command *cmd, const char *subcommand, int a
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt)) {
|
if (!_task_run(dmt)) {
|
||||||
r = 0;
|
r = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1434,7 +1453,7 @@ static uint64_t _get_device_size(const char *name)
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info) || !info.exists)
|
if (!dm_task_get_info(dmt, &info) || !info.exists)
|
||||||
@ -1483,7 +1502,7 @@ static int _error_device(CMD_ARGS)
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!_simple(DM_DEVICE_RESUME, name, 0, 0)) {
|
if (!_simple(DM_DEVICE_RESUME, name, 0, 0)) {
|
||||||
@ -1671,7 +1690,7 @@ static int _status(CMD_ARGS)
|
|||||||
if (_switches[NOFLUSH_ARG] && !dm_task_no_flush(dmt))
|
if (_switches[NOFLUSH_ARG] && !dm_task_no_flush(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info) || !info.exists)
|
if (!dm_task_get_info(dmt, &info) || !info.exists)
|
||||||
@ -1747,7 +1766,7 @@ static int _targets(CMD_ARGS)
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
target = dm_task_get_versions(dmt);
|
target = dm_task_get_versions(dmt);
|
||||||
@ -1799,7 +1818,7 @@ static int _info(CMD_ARGS)
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = _display_info(dmt);
|
r = _display_info(dmt);
|
||||||
@ -1843,7 +1862,7 @@ static int _deps(CMD_ARGS)
|
|||||||
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info))
|
if (!dm_task_get_info(dmt, &info))
|
||||||
@ -3001,7 +3020,7 @@ static int _mangle(CMD_ARGS)
|
|||||||
if (!_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
if (!_switches[CHECKS_ARG] && !dm_task_enable_checks(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!_task_run(dmt))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info) || !info.exists)
|
if (!dm_task_get_info(dmt, &info) || !info.exists)
|
||||||
@ -3808,8 +3827,17 @@ static int _process_switches(int *argcp, char ***argvp, const char *dev_dir)
|
|||||||
_switches[VERSION_ARG]++;
|
_switches[VERSION_ARG]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_switches[VERBOSE_ARG] > 1)
|
if (_switches[VERBOSE_ARG] > 1) {
|
||||||
dm_log_init_verbose(_switches[VERBOSE_ARG] - 1);
|
dm_log_init_verbose(_switches[VERBOSE_ARG] - 1);
|
||||||
|
if (_switches[VERBOSE_ARG] > 2) {
|
||||||
|
if (!(_initial_timestamp = dm_timestamp_alloc()))
|
||||||
|
stack;
|
||||||
|
else if (!dm_timestamp_get(_initial_timestamp))
|
||||||
|
stack;
|
||||||
|
else
|
||||||
|
log_debug("Timestamp: 0.000000000 seconds");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((_switches[MAJOR_ARG] && !_switches[MINOR_ARG]) ||
|
if ((_switches[MAJOR_ARG] && !_switches[MINOR_ARG]) ||
|
||||||
(!_switches[MAJOR_ARG] && _switches[MINOR_ARG])) {
|
(!_switches[MAJOR_ARG] && _switches[MINOR_ARG])) {
|
||||||
@ -3960,5 +3988,8 @@ out:
|
|||||||
|
|
||||||
dm_free(_table);
|
dm_free(_table);
|
||||||
|
|
||||||
|
if (_initial_timestamp)
|
||||||
|
dm_timestamp_destroy(_initial_timestamp);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user