[dm-devel] [PATCH v2] dm-ioctl: return UUID in DM_LIST_DEVICES_CMD result
Mike Snitzer
snitzer at redhat.com
Thu Mar 11 18:41:16 UTC 2021
On Thu, Mar 11 2021 at 1:26pm -0500,
Mikulas Patocka <mpatocka at redhat.com> wrote:
> When LVM needs to find a device with a particular UUID it needs to ask for
> UUID for each device. This patch returns UUID directly in the list of
> devices, so that LVM doesn't have to query all the devices with an ioctl.
> The UUID is returned if the flag DM_UUID_FLAG is set in the parameters.
>
> Returning UUID is done in backward-compatible way. There's one unused
> 32-bit word value after the event number. This patch sets the bit
> DM_NAME_LIST_FLAG_HAS_UUID if UUID is present and
> DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID if it isn't (if none of these bits is
> set, then we have an old kernel that doesn't support returning UUIDs). The
> UUID is stored after this word. The 'next' value is updated to point after
> the UUID, so that old version of libdevmapper will skip the UUID without
> attempting to interpret it.
>
> Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
>
> ---
> drivers/md/dm-ioctl.c | 20 +++++++++++++++++---
> include/uapi/linux/dm-ioctl.h | 7 +++++++
> 2 files changed, 24 insertions(+), 3 deletions(-)
>
> Index: linux-2.6/drivers/md/dm-ioctl.c
> ===================================================================
> --- linux-2.6.orig/drivers/md/dm-ioctl.c 2021-03-09 21:04:07.000000000 +0100
> +++ linux-2.6/drivers/md/dm-ioctl.c 2021-03-11 18:53:58.000000000 +0100
> @@ -558,7 +558,9 @@ static int list_devices(struct file *fil
> for (n = rb_first(&name_rb_tree); n; n = rb_next(n)) {
> hc = container_of(n, struct hash_cell, name_node);
> needed += align_val(offsetof(struct dm_name_list, name) + strlen(hc->name) + 1);
> - needed += align_val(sizeof(uint32_t));
> + needed += align_val(sizeof(uint32_t) * 2);
> + if (param->flags & DM_UUID_FLAG && hc->uuid)
> + needed += align_val(strlen(hc->uuid) + 1);
> }
>
> /*
> @@ -577,6 +579,7 @@ static int list_devices(struct file *fil
> * Now loop through filling out the names.
> */
> for (n = rb_first(&name_rb_tree); n; n = rb_next(n)) {
> + void *uuid_ptr;
> hc = container_of(n, struct hash_cell, name_node);
> if (old_nl)
> old_nl->next = (uint32_t) ((void *) nl -
> @@ -588,8 +591,19 @@ static int list_devices(struct file *fil
>
> old_nl = nl;
> event_nr = align_ptr(nl->name + strlen(hc->name) + 1);
> - *event_nr = dm_get_event_nr(hc->md);
> - nl = align_ptr(event_nr + 1);
> + event_nr[0] = dm_get_event_nr(hc->md);
> + event_nr[1] = 0;
> + uuid_ptr = align_ptr(event_nr + 2);
> + if (param->flags & DM_UUID_FLAG) {
> + if (hc->uuid) {
> + event_nr[1] |= DM_NAME_LIST_FLAG_HAS_UUID;
> + strcpy(uuid_ptr, hc->uuid);
> + uuid_ptr = align_ptr(uuid_ptr + strlen(hc->uuid) + 1);
> + } else {
> + event_nr[1] |= DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID;
> + }
> + }
> + nl = uuid_ptr;
> }
> /*
> * If mismatch happens, security may be compromised due to buffer
> Index: linux-2.6/include/uapi/linux/dm-ioctl.h
> ===================================================================
> --- linux-2.6.orig/include/uapi/linux/dm-ioctl.h 2021-03-09 12:20:23.000000000 +0100
> +++ linux-2.6/include/uapi/linux/dm-ioctl.h 2021-03-11 18:42:14.000000000 +0100
> @@ -193,8 +193,15 @@ struct dm_name_list {
> __u32 next; /* offset to the next record from
> the _start_ of this */
> char name[0];
> +
> + /* uint32_t event_nr; */
> + /* uint32_t flags; */
> + /* char uuid[0]; */
> };
If extra padding is being leveraged here (from the __u32 next), why not
at least explicitly add the members and then pad out the balance of that
__u32? I'm not liking the usage of phantom struct members.. e.g.
the games played with accessing them.
Mike
>
> +#define DM_NAME_LIST_FLAG_HAS_UUID 1
> +#define DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID 2
> +
> /*
> * Used to retrieve the target versions
> */
More information about the dm-devel
mailing list