Coverage Report

Created: 2026-08-30 07:13

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