Merge pull request #26693 from poettering/udev-loop-links
udev: add /dev/loop/by-inode/… + /dev/loop/by-ref/… loopback block device symlinks
This commit is contained in:
+63
-1
@@ -595,6 +595,8 @@ static int loop_device_make_internal(
|
||||
}
|
||||
|
||||
d->backing_file = TAKE_PTR(backing_file);
|
||||
d->backing_inode = st.st_ino;
|
||||
d->backing_devno = st.st_dev;
|
||||
|
||||
log_debug("Successfully acquired %s, devno=%u:%u, nr=%i, diskseq=%" PRIu64,
|
||||
d->node,
|
||||
@@ -841,11 +843,12 @@ int loop_device_open(
|
||||
|
||||
_cleanup_close_ int fd = -EBADF, lock_fd = -EBADF;
|
||||
_cleanup_free_ char *node = NULL, *backing_file = NULL;
|
||||
dev_t devnum, backing_devno = 0;
|
||||
struct loop_info64 info;
|
||||
ino_t backing_inode = 0;
|
||||
uint64_t diskseq = 0;
|
||||
LoopDevice *d;
|
||||
const char *s;
|
||||
dev_t devnum;
|
||||
int r, nr = -1;
|
||||
|
||||
assert(dev);
|
||||
@@ -878,6 +881,9 @@ int loop_device_open(
|
||||
if (!backing_file)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
backing_devno = info.lo_device;
|
||||
backing_inode = info.lo_inode;
|
||||
}
|
||||
|
||||
r = fd_get_diskseq(fd, &diskseq);
|
||||
@@ -913,6 +919,8 @@ int loop_device_open(
|
||||
.node = TAKE_PTR(node),
|
||||
.dev = sd_device_ref(dev),
|
||||
.backing_file = TAKE_PTR(backing_file),
|
||||
.backing_inode = backing_inode,
|
||||
.backing_devno = backing_devno,
|
||||
.relinquished = true, /* It's not ours, don't try to destroy it when this object is freed */
|
||||
.devno = devnum,
|
||||
.diskseq = diskseq,
|
||||
@@ -1103,3 +1111,57 @@ int loop_device_sync(LoopDevice *d) {
|
||||
|
||||
return RET_NERRNO(fsync(d->fd));
|
||||
}
|
||||
|
||||
int loop_device_set_autoclear(LoopDevice *d, bool autoclear) {
|
||||
struct loop_info64 info;
|
||||
|
||||
assert(d);
|
||||
|
||||
if (ioctl(d->fd, LOOP_GET_STATUS64, &info) < 0)
|
||||
return -errno;
|
||||
|
||||
if (autoclear == FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR))
|
||||
return 0;
|
||||
|
||||
SET_FLAG(info.lo_flags, LO_FLAGS_AUTOCLEAR, autoclear);
|
||||
|
||||
if (ioctl(d->fd, LOOP_SET_STATUS64, &info) < 0)
|
||||
return -errno;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,14 @@ struct LoopDevice {
|
||||
unsigned n_ref;
|
||||
int fd;
|
||||
int lock_fd;
|
||||
int nr; /* The loopback device index (i.e. 4 for /dev/loop4); if this object encapsulates a non-loopback block device, set to -1 */
|
||||
dev_t devno;
|
||||
int nr; /* The loopback device index (i.e. 4 for /dev/loop4); if this object encapsulates a non-loopback block device, set to -1 */
|
||||
dev_t devno; /* The loopback device's own dev_t */
|
||||
char *node;
|
||||
sd_device *dev;
|
||||
char *backing_file;
|
||||
bool relinquished;
|
||||
dev_t backing_devno; /* The backing file's dev_t */
|
||||
ino_t backing_inode; /* The backing file's ino_t */
|
||||
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 */
|
||||
usec_t timestamp_not_before; /* CLOCK_MONOTONIC timestamp taken immediately before attaching the loopback device, or USEC_INFINITY if we don't know */
|
||||
@@ -47,3 +49,6 @@ int loop_device_refresh_size(LoopDevice *d, uint64_t offset, uint64_t size);
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user