--- libldm-libldm-0.2.4/src/ldm.c 2018-04-26 11:32:45.000000000 +0100 +++ libldm-libldm-0.2.4-guysmoilov/src/ldm.c 2020-07-19 21:52:33.000000000 +0100 @@ -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], \ @@ -234,6 +236,41 @@ return etype; } +/* We catch log messages generated by device mapper with errno != 0 and store + * them here */ +static int _dm_err_last_level = 0; +static const char *_dm_err_last_file = NULL; +static int _dm_err_last_line = 0; +static int _dm_err_last_errno = 0; +static char *_dm_err_last_msg = NULL; + +static void +_dm_log_fn(const int level, const char * const file, const int line, + const int dm_errno, const char *f, ...) +{ + if (dm_errno == 0) return; + + _dm_err_last_level = level; + _dm_err_last_file = file; + _dm_err_last_line = line; + + /* device-mapper doesn't set dm_errno usefully (it only seems to use + * EUNCLASSIFIED), so we capture errno directly and cross our fingers */ + _dm_err_last_errno = errno; + + if (_dm_err_last_msg) { + free(_dm_err_last_msg); + _dm_err_last_msg = NULL; + } + + va_list ap; + va_start(ap, f); + if (vasprintf(&_dm_err_last_msg, f, ap) == -1) { + g_error("vasprintf"); + } + va_end(ap); +} + /* Macros for exporting object properties */ #define EXPORT_PROP_STRING(object, klass, property) \ @@ -267,15 +304,12 @@ /* LDM */ -#define LDM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), LDM_TYPE, LDMPrivate)) - struct _LDMPrivate { GArray *disk_groups; }; -G_DEFINE_TYPE(LDM, ldm, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_PRIVATE(LDM, ldm, G_TYPE_OBJECT) static void ldm_dispose(GObject * const object) @@ -285,13 +319,21 @@ if (ldm->priv->disk_groups) { g_array_unref(ldm->priv->disk_groups); ldm->priv->disk_groups = NULL; } + + /* Restore default logging function. */ + dm_log_with_errno_init(NULL); } static void ldm_init(LDM * const o) { - o->priv = LDM_GET_PRIVATE(o); + o->priv = ldm_get_instance_private(o); bzero(o->priv, sizeof(*o->priv)); + + /* Provide our logging function. */ + dm_log_with_errno_init(_dm_log_fn); + dm_set_name_mangling_mode(DM_STRING_MANGLING_AUTO); + dm_set_uuid_prefix(DM_UUID_PREFIX); } static void @@ -300,14 +342,10 @@ GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->dispose = ldm_dispose; - g_type_class_add_private(klass, sizeof(LDMPrivate)); } /* LDMDiskGroup */ -#define LDM_DISK_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), LDM_TYPE_DISK_GROUP, LDMDiskGroupPrivate)) - struct _LDMDiskGroupPrivate { uuid_t guid; @@ -326,7 +364,7 @@ GArray *comps; }; -G_DEFINE_TYPE(LDMDiskGroup, ldm_disk_group, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_PRIVATE(LDMDiskGroup, ldm_disk_group, G_TYPE_OBJECT) enum { PROP_LDM_DISK_GROUP_PROP0, @@ -396,7 +434,6 @@ object_class->finalize = ldm_disk_group_finalize; object_class->get_property = ldm_disk_group_get_property; - g_type_class_add_private(klass, sizeof(LDMDiskGroupPrivate)); /** * LDMDiskGroup:guid: @@ -431,7 +468,7 @@ static void ldm_disk_group_init(LDMDiskGroup * const o) { - o->priv = LDM_DISK_GROUP_GET_PRIVATE(o); + o->priv = ldm_disk_group_get_instance_private(o); bzero(o->priv, sizeof(*o->priv)); } @@ -457,9 +494,6 @@ /* LDMVolume */ -#define LDM_VOLUME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), LDM_TYPE_VOLUME, LDMVolumePrivate)) - typedef enum { _VOLUME_TYPE_GEN = 0x3, _VOLUME_TYPE_RAID5 = 0x4 @@ -469,6 +503,7 @@ { guint32 id; gchar *name; + uuid_t guid; gchar *dgname; guint64 size; @@ -491,11 +526,12 @@ guint32 _n_comps_i; }; -G_DEFINE_TYPE(LDMVolume, ldm_volume, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_PRIVATE(LDMVolume, ldm_volume, G_TYPE_OBJECT) enum { PROP_LDM_VOLUME_PROP0, PROP_LDM_VOLUME_NAME, + PROP_LDM_VOLUME_GUID, PROP_LDM_VOLUME_TYPE, PROP_LDM_VOLUME_SIZE, PROP_LDM_VOLUME_PART_TYPE, @@ -514,6 +550,14 @@ case PROP_LDM_VOLUME_NAME: g_value_set_string(value, priv->name); break; + case PROP_LDM_VOLUME_GUID: + { + char guid_str[37]; + uuid_unparse(priv->guid, guid_str); + g_value_set_string(value, guid_str); + } + break; + case PROP_LDM_VOLUME_TYPE: g_value_set_enum(value, priv->type); break; @@ -535,6 +579,7 @@ } EXPORT_PROP_STRING(volume, LDMVolume, name) +EXPORT_PROP_GUID(volume, LDMVolume) EXPORT_PROP_SCALAR(volume, LDMVolume, size, guint64) EXPORT_PROP_SCALAR(volume, LDMVolume, part_type, guint8) EXPORT_PROP_STRING(volume, LDMVolume, hint) @@ -577,7 +622,6 @@ object_class->finalize = ldm_volume_finalize; object_class->get_property = ldm_volume_get_property; - g_type_class_add_private(klass, sizeof(LDMVolumePrivate)); /** * LDMVolume:name: @@ -594,6 +638,20 @@ ); /** + * LDMVolume:guid: + * + * The GUID of the volume. + */ + g_object_class_install_property( + object_class, + PROP_LDM_VOLUME_GUID, + g_param_spec_string( + "guid", "GUID", "The GUID of the volume", + NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS + ) + ); + + /** * LDMVolume:type: * * The volume type: simple, spanned, striped, mirrored or raid5. @@ -677,7 +735,7 @@ static void ldm_volume_init(LDMVolume * const o) { - o->priv = LDM_VOLUME_GET_PRIVATE(o); + o->priv = ldm_volume_get_instance_private(o); bzero(o->priv, sizeof(*o->priv)); /* We don't have a trivial way to initialize this array to the correct size @@ -717,9 +775,6 @@ /* LDMPartition */ -#define LDM_PARTITION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), LDM_TYPE_PARTITION, LDMPartitionPrivate)) - struct _LDMPartitionPrivate { guint32 id; @@ -735,7 +790,7 @@ LDMDisk *disk; }; -G_DEFINE_TYPE(LDMPartition, ldm_partition, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_PRIVATE(LDMPartition, ldm_partition, G_TYPE_OBJECT) enum { PROP_LDM_PARTITION_PROP0, @@ -796,7 +851,6 @@ object_class->finalize = ldm_partition_finalize; object_class->get_property = ldm_partition_get_property; - g_type_class_add_private(klass, sizeof(LDMPartitionPrivate)); /** * LDMPartition:name: @@ -846,15 +900,12 @@ static void ldm_partition_init(LDMPartition * const o) { - o->priv = LDM_PARTITION_GET_PRIVATE(o); + o->priv = ldm_partition_get_instance_private(o); bzero(o->priv, sizeof(*o->priv)); } /* LDMDisk */ -#define LDM_DISK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), LDM_TYPE_DISK, LDMDiskPrivate)) - struct _LDMDiskPrivate { guint32 id; @@ -870,7 +921,7 @@ gchar *device; // NULL until device is found }; -G_DEFINE_TYPE(LDMDisk, ldm_disk, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_PRIVATE(LDMDisk, ldm_disk, G_TYPE_OBJECT) enum { PROP_LDM_DISK_PROP0, @@ -948,7 +999,6 @@ object_class->finalize = ldm_disk_finalize; object_class->get_property = ldm_disk_get_property; - g_type_class_add_private(klass, sizeof(LDMDiskPrivate)); /** * LDMDisk:name: @@ -1062,7 +1112,7 @@ static void ldm_disk_init(LDMDisk * const o) { - o->priv = LDM_DISK_GET_PRIVATE(o); + o->priv = ldm_disk_get_instance_private(o); bzero(o->priv, sizeof(*o->priv)); } @@ -1514,8 +1564,8 @@ vol->part_type = *((uint8_t *)vblk); vblk++; - /* Volume id */ - vblk += 16; + /* Volume GUID */ + memcpy(&vol->guid, vblk, 16); vblk += 16; if (flags & 0x08) vol->id1 = _parse_var_string(&vblk); if (flags & 0x20) vol->id2 = _parse_var_string(&vblk); @@ -2354,6 +2404,32 @@ } static GString * +_dm_part_name(const LDMPartitionPrivate * const part) +{ + const LDMDiskPrivate * const disk = part->disk->priv; + + GString * name = g_string_new(""); + g_string_printf(name, "ldm_part_%s_%s", disk->dgname, part->name); + + 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) { GString * r = g_string_new(""); @@ -2361,13 +2437,18 @@ return r; } -/* We catch log messages generated by device mapper with errno != 0 and store - * them here */ -static int _dm_err_last_level = 0; -static const char *_dm_err_last_file = NULL; -static int _dm_err_last_line = 0; -static int _dm_err_last_errno = 0; -static char *_dm_err_last_msg = NULL; +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; +} struct dm_target { guint64 start; @@ -2377,7 +2458,7 @@ }; static struct dm_tree * -_get_device_tree(GError **err) +_dm_get_device_tree(GError **err) { struct dm_tree *tree; tree = dm_tree_create(); @@ -2432,45 +2513,106 @@ return NULL; } -static struct dm_tree_node * -_walk_tree(const struct dm_tree * const tree, - const struct dm_tree_node * const node, - const char * const search) +/* Returns TRUE if device with specified UUID is found or FALSE otherwise. + * + * Found device node is returned if dm_node is not NULL. In this case dm_tree + * MUST not be NULL as well. And the caller is responsible to free device tree + * by calling dm_tree_free function. + */ +gboolean +_dm_find_tree_node_by_uuid(const gchar * const uuid, + struct dm_tree_node ** dm_node, + struct dm_tree ** dm_tree, + GError ** const err) { - void *handle = NULL; - struct dm_tree_node *child; - for (;;) { - child = dm_tree_next_child(&handle, node, 0); - if (!child) return NULL; - - const char * const name = dm_tree_node_get_name(child); - if (!name || *name == '\0') continue; + gboolean r = FALSE; - if (g_strcmp0(search, name) == 0) return child; + if (dm_node) { + g_assert(dm_tree != NULL); + *dm_node = NULL; + } + if (dm_tree) *dm_tree = NULL; + + struct dm_tree *tree = _dm_get_device_tree(err); + if (tree) { + struct dm_tree_node *node = dm_tree_find_node_by_uuid(tree, uuid); + if (node) r = TRUE; + + if (dm_tree) + *dm_tree = tree; + else + dm_tree_free(tree); - if (dm_tree_node_num_children(child, 0) > 0) { - struct dm_tree_node * const r_search = - _walk_tree(tree, child, search); - if (r_search) return r_search; - } + if (dm_node) *dm_node = node; } + + return r; } -static struct dm_tree_node * -_find_device_tree_node(struct dm_tree * const tree, - const char * const name) +gchar * +_dm_get_device(const gchar * const uuid, GError ** const err) { - const struct dm_tree_node * const root = dm_tree_find_node(tree, 0, 0); - return _walk_tree(tree, root, name); + GString *r = NULL; + + struct dm_tree_node *node = NULL; + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + + if (_dm_find_tree_node_by_uuid(uuid, &node, &tree, err)) { + const struct dm_info *info = dm_tree_node_get_info(node); + + task = dm_task_create(DM_DEVICE_INFO); + if (!task) { + g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, + "dm_task_create: %s", _dm_err_last_msg); + goto error; + } + + if (!dm_task_set_major(task, info->major)) { + g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, + "DM_DEVICE_INFO: dm_task_set_major(%d) failed: %s", + info->major, _dm_err_last_msg); + goto error; + } + + if (!dm_task_set_minor(task, info->minor)) { + g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, + "DM_DEVICE_INFO: dm_task_set_major(%d) failed: %s", + info->minor, _dm_err_last_msg); + goto error; + } + + if (!dm_task_run(task)) { + g_set_error_literal(err, LDM_ERROR, LDM_ERROR_EXTERNAL, + _dm_err_last_msg); + goto error; + } + + const char *dir = dm_dir(); + char *mangled_name = dm_task_get_name_mangled(task); + r = g_string_new(""); + g_string_printf(r, "%s/%s", dir, mangled_name); + dm_free(mangled_name); + } + +error: + if (tree) dm_tree_free(tree); + if (task) dm_task_destroy(task); + + /* Really FALSE here - don't free but return the character data. */ + return r ? g_string_free(r, FALSE) : NULL; } gboolean -_dm_create(const gchar * const name, uint32_t udev_cookie, - const guint n_targets, const struct dm_target * const targets, - GError ** const err) +_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; + if (mangled_name) *mangled_name = NULL; + struct dm_task * const task = dm_task_create(DM_DEVICE_CREATE); if (!task) { g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, @@ -2486,6 +2628,13 @@ 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]; @@ -2515,6 +2664,12 @@ r = FALSE; goto out; } + if (mangled_name) { + char *tmp = dm_task_get_name_mangled(task); + *mangled_name = g_string_new(tmp); + dm_free(tmp); + } + out: dm_task_destroy(task); return r; @@ -2588,37 +2743,40 @@ g_string_printf(target.params, "%s %" PRIu64, disk->device, disk->data_start + part->start); - /* Ensure we sanitise table names */ - char * dgname_esc = - g_uri_escape_string(disk->dgname, - G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, - FALSE); - char * partname_esc = - g_uri_escape_string(part->name, - G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, - FALSE); - - GString *name = g_string_new(""); - g_string_printf(name, "ldm_part_%s_%s", dgname_esc, partname_esc); - g_free(dgname_esc); - g_free(partname_esc); - - if (!_dm_create(name->str, cookie, 1, &target, err)) { - g_string_free(name, TRUE); - name = NULL; + GString *name = _dm_part_name(part); + GString *uuid = _dm_part_uuid(part); + GString *mangled_name = NULL; + + 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 name; + + return mangled_name; +} + +gint +_cmp_component_vol_offset(gconstpointer a, gconstpointer b) +{ + const LDMPartition * const ao = LDM_PARTITION(*(LDMPartition **)a); + const LDMPartition * const bo = LDM_PARTITION(*(LDMPartition **)b); + + return ao->priv->vol_offset - bo->priv->vol_offset; } static GString * _dm_create_spanned(const LDMVolumePrivate * const vol, GError ** const err) { - static GString *name = NULL; + GString *name = NULL; guint i = 0; struct dm_target *targets = g_malloc(sizeof(*targets) * vol->parts->len); + g_array_sort(vol->parts, _cmp_component_vol_offset); + uint64_t pos = 0; for (; i < vol->parts->len; i++) { const LDMPartition * const part_o = @@ -2661,12 +2819,15 @@ } name = _dm_vol_name(vol); + GString *uuid = _dm_vol_uuid(vol); - if (!_dm_create(name->str, cookie, vol->parts->len, targets, 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: @@ -2682,7 +2843,7 @@ static GString * _dm_create_striped(const LDMVolumePrivate * const vol, GError ** const err) { - static GString *name = NULL; + GString *name = NULL; struct dm_target target; target.start = 0; @@ -2718,12 +2879,14 @@ } name = _dm_vol_name(vol); + GString *uuid = _dm_vol_uuid(vol); - if (!_dm_create(name->str, cookie, 1, &target, 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: @@ -2754,6 +2917,8 @@ goto out; } + const char *dir = dm_dir(); + int found = 0; for (guint i = 0; i < vol->parts->len; i++) { const LDMPartition * const part_o = @@ -2774,7 +2939,7 @@ found++; g_array_append_val(devices, chunk); - g_string_append_printf(target.params, " - /dev/mapper/%s", chunk->str); + g_string_append_printf(target.params, " - %s/%s", dir, chunk->str); } if (found == 0) { @@ -2792,12 +2957,14 @@ } name = _dm_vol_name(vol); + GString *uuid = _dm_vol_uuid(vol); - if (!_dm_create(name->str, cookie, 1, &target, 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; @@ -2816,6 +2983,7 @@ } g_string_free(target.params, TRUE); + return name; } @@ -2823,6 +2991,7 @@ _dm_create_raid5(const LDMVolumePrivate * const vol, GError ** const err) { GString *name = NULL; + GString *uuid = NULL; struct dm_target target; target.start = 0; @@ -2842,6 +3011,8 @@ goto out; } + const char *dir = dm_dir(); + guint n_found = 0; for (guint i = 0; i < vol->parts->len; i++) { const LDMPartition * const part_o = @@ -2862,7 +3033,7 @@ n_found++; g_array_append_val(devices, chunk); - g_string_append_printf(target.params, " - /dev/mapper/%s", chunk->str); + g_string_append_printf(target.params, " - %s/%s", dir, chunk->str); } if (n_found < vol->parts->len - 1) { @@ -2880,12 +3051,15 @@ } name = _dm_vol_name(vol); + uuid = _dm_vol_uuid(vol); - if (!_dm_create(name->str, cookie, 1, &target, 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; @@ -2904,65 +3078,53 @@ } g_string_free(target.params, TRUE); + return name; } -static void -_dm_log_fn(const int level, const char * const file, const int line, - const int dm_errno, const char *f, ...) +GString * +ldm_volume_dm_get_name(const LDMVolume * const o) { - if (dm_errno == 0) return; - - _dm_err_last_level = level; - _dm_err_last_file = file; - _dm_err_last_line = line; - - /* device-mapper doesn't set dm_errno usefully (it only seems to use - * EUNCLASSIFIED), so we capture errno directly and cross our fingers */ - _dm_err_last_errno = errno; + return _dm_vol_name(o->priv); +} - if (_dm_err_last_msg) { - free(_dm_err_last_msg); - _dm_err_last_msg = NULL; - } +gchar * +ldm_partition_dm_get_device(const LDMPartition * const o, GError ** const err) +{ + GString *uuid = _dm_part_uuid(o->priv); + gchar* r = _dm_get_device(uuid->str, err); + g_string_free(uuid, TRUE); - va_list ap; - va_start(ap, f); - if (vasprintf(&_dm_err_last_msg, f, ap) == -1) { - g_error("vasprintf"); - } - va_end(ap); + return r; } -GString * -ldm_volume_dm_get_name(const LDMVolume * const o) +gchar * +ldm_volume_dm_get_device(const LDMVolume * const o, GError ** const err) { - return _dm_vol_name(o->priv); + GString *uuid = _dm_vol_uuid(o->priv); + gchar* r = _dm_get_device(uuid->str, err); + g_string_free(uuid, TRUE); + + return r; } gboolean ldm_volume_dm_create(const LDMVolume * const o, GString **created, GError ** const err) { - const LDMVolumePrivate * const vol = o->priv; + if (created) *created = NULL; - /* We should really store the previous logging function and restore it - * afterwards, but the API doesn't allow this. */ - dm_log_with_errno_init(_dm_log_fn); + const LDMVolumePrivate * const vol = o->priv; /* Check if the device already exists */ - struct dm_tree *tree = _get_device_tree(err); - if (!tree) return FALSE; - - GString *name = _dm_vol_name(vol); - struct dm_tree_node *node = _find_device_tree_node(tree, name->str); - if (node) { - dm_tree_free(tree); tree = NULL; + GString *uuid = _dm_vol_uuid(vol); + if (_dm_find_tree_node_by_uuid(uuid->str, NULL, NULL, err)) { + g_string_free(uuid, TRUE); return TRUE; } - dm_tree_free(tree); tree = NULL; - g_string_free(name, TRUE); + g_string_free(uuid, TRUE); + GString *name = NULL; switch (vol->type) { case LDM_VOLUME_TYPE_SIMPLE: case LDM_VOLUME_TYPE_SPANNED: @@ -2986,38 +3148,43 @@ g_error("Unexpected volume type: %u", vol->type); } - dm_log_with_errno_init(NULL); + gboolean r = name != NULL; + + if (created) + *created = name; + else if (name) + g_string_free(name, TRUE); - if (created && name) *created = name; - return name == NULL ? FALSE : TRUE; + return r; } gboolean ldm_volume_dm_remove(const LDMVolume * const o, GString **removed, GError ** const err) { + if (removed) *removed = NULL; + const LDMVolumePrivate * const vol = o->priv; - /* We should really store the previous logging function and restore it - * afterwards, but the API doesn't allow this. */ - dm_log_with_errno_init(_dm_log_fn); + gboolean r = FALSE; - struct dm_tree *tree = _get_device_tree(err); - if (!tree) return FALSE; + struct dm_tree *tree = NULL; + struct dm_tree_node *node = NULL; - gboolean r = FALSE; + GString *uuid = _dm_vol_uuid(vol); + gboolean found = _dm_find_tree_node_by_uuid(uuid->str, &node, &tree, err); + g_string_free(uuid, TRUE); - GString *name = _dm_vol_name(vol); - struct dm_tree_node *node = _find_device_tree_node(tree, name->str); - if (node) { + GString *name = NULL; + if (found) { uint32_t cookie; if (!dm_udev_create_cookie(&cookie)) { g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, "dm_udev_create_cookie: %s", _dm_err_last_msg); - g_string_free(name, TRUE); name = NULL; goto out; } + name = _dm_vol_name(vol); if (!_dm_remove(name->str, cookie, err)) { g_string_free(name, TRUE); name = NULL; goto out; @@ -3032,17 +3199,17 @@ } dm_udev_wait(cookie); - } else { - g_string_free(name, TRUE); name = NULL; } r = TRUE; out: - dm_tree_free(tree); - if (removed && name) *removed = name; + if (tree) dm_tree_free(tree); - dm_log_with_errno_init(NULL); + if (removed) + *removed = name; + else if (name) + g_string_free(name, TRUE); return r; }