]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
loop-util: add API for selecting "lo_file_name" field for a loopback device
authorLennart Poettering <lennart@poettering.net>
Mon, 6 Mar 2023 11:07:57 +0000 (12:07 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 9 Mar 2023 15:40:55 +0000 (16:40 +0100)
src/shared/loop-util.c
src/shared/loop-util.h

index 27a58952bbda33436ea1b205a7261278bf52125b..7d92a8ccce4c1b398f46e90683fc80638a0a72af 100644 (file)
@@ -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;
+}
index c98b69ceee7197a9237c63e206783c5fb49e0fd3..dda14ec4f01c6a142891c10f52d8543938cd60c9 100644 (file)
@@ -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);