• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 28485131107

30 Jun 2026 03:24PM UTC coverage: 72.877% (+0.07%) from 72.809%
28485131107

push

github

bluca
test: reduce number of disks in TEST-64-UDEV-STORAGE-simultaneous_events on Debian/Ubuntu

This test never finishes in Ubuntu autopkgtest with the current values,
and is currently skipped all together on Debian. When running on either,
reduce the number of disks to make the test more reliable.

341909 of 469157 relevant lines covered (72.88%)

1343417.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.05
/src/shared/loop-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#if HAVE_VALGRIND_MEMCHECK_H
4
#include <valgrind/memcheck.h>
5
#endif
6

7
#include <fcntl.h>
8
#include <linux/loop.h>
9
#include <sys/file.h>
10
#include <sys/ioctl.h>
11
#include <unistd.h>
12

13
#include "sd-device.h"
14

15
#include "alloc-util.h"
16
#include "blockdev-util.h"
17
#include "data-fd-util.h"
18
#include "device-private.h"
19
#include "device-util.h"
20
#include "devnum-util.h"
21
#include "dissect-image.h"
22
#include "env-util.h"
23
#include "errno-util.h"
24
#include "fd-util.h"
25
#include "fileio.h"
26
#include "fs-util.h"
27
#include "loop-util.h"
28
#include "parse-util.h"
29
#include "path-util.h"
30
#include "random-util.h"
31
#include "stat-util.h"
32
#include "stdio-util.h"
33
#include "string-util.h"
34
#include "strv.h"
35
#include "time-util.h"
36

37
static void cleanup_clear_loop_close(int *fd) {
2,559✔
38
        assert(fd);
2,559✔
39

40
        if (*fd < 0)
2,559✔
41
                return;
42

43
        (void) ioctl(*fd, LOOP_CLR_FD);
×
44
        (void) safe_close(*fd);
×
45
}
46

47
static int loop_is_bound(int fd) {
2,559✔
48
        struct loop_info64 info;
2,559✔
49

50
        if (ioctl(ASSERT_FD(fd), LOOP_GET_STATUS64, &info) < 0) {
2,559✔
51
                if (errno == ENXIO)
2,559✔
52
                        return false; /* not bound! */
2,559✔
53

54
                return -errno;
×
55
        }
56

57
        return true; /* bound! */
58
}
59

60
static int open_lock_fd(int primary_fd, int operation) {
2,720✔
61
        _cleanup_close_ int lock_fd = -EBADF;
2,720✔
62

63
        assert(IN_SET(operation & ~LOCK_NB, LOCK_SH, LOCK_EX));
2,720✔
64

65
        lock_fd = fd_reopen(ASSERT_FD(primary_fd), O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
2,720✔
66
        if (lock_fd < 0)
2,720✔
67
                return lock_fd;
68

69
        if (flock(lock_fd, operation) < 0)
2,720✔
70
                return -errno;
×
71

72
        return TAKE_FD(lock_fd);
73
}
74

75
static int loop_configure_verify_direct_io(int fd, const struct loop_config *c) {
2,559✔
76
        assert(fd >= 0);
2,559✔
77
        assert(c);
2,559✔
78

79
        if (FLAGS_SET(c->info.lo_flags, LO_FLAGS_DIRECT_IO)) {
2,559✔
80
                struct loop_info64 info;
2,558✔
81

82
                if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0)
2,558✔
83
                        return log_debug_errno(errno, "Failed to issue LOOP_GET_STATUS64: %m");
×
84

85
#if HAVE_VALGRIND_MEMCHECK_H
86
                VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
87
#endif
88

89
                /* On older kernels (<= 5.3) it was necessary to set the block size of the loopback block
90
                 * device to the logical block size of the underlying file system. Since there was no nice
91
                 * way to query the value, we are not bothering to do this however. On newer kernels the
92
                 * block size is propagated automatically and does not require intervention from us. We'll
93
                 * check here if enabling direct IO worked, to make this easily debuggable however.
94
                 *
95
                 * (Should anyone really care and actually wants direct IO on old kernels: it might be worth
96
                 * enabling direct IO with iteratively larger block sizes until it eventually works.)
97
                 *
98
                 * On older kernels (e.g.: 5.10) when this is attempted on a file stored on a dm-crypt
99
                 * backed partition the kernel will start returning I/O errors when accessing the mounted
100
                 * loop device, so return a recognizable error that causes the operation to be started
101
                 * from scratch without the LO_FLAGS_DIRECT_IO flag. */
102
                if (!FLAGS_SET(info.lo_flags, LO_FLAGS_DIRECT_IO))
2,558✔
103
                        return log_debug_errno(
×
104
                                        SYNTHETIC_ERRNO(ENOANO),
105
                                        "Could not enable direct IO mode, retrying in buffered IO mode.");
106
        }
107

108
        return 0;
109
}
110

111
static int loop_configure_verify(int fd, const struct loop_config *c) {
2,559✔
112
        bool broken = false;
2,559✔
113
        int r;
2,559✔
114

115
        assert(fd >= 0);
2,559✔
116
        assert(c);
2,559✔
117

118
        if (c->block_size != 0) {
2,559✔
119
                uint32_t ssz;
2,559✔
120

121
                r = blockdev_get_sector_size(fd, &ssz);
2,559✔
122
                if (r < 0)
2,559✔
123
                        return r;
×
124

125
                if (ssz != c->block_size) {
2,559✔
126
                        log_debug("LOOP_CONFIGURE didn't honour requested block size %" PRIu32 ", got %" PRIu32 " instead. Ignoring.", c->block_size, ssz);
×
127
                        broken = true;
128
                }
129
        }
130

131
        if (c->info.lo_sizelimit != 0) {
2,559✔
132
                /* Kernel 5.8 vanilla doesn't properly propagate the size limit into the
133
                 * block device. If it's used, let's immediately check if it had the desired
134
                 * effect hence. And if not use classic LOOP_SET_STATUS64. */
135
                uint64_t z;
102✔
136

137
                r = blockdev_get_device_size(fd, &z);
102✔
138
                if (r < 0)
102✔
139
                        return r;
×
140

141
                if (z != c->info.lo_sizelimit) {
102✔
142
                        log_debug("LOOP_CONFIGURE is broken, doesn't honour .info.lo_sizelimit. Falling back to LOOP_SET_STATUS64.");
×
143
                        broken = true;
144
                }
145
        }
146

147
        if (FLAGS_SET(c->info.lo_flags, LO_FLAGS_PARTSCAN)) {
2,559✔
148
                /* Kernel 5.8 vanilla doesn't properly propagate the partition scanning flag
149
                 * into the block device. Let's hence verify if things work correctly here
150
                 * before returning. */
151

152
                r = blockdev_partscan_enabled_fd(fd);
×
153
                if (r < 0)
×
154
                        return r;
155
                if (r == 0) {
×
156
                        log_debug("LOOP_CONFIGURE is broken, doesn't honour LO_FLAGS_PARTSCAN. Falling back to LOOP_SET_STATUS64.");
×
157
                        broken = true;
158
                }
159
        }
160

161
        r = loop_configure_verify_direct_io(fd, c);
2,559✔
162
        if (r < 0)
2,559✔
163
                return r;
164

165
        return !broken;
2,559✔
166
}
167

