From d4423cce9b9001c9de7ebc6f64f6cc2bb854944c Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 20 Apr 2021 13:20:12 +0200 Subject: [PATCH] lib/loopdev: fix is_loopdev() to be usable with partitions The current implementation of the function does not care if the device is whole-disk device or partition, all is loopdev. This is regression as the original is_loopdev() version was based on whole-disk devices major numbers only. Fixes: https://github.com/karelzak/util-linux/issues/1202 Signed-off-by: Karel Zak --- lib/Makemodule.am | 9 ++++++++- lib/loopdev.c | 21 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/Makemodule.am b/lib/Makemodule.am index 0f18c9489..d112736da 100644 --- a/lib/Makemodule.am +++ b/lib/Makemodule.am @@ -101,7 +101,8 @@ endif check_PROGRAMS += \ test_sysfs \ test_pager \ - test_caputils + test_caputils \ + test_loopdev endif if HAVE_OPENAT @@ -164,6 +165,7 @@ test_pty_LDADD = $(LDADD) libcommon.la $(MATH_LIBS) $(REALTIME_LIBS) -lutil endif if LINUX + test_cpuset_SOURCES = lib/cpuset.c test_cpuset_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_CPUSET @@ -199,3 +201,8 @@ test_remove_env_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM test_buffer_SOURCES = lib/buffer.c test_buffer_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_BUFFER + +test_loopdev_SOURCES = lib/loopdev.c \ + $(test_sysfs_SOURCES) \ + $(test_canonicalize_SOURCES) +test_loopdev_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_LOOPDEV diff --git a/lib/loopdev.c b/lib/loopdev.c index b946acf31..1eef15d89 100644 --- a/lib/loopdev.c +++ b/lib/loopdev.c @@ -641,7 +641,7 @@ int is_loopdev(const char *device) rc = 0; else if (major(st.st_rdev) == LOOPDEV_MAJOR) rc = 1; - else { + else if (sysfs_devno_is_wholedisk(st.st_rdev)) { /* It's possible that kernel creates a device with a different * major number ... check by /sys it's really loop device. */ @@ -1881,3 +1881,22 @@ int loopdev_count_by_backing_file(const char *filename, char **loopdev) return count; } +#ifdef TEST_PROGRAM_LOOPDEV +int main(int argc, char *argv[]) +{ + if (argc < 2) + goto usage; + + if (strcmp(argv[1], "--is-loopdev") == 0 && argc == 3) + printf("%s: %s\n", argv[2], is_loopdev(argv[2]) ? "OK" : "FAIL"); + else + goto usage; + + return EXIT_SUCCESS; +usage: + fprintf(stderr, "usage: %1$s --is-loopdev \n", + program_invocation_short_name); + return EXIT_FAILURE; +} +#endif +