summaryrefslogtreecommitdiffstats
path: root/src/shared/loop-util.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-09-05 22:19:46 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-09-07 13:45:24 +0200
commite77cab824829f33e7870eb188ccd014acac49075 (patch)
tree887c92f0c23af859ea2f6ab5330c7b9849f27817 /src/shared/loop-util.c
parentloop-util: move device_has_block_children() to blockdev-util.c (diff)
downloadsystemd-e77cab824829f33e7870eb188ccd014acac49075.tar.xz
systemd-e77cab824829f33e7870eb188ccd014acac49075.zip
loop-util: save backing file of loopback block device
It will be used in later commits.
Diffstat (limited to 'src/shared/loop-util.c')
-rw-r--r--src/shared/loop-util.c32
1 files changed, 29 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,