168
static int loop_configure_fallback(int fd, const struct loop_config *c) {
×
169
        struct loop_info64 info_copy;
×
170
        int r;
×
171

172
        assert(fd >= 0);
×
173
        assert(c);
×
174

175
        /* Only some of the flags LOOP_CONFIGURE can set are also settable via LOOP_SET_STATUS64, hence mask
176
         * them out. */
177
        info_copy = c->info;
×
178
        info_copy.lo_flags &= LOOP_SET_STATUS_SETTABLE_FLAGS;
×
179

180
        /* Since kernel commit 5db470e229e22b7eda6e23b5566e532c96fb5bc3 (kernel v5.0) the LOOP_SET_STATUS64
181
         * ioctl can return EAGAIN in case we change the info.lo_offset field, if someone else is accessing the
182
         * block device while we try to reconfigure it. This is a pretty common case, since udev might
183
         * instantly start probing the device as soon as we attach an fd to it. Hence handle it in two ways:
184
         * first, let's take the BSD lock to ensure that udev will not step in between the point in
185
         * time where we attach the fd and where we reconfigure the device. Secondly, let's wait 50ms on
186
         * EAGAIN and retry. The former should be an efficient mechanism to avoid we have to wait 50ms
187
         * needlessly if we are just racing against udev. The latter is protection against all other cases,
188
         * i.e. peers that do not take the BSD lock. */
189

190
        for (unsigned n_attempts = 0;;) {
×
191
                if (ioctl(fd, LOOP_SET_STATUS64, &info_copy) >= 0)
×
192
                        break;
193

194
                if (errno != EAGAIN || ++n_attempts >= 64)
×
195
                        return log_debug_errno(errno, "Failed to configure loopback block device: %m");
×
196

197
                /* Sleep some random time, but at least 10ms, at most 250ms. Increase the delay the more
198
                 * failed attempts we see */
199
                (void) usleep_safe(UINT64_C(10) * USEC_PER_MSEC +
×
200
                              random_u64_range(UINT64_C(240) * USEC_PER_MSEC * n_attempts/64));
×
201
        }
202

203
        /* If a block size is requested then try to configure it. If that doesn't work, ignore errors, but
204
         * afterwards, let's validate what is in effect, and if it doesn't match what we want, fail */
205
        if (c->block_size != 0) {
×
206
                uint32_t ssz;
×
207

208
                if (ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) c->block_size) < 0)
×
209
                        log_debug_errno(errno, "Failed to set sector size, ignoring: %m");
×
210

211
                r = blockdev_get_sector_size(fd, &ssz);
×
212
                if (r < 0)
×
213
                        return log_debug_errno(r, "Failed to read sector size: %m");
×
214
                if (ssz != c->block_size)
×
215
                        return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Sector size of loopback device doesn't match what we requested, refusing.");
×
216
        }
217

218
        /* LO_FLAGS_DIRECT_IO is a flags we need to configure via explicit ioctls. */
219
        if (FLAGS_SET(c->info.lo_flags, LO_FLAGS_DIRECT_IO))
×
220
                if (ioctl(fd, LOOP_SET_DIRECT_IO, 1UL) < 0)
×
221
                        log_debug_errno(errno, "Failed to enable direct IO mode, ignoring: %m");
×
222

223
        return loop_configure_verify_direct_io(fd, c);
×
224
}
225

226
static int loop_configure(
2,559✔
227
                int nr,
228
                int open_flags,
229
                int lock_op,
230
                const struct loop_config *c,
231
                LoopDevice **ret) {
232

233
        static bool loop_configure_broken = false;
2,559✔
234

235
        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
2,559✔
236
        _cleanup_(cleanup_clear_loop_close) int loop_with_fd = -EBADF; /* This must be declared before lock_fd. */
×
237
        _cleanup_close_ int fd = -EBADF, lock_fd = -EBADF;
5,118✔
238
        _cleanup_free_ char *node = NULL;
2,559✔
239
        uint64_t diskseq = 0;
2,559✔
240
        dev_t devno;
2,559✔
241
        int r;
2,559✔
242

243
        assert(nr >= 0);
2,559✔
244
        assert(c);
2,559✔
245
        assert(ret);
2,559✔
246

247
        if (asprintf(&node, "/dev/loop%i", nr) < 0)
2,559✔
248
                return log_oom_debug();
×
249

250
        r = sd_device_new_from_devname(&dev, node);
2,559✔
251
        if (r < 0)
2,559✔
252
                return log_debug_errno(r, "Failed to create sd_device object for \"%s\": %m", node);
×
253

254
        r = sd_device_get_devnum(dev, &devno);
2,559✔
255
        if (r < 0)
2,559✔
256
                return log_device_debug_errno(dev, r, "Failed to get devnum: %m");
×
257

258
        fd = sd_device_open(dev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags);
2,559✔
259
        if (fd < 0)
2,559✔
260
                return log_device_debug_errno(dev, fd, "Failed to open device: %m");
×
261

262
        /* Let's lock the device before we do anything. We take the BSD lock on a second, separately opened
263
         * fd for the device. udev after all watches for close() events (specifically IN_CLOSE_WRITE) on
264
         * block devices to reprobe them, hence by having a separate fd we will later close() we can ensure
265
         * we trigger udev after everything is done. If we'd lock our own fd instead and keep it open for a
266
         * long time udev would possibly never run on it again, even though the fd is unlocked, simply
267
         * because we never close() it. It also has the nice benefit we can use the _cleanup_close_ logic to
268
         * automatically release the lock, after we are done. */
269
        lock_fd = open_lock_fd(fd, LOCK_EX);
2,559✔
270
        if (lock_fd < 0)
2,559✔
271
                return log_device_debug_errno(dev, lock_fd, "Failed to acquire lock: %m");
×
272

273
        log_device_debug(dev, "Acquired exclusive lock.");
2,591✔
274

275
        /* Let's see if backing file is really unattached. Someone may already attach a backing file without
276
         * taking BSD lock. */
277
        r = loop_is_bound(fd);
2,559✔
278
        if (r < 0)
2,559✔
279
                return log_device_debug_errno(dev, r, "Failed to check if the loopback block device is bound: %m");
×
280
        if (r > 0)
2,559✔
281
                return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EBUSY),
×
282
                                              "The loopback block device is already bound, ignoring.");
283

284
        /* Let's see if the device is really detached, i.e. currently has no associated partition block
285
         * devices. On various kernels (such as 5.8) it is possible to have a loopback block device that
286
         * superficially is detached but still has partition block devices associated for it. Let's then
287
         * manually remove the partitions via BLKPG, and tell the caller we did that via EUCLEAN, so they try
288
         * again. */
289
        r = block_device_remove_all_partitions(dev, fd);
2,559✔
290
        if (r < 0)
2,559✔
291
                return log_device_debug_errno(dev, r, "Failed to remove partitions on the loopback block device: %m");
×
292
        if (r > 0)
2,559✔
293
                /* Removed all partitions. Let's report this to the caller, to try again, and count this as
294
                 * an attempt. */
295
                return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EUCLEAN),
×
296
                                              "Removed partitions on the loopback block device.");
297

298
        if (!loop_configure_broken) {
2,559✔
299
                if (ioctl(fd, LOOP_CONFIGURE, c) < 0) {
2,559✔
300
                        /* Do fallback only if LOOP_CONFIGURE is not supported, propagate all other errors. */
301
                        if (!ERRNO_IS_IOCTL_NOT_SUPPORTED(errno))
×
302
                                return log_device_debug_errno(dev, errno, "ioctl(LOOP_CONFIGURE) failed: %m");
×
303

304
                        loop_configure_broken = true;
×
305
                } else {
306
                        loop_with_fd = TAKE_FD(fd);
2,559✔
307

308
                        r = loop_configure_verify(loop_with_fd, c);
2,559✔
309
                        if (r < 0)
2,559✔
310
                                return log_device_debug_errno(dev, r, "Failed to verify if loopback block device is correctly configured: %m");
×
311
                        if (r == 0) {
2,559✔
312
                                /* LOOP_CONFIGURE doesn't work. Remember that. */
313
                                loop_configure_broken = true;
×
314

315
                                /* We return EBUSY here instead of retrying immediately with LOOP_SET_FD,
316
                                 * because LOOP_CLR_FD is async: if the operation cannot be executed right
317
                                 * away it just sets the autoclear flag on the device. This means there's a
318
                                 * good chance we cannot actually reuse the loopback device right-away. Hence
319
                                 * let's assume it's busy, avoid the trouble and let the calling loop call us
320
                                 * again with a new, likely unused device. */
321
                                return -EBUSY;
×
322
                        }
323
                }
324
        }
325

326
        if (loop_configure_broken) {
2,559✔
327
                if (ioctl(fd, LOOP_SET_FD, c->fd) < 0)
×
328
                        return log_device_debug_errno(dev, errno, "ioctl(LOOP_SET_FD) failed: %m");
×
329

330
                loop_with_fd = TAKE_FD(fd);
×
331

332
                r = loop_configure_fallback(loop_with_fd, c);
×
333
                if (r < 0)
×
334
                        return r;
335
        }
