From: "Jun'ichi Nomura" <j-nomura@ce.jp.nec.com>
To: device-mapper development <dm-devel@redhat.com>,
LVM2 development <lvm-devel@redhat.com>
Subject: [PATCH] (2/4) dmsetup info to use dm_report
Date: Fri, 12 Jan 2007 18:31:45 -0500 [thread overview]
Message-ID: <45A81A61.4070401@ce.jp.nec.com> (raw)
In-Reply-To: <45A81618.2080608@ce.jp.nec.com>
[-- Attachment #1: Type: text/plain, Size: 1504 bytes --]
Hi,
This patch makes "dmsetup info -c" to use dm_report
in libdevmapper.
For example, to see what maps are overlaying on each map,
# dmsetup info -c -o name,parents_count,parent_maps -O name
Name Parents Parent Maps
B8-root 0
B9-root 0
d1 2 testvg-m1_mimage_0,testvg-lvol2
d2 2 testvg-m1_mimage_1,testvg-lvol2
d3 1 testvg-lvol0-real
d4 2 testvg-lvol2,testvg-lvol0-real
d5 1 testvg-lvol1-cow
d6 1 testvg-lvol2
d7 1 testvg-m1_mlog
testvg-lvol0 0
testvg-lvol0-real 2 testvg-lvol1,testvg-lvol0
testvg-lvol1 0
testvg-lvol1-cow 1 testvg-lvol1
testvg-lvol2 0
testvg-m1 0
testvg-m1_mimage_0 1 testvg-m1
testvg-m1_mimage_1 1 testvg-m1
testvg-m1_mlog 1 testvg-m1
Then, to see the top level map names,
# dmsetup info -c -o name,-parents_count=0 --noheadings
B9-root
testvg-m1
testvg-lvol2
testvg-lvol1
testvg-lvol0
B8-root
Output of "dmsetup info -c" is basically same as the former version
except for a few spacing difference, which should be harmless.
- Field width is correctly aligned (e.g. in case of long map name)
- Trailing space is added to fill the width
(same behaviour as LVM2 lvs/pvs/vgs)
Thanks,
--
Jun'ichi Nomura, NEC Corporation of America
[-- Attachment #2: 02-dmsetup-report.patch --]
[-- Type: text/x-patch, Size: 17162 bytes --]
Extend "dmsetup info -c -o" using dm_report API.
New options "-O" and "--seprator" are also added.
Usage:
dmsetup info -c -o <field1>[,<field2>...] \
[-O <field>[,<field>...]
[--separator <string>]
Combination of the following field name is allowed:
name
device
major
minor
uuid
status
open_count
target_count
event_nr
deps
deps_count
parents
parents_count
parent_maps
Examples:
If you have the following dm tree:
# dmsetup ls --tree -o inverted
(7:0)
|-d4 (254:6)
| |-testvg-lvol2 (254:17)
| `-testvg-lvol0-real (254:15)
| |-testvg-lvol1 (254:14)
| `-testvg-lvol0 (254:13)
|-d1 (254:3)
| |-testvg-m1_mimage_0 (254:10)
| | `-testvg-m1 (254:12)
| `-testvg-lvol2 (254:17)
|-d3 (254:5)
| `-testvg-lvol0-real (254:15)
| |-testvg-lvol1 (254:14)
| `-testvg-lvol0 (254:13)
|-d2 (254:4)
| |-testvg-m1_mimage_1 (254:11)
| | `-testvg-m1 (254:12)
| `-testvg-lvol2 (254:17)
|-d7 (254:9)
| `-testvg-m1_mlog (254:0)
| `-testvg-m1 (254:12)
|-d6 (254:8)
| `-testvg-lvol2 (254:17)
`-d5 (254:7)
`-testvg-lvol1-cow (254:16)
`-testvg-lvol1 (254:14)
(8:48)
`-asr_HOSTRAID1 (254:18)
|-asr_HOSTRAID15 (254:22)
|-asr_HOSTRAID13 (254:21)
|-asr_HOSTRAID12 (254:20)
`-asr_HOSTRAID11 (254:19)
(8:32)
`-asr_HOSTRAID1 (254:18)
|-asr_HOSTRAID15 (254:22)
|-asr_HOSTRAID13 (254:21)
|-asr_HOSTRAID12 (254:20)
`-asr_HOSTRAID11 (254:19)
To obtain the sorted list of the maps which have no parent maps:
# dmsetup info -c -o 'name,-parents_count=0' --noheadings -O name
asr_HOSTRAID11
asr_HOSTRAID12
asr_HOSTRAID13
asr_HOSTRAID15
testvg-lvol0
testvg-lvol1
testvg-lvol2
testvg-m1
Output of "dmsetup info -c" is basically same as the former version
except for a few spacing difference, which should be harmless.
- Field width is correctly aligned (e.g. in case of long map name)
- Trailing space is added to fill the width
(same behaviour as LVM2 lvs/pvs/vgs)
Index: device-mapper/dmsetup/dmsetup.c
===================================================================
--- device-mapper.orig/dmsetup/dmsetup.c 2007-01-12 16:50:37.000000000 -0500
+++ device-mapper/dmsetup/dmsetup.c 2007-01-12 17:03:45.000000000 -0500
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2005 NEC Corperation
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2005-2007 NEC Corperation
*
* This file is part of the device-mapper userspace tools.
*
@@ -114,7 +114,9 @@ enum {
NOOPENCOUNT_ARG,
NOTABLE_ARG,
OPTIONS_ARG,
+ SEPARATOR_ARG,
SHOWKEYS_ARG,
+ SORTKEYS_ARG,
TABLE_ARG,
TARGET_ARG,
TREE_ARG,
@@ -129,11 +131,12 @@ static int _switches[NUM_SWITCHES];
static int _values[NUM_SWITCHES];
static int _num_devices;
static char *_uuid;
-static char *_fields;
+static char *_fields[NUM_SWITCHES];
static char *_table;
static char *_target;
static char *_command;
static struct dm_tree *_dtree;
+static struct dm_report *_rhandle;
/*
* Commands
@@ -322,6 +325,8 @@ static void _display_info_long(struct dm
printf("\n");
}
+static int _report(int argc, char **argv, void *data);
+
static int _display_info(struct dm_task *dmt)
{
struct dm_info info;
@@ -1056,6 +1061,12 @@ static int _info(int argc, char **argv,
struct dm_names *names = (struct dm_names *) data;
char *name = NULL;
+ /*
+ * Using reporter function
+ */
+ if (_switches[COLS_ARG])
+ return _report(argc, argv, data);
+
if (data)
name = names->name;
else {
@@ -1506,6 +1517,414 @@ static int _ls(int argc, char **argv, vo
return _process_all(argc, argv, 0, _display_name);
}
+
+/*
+ * Report device information
+ */
+
+/* dm specific display functions */
+
+static int _dm_name_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field, const void *data)
+{
+ const char *name = dm_task_get_name((struct dm_task *) data);
+
+ return dm_report_field_string(rh, mem, field, &name);
+}
+
+static int _dm_uuid_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data)
+{
+ const char *uuid = dm_task_get_uuid((struct dm_task *) data);
+
+ if (!uuid || !*uuid)
+ uuid = "";
+
+ return dm_report_field_string(rh, mem, field, &uuid);
+}
+
+static int _dm_info_status_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field, const void *data)
+{
+ char buf[5], *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, mem, field, &s);
+}
+
+#define MAJ_MIN_LEN 32
+
+static int _dm_info_device_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field, const void *data)
+{
+ char *repstr;
+ struct dm_info *info = (struct dm_info *) data;
+
+ if (!(repstr = dm_pool_zalloc(mem, MAJ_MIN_LEN))) {
+ log_error("dm_pool_alloc failed");
+ return 0;
+ }
+
+ if (dm_snprintf(repstr, MAJ_MIN_LEN, "%d:%d",
+ info->major, info->minor) < 0) {
+ dm_pool_free(mem, repstr);
+ log_error("dm_pool_alloc failed");
+ return 0;
+ }
+
+ return dm_report_field_raw(rh, mem, field, repstr);
+}
+
+static int _dm_tree_parent_maps_disp(struct dm_report *rh,
+ struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data)
+{
+ struct dm_tree_node *node = (struct dm_tree_node *) data, *parent;
+ void *t = NULL;
+ const char *name;
+ int first_node = 1;
+ char *repstr;
+
+ if (!dm_pool_begin_object(mem, 256)) {
+ log_error("dm_pool_begin_object failed");
+ return 0;
+ }
+
+ while ((parent = dm_tree_next_child(&t, node, 1))) {
+ name = dm_tree_node_get_name(parent);
+ if (!name || !*name)
+ continue;
+ if (!first_node && !dm_pool_grow_object(mem, ",", 1)) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+ if (!dm_pool_grow_object(mem, name, strlen(name))) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+ if (first_node)
+ first_node = 0;
+ }
+
+ if (!dm_pool_grow_object(mem, "\0", 1)) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+
+ repstr = dm_pool_end_object(mem);
+ return dm_report_field_raw(rh, mem, field, repstr);
+
+ return 1;
+
+ out_abandon:
+ dm_pool_abandon_object(mem);
+ return 0;
+}
+
+static int _dm_tree_parents_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data)
+{
+ struct dm_tree_node *node = (struct dm_tree_node *) data, *parent;
+ void *t = NULL;
+ const struct dm_info *info;
+ int first_node = 1;
+ char buf[MAJ_MIN_LEN], *repstr;
+
+ if (!dm_pool_begin_object(mem, 256)) {
+ log_error("dm_pool_begin_object failed");
+ return 0;
+ }
+
+ while ((parent = dm_tree_next_child(&t, node, 1))) {
+ info = dm_tree_node_get_info(parent);
+ if (!info->major && !info->minor)
+ continue;
+ if (!first_node && !dm_pool_grow_object(mem, ",", 1)) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+ if (dm_snprintf(buf, MAJ_MIN_LEN, "%d:%d",
+ info->major, info->minor) < 0) {
+ log_error("dm_snprintf failed");
+ goto out_abandon;
+ }
+ if (!dm_pool_grow_object(mem, buf, strlen(buf))) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+ if (first_node)
+ first_node = 0;
+ }
+
+ if (!dm_pool_grow_object(mem, "\0", 1)) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+
+ repstr = dm_pool_end_object(mem);
+ return dm_report_field_raw(rh, mem, field, repstr);
+
+ out_abandon:
+ dm_pool_abandon_object(mem);
+ return 0;
+}
+
+static int _dm_tree_parents_count_disp(struct dm_report *rh,
+ struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data)
+{
+ struct dm_tree_node *node = (struct dm_tree_node *) data;
+ int num_parent = dm_tree_node_num_children(node, 1);
+
+ return dm_report_field_int(rh, mem, field, &num_parent);
+}
+
+static int _dm_deps_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field, const void *data)
+{
+ struct dm_deps *deps = (struct dm_deps *) data;
+ int i;
+ char buf[MAJ_MIN_LEN], *repstr;
+
+ if (!dm_pool_begin_object(mem, 256)) {
+ log_error("dm_pool_begin_object failed");
+ return 0;
+ }
+
+ for (i = 0; i < deps->count; i++) {
+ if (dm_snprintf(buf, sizeof(buf) - 1, "%d:%d",
+ (int) MAJOR(deps->device[i]),
+ (int) MINOR(deps->device[i])) < 0) {
+ log_error("dm_snprintf failed");
+ goto out_abandon;
+ }
+ if (!dm_pool_grow_object(mem, buf, strlen(buf))) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+ if (i + 1 < deps->count && !dm_pool_grow_object(mem, ",", 1)) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+ }
+
+ if (!dm_pool_grow_object(mem, "\0", 1)) {
+ log_error("dm_pool_grow_object failed");
+ goto out_abandon;
+ }
+
+ repstr = dm_pool_end_object(mem);
+ return dm_report_field_raw(rh, mem, field, repstr);
+
+ out_abandon:
+ dm_pool_abandon_object(mem);
+ return 0;
+}
+
+/* Report object types */
+
+#define DESC1 "Device Mapper Device"
+#define DESC2 "Dependency"
+#define PREFIX "dm_"
+enum { DR_TASK = 1, DR_INFO = 2, DR_DEPS = 4, DR_TREE = 8 };
+
+struct dmsetup_report_obj {
+ struct dm_task *task;
+ struct dm_info *info;
+ struct dm_tree_node *tree;
+};
+
+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 void *_tree_get_obj(void *obj)
+{
+ return ((struct dmsetup_report_obj *)obj)->tree;
+}
+
+static void *_deps_get_obj(void *obj)
+{
+ struct dm_task *dmt;
+
+ if (!(dmt = _task_get_obj((struct dmsetup_report_obj *)obj)))
+ return NULL;
+
+ return dm_task_get_deps(dmt);
+}
+
+static const struct dm_report_object_type _report_types[] = {
+ { DR_TASK, DESC1, PREFIX, _task_get_obj },
+ { DR_INFO, DESC1, PREFIX, _info_get_obj },
+ { DR_DEPS, DESC2, PREFIX, _deps_get_obj },
+ { DR_TREE, DESC2, PREFIX, _tree_get_obj },
+};
+
+/* Column definitions */
+static union {
+ struct dm_info _dm_info;
+ struct dm_deps _dm_deps;
+} _dummy;
+
+#define OFFSET_OF(struct, field) ((unsigned int) ((void *)&_dummy._ ## struct.field - (void *)&_dummy._ ## struct))
+#define STR (DM_REPORT_FIELD_STRING | DM_REPORT_FIELD_ALIGN_LEFT)
+#define NUM (DM_REPORT_FIELD_NUMBER | DM_REPORT_FIELD_ALIGN_RIGHT)
+#define FIELD_O(type, strct, sorttype, head, field, width, func, id) {DR_ ## type, id, OFFSET_OF(strct, field), head, width, sorttype, &dm_report_field_ ## func},
+#define FIELD_F(type, sorttype, head, width, func, id) {DR_ ## type, id, 0, head, width, sorttype, &_ ## func ## _disp},
+
+static const struct dm_report_field_type _report_fields[] = {
+/* *INDENT-OFF* */
+FIELD_F(TASK, STR, "Name", 16, dm_name, "name")
+FIELD_F(TASK, STR, "UUID", 32, dm_uuid, "uuid")
+FIELD_F(INFO, STR, "Stat", 4, dm_info_status, "status")
+FIELD_F(INFO, STR, "Device", 6, dm_info_device, "device")
+FIELD_O(INFO, dm_info, NUM, "Maj", major, 3, int32, "major")
+FIELD_O(INFO, dm_info, NUM, "Min", minor, 3, int32, "minor")
+FIELD_O(INFO, dm_info, NUM, "Open", open_count, 4, int32, "open_count")
+FIELD_O(INFO, dm_info, NUM, "Targ", target_count, 4, int32, "target_count")
+FIELD_O(INFO, dm_info, NUM, "Event", event_nr, 6, uint32, "event_nr")
+FIELD_O(DEPS, dm_deps, NUM, "Deps", count, 4, int32, "deps_count")
+FIELD_F(DEPS, STR, "Depend on", 10, dm_deps, "deps")
+FIELD_F(TREE, STR, "Parent Devices", 16, dm_tree_parents, "parents")
+FIELD_F(TREE, STR, "Parent Maps", 12, dm_tree_parent_maps, "parent_maps")
+FIELD_F(TREE, NUM, "Parents", 7, dm_tree_parents_count, "parents_count")
+/* *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 unsigned int _num_report_fields = sizeof(_report_fields) / sizeof(_report_fields[0]);
+static unsigned int _num_report_types = sizeof(_report_types) / sizeof(_report_types[0]);
+
+static int _do_report(int argc, char **argv, void *data)
+{
+ const char *name = NULL;
+ struct dm_task *dmt;
+ struct dm_info info;
+ int r = 0;
+ struct dmsetup_report_obj obj;
+
+ if (data) {
+ if (argc == 0)
+ name = dm_task_get_name((struct dm_task *)data);
+ else
+ name = ((struct dm_names *)data)->name;
+ } else {
+ if (argc == 1)
+ return _process_all(argc, argv, 0, _report);
+ if (argc == 2)
+ name = argv[1];
+ }
+
+ if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
+ return 0;
+
+ if (!_set_task_device(dmt, name, 0))
+ goto out;
+
+ if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
+ goto out;
+
+ if (!dm_task_run(dmt))
+ goto out;
+
+ if (!dm_task_get_info(dmt, &info))
+ goto out;
+
+ obj.task = dmt;
+ obj.info = &info;
+ obj.tree = dm_tree_find_node(_dtree, info.major, info.minor);
+ dm_report_object(_rhandle, &obj);
+
+ r = 1;
+
+ out:
+ dm_task_destroy(dmt);
+ return r;
+}
+
+static int _report(int argc, char **argv, void *data)
+{
+ char *options = (char *) default_report_options;
+ const char *keys = "";
+ const char *separator = " ";
+ int aligned = 1, buffered = 1;
+ int headings = !_switches[NOHEADINGS_ARG];
+ uint32_t report_type = 0;
+
+ if (_rhandle)
+ return _do_report(argc, argv, data);
+
+ if (!(_dtree = dm_tree_create()))
+ return 0;
+ if (!_process_all(argc, argv, 0, _add_dep))
+ return 0;
+
+ if (_switches[OPTIONS_ARG] && _fields[OPTIONS_ARG]) {
+ if (*_fields[OPTIONS_ARG] == '+') {
+ int len = strlen(default_report_options) +
+ strlen(_fields[OPTIONS_ARG]);
+ if (!(options = dm_malloc(len))) {
+ err("Failed to malloc option string.");
+ return 0;
+ }
+ if (dm_snprintf(options, len, "%s,%s",
+ default_report_options,
+ &_fields[OPTIONS_ARG][1]) < 0) {
+ err("snprintf failed");
+ return 0;
+ }
+ } else
+ options = _fields[OPTIONS_ARG];
+ }
+ if (_switches[SORTKEYS_ARG] && _fields[SORTKEYS_ARG])
+ keys = _fields[SORTKEYS_ARG];
+ if (_switches[SEPARATOR_ARG] && _fields[SEPARATOR_ARG]) {
+ separator = _fields[SEPARATOR_ARG];
+ aligned = 0;
+ }
+
+ if (!(_rhandle = dm_report_init(options, keys, &report_type,
+ separator, aligned, buffered, headings,
+ _report_fields, _num_report_fields,
+ _report_types, _num_report_types,
+ NULL)))
+ return 0;
+
+ _do_report(argc, argv, data);
+
+ dm_report_output(_rhandle);
+ dm_report_free(_rhandle);
+ _rhandle = NULL;
+
+ if (_dtree) {
+ dm_tree_free(_dtree);
+ _dtree = NULL;
+ }
+
+ return 1;
+}
+
/*
* dispatch table
*/
@@ -1884,7 +2303,9 @@ static int _process_switches(int *argc,
{"noopencount", 0, &ind, NOOPENCOUNT_ARG},
{"notable", 0, &ind, NOTABLE_ARG},
{"options", 1, &ind, OPTIONS_ARG},
+ {"separator", 1, &ind, SEPARATOR_ARG},
{"showkeys", 0, &ind, SHOWKEYS_ARG},
+ {"sortkeys", 1, &ind, SORTKEYS_ARG},
{"table", 1, &ind, TABLE_ARG},
{"target", 1, &ind, TARGET_ARG},
{"tree", 0, &ind, TREE_ARG},
@@ -1914,7 +2335,7 @@ static int _process_switches(int *argc,
_switches[OPTIONS_ARG]++;
_switches[MAJOR_ARG]++;
_switches[MINOR_ARG]++;
- _fields = (char *) "name";
+ _fields[OPTIONS_ARG] = (char *) "name";
if (*argc == 3) {
_values[MAJOR_ARG] = atoi((*argv)[1]);
@@ -1946,7 +2367,7 @@ static int _process_switches(int *argc,
optarg = 0;
optind = OPTIND_INIT;
- while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCfGj:m:Mno:ru:Uv",
+ while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCfGj:m:Mno:O:ru:Uv",
long_options, NULL)) != -1) {
if (c == ':' || c == '?')
return 0;
@@ -1968,7 +2389,15 @@ static int _process_switches(int *argc,
_switches[NOTABLE_ARG]++;
if (c == 'o' || ind == OPTIONS_ARG) {
_switches[OPTIONS_ARG]++;
- _fields = optarg;
+ _fields[OPTIONS_ARG] = optarg;
+ }
+ if (ind == SEPARATOR_ARG) {
+ _switches[SEPARATOR_ARG]++;
+ _fields[SEPARATOR_ARG] = optarg;
+ }
+ if (c == 'O' || ind == SORTKEYS_ARG) {
+ _switches[SORTKEYS_ARG]++;
+ _fields[SORTKEYS_ARG] = optarg;
}
if (c == 'v' || ind == VERBOSE_ARG)
_switches[VERBOSE_ARG]++;
@@ -2027,13 +2456,7 @@ static int _process_switches(int *argc,
return 0;
}
- if (_switches[COLS_ARG] && _switches[OPTIONS_ARG] &&
- strcmp(_fields, "name")) {
- fprintf(stderr, "Only -o name is supported so far.\n");
- return 0;
- }
-
- if (_switches[TREE_ARG] && !_process_tree_options(_fields))
+ if (_switches[TREE_ARG] && !_process_tree_options(_fields[OPTIONS_ARG]))
return 0;
if (_switches[TABLE_ARG] && _switches[NOTABLE_ARG]) {
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
To: lvm-devel@redhat.com
Subject: [PATCH] (2/4) dmsetup info to use dm_report
Date: Fri, 12 Jan 2007 18:31:45 -0500 [thread overview]
Message-ID: <45A81A61.4070401@ce.jp.nec.com> (raw)
In-Reply-To: <45A81618.2080608@ce.jp.nec.com>
Hi,
This patch makes "dmsetup info -c" to use dm_report
in libdevmapper.
For example, to see what maps are overlaying on each map,
# dmsetup info -c -o name,parents_count,parent_maps -O name
Name Parents Parent Maps
B8-root 0
B9-root 0
d1 2 testvg-m1_mimage_0,testvg-lvol2
d2 2 testvg-m1_mimage_1,testvg-lvol2
d3 1 testvg-lvol0-real
d4 2 testvg-lvol2,testvg-lvol0-real
d5 1 testvg-lvol1-cow
d6 1 testvg-lvol2
d7 1 testvg-m1_mlog
testvg-lvol0 0
testvg-lvol0-real 2 testvg-lvol1,testvg-lvol0
testvg-lvol1 0
testvg-lvol1-cow 1 testvg-lvol1
testvg-lvol2 0
testvg-m1 0
testvg-m1_mimage_0 1 testvg-m1
testvg-m1_mimage_1 1 testvg-m1
testvg-m1_mlog 1 testvg-m1
Then, to see the top level map names,
# dmsetup info -c -o name,-parents_count=0 --noheadings
B9-root
testvg-m1
testvg-lvol2
testvg-lvol1
testvg-lvol0
B8-root
Output of "dmsetup info -c" is basically same as the former version
except for a few spacing difference, which should be harmless.
- Field width is correctly aligned (e.g. in case of long map name)
- Trailing space is added to fill the width
(same behaviour as LVM2 lvs/pvs/vgs)
Thanks,
--
Jun'ichi Nomura, NEC Corporation of America
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 02-dmsetup-report.patch
Type: text/x-patch
Size: 17162 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/lvm-devel/attachments/20070112/47367b4c/attachment.bin>
next prev parent reply other threads:[~2007-01-12 23:31 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-12 23:13 [PATCH] (1/4) dm_report support in libdevmapper Jun'ichi Nomura
2007-01-12 23:13 ` Jun'ichi Nomura
2007-01-12 23:31 ` Jun'ichi Nomura [this message]
2007-01-12 23:31 ` [PATCH] (2/4) dmsetup info to use dm_report Jun'ichi Nomura
2007-01-12 23:31 ` [PATCH] (3/4) Remove old codes for "info -c" from dmsetup Jun'ichi Nomura
2007-01-12 23:31 ` Jun'ichi Nomura
2007-01-12 23:32 ` [PATCH] (4/4) LVM2 to use dm_report Jun'ichi Nomura
2007-01-12 23:32 ` Jun'ichi Nomura
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45A81A61.4070401@ce.jp.nec.com \
--to=j-nomura@ce.jp.nec.com \
--cc=dm-devel@redhat.com \
--cc=lvm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.