diff options
author | Erik Andersen <andersen@codepoet.org> | 2000-01-13 06:38:14 +0000 |
---|---|---|
committer | Erik Andersen <andersen@codepoet.org> | 2000-01-13 06:38:14 +0000 |
commit | b7cc49d992ed9a5a59261096012e0b4a811bb7f4 (patch) | |
tree | d151960bd89e78df235150a498cb63f39bfcab2e | |
parent | 05df239ed90584156b820dbf3ede638208eb440f (diff) | |
download | busybox-w32-b7cc49d992ed9a5a59261096012e0b4a811bb7f4.tar.gz busybox-w32-b7cc49d992ed9a5a59261096012e0b4a811bb7f4.tar.bz2 busybox-w32-b7cc49d992ed9a5a59261096012e0b4a811bb7f4.zip |
* Added -o loop option for mount, and support in umount for loop
devices. Support is toggled by MOUNT_LOOP feature -- Ben Collins
<bcollins@debian.org>
-Erik
-rw-r--r-- | Changelog | 3 | ||||
-rw-r--r-- | busybox.def.h | 11 | ||||
-rw-r--r-- | mount.c | 139 | ||||
-rw-r--r-- | umount.c | 72 | ||||
-rw-r--r-- | util-linux/mount.c | 139 | ||||
-rw-r--r-- | util-linux/umount.c | 72 |
6 files changed, 392 insertions, 44 deletions
@@ -10,6 +10,9 @@ | |||
10 | * mkdir -p would print an error when asked to mkdir an existing dir | 10 | * mkdir -p would print an error when asked to mkdir an existing dir |
11 | with no interveining subdirectories. | 11 | with no interveining subdirectories. |
12 | * Fixed "syslogd -O" so that it works. | 12 | * Fixed "syslogd -O" so that it works. |
13 | * Added -o loop option for mount, and support in umount for loop | ||
14 | devices. Support is toggled by MOUNT_LOOP feature -- Ben Collins | ||
15 | <bcollins@debian.org> | ||
13 | 16 | ||
14 | -Erik Andersen | 17 | -Erik Andersen |
15 | 18 | ||
diff --git a/busybox.def.h b/busybox.def.h index 65ed365a5..099eba96c 100644 --- a/busybox.def.h +++ b/busybox.def.h | |||
@@ -103,20 +103,31 @@ | |||
103 | // enable features that use the /proc filesystem (apps that | 103 | // enable features that use the /proc filesystem (apps that |
104 | // break without this will tell you on compile)... | 104 | // break without this will tell you on compile)... |
105 | #define BB_FEATURE_USE_PROCFS | 105 | #define BB_FEATURE_USE_PROCFS |
106 | // | ||
106 | // Use termios to manipulate the screen ('more' is prettier with this on) | 107 | // Use termios to manipulate the screen ('more' is prettier with this on) |
107 | #define BB_FEATURE_USE_TERMIOS | 108 | #define BB_FEATURE_USE_TERMIOS |
109 | // | ||
108 | // calculate terminal & column widths (for more and ls) | 110 | // calculate terminal & column widths (for more and ls) |
109 | #define BB_FEATURE_AUTOWIDTH | 111 | #define BB_FEATURE_AUTOWIDTH |
112 | // | ||
110 | // show username/groupnames (bypasses libc6 NSS) for ls | 113 | // show username/groupnames (bypasses libc6 NSS) for ls |
111 | #define BB_FEATURE_LS_USERNAME | 114 | #define BB_FEATURE_LS_USERNAME |
115 | // | ||
112 | // show file timestamps in ls | 116 | // show file timestamps in ls |
113 | #define BB_FEATURE_LS_TIMESTAMPS | 117 | #define BB_FEATURE_LS_TIMESTAMPS |
118 | // | ||
114 | // enable ls -p and -F | 119 | // enable ls -p and -F |
115 | #define BB_FEATURE_LS_FILETYPES | 120 | #define BB_FEATURE_LS_FILETYPES |
121 | // | ||
116 | // Change ping implementation -- simplified, featureless, but really small. | 122 | // Change ping implementation -- simplified, featureless, but really small. |
117 | //#define BB_SIMPLE_PING | 123 | //#define BB_SIMPLE_PING |
124 | //// | ||
118 | // Make init use a simplified /etc/inittab file (recommended). | 125 | // Make init use a simplified /etc/inittab file (recommended). |
119 | #define BB_FEATURE_USE_INITTAB | 126 | #define BB_FEATURE_USE_INITTAB |
127 | // | ||
120 | //Enable init being called as /linuxrc | 128 | //Enable init being called as /linuxrc |
121 | #define BB_FEATURE_LINUXRC | 129 | #define BB_FEATURE_LINUXRC |
122 | // | 130 | // |
131 | // Enable support for loop devices in mount | ||
132 | #define BB_FEATURE_MOUNT_LOOP | ||
133 | // | ||
@@ -28,7 +28,10 @@ | |||
28 | * putting it back as a compile-time option some time), | 28 | * putting it back as a compile-time option some time), |
29 | * major adjustments to option parsing, and some serious | 29 | * major adjustments to option parsing, and some serious |
30 | * dieting all around. | 30 | * dieting all around. |
31 | */ | 31 | * |
32 | * 2000-01-12 Ben Collins <bcollins@debian.org>, Borrowed utils-linux's | ||
33 | * mount to add loop support. | ||
34 | */ | ||
32 | 35 | ||
33 | #include "internal.h" | 36 | #include "internal.h" |
34 | #include <stdlib.h> | 37 | #include <stdlib.h> |
@@ -41,6 +44,17 @@ | |||
41 | #include <ctype.h> | 44 | #include <ctype.h> |
42 | #include <fstab.h> | 45 | #include <fstab.h> |
43 | 46 | ||
47 | #if defined BB_FEATURE_MOUNT_LOOP | ||
48 | #include <fcntl.h> | ||
49 | #include <sys/ioctl.h> | ||
50 | #include <linux/loop.h> | ||
51 | |||
52 | static int set_loop(const char *device, const char *file, int offset, int *loopro); | ||
53 | static char *find_unused_loop_device (void); | ||
54 | |||
55 | static int use_loop = 0; | ||
56 | #endif | ||
57 | |||
44 | extern const char mtab_file[]; /* Defined in utility.c */ | 58 | extern const char mtab_file[]; /* Defined in utility.c */ |
45 | 59 | ||
46 | static const char mount_usage[] = "\tmount [flags]\n" | 60 | static const char mount_usage[] = "\tmount [flags]\n" |
@@ -61,6 +75,9 @@ static const char mount_usage[] = "\tmount [flags]\n" | |||
61 | "\tasync / sync:\tWrites are asynchronous / synchronous.\n" | 75 | "\tasync / sync:\tWrites are asynchronous / synchronous.\n" |
62 | "\tdev / nodev:\tAllow use of special device files / disallow them.\n" | 76 | "\tdev / nodev:\tAllow use of special device files / disallow them.\n" |
63 | "\texec / noexec:\tAllow use of executable files / disallow them.\n" | 77 | "\texec / noexec:\tAllow use of executable files / disallow them.\n" |
78 | #if defined BB_FEATURE_MOUNT_LOOP | ||
79 | "\tloop: Mounts a file via loop device.\n" | ||
80 | #endif | ||
64 | "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" | 81 | "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" |
65 | "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" | 82 | "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" |
66 | "\tro / rw: Mount for read-only / read-write.\n" | 83 | "\tro / rw: Mount for read-only / read-write.\n" |
@@ -91,28 +108,48 @@ static const struct mount_options mount_options[] = { | |||
91 | {0, 0, 0} | 108 | {0, 0, 0} |
92 | }; | 109 | }; |
93 | 110 | ||
94 | #if ! defined BB_MTAB | ||
95 | #define do_mount(specialfile, dir, filesystemtype, flags, string_flags, useMtab, fakeIt, mtab_opts) \ | ||
96 | mount(specialfile, dir, filesystemtype, flags, string_flags) | ||
97 | #else | ||
98 | static int | 111 | static int |
99 | do_mount(char* specialfile, char* dir, char* filesystemtype, | 112 | do_mount(char* specialfile, char* dir, char* filesystemtype, |
100 | long flags, void* string_flags, int useMtab, int fakeIt, char* mtab_opts) | 113 | long flags, void* string_flags, int useMtab, int fakeIt, char* mtab_opts) |
101 | { | 114 | { |
102 | int status=0; | 115 | int status=0; |
103 | 116 | ||
117 | #if defined BB_MTAB | ||
104 | if (fakeIt==FALSE) | 118 | if (fakeIt==FALSE) |
119 | #endif | ||
120 | { | ||
121 | #if defined BB_FEATURE_MOUNT_LOOP | ||
122 | if (use_loop) { | ||
123 | int loro = flags & MS_RDONLY; | ||
124 | char *lofile = specialfile; | ||
125 | specialfile = find_unused_loop_device(); | ||
126 | if (specialfile == NULL) { | ||
127 | fprintf(stderr, "Could not find a spare loop device\n"); | ||
128 | exit(1); | ||
129 | } | ||
130 | if (set_loop (specialfile, lofile, 0, &loro)) { | ||
131 | fprintf(stderr, "Could not setup loop device\n"); | ||
132 | exit(1); | ||
133 | } | ||
134 | if (!(flags & MS_RDONLY) && loro) { /* loop is ro, but wanted rw */ | ||
135 | fprintf(stderr, "WARNING: loop device is read-only\n"); | ||
136 | flags &= ~MS_RDONLY; | ||
137 | } | ||
138 | } | ||
139 | #endif | ||
105 | status=mount(specialfile, dir, filesystemtype, flags, string_flags); | 140 | status=mount(specialfile, dir, filesystemtype, flags, string_flags); |
106 | 141 | } | |
107 | if ( status == 0 ) { | 142 | #if defined BB_MTAB |
108 | if ( useMtab==TRUE ) | 143 | if (status == 0) { |
144 | if (useMtab==TRUE) | ||
109 | write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts); | 145 | write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts); |
110 | return 0; | 146 | return 0; |
111 | } | 147 | } |
112 | else | 148 | else |
113 | return( status); | ||
114 | } | ||
115 | #endif | 149 | #endif |
150 | return(status); | ||
151 | } | ||
152 | |||
116 | 153 | ||
117 | 154 | ||
118 | #if defined BB_MTAB | 155 | #if defined BB_MTAB |
@@ -148,16 +185,20 @@ parse_mount_options ( char *options, unsigned long *flags, char *strflags) | |||
148 | } | 185 | } |
149 | f++; | 186 | f++; |
150 | } | 187 | } |
188 | #if defined BB_FEATURE_MOUNT_LOOP | ||
189 | if (gotone==FALSE && !strcasecmp ("loop", options)) { /* loop device support */ | ||
190 | use_loop = 1; | ||
191 | gotone=TRUE; | ||
192 | } | ||
193 | #endif | ||
151 | if (*strflags && strflags!= '\0' && gotone==FALSE) { | 194 | if (*strflags && strflags!= '\0' && gotone==FALSE) { |
152 | char *temp=strflags; | 195 | char *temp=strflags; |
153 | temp += strlen (strflags); | 196 | temp += strlen (strflags); |
154 | *temp++ = ','; | 197 | *temp++ = ','; |
155 | *temp++ = '\0'; | 198 | *temp++ = '\0'; |
156 | } | 199 | } |
157 | if (gotone==FALSE) { | 200 | if (gotone==FALSE) |
158 | strcat (strflags, options); | 201 | strcat (strflags, options); |
159 | gotone=FALSE; | ||
160 | } | ||
161 | if (comma) { | 202 | if (comma) { |
162 | *comma = ','; | 203 | *comma = ','; |
163 | options = ++comma; | 204 | options = ++comma; |
@@ -356,3 +397,73 @@ extern int mount_main (int argc, char **argv) | |||
356 | goodbye: | 397 | goodbye: |
357 | usage( mount_usage); | 398 | usage( mount_usage); |
358 | } | 399 | } |
400 | |||
401 | #if defined BB_FEATURE_MOUNT_LOOP | ||
402 | static int set_loop(const char *device, const char *file, int offset, int *loopro) | ||
403 | { | ||
404 | struct loop_info loopinfo; | ||
405 | int fd, ffd, mode; | ||
406 | |||
407 | mode = *loopro ? O_RDONLY : O_RDWR; | ||
408 | if ((ffd = open (file, mode)) < 0 && !*loopro | ||
409 | && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) { | ||
410 | perror (file); | ||
411 | return 1; | ||
412 | } | ||
413 | if ((fd = open (device, mode)) < 0) { | ||
414 | close(ffd); | ||
415 | perror (device); | ||
416 | return 1; | ||
417 | } | ||
418 | *loopro = (mode == O_RDONLY); | ||
419 | |||
420 | memset(&loopinfo, 0, sizeof(loopinfo)); | ||
421 | strncpy(loopinfo.lo_name, file, LO_NAME_SIZE); | ||
422 | loopinfo.lo_name[LO_NAME_SIZE-1] = 0; | ||
423 | |||
424 | loopinfo.lo_offset = offset; | ||
425 | |||
426 | loopinfo.lo_encrypt_key_size = 0; | ||
427 | if (ioctl(fd, LOOP_SET_FD, ffd) < 0) { | ||
428 | perror("ioctl: LOOP_SET_FD"); | ||
429 | exit(1); | ||
430 | } | ||
431 | if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) { | ||
432 | (void) ioctl(fd, LOOP_CLR_FD, 0); | ||
433 | perror("ioctl: LOOP_SET_STATUS"); | ||
434 | exit(1); | ||
435 | } | ||
436 | close(fd); | ||
437 | close(ffd); | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static char *find_unused_loop_device (void) | ||
442 | { | ||
443 | char dev[20]; | ||
444 | int i, fd, somedev = 0, someloop = 0; | ||
445 | struct stat statbuf; | ||
446 | struct loop_info loopinfo; | ||
447 | |||
448 | for(i = 0; i < 256; i++) { | ||
449 | sprintf(dev, "/dev/loop%d", i); | ||
450 | if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { | ||
451 | somedev++; | ||
452 | fd = open (dev, O_RDONLY); | ||
453 | if (fd >= 0) { | ||
454 | if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0) | ||
455 | someloop++; /* in use */ | ||
456 | else if (errno == ENXIO) { | ||
457 | close (fd); | ||
458 | return strdup(dev); /* probably free */ | ||
459 | } | ||
460 | close (fd); | ||
461 | } | ||
462 | continue; | ||
463 | } | ||
464 | if (i >= 7) | ||
465 | break; | ||
466 | } | ||
467 | return NULL; | ||
468 | } | ||
469 | #endif /* BB_FEATURE_MOUNT_LOOP */ | ||
@@ -28,6 +28,14 @@ | |||
28 | #include <fstab.h> | 28 | #include <fstab.h> |
29 | #include <errno.h> | 29 | #include <errno.h> |
30 | 30 | ||
31 | #if defined BB_FEATURE_MOUNT_LOOP | ||
32 | #include <fcntl.h> | ||
33 | #include <sys/ioctl.h> | ||
34 | #include <linux/loop.h> | ||
35 | |||
36 | static int del_loop(const char *device); | ||
37 | #endif | ||
38 | |||
31 | static const char umount_usage[] = | 39 | static const char umount_usage[] = |
32 | "Usage: umount [flags] filesystem|directory\n\n" | 40 | "Usage: umount [flags] filesystem|directory\n\n" |
33 | "Flags:\n" | 41 | "Flags:\n" |
@@ -44,23 +52,54 @@ static int useMtab = TRUE; | |||
44 | static int umountAll = FALSE; | 52 | static int umountAll = FALSE; |
45 | extern const char mtab_file[]; /* Defined in utility.c */ | 53 | extern const char mtab_file[]; /* Defined in utility.c */ |
46 | 54 | ||
47 | #if ! defined BB_MTAB | ||
48 | #define do_umount( blockDevice, useMtab) umount( blockDevice) | ||
49 | #else | ||
50 | static int | 55 | static int |
51 | do_umount(const char* name, int useMtab) | 56 | do_umount(const char* name, int useMtab) |
52 | { | 57 | { |
53 | int status = umount(name); | 58 | int status; |
59 | |||
60 | #if defined BB_FEATURE_MOUNT_LOOP | ||
61 | /* check to see if this is a loop device */ | ||
62 | struct stat fst; | ||
63 | char dev[20]; | ||
64 | const char *oldname = NULL; | ||
65 | int i; | ||
66 | |||
67 | if (stat(name, &fst)) { | ||
68 | fprintf(stderr, "umount: %s: %s\n", name, strerror(errno)); | ||
69 | exit(1); | ||
70 | } | ||
71 | for (i = 0 ; i <= 7 ; i++) { | ||
72 | struct stat lst; | ||
73 | sprintf(dev, "/dev/loop%d", i); | ||
74 | if (stat(dev, &lst)) | ||
75 | continue; | ||
76 | if (lst.st_dev == fst.st_dev) { | ||
77 | oldname = name; | ||
78 | name = dev; | ||
79 | break; | ||
80 | } | ||
81 | } | ||
82 | #endif | ||
83 | |||
84 | status = umount(name); | ||
54 | 85 | ||
86 | #if defined BB_FEATURE_MOUNT_LOOP | ||
87 | if (!strncmp("/dev/loop", name, 9)) { /* this was a loop device, delete it */ | ||
88 | del_loop(name); | ||
89 | if (oldname != NULL) | ||
90 | name = oldname; | ||
91 | } | ||
92 | #endif | ||
93 | #if defined BB_MTAB | ||
55 | if ( status == 0 ) { | 94 | if ( status == 0 ) { |
56 | if ( useMtab==TRUE ) | 95 | if ( useMtab==TRUE ) |
57 | erase_mtab(name); | 96 | erase_mtab(name); |
58 | return 0; | 97 | return 0; |
59 | } | 98 | } |
60 | else | 99 | else |
61 | return( status); | ||
62 | } | ||
63 | #endif | 100 | #endif |
101 | return(status); | ||
102 | } | ||
64 | 103 | ||
65 | static int | 104 | static int |
66 | umount_all(int useMtab) | 105 | umount_all(int useMtab) |
@@ -135,7 +174,24 @@ umount_main(int argc, char** argv) | |||
135 | exit (TRUE); | 174 | exit (TRUE); |
136 | else { | 175 | else { |
137 | perror("umount"); | 176 | perror("umount"); |
138 | exit( FALSE); | 177 | exit(FALSE); |
139 | } | 178 | } |
140 | } | 179 | } |
141 | 180 | ||
181 | #if defined BB_FEATURE_MOUNT_LOOP | ||
182 | static int del_loop(const char *device) | ||
183 | { | ||
184 | int fd; | ||
185 | |||
186 | if ((fd = open(device, O_RDONLY)) < 0) { | ||
187 | perror(device); | ||
188 | exit(1); | ||
189 | } | ||
190 | if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { | ||
191 | perror("ioctl: LOOP_CLR_FD"); | ||
192 | exit(1); | ||
193 | } | ||
194 | close(fd); | ||
195 | return(0); | ||
196 | } | ||
197 | #endif | ||
diff --git a/util-linux/mount.c b/util-linux/mount.c index ee6fe15e6..8777a3be4 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -28,7 +28,10 @@ | |||
28 | * putting it back as a compile-time option some time), | 28 | * putting it back as a compile-time option some time), |
29 | * major adjustments to option parsing, and some serious | 29 | * major adjustments to option parsing, and some serious |
30 | * dieting all around. | 30 | * dieting all around. |
31 | */ | 31 | * |
32 | * 2000-01-12 Ben Collins <bcollins@debian.org>, Borrowed utils-linux's | ||
33 | * mount to add loop support. | ||
34 | */ | ||
32 | 35 | ||
33 | #include "internal.h" | 36 | #include "internal.h" |
34 | #include <stdlib.h> | 37 | #include <stdlib.h> |
@@ -41,6 +44,17 @@ | |||
41 | #include <ctype.h> | 44 | #include <ctype.h> |
42 | #include <fstab.h> | 45 | #include <fstab.h> |
43 | 46 | ||
47 | #if defined BB_FEATURE_MOUNT_LOOP | ||
48 | #include <fcntl.h> | ||
49 | #include <sys/ioctl.h> | ||
50 | #include <linux/loop.h> | ||
51 | |||
52 | static int set_loop(const char *device, const char *file, int offset, int *loopro); | ||
53 | static char *find_unused_loop_device (void); | ||
54 | |||
55 | static int use_loop = 0; | ||
56 | #endif | ||
57 | |||
44 | extern const char mtab_file[]; /* Defined in utility.c */ | 58 | extern const char mtab_file[]; /* Defined in utility.c */ |
45 | 59 | ||
46 | static const char mount_usage[] = "\tmount [flags]\n" | 60 | static const char mount_usage[] = "\tmount [flags]\n" |
@@ -61,6 +75,9 @@ static const char mount_usage[] = "\tmount [flags]\n" | |||
61 | "\tasync / sync:\tWrites are asynchronous / synchronous.\n" | 75 | "\tasync / sync:\tWrites are asynchronous / synchronous.\n" |
62 | "\tdev / nodev:\tAllow use of special device files / disallow them.\n" | 76 | "\tdev / nodev:\tAllow use of special device files / disallow them.\n" |
63 | "\texec / noexec:\tAllow use of executable files / disallow them.\n" | 77 | "\texec / noexec:\tAllow use of executable files / disallow them.\n" |
78 | #if defined BB_FEATURE_MOUNT_LOOP | ||
79 | "\tloop: Mounts a file via loop device.\n" | ||
80 | #endif | ||
64 | "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" | 81 | "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" |
65 | "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" | 82 | "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" |
66 | "\tro / rw: Mount for read-only / read-write.\n" | 83 | "\tro / rw: Mount for read-only / read-write.\n" |
@@ -91,28 +108,48 @@ static const struct mount_options mount_options[] = { | |||
91 | {0, 0, 0} | 108 | {0, 0, 0} |
92 | }; | 109 | }; |
93 | 110 | ||
94 | #if ! defined BB_MTAB | ||
95 | #define do_mount(specialfile, dir, filesystemtype, flags, string_flags, useMtab, fakeIt, mtab_opts) \ | ||
96 | mount(specialfile, dir, filesystemtype, flags, string_flags) | ||
97 | #else | ||
98 | static int | 111 | static int |
99 | do_mount(char* specialfile, char* dir, char* filesystemtype, | 112 | do_mount(char* specialfile, char* dir, char* filesystemtype, |
100 | long flags, void* string_flags, int useMtab, int fakeIt, char* mtab_opts) | 113 | long flags, void* string_flags, int useMtab, int fakeIt, char* mtab_opts) |
101 | { | 114 | { |
102 | int status=0; | 115 | int status=0; |
103 | 116 | ||
117 | #if defined BB_MTAB | ||
104 | if (fakeIt==FALSE) | 118 | if (fakeIt==FALSE) |
119 | #endif | ||
120 | { | ||
121 | #if defined BB_FEATURE_MOUNT_LOOP | ||
122 | if (use_loop) { | ||
123 | int loro = flags & MS_RDONLY; | ||
124 | char *lofile = specialfile; | ||
125 | specialfile = find_unused_loop_device(); | ||
126 | if (specialfile == NULL) { | ||
127 | fprintf(stderr, "Could not find a spare loop device\n"); | ||
128 | exit(1); | ||
129 | } | ||
130 | if (set_loop (specialfile, lofile, 0, &loro)) { | ||
131 | fprintf(stderr, "Could not setup loop device\n"); | ||
132 | exit(1); | ||
133 | } | ||
134 | if (!(flags & MS_RDONLY) && loro) { /* loop is ro, but wanted rw */ | ||
135 | fprintf(stderr, "WARNING: loop device is read-only\n"); | ||
136 | flags &= ~MS_RDONLY; | ||
137 | } | ||
138 | } | ||
139 | #endif | ||
105 | status=mount(specialfile, dir, filesystemtype, flags, string_flags); | 140 | status=mount(specialfile, dir, filesystemtype, flags, string_flags); |
106 | 141 | } | |
107 | if ( status == 0 ) { | 142 | #if defined BB_MTAB |
108 | if ( useMtab==TRUE ) | 143 | if (status == 0) { |
144 | if (useMtab==TRUE) | ||
109 | write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts); | 145 | write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts); |
110 | return 0; | 146 | return 0; |
111 | } | 147 | } |
112 | else | 148 | else |
113 | return( status); | ||
114 | } | ||
115 | #endif | 149 | #endif |
150 | return(status); | ||
151 | } | ||
152 | |||
116 | 153 | ||
117 | 154 | ||
118 | #if defined BB_MTAB | 155 | #if defined BB_MTAB |
@@ -148,16 +185,20 @@ parse_mount_options ( char *options, unsigned long *flags, char *strflags) | |||
148 | } | 185 | } |
149 | f++; | 186 | f++; |
150 | } | 187 | } |
188 | #if defined BB_FEATURE_MOUNT_LOOP | ||
189 | if (gotone==FALSE && !strcasecmp ("loop", options)) { /* loop device support */ | ||
190 | use_loop = 1; | ||
191 | gotone=TRUE; | ||
192 | } | ||
193 | #endif | ||
151 | if (*strflags && strflags!= '\0' && gotone==FALSE) { | 194 | if (*strflags && strflags!= '\0' && gotone==FALSE) { |
152 | char *temp=strflags; | 195 | char *temp=strflags; |
153 | temp += strlen (strflags); | 196 | temp += strlen (strflags); |
154 | *temp++ = ','; | 197 | *temp++ = ','; |
155 | *temp++ = '\0'; | 198 | *temp++ = '\0'; |
156 | } | 199 | } |
157 | if (gotone==FALSE) { | 200 | if (gotone==FALSE) |
158 | strcat (strflags, options); | 201 | strcat (strflags, options); |
159 | gotone=FALSE; | ||
160 | } | ||
161 | if (comma) { | 202 | if (comma) { |
162 | *comma = ','; | 203 | *comma = ','; |
163 | options = ++comma; | 204 | options = ++comma; |
@@ -356,3 +397,73 @@ extern int mount_main (int argc, char **argv) | |||
356 | goodbye: | 397 | goodbye: |
357 | usage( mount_usage); | 398 | usage( mount_usage); |
358 | } | 399 | } |
400 | |||
401 | #if defined BB_FEATURE_MOUNT_LOOP | ||
402 | static int set_loop(const char *device, const char *file, int offset, int *loopro) | ||
403 | { | ||
404 | struct loop_info loopinfo; | ||
405 | int fd, ffd, mode; | ||
406 | |||
407 | mode = *loopro ? O_RDONLY : O_RDWR; | ||
408 | if ((ffd = open (file, mode)) < 0 && !*loopro | ||
409 | && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) { | ||
410 | perror (file); | ||
411 | return 1; | ||
412 | } | ||
413 | if ((fd = open (device, mode)) < 0) { | ||
414 | close(ffd); | ||
415 | perror (device); | ||
416 | return 1; | ||
417 | } | ||
418 | *loopro = (mode == O_RDONLY); | ||
419 | |||
420 | memset(&loopinfo, 0, sizeof(loopinfo)); | ||
421 | strncpy(loopinfo.lo_name, file, LO_NAME_SIZE); | ||
422 | loopinfo.lo_name[LO_NAME_SIZE-1] = 0; | ||
423 | |||
424 | loopinfo.lo_offset = offset; | ||
425 | |||
426 | loopinfo.lo_encrypt_key_size = 0; | ||
427 | if (ioctl(fd, LOOP_SET_FD, ffd) < 0) { | ||
428 | perror("ioctl: LOOP_SET_FD"); | ||
429 | exit(1); | ||
430 | } | ||
431 | if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) { | ||
432 | (void) ioctl(fd, LOOP_CLR_FD, 0); | ||
433 | perror("ioctl: LOOP_SET_STATUS"); | ||
434 | exit(1); | ||
435 | } | ||
436 | close(fd); | ||
437 | close(ffd); | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static char *find_unused_loop_device (void) | ||
442 | { | ||
443 | char dev[20]; | ||
444 | int i, fd, somedev = 0, someloop = 0; | ||
445 | struct stat statbuf; | ||
446 | struct loop_info loopinfo; | ||
447 | |||
448 | for(i = 0; i < 256; i++) { | ||
449 | sprintf(dev, "/dev/loop%d", i); | ||
450 | if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { | ||
451 | somedev++; | ||
452 | fd = open (dev, O_RDONLY); | ||
453 | if (fd >= 0) { | ||
454 | if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0) | ||
455 | someloop++; /* in use */ | ||
456 | else if (errno == ENXIO) { | ||
457 | close (fd); | ||
458 | return strdup(dev); /* probably free */ | ||
459 | } | ||
460 | close (fd); | ||
461 | } | ||
462 | continue; | ||
463 | } | ||
464 | if (i >= 7) | ||
465 | break; | ||
466 | } | ||
467 | return NULL; | ||
468 | } | ||
469 | #endif /* BB_FEATURE_MOUNT_LOOP */ | ||
diff --git a/util-linux/umount.c b/util-linux/umount.c index ab76be4da..af1b3a43e 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
@@ -28,6 +28,14 @@ | |||
28 | #include <fstab.h> | 28 | #include <fstab.h> |
29 | #include <errno.h> | 29 | #include <errno.h> |
30 | 30 | ||
31 | #if defined BB_FEATURE_MOUNT_LOOP | ||
32 | #include <fcntl.h> | ||
33 | #include <sys/ioctl.h> | ||
34 | #include <linux/loop.h> | ||
35 | |||
36 | static int del_loop(const char *device); | ||
37 | #endif | ||
38 | |||
31 | static const char umount_usage[] = | 39 | static const char umount_usage[] = |
32 | "Usage: umount [flags] filesystem|directory\n\n" | 40 | "Usage: umount [flags] filesystem|directory\n\n" |
33 | "Flags:\n" | 41 | "Flags:\n" |
@@ -44,23 +52,54 @@ static int useMtab = TRUE; | |||
44 | static int umountAll = FALSE; | 52 | static int umountAll = FALSE; |
45 | extern const char mtab_file[]; /* Defined in utility.c */ | 53 | extern const char mtab_file[]; /* Defined in utility.c */ |
46 | 54 | ||
47 | #if ! defined BB_MTAB | ||
48 | #define do_umount( blockDevice, useMtab) umount( blockDevice) | ||
49 | #else | ||
50 | static int | 55 | static int |
51 | do_umount(const char* name, int useMtab) | 56 | do_umount(const char* name, int useMtab) |
52 | { | 57 | { |
53 | int status = umount(name); | 58 | int status; |
59 | |||
60 | #if defined BB_FEATURE_MOUNT_LOOP | ||
61 | /* check to see if this is a loop device */ | ||
62 | struct stat fst; | ||
63 | char dev[20]; | ||
64 | const char *oldname = NULL; | ||
65 | int i; | ||
66 | |||
67 | if (stat(name, &fst)) { | ||
68 | fprintf(stderr, "umount: %s: %s\n", name, strerror(errno)); | ||
69 | exit(1); | ||
70 | } | ||
71 | for (i = 0 ; i <= 7 ; i++) { | ||
72 | struct stat lst; | ||
73 | sprintf(dev, "/dev/loop%d", i); | ||
74 | if (stat(dev, &lst)) | ||
75 | continue; | ||
76 | if (lst.st_dev == fst.st_dev) { | ||
77 | oldname = name; | ||
78 | name = dev; | ||
79 | break; | ||
80 | } | ||
81 | } | ||
82 | #endif | ||
83 | |||
84 | status = umount(name); | ||
54 | 85 | ||
86 | #if defined BB_FEATURE_MOUNT_LOOP | ||
87 | if (!strncmp("/dev/loop", name, 9)) { /* this was a loop device, delete it */ | ||
88 | del_loop(name); | ||
89 | if (oldname != NULL) | ||
90 | name = oldname; | ||
91 | } | ||
92 | #endif | ||
93 | #if defined BB_MTAB | ||
55 | if ( status == 0 ) { | 94 | if ( status == 0 ) { |
56 | if ( useMtab==TRUE ) | 95 | if ( useMtab==TRUE ) |
57 | erase_mtab(name); | 96 | erase_mtab(name); |
58 | return 0; | 97 | return 0; |
59 | } | 98 | } |
60 | else | 99 | else |
61 | return( status); | ||
62 | } | ||
63 | #endif | 100 | #endif |
101 | return(status); | ||
102 | } | ||
64 | 103 | ||
65 | static int | 104 | static int |
66 | umount_all(int useMtab) | 105 | umount_all(int useMtab) |
@@ -135,7 +174,24 @@ umount_main(int argc, char** argv) | |||
135 | exit (TRUE); | 174 | exit (TRUE); |
136 | else { | 175 | else { |
137 | perror("umount"); | 176 | perror("umount"); |
138 | exit( FALSE); | 177 | exit(FALSE); |
139 | } | 178 | } |
140 | } | 179 | } |
141 | 180 | ||
181 | #if defined BB_FEATURE_MOUNT_LOOP | ||
182 | static int del_loop(const char *device) | ||
183 | { | ||
184 | int fd; | ||
185 | |||
186 | if ((fd = open(device, O_RDONLY)) < 0) { | ||
187 | perror(device); | ||
188 | exit(1); | ||
189 | } | ||
190 | if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { | ||
191 | perror("ioctl: LOOP_CLR_FD"); | ||
192 | exit(1); | ||
193 | } | ||
194 | close(fd); | ||
195 | return(0); | ||
196 | } | ||
197 | #endif | ||