336

337
        r = fd_get_diskseq(loop_with_fd, &diskseq);
2,559✔
338
        if (r < 0 && r != -EOPNOTSUPP)
2,559✔
339
                return log_device_debug_errno(dev, r, "Failed to get diskseq: %m");
×
340

341
        switch (lock_op & ~LOCK_NB) {
2,559✔
342
        case LOCK_EX: /* Already in effect */
343
                break;
344
        case LOCK_SH: /* Downgrade */
2,423✔
345
                if (flock(lock_fd, lock_op) < 0)
2,423✔
346
                        return log_device_debug_errno(dev, errno, "Failed to downgrade lock level: %m");
×
347
                break;
348
        case LOCK_UN: /* Release */
×
349
                lock_fd = safe_close(lock_fd);
×
350
                break;
351
        default:
×
352
                assert_not_reached();
×
353
        }
354

355
        uint64_t device_size;
2,559✔
356
        r = blockdev_get_device_size(loop_with_fd, &device_size);
2,559✔
357
        if (r < 0)
2,559✔
358
                return log_device_debug_errno(dev, r, "Failed to get loopback device size: %m");
×
359

360
        LoopDevice *d = new(LoopDevice, 1);
2,559✔
361
        if (!d)
2,559✔
362
                return log_oom_debug();
×
363

364
        *d = (LoopDevice) {
2,559✔
365
                .n_ref = 1,
366
                .fd = TAKE_FD(loop_with_fd),
2,559✔
367
                .lock_fd = TAKE_FD(lock_fd),
2,559✔
368
                .node = TAKE_PTR(node),
2,559✔
369
                .nr = nr,
370
                .devno = devno,
371
                .dev = TAKE_PTR(dev),
2,559✔
372
                .diskseq = diskseq,
373
                .sector_size = c->block_size,
2,559✔
374
                .device_size = device_size,
375
                .created = true,
376
        };
377

378
        *ret = TAKE_PTR(d);
2,559✔
379
        return 0;
2,559✔
380
}
381

382
static int fd_get_max_discard(int fd, uint64_t *ret) {
×
383
        char sysfs_path[STRLEN("/sys/dev/block/" ":" "/queue/discard_max_bytes") + DECIMAL_STR_MAX(dev_t) * 2 + 1];
×
384
        _cleanup_free_ char *buffer = NULL;
×
385
        struct stat st;
×
386
        int r;
×
387

388
        assert(ret);
×
389

390
        if (fstat(ASSERT_FD(fd), &st) < 0)
×
391
                return -errno;
×
392

393
        r = stat_verify_block(&st);
×
394
        if (r < 0)
×
395
                return r;
396

397
        xsprintf(sysfs_path, "/sys/dev/block/" DEVNUM_FORMAT_STR "/queue/discard_max_bytes", DEVNUM_FORMAT_VAL(st.st_rdev));
×
398

399
        r = read_one_line_file(sysfs_path, &buffer);
×
400
        if (r < 0)
×
401
                return r;
402

403
        return safe_atou64(buffer, ret);
×
404
}
405

406
static int fd_set_max_discard(int fd, uint64_t max_discard) {
×
407
        char sysfs_path[STRLEN("/sys/dev/block/" ":" "/queue/discard_max_bytes") + DECIMAL_STR_MAX(dev_t) * 2 + 1];
×
408
        struct stat st;
×
409
        int r;
×
410

411
        if (fstat(ASSERT_FD(fd), &st) < 0)
×
412
                return -errno;
×
413

414
        r = stat_verify_block(&st);
×
415
        if (r < 0)
×
416
                return r;
417

418
        xsprintf(sysfs_path, "/sys/dev/block/" DEVNUM_FORMAT_STR "/queue/discard_max_bytes", DEVNUM_FORMAT_VAL(st.st_rdev));
×
419

420
        return write_string_filef(sysfs_path, WRITE_STRING_FILE_DISABLE_BUFFER, "%" PRIu64, max_discard);
×
421
}
422

423
static int probe_fd_open(int fd, int f_flags, int *ret_to_close) {
2,446✔
424
        int r;
2,446✔
425

426
        assert(fd >= 0);
2,446✔
427
        assert(ret_to_close);
2,446✔
428

429
        /* blkid- and pread-based probing has no special handling for the strict alignment requirements of
430
         * O_DIRECT, so if fd was opened with O_DIRECT we reopen it without for the probing logic. Returns the
431
         * fd to use for probing; when a new fd had to be opened it is also stored in *ret_to_close for the
432
         * caller to close, otherwise *ret_to_close is set to -EBADF and the original fd is returned. */
433

434
        if (!FLAGS_SET(f_flags, O_DIRECT)) {
2,446✔
435
                *ret_to_close = -EBADF;
7✔
436
                return fd;
7✔
437
        }
438

439
        r = fd_reopen(fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
2,439✔
440
        if (r < 0)
2,439✔
441
                return r;
442

443
        return (*ret_to_close = r);
2,439✔
444
}
445

446
static int fd_has_partition_table(int fd) {
2✔
447
        _cleanup_free_ char *pttype = NULL;
2✔
448
        int r;
2✔
449

450
        assert(fd >= 0);
2✔
451

452
        /* Checks whether the device carries a partition table the image dissection logic acts upon. We use
453
         * this to decide whether wrapping the device in a loopback device with partition scanning enabled
454
         * actually serves a purpose: if there are no partitions to expose we can hand back the original fd
455
         * instead. Expects an fd suitable for probing, i.e. opened without O_DIRECT (see probe_fd_open()). */
456

457
        r = probe_partition_table(fd, &pttype); /* already logs on error */
2✔
458
        if (r < 0)
2✔
459
                return r;
460

461
        /* Only GPT and MBR ("dos") tables are understood by the dissection logic and require partition
462
         * scanning to expose their partitions; anything else it treats as unpartitioned, so a loopback
463
         * device wouldn't help (and STRPTR_IN_SET() handles a NULL pttype, i.e. no table, as false). */
464
        return STRPTR_IN_SET(pttype, "gpt", "dos");
2✔
465
}
466

467
static int loop_device_can_shortcut(
3✔
468
                int fd,
469
                uint64_t offset,
470
                uint64_t size,
471
                uint32_t sector_size,
472
                uint32_t device_ssz,
473
                uint32_t loop_flags) {
474

475
        int r;
3✔
476

477
        /* Returns whether we can hand back the original block device fd instead of allocating a real
478
         * loopback device for it: it must cover the whole device, the requested sector size must match the
479
         * device's sector size, and if partscan was requested the device must either already have it enabled
480
         * or — unless the caller declared it may populate the image via LOOP_DEVICE_MAY_POPULATE_PARTITION_TABLE
481
         * — carry no partition table at all (in which case there are no partitions to scan and the loopback
482
         * would serve no purpose). */
483

484
        assert(fd >= 0);
3✔
485

486
        if (offset != 0)
3✔
487
                return false;
488
        if (!IN_SET(size, 0, UINT64_MAX))
3✔
489
                return false;
490
        if (sector_size != device_ssz)
3✔
491
                return false;
492

493
        if (FLAGS_SET(loop_flags, LO_FLAGS_PARTSCAN)) {
3✔
494
                r = blockdev_partscan_enabled_fd(fd);
3✔
495
                if (r < 0)
3✔
496
                        return r;
497
                if (r == 0) {
3✔
498
                        /* Partition scanning was requested but cannot be enabled on this device (e.g. it's a
499
                         * partition itself). If the caller might write a (nested) partition table into the
500
                         * device, it must get a real loopback device so scanning works once the table is
501
                         * there. */
502
                        if (FLAGS_SET(loop_flags, LOOP_DEVICE_MAY_POPULATE_PARTITION_TABLE))
2✔
503
                                return false;
504

505
                        /* Otherwise we shortcut when the device carries no partition table: there are then no
506
                         * partitions to scan, and routing e.g. a multi-device btrfs member through a loop
507
                         * device breaks it, see https://github.com/systemd/systemd/issues/42520.
508
                         *
509
                         * If we can't probe the device, fall back to allocating a real loop device rather than
510
                         * failing the whole operation: we can't prove there's no partition table, and the
511
                         * image is potentially untrusted (a crafted or corrupt partition table can make the
512
                         * probe fail, e.g. with -EUCLEAN), so failing here would be a fail-unsafe DoS. */
513
                        r = fd_has_partition_table(fd);
2✔
514
                        if (r != 0)
2✔
515
                                return false;
×
516
                }
517
        }
518

519
        return true;
520
}
521

522
static int loop_device_make_internal(
2,582✔
523
                const char *path,
524
                int fd,
525
                int open_flags,
526
                uint64_t offset,
527
                uint64_t size,
528
                uint32_t sector_size,
529
                uint32_t loop_flags,
530
                int lock_op,
531
                LoopDevice **ret) {
532

533
        _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
×
534
        _cleanup_close_ int reopened_fd = -EBADF, control = -EBADF, probe_close_fd = -EBADF;
7,746✔
535
        _cleanup_free_ char *backing_file = NULL;
2,582✔
536
        struct loop_config config;
2,582✔
537
        int r, f_flags, probe_fd = -EBADF;
2,582✔
538
        struct stat st;
2,582✔
539

540
        assert(fd >= 0);
2,582✔
541
        assert(open_flags < 0 || IN_SET(open_flags, O_RDWR, O_RDONLY));
2,582✔
542
        assert(ret);
2,582✔
543

544
        /* sector_size interpretation:
545
         *   0          → use device sector size for block devices, 512 for regular files
546
         *   UINT32_MAX → probe GPT header to find the right sector size, fall back to 0 behavior
547
         *   other      → use the specified sector size explicitly */
548

549
        f_flags = fcntl(fd, F_GETFL);
2,582✔
550
        if (f_flags < 0)
2,582✔
551
                return -errno;
×
552

553
        if (open_flags < 0) {
2,582✔
554
                /* If open_flags is unset, initialize it from the open fd */
555
                if (FLAGS_SET(f_flags, O_PATH))
6✔
556
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADFD), "Access mode of image file indicates O_PATH, cannot determine read/write flags.");
×
557

558
                open_flags = f_flags & O_ACCMODE_STRICT;
6✔
559
                if (!IN_SET(open_flags, O_RDWR, O_RDONLY))
6✔
560
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADFD), "Access mode of image file is write only (?)");
×
561
        }
