mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
Migrate dmsetup column-based output over to new libdevmapper report framework.
This commit is contained in:
parent
84e348fade
commit
d6d597e3dd
@ -1,5 +1,6 @@
|
|||||||
Version 1.02.16 -
|
Version 1.02.16 -
|
||||||
===================================
|
===================================
|
||||||
|
Migrate dmsetup column-based output over to new libdevmapper report framework.
|
||||||
Add descriptions to reporting field definitions.
|
Add descriptions to reporting field definitions.
|
||||||
Add a dso-private variable to dmeventd dso interface.
|
Add a dso-private variable to dmeventd dso interface.
|
||||||
Add dm_event_handler_[gs]et_timeout functions.
|
Add dm_event_handler_[gs]et_timeout functions.
|
||||||
|
296
tools/dmsetup.c
296
tools/dmsetup.c
@ -136,10 +136,22 @@ static char *_table;
|
|||||||
static char *_target;
|
static char *_target;
|
||||||
static char *_command;
|
static char *_command;
|
||||||
static struct dm_tree *_dtree;
|
static struct dm_tree *_dtree;
|
||||||
|
static struct dm_report *_report;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Commands
|
* Commands
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef int (*command_fn) (int argc, char **argv, void *data);
|
||||||
|
|
||||||
|
struct command {
|
||||||
|
const char *name;
|
||||||
|
const char *help;
|
||||||
|
int min_args;
|
||||||
|
int max_args;
|
||||||
|
command_fn fn;
|
||||||
|
};
|
||||||
|
|
||||||
static int _parse_line(struct dm_task *dmt, char *buffer, const char *file,
|
static int _parse_line(struct dm_task *dmt, char *buffer, const char *file,
|
||||||
int line)
|
int line)
|
||||||
{
|
{
|
||||||
@ -224,66 +236,27 @@ static int _parse_file(struct dm_task *dmt, const char *file)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _display_info_cols_noheadings(struct dm_task *dmt,
|
struct dmsetup_report_obj {
|
||||||
struct dm_info *info)
|
struct dm_task *task;
|
||||||
|
struct dm_info *info;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _display_info_cols(struct dm_task *dmt, struct dm_info *info)
|
||||||
{
|
{
|
||||||
const char *uuid;
|
struct dmsetup_report_obj obj;
|
||||||
|
|
||||||
if (!info->exists)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uuid = dm_task_get_uuid(dmt);
|
|
||||||
|
|
||||||
if (_switches[OPTIONS_ARG])
|
|
||||||
printf("%s\n", dm_task_get_name(dmt));
|
|
||||||
else
|
|
||||||
printf("%s:%d:%d:%s%s%s%s:%d:%d:%" PRIu32 ":%s\n",
|
|
||||||
dm_task_get_name(dmt),
|
|
||||||
info->major, info->minor,
|
|
||||||
info->live_table ? "L" : "-",
|
|
||||||
info->inactive_table ? "I" : "-",
|
|
||||||
info->suspended ? "s" : "-",
|
|
||||||
info->read_only ? "r" : "w",
|
|
||||||
info->open_count, info->target_count, info->event_nr,
|
|
||||||
uuid && *uuid ? uuid : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _display_info_cols(struct dm_task *dmt, struct dm_info *info)
|
|
||||||
{
|
|
||||||
static int _headings = 0;
|
|
||||||
const char *uuid;
|
|
||||||
|
|
||||||
if (!info->exists) {
|
if (!info->exists) {
|
||||||
printf("Device does not exist.\n");
|
fprintf(stderr, "Device does not exist.\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_headings) {
|
obj.task = dmt;
|
||||||
if (_switches[OPTIONS_ARG])
|
obj.info = info;
|
||||||
printf("Name\n");
|
|
||||||
else
|
|
||||||
printf("Name Maj Min Stat Open Targ "
|
|
||||||
"Event UUID\n");
|
|
||||||
_headings = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_switches[OPTIONS_ARG])
|
if (!dm_report_object(_report, &obj))
|
||||||
printf("%s\n", dm_task_get_name(dmt));
|
return 0;
|
||||||
else {
|
|
||||||
printf("%-16s %3d %3d %s%s%s%s %4d %4d %6" PRIu32 " ",
|
|
||||||
dm_task_get_name(dmt),
|
|
||||||
info->major, info->minor,
|
|
||||||
info->live_table ? "L" : "-",
|
|
||||||
info->inactive_table ? "I" : "-",
|
|
||||||
info->suspended ? "s" : "-",
|
|
||||||
info->read_only ? "r" : "w",
|
|
||||||
info->open_count, info->target_count, info->event_nr);
|
|
||||||
|
|
||||||
if ((uuid = dm_task_get_uuid(dmt)) && *uuid)
|
return 1;
|
||||||
printf("%s", uuid);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _display_info_long(struct dm_task *dmt, struct dm_info *info)
|
static void _display_info_long(struct dm_task *dmt, struct dm_info *info)
|
||||||
@ -333,9 +306,8 @@ static int _display_info(struct dm_task *dmt)
|
|||||||
|
|
||||||
if (!_switches[COLS_ARG])
|
if (!_switches[COLS_ARG])
|
||||||
_display_info_long(dmt, &info);
|
_display_info_long(dmt, &info);
|
||||||
else if (_switches[NOHEADINGS_ARG])
|
|
||||||
_display_info_cols_noheadings(dmt, &info);
|
|
||||||
else
|
else
|
||||||
|
/* FIXME return code */
|
||||||
_display_info_cols(dmt, &info);
|
_display_info_cols(dmt, &info);
|
||||||
|
|
||||||
return info.exists ? 1 : 0;
|
return info.exists ? 1 : 0;
|
||||||
@ -1498,6 +1470,194 @@ static int _tree(int argc, char **argv, void *data __attribute((unused)))
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Report device information
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* dm specific display functions */
|
||||||
|
|
||||||
|
static int _int32_disp(struct dm_report *rh,
|
||||||
|
struct dm_pool *mem __attribute((unused)),
|
||||||
|
struct dm_report_field *field, const void *data,
|
||||||
|
void *private)
|
||||||
|
{
|
||||||
|
const int32_t value = *(const int32_t *)data;
|
||||||
|
|
||||||
|
return dm_report_field_int32(rh, field, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _uint32_disp(struct dm_report *rh,
|
||||||
|
struct dm_pool *mem __attribute((unused)),
|
||||||
|
struct dm_report_field *field, const void *data,
|
||||||
|
void *private)
|
||||||
|
{
|
||||||
|
const uint32_t value = *(const int32_t *)data;
|
||||||
|
|
||||||
|
return dm_report_field_uint32(rh, field, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _dm_name_disp(struct dm_report *rh,
|
||||||
|
struct dm_pool *mem __attribute((unused)),
|
||||||
|
struct dm_report_field *field, const void *data,
|
||||||
|
void *private)
|
||||||
|
{
|
||||||
|
const char *name = dm_task_get_name((struct dm_task *) data);
|
||||||
|
|
||||||
|
return dm_report_field_string(rh, field, &name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _dm_uuid_disp(struct dm_report *rh,
|
||||||
|
struct dm_pool *mem __attribute((unused)),
|
||||||
|
struct dm_report_field *field,
|
||||||
|
const void *data, void *private)
|
||||||
|
{
|
||||||
|
const char *uuid = dm_task_get_uuid((struct dm_task *) data);
|
||||||
|
|
||||||
|
if (!uuid || !*uuid)
|
||||||
|
uuid = "";
|
||||||
|
|
||||||
|
return dm_report_field_string(rh, field, &uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _dm_info_status_disp(struct dm_report *rh,
|
||||||
|
struct dm_pool *mem __attribute((unused)),
|
||||||
|
struct dm_report_field *field, const void *data,
|
||||||
|
void *private)
|
||||||
|
{
|
||||||
|
char buf[5];
|
||||||
|
const char *s = buf;
|
||||||
|
struct dm_info *info = (struct dm_info *) data;
|
||||||
|
|
||||||
|
buf[0] = info->live_table ? 'L' : '-';
|
||||||
|
buf[1] = info->inactive_table ? 'I' : '-';
|
||||||
|
buf[2] = info->suspended ? 's' : '-';
|
||||||
|
buf[3] = info->read_only ? 'r' : 'w';
|
||||||
|
buf[4] = '\0';
|
||||||
|
|
||||||
|
return dm_report_field_string(rh, field, &s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Report types */
|
||||||
|
enum { DR_TASK = 1, DR_INFO = 2 };
|
||||||
|
|
||||||
|
static void *_task_get_obj(void *obj)
|
||||||
|
{
|
||||||
|
return ((struct dmsetup_report_obj *)obj)->task;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *_info_get_obj(void *obj)
|
||||||
|
{
|
||||||
|
return ((struct dmsetup_report_obj *)obj)->info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dm_report_object_type _report_types[] = {
|
||||||
|
{ DR_TASK, "Mapped Device Name", "", _task_get_obj },
|
||||||
|
{ DR_INFO, "Mapped Device Information", "", _info_get_obj },
|
||||||
|
{ 0, "", "", NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Column definitions */
|
||||||
|
#define OFFSET_OF(strct, field) ((unsigned int) &((struct strct *)NULL)->field)
|
||||||
|
#define STR (DM_REPORT_FIELD_TYPE_STRING)
|
||||||
|
#define NUM (DM_REPORT_FIELD_TYPE_NUMBER)
|
||||||
|
#define FIELD_O(type, strct, sorttype, head, field, width, func, id, desc) {DR_ ## type, id, OFFSET_OF(strct, field), head, width, sorttype, &_ ## func ## _disp, desc},
|
||||||
|
#define FIELD_F(type, sorttype, head, width, func, id, desc) {DR_ ## type, id, 0, head, width, sorttype, &_ ## func ## _disp, desc},
|
||||||
|
|
||||||
|
static const struct dm_report_field_type _report_fields[] = {
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
FIELD_F(TASK, STR, "Name", 16, dm_name, "name", "Name of mapped device.")
|
||||||
|
FIELD_F(TASK, STR, "UUID", 32, dm_uuid, "uuid", "Unique identifier for mapped device (optional).")
|
||||||
|
FIELD_F(INFO, STR, "Stat", 4, dm_info_status, "status", "Attributes.")
|
||||||
|
FIELD_O(INFO, dm_info, NUM, "Maj", major, 3, int32, "major", "Major number.")
|
||||||
|
FIELD_O(INFO, dm_info, NUM, "Min", minor, 3, int32, "minor", "Minor number.")
|
||||||
|
FIELD_O(INFO, dm_info, NUM, "Open", open_count, 4, int32, "open_count", "Number of references to open device, if requested.")
|
||||||
|
FIELD_O(INFO, dm_info, NUM, "Targ", target_count, 4, int32, "target_count", "Number of segments in live table, if present.")
|
||||||
|
FIELD_O(INFO, dm_info, NUM, "Event", event_nr, 6, uint32, "event_nr", "Current event number.")
|
||||||
|
{0, "", 0, "", 0, 0, NULL, NULL},
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef STR
|
||||||
|
#undef NUM
|
||||||
|
#undef FIELD_O
|
||||||
|
#undef FIELD_F
|
||||||
|
|
||||||
|
static const char *default_report_options = "name,major,minor,status,open_count,target_count,event_nr,uuid";
|
||||||
|
|
||||||
|
static int _report_init(struct command *c)
|
||||||
|
{
|
||||||
|
char *options = (char *) default_report_options;
|
||||||
|
const char *keys = "";
|
||||||
|
const char *separator = " ";
|
||||||
|
int aligned = 1, headings = 1, buffered = 0;
|
||||||
|
uint32_t report_type = 0;
|
||||||
|
uint32_t flags = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
/* emulate old dmsetup behaviour */
|
||||||
|
if (_switches[NOHEADINGS_ARG]) {
|
||||||
|
separator = ":";
|
||||||
|
aligned = 0;
|
||||||
|
headings = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_switches[OPTIONS_ARG] && _string_args[OPTIONS_ARG]) {
|
||||||
|
if (*_string_args[OPTIONS_ARG] != '+')
|
||||||
|
options = _string_args[OPTIONS_ARG];
|
||||||
|
else {
|
||||||
|
len = strlen(default_report_options) +
|
||||||
|
strlen(_string_args[OPTIONS_ARG]);
|
||||||
|
if (!(options = dm_malloc(len))) {
|
||||||
|
err("Failed to allocate option string.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (dm_snprintf(options, len, "%s,%s",
|
||||||
|
default_report_options,
|
||||||
|
&_string_args[OPTIONS_ARG][1]) < 0) {
|
||||||
|
err("snprintf failed");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_switches[SORT_ARG] && _string_args[SORT_ARG]) {
|
||||||
|
keys = _string_args[SORT_ARG];
|
||||||
|
buffered = 1;
|
||||||
|
if (!strcmp(c->name, "status") || !strcmp(c->name, "table")) {
|
||||||
|
err("--sort is not yet supported with status and table");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_switches[SEPARATOR_ARG] && _string_args[SEPARATOR_ARG]) {
|
||||||
|
separator = _string_args[SEPARATOR_ARG];
|
||||||
|
aligned = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aligned)
|
||||||
|
flags |= DM_REPORT_OUTPUT_ALIGNED;
|
||||||
|
|
||||||
|
if (buffered)
|
||||||
|
flags |= DM_REPORT_OUTPUT_BUFFERED;
|
||||||
|
|
||||||
|
if (headings)
|
||||||
|
flags |= DM_REPORT_OUTPUT_HEADINGS;
|
||||||
|
|
||||||
|
if (!(_report = dm_report_init(&report_type,
|
||||||
|
_report_types, _report_fields,
|
||||||
|
options, separator, flags, keys, NULL)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (len)
|
||||||
|
dm_free(options);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List devices
|
* List devices
|
||||||
*/
|
*/
|
||||||
@ -1513,18 +1673,8 @@ static int _ls(int argc, char **argv, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dispatch table
|
* Dispatch table
|
||||||
*/
|
*/
|
||||||
typedef int (*command_fn) (int argc, char **argv, void *data);
|
|
||||||
|
|
||||||
struct command {
|
|
||||||
const char *name;
|
|
||||||
const char *help;
|
|
||||||
int min_args;
|
|
||||||
int max_args;
|
|
||||||
command_fn fn;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct command _commands[] = {
|
static struct command _commands[] = {
|
||||||
{"create", "<dev_name> [-j|--major <major> -m|--minor <minor>]\n"
|
{"create", "<dev_name> [-j|--major <major> -m|--minor <minor>]\n"
|
||||||
"\t [-U|--uid <uid>] [-G|--gid <gid>] [-M|--mode <octal_mode>]\n"
|
"\t [-U|--uid <uid>] [-G|--gid <gid>] [-M|--mode <octal_mode>]\n"
|
||||||
@ -2044,12 +2194,6 @@ static int _process_switches(int *argc, char ***argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_switches[COLS_ARG] && _switches[OPTIONS_ARG] &&
|
|
||||||
strcmp(_string_args[OPTIONS_ARG], "name")) {
|
|
||||||
fprintf(stderr, "Only -o name is supported so far.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_switches[TREE_ARG] && !_process_tree_options(_string_args[OPTIONS_ARG]))
|
if (_switches[TREE_ARG] && !_process_tree_options(_string_args[OPTIONS_ARG]))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -2098,6 +2242,9 @@ int main(int argc, char **argv)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_switches[COLS_ARG] && !_report_init(c))
|
||||||
|
goto out;
|
||||||
|
|
||||||
doit:
|
doit:
|
||||||
if (!c->fn(argc, argv, NULL)) {
|
if (!c->fn(argc, argv, NULL)) {
|
||||||
fprintf(stderr, "Command failed\n");
|
fprintf(stderr, "Command failed\n");
|
||||||
@ -2107,5 +2254,10 @@ int main(int argc, char **argv)
|
|||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (_report) {
|
||||||
|
dm_report_output(_report);
|
||||||
|
dm_report_free(_report);
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user