diff options
| author | Erik Andersen <andersen@codepoet.org> | 2000-01-26 20:06:48 +0000 |
|---|---|---|
| committer | Erik Andersen <andersen@codepoet.org> | 2000-01-26 20:06:48 +0000 |
| commit | 5cbdd712f5320ffc109053a94b7cf36c82292cf6 (patch) | |
| tree | 77236e83cc0583411a75b752a6152d445eb680e0 | |
| parent | 3fe39dce5d1a0b0946878c66bbd7f694c5aa38ea (diff) | |
| download | busybox-w32-5cbdd712f5320ffc109053a94b7cf36c82292cf6.tar.gz busybox-w32-5cbdd712f5320ffc109053a94b7cf36c82292cf6.tar.bz2 busybox-w32-5cbdd712f5320ffc109053a94b7cf36c82292cf6.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
| -rw-r--r-- | Changelog | 5 | ||||
| -rw-r--r-- | init.c | 4 | ||||
| -rw-r--r-- | init/init.c | 4 | ||||
| -rw-r--r-- | internal.h | 4 | ||||
| -rw-r--r-- | mount.c | 165 | ||||
| -rw-r--r-- | networking/ping.c | 9 | ||||
| -rw-r--r-- | ping.c | 9 | ||||
| -rw-r--r-- | umount.c | 70 | ||||
| -rw-r--r-- | util-linux/mount.c | 165 | ||||
| -rw-r--r-- | util-linux/umount.c | 70 | ||||
| -rw-r--r-- | utility.c | 25 |
11 files changed, 266 insertions, 264 deletions
| @@ -32,6 +32,11 @@ | |||
| 32 | tail -f work only with a single file. This reduced tail | 32 | tail -f work only with a single file. This reduced tail |
| 33 | from 6k to 2.4k. The bigger/more featured tail can still be | 33 | from 6k to 2.4k. The bigger/more featured tail can still be |
| 34 | had by disabling BB_FEATURE_SIMPLE_TAIL in dusybox.defs.h | 34 | had by disabling BB_FEATURE_SIMPLE_TAIL in dusybox.defs.h |
| 35 | * Ping now falls back to doing the right thing if /etc/protocols | ||
| 36 | turns up missing. | ||
| 37 | * Fixed mount and umount. Previously they could leak loop device | ||
| 38 | allocations, causing the system to quickly run out. Fix for umount | ||
| 39 | by Ben Collins <bcollins@debian.org>, and mount was fixed by me. | ||
| 35 | 40 | ||
| 36 | 41 | ||
| 37 | -Erik Andersen | 42 | -Erik Andersen |
| @@ -359,6 +359,7 @@ static pid_t run(char* command, | |||
| 359 | signal(SIGUSR2, SIG_DFL); | 359 | signal(SIGUSR2, SIG_DFL); |
| 360 | signal(SIGINT, SIG_DFL); | 360 | signal(SIGINT, SIG_DFL); |
| 361 | signal(SIGTERM, SIG_DFL); | 361 | signal(SIGTERM, SIG_DFL); |
| 362 | signal(SIGHUP, SIG_DFL); | ||
| 362 | 363 | ||
| 363 | if ((fd = device_open(terminal, O_RDWR)) < 0) { | 364 | if ((fd = device_open(terminal, O_RDWR)) < 0) { |
| 364 | message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal); | 365 | message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal); |
| @@ -458,6 +459,9 @@ goodnight: | |||
| 458 | #ifndef DEBUG_INIT | 459 | #ifndef DEBUG_INIT |
| 459 | static void shutdown_system(void) | 460 | static void shutdown_system(void) |
| 460 | { | 461 | { |
| 462 | /* first disable our SIGHUP signal */ | ||
| 463 | signal(SIGHUP, SIG_DFL); | ||
| 464 | |||
| 461 | /* Allow Ctrl-Alt-Del to reboot system. */ | 465 | /* Allow Ctrl-Alt-Del to reboot system. */ |
| 462 | reboot(RB_ENABLE_CAD); | 466 | reboot(RB_ENABLE_CAD); |
| 463 | message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); | 467 | message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); |
diff --git a/init/init.c b/init/init.c index 5b80cc561..09540ff01 100644 --- a/init/init.c +++ b/init/init.c | |||
| @@ -359,6 +359,7 @@ static pid_t run(char* command, | |||
| 359 | signal(SIGUSR2, SIG_DFL); | 359 | signal(SIGUSR2, SIG_DFL); |
| 360 | signal(SIGINT, SIG_DFL); | 360 | signal(SIGINT, SIG_DFL); |
| 361 | signal(SIGTERM, SIG_DFL); | 361 | signal(SIGTERM, SIG_DFL); |
| 362 | signal(SIGHUP, SIG_DFL); | ||
| 362 | 363 | ||
| 363 | if ((fd = device_open(terminal, O_RDWR)) < 0) { | 364 | if ((fd = device_open(terminal, O_RDWR)) < 0) { |
| 364 | message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal); | 365 | message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal); |
| @@ -458,6 +459,9 @@ goodnight: | |||
| 458 | #ifndef DEBUG_INIT | 459 | #ifndef DEBUG_INIT |
| 459 | static void shutdown_system(void) | 460 | static void shutdown_system(void) |
| 460 | { | 461 | { |
| 462 | /* first disable our SIGHUP signal */ | ||
| 463 | signal(SIGHUP, SIG_DFL); | ||
| 464 | |||
| 461 | /* Allow Ctrl-Alt-Del to reboot system. */ | 465 | /* Allow Ctrl-Alt-Del to reboot system. */ |
| 462 | reboot(RB_ENABLE_CAD); | 466 | reboot(RB_ENABLE_CAD); |
| 463 | message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); | 467 | message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); |
diff --git a/internal.h b/internal.h index 500a63e62..9611c1922 100644 --- a/internal.h +++ b/internal.h | |||
| @@ -175,6 +175,10 @@ extern int check_wildcard_match(const char* text, const char* pattern); | |||
| 175 | extern long getNum (const char *cp); | 175 | extern long getNum (const char *cp); |
| 176 | extern pid_t findInitPid(); | 176 | extern pid_t findInitPid(); |
| 177 | 177 | ||
| 178 | #if defined BB_FEATURE_MOUNT_LOOP | ||
| 179 | extern int del_loop(const char *device); | ||
| 180 | #endif | ||
| 181 | |||
| 178 | #if defined BB_GUNZIP || defined BB_GZIP || defined BB_PRINTF || defined BB_TAIL | 182 | #if defined BB_GUNZIP || defined BB_GZIP || defined BB_PRINTF || defined BB_TAIL |
| 179 | extern void *xmalloc (size_t size); | 183 | extern void *xmalloc (size_t size); |
| 180 | extern void error(char *msg); | 184 | extern void error(char *msg); |
| @@ -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 | ||
| 181 | static 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 | |||
| 224 | char *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 */ |
| 170 | static void | 250 | static void |
| 171 | parse_mount_options ( char *options, unsigned long *flags, char *strflags) | 251 | parse_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 | ||
| 404 | static 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 | |||
| 447 | char *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/networking/ping.c b/networking/ping.c index 92b62def3..2b6e7f5f2 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * $Id: ping.c,v 1.6 1999/12/11 08:41:28 andersen Exp $ | 2 | * $Id: ping.c,v 1.7 2000/01/26 20:06:48 erik Exp $ |
| 3 | * Mini ping implementation for busybox | 3 | * Mini ping implementation for busybox |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> | 5 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> |
| @@ -319,10 +319,11 @@ static void ping(char *host) | |||
| 319 | int sockopt; | 319 | int sockopt; |
| 320 | 320 | ||
| 321 | if (!(proto = getprotobyname("icmp"))) { | 321 | if (!(proto = getprotobyname("icmp"))) { |
| 322 | fprintf(stderr, "ping: unknown protocol icmp\n"); | 322 | /* getprotobyname failed, so just silently force |
| 323 | exit(1); | 323 | * proto->p_proto to have the correct value for "icmp" */ |
| 324 | proto->p_proto = 1; | ||
| 324 | } | 325 | } |
| 325 | if ((pingsock = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) { | 326 | if ((pingsock = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) { /* 1 == ICMP */ |
| 326 | if (errno == EPERM) { | 327 | if (errno == EPERM) { |
| 327 | fprintf(stderr, "ping: permission denied. (are you root?)\n"); | 328 | fprintf(stderr, "ping: permission denied. (are you root?)\n"); |
| 328 | } else { | 329 | } else { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * $Id: ping.c,v 1.6 1999/12/11 08:41:28 andersen Exp $ | 2 | * $Id: ping.c,v 1.7 2000/01/26 20:06:48 erik Exp $ |
| 3 | * Mini ping implementation for busybox | 3 | * Mini ping implementation for busybox |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> | 5 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> |
| @@ -319,10 +319,11 @@ static void ping(char *host) | |||
| 319 | int sockopt; | 319 | int sockopt; |
| 320 | 320 | ||
| 321 | if (!(proto = getprotobyname("icmp"))) { | 321 | if (!(proto = getprotobyname("icmp"))) { |
| 322 | fprintf(stderr, "ping: unknown protocol icmp\n"); | 322 | /* getprotobyname failed, so just silently force |
| 323 | exit(1); | 323 | * proto->p_proto to have the correct value for "icmp" */ |
| 324 | proto->p_proto = 1; | ||
| 324 | } | 325 | } |
| 325 | if ((pingsock = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) { | 326 | if ((pingsock = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) { /* 1 == ICMP */ |
| 326 | if (errno == EPERM) { | 327 | if (errno == EPERM) { |
| 327 | fprintf(stderr, "ping: permission denied. (are you root?)\n"); | 328 | fprintf(stderr, "ping: permission denied. (are you root?)\n"); |
| 328 | } else { | 329 | } else { |
| @@ -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 | |||
| 36 | static int del_loop(const char *device); | ||
| 37 | #endif | ||
| 38 | |||
| 39 | static const char umount_usage[] = | 31 | static 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; | |||
| 52 | static int umountAll = FALSE; | 44 | static int umountAll = FALSE; |
| 53 | extern const char mtab_file[]; /* Defined in utility.c */ | 45 | extern const char mtab_file[]; /* Defined in utility.c */ |
| 54 | 46 | ||
| 47 | #define MIN(x,y) (x > y ? x : y) | ||
| 48 | |||
| 55 | static int | 49 | static int |
| 56 | do_umount(const char* name, int useMtab) | 50 | do_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 | ||
| 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 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 | ||
| 181 | static 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 | |||
| 224 | char *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 */ |
| 170 | static void | 250 | static void |
| 171 | parse_mount_options ( char *options, unsigned long *flags, char *strflags) | 251 | parse_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 | ||
| 404 | static 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 | |||
| 447 | char *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 | |||
| 36 | static int del_loop(const char *device); | ||
| 37 | #endif | ||
| 38 | |||
| 39 | static const char umount_usage[] = | 31 | static 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; | |||
| 52 | static int umountAll = FALSE; | 44 | static int umountAll = FALSE; |
| 53 | extern const char mtab_file[]; /* Defined in utility.c */ | 45 | extern const char mtab_file[]; /* Defined in utility.c */ |
| 54 | 46 | ||
| 47 | #define MIN(x,y) (x > y ? x : y) | ||
| 48 | |||
| 55 | static int | 49 | static int |
| 56 | do_umount(const char* name, int useMtab) | 50 | do_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 | ||
| 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 | ||
| @@ -36,6 +36,13 @@ | |||
| 36 | #include <unistd.h> | 36 | #include <unistd.h> |
| 37 | #include <ctype.h> | 37 | #include <ctype.h> |
| 38 | 38 | ||
| 39 | #if defined BB_FEATURE_MOUNT_LOOP | ||
| 40 | #include <fcntl.h> | ||
| 41 | #include <sys/ioctl.h> | ||
| 42 | #include <linux/loop.h> | ||
| 43 | #endif | ||
| 44 | |||
| 45 | |||
| 39 | #if defined BB_MOUNT || defined BB_UMOUNT || defined BB_DF | 46 | #if defined BB_MOUNT || defined BB_UMOUNT || defined BB_DF |
| 40 | # if defined BB_FEATURE_USE_PROCFS | 47 | # if defined BB_FEATURE_USE_PROCFS |
| 41 | const char mtab_file[] = "/proc/mounts"; | 48 | const char mtab_file[] = "/proc/mounts"; |
| @@ -1146,4 +1153,22 @@ extern int vdprintf(int d, const char *format, va_list ap) | |||
| 1146 | } | 1153 | } |
| 1147 | #endif | 1154 | #endif |
| 1148 | 1155 | ||
| 1156 | #if defined BB_FEATURE_MOUNT_LOOP | ||
| 1157 | extern int del_loop(const char *device) | ||
| 1158 | { | ||
| 1159 | int fd; | ||
| 1160 | |||
| 1161 | if ((fd = open(device, O_RDONLY)) < 0) { | ||
| 1162 | perror(device); | ||
| 1163 | return( FALSE); | ||
| 1164 | } | ||
| 1165 | if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { | ||
| 1166 | perror("ioctl: LOOP_CLR_FD"); | ||
| 1167 | return( FALSE); | ||
| 1168 | } | ||
| 1169 | close(fd); | ||
| 1170 | return( TRUE); | ||
| 1171 | } | ||
| 1172 | #endif | ||
| 1173 | |||
| 1149 | /* END CODE */ | 1174 | /* END CODE */ |