562

563
        if (sector_size == UINT32_MAX) {
2,582✔
564
                /* If sector size is specified as UINT32_MAX, we'll try to probe the right sector size
565
                 * by looking for the GPT partition header at various offsets. This of course only works
566
                 * if the image already has a disk label. */
567

568
                if (probe_fd < 0) {
2,446✔
569
                        probe_fd = probe_fd_open(fd, f_flags, &probe_close_fd);
2,446✔
570
                        if (probe_fd < 0)
2,446✔
571
                                return probe_fd;
572
                }
573

574
                r = probe_sector_size(probe_fd, &sector_size);
2,446✔
575
                if (r < 0)
2,446✔
576
                        return r;
577
                if (r == 0)
2,446✔
578
                        sector_size = 0; /* If we can't probe anything, use default sector size. */
2,326✔
579
        }
580

581
        if (fstat(fd, &st) < 0)
2,582✔
582
                return -errno;
×
583

584
        if (S_ISBLK(st.st_mode)) {
2,582✔
585
                uint32_t device_ssz;
3✔
586
                r = blockdev_get_sector_size(fd, &device_ssz);
3✔
587
                if (r < 0)
3✔
588
                        return r;
3✔
589

590
                if (sector_size == 0)
3✔
591
                        sector_size = device_ssz;
2✔
592

593
                if (probe_fd < 0) {
3✔
594
                        probe_fd = probe_fd_open(fd, f_flags, &probe_close_fd);
×
595
                        if (probe_fd < 0)
×
596
                                return probe_fd;
597
                }
598

599
                r = loop_device_can_shortcut(probe_fd, offset, size, sector_size, device_ssz, loop_flags);
3✔
600
                if (r < 0)
3✔
601
                        return r;
602
                if (r > 0)
3✔
603
                        return loop_device_open_from_fd(fd, open_flags, lock_op, ret);
3✔
604
        } else {
605
                r = stat_verify_regular(&st);
2,579✔
606
                if (r < 0)
2,579✔
607
                        return r;
608

609
                if (sector_size == 0)
2,579✔
610
                        sector_size = 512;
2,324✔
611
        }
612

613
        if (path) {
2,579✔
614
                r = path_make_absolute_cwd(path, &backing_file);
357✔
615
                if (r < 0)
357✔
616
                        return r;
617

618
                path_simplify(backing_file);
357✔
619
        } else {
620
                r = fd_get_path(fd, &backing_file);
2,222✔
621
                if (r < 0)
2,222✔
622
                        return r;
623
        }
624

625
        if (FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) != FLAGS_SET(f_flags, O_DIRECT)) {
2,579✔
626
                /* If LO_FLAGS_DIRECT_IO is requested, then make sure we have the fd open with O_DIRECT, as
627
                 * that's required. Conversely, if it's off require that O_DIRECT is off too (that's because
628
                 * new kernels will implicitly enable LO_FLAGS_DIRECT_IO if O_DIRECT is set).
629
                 *
630
                 * Our intention here is that LO_FLAGS_DIRECT_IO is the primary knob, and O_DIRECT derived
631
                 * from that automatically. */
632

633
                reopened_fd = fd_reopen(fd, (FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) ? O_DIRECT : 0)|O_CLOEXEC|O_NONBLOCK|open_flags);
142✔
634
                if (reopened_fd < 0) {
142✔
635
                        if (!FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO))
×
636
                                return log_debug_errno(reopened_fd, "Failed to reopen file descriptor without O_DIRECT: %m");
×
637

638
                        /* Some file systems might not support O_DIRECT, let's gracefully continue without it then. */
639
                        log_debug_errno(reopened_fd, "Failed to enable O_DIRECT for backing file descriptor for loopback device. Continuing without.");
×
640
                        loop_flags &= ~LO_FLAGS_DIRECT_IO;
×
641
                } else
642
                        fd = reopened_fd; /* From now on, operate on our new O_DIRECT fd */
643
        }
644

645
        control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
2,579✔
646
        if (control < 0)
2,579✔
647
                return -errno;
20✔
648

649
        /* Strip LO_FLAGS_PARTSCAN from LOOP_CONFIGURE and enable it afterwards via
650
         * LOOP_SET_STATUS64 to work around a kernel race: LOOP_CONFIGURE sends a uevent with
651
         * GD_NEED_PART_SCAN set before calling loop_reread_partitions(). If udev opens the device in
652
         * response, blkdev_get_whole() triggers a first scan, then loop_reread_partitions() does a
653
         * second scan that briefly drops all partitions. By configuring without partscan,
654
         * GD_SUPPRESS_PART_SCAN stays set, making any concurrent open harmless. LOOP_SET_STATUS64
655
         * doesn't call disk_force_media_change() so it doesn't set GD_NEED_PART_SCAN.
656
         *
657
         * See: https://lore.kernel.org/linux-block/20260330081819.652890-1-daan@amutable.com/T/#u
658
         * Drop this workaround once the kernel fix is widely available. */
659
        bool deferred_partscan = FLAGS_SET(loop_flags, LO_FLAGS_PARTSCAN);
2,559✔
660

661
        config = (struct loop_config) {
5,118✔
662
                .fd = fd,
663
                .block_size = sector_size,
664
                .info = {
665
                        /* Use the specified flags, but strip our systemd-internal flags and the read-only and
666
                         * partscan flags (the latter handled separately below/above), and force autoclear */
667
                        .lo_flags = ((loop_flags & ~(LOOP_DEVICE_MAY_POPULATE_PARTITION_TABLE|LO_FLAGS_READ_ONLY|LO_FLAGS_PARTSCAN)) |
5,118✔
668
                                     ((open_flags & O_ACCMODE_STRICT) == O_RDONLY ? LO_FLAGS_READ_ONLY : 0) |
2,559✔
669
                                     LO_FLAGS_AUTOCLEAR),
670
                        .lo_offset = offset,
671
                        .lo_sizelimit = size == UINT64_MAX ? 0 : size,
2,559✔
672
                },
673
        };
