diff options
Diffstat (limited to 'util-linux')
| -rw-r--r-- | util-linux/umount.c | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/util-linux/umount.c b/util-linux/umount.c index dd072e7f6..e55002bf0 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
| @@ -18,19 +18,27 @@ | |||
| 18 | #include <string.h> | 18 | #include <string.h> |
| 19 | #include <stdlib.h> | 19 | #include <stdlib.h> |
| 20 | #include <sys/mount.h> | 20 | #include <sys/mount.h> |
| 21 | #include <getopt.h> | ||
| 21 | #include "busybox.h" | 22 | #include "busybox.h" |
| 22 | 23 | ||
| 24 | #define OPTION_STRING "flaDnrv" | ||
| 25 | #define OPT_FORCE 1 | ||
| 26 | #define OPT_LAZY 2 | ||
| 27 | #define OPT_ALL 4 | ||
| 28 | #define OPT_DONTFREELOOP 8 | ||
| 29 | #define OPT_NO_MTAB 16 | ||
| 30 | #define OPT_REMOUNT 32 | ||
| 31 | /* -v is ignored */ | ||
| 32 | |||
| 33 | |||
| 23 | extern int umount_main(int argc, char **argv) | 34 | extern int umount_main(int argc, char **argv) |
| 24 | { | 35 | { |
| 25 | int doForce = 0; | 36 | int doForce; |
| 26 | int freeLoop = ENABLE_FEATURE_MOUNT_LOOP; | ||
| 27 | int useMtab = ENABLE_FEATURE_MTAB_SUPPORT; | ||
| 28 | int umountAll = FALSE; | ||
| 29 | int doRemount = FALSE; | ||
| 30 | char path[2*PATH_MAX]; | 37 | char path[2*PATH_MAX]; |
| 31 | struct mntent me; | 38 | struct mntent me; |
| 32 | FILE *fp; | 39 | FILE *fp; |
| 33 | int status=EXIT_SUCCESS; | 40 | int status=EXIT_SUCCESS; |
| 41 | unsigned long opt; | ||
| 34 | struct mtab_list { | 42 | struct mtab_list { |
| 35 | char *dir; | 43 | char *dir; |
| 36 | char *device; | 44 | char *device; |
| @@ -40,19 +48,14 @@ extern int umount_main(int argc, char **argv) | |||
| 40 | if(argc < 2) bb_show_usage(); | 48 | if(argc < 2) bb_show_usage(); |
| 41 | 49 | ||
| 42 | /* Parse any options */ | 50 | /* Parse any options */ |
| 43 | while (--argc > 0 && **(++argv) == '-') { | 51 | |
| 44 | while (*++(*argv)) { | 52 | opt = bb_getopt_ulflags (argc, argv, "flaDnrv"); |
| 45 | if(**argv=='a') umountAll = TRUE; | 53 | |
| 46 | else if(ENABLE_FEATURE_MOUNT_LOOP && **argv=='D') freeLoop = FALSE; | 54 | argc -= optind; |
| 47 | else if(ENABLE_FEATURE_MTAB_SUPPORT && **argv=='n') useMtab = FALSE; | 55 | argv += optind; |
| 48 | else if(**argv=='f') doForce = 1; // MNT_FORCE | ||
| 49 | else if(**argv=='l') doForce = 2; // MNT_DETACH | ||
| 50 | else if(**argv=='r') doRemount = TRUE; | ||
| 51 | else if(**argv=='v'); | ||
| 52 | else bb_show_usage(); | ||
| 53 | } | ||
| 54 | } | ||
| 55 | 56 | ||
| 57 | doForce = MAX((opt & OPT_FORCE), (opt & OPT_LAZY)); | ||
| 58 | |||
| 56 | /* Get a list of mount points from mtab. We read them all in now mostly | 59 | /* Get a list of mount points from mtab. We read them all in now mostly |
| 57 | * for umount -a (so we don't have to worry about the list changing while | 60 | * for umount -a (so we don't have to worry about the list changing while |
| 58 | * we iterate over it, or about getting stuck in a loop on the same failing | 61 | * we iterate over it, or about getting stuck in a loop on the same failing |
| @@ -73,16 +76,16 @@ extern int umount_main(int argc, char **argv) | |||
| 73 | 76 | ||
| 74 | /* If we're umounting all, then m points to the start of the list and | 77 | /* If we're umounting all, then m points to the start of the list and |
| 75 | * the argument list should be empty (which will match all). */ | 78 | * the argument list should be empty (which will match all). */ |
| 76 | if(!umountAll) m=0; | 79 | if(!(opt & OPT_ALL)) m=0; |
| 77 | 80 | ||
| 78 | // Loop through everything we're supposed to umount, and do so. | 81 | // Loop through everything we're supposed to umount, and do so. |
| 79 | for(;;) { | 82 | for(;;) { |
| 80 | int curstat; | 83 | int curstat; |
| 81 | 84 | ||
| 82 | // Do we alrady know what to umount this time through the loop? | 85 | // Do we already know what to umount this time through the loop? |
| 83 | if(m) safe_strncpy(path,m->dir,PATH_MAX); | 86 | if(m) safe_strncpy(path,m->dir,PATH_MAX); |
| 84 | // For umountAll, end of mtab means time to exit. | 87 | // For umount -a, end of mtab means time to exit. |
| 85 | else if(umountAll) break; | 88 | else if(opt & OPT_ALL) break; |
| 86 | // Get next command line argument (and look it up in mtab list) | 89 | // Get next command line argument (and look it up in mtab list) |
| 87 | else if(!argc--) break; | 90 | else if(!argc--) break; |
| 88 | else { | 91 | else { |
| @@ -104,27 +107,28 @@ extern int umount_main(int argc, char **argv) | |||
| 104 | } | 107 | } |
| 105 | 108 | ||
| 106 | // If still can't umount, maybe remount read-only? | 109 | // If still can't umount, maybe remount read-only? |
| 107 | if (curstat && doRemount && errno == EBUSY && m) { | 110 | if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) { |
| 108 | curstat = mount(m->device, path, NULL, MS_REMOUNT|MS_RDONLY, NULL); | 111 | curstat = mount(m->device, path, NULL, MS_REMOUNT|MS_RDONLY, NULL); |
| 109 | bb_error_msg(curstat ? "Cannot remount %s read-only" : | 112 | bb_error_msg(curstat ? "Cannot remount %s read-only" : |
| 110 | "%s busy - remounted read-only", m->device); | 113 | "%s busy - remounted read-only", m->device); |
| 111 | } | 114 | } |
| 112 | 115 | ||
| 113 | /* De-allcate the loop device. This ioctl should be ignored on any | 116 | /* De-allocate the loop device. This ioctl should be ignored on any |
| 114 | * non-loop block devices. */ | 117 | * non-loop block devices. */ |
| 115 | if(ENABLE_FEATURE_MOUNT_LOOP && freeLoop && m) | 118 | if(ENABLE_FEATURE_MOUNT_LOOP && !(opt & OPT_DONTFREELOOP) && m) |
| 116 | del_loop(m->device); | 119 | del_loop(m->device); |
| 117 | 120 | ||
| 118 | if(curstat) { | 121 | if(curstat) { |
| 119 | /* Yes, the ENABLE is redundant here, but the optimizer for ARM | 122 | /* Yes, the ENABLE is redundant here, but the optimizer for ARM |
| 120 | * can't do simple constant propogation in local variables... */ | 123 | * can't do simple constant propagation in local variables... */ |
| 121 | if(ENABLE_FEATURE_MTAB_SUPPORT && useMtab && m) erase_mtab(m->dir); | 124 | if(ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m) |
| 125 | erase_mtab(m->dir); | ||
| 122 | status = EXIT_FAILURE; | 126 | status = EXIT_FAILURE; |
| 123 | bb_perror_msg("Couldn't umount %s\n", path); | 127 | bb_perror_msg("Couldn't umount %s\n", path); |
| 124 | } | 128 | } |
| 125 | // Find next matching mtab entry for -a or umount /dev | 129 | // Find next matching mtab entry for -a or umount /dev |
| 126 | while(m && (m = m->next)) | 130 | while(m && (m = m->next)) |
| 127 | if(umountAll || !strcmp(path,m->device)) | 131 | if((opt & OPT_ALL) || !strcmp(path,m->device)) |
| 128 | break; | 132 | break; |
| 129 | } | 133 | } |
| 130 | 134 | ||
