Coverage Report

Created: 2025-11-11 06:33

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