diff options
author | Karel Zak | 2006-12-07 00:25:34 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:25:34 +0100 |
commit | fd6b7a7ffc50400704beb41d5a23af5f9edb1eed (patch) | |
tree | 997c0ca2abc018369babd7da59bcd0afe492068e /mount/lomount.c | |
parent | Imported from util-linux-2.5 tarball. (diff) | |
download | kernel-qcow2-util-linux-fd6b7a7ffc50400704beb41d5a23af5f9edb1eed.tar.gz kernel-qcow2-util-linux-fd6b7a7ffc50400704beb41d5a23af5f9edb1eed.tar.xz kernel-qcow2-util-linux-fd6b7a7ffc50400704beb41d5a23af5f9edb1eed.zip |
Imported from util-linux-2.7.1 tarball.
Diffstat (limited to 'mount/lomount.c')
-rw-r--r-- | mount/lomount.c | 232 |
1 files changed, 145 insertions, 87 deletions
diff --git a/mount/lomount.c b/mount/lomount.c index 5dd02d8bb..a6ad187ae 100644 --- a/mount/lomount.c +++ b/mount/lomount.c @@ -1,4 +1,8 @@ /* Taken from Ted's losetup.c - Mitch <m.dsouza@mrc-apu.cam.ac.uk> */ +/* Added vfs mount options - aeb - 960223 */ +/* Removed lomount - aeb - 960224 */ + +#define PROC_DEVICES "/proc/devices" /* * losetup.c - setup and control loop devices @@ -8,71 +12,62 @@ #include <string.h> #include <ctype.h> #include <fcntl.h> +#include <errno.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> -#include <linux/fs.h> -#include "loop.h" +#include <sys/stat.h> -char *crypt_name (int); -int crypt_type (char *); -void show_loop (char *); -int del_loop (const char *); -int set_loop (const char *, const char *, int offset, char *); -int lomount (const char *, const char *, const char *, char **, - int *, char **, char **); +#if defined(__GLIBC__) +#define _SOCKETBITS_H +#endif /* __GLIBC */ +#include "sundries.h" /* for xstrdup */ +#include "loop.h" +#include "lomount.h" +#ifdef LOOP_SET_FD struct crypt_type_struct { int id; char *name; } crypt_type_tbl[] = { - - { - LO_CRYPT_NONE, "no" - }, - { - LO_CRYPT_NONE, "none" - }, - { - LO_CRYPT_XOR, "xor" - }, - { - LO_CRYPT_DES, "DES" - }, - { - -1, NULL - } + { LO_CRYPT_NONE, "no" }, + { LO_CRYPT_NONE, "none" }, + { LO_CRYPT_XOR, "xor" }, + { LO_CRYPT_DES, "DES" }, + { -1, NULL } }; -char * -crypt_name (int id) +static int +crypt_type (const char *name) { int i; - for (i = 0; crypt_type_tbl[i].id != -1; i++) - if (id == crypt_type_tbl[i].id) - return crypt_type_tbl[i].name; - return "undefined"; + if (name) + for (i = 0; crypt_type_tbl[i].id != -1; i++) + if (!strcasecmp (name, crypt_type_tbl[i].name)) + return crypt_type_tbl[i].id; + return -1; } -int -crypt_type (char *name) +#if 0 +static char * +crypt_name (int id) { int i; for (i = 0; crypt_type_tbl[i].id != -1; i++) - if (!strcasecmp (name, crypt_type_tbl[i].name)) - return crypt_type_tbl[i].id; - return -1; + if (id == crypt_type_tbl[i].id) + return crypt_type_tbl[i].name; + return "undefined"; } -void +static void show_loop (char *device) { struct loop_info loopinfo; int fd; - if ((fd = open (device, O_RDWR)) < 0) { + if ((fd = open (device, O_RDONLY)) < 0) { fprintf(stderr, "loop: can't open device %s: %s\n", device, strerror (errno)); return; @@ -89,24 +84,97 @@ show_loop (char *device) crypt_name (loopinfo.lo_encrypt_type)); close (fd); } +#endif + +char * +find_unused_loop_device (void) +{ + /* Just creating a device, say in /tmp, is probably a bad idea - + people might have problems with backup or so. + So, we just try /dev/loop[0-7]. */ + char dev[20]; + int i, fd, somedev = 0, someloop = 0, loop_known = 0; + struct stat statbuf; + struct loop_info loopinfo; + FILE *procdev; + + for(i = 0; i < 256; i++) { + sprintf(dev, "/dev/loop%d", i); + if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { + somedev++; + fd = open (dev, O_RDONLY); + if (fd >= 0) { + if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0) + someloop++; /* in use */ + else if (errno == ENXIO) { + close (fd); + return xstrdup(dev); /* probably free */ + } + close (fd); + } + continue; /* continue trying as long as devices exist */ + } + if (i >= 7) + break; + } + + /* Nothing found. Why not? */ + if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) { + char line[100]; + while (fgets (line, sizeof(line), procdev)) + if (strstr (line, " loop\n")) { + loop_known = 1; + break; + } + fclose(procdev); + if (!loop_known) + loop_known = -1; + } + + if (!somedev) + error("mount: could not find any device /dev/loop#"); + else if(!someloop) { + if (loop_known == 1) + error( +"mount: Could not find any loop device.\n" +" Maybe /dev/loop# has a wrong major number?\n"); + else if (loop_known == -1) + error( +"mount: Could not find any loop device, and, according to %s,\n" +" this kernel does not know about the loop device.\n" +" (If so, then recompile or `insmod loop.o'.)\n", PROC_DEVICES); + else + error( +"mount: Could not find any loop device. Maybe this kernel does not know\n" +" about the loop device (then recompile or `insmod loop.o'), or\n" +" maybe /dev/loop# has the wrong major number?\n"); + } else + error("mount: could not find any free loop device"); + return 0; +} int -set_loop (const char *device, const char *file, int offset, char *encryption) +set_loop (const char *device, const char *file, int offset, + const char *encryption, int *loopro) { struct loop_info loopinfo; - int fd, - ffd, - i; + int fd, ffd, mode, i; char *pass; - if ((fd = open (device, O_RDWR)) < 0) { - perror (device); - return 1; + mode = (*loopro ? O_RDONLY : O_RDWR); + if ((ffd = open (file, mode)) < 0) { + if (!*loopro && errno == EROFS) + ffd = open (file, mode = O_RDONLY); + if (ffd < 0) { + perror (file); + return 1; + } } - if ((ffd = open (file, O_RDWR)) < 0) { - perror (file); + if ((fd = open (device, mode)) < 0) { + perror (device); return 1; } + *loopro = (mode == O_RDONLY); memset (&loopinfo, 0, sizeof (loopinfo)); strncpy (loopinfo.lo_name, file, LO_NAME_SIZE); loopinfo.lo_name[LO_NAME_SIZE - 1] = 0; @@ -159,6 +227,8 @@ set_loop (const char *device, const char *file, int offset, char *encryption) } close (fd); close (ffd); + if (verbose > 1) + printf("set_loop(%s,%s,%d): success\n", device, file, offset); return 0; } @@ -173,51 +243,39 @@ del_loop (const char *device) return 1; } if (ioctl (fd, LOOP_CLR_FD, 0) < 0) { -#if 0 perror ("ioctl: LOOP_CLR_FD"); -#endif return 1; } + close (fd); + if (verbose > 1) + printf("del_loop(%s): success\n", device); return 0; } +#else /* no LOOP_SET_FD defined */ +static void +mutter(void) { + fprintf(stderr, + "This mount was compiled without loop support. Please recompile.\n"); +} -int -lomount (const char *spec, const char *node, const char *device, char **type, - int *flags, char **extra_opts, char **mount_opts) -{ - char *opt, - *opteq; - int val; - char *encryption = NULL, *vfs = NULL; - int offset = 0, err; - char new_opts[1024]; - - for (opt = strtok (*extra_opts, ","); opt; opt = strtok (NULL, ",")) { - if ((opteq = strchr (opt, '='))) { - val = atoi (opteq + 1); - *opteq = '\0'; - if (!strcmp (opt, "encryption")) - encryption = strdup(opteq + 1); - else if (!strcmp (opt, "vfs")) - vfs = strdup(opteq + 1); - else if (!strcmp (opt, "offset")) - offset = val; - else { - printf ("unknown loop mount parameter: " - "%s=%d (%s)\n", opt, val, opteq+1); - return 1; - } - } else { - printf ("unknown loop mount parameter: " - "%s\n", opt); - return 1; - } - } - err = set_loop (device, spec, offset, encryption); - sprintf(new_opts, "vfs=%s,offset=%d,encryption=%s", - *type = vfs ? vfs : FSTYPE_DEFAULT, offset, - encryption=crypt_type(encryption)<0?"none":encryption); - *extra_opts=strdup(new_opts); - return err; +int +set_loop (const char *device, const char *file, int offset, + const char *encryption, int *loopro) { + mutter(); + return 1; +} + +int +del_loop (const char *device) { + mutter(); + return 1; } + +char * +find_unused_loop_device (void) { + mutter(); + return 0; +} + +#endif |