summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-03-06 12:07:57 +0100
committerLennart Poettering <lennart@poettering.net>2023-03-09 16:40:55 +0100
commit999ac3e2b0b729cba0db27cdcace28ff509e0fe4 (patch)
treeeee9bb169b77b1f31558761ce5c33608d3bb25e1
parentloop-util: add call for setting the autoclear flag at arbitrary times (diff)
downloadsystemd-999ac3e2b0b729cba0db27cdcace28ff509e0fe4.tar.xz
systemd-999ac3e2b0b729cba0db27cdcace28ff509e0fe4.zip
loop-util: add API for selecting "lo_file_name" field for a loopback device
-rw-r--r--src/shared/loop-util.c35
-rw-r--r--src/shared/loop-util.h1
2 files changed, 36 insertions, 0 deletions
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
index 27a58952bb..7d92a8ccce 100644
--- a/src/shared/loop-util.c
+++ b/src/shared/loop-util.c
@@ -1130,3 +1130,38 @@ int loop_device_set_autoclear(LoopDevice *d, bool autoclear) {
return 1;
}
+
+int loop_device_set_filename(LoopDevice *d, const char *name) {
+ struct loop_info64 info;
+
+ assert(d);
+
+ /* Sets the .lo_file_name of the loopback device. This is supposed to contain the path to the file
+ * backing the block device, but is actually just a free-form string you can pass to the kernel. Most
+ * tools that actually care for the backing file path use the sysfs attribute file loop/backing_file
+ * which is a kernel generated string, subject to file system namespaces and such.
+ *
+ * .lo_file_name is useful since userspace can select it freely when creating a loopback block
+ * device, and we can use it for /dev/loop/by-ref/ symlinks, and similar, so that apps can recognize
+ * their own loopback files. */
+
+ if (name && strlen(name) >= sizeof(info.lo_file_name))
+ return -ENOBUFS;
+
+ if (ioctl(d->fd, LOOP_GET_STATUS64, &info) < 0)
+ return -errno;
+
+ if (strneq((char*) info.lo_file_name, strempty(name), sizeof(info.lo_file_name)))
+ return 0;
+
+ if (name) {
+ strncpy((char*) info.lo_file_name, name, sizeof(info.lo_file_name)-1);
+ info.lo_file_name[sizeof(info.lo_file_name)-1] = 0;
+ } else
+ memzero(info.lo_file_name, sizeof(info.lo_file_name));
+
+ if (ioctl(d->fd, LOOP_SET_STATUS64, &info) < 0)
+ return -errno;
+
+ return 1;
+}
diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h
index c98b69ceee..dda14ec4f0 100644
--- a/src/shared/loop-util.h
+++ b/src/shared/loop-util.h
@@ -51,3 +51,4 @@ int loop_device_flock(LoopDevice *d, int operation);
int loop_device_sync(LoopDevice *d);
int loop_device_set_autoclear(LoopDevice *d, bool autoclear);
+int loop_device_set_filename(LoopDevice *d, const char *name);