674

675
        /* Loop around LOOP_CTL_GET_FREE, since at the moment we attempt to open the returned device it might
676
         * be gone already, taken by somebody else racing against us. */
677
        for (unsigned n_attempts = 0;;) {
2,559✔
678
                usec_t usec;
2,559✔
679
                int nr;
2,559✔
680

681
                /* Let's take a lock on the control device first. On a busy system, where many programs
682
                 * attempt to allocate a loopback device at the same time, we might otherwise keep looping
683
                 * around relatively heavy operations: asking for a free loopback device, then opening it,
684
                 * validating it, attaching something to it. Let's serialize this whole operation, to make
685
                 * unnecessary busywork less likely. Note that this is just something we do to optimize our
686
                 * own code (and whoever else decides to use LOCK_EX locks for this), taking this lock is not
687
                 * necessary, it just means it's less likely we have to iterate through this loop again and
688
                 * again if our own code races against our own code.
689
                 *
690
                 * Note: our lock protocol is to take the /dev/loop-control lock first, and the block device
691
                 * lock second, if both are taken, and always in this order, to avoid ABBA locking issues. */
692
                if (flock(control, LOCK_EX) < 0)
2,559✔
693
                        return -errno;
×
694

695
                nr = ioctl(control, LOOP_CTL_GET_FREE);
2,559✔
696
                if (nr < 0)
2,559✔
697
                        return -errno;
×
698

699
                r = loop_configure(nr, open_flags, lock_op, &config, &d);
2,559✔
700
                if (r >= 0)
2,559✔
701
                        break;
702

703
                /* -ENODEV or friends: Somebody might've gotten the same number from the kernel, used the
704
                 * device, and called LOOP_CTL_REMOVE on it. Let's retry with a new number.
705
                 * -EBUSY: a file descriptor is already bound to the loopback block device.
706
                 * -EUCLEAN: some left-over partition devices that were cleaned up.
707
                 * -ENOANO: we tried to use LO_FLAGS_DIRECT_IO but the kernel rejected it. */
708
                if (!ERRNO_IS_DEVICE_ABSENT(r) && !IN_SET(r, -EBUSY, -EUCLEAN, -ENOANO))
×
709
                        return r;
710

711
                /* OK, this didn't work, let's try again a bit later, but first release the lock on the
712
                 * control device */
713
                if (flock(control, LOCK_UN) < 0)
×
714
                        return -errno;
×
715

716
                if (++n_attempts >= 64) /* Give up eventually */
×
717
                        return -EBUSY;
718

719
                /* If we failed to enable direct IO mode, let's retry without it. We restart the process as
720
                 * on some combination of kernel version and storage filesystem, the kernel is very unhappy
721
                 * about a failed DIRECT_IO enablement and throws I/O errors. */
722
                if (r == -ENOANO && FLAGS_SET(config.info.lo_flags, LO_FLAGS_DIRECT_IO)) {
×
723
                        config.info.lo_flags &= ~LO_FLAGS_DIRECT_IO;
×
724
                        open_flags &= ~O_DIRECT;
×
725

726
                        int non_direct_io_fd = fd_reopen(config.fd, O_CLOEXEC|O_NONBLOCK|open_flags);
×
727
                        if (non_direct_io_fd < 0)
×
728
                                return log_debug_errno(
×
729
                                                non_direct_io_fd,
730
                                                "Failed to reopen file descriptor without O_DIRECT: %m");
731

732
                        safe_close(reopened_fd);
×
733
                        fd = config.fd = /* For cleanups */ reopened_fd = non_direct_io_fd;
×
734
                }
735

736
                /* Wait some random time, to make collision less likely. Let's pick a random time in the
737
                 * range 0ms…250ms, linearly scaled by the number of failed attempts. */
738
                usec = random_u64_range(UINT64_C(10) * USEC_PER_MSEC +
×
739
                                        UINT64_C(240) * USEC_PER_MSEC * n_attempts/64);
×
740
                log_debug("Trying again after %s.", FORMAT_TIMESPAN(usec, USEC_PER_MSEC));
×
741
                (void) usleep_safe(usec);
×
742
        }
743

744
        if (S_ISBLK(st.st_mode)) {
2,559✔
745
                /* Propagate backing device's discard byte limit to our loopback block device. We do this in
746
                 * order to avoid that (supposedly quick) discard requests on the loopback device get turned
747
                 * into (likely slow) zero-out requests on backing devices that do not support discarding
748
                 * natively, but do support zero-out. */
749
                uint64_t discard_max_bytes;
×
750

751
                r = fd_get_max_discard(fd, &discard_max_bytes);
×
752
                if (r < 0)
×
753
                        log_debug_errno(r, "Failed to read 'discard_max_bytes' of backing device, ignoring: %m");
×
754
                else {
755
                        r = fd_set_max_discard(d->fd, discard_max_bytes);
×
756
                        if (r < 0)
×
757
                                log_debug_errno(r, "Failed to write 'discard_max_bytes' of loop device, ignoring: %m");
×
758
                }
759
        }
760

761
        if (deferred_partscan) {
2,559✔
762
                /* Open+close to drain GD_NEED_PART_SCAN harmlessly (GD_SUPPRESS_PART_SCAN is still
763
                 * set so no partitions appear). Then enable partscan via LOOP_SET_STATUS64. */
764
                int tmp_fd = fd_reopen(d->fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
2,379✔
765
                if (tmp_fd < 0)
2,379✔
766
                        return log_debug_errno(tmp_fd, "Failed to reopen loop device to drain partscan flag: %m");
×
767
                safe_close(tmp_fd);
2,379✔
768

769
                struct loop_info64 info;
2,379✔
770
                if (ioctl(d->fd, LOOP_GET_STATUS64, &info) < 0)
2,379✔
771
                        return log_debug_errno(errno, "Failed to get loop device status: %m");
×
772

773
                info.lo_flags |= LO_FLAGS_PARTSCAN;
2,379✔
774

775
                if (ioctl(d->fd, LOOP_SET_STATUS64, &info) < 0)
2,379✔
776
                        return log_debug_errno(errno, "Failed to enable partscan on loop device: %m");
×
777
        }
778

779
        d->backing_file = TAKE_PTR(backing_file);
2,559✔
780
        d->backing_inode = st.st_ino;
2,559✔
781
        d->backing_devno = st.st_dev;
2,559✔
782

783
        log_debug("Successfully acquired %s, devno=%u:%u, nr=%i, diskseq=%" PRIu64,
2,559✔
784
                  d->node,
785
                  major(d->devno), minor(d->devno),
786
                  d->nr,
787
                  d->diskseq);
788

789
        *ret = TAKE_PTR(d);
2,559✔
790
        return 0;
2,559✔
791
}
792

793
static uint32_t loop_flags_mangle(uint32_t loop_flags) {
2,582✔
794
        int r;
2,582✔
795

796
        r = getenv_bool("SYSTEMD_LOOP_DIRECT_IO");
2,582✔
797
        if (r < 0 && r != -ENXIO)
2,582✔
798
                log_debug_errno(r, "Failed to parse $SYSTEMD_LOOP_DIRECT_IO, ignoring: %m");
×
799

800
        return UPDATE_FLAG(loop_flags, LO_FLAGS_DIRECT_IO, r != 0); /* Turn on LO_FLAGS_DIRECT_IO by default, unless explicitly configured to off. */
2,582✔
801
}
802

803
int loop_device_make(
142✔
804
                int fd,
805
                int open_flags,
806
                uint64_t offset,
807
                uint64_t size,
808
                uint32_t sector_size,
809
                uint32_t loop_flags,
810
                int lock_op,
811
                LoopDevice **ret) {
812

813
        assert(fd >= 0);
142✔
814
        assert(ret);
142✔
815

816
        return loop_device_make_internal(
142✔
817
                        NULL,
818
                        fd,
819
                        open_flags,
820
                        offset,
821
                        size,
822
                        sector_size,
823
                        loop_flags_mangle(loop_flags),
824
                        lock_op,
825
                        ret);
826
}
827

