diff --git a/src/utils/dev_utils.c b/src/utils/dev_utils.c index 9280b807..8587bede 100644 --- a/src/utils/dev_utils.c +++ b/src/utils/dev_utils.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "dev_utils.h" @@ -94,7 +95,15 @@ gchar* bd_utils_resolve_device (const gchar *dev_spec, GError **error) { } g_free (path); - if (g_str_has_prefix (symlink, "../")) + if (g_path_is_absolute (symlink)) { + /* the target may be another symlink, resolve it completely */ + path = realpath (symlink, NULL); + if (!path) { + g_set_error (error, BD_UTILS_DEV_UTILS_ERROR, BD_UTILS_DEV_UTILS_ERROR_FAILED, + "Failed to resolve '%s': %s", dev_spec, strerror_l (errno, _C_LOCALE)); + return NULL; + } + } else if (g_str_has_prefix (symlink, "../")) path = g_strdup_printf ("/dev/%s", symlink + 3); else path = g_strdup_printf ("/dev/%s", symlink); diff --git a/tests/utils_test.py b/tests/utils_test.py index b1756aee..32a6aa6e 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -468,6 +468,13 @@ def test_resolve_device(self): # should resolve the other symlink even without the "/dev" prefix self.assertEqual(BlockDev.utils_resolve_device(dev_link2[5:]), dev_node) + # should resolve a symlink with an absolute target + abs_link = "/dev/utilsTestAbsoluteLink" + os.symlink(dev_node, abs_link) + self.addCleanup(os.unlink, abs_link) + self.assertEqual(BlockDev.utils_resolve_device(abs_link), dev_node) + self.assertEqual(BlockDev.utils_resolve_device(abs_link[5:]), dev_node) + # vg is not a block device, shouldn't be resolved with self.assertRaisesRegex(GLib.GError, "not a block device"): BlockDev.utils_resolve_device("/dev/utilsTestVG")