Device mapper device UUID (alongside with device name) is an unique
characteristic of device. However libldm didn't set device UUID. Also
"dmsetup" user space tool has "mangle" command which issue a warning
if
device doesn't have UUID. Let's set UUID for created devices to be
consistent with DM devices created by other subsystems.
Device mapper device UUID is an arbitrary string conventionally prefixed
with UUID prefix which is a short capitalised prefix indicating the
subsystem that is managing the devices, e.g. "LVM-" or "MPATH-".
"LDM-"
prefix is used for device created by libldm.
Partition UUID is composed in a form
"LDM-<partition_name>-<disk_guid>".
Disk GUID should be unique a cross disks and LDM partition name is
unique within a disk. So, overall generated UUID should be unique.
Volume UUID is composed in a form
"LDM-<volume_name>-<volume_guid>".
Volume GUID should be unique a cross all LDM volumes. So, overall
generated UUID should be unique (despite LDM volume name).
---
src/ldm.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 62 insertions(+), 7 deletions(-)
diff --git a/src/ldm.c b/src/ldm.c
index c701cbd..02378f8 100644
--- a/src/ldm.c
+++ b/src/ldm.c
@@ -39,6 +39,8 @@
#include "gpt.h"
#include "ldm.h"
+#define DM_UUID_PREFIX "LDM-"
+
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-" \
"%02x%02x-%02x%02x%02x%02x%02x%02x"
#define UUID_VALS(uuid) (uuid)[0], (uuid)[1], (uuid)[2], (uuid)[3], \
@@ -294,6 +296,7 @@ ldm_init(LDM * const o)
bzero(o->priv, sizeof(*o->priv));
dm_set_name_mangling_mode(DM_STRING_MANGLING_AUTO);
+ dm_set_uuid_prefix(DM_UUID_PREFIX);
}
static void
@@ -2391,6 +2394,21 @@ _dm_part_name(const LDMPartitionPrivate * const part)
return name;
}
+static GString *
+_dm_part_uuid(const LDMPartitionPrivate * const part)
+{
+ const LDMDiskPrivate * const disk = part->disk->priv;
+
+ char ldm_disk_guid[37];
+ uuid_unparse_lower(disk->guid, ldm_disk_guid);
+
+ GString * dm_uuid = g_string_new("");
+ g_string_printf(dm_uuid, "%s%s-%s",
+ DM_UUID_PREFIX, part->name, ldm_disk_guid);
+
+ return dm_uuid;
+}
+
static GString *
_dm_vol_name(const LDMVolumePrivate * const vol)
{
@@ -2399,6 +2417,19 @@ _dm_vol_name(const LDMVolumePrivate * const vol)
return r;
}
+static GString *
+_dm_vol_uuid(const LDMVolumePrivate * const vol)
+{
+ char ldm_vol_uuid[37];
+ uuid_unparse_lower(vol->guid, ldm_vol_uuid);
+
+ GString * dm_uuid = g_string_new("");
+ g_string_printf(dm_uuid, "%s%s-%s",
+ DM_UUID_PREFIX, vol->name, ldm_vol_uuid);
+
+ return dm_uuid;
+}
+
/* We catch log messages generated by device mapper with errno != 0 and store
* them here */
static int _dm_err_last_level = 0;
@@ -2503,8 +2534,9 @@ _find_device_tree_node(struct dm_tree * const tree,
}
gboolean
-_dm_create(const gchar * const name, uint32_t udev_cookie,
- const guint n_targets, const struct dm_target * const targets,
+_dm_create(const gchar * const name, const gchar * const uuid,
+ uint32_t udev_cookie, const guint n_targets,
+ const struct dm_target * const targets,
GString **mangled_name, GError ** const err)
{
gboolean r = TRUE;
@@ -2526,6 +2558,13 @@ _dm_create(const gchar * const name, uint32_t udev_cookie,
r = FALSE; goto out;
}
+ if (!dm_task_set_uuid(task, uuid)) {
+ g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL,
+ "DM_DEVICE_CREATE: dm_task_set_uuid(%s) failed: %s",
+ uuid, _dm_err_last_msg);
+ r = FALSE; goto out;
+ }
+
for (guint i = 0; i < n_targets; i++) {
const struct dm_target * const target = &targets[i];
@@ -2635,14 +2674,18 @@ _dm_create_part(const LDMPartitionPrivate * const part, uint32_t
cookie,
disk->device, disk->data_start + part->start);
GString *name = _dm_part_name(part);
+ GString *uuid = _dm_part_uuid(part);
GString *mangled_name = NULL;
- if (!_dm_create(name->str, cookie, 1, &target, &mangled_name, err)) {
+ if (!_dm_create(name->str, uuid->str, cookie, 1, &target,
+ &mangled_name, err)) {
mangled_name = NULL;
}
g_string_free(name, TRUE);
+ g_string_free(uuid, TRUE);
g_string_free(target.params, TRUE);
+
return mangled_name;
}
@@ -2695,12 +2738,15 @@ _dm_create_spanned(const LDMVolumePrivate * const vol, GError **
const err)
}
name = _dm_vol_name(vol);
+ GString *uuid = _dm_vol_uuid(vol);
- if (!_dm_create(name->str, cookie, vol->parts->len, targets, NULL, err)) {
+ if (!_dm_create(name->str, uuid->str, cookie, vol->parts->len, targets,
+ NULL, err)) {
g_string_free(name, TRUE);
name = NULL;
}
+ g_string_free(uuid, TRUE);
dm_udev_wait(cookie);
out:
@@ -2752,12 +2798,14 @@ _dm_create_striped(const LDMVolumePrivate * const vol, GError **
const err)
}
name = _dm_vol_name(vol);
+ GString *uuid = _dm_vol_uuid(vol);
- if (!_dm_create(name->str, cookie, 1, &target, NULL, err)) {
+ if (!_dm_create(name->str, uuid->str, cookie, 1, &target, NULL, err)) {
g_string_free(name, TRUE);
name = NULL;
}
+ g_string_free(uuid, TRUE);
dm_udev_wait(cookie);
out:
@@ -2826,12 +2874,14 @@ _dm_create_mirrored(const LDMVolumePrivate * const vol, GError **
const err)
}
name = _dm_vol_name(vol);
+ GString *uuid = _dm_vol_uuid(vol);
- if (!_dm_create(name->str, cookie, 1, &target, NULL, err)) {
+ if (!_dm_create(name->str, uuid->str, cookie, 1, &target, NULL, err)) {
g_string_free(name, TRUE);
name = NULL;
}
+ g_string_free(uuid, TRUE);
dm_udev_wait(cookie);
g_array_unref(devices); devices = NULL;
@@ -2857,6 +2907,7 @@ static GString *
_dm_create_raid5(const LDMVolumePrivate * const vol, GError ** const err)
{
GString *name = NULL;
+ GString *uuid = NULL;
struct dm_target target;
target.start = 0;
@@ -2914,12 +2965,15 @@ _dm_create_raid5(const LDMVolumePrivate * const vol, GError **
const err)
}
name = _dm_vol_name(vol);
+ uuid = _dm_vol_uuid(vol);
- if (!_dm_create(name->str, cookie, 1, &target, NULL, err)) {
+ if (!_dm_create(name->str, uuid->str, cookie, 1, &target, NULL, err)) {
g_string_free(name, TRUE); name = NULL;
+ g_string_free(uuid, TRUE);
goto out;
}
+ g_string_free(uuid, TRUE);
dm_udev_wait(cookie);
g_array_unref(devices); devices = NULL;
@@ -2938,6 +2992,7 @@ out:
}
g_string_free(target.params, TRUE);
+
return name;
}
--
2.17.0