Coverage Report

Created: 2023-06-07 06:09

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