[lvm-devel] [PATCH 5/6][devname mangling] Add support for decoding mangled strings and add a new field for "dmsetup info"
Peter Rajnoha
prajnoha at redhat.com
Fri Oct 14 14:59:46 UTC 2011
Add support for decoding mangled string back to a human readable form
(at least if the character is printable :)), accomplished with a new
libdemapper helper function "dm_string_mangle_decode".
Use it to decode the "Name" and show also a new "Name (unmangled)" field
in dmsetup info/dmsetup info -c output. For dmsetup info -c -o, the
new column name is called "name_unmangled".
Peter
---
libdm/libdevmapper.h | 3 +++
libdm/libdm-common.c | 41 +++++++++++++++++++++++++++++++++++++++++
tools/dmsetup.c | 26 ++++++++++++++++++++++++--
3 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index fb4b2cb..fb6ad22 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -270,6 +270,9 @@ dm_string_mangle_t dm_get_default_name_mangle(void);
int dm_task_set_name_mangle(struct dm_task *dmt, dm_string_mangle_t name_mangle);
dm_string_mangle_t dm_task_get_name_mangle(struct dm_task *dmt);
+int dm_string_mangle_decode(dm_string_mangle_t type, const char *mangled_str,
+ char *buf, size_t buf_len);
+
/*
* Configure the device-mapper directory
*/
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index e836661..fe0003d 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -306,6 +306,47 @@ static int _is_whitelisted_char(char c)
return 0;
}
+int dm_string_mangle_decode(dm_string_mangle_t type, const char *mangled_str,
+ char *buf, size_t buf_len)
+{
+ size_t i, j;
+ int code;
+ char str[DM_NAME_LEN];
+
+ if (buf_len < DM_NAME_LEN) {
+ log_error("dm_string_mangle_decode \"%s\": "
+ "output buffer too small", mangled_str);
+ goto bad;
+ }
+
+ if (type == DM_STRING_MANGLE_NONE) {
+ strcpy(buf, mangled_str);
+ return 1;
+ }
+
+ for (i = 0, j = 0; mangled_str[i]; i++) {
+ if (mangled_str[i] == '\\' && mangled_str[i+1] == 'x') {
+ if (!sscanf(&mangled_str[i+2], "%2x%s", &code, str)) {
+ log_error("Improperly encoded string %s", mangled_str);
+ goto bad;
+ }
+ buf[j] = (unsigned char) code;
+ i+= 3; j++;
+ }
+ else {
+ buf[j] = mangled_str[i];
+ j++;
+ }
+ }
+
+ buf[j] = '\0';
+ return 1;
+
+bad:
+ buf[0] = '\0';
+ return 0;
+}
+
/*
* Encode all characters in the input string which are not on a whitelist
* with '\xNN' format where NN is the hex value of the character.
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index a733dcd..0187a2f 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -441,13 +441,20 @@ static void _display_info_long(struct dm_task *dmt, struct dm_info *info)
{
const char *uuid;
uint32_t read_ahead;
+ char buf[PATH_MAX];
+ const char *name;
if (!info->exists) {
printf("Device does not exist.\n");
return;
}
- printf("Name: %s\n", dm_task_get_name(dmt));
+ name = dm_task_get_name(dmt);
+ printf("Name: %s\n", name);
+
+ if (!dm_string_mangle_decode(DM_STRING_MANGLE_HEX, name, buf, PATH_MAX))
+ log_error("Could not unmangle device name");
+ printf("Name (unmangled): %s\n", buf);
printf("State: %s%s\n",
info->suspended ? "SUSPENDED" : "ACTIVE",
@@ -475,7 +482,7 @@ static void _display_info_long(struct dm_task *dmt, struct dm_info *info)
printf("Number of targets: %d\n", info->target_count);
if ((uuid = dm_task_get_uuid(dmt)) && *uuid)
- printf("UUID: %s\n", uuid);
+ printf("UUID: %s\n", uuid);
printf("\n");
}
@@ -2225,6 +2232,20 @@ static int _dm_name_disp(struct dm_report *rh,
return dm_report_field_string(rh, field, &name);
}
+static int _dm_name_unmangled_disp(struct dm_report *rh,
+ struct dm_pool *mem __attribute__((unused)),
+ struct dm_report_field *field, const void *data,
+ void *private __attribute__((unused)))
+{
+ const char *name = dm_task_get_name((const struct dm_task *) data);
+ char buf[PATH_MAX];
+ const char *p = buf;
+
+ dm_string_mangle_decode(DM_STRING_MANGLE_HEX, name, buf, PATH_MAX);
+
+ return dm_report_field_string(rh, field, &p);
+}
+
static int _dm_uuid_disp(struct dm_report *rh,
struct dm_pool *mem __attribute__((unused)),
struct dm_report_field *field,
@@ -2605,6 +2626,7 @@ static const struct dm_report_object_type _report_types[] = {
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, "Name (unmangled)", 18, dm_name_unmangled, "name_unmangled", "Name of mapped device (unmangled).")
FIELD_F(TASK, STR, "UUID", 32, dm_uuid, "uuid", "Unique (optional) identifier for mapped device.")
/* FIXME Next one should be INFO */
More information about the lvm-devel
mailing list