]> git.ipfire.org Git - thirdparty/util-linux.git/blame - lib/loopdev.c
taskset: Accept 0 pid for current process
[thirdparty/util-linux.git] / lib / loopdev.c
CommitLineData
c444a71b 1
10ee5932 2/*
0f23ee0c
KZ
3 * No copyright is claimed. This code is in the public domain; do with
4 * it what you wish.
5 *
6 * Written by Karel Zak <kzak@redhat.com>
10ee5932
KZ
7 *
8 * -- based on mount/losetup.c
9 *
10 * Simple library for work with loop devices.
11 *
12 * - requires kernel 2.6.x
13 * - reads info from /sys/block/loop<N>/loop/<attr> (new kernels)
14 * - reads info by ioctl
15 * - supports *unlimited* number of loop devices
16 * - supports /dev/loop<N> as well as /dev/loop/<N>
17 * - minimize overhead (fd, loopinfo, ... are shared for all operations)
18 * - setup (associate device and backing file)
19 * - delete (dis-associate file)
20 * - old LOOP_{SET,GET}_STATUS (32bit) ioctls are unsupported
21 * - extendible
22 */
23#include <stdio.h>
24#include <stdint.h>
25#include <string.h>
26#include <ctype.h>
27#include <fcntl.h>
10ee5932
KZ
28#include <stdlib.h>
29#include <unistd.h>
30#include <sys/ioctl.h>
31#include <sys/stat.h>
32#include <sys/mman.h>
10ee5932
KZ
33#include <inttypes.h>
34#include <dirent.h>
10ee5932
KZ
35
36#include "linux_version.h"
37#include "c.h"
38#include "sysfs.h"
39#include "pathnames.h"
40#include "loopdev.h"
41#include "canonicalize.h"
293714c0 42#include "blkdev.h"
0bf03740 43#include "debug.h"
fbc2fe82 44#include "fileutils.h"
10ee5932 45
0ae7bb11
KZ
46#define LOOPDEV_MAX_TRIES 10
47
0bf03740
KZ
48/*
49 * Debug stuff (based on include/debug.h)
50 */
2ba641e5 51static UL_DEBUG_DEFINE_MASK(loopdev);
0bf03740 52UL_DEBUG_DEFINE_MASKNAMES(loopdev) = UL_DEBUG_EMPTY_MASKNAMES;
aee31ddc 53
0bf03740
KZ
54#define LOOPDEV_DEBUG_INIT (1 << 1)
55#define LOOPDEV_DEBUG_CXT (1 << 2)
56#define LOOPDEV_DEBUG_ITER (1 << 3)
57#define LOOPDEV_DEBUG_SETUP (1 << 4)
aee31ddc 58
0bf03740
KZ
59#define DBG(m, x) __UL_DBG(loopdev, LOOPDEV_DEBUG_, m, x)
60#define ON_DBG(m, x) __UL_DBG_CALL(loopdev, LOOPDEV_DEBUG_, m, x)
aee31ddc 61
6d00cfb2
KZ
62#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(loopdev)
63#include "debugobj.h"
64
0bf03740 65static void loopdev_init_debug(void)
aee31ddc 66{
0bf03740
KZ
67 if (loopdev_debug_mask)
68 return;
a15dca2f 69 __UL_INIT_DEBUG_FROM_ENV(loopdev, LOOPDEV_DEBUG_, 0, LOOPDEV_DEBUG);
aee31ddc
KZ
70}
71
e4062c72
KZ
72/*
73 * see loopcxt_init()
74 */
10ee5932 75#define loopcxt_ioctl_enabled(_lc) (!((_lc)->flags & LOOPDEV_FL_NOIOCTL))
e4062c72
KZ
76#define loopcxt_sysfs_available(_lc) (!((_lc)->flags & LOOPDEV_FL_NOSYSFS)) \
77 && !loopcxt_ioctl_enabled(_lc)
10ee5932 78
9d5424c2
KZ
79/*
80 * Calls @x and repeat on EAGAIN
81 */
82#define repeat_on_eagain(x) __extension__ ({ \
83 int _c = 0, _e; \
84 do { \
85 errno = 0; \
86 _e = x; \
87 if (_e == 0 || errno != EAGAIN) \
88 break; \
89 if (_c >= LOOPDEV_MAX_TRIES) \
90 break; \
91 xusleep(250000); \
92 _c++; \
93 } while (1); \
94 _e == 0 ? 0 : errno ? -errno : -1; \
95 })
96
10ee5932
KZ
97/*
98 * @lc: context
99 * @device: device name, absolute device path or NULL to reset the current setting
100 *
101 * Sets device, absolute paths (e.g. "/dev/loop<N>") are unchanged, device
102 * names ("loop<N>") are converted to the path (/dev/loop<N> or to
103 * /dev/loop/<N>)
104 *
85794fb0
KZ
105 * This sets the device name, but does not check if the device exists!
106 *
10ee5932
KZ
107 * Returns: <0 on error, 0 on success
108 */
109int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
110{
111 if (!lc)
112 return -EINVAL;
113
f4bf9592 114 if (lc->fd >= 0) {
10ee5932 115 close(lc->fd);
0bf03740 116 DBG(CXT, ul_debugobj(lc, "closing old open fd"));
f4bf9592 117 }
10ee5932 118 lc->fd = -1;
a6ca0456
JB
119 lc->is_lost = 0;
120 lc->devno = 0;
ced1142d 121 lc->mode = O_RDONLY;
75d239ff 122 lc->blocksize = 0;
10ee5932 123 lc->has_info = 0;
6c224de1 124 lc->info_failed = 0;
10ee5932 125 *lc->device = '\0';
d5fd456c 126 memset(&lc->config, 0, sizeof(lc->config));
10ee5932
KZ
127
128 /* set new */
129 if (device) {
130 if (*device != '/') {
131 const char *dir = _PATH_DEV;
132
133 /* compose device name for /dev/loop<n> or /dev/loop/<n> */
134 if (lc->flags & LOOPDEV_FL_DEVSUBDIR) {
135 if (strlen(device) < 5)
136 return -1;
137 device += 4;
67e194ae 138 dir = _PATH_DEV_LOOP "/"; /* _PATH_DEV uses trailing slash */
10ee5932
KZ
139 }
140 snprintf(lc->device, sizeof(lc->device), "%s%s",
141 dir, device);
91072cd4
KZ
142 } else
143 xstrncpy(lc->device, device, sizeof(lc->device));
144
0bf03740 145 DBG(CXT, ul_debugobj(lc, "%s name assigned", device));
10ee5932
KZ
146 }
147
7604f85f
KZ
148 ul_unref_path(lc->sysfs);
149 lc->sysfs = NULL;
10ee5932
KZ
150 return 0;
151}
152
dab13032 153int loopcxt_has_device(struct loopdev_cxt *lc)
c7e0925d
KZ
154{
155 return lc && *lc->device;
156}
157
a6ca0456
JB
158dev_t loopcxt_get_devno(struct loopdev_cxt *lc)
159{
160 if (!lc || !loopcxt_has_device(lc))
161 return 0;
162 if (!lc->devno)
163 lc->devno = sysfs_devname_to_devno(lc->device);
164 return lc->devno;
165}
166
167int loopcxt_is_lost(struct loopdev_cxt *lc)
168{
169 if (!lc || !loopcxt_has_device(lc))
170 return 0;
171 if (lc->is_lost)
172 return 1;
173
174 lc->is_lost = access(lc->device, F_OK) != 0
175 && loopcxt_get_devno(lc) != 0;
176
177 return lc->is_lost;
178}
179
10ee5932
KZ
180/*
181 * @lc: context
182 * @flags: LOOPDEV_FL_* flags
183 *
3fd1f771 184 * Initialize loop handler.
10ee5932 185 *
fd7f0718
KZ
186 * We have two sets of the flags:
187 *
188 * * LOOPDEV_FL_* flags control loopcxt_* API behavior
189 *
190 * * LO_FLAGS_* are kernel flags used for LOOP_{SET,GET}_STAT64 ioctls
191 *
10ee5932
KZ
192 * Returns: <0 on error, 0 on success.
193 */
194int loopcxt_init(struct loopdev_cxt *lc, int flags)
195{
defa0710 196 int rc;
0b14bf7a 197 struct stat st;
6219c25e 198 struct loopdev_cxt dummy = UL_LOOPDEVCXT_EMPTY;
0b14bf7a 199
10ee5932
KZ
200 if (!lc)
201 return -EINVAL;
202
0bf03740
KZ
203 loopdev_init_debug();
204 DBG(CXT, ul_debugobj(lc, "initialize context"));
205
6219c25e 206 memcpy(lc, &dummy, sizeof(dummy));
10ee5932 207 lc->flags = flags;
defa0710
KZ
208
209 rc = loopcxt_set_device(lc, NULL);
210 if (rc)
211 return rc;
10ee5932 212
df0f2ad7
KZ
213 if (stat(_PATH_SYS_BLOCK, &st) || !S_ISDIR(st.st_mode)) {
214 lc->flags |= LOOPDEV_FL_NOSYSFS;
215 lc->flags &= ~LOOPDEV_FL_NOIOCTL;
0bf03740 216 DBG(CXT, ul_debugobj(lc, "init: disable /sys usage"));
df0f2ad7
KZ
217 }
218
82b4082e 219 if (!(lc->flags & LOOPDEV_FL_NOSYSFS) &&
f4bf9592 220 get_linux_version() >= KERNEL_VERSION(2,6,37)) {
10ee5932
KZ
221 /*
222 * Use only sysfs for basic information about loop devices
223 */
224 lc->flags |= LOOPDEV_FL_NOIOCTL;
0bf03740 225 DBG(CXT, ul_debugobj(lc, "init: ignore ioctls"));
f4bf9592 226 }
10ee5932 227
f4bf9592 228 if (!(lc->flags & LOOPDEV_FL_CONTROL) && !stat(_PATH_DEV_LOOPCTL, &st)) {
0b14bf7a 229 lc->flags |= LOOPDEV_FL_CONTROL;
0bf03740 230 DBG(CXT, ul_debugobj(lc, "init: loop-control detected "));
f4bf9592 231 }
0b14bf7a 232
10ee5932
KZ
233 return 0;
234}
235
236/*
237 * @lc: context
238 *
239 * Deinitialize loop context
240 */
241void loopcxt_deinit(struct loopdev_cxt *lc)
242{
82756a74
KZ
243 int errsv = errno;
244
10ee5932
KZ
245 if (!lc)
246 return;
247
0bf03740 248 DBG(CXT, ul_debugobj(lc, "de-initialize"));
aee31ddc 249
10ee5932
KZ
250 free(lc->filename);
251 lc->filename = NULL;
252
defa0710 253 ignore_result( loopcxt_set_device(lc, NULL) );
10ee5932 254 loopcxt_deinit_iterator(lc);
82756a74
KZ
255
256 errno = errsv;
10ee5932
KZ
257}
258
259/*
260 * @lc: context
261 *
262 * Returns newly allocated device path.
263 */
264char *loopcxt_strdup_device(struct loopdev_cxt *lc)
265{
cba69bb5 266 if (!lc || !*lc->device)
10ee5932
KZ
267 return NULL;
268 return strdup(lc->device);
269}
270
271/*
272 * @lc: context
273 *
274 * Returns pointer device name in the @lc struct.
275 */
276const char *loopcxt_get_device(struct loopdev_cxt *lc)
277{
cba69bb5 278 return lc && *lc->device ? lc->device : NULL;
10ee5932
KZ
279}
280
281/*
282 * @lc: context
283 *
284 * Returns pointer to the sysfs context (see lib/sysfs.c)
285 */
7604f85f 286static struct path_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc)
10ee5932
KZ
287{
288 if (!lc || !*lc->device || (lc->flags & LOOPDEV_FL_NOSYSFS))
289 return NULL;
290
7604f85f 291 if (!lc->sysfs) {
a6ca0456 292 dev_t devno = loopcxt_get_devno(lc);
aee31ddc 293 if (!devno) {
0bf03740 294 DBG(CXT, ul_debugobj(lc, "sysfs: failed devname to devno"));
10ee5932 295 return NULL;
aee31ddc 296 }
7604f85f
KZ
297
298 lc->sysfs = ul_new_sysfs_path(devno, NULL, NULL);
299 if (!lc->sysfs)
0bf03740 300 DBG(CXT, ul_debugobj(lc, "sysfs: init failed"));
10ee5932 301 }
aee31ddc 302
7604f85f 303 return lc->sysfs;
10ee5932
KZ
304}
305
ced1142d 306static int __loopcxt_get_fd(struct loopdev_cxt *lc, mode_t mode)
10ee5932 307{
ced1142d
KZ
308 int old = -1;
309
10ee5932 310 if (!lc || !*lc->device)
fd7f0718 311 return -EINVAL;
10ee5932 312
ced1142d
KZ
313 /* It's okay to return a FD with read-write permissions if someone
314 * asked for read-only, but you shouldn't do the opposite.
315 *
316 * (O_RDONLY is a widely usable default.)
317 */
318 if (lc->fd >= 0 && mode == O_RDWR && lc->mode == O_RDONLY) {
319 DBG(CXT, ul_debugobj(lc, "closing already open device (mode mismatch)"));
320 old = lc->fd;
321 lc->fd = -1;
322 }
323
fd7f0718 324 if (lc->fd < 0) {
ced1142d 325 lc->mode = mode;
b1fa3e22 326 lc->fd = open(lc->device, lc->mode | O_CLOEXEC);
0bf03740 327 DBG(CXT, ul_debugobj(lc, "open %s [%s]: %m", lc->device,
ced1142d
KZ
328 mode == O_RDONLY ? "ro" :
329 mode == O_RDWR ? "rw" : "??"));
330
331 if (lc->fd < 0 && old >= 0) {
332 /* restore original on error */
333 lc->fd = old;
334 old = -1;
335 }
fd7f0718 336 }
ced1142d
KZ
337
338 if (old >= 0)
339 close(old);
10ee5932
KZ
340 return lc->fd;
341}
342
ced1142d
KZ
343/* default is read-only file descriptor, it's enough for all ioctls */
344int loopcxt_get_fd(struct loopdev_cxt *lc)
345{
346 return __loopcxt_get_fd(lc, O_RDONLY);
347}
348
10ee5932
KZ
349/*
350 * @lc: context
351 * @flags: LOOPITER_FL_* flags
352 *
29e204d1 353 * Iterator can be used to scan list of the free or used loop devices.
10ee5932
KZ
354 *
355 * Returns: <0 on error, 0 on success
356 */
357int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags)
358{
359 struct loopdev_iter *iter;
360 struct stat st;
361
362 if (!lc)
363 return -EINVAL;
364
aee31ddc 365
10ee5932 366 iter = &lc->iter;
0bf03740 367 DBG(ITER, ul_debugobj(iter, "initialize"));
10ee5932
KZ
368
369 /* always zeroize
370 */
371 memset(iter, 0, sizeof(*iter));
372 iter->ncur = -1;
373 iter->flags = flags;
374 iter->default_check = 1;
375
376 if (!lc->extra_check) {
377 /*
378 * Check for /dev/loop/<N> subdirectory
379 */
82b4082e 380 if (!(lc->flags & LOOPDEV_FL_DEVSUBDIR) &&
10ee5932
KZ
381 stat(_PATH_DEV_LOOP, &st) == 0 && S_ISDIR(st.st_mode))
382 lc->flags |= LOOPDEV_FL_DEVSUBDIR;
383
384 lc->extra_check = 1;
385 }
386 return 0;
387}
388
389/*
390 * @lc: context
391 *
392 * Returns: <0 on error, 0 on success
393 */
394int loopcxt_deinit_iterator(struct loopdev_cxt *lc)
395{
7552258a 396 struct loopdev_iter *iter;
10ee5932
KZ
397
398 if (!lc)
399 return -EINVAL;
400
401 iter = &lc->iter;
0bf03740 402 DBG(ITER, ul_debugobj(iter, "de-initialize"));
10ee5932
KZ
403
404 free(iter->minors);
405 if (iter->proc)
406 fclose(iter->proc);
e4062c72
KZ
407 if (iter->sysblock)
408 closedir(iter->sysblock);
9a94b634
KZ
409
410 memset(iter, 0, sizeof(*iter));
10ee5932
KZ
411 return 0;
412}
413
414/*
415 * Same as loopcxt_set_device, but also checks if the device is
11026083 416 * associated with any file.
10ee5932
KZ
417 *
418 * Returns: <0 on error, 0 on success, 1 device does not match with
419 * LOOPITER_FL_{USED,FREE} flags.
420 */
421static int loopiter_set_device(struct loopdev_cxt *lc, const char *device)
422{
423 int rc = loopcxt_set_device(lc, device);
424 int used;
425
426 if (rc)
427 return rc;
428
429 if (!(lc->iter.flags & LOOPITER_FL_USED) &&
430 !(lc->iter.flags & LOOPITER_FL_FREE))
431 return 0; /* caller does not care about device status */
432
433 used = loopcxt_get_offset(lc, NULL) == 0;
434
435 if ((lc->iter.flags & LOOPITER_FL_USED) && used)
436 return 0;
437
438 if ((lc->iter.flags & LOOPITER_FL_FREE) && !used)
439 return 0;
440
0bf03740
KZ
441 DBG(ITER, ul_debugobj(&lc->iter, "failed to use %s device", lc->device));
442
defa0710 443 ignore_result( loopcxt_set_device(lc, NULL) );
10ee5932
KZ
444 return 1;
445}
446
447static int cmpnum(const void *p1, const void *p2)
448{
0145c00a
KZ
449 return (((* (const int *) p1) > (* (const int *) p2)) -
450 ((* (const int *) p1) < (* (const int *) p2)));
10ee5932
KZ
451}
452
453/*
454 * The classic scandir() is more expensive and less portable.
455 * We needn't full loop device names -- loop numbers (loop<N>)
456 * are enough.
457 */
458static int loop_scandir(const char *dirname, int **ary, int hasprefix)
459{
460 DIR *dir;
461 struct dirent *d;
462 unsigned int n, count = 0, arylen = 0;
463
464 if (!dirname || !ary)
465 return 0;
0bf03740
KZ
466
467 DBG(ITER, ul_debug("scan dir: %s", dirname));
468
10ee5932
KZ
469 dir = opendir(dirname);
470 if (!dir)
471 return 0;
10ee5932
KZ
472 free(*ary);
473 *ary = NULL;
474
475 while((d = readdir(dir))) {
476#ifdef _DIRENT_HAVE_D_TYPE
477 if (d->d_type != DT_BLK && d->d_type != DT_UNKNOWN &&
478 d->d_type != DT_LNK)
479 continue;
480#endif
481 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
482 continue;
483
484 if (hasprefix) {
485 /* /dev/loop<N> */
486 if (sscanf(d->d_name, "loop%u", &n) != 1)
487 continue;
488 } else {
489 /* /dev/loop/<N> */
490 char *end = NULL;
491
f0fe8ab5 492 errno = 0;
10ee5932
KZ
493 n = strtol(d->d_name, &end, 10);
494 if (d->d_name == end || (end && *end) || errno)
495 continue;
496 }
497 if (n < LOOPDEV_DEFAULT_NNODES)
498 continue; /* ignore loop<0..7> */
499
500 if (count + 1 > arylen) {
501 int *tmp;
502
503 arylen += 1;
504
64d6d400 505 tmp = reallocarray(*ary, arylen, sizeof(int));
10ee5932
KZ
506 if (!tmp) {
507 free(*ary);
34f6177a 508 *ary = NULL;
2e566efd 509 closedir(dir);
10ee5932
KZ
510 return -1;
511 }
512 *ary = tmp;
513 }
fc8b1f36
KZ
514 if (*ary)
515 (*ary)[count++] = n;
10ee5932 516 }
fc8b1f36 517 if (count && *ary)
10ee5932
KZ
518 qsort(*ary, count, sizeof(int), cmpnum);
519
520 closedir(dir);
521 return count;
522}
523
e4062c72
KZ
524/*
525 * Set the next *used* loop device according to /proc/partitions.
526 *
527 * Loop devices smaller than 512 bytes are invisible for this function.
528 */
529static int loopcxt_next_from_proc(struct loopdev_cxt *lc)
530{
531 struct loopdev_iter *iter = &lc->iter;
532 char buf[BUFSIZ];
533
0bf03740 534 DBG(ITER, ul_debugobj(iter, "scan /proc/partitions"));
e4062c72
KZ
535
536 if (!iter->proc)
b1fa3e22 537 iter->proc = fopen(_PATH_PROC_PARTITIONS, "r" UL_CLOEXECSTR);
e4062c72
KZ
538 if (!iter->proc)
539 return 1;
540
541 while (fgets(buf, sizeof(buf), iter->proc)) {
542 unsigned int m;
657d9adb 543 char name[128 + 1];
e4062c72
KZ
544
545
546 if (sscanf(buf, " %u %*s %*s %128[^\n ]",
547 &m, name) != 2 || m != LOOPDEV_MAJOR)
548 continue;
549
0bf03740 550 DBG(ITER, ul_debugobj(iter, "checking %s", name));
e4062c72
KZ
551
552 if (loopiter_set_device(lc, name) == 0)
553 return 0;
554 }
555
556 return 1;
557}
558
559/*
560 * Set the next *used* loop device according to
561 * /sys/block/loopN/loop/backing_file (kernel >= 2.6.37 is required).
562 *
563 * This is preferred method.
564 */
565static int loopcxt_next_from_sysfs(struct loopdev_cxt *lc)
566{
567 struct loopdev_iter *iter = &lc->iter;
568 struct dirent *d;
569 int fd;
570
0bf03740 571 DBG(ITER, ul_debugobj(iter, "scanning /sys/block"));
e4062c72
KZ
572
573 if (!iter->sysblock)
574 iter->sysblock = opendir(_PATH_SYS_BLOCK);
575
576 if (!iter->sysblock)
577 return 1;
578
579 fd = dirfd(iter->sysblock);
580
581 while ((d = readdir(iter->sysblock))) {
acecab61 582 char name[NAME_MAX + 18 + 1];
e4062c72
KZ
583 struct stat st;
584
0bf03740 585 DBG(ITER, ul_debugobj(iter, "check %s", d->d_name));
e4062c72
KZ
586
587 if (strcmp(d->d_name, ".") == 0
588 || strcmp(d->d_name, "..") == 0
589 || strncmp(d->d_name, "loop", 4) != 0)
590 continue;
591
592 snprintf(name, sizeof(name), "%s/loop/backing_file", d->d_name);
2208b3cc 593 if (fstatat(fd, name, &st, 0) != 0)
e4062c72
KZ
594 continue;
595
596 if (loopiter_set_device(lc, d->d_name) == 0)
597 return 0;
598 }
599
600 return 1;
601}
602
10ee5932
KZ
603/*
604 * @lc: context, has to initialized by loopcxt_init_iterator()
605 *
af5efcd8 606 * Returns: 0 on success, < 0 on error, 1 at the end of scanning. The details
10ee5932
KZ
607 * about the current loop device are available by
608 * loopcxt_get_{fd,backing_file,device,offset, ...} functions.
609 */
610int loopcxt_next(struct loopdev_cxt *lc)
611{
612 struct loopdev_iter *iter;
613
614 if (!lc)
615 return -EINVAL;
aee31ddc 616
aee31ddc 617
10ee5932
KZ
618 iter = &lc->iter;
619 if (iter->done)
620 return 1;
621
0bf03740
KZ
622 DBG(ITER, ul_debugobj(iter, "next"));
623
10ee5932
KZ
624 /* A) Look for used loop devices in /proc/partitions ("losetup -a" only)
625 */
626 if (iter->flags & LOOPITER_FL_USED) {
e4062c72
KZ
627 int rc;
628
629 if (loopcxt_sysfs_available(lc))
630 rc = loopcxt_next_from_sysfs(lc);
631 else
632 rc = loopcxt_next_from_proc(lc);
633 if (rc == 0)
634 return 0;
10ee5932
KZ
635 goto done;
636 }
637
638 /* B) Classic way, try first eight loop devices (default number
639 * of loop devices). This is enough for 99% of all cases.
640 */
641 if (iter->default_check) {
0bf03740 642 DBG(ITER, ul_debugobj(iter, "next: default check"));
10ee5932
KZ
643 for (++iter->ncur; iter->ncur < LOOPDEV_DEFAULT_NNODES;
644 iter->ncur++) {
645 char name[16];
646 snprintf(name, sizeof(name), "loop%d", iter->ncur);
647
648 if (loopiter_set_device(lc, name) == 0)
649 return 0;
650 }
651 iter->default_check = 0;
652 }
653
654 /* C) the worst possibility, scan whole /dev or /dev/loop/<N>
655 */
656 if (!iter->minors) {
0bf03740 657 DBG(ITER, ul_debugobj(iter, "next: scanning /dev"));
10ee5932
KZ
658 iter->nminors = (lc->flags & LOOPDEV_FL_DEVSUBDIR) ?
659 loop_scandir(_PATH_DEV_LOOP, &iter->minors, 0) :
660 loop_scandir(_PATH_DEV, &iter->minors, 1);
661 iter->ncur = -1;
662 }
663 for (++iter->ncur; iter->ncur < iter->nminors; iter->ncur++) {
664 char name[16];
665 snprintf(name, sizeof(name), "loop%d", iter->minors[iter->ncur]);
666
667 if (loopiter_set_device(lc, name) == 0)
668 return 0;
669 }
670done:
671 loopcxt_deinit_iterator(lc);
672 return 1;
673}
674
675/*
676 * @device: path to device
677 */
678int is_loopdev(const char *device)
679{
680 struct stat st;
fbc2fe82
KZ
681 int rc = 0;
682
683 if (!device || stat(device, &st) != 0 || !S_ISBLK(st.st_mode))
684 rc = 0;
685 else if (major(st.st_rdev) == LOOPDEV_MAJOR)
686 rc = 1;
d4423cce 687 else if (sysfs_devno_is_wholedisk(st.st_rdev)) {
fbc2fe82
KZ
688 /* It's possible that kernel creates a device with a different
689 * major number ... check by /sys it's really loop device.
690 */
691 char name[PATH_MAX], *cn, *p = NULL;
692
693 snprintf(name, sizeof(name), _PATH_SYS_DEVBLOCK "/%d:%d",
694 major(st.st_rdev), minor(st.st_rdev));
695 cn = canonicalize_path(name);
696 if (cn)
697 p = stripoff_last_component(cn);
aa07db0a 698 rc = p && ul_startswith(p, "loop");
fbc2fe82
KZ
699 free(cn);
700 }
10ee5932 701
fbc2fe82
KZ
702 if (rc == 0)
703 errno = ENODEV;
704 return rc;
10ee5932
KZ
705}
706
707/*
708 * @lc: context
709 *
710 * Returns result from LOOP_GET_STAT64 ioctl or NULL on error.
711 */
712struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc)
713{
714 int fd;
715
85794fb0
KZ
716 if (!lc || lc->info_failed) {
717 errno = EINVAL;
10ee5932 718 return NULL;
85794fb0
KZ
719 }
720 errno = 0;
10ee5932 721 if (lc->has_info)
d5fd456c 722 return &lc->config.info;
10ee5932
KZ
723
724 fd = loopcxt_get_fd(lc);
725 if (fd < 0)
726 return NULL;
727
d5fd456c 728 if (ioctl(fd, LOOP_GET_STATUS64, &lc->config.info) == 0) {
10ee5932 729 lc->has_info = 1;
6c224de1 730 lc->info_failed = 0;
0bf03740 731 DBG(CXT, ul_debugobj(lc, "reading loop_info64 OK"));
d5fd456c 732 return &lc->config.info;
10ee5932
KZ
733 }
734
85794fb0 735 lc->info_failed = 1;
0bf03740 736 DBG(CXT, ul_debugobj(lc, "reading loop_info64 FAILED"));
85794fb0 737
10ee5932
KZ
738 return NULL;
739}
740
741/*
742 * @lc: context
743 *
311e33af 744 * Returns (allocated) string with path to the file associated
10ee5932
KZ
745 * with the current loop device.
746 */
747char *loopcxt_get_backing_file(struct loopdev_cxt *lc)
748{
7604f85f 749 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
10ee5932
KZ
750 char *res = NULL;
751
752 if (sysfs)
fd7f0718 753 /*
11026083 754 * This is always preferred, the loop_info64
fd7f0718
KZ
755 * has too small buffer for the filename.
756 */
7604f85f 757 ul_path_read_string(sysfs, &res, "loop/backing_file");
10ee5932
KZ
758
759 if (!res && loopcxt_ioctl_enabled(lc)) {
760 struct loop_info64 *lo = loopcxt_get_info(lc);
761
762 if (lo) {
763 lo->lo_file_name[LO_NAME_SIZE - 2] = '*';
764 lo->lo_file_name[LO_NAME_SIZE - 1] = '\0';
765 res = strdup((char *) lo->lo_file_name);
766 }
767 }
aee31ddc 768
0bf03740 769 DBG(CXT, ul_debugobj(lc, "get_backing_file [%s]", res));
10ee5932
KZ
770 return res;
771}
772
db8f7815
KZ
773/*
774 * @lc: context
775 *
776 * Returns (allocated) string with loop reference. The same as backing file by
777 * default.
778 */
779char *loopcxt_get_refname(struct loopdev_cxt *lc)
780{
781 char *res = NULL;
782 struct loop_info64 *lo = loopcxt_get_info(lc);
783
784 if (lo) {
785 lo->lo_file_name[LO_NAME_SIZE - 1] = '\0';
786 res = strdup((char *) lo->lo_file_name);
787 }
788
789 DBG(CXT, ul_debugobj(lc, "get_refname [%s]", res));
790 return res;
791}
792
10ee5932
KZ
793/*
794 * @lc: context
795 * @offset: returns offset number for the given device
796 *
797 * Returns: <0 on error, 0 on success
798 */
799int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset)
800{
7604f85f 801 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
10ee5932
KZ
802 int rc = -EINVAL;
803
804 if (sysfs)
fb4b6b11
JK
805 if (ul_path_read_u64(sysfs, offset, "loop/offset") == 0)
806 rc = 0;
10ee5932
KZ
807
808 if (rc && loopcxt_ioctl_enabled(lc)) {
809 struct loop_info64 *lo = loopcxt_get_info(lc);
810 if (lo) {
811 if (offset)
812 *offset = lo->lo_offset;
6c224de1 813 rc = 0;
85794fb0
KZ
814 } else
815 rc = -errno;
10ee5932
KZ
816 }
817
0bf03740 818 DBG(CXT, ul_debugobj(lc, "get_offset [rc=%d]", rc));
10ee5932
KZ
819 return rc;
820}
821
a1a41597
SB
822/*
823 * @lc: context
824 * @blocksize: returns logical blocksize for the given device
825 *
826 * Returns: <0 on error, 0 on success
827 */
828int loopcxt_get_blocksize(struct loopdev_cxt *lc, uint64_t *blocksize)
829{
7604f85f 830 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
a1a41597
SB
831 int rc = -EINVAL;
832
833 if (sysfs)
fb4b6b11
JK
834 if (ul_path_read_u64(sysfs, blocksize, "queue/logical_block_size") == 0)
835 rc = 0;
a1a41597
SB
836
837 /* Fallback based on BLKSSZGET ioctl */
838 if (rc) {
839 int fd = loopcxt_get_fd(lc);
840 int sz = 0;
841
842 if (fd < 0)
843 return -EINVAL;
844 rc = blkdev_get_sector_size(fd, &sz);
845 if (rc)
846 return rc;
847
848 *blocksize = sz;
849 }
850
851 DBG(CXT, ul_debugobj(lc, "get_blocksize [rc=%d]", rc));
852 return rc;
853}
854
10ee5932
KZ
855/*
856 * @lc: context
857 * @sizelimit: returns size limit for the given device
858 *
859 * Returns: <0 on error, 0 on success
860 */
861int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size)
862{
7604f85f 863 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
10ee5932
KZ
864 int rc = -EINVAL;
865
866 if (sysfs)
fb4b6b11
JK
867 if (ul_path_read_u64(sysfs, size, "loop/sizelimit") == 0)
868 rc = 0;
10ee5932
KZ
869
870 if (rc && loopcxt_ioctl_enabled(lc)) {
871 struct loop_info64 *lo = loopcxt_get_info(lc);
872 if (lo) {
873 if (size)
874 *size = lo->lo_sizelimit;
6c224de1 875 rc = 0;
85794fb0
KZ
876 } else
877 rc = -errno;
10ee5932
KZ
878 }
879
0bf03740 880 DBG(CXT, ul_debugobj(lc, "get_sizelimit [rc=%d]", rc));
6c224de1
KZ
881 return rc;
882}
883
884/*
885 * @lc: context
a6ca0456 886 * @type: returns encryption type
6c224de1
KZ
887 *
888 * Cryptoloop is DEPRECATED!
889 *
890 * Returns: <0 on error, 0 on success
891 */
892int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type)
893{
894 struct loop_info64 *lo = loopcxt_get_info(lc);
85794fb0 895 int rc;
6c224de1 896
85794fb0 897 /* not provided by sysfs */
6c224de1
KZ
898 if (lo) {
899 if (type)
900 *type = lo->lo_encrypt_type;
901 rc = 0;
85794fb0
KZ
902 } else
903 rc = -errno;
904
0bf03740 905 DBG(CXT, ul_debugobj(lc, "get_encrypt_type [rc=%d]", rc));
6c224de1
KZ
906 return rc;
907}
908
909/*
910 * @lc: context
6c224de1
KZ
911 *
912 * Cryptoloop is DEPRECATED!
913 *
914 * Returns: <0 on error, 0 on success
915 */
916const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc)
917{
918 struct loop_info64 *lo = loopcxt_get_info(lc);
919
920 if (lo)
921 return (char *) lo->lo_crypt_name;
922
0bf03740 923 DBG(CXT, ul_debugobj(lc, "get_crypt_name failed"));
6c224de1
KZ
924 return NULL;
925}
926
927/*
928 * @lc: context
929 * @devno: returns backing file devno
930 *
931 * Returns: <0 on error, 0 on success
932 */
933int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno)
934{
935 struct loop_info64 *lo = loopcxt_get_info(lc);
85794fb0 936 int rc;
6c224de1
KZ
937
938 if (lo) {
939 if (devno)
940 *devno = lo->lo_device;
941 rc = 0;
85794fb0
KZ
942 } else
943 rc = -errno;
944
0bf03740 945 DBG(CXT, ul_debugobj(lc, "get_backing_devno [rc=%d]", rc));
6c224de1
KZ
946 return rc;
947}
948
949/*
950 * @lc: context
951 * @ino: returns backing file inode
952 *
953 * Returns: <0 on error, 0 on success
954 */
955int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino)
956{
957 struct loop_info64 *lo = loopcxt_get_info(lc);
85794fb0 958 int rc;
6c224de1
KZ
959
960 if (lo) {
961 if (ino)
962 *ino = lo->lo_inode;
963 rc = 0;
85794fb0
KZ
964 } else
965 rc = -errno;
966
0bf03740 967 DBG(CXT, ul_debugobj(lc, "get_backing_inode [rc=%d]", rc));
10ee5932
KZ
968 return rc;
969}
970
59d749c3
KZ
971/*
972 * Check if the kernel supports partitioned loop devices.
973 *
974 * Notes:
975 * - kernels < 3.2 support partitioned loop devices and PT scanning
9e930041 976 * only if max_part= module parameter is non-zero
59d749c3
KZ
977 *
978 * - kernels >= 3.2 always support partitioned loop devices
979 *
980 * - kernels >= 3.2 always support BLKPG_{ADD,DEL}_PARTITION ioctls
981 *
982 * - kernels >= 3.2 enable PT scanner only if max_part= is non-zero or if the
983 * LO_FLAGS_PARTSCAN flag is set for the device. The PT scanner is disabled
984 * by default.
985 *
986 * See kernel commit e03c8dd14915fabc101aa495828d58598dc5af98.
987 */
988int loopmod_supports_partscan(void)
989{
990 int rc, ret = 0;
991 FILE *f;
992
993 if (get_linux_version() >= KERNEL_VERSION(3,2,0))
994 return 1;
995
b1fa3e22 996 f = fopen("/sys/module/loop/parameters/max_part", "r" UL_CLOEXECSTR);
59d749c3
KZ
997 if (!f)
998 return 0;
999 rc = fscanf(f, "%d", &ret);
1000 fclose(f);
8b04761d 1001 return rc == 1 ? ret : 0;
59d749c3
KZ
1002}
1003
10ee5932
KZ
1004/*
1005 * @lc: context
1006 *
59d749c3 1007 * Returns: 1 if the partscan flags is set *or* (for old kernels) partitions
9e930041 1008 * scanning is enabled for all loop devices.
59d749c3
KZ
1009 */
1010int loopcxt_is_partscan(struct loopdev_cxt *lc)
1011{
7604f85f 1012 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
59d749c3
KZ
1013
1014 if (sysfs) {
1015 /* kernel >= 3.2 */
1016 int fl;
7604f85f 1017 if (ul_path_read_s32(sysfs, &fl, "loop/partscan") == 0)
59d749c3
KZ
1018 return fl;
1019 }
1020
1021 /* old kernels (including kernels without loopN/loop/<flags> directory */
1022 return loopmod_supports_partscan();
1023}
1024
1025/*
1026 * @lc: context
1027 *
1028 * Returns: 1 if the autoclear flags is set.
10ee5932
KZ
1029 */
1030int loopcxt_is_autoclear(struct loopdev_cxt *lc)
1031{
7604f85f 1032 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
10ee5932
KZ
1033
1034 if (sysfs) {
1035 int fl;
7604f85f 1036 if (ul_path_read_s32(sysfs, &fl, "loop/autoclear") == 0)
10ee5932
KZ
1037 return fl;
1038 }
1039
1040 if (loopcxt_ioctl_enabled(lc)) {
1041 struct loop_info64 *lo = loopcxt_get_info(lc);
1042 if (lo)
1043 return lo->lo_flags & LO_FLAGS_AUTOCLEAR;
1044 }
1045 return 0;
1046}
1047
fd7f0718
KZ
1048/*
1049 * @lc: context
1050 *
59d749c3 1051 * Returns: 1 if the readonly flags is set.
fd7f0718
KZ
1052 */
1053int loopcxt_is_readonly(struct loopdev_cxt *lc)
1054{
7604f85f 1055 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
fd7f0718
KZ
1056
1057 if (sysfs) {
1058 int fl;
7604f85f 1059 if (ul_path_read_s32(sysfs, &fl, "ro") == 0)
fd7f0718
KZ
1060 return fl;
1061 }
1062
1063 if (loopcxt_ioctl_enabled(lc)) {
1064 struct loop_info64 *lo = loopcxt_get_info(lc);
1065 if (lo)
1066 return lo->lo_flags & LO_FLAGS_READ_ONLY;
1067 }
1068 return 0;
1069}
1070
faeef4d2
ML
1071/*
1072 * @lc: context
1073 *
1074 * Returns: 1 if the dio flags is set.
1075 */
1076int loopcxt_is_dio(struct loopdev_cxt *lc)
1077{
7604f85f 1078 struct path_cxt *sysfs = loopcxt_get_sysfs(lc);
faeef4d2
ML
1079
1080 if (sysfs) {
1081 int fl;
7604f85f 1082 if (ul_path_read_s32(sysfs, &fl, "loop/dio") == 0)
faeef4d2
ML
1083 return fl;
1084 }
1085 if (loopcxt_ioctl_enabled(lc)) {
1086 struct loop_info64 *lo = loopcxt_get_info(lc);
1087 if (lo)
1088 return lo->lo_flags & LO_FLAGS_DIRECT_IO;
1089 }
1090 return 0;
1091}
1092
6c224de1
KZ
1093/*
1094 * @lc: context
1095 * @st: backing file stat or NULL
1096 * @backing_file: filename
c444a71b
KZ
1097 * @offset: offset (use LOOPDEV_FL_OFFSET if specified)
1098 * @sizelimit: size limit (use LOOPDEV_FL_SIZELIMIT if specified)
1099 * @flags: LOOPDEV_FL_{OFFSET,SIZELIMIT}
6c224de1
KZ
1100 *
1101 * Returns 1 if the current @lc loopdev is associated with the given backing
1102 * file. Note that the preferred way is to use devno and inode number rather
1103 * than filename. The @backing_file filename is poor solution usable in case
1104 * that you don't have rights to call stat().
1105 *
74a4705a
SB
1106 * LOOPDEV_FL_SIZELIMIT requires LOOPDEV_FL_OFFSET being set as well.
1107 *
6c224de1
KZ
1108 * Don't forget that old kernels provide very restricted (in size) backing
1109 * filename by LOOP_GET_STAT64 ioctl only.
1110 */
1111int loopcxt_is_used(struct loopdev_cxt *lc,
1112 struct stat *st,
1113 const char *backing_file,
1114 uint64_t offset,
74a4705a 1115 uint64_t sizelimit,
6c224de1
KZ
1116 int flags)
1117{
3011b381
KZ
1118 ino_t ino = 0;
1119 dev_t dev = 0;
6c224de1
KZ
1120
1121 if (!lc)
1122 return 0;
1123
0bf03740 1124 DBG(CXT, ul_debugobj(lc, "checking %s vs. %s",
6c224de1
KZ
1125 loopcxt_get_device(lc),
1126 backing_file));
1127
1128 if (st && loopcxt_get_backing_inode(lc, &ino) == 0 &&
1129 loopcxt_get_backing_devno(lc, &dev) == 0) {
1130
1131 if (ino == st->st_ino && dev == st->st_dev)
1132 goto found;
1133
1134 /* don't use filename if we have devno and inode */
1135 return 0;
1136 }
1137
1138 /* poor man's solution */
1139 if (backing_file) {
1140 char *name = loopcxt_get_backing_file(lc);
1141 int rc = name && strcmp(name, backing_file) == 0;
1142
1143 free(name);
1144 if (rc)
1145 goto found;
1146 }
1147
1148 return 0;
1149found:
1150 if (flags & LOOPDEV_FL_OFFSET) {
3011b381 1151 uint64_t off = 0;
6c224de1 1152
74a4705a
SB
1153 int rc = loopcxt_get_offset(lc, &off) == 0 && off == offset;
1154
1155 if (rc && flags & LOOPDEV_FL_SIZELIMIT) {
3011b381 1156 uint64_t sz = 0;
74a4705a
SB
1157
1158 return loopcxt_get_sizelimit(lc, &sz) == 0 && sz == sizelimit;
042f62df
RP
1159 }
1160 return rc;
6c224de1
KZ
1161 }
1162 return 1;
1163}
1164
fd7f0718
KZ
1165/*
1166 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1167 */
10ee5932
KZ
1168int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset)
1169{
1170 if (!lc)
1171 return -EINVAL;
d5fd456c 1172 lc->config.info.lo_offset = offset;
aee31ddc 1173
0bf03740 1174 DBG(CXT, ul_debugobj(lc, "set offset=%jd", offset));
10ee5932
KZ
1175 return 0;
1176}
1177
fd7f0718
KZ
1178/*
1179 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1180 */
10ee5932
KZ
1181int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit)
1182{
1183 if (!lc)
1184 return -EINVAL;
d5fd456c 1185 lc->config.info.lo_sizelimit = sizelimit;
aee31ddc 1186
0bf03740 1187 DBG(CXT, ul_debugobj(lc, "set sizelimit=%jd", sizelimit));
10ee5932
KZ
1188 return 0;
1189}
1190
75d239ff
KZ
1191/*
1192 * The blocksize will be used by loopcxt_set_device(). For already exiting
1193 * devices use loopcxt_ioctl_blocksize().
1194 *
1195 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1196 */
1197int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
1198{
1199 if (!lc)
1200 return -EINVAL;
1201 lc->blocksize = blocksize;
1202
1203 DBG(CXT, ul_debugobj(lc, "set blocksize=%jd", blocksize));
1204 return 0;
1205}
1206
10ee5932
KZ
1207/*
1208 * @lc: context
1209 * @flags: kernel LO_FLAGS_{READ_ONLY,USE_AOPS,AUTOCLEAR} flags
1210 *
fd7f0718
KZ
1211 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1212 *
10ee5932
KZ
1213 * Returns: 0 on success, <0 on error.
1214 */
1215int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags)
1216{
1217 if (!lc)
1218 return -EINVAL;
d5fd456c 1219 lc->config.info.lo_flags = flags;
aee31ddc 1220
0bf03740 1221 DBG(CXT, ul_debugobj(lc, "set flags=%u", (unsigned) flags));
10ee5932
KZ
1222 return 0;
1223}
1224
db8f7815
KZ
1225/*
1226 * @lc: context
1227 * @refname: reference name (used to overwrite lo_file_name where is backing
1228 * file by default)
1229 *
1230 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1231 *
1232 * Returns: 0 on success, <0 on error.
1233 */
1234int loopcxt_set_refname(struct loopdev_cxt *lc, const char *refname)
1235{
1236 if (!lc)
1237 return -EINVAL;
1238
1239 memset(lc->config.info.lo_file_name, 0, sizeof(lc->config.info.lo_file_name));
1240 if (refname)
1241 xstrncpy((char *)lc->config.info.lo_file_name, refname, LO_NAME_SIZE);
1242
1243 DBG(CXT, ul_debugobj(lc, "set refname=%s", (char *)lc->config.info.lo_file_name));
1244 return 0;
1245}
1246
10ee5932
KZ
1247/*
1248 * @lc: context
1249 * @filename: backing file path (the path will be canonicalized)
1250 *
fd7f0718
KZ
1251 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1252 *
10ee5932
KZ
1253 * Returns: 0 on success, <0 on error.
1254 */
1255int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename)
1256{
1257 if (!lc)
1258 return -EINVAL;
1259
1260 lc->filename = canonicalize_path(filename);
1261 if (!lc->filename)
1262 return -errno;
1263
db8f7815
KZ
1264 if (!lc->config.info.lo_file_name[0])
1265 loopcxt_set_refname(lc, lc->filename);
10ee5932 1266
db8f7815 1267 DBG(CXT, ul_debugobj(lc, "set backing file=%s", lc->filename));
10ee5932
KZ
1268 return 0;
1269}
1270
293714c0
JM
1271/*
1272 * In kernels prior to v3.9, if the offset or sizelimit options
1273 * are used, the block device's size won't be synced automatically.
1274 * blockdev --getsize64 and filesystems will use the backing
1275 * file size until the block device has been re-opened or the
1276 * LOOP_SET_CAPACITY ioctl is called to sync the sizes.
1277 *
1278 * Since mount -oloop uses the LO_FLAGS_AUTOCLEAR option and passes
1279 * the open file descriptor to the mount system call, we need to use
1280 * the ioctl. Calling losetup directly doesn't have this problem since
1281 * it closes the device when it exits and whatever consumes the device
1282 * next will re-open it, causing the resync.
1283 */
1284static int loopcxt_check_size(struct loopdev_cxt *lc, int file_fd)
1285{
1286 uint64_t size, expected_size;
1287 int dev_fd;
1288 struct stat st;
1289
d5fd456c 1290 if (!lc->config.info.lo_offset && !lc->config.info.lo_sizelimit)
293714c0
JM
1291 return 0;
1292
01307ecf 1293 if (fstat(file_fd, &st)) {
0bf03740 1294 DBG(CXT, ul_debugobj(lc, "failed to fstat backing file"));
293714c0 1295 return -errno;
01307ecf 1296 }
e3b6cb87
KZ
1297 if (S_ISBLK(st.st_mode)) {
1298 if (blkdev_get_size(file_fd,
01307ecf 1299 (unsigned long long *) &expected_size)) {
0bf03740 1300 DBG(CXT, ul_debugobj(lc, "failed to determine device size"));
e3b6cb87 1301 return -errno;
01307ecf 1302 }
e3b6cb87
KZ
1303 } else
1304 expected_size = st.st_size;
1305
d5fd456c 1306 if (expected_size == 0 || expected_size <= lc->config.info.lo_offset) {
0bf03740 1307 DBG(CXT, ul_debugobj(lc, "failed to determine expected size"));
e3b6cb87
KZ
1308 return 0; /* ignore this error */
1309 }
293714c0 1310
d5fd456c
SK
1311 if (lc->config.info.lo_offset > 0)
1312 expected_size -= lc->config.info.lo_offset;
293714c0 1313
d5fd456c
SK
1314 if (lc->config.info.lo_sizelimit > 0 && lc->config.info.lo_sizelimit < expected_size)
1315 expected_size = lc->config.info.lo_sizelimit;
293714c0
JM
1316
1317 dev_fd = loopcxt_get_fd(lc);
01307ecf 1318 if (dev_fd < 0) {
0bf03740 1319 DBG(CXT, ul_debugobj(lc, "failed to get loop FD"));
293714c0 1320 return -errno;
01307ecf 1321 }
293714c0 1322
01307ecf 1323 if (blkdev_get_size(dev_fd, (unsigned long long *) &size)) {
0bf03740 1324 DBG(CXT, ul_debugobj(lc, "failed to determine loopdev size"));
293714c0 1325 return -errno;
01307ecf 1326 }
293714c0 1327
a7d5202b
KZ
1328 /* It's block device, so, align to 512-byte sectors */
1329 if (expected_size % 512) {
0bf03740 1330 DBG(CXT, ul_debugobj(lc, "expected size misaligned to 512-byte sectors"));
a7d5202b
KZ
1331 expected_size = (expected_size >> 9) << 9;
1332 }
1333
293714c0 1334 if (expected_size != size) {
0bf03740 1335 DBG(CXT, ul_debugobj(lc, "warning: loopdev and expected "
9e930041 1336 "size mismatch (%ju/%ju)",
e3b6cb87
KZ
1337 size, expected_size));
1338
9fcc8936 1339 if (loopcxt_ioctl_capacity(lc)) {
293714c0
JM
1340 /* ioctl not available */
1341 if (errno == ENOTTY || errno == EINVAL)
1342 errno = ERANGE;
1343 return -errno;
1344 }
1345
1346 if (blkdev_get_size(dev_fd, (unsigned long long *) &size))
1347 return -errno;
1348
01307ecf
KZ
1349 if (expected_size != size) {
1350 errno = ERANGE;
0bf03740 1351 DBG(CXT, ul_debugobj(lc, "failed to set loopdev size, "
01307ecf
KZ
1352 "size: %ju, expected: %ju",
1353 size, expected_size));
1354 return -errno;
1355 }
293714c0
JM
1356 }
1357
1358 return 0;
1359}
1360
9d5424c2 1361
10ee5932 1362/*
bfd4e1f7 1363 * @lc: context
10ee5932
KZ
1364 *
1365 * Associate the current device (see loopcxt_{set,get}_device()) with
1366 * a file (see loopcxt_set_backing_file()).
1367 *
fd7f0718
KZ
1368 * The device is initialized read-write by default. If you want read-only
1369 * device then set LO_FLAGS_READ_ONLY by loopcxt_set_flags(). The LOOPDEV_FL_*
1370 * flags are ignored and modified according to LO_FLAGS_*.
1371 *
1372 * If the device is already open by loopcxt_get_fd() then this setup device
1373 * function will re-open the device to fix read/write mode.
1374 *
1375 * The device is also initialized read-only if the backing file is not
1376 * possible to open read-write (e.g. read-only FS).
10ee5932
KZ
1377 *
1378 * Returns: <0 on error, 0 on success.
1379 */
1380int loopcxt_setup_device(struct loopdev_cxt *lc)
1381{
ced1142d
KZ
1382 int file_fd, dev_fd;
1383 mode_t flags = O_CLOEXEC, mode = O_RDWR;
1328e0f7 1384 int rc = -1, cnt = 0;
2cde9865 1385 int errsv = 0;
d5fd456c 1386 int fallback = 0;
10ee5932
KZ
1387
1388 if (!lc || !*lc->device || !lc->filename)
1389 return -EINVAL;
1390
0bf03740 1391 DBG(SETUP, ul_debugobj(lc, "device setup requested"));
aee31ddc 1392
10ee5932
KZ
1393 /*
1394 * Open backing file and device
1395 */
d5fd456c 1396 if (lc->config.info.lo_flags & LO_FLAGS_READ_ONLY)
fd7f0718 1397 mode = O_RDONLY;
10ee5932 1398
d53346ed
AXH
1399 if (lc->config.info.lo_flags & LO_FLAGS_DIRECT_IO)
1400 flags |= O_DIRECT;
1401
1402 if ((file_fd = open(lc->filename, mode | flags)) < 0) {
10ee5932 1403 if (mode != O_RDONLY && (errno == EROFS || errno == EACCES))
d53346ed 1404 file_fd = open(lc->filename, (mode = O_RDONLY) | flags);
10ee5932 1405
aee31ddc 1406 if (file_fd < 0) {
0bf03740 1407 DBG(SETUP, ul_debugobj(lc, "open backing file failed: %m"));
10ee5932 1408 return -errno;
aee31ddc 1409 }
10ee5932 1410 }
0bf03740 1411 DBG(SETUP, ul_debugobj(lc, "backing file open: OK"));
10ee5932 1412
ced1142d 1413 if (mode == O_RDONLY)
d5fd456c 1414 lc->config.info.lo_flags |= LO_FLAGS_READ_ONLY; /* kernel loopdev mode */
ced1142d 1415 else
d5fd456c 1416 lc->config.info.lo_flags &= ~LO_FLAGS_READ_ONLY;
10ee5932 1417
663bf040
KZ
1418 do {
1419 errno = 0;
ced1142d 1420
47ed406f 1421 dev_fd = __loopcxt_get_fd(lc, mode);
663bf040
KZ
1422 if (dev_fd >= 0 || lc->control_ok == 0)
1423 break;
1424 if (errno != EACCES && errno != ENOENT)
1425 break;
1426 /* We have permissions to open /dev/loop-control, but open
1427 * /dev/loopN failed with EACCES, it's probably because udevd
1428 * does not applied chown yet. Let's wait a moment. */
1429 xusleep(25000);
1430 } while (cnt++ < 16);
1431
10ee5932
KZ
1432 if (dev_fd < 0) {
1433 rc = -errno;
1434 goto err;
1435 }
1436
0bf03740 1437 DBG(SETUP, ul_debugobj(lc, "device open: OK"));
d356c5d2 1438
a61955ba
KZ
1439 /*
1440 * Atomic way to configure all by one ioctl call
1441 * -- since Linux v5.8-rc1, commit 3448914e8cc550ba792d4ccc74471d1ca4293aae
1442 */
d5fd456c 1443 lc->config.fd = file_fd;
854abba0
HE
1444 if (lc->blocksize > 0)
1445 lc->config.block_size = lc->blocksize;
9d5424c2
KZ
1446
1447 rc = repeat_on_eagain( ioctl(dev_fd, LOOP_CONFIGURE, &lc->config) );
1448 if (rc != 0) {
2cde9865 1449 errsv = errno;
f6385a6a 1450 if (errno != EINVAL && errno != ENOTTY && errno != ENOSYS) {
d5fd456c
SK
1451 DBG(SETUP, ul_debugobj(lc, "LOOP_CONFIGURE failed: %m"));
1452 goto err;
1453 }
1454 fallback = 1;
a61955ba 1455 } else {
d5fd456c 1456 DBG(SETUP, ul_debugobj(lc, "LOOP_CONFIGURE: OK"));
75d239ff
KZ
1457 }
1458
a61955ba
KZ
1459 /*
1460 * Old deprecated way; first assign backing file FD and then in the
1461 * second step set loop device properties.
1462 */
d5fd456c 1463 if (fallback) {
d5fd456c
SK
1464 if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) {
1465 rc = -errno;
1466 errsv = errno;
1467 DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD failed: %m"));
1468 goto err;
1469 }
d356c5d2 1470
d5fd456c
SK
1471 DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD: OK"));
1472
1473 if (lc->blocksize > 0
1474 && (rc = loopcxt_ioctl_blocksize(lc, lc->blocksize)) < 0) {
1475 errsv = -rc;
1476 goto err;
1477 }
1478
1328e0f7
KZ
1479 if ((rc = loopcxt_ioctl_status(lc)) < 0) {
1480 errsv = -rc;
d5fd456c
SK
1481 goto err;
1482 }
d5fd456c 1483 }
d356c5d2 1484
293714c0
JM
1485 if ((rc = loopcxt_check_size(lc, file_fd)))
1486 goto err;
1487
1488 close(file_fd);
293714c0 1489
d5fd456c 1490 memset(&lc->config, 0, sizeof(lc->config));
10ee5932 1491 lc->has_info = 0;
6c224de1 1492 lc->info_failed = 0;
10ee5932 1493
0bf03740 1494 DBG(SETUP, ul_debugobj(lc, "success [rc=0]"));
10ee5932
KZ
1495 return 0;
1496err:
1497 if (file_fd >= 0)
1498 close(file_fd);
f7e21185 1499 if (dev_fd >= 0 && rc != -EBUSY)
10ee5932 1500 ioctl(dev_fd, LOOP_CLR_FD, 0);
2cde9865
KZ
1501 if (errsv)
1502 errno = errsv;
10ee5932 1503
0bf03740 1504 DBG(SETUP, ul_debugobj(lc, "failed [rc=%d]", rc));
10ee5932
KZ
1505 return rc;
1506}
1507
9d5424c2 1508
bfd4e1f7
SB
1509/*
1510 * @lc: context
1511 *
1512 * Update status of the current device (see loopcxt_{set,get}_device()).
1513 *
1514 * Note that once initialized, kernel accepts only selected changes:
1515 * LO_FLAGS_AUTOCLEAR and LO_FLAGS_PARTSCAN
1516 * For more see linux/drivers/block/loop.c:loop_set_status()
1517 *
1518 * Returns: <0 on error, 0 on success.
1519 */
9fcc8936 1520int loopcxt_ioctl_status(struct loopdev_cxt *lc)
bfd4e1f7 1521{
9d5424c2 1522 int dev_fd, rc;
bfd4e1f7
SB
1523
1524 errno = 0;
1525 dev_fd = loopcxt_get_fd(lc);
1526
9d5424c2
KZ
1527 if (dev_fd < 0)
1528 return -errno;
bfd4e1f7 1529
9d5424c2 1530 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_STATUS64"));
0ae7bb11 1531
9d5424c2
KZ
1532 rc = repeat_on_eagain( ioctl(dev_fd, LOOP_SET_STATUS64, &lc->config.info) );
1533 if (rc != 0) {
bfd4e1f7
SB
1534 DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m"));
1535 return rc;
1536 }
1537
1538 DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64: OK"));
1539 return 0;
1540}
1541
9fcc8936 1542int loopcxt_ioctl_capacity(struct loopdev_cxt *lc)
293714c0 1543{
9d5424c2 1544 int rc, fd = loopcxt_get_fd(lc);
293714c0
JM
1545
1546 if (fd < 0)
1547 return -EINVAL;
1548
9d5424c2
KZ
1549 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_CAPACITY"));
1550
293714c0 1551 /* Kernels prior to v2.6.30 don't support this ioctl */
9d5424c2
KZ
1552 rc = repeat_on_eagain( ioctl(fd, LOOP_SET_CAPACITY, 0) );
1553 if (rc != 0) {
0bf03740 1554 DBG(CXT, ul_debugobj(lc, "LOOP_SET_CAPACITY failed: %m"));
293714c0
JM
1555 return rc;
1556 }
1557
0bf03740 1558 DBG(CXT, ul_debugobj(lc, "capacity set"));
293714c0
JM
1559 return 0;
1560}
1561
9fcc8936 1562int loopcxt_ioctl_dio(struct loopdev_cxt *lc, unsigned long use_dio)
64c3bb3c 1563{
9d5424c2 1564 int rc, fd = loopcxt_get_fd(lc);
64c3bb3c
ML
1565
1566 if (fd < 0)
1567 return -EINVAL;
1568
9d5424c2
KZ
1569 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_DIRECT_IO"));
1570
64c3bb3c 1571 /* Kernels prior to v4.4 don't support this ioctl */
9d5424c2
KZ
1572 rc = repeat_on_eagain( ioctl(fd, LOOP_SET_DIRECT_IO, use_dio) );
1573 if (rc != 0) {
64c3bb3c
ML
1574 DBG(CXT, ul_debugobj(lc, "LOOP_SET_DIRECT_IO failed: %m"));
1575 return rc;
1576 }
1577
1578 DBG(CXT, ul_debugobj(lc, "direct io set"));
1579 return 0;
1580}
1581
c4e60bc0
KZ
1582/*
1583 * Kernel uses "unsigned long" as ioctl arg, but we use u64 for all sizes to
1584 * keep loopdev internal API simple.
1585 */
9fcc8936 1586int loopcxt_ioctl_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
a1a41597 1587{
9d5424c2 1588 int rc, fd = loopcxt_get_fd(lc);
a1a41597
SB
1589
1590 if (fd < 0)
1591 return -EINVAL;
1592
9d5424c2
KZ
1593 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_BLOCK_SIZE"));
1594
1595 rc = repeat_on_eagain(
1596 ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) blocksize) );
1597 if (rc != 0) {
1598 DBG(CXT, ul_debugobj(lc, "LOOP_SET_BLOCK_SIZE failed: %m"));
1599 return rc;
1600 }
a1a41597
SB
1601
1602 DBG(CXT, ul_debugobj(lc, "logical block size set"));
1603 return 0;
1604}
1605
10ee5932
KZ
1606int loopcxt_delete_device(struct loopdev_cxt *lc)
1607{
9d5424c2 1608 int rc, fd = loopcxt_get_fd(lc);
10ee5932
KZ
1609
1610 if (fd < 0)
1611 return -EINVAL;
1612
9d5424c2
KZ
1613 DBG(SETUP, ul_debugobj(lc, "calling LOOP_SET_CLR_FD"));
1614
1615 rc = repeat_on_eagain( ioctl(fd, LOOP_CLR_FD, 0) );
1616 if (rc != 0) {
0bf03740 1617 DBG(CXT, ul_debugobj(lc, "LOOP_CLR_FD failed: %m"));
9d5424c2 1618 return rc;
aee31ddc
KZ
1619 }
1620
0bf03740 1621 DBG(CXT, ul_debugobj(lc, "device removed"));
10ee5932
KZ
1622 return 0;
1623}
1624
3cb2413b
KZ
1625int loopcxt_add_device(struct loopdev_cxt *lc)
1626{
1627 int rc = -EINVAL;
1628 int ctl, nr = -1;
1629 const char *p, *dev = loopcxt_get_device(lc);
1630
1631 if (!dev)
1632 goto done;
1633
1634 if (!(lc->flags & LOOPDEV_FL_CONTROL)) {
1635 rc = -ENOSYS;
1636 goto done;
1637 }
1638
1639 p = strrchr(dev, '/');
1640 if (!p || (sscanf(p, "/loop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1)
1641 || nr < 0)
1642 goto done;
1643
1644 ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
1645 if (ctl >= 0) {
0bf03740 1646 DBG(CXT, ul_debugobj(lc, "add_device %d", nr));
3cb2413b
KZ
1647 rc = ioctl(ctl, LOOP_CTL_ADD, nr);
1648 close(ctl);
1649 }
663bf040 1650 lc->control_ok = rc >= 0 ? 1 : 0;
3cb2413b 1651done:
0bf03740 1652 DBG(CXT, ul_debugobj(lc, "add_device done [rc=%d]", rc));
3cb2413b
KZ
1653 return rc;
1654}
1655
59d749c3
KZ
1656/*
1657 * Note that LOOP_CTL_GET_FREE ioctl is supported since kernel 3.1. In older
1658 * kernels we have to check all loop devices to found unused one.
1659 *
1660 * See kernel commit 770fe30a46a12b6fb6b63fbe1737654d28e8484.
3c540264
TW
1661 *
1662 * Returns: 0 = success, < 0 error
59d749c3 1663 */
10ee5932
KZ
1664int loopcxt_find_unused(struct loopdev_cxt *lc)
1665{
0b14bf7a 1666 int rc = -1;
10ee5932 1667
0bf03740 1668 DBG(CXT, ul_debugobj(lc, "find_unused requested"));
aee31ddc 1669
0b14bf7a 1670 if (lc->flags & LOOPDEV_FL_CONTROL) {
9a94b634
KZ
1671 int ctl;
1672
1673 DBG(CXT, ul_debugobj(lc, "using loop-control"));
10ee5932 1674
9a94b634 1675 ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
0b14bf7a
KZ
1676 if (ctl >= 0)
1677 rc = ioctl(ctl, LOOP_CTL_GET_FREE);
3c540264
TW
1678 else
1679 rc = -errno;
0b14bf7a
KZ
1680 if (rc >= 0) {
1681 char name[16];
1682 snprintf(name, sizeof(name), "loop%d", rc);
1683
1684 rc = loopiter_set_device(lc, name);
1685 }
663bf040 1686 lc->control_ok = ctl >= 0 && rc == 0 ? 1 : 0;
0b14bf7a
KZ
1687 if (ctl >= 0)
1688 close(ctl);
0bf03740 1689 DBG(CXT, ul_debugobj(lc, "find_unused by loop-control [rc=%d]", rc));
0b14bf7a
KZ
1690 }
1691
1692 if (rc < 0) {
9a94b634 1693 DBG(CXT, ul_debugobj(lc, "using loop scan"));
0b14bf7a
KZ
1694 rc = loopcxt_init_iterator(lc, LOOPITER_FL_FREE);
1695 if (rc)
1696 return rc;
10ee5932 1697
0b14bf7a
KZ
1698 rc = loopcxt_next(lc);
1699 loopcxt_deinit_iterator(lc);
0bf03740 1700 DBG(CXT, ul_debugobj(lc, "find_unused by scan [rc=%d]", rc));
3c540264
TW
1701 if (rc)
1702 return -ENOENT;
0b14bf7a 1703 }
10ee5932
KZ
1704 return rc;
1705}
1706
1707
1708
1709/*
1710 * Return: TRUE/FALSE
1711 */
1712int loopdev_is_autoclear(const char *device)
1713{
1714 struct loopdev_cxt lc;
1715 int rc;
1716
1717 if (!device)
1718 return 0;
1719
defa0710
KZ
1720 rc = loopcxt_init(&lc, 0);
1721 if (!rc)
1722 rc = loopcxt_set_device(&lc, device);
1723 if (!rc)
1724 rc = loopcxt_is_autoclear(&lc);
10ee5932 1725
defa0710 1726 loopcxt_deinit(&lc);
10ee5932
KZ
1727 return rc;
1728}
1729
1730char *loopdev_get_backing_file(const char *device)
1731{
1732 struct loopdev_cxt lc;
defa0710 1733 char *res = NULL;
10ee5932
KZ
1734
1735 if (!device)
1736 return NULL;
defa0710
KZ
1737 if (loopcxt_init(&lc, 0))
1738 return NULL;
1739 if (loopcxt_set_device(&lc, device) == 0)
1740 res = loopcxt_get_backing_file(&lc);
10ee5932 1741
10ee5932 1742 loopcxt_deinit(&lc);
10ee5932
KZ
1743 return res;
1744}
1745
af5efcd8
TW
1746/*
1747 * Returns: TRUE/FALSE
1748 */
14bb8e3c
KZ
1749int loopdev_has_backing_file(const char *device)
1750{
1751 char *tmp = loopdev_get_backing_file(device);
1752
1753 if (tmp) {
1754 free(tmp);
1755 return 1;
1756 }
1757 return 0;
1758}
1759
10ee5932
KZ
1760/*
1761 * Returns: TRUE/FALSE
1762 */
1763int loopdev_is_used(const char *device, const char *filename,
74a4705a 1764 uint64_t offset, uint64_t sizelimit, int flags)
10ee5932
KZ
1765{
1766 struct loopdev_cxt lc;
6c224de1 1767 struct stat st;
10ee5932
KZ
1768 int rc = 0;
1769
8b470b20 1770 if (!device || !filename)
10ee5932
KZ
1771 return 0;
1772
defa0710
KZ
1773 rc = loopcxt_init(&lc, 0);
1774 if (!rc)
1775 rc = loopcxt_set_device(&lc, device);
1776 if (rc)
1777 return rc;
10ee5932 1778
6c224de1 1779 rc = !stat(filename, &st);
74a4705a 1780 rc = loopcxt_is_used(&lc, rc ? &st : NULL, filename, offset, sizelimit, flags);
10ee5932 1781
10ee5932 1782 loopcxt_deinit(&lc);
10ee5932
KZ
1783 return rc;
1784}
1785
af5efcd8
TW
1786/*
1787 * Returns: 0 = success, < 0 error
1788 */
10ee5932
KZ
1789int loopdev_delete(const char *device)
1790{
1791 struct loopdev_cxt lc;
1792 int rc;
1793
8b470b20
KZ
1794 if (!device)
1795 return -EINVAL;
1796
defa0710
KZ
1797 rc = loopcxt_init(&lc, 0);
1798 if (!rc)
1799 rc = loopcxt_set_device(&lc, device);
10ee5932
KZ
1800 if (!rc)
1801 rc = loopcxt_delete_device(&lc);
1802 loopcxt_deinit(&lc);
1803 return rc;
1804}
1805
1806/*
1807 * Returns: 0 = success, < 0 error, 1 not found
1808 */
1809int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, const char *filename,
74a4705a 1810 uint64_t offset, uint64_t sizelimit, int flags)
10ee5932 1811{
6c224de1
KZ
1812 int rc, hasst;
1813 struct stat st;
10ee5932
KZ
1814
1815 if (!filename)
1816 return -EINVAL;
1817
6c224de1
KZ
1818 hasst = !stat(filename, &st);
1819
10ee5932
KZ
1820 rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED);
1821 if (rc)
1822 return rc;
1823
6c224de1 1824 while ((rc = loopcxt_next(lc)) == 0) {
10ee5932 1825
6c224de1 1826 if (loopcxt_is_used(lc, hasst ? &st : NULL,
74a4705a 1827 filename, offset, sizelimit, flags))
6c224de1 1828 break;
10ee5932
KZ
1829 }
1830
1831 loopcxt_deinit_iterator(lc);
1832 return rc;
1833}
1834
211e1d46 1835/*
dff7e160 1836 * Returns: 0 = not found, < 0 error, 1 found, 2 found full size and offset match
211e1d46 1837 */
c444a71b 1838int loopcxt_find_overlap(struct loopdev_cxt *lc, const char *filename,
211e1d46
SB
1839 uint64_t offset, uint64_t sizelimit)
1840{
1841 int rc, hasst;
1842 struct stat st;
1843
1844 if (!filename)
1845 return -EINVAL;
1846
9a94b634 1847 DBG(CXT, ul_debugobj(lc, "find_overlap requested"));
211e1d46
SB
1848 hasst = !stat(filename, &st);
1849
1850 rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED);
1851 if (rc)
1852 return rc;
1853
1854 while ((rc = loopcxt_next(lc)) == 0) {
1855 uint64_t lc_sizelimit, lc_offset;
1856
1857 rc = loopcxt_is_used(lc, hasst ? &st : NULL,
1858 filename, offset, sizelimit, 0);
562990b5
JK
1859 /*
1860 * Either the loopdev is unused or we've got an error which can
1861 * happen when we are racing with device autoclear. Just ignore
1862 * this loopdev...
1863 */
1864 if (rc <= 0)
1865 continue;
c444a71b 1866
211e1d46
SB
1867 DBG(CXT, ul_debugobj(lc, "found %s backed by %s",
1868 loopcxt_get_device(lc), filename));
c444a71b 1869
211e1d46
SB
1870 rc = loopcxt_get_offset(lc, &lc_offset);
1871 if (rc) {
1872 DBG(CXT, ul_debugobj(lc, "failed to get offset for device %s",
1873 loopcxt_get_device(lc)));
562990b5 1874 continue;
211e1d46
SB
1875 }
1876 rc = loopcxt_get_sizelimit(lc, &lc_sizelimit);
1877 if (rc) {
1878 DBG(CXT, ul_debugobj(lc, "failed to get sizelimit for device %s",
1879 loopcxt_get_device(lc)));
562990b5 1880 continue;
211e1d46
SB
1881 }
1882
dff7e160
KZ
1883 /* full match */
1884 if (lc_sizelimit == sizelimit && lc_offset == offset) {
1885 DBG(CXT, ul_debugobj(lc, "overlapping loop device %s (full match)",
1886 loopcxt_get_device(lc)));
1887 rc = 2;
1888 goto found;
1889 }
1890
1891 /* overlap */
211e1d46
SB
1892 if (lc_sizelimit != 0 && offset >= lc_offset + lc_sizelimit)
1893 continue;
1894 if (sizelimit != 0 && offset + sizelimit <= lc_offset)
1895 continue;
dff7e160 1896
211e1d46
SB
1897 DBG(CXT, ul_debugobj(lc, "overlapping loop device %s",
1898 loopcxt_get_device(lc)));
dff7e160
KZ
1899 rc = 1;
1900 goto found;
211e1d46 1901 }
dff7e160
KZ
1902
1903 if (rc == 1)
1904 rc = 0; /* not found */
1905found:
211e1d46 1906 loopcxt_deinit_iterator(lc);
9a94b634 1907 DBG(CXT, ul_debugobj(lc, "find_overlap done [rc=%d]", rc));
211e1d46
SB
1908 return rc;
1909}
1910
10ee5932
KZ
1911/*
1912 * Returns allocated string with device name
1913 */
74a4705a 1914char *loopdev_find_by_backing_file(const char *filename, uint64_t offset, uint64_t sizelimit, int flags)
10ee5932
KZ
1915{
1916 struct loopdev_cxt lc;
1917 char *res = NULL;
1918
1919 if (!filename)
1920 return NULL;
1921
defa0710
KZ
1922 if (loopcxt_init(&lc, 0))
1923 return NULL;
74a4705a 1924 if (loopcxt_find_by_backing_file(&lc, filename, offset, sizelimit, flags) == 0)
10ee5932
KZ
1925 res = loopcxt_strdup_device(&lc);
1926 loopcxt_deinit(&lc);
1927
1928 return res;
1929}
1930
d5688130
KZ
1931/*
1932 * Returns number of loop devices associated with @file, if only one loop
11026083 1933 * device is associated with the given @filename and @loopdev is not NULL then
d5688130
KZ
1934 * @loopdev returns name of the device.
1935 */
1936int loopdev_count_by_backing_file(const char *filename, char **loopdev)
1937{
1938 struct loopdev_cxt lc;
defa0710 1939 int count = 0, rc;
d5688130
KZ
1940
1941 if (!filename)
1942 return -1;
1943
defa0710
KZ
1944 rc = loopcxt_init(&lc, 0);
1945 if (rc)
1946 return rc;
d5688130
KZ
1947 if (loopcxt_init_iterator(&lc, LOOPITER_FL_USED))
1948 return -1;
1949
1950 while(loopcxt_next(&lc) == 0) {
1951 char *backing = loopcxt_get_backing_file(&lc);
1952
ad296391 1953 if (!backing || strcmp(backing, filename) != 0) {
d5688130
KZ
1954 free(backing);
1955 continue;
1956 }
1957
1958 free(backing);
1959 if (loopdev && count == 0)
1960 *loopdev = loopcxt_strdup_device(&lc);
1961 count++;
1962 }
1963
1964 loopcxt_deinit(&lc);
1965
1966 if (loopdev && count > 1) {
1967 free(*loopdev);
1968 *loopdev = NULL;
1969 }
1970 return count;
1971}
1972
d4423cce
KZ
1973#ifdef TEST_PROGRAM_LOOPDEV
1974int main(int argc, char *argv[])
1975{
1976 if (argc < 2)
1977 goto usage;
1978
1979 if (strcmp(argv[1], "--is-loopdev") == 0 && argc == 3)
1980 printf("%s: %s\n", argv[2], is_loopdev(argv[2]) ? "OK" : "FAIL");
1981 else
1982 goto usage;
1983
1984 return EXIT_SUCCESS;
1985usage:
1986 fprintf(stderr, "usage: %1$s --is-loopdev <dev>\n",
1987 program_invocation_short_name);
1988 return EXIT_FAILURE;
1989}
1990#endif
1991