828
int loop_device_make_by_path_at(
2,440✔
829
                int dir_fd,
830
                const char *path,
831
                int open_flags,
832
                uint32_t sector_size,
833
                uint32_t loop_flags,
834
                int lock_op,
835
                LoopDevice **ret) {
836

837
        int r, basic_flags, direct_flags, rdwr_flags;
2,440✔
838
        _cleanup_close_ int fd = -EBADF;
2,440✔
839
        bool direct = false;
2,440✔
840

841
        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
2,440✔
842
        assert(ret);
2,440✔
843
        assert(open_flags < 0 || IN_SET(open_flags, O_RDWR, O_RDONLY));
2,440✔
844

845
        /* Passing < 0 as open_flags here means we'll try to open the device writable if we can, retrying
846
         * read-only if we cannot. */
847

848
        loop_flags = loop_flags_mangle(loop_flags);
2,440✔
849

850
        /* Let's open with O_DIRECT if we can. But not all file systems support that, hence fall back to
851
         * non-O_DIRECT mode automatically, if it fails. */
852

853
        basic_flags = O_CLOEXEC|O_NONBLOCK|O_NOCTTY;
2,440✔
854
        direct_flags = FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) ? O_DIRECT : 0;
2,440✔
855
        rdwr_flags = open_flags >= 0 ? open_flags : O_RDWR;
2,440✔
856

857
        fd = xopenat(dir_fd, path, basic_flags|direct_flags|rdwr_flags);
2,440✔
858
        if (fd < 0 && direct_flags != 0) /* If we had O_DIRECT on, and things failed with that, let's immediately try again without */
2,440✔
859
                fd = xopenat(dir_fd, path, basic_flags|rdwr_flags);
1✔
860
        else
861
                direct = direct_flags != 0;
×
862
        if (fd < 0) {
2,440✔
863
                r = fd;
1✔
864

865
                /* Retry read-only? */
866
                if (open_flags >= 0 || !ERRNO_IS_NEG_FS_WRITE_REFUSED(r))
2,441✔
867
                        return r;
868

869
                fd = xopenat(dir_fd, path, basic_flags|direct_flags|O_RDONLY);
×
870
                if (fd < 0 && direct_flags != 0) /* as above */
×
871
                        fd = xopenat(dir_fd, path, basic_flags|O_RDONLY);
×
872
                else
873
                        direct = direct_flags != 0;
×
874
                if (fd < 0)
×
875
                        return r; /* Propagate original error */
876

877
                open_flags = O_RDONLY;
878
        } else if (open_flags < 0)
2,439✔
879
                open_flags = O_RDWR;
164✔
880

881
        log_debug("Opened %s in %s access mode%s, with O_DIRECT %s%s.",
11,608✔
882
                  path ?: "loop device",
883
                  open_flags == O_RDWR ? "O_RDWR" : "O_RDONLY",
884
                  open_flags != rdwr_flags ? " (O_RDWR was requested but not allowed)" : "",
885
                  direct ? "enabled" : "disabled",
886
                  direct != (direct_flags != 0) ? " (O_DIRECT was requested but not supported)" : "");
887

888
        return loop_device_make_internal(
4,518✔
889
                        dir_fd == AT_FDCWD ? path : NULL,
890
                        fd,
891
                        open_flags,
892
                        /* offset= */ 0,
893
                        /* size= */ 0,
894
                        sector_size,
895
                        loop_flags,
896
                        lock_op,
897
                        ret);
898
}
899

900
int loop_device_make_by_path_memory(
1✔
901
                const char *path,
902
                int open_flags,
903
                uint32_t sector_size,
904
                uint32_t loop_flags,
905
                int lock_op,
906
                LoopDevice **ret) {
907

908
        _cleanup_close_ int fd = -EBADF, mfd = -EBADF;
1✔
909
        _cleanup_free_ char *fn = NULL;
1✔
910
        int r;
1✔
911

912
        assert(path);
1✔
913
        assert(open_flags < 0 || IN_SET(open_flags, O_RDWR, O_RDONLY));
1✔
914
        assert(ret);
1✔
915

916
        /* memfds are always writable, so default to O_RDWR when auto-detecting. */
917
        if (open_flags < 0)
1✔
918
                open_flags = O_RDWR;
1✔
919

920
        loop_flags &= ~LO_FLAGS_DIRECT_IO; /* memfds don't support O_DIRECT, hence LO_FLAGS_DIRECT_IO can't be used either */
1✔
921

922
        fd = open(path, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_RDONLY);
1✔
923
        if (fd < 0)
1✔
924
                return -errno;
×
925

926
        r = fd_verify_regular_or_block(fd);
1✔
927
        if (r < 0)
1✔
928
                return r;
929

930
        r = path_extract_filename(path, &fn);
1✔
931
        if (r < 0)
1✔
932
                return r;
933

934
        mfd = memfd_clone_fd(fd, fn, open_flags|O_CLOEXEC);
1✔
935
        if (mfd < 0)
1✔
936
                return mfd;
937

938
        fd = safe_close(fd); /* Let's close the original early */
1✔
939

940
        return loop_device_make_internal(NULL, mfd, open_flags, 0, 0, sector_size, loop_flags, lock_op, ret);
1✔
941
}
942

943
static LoopDevice* loop_device_free(LoopDevice *d) {
2,620✔
944
        _cleanup_close_ int control = -EBADF;
2,620✔
945
        int r;
2,620✔
946

947
        if (!d)
2,620✔
948
                return NULL;
949

950
        /* Release any lock we might have on the device first. We want to open+lock the /dev/loop-control
951
         * device below, but our lock protocol says that if both control and block device locks are taken,
952
         * the control lock needs to be taken first, the block device lock second — in order to avoid ABBA
953
         * locking issues. Moreover, we want to issue LOOP_CLR_FD on the block device further down, and that
954
         * would fail if we had another fd open to the device. */
955
        d->lock_fd = safe_close(d->lock_fd);
2,620✔
956

957
        /* Let's open the control device early, and lock it, so that we can release our block device and
958
         * delete it in a synchronized fashion, and allocators won't needlessly see the block device as free
959
         * while we are about to delete it. */
960
        if (!LOOP_DEVICE_IS_FOREIGN(d) && !d->relinquished) {
2,620✔
961
                control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
2,288✔
962
                if (control < 0)
2,288✔
963
                        log_debug_errno(errno, "Failed to open loop control device, cannot remove loop device '%s', ignoring: %m", strna(d->node));
×
964
                else if (flock(control, LOCK_EX) < 0)
2,288✔
965
                        log_debug_errno(errno, "Failed to lock loop control device, ignoring: %m");
×
966
        }
967

968
        /* Then let's release the loopback block device */
969
        if (d->fd >= 0) {
2,620✔
970
                /* Implicitly sync the device, since otherwise in-flight blocks might not get written */
971
                if (fsync(d->fd) < 0)
2,620✔
972
                        log_debug_errno(errno, "Failed to sync loop block device, ignoring: %m");
×
973

974
                if (!LOOP_DEVICE_IS_FOREIGN(d) && !d->relinquished) {
2,620✔
975
                        /* We are supposed to clear the loopback device. Let's do this synchronously: lock
976
                         * the device, manually remove all partitions and then clear it. This should ensure
977
                         * udev doesn't concurrently access the devices, and we can be reasonably sure that
978
                         * once we are done here the device is cleared and all its partition children
979
                         * removed. Note that we lock our primary device fd here (and not a separate locking
980
                         * fd, as we do during allocation, since we want to keep the lock all the way through
981
                         * the LOOP_CLR_FD, but that call would fail if we had more than one fd open.) */
982

983
                        if (flock(d->fd, LOCK_EX) < 0)
2,288✔
984
                                log_debug_errno(errno, "Failed to lock loop block device, ignoring: %m");
×
985

986
                        r = block_device_remove_all_partitions(d->dev, d->fd);
2,288✔
987
                        if (r < 0)
2,288✔
988
                                log_debug_errno(r, "Failed to remove partitions of loopback block device, ignoring: %m");
×
989

990
                        if (ioctl(d->fd, LOOP_CLR_FD) < 0)
2,288✔
991
                                log_debug_errno(errno, "Failed to clear loop device, ignoring: %m");
×
992
                }
993

994
                safe_close(d->fd);
2,620✔
995
        }
996

997
        /* Now that the block device is released, let's also try to remove it */
998
        if (control >= 0) {
2,620✔
999
                useconds_t delay = 5 * USEC_PER_MSEC;  /* A total delay of 5090 ms between 39 attempts,
1000
                                                        * (4*5 + 5*10 + 5*20 + … + 3*640) = 5090. */
1001

1002
                for (unsigned attempt = 1;; attempt++) {
200✔
1003
                        if (ioctl(control, LOOP_CTL_REMOVE, d->nr) >= 0)
2,488✔
1004
                                break;
1005
                        if (errno != EBUSY || attempt > 38) {
201✔
1006
                                log_debug_errno(errno, "Failed to remove device %s: %m", strna(d->node));
1✔
1007
                                break;
1008
                        }
1009
                        if (attempt % 5 == 0) {
200✔
1010
                                log_debug("Device is still busy after %u attempts…", attempt);
20✔
1011
                                delay *= 2;
20✔
1012
                        }
1013

1014
                        (void) usleep_safe(delay);
200✔
1015
                }
1016
        }
1017

1018
        free(d->node);
2,620✔
1019
        sd_device_unref(d->dev);
2,620✔
1020
        free(d->backing_file);
2,620✔
1021
        return mfree(d);
2,620✔
1022
}
1023

