3 * No copyright is claimed. This code is in the public domain; do with
6 * Written by Karel Zak <kzak@redhat.com>
8 * -- based on mount/losetup.c
10 * Simple library for work with loop devices.
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
30 #include <sys/ioctl.h>
36 #include "linux_version.h"
39 #include "pathnames.h"
41 #include "canonicalize.h"
44 #include "fileutils.h"
46 #define LOOPDEV_MAX_TRIES 10
49 * Debug stuff (based on include/debug.h)
51 static UL_DEBUG_DEFINE_MASK(loopdev
);
52 UL_DEBUG_DEFINE_MASKNAMES(loopdev
) = UL_DEBUG_EMPTY_MASKNAMES
;
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)
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)
62 #define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(loopdev)
65 static void loopdev_init_debug(void)
67 if (loopdev_debug_mask
)
69 __UL_INIT_DEBUG_FROM_ENV(loopdev
, LOOPDEV_DEBUG_
, 0, LOOPDEV_DEBUG
);
75 #define loopcxt_ioctl_enabled(_lc) (!((_lc)->flags & LOOPDEV_FL_NOIOCTL))
76 #define loopcxt_sysfs_available(_lc) (!((_lc)->flags & LOOPDEV_FL_NOSYSFS)) \
77 && !loopcxt_ioctl_enabled(_lc)
80 * Calls @x and repeat on EAGAIN
82 #define repeat_on_eagain(x) __extension__ ({ \
87 if (_e == 0 || errno != EAGAIN) \
89 if (_c >= LOOPDEV_MAX_TRIES) \
94 _e == 0 ? 0 : errno ? -errno : -1; \
99 * @device: device name, absolute device path or NULL to reset the current setting
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
105 * This sets the device name, but does not check if the device exists!
107 * Returns: <0 on error, 0 on success
109 int loopcxt_set_device(struct loopdev_cxt
*lc
, const char *device
)
116 DBG(CXT
, ul_debugobj(lc
, "closing old open fd"));
126 memset(&lc
->config
, 0, sizeof(lc
->config
));
130 if (*device
!= '/') {
131 const char *dir
= _PATH_DEV
;
133 /* compose device name for /dev/loop<n> or /dev/loop/<n> */
134 if (lc
->flags
& LOOPDEV_FL_DEVSUBDIR
) {
135 if (strlen(device
) < 5)
138 dir
= _PATH_DEV_LOOP
"/"; /* _PATH_DEV uses tailing slash */
140 snprintf(lc
->device
, sizeof(lc
->device
), "%s%s",
143 xstrncpy(lc
->device
, device
, sizeof(lc
->device
));
145 DBG(CXT
, ul_debugobj(lc
, "%s name assigned", device
));
148 ul_unref_path(lc
->sysfs
);
153 int loopcxt_has_device(struct loopdev_cxt
*lc
)
155 return lc
&& *lc
->device
;
158 dev_t
loopcxt_get_devno(struct loopdev_cxt
*lc
)
160 if (!lc
|| !loopcxt_has_device(lc
))
163 lc
->devno
= sysfs_devname_to_devno(lc
->device
);
167 int loopcxt_is_lost(struct loopdev_cxt
*lc
)
169 if (!lc
|| !loopcxt_has_device(lc
))
174 lc
->is_lost
= access(lc
->device
, F_OK
) != 0
175 && loopcxt_get_devno(lc
) != 0;
182 * @flags: LOOPDEV_FL_* flags
184 * Initialize loop handler.
186 * We have two sets of the flags:
188 * * LOOPDEV_FL_* flags control loopcxt_* API behavior
190 * * LO_FLAGS_* are kernel flags used for LOOP_{SET,GET}_STAT64 ioctls
192 * Returns: <0 on error, 0 on success.
194 int loopcxt_init(struct loopdev_cxt
*lc
, int flags
)
198 struct loopdev_cxt dummy
= UL_LOOPDEVCXT_EMPTY
;
203 loopdev_init_debug();
204 DBG(CXT
, ul_debugobj(lc
, "initialize context"));
206 memcpy(lc
, &dummy
, sizeof(dummy
));
209 rc
= loopcxt_set_device(lc
, NULL
);
213 if (stat(_PATH_SYS_BLOCK
, &st
) || !S_ISDIR(st
.st_mode
)) {
214 lc
->flags
|= LOOPDEV_FL_NOSYSFS
;
215 lc
->flags
&= ~LOOPDEV_FL_NOIOCTL
;
216 DBG(CXT
, ul_debugobj(lc
, "init: disable /sys usage"));
219 if (!(lc
->flags
& LOOPDEV_FL_NOSYSFS
) &&
220 get_linux_version() >= KERNEL_VERSION(2,6,37)) {
222 * Use only sysfs for basic information about loop devices
224 lc
->flags
|= LOOPDEV_FL_NOIOCTL
;
225 DBG(CXT
, ul_debugobj(lc
, "init: ignore ioctls"));
228 if (!(lc
->flags
& LOOPDEV_FL_CONTROL
) && !stat(_PATH_DEV_LOOPCTL
, &st
)) {
229 lc
->flags
|= LOOPDEV_FL_CONTROL
;
230 DBG(CXT
, ul_debugobj(lc
, "init: loop-control detected "));
239 * Deinitialize loop context
241 void loopcxt_deinit(struct loopdev_cxt
*lc
)
248 DBG(CXT
, ul_debugobj(lc
, "de-initialize"));
253 ignore_result( loopcxt_set_device(lc
, NULL
) );
254 loopcxt_deinit_iterator(lc
);
262 * Returns newly allocated device path.
264 char *loopcxt_strdup_device(struct loopdev_cxt
*lc
)
266 if (!lc
|| !*lc
->device
)
268 return strdup(lc
->device
);
274 * Returns pointer device name in the @lc struct.
276 const char *loopcxt_get_device(struct loopdev_cxt
*lc
)
278 return lc
&& *lc
->device
? lc
->device
: NULL
;
284 * Returns pointer to the sysfs context (see lib/sysfs.c)
286 static struct path_cxt
*loopcxt_get_sysfs(struct loopdev_cxt
*lc
)
288 if (!lc
|| !*lc
->device
|| (lc
->flags
& LOOPDEV_FL_NOSYSFS
))
292 dev_t devno
= loopcxt_get_devno(lc
);
294 DBG(CXT
, ul_debugobj(lc
, "sysfs: failed devname to devno"));
298 lc
->sysfs
= ul_new_sysfs_path(devno
, NULL
, NULL
);
300 DBG(CXT
, ul_debugobj(lc
, "sysfs: init failed"));
306 static int __loopcxt_get_fd(struct loopdev_cxt
*lc
, mode_t mode
)
310 if (!lc
|| !*lc
->device
)
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.
316 * (O_RDONLY is a widely usable default.)
318 if (lc
->fd
>= 0 && mode
== O_RDWR
&& lc
->mode
== O_RDONLY
) {
319 DBG(CXT
, ul_debugobj(lc
, "closing already open device (mode mismatch)"));
326 lc
->fd
= open(lc
->device
, lc
->mode
| O_CLOEXEC
);
327 DBG(CXT
, ul_debugobj(lc
, "open %s [%s]: %m", lc
->device
,
328 mode
== O_RDONLY
? "ro" :
329 mode
== O_RDWR
? "rw" : "??"));
331 if (lc
->fd
< 0 && old
>= 0) {
332 /* restore original on error */
343 /* default is read-only file descriptor, it's enough for all ioctls */
344 int loopcxt_get_fd(struct loopdev_cxt
*lc
)
346 return __loopcxt_get_fd(lc
, O_RDONLY
);
349 int loopcxt_set_fd(struct loopdev_cxt
*lc
, int fd
, mode_t mode
)
361 * @flags: LOOPITER_FL_* flags
363 * Iterator can be used to scan list of the free or used loop devices.
365 * Returns: <0 on error, 0 on success
367 int loopcxt_init_iterator(struct loopdev_cxt
*lc
, int flags
)
369 struct loopdev_iter
*iter
;
377 DBG(ITER
, ul_debugobj(iter
, "initialize"));
381 memset(iter
, 0, sizeof(*iter
));
384 iter
->default_check
= 1;
386 if (!lc
->extra_check
) {
388 * Check for /dev/loop/<N> subdirectory
390 if (!(lc
->flags
& LOOPDEV_FL_DEVSUBDIR
) &&
391 stat(_PATH_DEV_LOOP
, &st
) == 0 && S_ISDIR(st
.st_mode
))
392 lc
->flags
|= LOOPDEV_FL_DEVSUBDIR
;
402 * Returns: <0 on error, 0 on success
404 int loopcxt_deinit_iterator(struct loopdev_cxt
*lc
)
406 struct loopdev_iter
*iter
;
412 DBG(ITER
, ul_debugobj(iter
, "de-initialize"));
418 closedir(iter
->sysblock
);
420 memset(iter
, 0, sizeof(*iter
));
425 * Same as loopcxt_set_device, but also checks if the device is
426 * associated with any file.
428 * Returns: <0 on error, 0 on success, 1 device does not match with
429 * LOOPITER_FL_{USED,FREE} flags.
431 static int loopiter_set_device(struct loopdev_cxt
*lc
, const char *device
)
433 int rc
= loopcxt_set_device(lc
, device
);
439 if (!(lc
->iter
.flags
& LOOPITER_FL_USED
) &&
440 !(lc
->iter
.flags
& LOOPITER_FL_FREE
))
441 return 0; /* caller does not care about device status */
443 used
= loopcxt_get_offset(lc
, NULL
) == 0;
445 if ((lc
->iter
.flags
& LOOPITER_FL_USED
) && used
)
448 if ((lc
->iter
.flags
& LOOPITER_FL_FREE
) && !used
)
451 DBG(ITER
, ul_debugobj(&lc
->iter
, "failed to use %s device", lc
->device
));
453 ignore_result( loopcxt_set_device(lc
, NULL
) );
457 static int cmpnum(const void *p1
, const void *p2
)
459 return (((* (const int *) p1
) > (* (const int *) p2
)) -
460 ((* (const int *) p1
) < (* (const int *) p2
)));
464 * The classic scandir() is more expensive and less portable.
465 * We needn't full loop device names -- loop numbers (loop<N>)
468 static int loop_scandir(const char *dirname
, int **ary
, int hasprefix
)
472 unsigned int n
, count
= 0, arylen
= 0;
474 if (!dirname
|| !ary
)
477 DBG(ITER
, ul_debug("scan dir: %s", dirname
));
479 dir
= opendir(dirname
);
485 while((d
= readdir(dir
))) {
486 #ifdef _DIRENT_HAVE_D_TYPE
487 if (d
->d_type
!= DT_BLK
&& d
->d_type
!= DT_UNKNOWN
&&
491 if (!strcmp(d
->d_name
, ".") || !strcmp(d
->d_name
, ".."))
496 if (sscanf(d
->d_name
, "loop%u", &n
) != 1)
503 n
= strtol(d
->d_name
, &end
, 10);
504 if (d
->d_name
== end
|| (end
&& *end
) || errno
)
507 if (n
< LOOPDEV_DEFAULT_NNODES
)
508 continue; /* ignore loop<0..7> */
510 if (count
+ 1 > arylen
) {
515 tmp
= reallocarray(*ary
, arylen
, sizeof(int));
528 qsort(*ary
, count
, sizeof(int), cmpnum
);
535 * Set the next *used* loop device according to /proc/partitions.
537 * Loop devices smaller than 512 bytes are invisible for this function.
539 static int loopcxt_next_from_proc(struct loopdev_cxt
*lc
)
541 struct loopdev_iter
*iter
= &lc
->iter
;
544 DBG(ITER
, ul_debugobj(iter
, "scan /proc/partitions"));
547 iter
->proc
= fopen(_PATH_PROC_PARTITIONS
, "r" UL_CLOEXECSTR
);
551 while (fgets(buf
, sizeof(buf
), iter
->proc
)) {
556 if (sscanf(buf
, " %u %*s %*s %128[^\n ]",
557 &m
, name
) != 2 || m
!= LOOPDEV_MAJOR
)
560 DBG(ITER
, ul_debugobj(iter
, "checking %s", name
));
562 if (loopiter_set_device(lc
, name
) == 0)
570 * Set the next *used* loop device according to
571 * /sys/block/loopN/loop/backing_file (kernel >= 2.6.37 is required).
573 * This is preferred method.
575 static int loopcxt_next_from_sysfs(struct loopdev_cxt
*lc
)
577 struct loopdev_iter
*iter
= &lc
->iter
;
581 DBG(ITER
, ul_debugobj(iter
, "scanning /sys/block"));
584 iter
->sysblock
= opendir(_PATH_SYS_BLOCK
);
589 fd
= dirfd(iter
->sysblock
);
591 while ((d
= readdir(iter
->sysblock
))) {
592 char name
[NAME_MAX
+ 18 + 1];
595 DBG(ITER
, ul_debugobj(iter
, "check %s", d
->d_name
));
597 if (strcmp(d
->d_name
, ".") == 0
598 || strcmp(d
->d_name
, "..") == 0
599 || strncmp(d
->d_name
, "loop", 4) != 0)
602 snprintf(name
, sizeof(name
), "%s/loop/backing_file", d
->d_name
);
603 if (fstatat(fd
, name
, &st
, 0) != 0)
606 if (loopiter_set_device(lc
, d
->d_name
) == 0)
614 * @lc: context, has to initialized by loopcxt_init_iterator()
616 * Returns: 0 on success, < 0 on error, 1 at the end of scanning. The details
617 * about the current loop device are available by
618 * loopcxt_get_{fd,backing_file,device,offset, ...} functions.
620 int loopcxt_next(struct loopdev_cxt
*lc
)
622 struct loopdev_iter
*iter
;
632 DBG(ITER
, ul_debugobj(iter
, "next"));
634 /* A) Look for used loop devices in /proc/partitions ("losetup -a" only)
636 if (iter
->flags
& LOOPITER_FL_USED
) {
639 if (loopcxt_sysfs_available(lc
))
640 rc
= loopcxt_next_from_sysfs(lc
);
642 rc
= loopcxt_next_from_proc(lc
);
648 /* B) Classic way, try first eight loop devices (default number
649 * of loop devices). This is enough for 99% of all cases.
651 if (iter
->default_check
) {
652 DBG(ITER
, ul_debugobj(iter
, "next: default check"));
653 for (++iter
->ncur
; iter
->ncur
< LOOPDEV_DEFAULT_NNODES
;
656 snprintf(name
, sizeof(name
), "loop%d", iter
->ncur
);
658 if (loopiter_set_device(lc
, name
) == 0)
661 iter
->default_check
= 0;
664 /* C) the worst possibility, scan whole /dev or /dev/loop/<N>
667 DBG(ITER
, ul_debugobj(iter
, "next: scanning /dev"));
668 iter
->nminors
= (lc
->flags
& LOOPDEV_FL_DEVSUBDIR
) ?
669 loop_scandir(_PATH_DEV_LOOP
, &iter
->minors
, 0) :
670 loop_scandir(_PATH_DEV
, &iter
->minors
, 1);
673 for (++iter
->ncur
; iter
->ncur
< iter
->nminors
; iter
->ncur
++) {
675 snprintf(name
, sizeof(name
), "loop%d", iter
->minors
[iter
->ncur
]);
677 if (loopiter_set_device(lc
, name
) == 0)
681 loopcxt_deinit_iterator(lc
);
686 * @device: path to device
688 int is_loopdev(const char *device
)
693 if (!device
|| stat(device
, &st
) != 0 || !S_ISBLK(st
.st_mode
))
695 else if (major(st
.st_rdev
) == LOOPDEV_MAJOR
)
697 else if (sysfs_devno_is_wholedisk(st
.st_rdev
)) {
698 /* It's possible that kernel creates a device with a different
699 * major number ... check by /sys it's really loop device.
701 char name
[PATH_MAX
], *cn
, *p
= NULL
;
703 snprintf(name
, sizeof(name
), _PATH_SYS_DEVBLOCK
"/%d:%d",
704 major(st
.st_rdev
), minor(st
.st_rdev
));
705 cn
= canonicalize_path(name
);
707 p
= stripoff_last_component(cn
);
708 rc
= p
&& startswith(p
, "loop");
720 * Returns result from LOOP_GET_STAT64 ioctl or NULL on error.
722 struct loop_info64
*loopcxt_get_info(struct loopdev_cxt
*lc
)
726 if (!lc
|| lc
->info_failed
) {
732 return &lc
->config
.info
;
734 fd
= loopcxt_get_fd(lc
);
738 if (ioctl(fd
, LOOP_GET_STATUS64
, &lc
->config
.info
) == 0) {
741 DBG(CXT
, ul_debugobj(lc
, "reading loop_info64 OK"));
742 return &lc
->config
.info
;
746 DBG(CXT
, ul_debugobj(lc
, "reading loop_info64 FAILED"));
754 * Returns (allocated) string with path to the file associated
755 * with the current loop device.
757 char *loopcxt_get_backing_file(struct loopdev_cxt
*lc
)
759 struct path_cxt
*sysfs
= loopcxt_get_sysfs(lc
);
764 * This is always preferred, the loop_info64
765 * has too small buffer for the filename.
767 ul_path_read_string(sysfs
, &res
, "loop/backing_file");
769 if (!res
&& loopcxt_ioctl_enabled(lc
)) {
770 struct loop_info64
*lo
= loopcxt_get_info(lc
);
773 lo
->lo_file_name
[LO_NAME_SIZE
- 2] = '*';
774 lo
->lo_file_name
[LO_NAME_SIZE
- 1] = '\0';
775 res
= strdup((char *) lo
->lo_file_name
);
779 DBG(CXT
, ul_debugobj(lc
, "get_backing_file [%s]", res
));
786 * Returns (allocated) string with loop reference. The same as backing file by
789 char *loopcxt_get_refname(struct loopdev_cxt
*lc
)
792 struct loop_info64
*lo
= loopcxt_get_info(lc
);
795 lo
->lo_file_name
[LO_NAME_SIZE
- 1] = '\0';
796 res
= strdup((char *) lo
->lo_file_name
);
799 DBG(CXT
, ul_debugobj(lc
, "get_refname [%s]", res
));
805 * @offset: returns offset number for the given device
807 * Returns: <0 on error, 0 on success
809 int loopcxt_get_offset(struct loopdev_cxt
*lc
, uint64_t *offset
)
811 struct path_cxt
*sysfs
= loopcxt_get_sysfs(lc
);
815 if (ul_path_read_u64(sysfs
, offset
, "loop/offset") == 0)
818 if (rc
&& loopcxt_ioctl_enabled(lc
)) {
819 struct loop_info64
*lo
= loopcxt_get_info(lc
);
822 *offset
= lo
->lo_offset
;
828 DBG(CXT
, ul_debugobj(lc
, "get_offset [rc=%d]", rc
));
834 * @blocksize: returns logical blocksize for the given device
836 * Returns: <0 on error, 0 on success
838 int loopcxt_get_blocksize(struct loopdev_cxt
*lc
, uint64_t *blocksize
)
840 struct path_cxt
*sysfs
= loopcxt_get_sysfs(lc
);
844 if (ul_path_read_u64(sysfs
, blocksize
, "queue/logical_block_size") == 0)
847 /* Fallback based on BLKSSZGET ioctl */
849 int fd
= loopcxt_get_fd(lc
);
854 rc
= blkdev_get_sector_size(fd
, &sz
);
861 DBG(CXT
, ul_debugobj(lc
, "get_blocksize [rc=%d]", rc
));
867 * @sizelimit: returns size limit for the given device
869 * Returns: <0 on error, 0 on success
871 int loopcxt_get_sizelimit(struct loopdev_cxt
*lc
, uint64_t *size
)
873 struct path_cxt
*sysfs
= loopcxt_get_sysfs(lc
);
877 if (ul_path_read_u64(sysfs
, size
, "loop/sizelimit") == 0)
880 if (rc
&& loopcxt_ioctl_enabled(lc
)) {
881 struct loop_info64
*lo
= loopcxt_get_info(lc
);
884 *size
= lo
->lo_sizelimit
;
890 DBG(CXT
, ul_debugobj(lc
, "get_sizelimit [rc=%d]", rc
));
896 * @type: returns encryption type
898 * Cryptoloop is DEPRECATED!
900 * Returns: <0 on error, 0 on success
902 int loopcxt_get_encrypt_type(struct loopdev_cxt
*lc
, uint32_t *type
)
904 struct loop_info64
*lo
= loopcxt_get_info(lc
);
907 /* not provided by sysfs */
910 *type
= lo
->lo_encrypt_type
;
915 DBG(CXT
, ul_debugobj(lc
, "get_encrypt_type [rc=%d]", rc
));
922 * Cryptoloop is DEPRECATED!
924 * Returns: <0 on error, 0 on success
926 const char *loopcxt_get_crypt_name(struct loopdev_cxt
*lc
)
928 struct loop_info64
*lo
= loopcxt_get_info(lc
);
931 return (char *) lo
->lo_crypt_name
;
933 DBG(CXT
, ul_debugobj(lc
, "get_crypt_name failed"));
939 * @devno: returns backing file devno
941 * Returns: <0 on error, 0 on success
943 int loopcxt_get_backing_devno(struct loopdev_cxt
*lc
, dev_t
*devno
)
945 struct loop_info64
*lo
= loopcxt_get_info(lc
);
950 *devno
= lo
->lo_device
;
955 DBG(CXT
, ul_debugobj(lc
, "get_backing_devno [rc=%d]", rc
));
961 * @ino: returns backing file inode
963 * Returns: <0 on error, 0 on success
965 int loopcxt_get_backing_inode(struct loopdev_cxt
*lc
, ino_t
*ino
)
967 struct loop_info64
*lo
= loopcxt_get_info(lc
);
977 DBG(CXT
, ul_debugobj(lc
, "get_backing_inode [rc=%d]", rc
));
982 * Check if the kernel supports partitioned loop devices.
985 * - kernels < 3.2 support partitioned loop devices and PT scanning
986 * only if max_part= module parameter is non-zero
988 * - kernels >= 3.2 always support partitioned loop devices
990 * - kernels >= 3.2 always support BLKPG_{ADD,DEL}_PARTITION ioctls
992 * - kernels >= 3.2 enable PT scanner only if max_part= is non-zero or if the
993 * LO_FLAGS_PARTSCAN flag is set for the device. The PT scanner is disabled
996 * See kernel commit e03c8dd14915fabc101aa495828d58598dc5af98.
998 int loopmod_supports_partscan(void)
1003 if (get_linux_version() >= KERNEL_VERSION(3,2,0))
1006 f
= fopen("/sys/module/loop/parameters/max_part", "r" UL_CLOEXECSTR
);
1009 rc
= fscanf(f
, "%d", &ret
);
1011 return rc
== 1 ? ret
: 0;
1017 * Returns: 1 if the partscan flags is set *or* (for old kernels) partitions
1018 * scanning is enabled for all loop devices.
1020 int loopcxt_is_partscan(struct loopdev_cxt
*lc
)
1022 struct path_cxt
*sysfs
= loopcxt_get_sysfs(lc
);
1027 if (ul_path_read_s32(sysfs
, &fl
, "loop/partscan") == 0)
1031 /* old kernels (including kernels without loopN/loop/<flags> directory */
1032 return loopmod_supports_partscan();
1038 * Returns: 1 if the autoclear flags is set.
1040 int loopcxt_is_autoclear(struct loopdev_cxt
*lc
)
1042 struct path_cxt
*sysfs
= loopcxt_get_sysfs(lc
);
1046 if (ul_path_read_s32(sysfs
, &fl
, "loop/autoclear") == 0)
1050 if (loopcxt_ioctl_enabled(lc
)) {
1051 struct loop_info64
*lo
= loopcxt_get_info(lc
);
1053 return lo
->lo_flags
& LO_FLAGS_AUTOCLEAR
;
1061 * Returns: 1 if the readonly flags is set.
1063 int loopcxt_is_readonly(struct loopdev_cxt
*lc
)
1065 struct path_cxt
*sysfs
= loopcxt_get_sysfs(lc
);
1069 if (ul_path_read_s32(sysfs
, &fl
, "ro") == 0)
1073 if (loopcxt_ioctl_enabled(lc
)) {
1074 struct loop_info64
*lo
= loopcxt_get_info(lc
);
1076 return lo
->lo_flags
& LO_FLAGS_READ_ONLY
;
1084 * Returns: 1 if the dio flags is set.
1086 int loopcxt_is_dio(struct loopdev_cxt
*lc
)
1088 struct path_cxt
*sysfs
= loopcxt_get_sysfs(lc
);
1092 if (ul_path_read_s32(sysfs
, &fl
, "loop/dio") == 0)
1095 if (loopcxt_ioctl_enabled(lc
)) {
1096 struct loop_info64
*lo
= loopcxt_get_info(lc
);
1098 return lo
->lo_flags
& LO_FLAGS_DIRECT_IO
;
1105 * @st: backing file stat or NULL
1106 * @backing_file: filename
1107 * @offset: offset (use LOOPDEV_FL_OFFSET if specified)
1108 * @sizelimit: size limit (use LOOPDEV_FL_SIZELIMIT if specified)
1109 * @flags: LOOPDEV_FL_{OFFSET,SIZELIMIT}
1111 * Returns 1 if the current @lc loopdev is associated with the given backing
1112 * file. Note that the preferred way is to use devno and inode number rather
1113 * than filename. The @backing_file filename is poor solution usable in case
1114 * that you don't have rights to call stat().
1116 * LOOPDEV_FL_SIZELIMIT requires LOOPDEV_FL_OFFSET being set as well.
1118 * Don't forget that old kernels provide very restricted (in size) backing
1119 * filename by LOOP_GET_STAT64 ioctl only.
1121 int loopcxt_is_used(struct loopdev_cxt
*lc
,
1123 const char *backing_file
,
1134 DBG(CXT
, ul_debugobj(lc
, "checking %s vs. %s",
1135 loopcxt_get_device(lc
),
1138 if (st
&& loopcxt_get_backing_inode(lc
, &ino
) == 0 &&
1139 loopcxt_get_backing_devno(lc
, &dev
) == 0) {
1141 if (ino
== st
->st_ino
&& dev
== st
->st_dev
)
1144 /* don't use filename if we have devno and inode */
1148 /* poor man's solution */
1150 char *name
= loopcxt_get_backing_file(lc
);
1151 int rc
= name
&& strcmp(name
, backing_file
) == 0;
1160 if (flags
& LOOPDEV_FL_OFFSET
) {
1163 int rc
= loopcxt_get_offset(lc
, &off
) == 0 && off
== offset
;
1165 if (rc
&& flags
& LOOPDEV_FL_SIZELIMIT
) {
1168 return loopcxt_get_sizelimit(lc
, &sz
) == 0 && sz
== sizelimit
;
1176 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1178 int loopcxt_set_offset(struct loopdev_cxt
*lc
, uint64_t offset
)
1182 lc
->config
.info
.lo_offset
= offset
;
1184 DBG(CXT
, ul_debugobj(lc
, "set offset=%jd", offset
));
1189 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1191 int loopcxt_set_sizelimit(struct loopdev_cxt
*lc
, uint64_t sizelimit
)
1195 lc
->config
.info
.lo_sizelimit
= sizelimit
;
1197 DBG(CXT
, ul_debugobj(lc
, "set sizelimit=%jd", sizelimit
));
1202 * The blocksize will be used by loopcxt_set_device(). For already exiting
1203 * devices use loopcxt_ioctl_blocksize().
1205 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1207 int loopcxt_set_blocksize(struct loopdev_cxt
*lc
, uint64_t blocksize
)
1211 lc
->blocksize
= blocksize
;
1213 DBG(CXT
, ul_debugobj(lc
, "set blocksize=%jd", blocksize
));
1219 * @flags: kernel LO_FLAGS_{READ_ONLY,USE_AOPS,AUTOCLEAR} flags
1221 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1223 * Returns: 0 on success, <0 on error.
1225 int loopcxt_set_flags(struct loopdev_cxt
*lc
, uint32_t flags
)
1229 lc
->config
.info
.lo_flags
= flags
;
1231 DBG(CXT
, ul_debugobj(lc
, "set flags=%u", (unsigned) flags
));
1237 * @refname: reference name (used to overwrite lo_file_name where is backing
1240 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1242 * Returns: 0 on success, <0 on error.
1244 int loopcxt_set_refname(struct loopdev_cxt
*lc
, const char *refname
)
1249 memset(lc
->config
.info
.lo_file_name
, 0, sizeof(lc
->config
.info
.lo_file_name
));
1251 xstrncpy((char *)lc
->config
.info
.lo_file_name
, refname
, LO_NAME_SIZE
);
1253 DBG(CXT
, ul_debugobj(lc
, "set refname=%s", (char *)lc
->config
.info
.lo_file_name
));
1259 * @filename: backing file path (the path will be canonicalized)
1261 * The setting is removed by loopcxt_set_device() loopcxt_next()!
1263 * Returns: 0 on success, <0 on error.
1265 int loopcxt_set_backing_file(struct loopdev_cxt
*lc
, const char *filename
)
1270 lc
->filename
= canonicalize_path(filename
);
1274 if (!lc
->config
.info
.lo_file_name
[0])
1275 loopcxt_set_refname(lc
, lc
->filename
);
1277 DBG(CXT
, ul_debugobj(lc
, "set backing file=%s", lc
->filename
));
1282 * In kernels prior to v3.9, if the offset or sizelimit options
1283 * are used, the block device's size won't be synced automatically.
1284 * blockdev --getsize64 and filesystems will use the backing
1285 * file size until the block device has been re-opened or the
1286 * LOOP_SET_CAPACITY ioctl is called to sync the sizes.
1288 * Since mount -oloop uses the LO_FLAGS_AUTOCLEAR option and passes
1289 * the open file descriptor to the mount system call, we need to use
1290 * the ioctl. Calling losetup directly doesn't have this problem since
1291 * it closes the device when it exits and whatever consumes the device
1292 * next will re-open it, causing the resync.
1294 static int loopcxt_check_size(struct loopdev_cxt
*lc
, int file_fd
)
1296 uint64_t size
, expected_size
;
1300 if (!lc
->config
.info
.lo_offset
&& !lc
->config
.info
.lo_sizelimit
)
1303 if (fstat(file_fd
, &st
)) {
1304 DBG(CXT
, ul_debugobj(lc
, "failed to fstat backing file"));
1307 if (S_ISBLK(st
.st_mode
)) {
1308 if (blkdev_get_size(file_fd
,
1309 (unsigned long long *) &expected_size
)) {
1310 DBG(CXT
, ul_debugobj(lc
, "failed to determine device size"));
1314 expected_size
= st
.st_size
;
1316 if (expected_size
== 0 || expected_size
<= lc
->config
.info
.lo_offset
) {
1317 DBG(CXT
, ul_debugobj(lc
, "failed to determine expected size"));
1318 return 0; /* ignore this error */
1321 if (lc
->config
.info
.lo_offset
> 0)
1322 expected_size
-= lc
->config
.info
.lo_offset
;
1324 if (lc
->config
.info
.lo_sizelimit
> 0 && lc
->config
.info
.lo_sizelimit
< expected_size
)
1325 expected_size
= lc
->config
.info
.lo_sizelimit
;
1327 dev_fd
= loopcxt_get_fd(lc
);
1329 DBG(CXT
, ul_debugobj(lc
, "failed to get loop FD"));
1333 if (blkdev_get_size(dev_fd
, (unsigned long long *) &size
)) {
1334 DBG(CXT
, ul_debugobj(lc
, "failed to determine loopdev size"));
1338 /* It's block device, so, align to 512-byte sectors */
1339 if (expected_size
% 512) {
1340 DBG(CXT
, ul_debugobj(lc
, "expected size misaligned to 512-byte sectors"));
1341 expected_size
= (expected_size
>> 9) << 9;
1344 if (expected_size
!= size
) {
1345 DBG(CXT
, ul_debugobj(lc
, "warning: loopdev and expected "
1346 "size mismatch (%ju/%ju)",
1347 size
, expected_size
));
1349 if (loopcxt_ioctl_capacity(lc
)) {
1350 /* ioctl not available */
1351 if (errno
== ENOTTY
|| errno
== EINVAL
)
1356 if (blkdev_get_size(dev_fd
, (unsigned long long *) &size
))
1359 if (expected_size
!= size
) {
1361 DBG(CXT
, ul_debugobj(lc
, "failed to set loopdev size, "
1362 "size: %ju, expected: %ju",
1363 size
, expected_size
));
1375 * Associate the current device (see loopcxt_{set,get}_device()) with
1376 * a file (see loopcxt_set_backing_file()).
1378 * The device is initialized read-write by default. If you want read-only
1379 * device then set LO_FLAGS_READ_ONLY by loopcxt_set_flags(). The LOOPDEV_FL_*
1380 * flags are ignored and modified according to LO_FLAGS_*.
1382 * If the device is already open by loopcxt_get_fd() then this setup device
1383 * function will re-open the device to fix read/write mode.
1385 * The device is also initialized read-only if the backing file is not
1386 * possible to open read-write (e.g. read-only FS).
1388 * Returns: <0 on error, 0 on success.
1390 int loopcxt_setup_device(struct loopdev_cxt
*lc
)
1392 int file_fd
, dev_fd
;
1393 mode_t flags
= O_CLOEXEC
, mode
= O_RDWR
;
1394 int rc
= -1, cnt
= 0;
1398 if (!lc
|| !*lc
->device
|| !lc
->filename
)
1401 DBG(SETUP
, ul_debugobj(lc
, "device setup requested"));
1404 * Open backing file and device
1406 if (lc
->config
.info
.lo_flags
& LO_FLAGS_READ_ONLY
)
1409 if (lc
->config
.info
.lo_flags
& LO_FLAGS_DIRECT_IO
)
1412 if ((file_fd
= open(lc
->filename
, mode
| flags
)) < 0) {
1413 if (mode
!= O_RDONLY
&& (errno
== EROFS
|| errno
== EACCES
))
1414 file_fd
= open(lc
->filename
, (mode
= O_RDONLY
) | flags
);
1417 DBG(SETUP
, ul_debugobj(lc
, "open backing file failed: %m"));
1421 DBG(SETUP
, ul_debugobj(lc
, "backing file open: OK"));
1423 if (mode
== O_RDONLY
)
1424 lc
->config
.info
.lo_flags
|= LO_FLAGS_READ_ONLY
; /* kernel loopdev mode */
1426 lc
->config
.info
.lo_flags
&= ~LO_FLAGS_READ_ONLY
;
1431 /* For the ioctls, it's enough to use O_RDONLY, but udevd
1432 * monitor devices by inotify, and udevd needs IN_CLOSE_WRITE
1433 * event to trigger probing of the new device.
1435 * The mode used for the device does not have to match the mode
1436 * used for the backing file.
1438 dev_fd
= __loopcxt_get_fd(lc
, O_RDWR
);
1439 if (dev_fd
>= 0 || lc
->control_ok
== 0)
1441 if (errno
!= EACCES
&& errno
!= ENOENT
)
1443 /* We have permissions to open /dev/loop-control, but open
1444 * /dev/loopN failed with EACCES, it's probably because udevd
1445 * does not applied chown yet. Let's wait a moment. */
1447 } while (cnt
++ < 16);
1454 DBG(SETUP
, ul_debugobj(lc
, "device open: OK"));
1457 * Atomic way to configure all by one ioctl call
1458 * -- since Linux v5.8-rc1, commit 3448914e8cc550ba792d4ccc74471d1ca4293aae
1460 lc
->config
.fd
= file_fd
;
1461 if (lc
->blocksize
> 0)
1462 lc
->config
.block_size
= lc
->blocksize
;
1464 rc
= repeat_on_eagain( ioctl(dev_fd
, LOOP_CONFIGURE
, &lc
->config
) );
1467 if (errno
!= EINVAL
&& errno
!= ENOTTY
&& errno
!= ENOSYS
) {
1468 DBG(SETUP
, ul_debugobj(lc
, "LOOP_CONFIGURE failed: %m"));
1473 DBG(SETUP
, ul_debugobj(lc
, "LOOP_CONFIGURE: OK"));
1477 * Old deprecated way; first assign backing file FD and then in the
1478 * second step set loop device properties.
1481 if (ioctl(dev_fd
, LOOP_SET_FD
, file_fd
) < 0) {
1484 DBG(SETUP
, ul_debugobj(lc
, "LOOP_SET_FD failed: %m"));
1488 DBG(SETUP
, ul_debugobj(lc
, "LOOP_SET_FD: OK"));
1490 if (lc
->blocksize
> 0
1491 && (rc
= loopcxt_ioctl_blocksize(lc
, lc
->blocksize
)) < 0) {
1496 if ((rc
= loopcxt_ioctl_status(lc
)) < 0) {
1502 if ((rc
= loopcxt_check_size(lc
, file_fd
)))
1507 memset(&lc
->config
, 0, sizeof(lc
->config
));
1509 lc
->info_failed
= 0;
1511 DBG(SETUP
, ul_debugobj(lc
, "success [rc=0]"));
1516 if (dev_fd
>= 0 && rc
!= -EBUSY
)
1517 ioctl(dev_fd
, LOOP_CLR_FD
, 0);
1521 DBG(SETUP
, ul_debugobj(lc
, "failed [rc=%d]", rc
));
1529 * Update status of the current device (see loopcxt_{set,get}_device()).
1531 * Note that once initialized, kernel accepts only selected changes:
1532 * LO_FLAGS_AUTOCLEAR and LO_FLAGS_PARTSCAN
1533 * For more see linux/drivers/block/loop.c:loop_set_status()
1535 * Returns: <0 on error, 0 on success.
1537 int loopcxt_ioctl_status(struct loopdev_cxt
*lc
)
1542 dev_fd
= loopcxt_get_fd(lc
);
1547 DBG(SETUP
, ul_debugobj(lc
, "calling LOOP_SET_STATUS64"));
1549 rc
= repeat_on_eagain( ioctl(dev_fd
, LOOP_SET_STATUS64
, &lc
->config
.info
) );
1551 DBG(SETUP
, ul_debugobj(lc
, "LOOP_SET_STATUS64 failed: %m"));
1555 DBG(SETUP
, ul_debugobj(lc
, "LOOP_SET_STATUS64: OK"));
1559 int loopcxt_ioctl_capacity(struct loopdev_cxt
*lc
)
1561 int rc
, fd
= loopcxt_get_fd(lc
);
1566 DBG(SETUP
, ul_debugobj(lc
, "calling LOOP_SET_CAPACITY"));
1568 /* Kernels prior to v2.6.30 don't support this ioctl */
1569 rc
= repeat_on_eagain( ioctl(fd
, LOOP_SET_CAPACITY
, 0) );
1571 DBG(CXT
, ul_debugobj(lc
, "LOOP_SET_CAPACITY failed: %m"));
1575 DBG(CXT
, ul_debugobj(lc
, "capacity set"));
1579 int loopcxt_ioctl_dio(struct loopdev_cxt
*lc
, unsigned long use_dio
)
1581 int rc
, fd
= loopcxt_get_fd(lc
);
1586 DBG(SETUP
, ul_debugobj(lc
, "calling LOOP_SET_DIRECT_IO"));
1588 /* Kernels prior to v4.4 don't support this ioctl */
1589 rc
= repeat_on_eagain( ioctl(fd
, LOOP_SET_DIRECT_IO
, use_dio
) );
1591 DBG(CXT
, ul_debugobj(lc
, "LOOP_SET_DIRECT_IO failed: %m"));
1595 DBG(CXT
, ul_debugobj(lc
, "direct io set"));
1600 * Kernel uses "unsigned long" as ioctl arg, but we use u64 for all sizes to
1601 * keep loopdev internal API simple.
1603 int loopcxt_ioctl_blocksize(struct loopdev_cxt
*lc
, uint64_t blocksize
)
1605 int rc
, fd
= loopcxt_get_fd(lc
);
1610 DBG(SETUP
, ul_debugobj(lc
, "calling LOOP_SET_BLOCK_SIZE"));
1612 rc
= repeat_on_eagain(
1613 ioctl(fd
, LOOP_SET_BLOCK_SIZE
, (unsigned long) blocksize
) );
1615 DBG(CXT
, ul_debugobj(lc
, "LOOP_SET_BLOCK_SIZE failed: %m"));
1619 DBG(CXT
, ul_debugobj(lc
, "logical block size set"));
1623 int loopcxt_delete_device(struct loopdev_cxt
*lc
)
1625 int rc
, fd
= loopcxt_get_fd(lc
);
1630 DBG(SETUP
, ul_debugobj(lc
, "calling LOOP_SET_CLR_FD"));
1632 rc
= repeat_on_eagain( ioctl(fd
, LOOP_CLR_FD
, 0) );
1634 DBG(CXT
, ul_debugobj(lc
, "LOOP_CLR_FD failed: %m"));
1638 DBG(CXT
, ul_debugobj(lc
, "device removed"));
1642 int loopcxt_add_device(struct loopdev_cxt
*lc
)
1646 const char *p
, *dev
= loopcxt_get_device(lc
);
1651 if (!(lc
->flags
& LOOPDEV_FL_CONTROL
)) {
1656 p
= strrchr(dev
, '/');
1657 if (!p
|| (sscanf(p
, "/loop%d", &nr
) != 1 && sscanf(p
, "/%d", &nr
) != 1)
1661 ctl
= open(_PATH_DEV_LOOPCTL
, O_RDWR
|O_CLOEXEC
);
1663 DBG(CXT
, ul_debugobj(lc
, "add_device %d", nr
));
1664 rc
= ioctl(ctl
, LOOP_CTL_ADD
, nr
);
1667 lc
->control_ok
= rc
>= 0 ? 1 : 0;
1669 DBG(CXT
, ul_debugobj(lc
, "add_device done [rc=%d]", rc
));
1674 * Note that LOOP_CTL_GET_FREE ioctl is supported since kernel 3.1. In older
1675 * kernels we have to check all loop devices to found unused one.
1677 * See kernel commit 770fe30a46a12b6fb6b63fbe1737654d28e8484.
1679 * Returns: 0 = success, < 0 error
1681 int loopcxt_find_unused(struct loopdev_cxt
*lc
)
1685 DBG(CXT
, ul_debugobj(lc
, "find_unused requested"));
1687 if (lc
->flags
& LOOPDEV_FL_CONTROL
) {
1690 DBG(CXT
, ul_debugobj(lc
, "using loop-control"));
1692 ctl
= open(_PATH_DEV_LOOPCTL
, O_RDWR
|O_CLOEXEC
);
1694 rc
= ioctl(ctl
, LOOP_CTL_GET_FREE
);
1699 snprintf(name
, sizeof(name
), "loop%d", rc
);
1701 rc
= loopiter_set_device(lc
, name
);
1703 lc
->control_ok
= ctl
>= 0 && rc
== 0 ? 1 : 0;
1706 DBG(CXT
, ul_debugobj(lc
, "find_unused by loop-control [rc=%d]", rc
));
1710 DBG(CXT
, ul_debugobj(lc
, "using loop scan"));
1711 rc
= loopcxt_init_iterator(lc
, LOOPITER_FL_FREE
);
1715 rc
= loopcxt_next(lc
);
1716 loopcxt_deinit_iterator(lc
);
1717 DBG(CXT
, ul_debugobj(lc
, "find_unused by scan [rc=%d]", rc
));
1727 * Return: TRUE/FALSE
1729 int loopdev_is_autoclear(const char *device
)
1731 struct loopdev_cxt lc
;
1737 rc
= loopcxt_init(&lc
, 0);
1739 rc
= loopcxt_set_device(&lc
, device
);
1741 rc
= loopcxt_is_autoclear(&lc
);
1743 loopcxt_deinit(&lc
);
1747 char *loopdev_get_backing_file(const char *device
)
1749 struct loopdev_cxt lc
;
1754 if (loopcxt_init(&lc
, 0))
1756 if (loopcxt_set_device(&lc
, device
) == 0)
1757 res
= loopcxt_get_backing_file(&lc
);
1759 loopcxt_deinit(&lc
);
1764 * Returns: TRUE/FALSE
1766 int loopdev_has_backing_file(const char *device
)
1768 char *tmp
= loopdev_get_backing_file(device
);
1778 * Returns: TRUE/FALSE
1780 int loopdev_is_used(const char *device
, const char *filename
,
1781 uint64_t offset
, uint64_t sizelimit
, int flags
)
1783 struct loopdev_cxt lc
;
1787 if (!device
|| !filename
)
1790 rc
= loopcxt_init(&lc
, 0);
1792 rc
= loopcxt_set_device(&lc
, device
);
1796 rc
= !stat(filename
, &st
);
1797 rc
= loopcxt_is_used(&lc
, rc
? &st
: NULL
, filename
, offset
, sizelimit
, flags
);
1799 loopcxt_deinit(&lc
);
1804 * Returns: 0 = success, < 0 error
1806 int loopdev_delete(const char *device
)
1808 struct loopdev_cxt lc
;
1814 rc
= loopcxt_init(&lc
, 0);
1816 rc
= loopcxt_set_device(&lc
, device
);
1818 rc
= loopcxt_delete_device(&lc
);
1819 loopcxt_deinit(&lc
);
1824 * Returns: 0 = success, < 0 error, 1 not found
1826 int loopcxt_find_by_backing_file(struct loopdev_cxt
*lc
, const char *filename
,
1827 uint64_t offset
, uint64_t sizelimit
, int flags
)
1835 hasst
= !stat(filename
, &st
);
1837 rc
= loopcxt_init_iterator(lc
, LOOPITER_FL_USED
);
1841 while ((rc
= loopcxt_next(lc
)) == 0) {
1843 if (loopcxt_is_used(lc
, hasst
? &st
: NULL
,
1844 filename
, offset
, sizelimit
, flags
))
1848 loopcxt_deinit_iterator(lc
);
1853 * Returns: 0 = not found, < 0 error, 1 found, 2 found full size and offset match
1855 int loopcxt_find_overlap(struct loopdev_cxt
*lc
, const char *filename
,
1856 uint64_t offset
, uint64_t sizelimit
)
1864 DBG(CXT
, ul_debugobj(lc
, "find_overlap requested"));
1865 hasst
= !stat(filename
, &st
);
1867 rc
= loopcxt_init_iterator(lc
, LOOPITER_FL_USED
);
1871 while ((rc
= loopcxt_next(lc
)) == 0) {
1872 uint64_t lc_sizelimit
, lc_offset
;
1874 rc
= loopcxt_is_used(lc
, hasst
? &st
: NULL
,
1875 filename
, offset
, sizelimit
, 0);
1877 * Either the loopdev is unused or we've got an error which can
1878 * happen when we are racing with device autoclear. Just ignore
1884 DBG(CXT
, ul_debugobj(lc
, "found %s backed by %s",
1885 loopcxt_get_device(lc
), filename
));
1887 rc
= loopcxt_get_offset(lc
, &lc_offset
);
1889 DBG(CXT
, ul_debugobj(lc
, "failed to get offset for device %s",
1890 loopcxt_get_device(lc
)));
1893 rc
= loopcxt_get_sizelimit(lc
, &lc_sizelimit
);
1895 DBG(CXT
, ul_debugobj(lc
, "failed to get sizelimit for device %s",
1896 loopcxt_get_device(lc
)));
1901 if (lc_sizelimit
== sizelimit
&& lc_offset
== offset
) {
1902 DBG(CXT
, ul_debugobj(lc
, "overlapping loop device %s (full match)",
1903 loopcxt_get_device(lc
)));
1909 if (lc_sizelimit
!= 0 && offset
>= lc_offset
+ lc_sizelimit
)
1911 if (sizelimit
!= 0 && offset
+ sizelimit
<= lc_offset
)
1914 DBG(CXT
, ul_debugobj(lc
, "overlapping loop device %s",
1915 loopcxt_get_device(lc
)));
1921 rc
= 0; /* not found */
1923 loopcxt_deinit_iterator(lc
);
1924 DBG(CXT
, ul_debugobj(lc
, "find_overlap done [rc=%d]", rc
));
1929 * Returns allocated string with device name
1931 char *loopdev_find_by_backing_file(const char *filename
, uint64_t offset
, uint64_t sizelimit
, int flags
)
1933 struct loopdev_cxt lc
;
1939 if (loopcxt_init(&lc
, 0))
1941 if (loopcxt_find_by_backing_file(&lc
, filename
, offset
, sizelimit
, flags
) == 0)
1942 res
= loopcxt_strdup_device(&lc
);
1943 loopcxt_deinit(&lc
);
1949 * Returns number of loop devices associated with @file, if only one loop
1950 * device is associated with the given @filename and @loopdev is not NULL then
1951 * @loopdev returns name of the device.
1953 int loopdev_count_by_backing_file(const char *filename
, char **loopdev
)
1955 struct loopdev_cxt lc
;
1961 rc
= loopcxt_init(&lc
, 0);
1964 if (loopcxt_init_iterator(&lc
, LOOPITER_FL_USED
))
1967 while(loopcxt_next(&lc
) == 0) {
1968 char *backing
= loopcxt_get_backing_file(&lc
);
1970 if (!backing
|| strcmp(backing
, filename
) != 0) {
1976 if (loopdev
&& count
== 0)
1977 *loopdev
= loopcxt_strdup_device(&lc
);
1981 loopcxt_deinit(&lc
);
1983 if (loopdev
&& count
> 1) {
1990 #ifdef TEST_PROGRAM_LOOPDEV
1991 int main(int argc
, char *argv
[])
1996 if (strcmp(argv
[1], "--is-loopdev") == 0 && argc
== 3)
1997 printf("%s: %s\n", argv
[2], is_loopdev(argv
[2]) ? "OK" : "FAIL");
2001 return EXIT_SUCCESS
;
2003 fprintf(stderr
, "usage: %1$s --is-loopdev <dev>\n",
2004 program_invocation_short_name
);
2005 return EXIT_FAILURE
;