diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/shared/loop-util.c | 32 | ||||
-rw-r--r-- | src/shared/loop-util.h | 1 | ||||
-rw-r--r-- | src/test/test-loop-block.c | 1 |
3 files changed, 31 insertions, 3 deletions
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index b5c16b0b0e..7a1b5ad2d3 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -26,6 +26,7 @@ #include "loop-util.h" #include "missing_loop.h" #include "parse-util.h" +#include "path-util.h" #include "random-util.h" #include "stat-util.h" #include "stdio-util.h" @@ -294,6 +295,7 @@ fail: } static int loop_device_make_internal( + const char *path, int fd, int open_flags, uint64_t offset, @@ -304,7 +306,7 @@ static int loop_device_make_internal( _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int direct_io_fd = -1; - _cleanup_free_ char *node = NULL; + _cleanup_free_ char *node = NULL, *backing_file = NULL; bool try_loop_configure = true; struct loop_config config; LoopDevice *d; @@ -332,6 +334,18 @@ static int loop_device_make_internal( return r; } + if (path) { + r = path_make_absolute_cwd(path, &backing_file); + if (r < 0) + return r; + + path_simplify(backing_file); + } else { + r = fd_get_path(fd, &backing_file); + if (r < 0) + return r; + } + f_flags = fcntl(fd, F_GETFL); if (f_flags < 0) return -errno; @@ -497,6 +511,7 @@ static int loop_device_make_internal( .nr = nr, .devno = st.st_rdev, .dev = TAKE_PTR(dev), + .backing_file = TAKE_PTR(backing_file), .diskseq = diskseq, .uevent_seqnum_not_before = seqnum, .timestamp_not_before = timestamp, @@ -535,6 +550,7 @@ int loop_device_make( assert(ret); return loop_device_make_internal( + NULL, fd, open_flags, offset, @@ -602,7 +618,7 @@ int loop_device_make_by_path( direct ? "enabled" : "disabled", direct != (direct_flags != 0) ? " (O_DIRECT was requested but not supported)" : ""); - return loop_device_make_internal(fd, open_flags, 0, 0, loop_flags, lock_op, ret); + return loop_device_make_internal(path, fd, open_flags, 0, 0, loop_flags, lock_op, ret); } LoopDevice* loop_device_unref(LoopDevice *d) { @@ -673,6 +689,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) { free(d->node); sd_device_unref(d->dev); + free(d->backing_file); return mfree(d); } @@ -699,7 +716,7 @@ int loop_device_open_full( _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int fd = -1, lock_fd = -1; - _cleanup_free_ char *p = NULL; + _cleanup_free_ char *p = NULL, *backing_file = NULL; struct loop_info64 info; uint64_t diskseq = 0; struct stat st; @@ -738,11 +755,19 @@ int loop_device_open_full( } if (ioctl(loop_fd, LOOP_GET_STATUS64, &info) >= 0) { + const char *s; + #if HAVE_VALGRIND_MEMCHECK_H /* Valgrind currently doesn't know LOOP_GET_STATUS64. Remove this once it does */ VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info)); #endif nr = info.lo_number; + + if (sd_device_get_sysattr_value(dev, "loop/backing_file", &s) >= 0) { + backing_file = strdup(s); + if (!backing_file) + return -ENOMEM; + } } r = fd_get_diskseq(loop_fd, &diskseq); @@ -773,6 +798,7 @@ int loop_device_open_full( .nr = nr, .node = TAKE_PTR(p), .dev = TAKE_PTR(dev), + .backing_file = TAKE_PTR(backing_file), .relinquished = true, /* It's not ours, don't try to destroy it when this object is freed */ .devno = st.st_rdev, .diskseq = diskseq, diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h index 43bd25d445..cb0183ba07 100644 --- a/src/shared/loop-util.h +++ b/src/shared/loop-util.h @@ -17,6 +17,7 @@ struct LoopDevice { dev_t devno; char *node; sd_device *dev; + char *backing_file; bool relinquished; uint64_t diskseq; /* Block device sequence number, monothonically incremented by the kernel on create/attach, or 0 if we don't know */ uint64_t uevent_seqnum_not_before; /* uevent sequm right before we attached the loopback device, or UINT64_MAX if we don't know */ diff --git a/src/test/test-loop-block.c b/src/test/test-loop-block.c index 1809d9f3b8..70d4aedb42 100644 --- a/src/test/test-loop-block.c +++ b/src/test/test-loop-block.c @@ -55,6 +55,7 @@ static void* thread_func(void *ptr) { log_error_errno(r, "Failed to allocate loopback device: %m"); assert_se(r >= 0); assert_se(loop->dev); + assert_se(loop->backing_file); log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted); |