1024
DEFINE_TRIVIAL_REF_UNREF_FUNC(LoopDevice, loop_device, loop_device_free);
10,567✔
1025

1026
void loop_device_relinquish(LoopDevice *d) {
218✔
1027
        assert(d);
218✔
1028

1029
        /* Don't attempt to clean up the loop device anymore from this point on. Leave the clean-ing up to the kernel
1030
         * itself, using the loop device "auto-clear" logic we already turned on when creating the device. */
1031

1032
        d->relinquished = true;
218✔
1033
}
218✔
1034

1035
void loop_device_unrelinquish(LoopDevice *d) {
43✔
1036
        assert(d);
43✔
1037
        d->relinquished = false;
43✔
1038
}
43✔
1039

1040
int loop_device_open(
160✔
1041
                sd_device *dev,
1042
                int open_flags,
1043
                int lock_op,
1044
                LoopDevice **ret) {
1045

1046
        _cleanup_close_ int fd = -EBADF, lock_fd = -EBADF;
160✔
1047
        _cleanup_free_ char *node = NULL, *backing_file = NULL;
160✔
1048
        dev_t devnum, backing_devno = 0;
160✔
1049
        struct loop_info64 info;
160✔
1050
        ino_t backing_inode = 0;
160✔
1051
        uint64_t diskseq = 0;
160✔
1052
        LoopDevice *d;
160✔
1053
        const char *s;
160✔
1054
        int r, nr = -1;
160✔
1055

1056
        assert(dev);
160✔
1057
        assert(IN_SET(open_flags, O_RDWR, O_RDONLY));
160✔
1058
        assert(ret);
160✔
1059

1060
        /* Even if fd is provided through the argument in loop_device_open_from_fd(), we reopen the inode
1061
         * here, instead of keeping just a dup() clone of it around, since we want to ensure that the
1062
         * O_DIRECT flag of the handle we keep is off, we have our own file index, and have the right
1063
         * read/write mode in effect. */
1064
        fd = sd_device_open(dev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags);
160✔
1065
        if (fd < 0)
160✔
1066
                return fd;
1067

1068
        if ((lock_op & ~LOCK_NB) != LOCK_UN) {
160✔
1069
                lock_fd = open_lock_fd(fd, lock_op);
160✔
1070
                if (lock_fd < 0)
160✔
1071
                        return lock_fd;
1072
        }
1073

1074
        if (ioctl(fd, LOOP_GET_STATUS64, &info) >= 0) {
160✔
1075
#if HAVE_VALGRIND_MEMCHECK_H
1076
                /* Valgrind currently doesn't know LOOP_GET_STATUS64. Remove this once it does */
1077
                VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
1078
#endif
1079
                nr = info.lo_number;
51✔
1080

1081
                if (device_get_sysattr_safe_string(dev, "loop/backing_file", &s) >= 0) {
51✔
1082
                        backing_file = strdup(s);
39✔
1083
                        if (!backing_file)
39✔
1084
                                return -ENOMEM;
1085
                }
1086

1087
                backing_devno = info.lo_device;
51✔
1088
                backing_inode = info.lo_inode;
51✔
1089
        }
1090

1091
        r = fd_get_diskseq(fd, &diskseq);
160✔
1092
        if (r < 0 && r != -EOPNOTSUPP)
160✔
1093
                return r;
1094

1095
        uint32_t sector_size;
160✔
1096
        r = blockdev_get_sector_size(fd, &sector_size);
160✔
1097
        if (r < 0)
160✔
1098
                return r;
1099

1100
        uint64_t device_size;
160✔
1101
        r = blockdev_get_device_size(fd, &device_size);
160✔
1102
        if (r < 0)
160✔
1103
                return r;
1104

1105
        r = sd_device_get_devnum(dev, &devnum);
160✔
1106
        if (r < 0)
160✔
1107
                return r;
1108

1109
        r = sd_device_get_devname(dev, &s);
160✔
1110
        if (r < 0)
160✔
1111
                return r;
1112

1113
        node = strdup(s);
160✔
1114
        if (!node)
160✔
1115
                return -ENOMEM;
1116

1117
        d = new(LoopDevice, 1);
160✔
1118
        if (!d)
160✔
1119
                return -ENOMEM;
1120

1121
        *d = (LoopDevice) {
320✔
1122
                .n_ref = 1,
1123
                .fd = TAKE_FD(fd),
160✔
1124
                .lock_fd = TAKE_FD(lock_fd),
160✔
1125
                .nr = nr,
1126
                .node = TAKE_PTR(node),
160✔
1127
                .dev = sd_device_ref(dev),
160✔
1128
                .backing_file = TAKE_PTR(backing_file),
160✔
1129
                .backing_inode = backing_inode,
1130
                .backing_devno = backing_devno,
1131
                .relinquished = true, /* It's not ours, don't try to destroy it when this object is freed */
1132
                .devno = devnum,
1133
                .diskseq = diskseq,
1134
                .sector_size = sector_size,
1135
                .device_size = device_size,
1136
                .created = false,
1137
        };
1138

1139
        *ret = d;
160✔
1140
        return 0;
160✔
1141
}
1142

1143
int loop_device_open_from_fd(
26✔
1144
                int fd,
1145
                int open_flags,
1146
                int lock_op,
1147
                LoopDevice **ret) {
1148

1149
        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
26✔
1150
        int r;
26✔
1151

1152
        r = block_device_new_from_fd(ASSERT_FD(fd), 0, &dev);
26✔
1153
        if (r < 0)
26✔
1154
                return r;
1155

1156
        return loop_device_open(dev, open_flags, lock_op, ret);
26✔
1157
}
1158

1159
int loop_device_open_from_path(
×
1160
                const char *path,
1161
                int open_flags,
1162
                int lock_op,
1163
                LoopDevice **ret) {
1164

1165
        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
×
1166
        int r;
×
1167

1168
        assert(path);
×
1169

1170
        r = block_device_new_from_path(path, 0, &dev);
×
1171
        if (r < 0)
×
1172
                return r;
1173

1174
        return loop_device_open(dev, open_flags, lock_op, ret);
×
1175
}
1176

