Skip to content

Commit

Permalink
lvm: Also look at symlinks for segment PVs
Browse files Browse the repository at this point in the history
When a PV is on a LUKS device, lvm reports that device as
"/dev/mapper/luks-1234...", which is a symlink to the real device.
UDisks2 would miss this and report the segment as having lost its
backing PV.

In addition to looking harder for devices, UDisks2 now also
distinguises between "PV is gone" and "PV is there but I can't find a
D-Bus object for it".
  • Loading branch information
mvollmer committed Oct 20, 2023
1 parent a76eda8 commit 6cda264
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 5 deletions.
17 changes: 12 additions & 5 deletions modules/lvm2/udiskslinuxlogicalvolume.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,21 @@ build_segment (UDisksDaemon *daemon,
g_variant_builder_init (&seg_builder, G_VARIANT_TYPE ("(tto)"));
g_variant_builder_add (&seg_builder, "t", seg->pv_start_pe * extent_size);
g_variant_builder_add (&seg_builder, "t", seg->size_pe * extent_size);
block_object = udisks_daemon_find_block_by_device_file (daemon, seg->pvdev);
if (block_object)
if (seg->pvdev == NULL)
{
g_variant_builder_add (&seg_builder, "o", g_dbus_object_get_object_path (G_DBUS_OBJECT (block_object)));
g_object_unref (block_object);
g_variant_builder_add (&seg_builder, "o", "/");
}
else
g_variant_builder_add (&seg_builder, "o", "/");
{
block_object = udisks_daemon_find_block_by_device_file_and_symlinks (daemon, seg->pvdev);
if (block_object)
{
g_variant_builder_add (&seg_builder, "o", g_dbus_object_get_object_path (G_DBUS_OBJECT (block_object)));
g_object_unref (block_object);
}
else
g_variant_builder_add (&seg_builder, "o", "/notfound");
}
return g_variant_builder_end (&seg_builder);
}

Expand Down
46 changes: 46 additions & 0 deletions src/udisksdaemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1633,6 +1633,52 @@ udisks_daemon_find_block_by_device_file (UDisksDaemon *daemon,
return ret;
}

/**
* udisks_daemon_find_block_by_device_file_and_symlinks:
* @daemon: A #UDisksDaemon.
* @device_file: A device file.
*
* Like udisks_daemon_find_block_by_device_file, but also checks all
* symlinks for the device.
*
* Returns: (transfer full): A #UDisksObject or %NULL if not found. Free with g_object_unref().
*/
UDisksObject *
udisks_daemon_find_block_by_device_file_and_symlinks (UDisksDaemon *daemon,
const gchar *device_file)
{
UDisksObject *ret = NULL;
GList *objects, *l;

objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (daemon->object_manager));
for (l = objects; l != NULL; l = l->next)
{
UDisksObject *object = UDISKS_OBJECT (l->data);
UDisksBlock *block;
const gchar *const *symlinks;

block = udisks_object_peek_block (object);
if (block == NULL)
continue;

if (g_strcmp0 (udisks_block_get_device (block), device_file) == 0)
{
ret = g_object_ref (object);
goto out;
}

symlinks = udisks_block_get_symlinks (UDISKS_BLOCK (block));
if (symlinks && g_strv_contains (symlinks, device_file))
{
ret = g_object_ref (object);
goto out;
}
}
out:
g_list_free_full (objects, g_object_unref);
return ret;
}

/* ---------------------------------------------------------------------------------------------------- */

/**
Expand Down
3 changes: 3 additions & 0 deletions src/udisksdaemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ UDisksObject *udisks_daemon_find_block (UDisksDaemon
UDisksObject *udisks_daemon_find_block_by_device_file (UDisksDaemon *daemon,
const gchar *device_file);

UDisksObject *udisks_daemon_find_block_by_device_file_and_symlinks (UDisksDaemon *daemon,
const gchar *device_file);

UDisksObject *udisks_daemon_find_block_by_sysfs_path (UDisksDaemon *daemon,
const gchar *sysfs_path);

Expand Down

0 comments on commit 6cda264

Please sign in to comment.