aboutsummaryrefslogtreecommitdiff
path: root/util-linux
diff options
context:
space:
mode:
authorerik <erik@69ca8d6d-28ef-0310-b511-8ec308f3f277>2000-01-26 20:06:48 +0000
committererik <erik@69ca8d6d-28ef-0310-b511-8ec308f3f277>2000-01-26 20:06:48 +0000
commitfa753f920b64a3f2c50295356e577a7c980c8408 (patch)
tree77236e83cc0583411a75b752a6152d445eb680e0 /util-linux
parent67c5194a104e193ec26bad4013c2a9aa9d73312f (diff)
downloadbusybox-w32-fa753f920b64a3f2c50295356e577a7c980c8408.tar.gz
busybox-w32-fa753f920b64a3f2c50295356e577a7c980c8408.tar.bz2
busybox-w32-fa753f920b64a3f2c50295356e577a7c980c8408.zip
mount and umount could leak loop device allocations causing the system to
quickly run out. Also disable init's SIGHUP handler during shutdown. -Erik git-svn-id: svn://busybox.net/trunk/busybox@341 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'util-linux')
-rw-r--r--util-linux/mount.c165
-rw-r--r--util-linux/umount.c70
2 files changed, 107 insertions, 128 deletions
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 709c7fc49..3c1568aad 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -127,11 +127,11 @@ do_mount(char* specialfile, char* dir, char* filesystemtype,
127 specialfile = find_unused_loop_device(); 127 specialfile = find_unused_loop_device();
128 if (specialfile == NULL) { 128 if (specialfile == NULL) {
129 fprintf(stderr, "Could not find a spare loop device\n"); 129 fprintf(stderr, "Could not find a spare loop device\n");
130 exit(1); 130 return( FALSE);
131 } 131 }
132 if (set_loop (specialfile, lofile, 0, &loro)) { 132 if (set_loop (specialfile, lofile, 0, &loro)) {
133 fprintf(stderr, "Could not setup loop device\n"); 133 fprintf(stderr, "Could not setup loop device\n");
134 exit(1); 134 return( FALSE);
135 } 135 }
136 if (!(flags & MS_RDONLY) && loro) { /* loop is ro, but wanted rw */ 136 if (!(flags & MS_RDONLY) && loro) { /* loop is ro, but wanted rw */
137 fprintf(stderr, "WARNING: loop device is read-only\n"); 137 fprintf(stderr, "WARNING: loop device is read-only\n");
@@ -141,15 +141,26 @@ do_mount(char* specialfile, char* dir, char* filesystemtype,
141#endif 141#endif
142 status=mount(specialfile, dir, filesystemtype, flags, string_flags); 142 status=mount(specialfile, dir, filesystemtype, flags, string_flags);
143 } 143 }
144#if defined BB_MTAB 144
145
146 /* If the mount was sucessful, do anything needed, then return TRUE */
145 if (status == 0) { 147 if (status == 0) {
146 if (useMtab==TRUE) 148
149#if defined BB_MTAB
150 if (useMtab==TRUE) {
147 write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts); 151 write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts);
148 return 0; 152 }
153#endif
154 return( TRUE);
155 }
156
157 /* Bummer. mount failed. Clean up */
158#if defined BB_FEATURE_MOUNT_LOOP
159 if (specialfile != NULL) {
160 del_loop(specialfile);
149 } 161 }
150 else
151#endif 162#endif
152 return(status); 163 return( FALSE);
153} 164}
154 165
155 166
@@ -166,6 +177,75 @@ extern void whine_if_fstab_is_missing()
166#endif 177#endif
167 178
168 179
180#if defined BB_FEATURE_MOUNT_LOOP
181static int set_loop(const char *device, const char *file, int offset, int *loopro)
182{
183 struct loop_info loopinfo;
184 int fd, ffd, mode;
185
186 mode = *loopro ? O_RDONLY : O_RDWR;
187 if ((ffd = open (file, mode)) < 0 && !*loopro
188 && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) {
189 perror (file);
190 return 1;
191 }
192 if ((fd = open (device, mode)) < 0) {
193 close(ffd);
194 perror (device);
195 return 1;
196 }
197 *loopro = (mode == O_RDONLY);
198
199 memset(&loopinfo, 0, sizeof(loopinfo));
200 strncpy(loopinfo.lo_name, file, LO_NAME_SIZE);
201 loopinfo.lo_name[LO_NAME_SIZE-1] = 0;
202
203 loopinfo.lo_offset = offset;
204
205 loopinfo.lo_encrypt_key_size = 0;
206 if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
207 perror("ioctl: LOOP_SET_FD");
208 close(fd);
209 close(ffd);
210 return 1;
211 }
212 if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
213 (void) ioctl(fd, LOOP_CLR_FD, 0);
214 perror("ioctl: LOOP_SET_STATUS");
215 close(fd);
216 close(ffd);
217 return 1;
218 }
219 close(fd);
220 close(ffd);
221 return 0;
222}
223
224char *find_unused_loop_device (void)
225{
226 char dev[20];
227 int i, fd;
228 struct stat statbuf;
229 struct loop_info loopinfo;
230
231 for(i = 0; i <= 7; i++) {
232 sprintf(dev, "/dev/loop%d", i);
233 if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
234 if ((fd = open (dev, O_RDONLY)) >= 0) {
235 if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == -1) {
236 if (errno == ENXIO) { /* probably free */
237 close (fd);
238 return strdup(dev);
239 }
240 }
241 close (fd);
242 }
243 }
244 }
245 return NULL;
246}
247#endif /* BB_FEATURE_MOUNT_LOOP */
248
169/* Seperate standard mount options from the nonstandard string options */ 249/* Seperate standard mount options from the nonstandard string options */
170static void 250static void
171parse_mount_options ( char *options, unsigned long *flags, char *strflags) 251parse_mount_options ( char *options, unsigned long *flags, char *strflags)
@@ -240,7 +320,7 @@ mount_one(char *blockDevice, char *directory, char *filesystemType,
240 status = do_mount (blockDevice, directory, filesystemType, 320 status = do_mount (blockDevice, directory, filesystemType,
241 flags | MS_MGC_VAL, string_flags, useMtab, 321 flags | MS_MGC_VAL, string_flags, useMtab,
242 fakeIt, mtab_opts); 322 fakeIt, mtab_opts);
243 if (status == 0) 323 if (status == TRUE)
244 break; 324 break;
245 } 325 }
246 } 326 }
@@ -253,7 +333,7 @@ mount_one(char *blockDevice, char *directory, char *filesystemType,
253 fakeIt, mtab_opts); 333 fakeIt, mtab_opts);
254 } 334 }
255 335
256 if (status) { 336 if (status==FALSE) {
257 fprintf (stderr, "Mounting %s on %s failed: %s\n", 337 fprintf (stderr, "Mounting %s on %s failed: %s\n",
258 blockDevice, directory, strerror(errno)); 338 blockDevice, directory, strerror(errno));
259 return (FALSE); 339 return (FALSE);
@@ -400,70 +480,3 @@ goodbye:
400 usage( mount_usage); 480 usage( mount_usage);
401} 481}
402 482
403#if defined BB_FEATURE_MOUNT_LOOP
404static int set_loop(const char *device, const char *file, int offset, int *loopro)
405{
406 struct loop_info loopinfo;
407 int fd, ffd, mode;
408
409 mode = *loopro ? O_RDONLY : O_RDWR;
410 if ((ffd = open (file, mode)) < 0 && !*loopro
411 && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) {
412 perror (file);
413 return 1;
414 }
415 if ((fd = open (device, mode)) < 0) {
416 close(ffd);
417 perror (device);
418 return 1;
419 }
420 *loopro = (mode == O_RDONLY);
421
422 memset(&loopinfo, 0, sizeof(loopinfo));
423 strncpy(loopinfo.lo_name, file, LO_NAME_SIZE);
424 loopinfo.lo_name[LO_NAME_SIZE-1] = 0;
425
426 loopinfo.lo_offset = offset;
427
428 loopinfo.lo_encrypt_key_size = 0;
429 if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
430 perror("ioctl: LOOP_SET_FD");
431 close(fd);
432 close(ffd);
433 return 1;
434 }
435 if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
436 (void) ioctl(fd, LOOP_CLR_FD, 0);
437 perror("ioctl: LOOP_SET_STATUS");
438 close(fd);
439 close(ffd);
440 return 1;
441 }
442 close(fd);
443 close(ffd);
444 return 0;
445}
446
447char *find_unused_loop_device (void)
448{
449 char dev[20];
450 int i, fd;
451 struct stat statbuf;
452 struct loop_info loopinfo;
453
454 for(i = 0; i <= 7; i++) {
455 sprintf(dev, "/dev/loop%d", i);
456 if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
457 if ((fd = open (dev, O_RDONLY)) >= 0) {
458 if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == -1 &&
459 errno == ENXIO) { /* probably free */
460 close (fd);
461 return strdup(dev);
462 }
463 close (fd);
464 }
465 }
466 }
467 return NULL;
468}
469#endif /* BB_FEATURE_MOUNT_LOOP */
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 9ad6f26c2..68b27e385 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -28,14 +28,6 @@
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
36static int del_loop(const char *device);
37#endif
38
39static const char umount_usage[] = 31static const char umount_usage[] =
40"umount [flags] filesystem|directory\n\n" 32"umount [flags] filesystem|directory\n\n"
41"Flags:\n" 33"Flags:\n"
@@ -52,43 +44,34 @@ static int useMtab = TRUE;
52static int umountAll = FALSE; 44static int umountAll = FALSE;
53extern const char mtab_file[]; /* Defined in utility.c */ 45extern const char mtab_file[]; /* Defined in utility.c */
54 46
47#define MIN(x,y) (x > y ? x : y)
48
55static int 49static int
56do_umount(const char* name, int useMtab) 50do_umount(const char* name, int useMtab)
57{ 51{
58 int status; 52 int status;
59 53 struct mntent *m;
60#if defined BB_FEATURE_MOUNT_LOOP 54 FILE *mountTable;
61 /* check to see if this is a loop device */ 55 const char *blockDevice = NULL;
62 struct stat fst; 56
63 char dev[20]; 57 if ((mountTable = setmntent (mtab_file, "r"))) {
64 const char *oldname = NULL; 58 while ((m = getmntent (mountTable)) != 0) {
65 int i; 59 if (strncmp(m->mnt_dir, name,
66 60 MIN(strlen(m->mnt_dir),strlen(name))) == 0)
67 if (stat(name, &fst)) { 61 blockDevice = m->mnt_fsname;
68 fprintf(stderr, "umount: %s: %s\n", name, strerror(errno)); 62 else if (strcmp(m->mnt_fsname, name) == 0) {
69 exit(1); 63 blockDevice = name;
70 } 64 name = m->mnt_dir;
71 for (i = 0 ; i <= 7 ; i++) { 65 }
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 } 66 }
81 } 67 }
82#endif
83 68
84 status = umount(name); 69 status = umount(name);
85 70
86#if defined BB_FEATURE_MOUNT_LOOP 71#if defined BB_FEATURE_MOUNT_LOOP
87 if (!strncmp("/dev/loop", name, 9)) { /* this was a loop device, delete it */ 72 if (blockDevice != NULL && !strncmp("/dev/loop", blockDevice, 9))
88 del_loop(name); 73 /* this was a loop device, delete it */
89 if (oldname != NULL) 74 del_loop(blockDevice);
90 name = oldname;
91 }
92#endif 75#endif
93#if defined BB_MTAB 76#if defined BB_MTAB
94 if ( status == 0 ) { 77 if ( status == 0 ) {
@@ -178,20 +161,3 @@ umount_main(int argc, char** argv)
178 } 161 }
179} 162}
180 163
181#if defined BB_FEATURE_MOUNT_LOOP
182static 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