1177
static int resize_partition(int partition_fd, uint64_t offset, uint64_t size) {
×
1178
        char sysfs[STRLEN("/sys/dev/block/:/partition") + 2*DECIMAL_STR_MAX(dev_t) + 1];
×
1179
        _cleanup_free_ char *buffer = NULL;
×
1180
        uint64_t current_offset, current_size, partno;
×
1181
        _cleanup_close_ int whole_fd = -EBADF;
×
1182
        struct stat st;
×
1183
        dev_t devno;
×
1184
        int r;
×
1185

1186
        /* Resizes the partition the loopback device refer to (assuming it refers to one instead of an actual
1187
         * loopback device), and changes the offset, if needed. This is a fancy wrapper around
1188
         * BLKPG_RESIZE_PARTITION. */
1189

1190
        if (fstat(ASSERT_FD(partition_fd), &st) < 0)
×
1191
                return -errno;
×
1192

1193
        assert(S_ISBLK(st.st_mode));
×
1194

1195
        xsprintf(sysfs, "/sys/dev/block/" DEVNUM_FORMAT_STR "/partition", DEVNUM_FORMAT_VAL(st.st_rdev));
×
1196
        r = read_one_line_file(sysfs, &buffer);
×
1197
        if (r == -ENOENT) /* not a partition, cannot resize */
×
1198
                return -ENOTTY;
1199
        if (r < 0)
×
1200
                return r;
1201
        r = safe_atou64(buffer, &partno);
×
1202
        if (r < 0)
×
1203
                return r;
1204

1205
        xsprintf(sysfs, "/sys/dev/block/" DEVNUM_FORMAT_STR "/start", DEVNUM_FORMAT_VAL(st.st_rdev));
×
1206

1207
        buffer = mfree(buffer);
×
1208
        r = read_one_line_file(sysfs, &buffer);
×
1209
        if (r < 0)
×
1210
                return r;
1211
        r = safe_atou64(buffer, &current_offset);
×
1212
        if (r < 0)
×
1213
                return r;
1214
        if (current_offset > UINT64_MAX/512U)
×
1215
                return -EINVAL;
1216
        current_offset *= 512U;
×
1217

1218
        r = blockdev_get_device_size(partition_fd, &current_size);
×
1219
        if (r < 0)
×
1220
                return r;
1221

1222
        if (size == UINT64_MAX && offset == UINT64_MAX)
×
1223
                return 0;
1224
        if (current_size == size && current_offset == offset)
×
1225
                return 0;
1226

1227
        xsprintf(sysfs, "/sys/dev/block/" DEVNUM_FORMAT_STR "/../dev", DEVNUM_FORMAT_VAL(st.st_rdev));
×
1228

1229
        buffer = mfree(buffer);
×
1230
        r = read_one_line_file(sysfs, &buffer);
×
1231
        if (r < 0)
×
1232
                return r;
1233
        r = parse_devnum(buffer, &devno);
×
1234
        if (r < 0)
×
1235
                return r;
1236

1237
        whole_fd = r = device_open_from_devnum(S_IFBLK, devno, O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, NULL);
×
1238
        if (r < 0)
×
1239
                return r;
1240

1241
        return block_device_resize_partition(
×
1242
                        whole_fd,
1243
                        partno,
1244
                        offset == UINT64_MAX ? current_offset : offset,
1245
                        size == UINT64_MAX ? current_size : size);
1246
}
1247

1248
int loop_device_refresh_size(LoopDevice *d, uint64_t offset, uint64_t size) {
22✔
1249
        struct loop_info64 info;
22✔
1250

1251
        assert(d);
22✔
1252
        assert(d->fd >= 0);
22✔
1253

1254
        /* Changes the offset/start of the loop device relative to the beginning of the underlying file or
1255
         * block device. If this loop device actually refers to a partition and not a loopback device, we'll
1256
         * try to adjust the partition offsets instead.
1257
         *
1258
         * If either offset or size is UINT64_MAX we won't change that parameter. */
1259

1260
        if (d->nr < 0) /* not a loopback device */
22✔
1261
                return resize_partition(d->fd, offset, size);
×
1262

1263
        if (ioctl(d->fd, LOOP_GET_STATUS64, &info) < 0)
22✔
1264
                return -errno;
×
1265

1266
#if HAVE_VALGRIND_MEMCHECK_H
1267
        /* Valgrind currently doesn't know LOOP_GET_STATUS64. Remove this once it does */
1268
        VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
1269
#endif
1270

1271
        if ((size == UINT64_MAX || info.lo_sizelimit == size) &&
22✔
1272
            (offset == UINT64_MAX || info.lo_offset == offset))
×
1273
                return 0;
1274

1275
        if (size != UINT64_MAX)
22✔
1276
                info.lo_sizelimit = size;
22✔
1277
        if (offset != UINT64_MAX)
22✔
1278
                info.lo_offset = offset;
×
1279

1280
        return RET_NERRNO(ioctl(d->fd, LOOP_SET_STATUS64, &info));
22✔
1281
}
1282

1283
int loop_device_flock(LoopDevice *d, int operation) {
160✔
1284
        assert(IN_SET(operation & ~LOCK_NB, LOCK_UN, LOCK_SH, LOCK_EX));
160✔
1285
        assert(d);
160✔
1286

1287
        /* When unlocking just close the lock fd */
1288
        if ((operation & ~LOCK_NB) == LOCK_UN) {
160✔
1289
                d->lock_fd = safe_close(d->lock_fd);
158✔
1290
                return 0;
158✔
1291
        }
1292

1293
        /* If we had no lock fd so far, create one and lock it right-away */
1294
        if (d->lock_fd < 0) {
2✔
1295
                d->lock_fd = open_lock_fd(ASSERT_FD(d->fd), operation);
1✔
1296
                if (d->lock_fd < 0)
1✔
1297
                        return d->lock_fd;
1298

1299
                return 0;
1✔
1300
        }
1301

1302
        /* Otherwise change the current lock mode on the existing fd */
1303
        return RET_NERRNO(flock(d->lock_fd, operation));
1✔
1304
}
1305

1306
int loop_device_sync(LoopDevice *d) {
80✔
1307
        assert(d);
80✔
1308

1309
        /* We also do this implicitly in loop_device_unref(). Doing this explicitly here has the benefit that
1310
         * we can check the return value though. */
1311

1312
        return RET_NERRNO(fsync(ASSERT_FD(d->fd)));
80✔
1313
}
1314

1315
int loop_device_set_autoclear(LoopDevice *d, bool autoclear) {
49✔
1316
        struct loop_info64 info;
49✔
1317

1318
        assert(d);
49✔
1319

1320
        if (LOOP_DEVICE_IS_FOREIGN(d))
49✔
1321
                return 0;
49✔
1322

1323
        if (ioctl(ASSERT_FD(d->fd), LOOP_GET_STATUS64, &info) < 0)
49✔
1324
                return -errno;
×
1325

1326
        if (autoclear == FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR))
49✔
1327
                return 0;
1328

1329
        SET_FLAG(info.lo_flags, LO_FLAGS_AUTOCLEAR, autoclear);
49✔
1330

1331
        if (ioctl(d->fd, LOOP_SET_STATUS64, &info) < 0)
49✔
1332
                return -errno;
×
1333

1334
        return 1;
1335
}
1336

1337
int loop_device_set_filename(LoopDevice *d, const char *name) {
23✔
1338
        struct loop_info64 info;
23✔
1339

1340
        assert(d);
23✔
1341

1342
        /* Sets the .lo_file_name of the loopback device. This is supposed to contain the path to the file
1343
         * backing the block device, but is actually just a free-form string you can pass to the kernel. Most
1344
         * tools that actually care for the backing file path use the sysfs attribute file loop/backing_file
1345
         * which is a kernel generated string, subject to file system namespaces and such.
1346
         *
1347
         * .lo_file_name is useful since userspace can select it freely when creating a loopback block
1348
         * device, and we can use it for /dev/disk/by-loop-ref/ symlinks, and similar, so that apps can
1349
         * recognize their own loopback files. */
1350

1351
        if (name && strlen(name) >= sizeof(info.lo_file_name))
23✔
1352
                return -ENOBUFS;
23✔
1353

1354
        if (ioctl(ASSERT_FD(d->fd), LOOP_GET_STATUS64, &info) < 0)
23✔
1355
                return -errno;
×
1356

1357
        if (strneq((char*) info.lo_file_name, strempty(name), sizeof(info.lo_file_name)))
23✔
1358
                return 0;
1359

1360
        if (name) {
23✔
1361
                strncpy((char*) info.lo_file_name, name, sizeof(info.lo_file_name)-1);
23✔
1362
                info.lo_file_name[sizeof(info.lo_file_name)-1] = 0;
23✔
1363
        } else
1364
                memzero(info.lo_file_name, sizeof(info.lo_file_name));
×
1365

1366
        if (ioctl(d->fd, LOOP_SET_STATUS64, &info) < 0)
23✔
1367
                return -errno;
×
1368

1369
        return 1;
1370
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc