1 /* Originally from Ted's losetup.c */
3 * losetup.c - setup and control loop devices
12 #include <sys/ioctl.h>
15 #include <sys/sysmacros.h>
25 #include "pathnames.h"
27 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
31 static int is_associated(int dev, struct stat *file, unsigned long long offset, int isoff);
34 loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
36 memset(info, 0, sizeof(*info));
37 info->lo_number = info64->lo_number;
38 info->lo_device = info64->lo_device;
39 info->lo_inode = info64->lo_inode;
40 info->lo_rdevice = info64->lo_rdevice;
41 info->lo_offset = info64->lo_offset;
42 info->lo_encrypt_type = info64->lo_encrypt_type;
43 info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
44 info->lo_flags = info64->lo_flags;
45 info->lo_init[0] = info64->lo_init[0];
46 info->lo_init[1] = info64->lo_init[1];
47 if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
48 memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
50 memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
51 memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
53 /* error in case values were truncated */
54 if (info->lo_device != info64->lo_device ||
55 info->lo_rdevice != info64->lo_rdevice ||
56 info->lo_inode != info64->lo_inode ||
57 info->lo_offset != info64->lo_offset)
64 #define NLOOPS_DEFAULT 8 /* /dev/loop[0-7] */
67 int flag; /* scanning options */
68 FILE *proc; /* /proc/partitions */
69 int ncur; /* current possition */
70 int *minors; /* ary of minor numbers (when scan whole /dev) */
71 int nminors; /* number of items in *minors */
72 char name[128]; /* device name */
73 int ct_perm; /* count permission problems */
74 int ct_succ; /* count number of successfully
78 #define LLFLG_USEDONLY (1 << 1) /* return used devices only */
79 #define LLFLG_FREEONLY (1 << 2) /* return non-used devices */
80 #define LLFLG_DONE (1 << 3) /* all is done */
81 #define LLFLG_PROCFS (1 << 4) /* try to found used devices in /proc/partitions */
82 #define LLFLG_SUBDIR (1 << 5) /* /dev/loop/N */
83 #define LLFLG_DFLT (1 << 6) /* directly try to check default loops */
86 is_loop_device (const char *device) {
89 return (stat(device, &st) == 0 &&
90 S_ISBLK(st.st_mode) &&
91 major(st.st_rdev) == LOOPMAJOR);
100 if (ioctl (fd, LOOP_GET_STATUS, &li) < 0 && errno == ENXIO)
106 is_loopfd_autoclear(int fd)
109 struct loop_info64 lo64;
111 if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0) {
112 if (lo64.lo_flags & LO_FLAGS_AUTOCLEAR)
115 } else if (ioctl(fd, LOOP_GET_STATUS, &lo) == 0) {
116 if (lo.lo_flags & LO_FLAGS_AUTOCLEAR)
123 is_loop_autoclear(const char *device)
127 if ((fd = open(device, O_RDONLY)) < 0)
129 rc = is_loopfd_autoclear(fd);
136 looplist_open(struct looplist *ll, int flag)
140 memset(ll, 0, sizeof(*ll));
144 if (stat(_PATH_DEV, &st) == -1 || (!S_ISDIR(st.st_mode)))
145 return -1; /* /dev doesn't exist */
147 if (stat(_PATH_DEV_LOOP, &st) == 0 && S_ISDIR(st.st_mode))
148 ll->flag |= LLFLG_SUBDIR; /* /dev/loop/ exists */
150 if ((ll->flag & LLFLG_USEDONLY) &&
151 stat(_PATH_PROC_PARTITIONS, &st) == 0)
152 ll->flag |= LLFLG_PROCFS; /* try /proc/partitions */
154 ll->flag |= LLFLG_DFLT; /* required! */
159 looplist_close(struct looplist *ll)
167 ll->flag |= LLFLG_DONE;
171 looplist_open_dev(struct looplist *ll, int lnum)
177 /* create a full device path */
178 snprintf(ll->name, sizeof(ll->name),
179 ll->flag & LLFLG_SUBDIR ?
180 _PATH_DEV_LOOP "/%d" :
184 fd = open(ll->name, O_RDONLY);
190 if (fstat(fd, &st) == -1)
192 if (!S_ISBLK(st.st_mode) || major(st.st_rdev) != LOOPMAJOR)
197 /* check if the device is wanted */
198 if (!(ll->flag & (LLFLG_USEDONLY | LLFLG_FREEONLY)))
201 used = is_loop_used(fd);
203 if ((ll->flag & LLFLG_USEDONLY) && used)
205 if ((ll->flag & LLFLG_FREEONLY) && !used)
212 /* returns <N> from "loop<N>" */
214 name2minor(int hasprefix, const char *name)
220 if (strncmp(name, "loop", 4))
224 n = strtol(name, &end, 10);
225 if (end && end != name && *end == '\0' && n >= 0)
231 cmpnum(const void *p1, const void *p2)
233 return (* (int *) p1) > (* (int *) p2);
237 * The classic scandir() is more expensive and less portable.
238 * We needn't full loop device names -- minor numers (loop<N>)
242 loop_scandir(const char *dirname, int **ary, int hasprefix)
246 int n, count = 0, arylen = 0;
248 if (!dirname || !ary)
250 dir = opendir(dirname);
256 while((d = readdir(dir))) {
257 if (d->d_type != DT_BLK && d->d_type != DT_UNKNOWN && d->d_type != DT_LNK)
259 n = name2minor(hasprefix, d->d_name);
260 if (n == -1 || n < NLOOPS_DEFAULT)
262 if (count + 1 > arylen) {
264 *ary = *ary ? realloc(*ary, arylen * sizeof(int)) :
265 malloc(arylen * sizeof(int));
272 qsort(*ary, count, sizeof(int), cmpnum);
279 looplist_next(struct looplist *ll)
283 if (ll->flag & LLFLG_DONE)
286 /* A) Look for used loop devices in /proc/partitions ("losetup -a" only)
288 if (ll->flag & LLFLG_PROCFS) {
292 ll->proc = fopen(_PATH_PROC_PARTITIONS, "r");
294 while (ll->proc && fgets(buf, sizeof(buf), ll->proc)) {
296 unsigned long long sz;
299 if (sscanf(buf, " %d %d %llu %128[^\n ]",
300 &m, &n, &sz, name) != 4)
304 /* unfortunately, real minor numbers needn't to match
305 * loop<N> device name. We have to follow device name.
307 n = name2minor(1, name);
308 fd = looplist_open_dev(ll, n);
316 /* B) Classic way, try first eight loop devices (default number
317 * of loop devices). This is enough for 99% of all cases.
319 if (ll->flag & LLFLG_DFLT) {
320 for (++ll->ncur; ll->ncur < NLOOPS_DEFAULT; ll->ncur++) {
321 fd = looplist_open_dev(ll, ll->ncur);
325 ll->flag &= ~LLFLG_DFLT;
328 /* C) the worst posibility, scan all /dev or /dev/loop
331 ll->nminors = (ll->flag & LLFLG_SUBDIR) ?
332 loop_scandir(_PATH_DEV_LOOP, &ll->minors, 0) :
333 loop_scandir(_PATH_DEV, &ll->minors, 1);
336 for (++ll->ncur; ll->ncur < ll->nminors; ll->ncur++) {
337 fd = looplist_open_dev(ll, ll->minors[ll->ncur]);
350 set_capacity(const char *device)
353 int fd = open(device, O_RDONLY);
358 if (ioctl(fd, LOOP_SET_CAPACITY) != 0)
364 fprintf(stderr, _("loop: can't set capacity on device %s: %s\n"),
365 device, strerror (errsv));
372 show_loop_fd(int fd, char *device) {
373 struct loop_info loopinfo;
374 struct loop_info64 loopinfo64;
377 if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
379 loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
380 loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
381 loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
383 printf("%s: [%04" PRIx64 "]:%" PRIu64 " (%s)",
384 device, loopinfo64.lo_device, loopinfo64.lo_inode,
385 loopinfo64.lo_file_name);
387 if (loopinfo64.lo_offset)
388 printf(_(", offset %" PRIu64 ), loopinfo64.lo_offset);
390 if (loopinfo64.lo_sizelimit)
391 printf(_(", sizelimit %" PRIu64 ), loopinfo64.lo_sizelimit);
393 if (loopinfo64.lo_encrypt_type ||
394 loopinfo64.lo_crypt_name[0]) {
395 char *e = (char *)loopinfo64.lo_crypt_name;
397 if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
399 printf(_(", encryption %s (type %" PRIu32 ")"),
400 e, loopinfo64.lo_encrypt_type);
406 if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
407 printf ("%s: [%04x]:%ld (%s)",
408 device, (unsigned int)loopinfo.lo_device, loopinfo.lo_inode,
411 if (loopinfo.lo_offset)
412 printf(_(", offset %d"), loopinfo.lo_offset);
414 if (loopinfo.lo_encrypt_type)
415 printf(_(", encryption type %d\n"),
416 loopinfo.lo_encrypt_type);
423 fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
424 device, strerror (errsv));
429 show_loop(char *device) {
432 if ((fd = open(device, O_RDONLY)) < 0) {
434 fprintf(stderr, _("loop: can't open device %s: %s\n"),
435 device, strerror (errsv));
438 ret = show_loop_fd(fd, device);
445 show_used_loop_devices (void) {
449 if (looplist_open(&ll, LLFLG_USEDONLY) == -1) {
450 error(_("%s: /dev directory does not exist."), progname);
454 while((fd = looplist_next(&ll)) != -1) {
455 show_loop_fd(fd, ll.name);
460 if (!ll.ct_succ && ll.ct_perm) {
461 error(_("%s: no permission to look at /dev/loop%s<N>"), progname,
462 (ll.flag & LLFLG_SUBDIR) ? "/" : "");
468 /* list all associated loop devices */
470 show_associated_loop_devices(char *filename, unsigned long long offset, int isoff)
473 struct stat filestat;
476 if (stat(filename, &filestat) == -1) {
481 if (looplist_open(&ll, LLFLG_USEDONLY) == -1) {
482 error(_("%s: /dev directory does not exist."), progname);
486 while((fd = looplist_next(&ll)) != -1) {
487 if (is_associated(fd, &filestat, offset, isoff) == 1)
488 show_loop_fd(fd, ll.name);
498 /* check if the loopfile is already associated with the same given
501 * returns: 0 unused / error
502 * 1 loop device already used
505 is_associated(int dev, struct stat *file, unsigned long long offset, int isoff)
507 struct loop_info64 linfo64;
508 struct loop_info64 linfo;
511 if (ioctl(dev, LOOP_GET_STATUS64, &linfo64) == 0) {
512 if (file->st_dev == linfo64.lo_device &&
513 file->st_ino == linfo64.lo_inode &&
514 (isoff == 0 || offset == linfo64.lo_offset))
517 } else if (ioctl(dev, LOOP_GET_STATUS, &linfo) == 0) {
518 if (file->st_dev == linfo.lo_device &&
519 file->st_ino == linfo.lo_inode &&
520 (isoff == 0 || offset == linfo.lo_offset))
527 /* check if the loop file is already used with the same given
528 * parameters. We check for device no, inode and offset.
529 * returns: associated devname or NULL
532 loopfile_used (const char *filename, unsigned long long offset) {
534 char *devname = NULL;
535 struct stat filestat;
538 if (stat(filename, &filestat) == -1) {
543 if (looplist_open(&ll, LLFLG_USEDONLY) == -1) {
544 error(_("%s: /dev directory does not exist."), progname);
548 while((fd = looplist_next(&ll)) != -1) {
549 int res = is_associated(fd, &filestat, offset, 1);
552 devname = xstrdup(ll.name);
562 loopfile_used_with(char *devname, const char *filename, unsigned long long offset)
567 if (!is_loop_device(devname))
570 if (stat(filename, &statbuf) == -1)
573 fd = open(devname, O_RDONLY);
577 ret = is_associated(fd, &statbuf, offset, 1);
583 find_unused_loop_device (void) {
585 char *devname = NULL;
588 if (looplist_open(&ll, LLFLG_FREEONLY) == -1) {
589 error(_("%s: /dev directory does not exist."), progname);
593 if ((fd = looplist_next(&ll)) != -1) {
595 devname = xstrdup(ll.name);
601 if (!ll.ct_succ && ll.ct_perm)
602 error(_("%s: no permission to look at /dev/loop%s<N>"), progname,
603 (ll.flag & LLFLG_SUBDIR) ? "/" : "");
605 error(_("%s: could not find any free loop device"), progname);
608 "%s: Could not find any loop device. Maybe this kernel "
610 " about the loop device? (If so, recompile or "
611 "`modprobe loop'.)"), progname);
616 * A function to read the passphrase either from the terminal or from
617 * an open file descriptor.
620 xgetpass(int pfd, const char *prompt) {
624 if (pfd < 0) /* terminal */
625 return getpass(prompt);
631 /* we're running out of space in the buffer.
633 char *tmppass = pass;
635 pass = realloc(tmppass, buflen);
637 /* realloc failed. Stop reading. */
638 error(_("Out of memory while reading passphrase"));
639 pass = tmppass; /* the old buffer hasn't changed */
643 if (read(pfd, pass+i, 1) != 1 ||
644 pass[i] == '\n' || pass[i] == 0)
656 digits_only(const char *s) {
670 set_loop(const char *device, const char *file, unsigned long long offset,
671 unsigned long long sizelimit, const char *encryption, int pfd, int *options) {
672 struct loop_info64 loopinfo64;
673 int fd, ffd, mode, i;
678 char *xdev = loopfile_used(file, offset);
681 printf(_("warning: %s is already associated with %s\n"),
687 mode = (*options & SETLOOP_RDONLY) ? O_RDONLY : O_RDWR;
688 if ((ffd = open(file, mode)) < 0) {
689 if (!(*options & SETLOOP_RDONLY) &&
690 (errno == EROFS || errno == EACCES))
691 ffd = open(file, mode = O_RDONLY);
697 printf(_("warning: %s: is write-protected, using read-only.\n"),
699 *options |= SETLOOP_RDONLY;
701 if ((fd = open(device, mode)) < 0) {
706 memset(&loopinfo64, 0, sizeof(loopinfo64));
708 if (!(filename = canonicalize(file)))
709 filename = (char *) file;
710 xstrncpy((char *)loopinfo64.lo_file_name, filename, LO_NAME_SIZE);
712 if (encryption && *encryption) {
713 if (digits_only(encryption)) {
714 loopinfo64.lo_encrypt_type = atoi(encryption);
716 loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
717 snprintf((char *)loopinfo64.lo_crypt_name, LO_NAME_SIZE,
722 loopinfo64.lo_offset = offset;
723 loopinfo64.lo_sizelimit = sizelimit;
727 * Oh-oh, sensitive data coming up. Better lock into memory to prevent
728 * passwd etc being swapped out and left somewhere on disk.
730 if (loopinfo64.lo_encrypt_type != LO_CRYPT_NONE) {
731 if(mlockall(MCL_CURRENT | MCL_FUTURE)) {
733 fprintf(stderr, _("Couldn't lock into memory, exiting.\n"));
739 switch (loopinfo64.lo_encrypt_type) {
741 loopinfo64.lo_encrypt_key_size = 0;
744 pass = getpass(_("Password: "));
747 pass = xgetpass(pfd, _("Password: "));
749 memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE);
750 xstrncpy((char *)loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
751 memset(pass, 0, strlen(pass));
752 loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
755 if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
758 if (errno == EBUSY) {
760 printf(_("ioctl LOOP_SET_FD failed: %s\n"),
764 perror("ioctl: LOOP_SET_FD");
768 if (file != filename)
774 if (*options & SETLOOP_AUTOCLEAR)
775 loopinfo64.lo_flags = LO_FLAGS_AUTOCLEAR;
777 i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);
779 struct loop_info loopinfo;
782 i = loop_info64_to_old(&loopinfo64, &loopinfo);
785 *options &= ~SETLOOP_AUTOCLEAR;
786 perror("ioctl: LOOP_SET_STATUS64");
788 i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);
790 perror("ioctl: LOOP_SET_STATUS");
792 memset(&loopinfo, 0, sizeof(loopinfo));
795 if ((*options & SETLOOP_AUTOCLEAR) && !is_loopfd_autoclear(fd))
796 /* kernel doesn't support loop auto-destruction */
797 *options &= ~SETLOOP_AUTOCLEAR;
799 memset(&loopinfo64, 0, sizeof(loopinfo64));
802 ioctl (fd, LOOP_CLR_FD, 0);
804 if (file != filename)
810 * HACK: here we're leeking a file descriptor,
811 * but mount is a short-lived process anyway.
813 if (!(*options & SETLOOP_AUTOCLEAR))
817 printf(_("set_loop(%s,%s,%llu,%llu): success\n"),
818 device, filename, offset, sizelimit);
819 if (file != filename)
825 del_loop (const char *device) {
828 if ((fd = open (device, O_RDONLY)) < 0) {
832 if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
838 printf(_("del_loop(%s): success\n"), device);
842 fprintf(stderr, _("loop: can't delete device %s: %s\n"),
843 device, strerror(errsv));
849 #else /* no LOOP_SET_FD defined */
853 _("This mount was compiled without loop support. "
854 "Please recompile.\n"));
858 set_loop(const char *device, const char *file, unsigned long long offset,
859 unsigned long long sizelimit, const char *encryption, int pfd, int *loopro,
860 int keysz, int hash_pass) {
866 del_loop (const char *device) {
872 find_unused_loop_device (void) {
877 #endif /* !LOOP_SET_FD */
888 fprintf(stderr, _("\nUsage:\n"
889 " %1$s loop_device give info\n"
890 " %1$s -a | --all list all used\n"
891 " %1$s -d | --detach <loopdev> [<loopdev> ...] delete\n"
892 " %1$s -f | --find find unused\n"
893 " %1$s -c | --set-capacity <loopdev> resize\n"
894 " %1$s -j | --associated <file> [-o <num>] list all associated with <file>\n"
895 " %1$s [ options ] {-f|--find|loopdev} <file> setup\n"),
898 fprintf(stderr, _("\nOptions:\n"
899 " -e | --encryption <type> enable data encryption with specified <name/num>\n"
900 " -h | --help this help\n"
901 " -o | --offset <num> start at offset <num> into file\n"
902 " --sizelimit <num> loop limited to only <num> bytes of the file\n"
903 " -p | --pass-fd <num> read passphrase from file descriptor <num>\n"
904 " -r | --read-only setup read-only loop device\n"
905 " --show print device name (with -f <file>)\n"
906 " -v | --verbose verbose mode\n\n"));
911 main(int argc, char **argv) {
912 char *p, *offset, *sizelimit, *encryption, *passfd, *device, *file, *assoc;
913 int delete, find, c, all, capacity;
918 unsigned long long off, slimit;
919 struct option longopts[] = {
920 { "all", 0, 0, 'a' },
921 { "set-capacity", 0, 0, 'c' },
922 { "detach", 0, 0, 'd' },
923 { "encryption", 1, 0, 'e' },
924 { "find", 0, 0, 'f' },
925 { "help", 0, 0, 'h' },
926 { "associated", 1, 0, 'j' },
927 { "offset", 1, 0, 'o' },
928 { "sizelimit", 1, 0, 128 },
929 { "pass-fd", 1, 0, 'p' },
930 { "read-only", 0, 0, 'r' },
931 { "show", 0, 0, 's' },
932 { "verbose", 0, 0, 'v' },
936 setlocale(LC_ALL, "");
937 bindtextdomain(PACKAGE, LOCALEDIR);
940 capacity = delete = find = all = 0;
943 assoc = offset = sizelimit = encryption = passfd = NULL;
946 if ((p = strrchr(progname, '/')) != NULL)
949 while ((c = getopt_long(argc, argv, "acde:E:fhj:o:p:rsv",
950 longopts, NULL)) != -1) {
987 case 128: /* --sizelimit */
999 if (argc < optind+1 || encryption || offset || sizelimit ||
1000 capacity || find || all || showdev || assoc || ro)
1003 if (capacity || all || assoc || argc < optind || argc > optind+1)
1009 if (capacity || encryption || showdev || passfd || ro)
1011 } else if (capacity) {
1012 if (argc != optind + 1 || encryption || offset || sizelimit ||
1016 if (argc < optind+1 || argc > optind+2)
1020 if (offset && sscanf(offset, "%llu", &off) != 1)
1023 if (sizelimit && sscanf(sizelimit, "%llu", &slimit) != 1)
1027 return show_used_loop_devices();
1029 return show_associated_loop_devices(assoc, off, offset ? 1 : 0);
1031 device = find_unused_loop_device();
1034 if (argc == optind) {
1036 printf(_("Loop device is %s\n"), device);
1037 printf("%s\n", device);
1040 file = argv[optind];
1041 } else if (!delete) {
1042 device = argv[optind];
1043 if (argc == optind+1)
1046 file = argv[optind+1];
1050 while (optind < argc)
1051 res += del_loop(argv[optind++]);
1052 } else if (capacity) {
1053 res = set_capacity(device);
1054 } else if (file == NULL)
1055 res = show_loop(device);
1057 if (passfd && sscanf(passfd, "%d", &pfd) != 1)
1060 res = set_loop(device, file, off, slimit, encryption, pfd, &ro);
1061 if (res == 2 && find) {
1063 printf(_("stolen loop=%s...trying again\n"),
1066 if (!(device = find_unused_loop_device()))
1069 } while (find && res == 2);
1073 error(_("%s: %s: device is busy"), progname, device);
1074 else if (res == 0) {
1076 printf(_("Loop device is %s\n"), device);
1077 if (showdev && find)
1078 printf("%s\n", device);
1085 #else /* LOOP_SET_FD not defined */
1088 main(int argc, char **argv) {
1090 _("No loop support was available at compile time. "
1091 "Please recompile.\n"));
1094 #endif /* !LOOP_SET_FD*/