aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util-linux/umount.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 24c1d03a9..fabc3d049 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -78,6 +78,7 @@ int umount_main(int argc, char **argv)
78 // Loop through everything we're supposed to umount, and do so. 78 // Loop through everything we're supposed to umount, and do so.
79 for (;;) { 79 for (;;) {
80 int curstat; 80 int curstat;
81 char *zapit = *argv;
81 82
82 // Do we already know what to umount this time through the loop? 83 // Do we already know what to umount this time through the loop?
83 if (m) safe_strncpy(path, m->dir, PATH_MAX); 84 if (m) safe_strncpy(path, m->dir, PATH_MAX);
@@ -86,32 +87,37 @@ int umount_main(int argc, char **argv)
86 // Get next command line argument (and look it up in mtab list) 87 // Get next command line argument (and look it up in mtab list)
87 else if (!argc--) break; 88 else if (!argc--) break;
88 else { 89 else {
89 realpath(*argv++, path); 90 argv++;
91 realpath(zapit, path);
90 for (m = mtl; m; m = m->next) 92 for (m = mtl; m; m = m->next)
91 if (!strcmp(path, m->dir) || !strcmp(path, m->device)) 93 if (!strcmp(path, m->dir) || !strcmp(path, m->device))
92 break; 94 break;
93 } 95 }
96 // If we couldn't find this sucker in /etc/mtab, punt by passing our
97 // command line argument straight to the umount syscall. Otherwise,
98 // umount the directory even if we were given the block device.
99 if (m) zapit = m->dir;
94 100
95 // Let's ask the thing nicely to unmount. 101 // Let's ask the thing nicely to unmount.
96 curstat = umount(path); 102 curstat = umount(zapit);
97 103
98 // Force the unmount, if necessary. 104 // Force the unmount, if necessary.
99 if (curstat && doForce) { 105 if (curstat && doForce) {
100 curstat = umount2(path, doForce); 106 curstat = umount2(zapit, doForce);
101 if (curstat) 107 if (curstat)
102 bb_error_msg_and_die("forced umount of %s failed!", path); 108 bb_error_msg_and_die("forced umount of %s failed!", zapit);
103 } 109 }
104 110
105 // If still can't umount, maybe remount read-only? 111 // If still can't umount, maybe remount read-only?
106 if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) { 112 if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) {
107 curstat = mount(m->device, path, NULL, MS_REMOUNT|MS_RDONLY, NULL); 113 curstat = mount(m->device, zapit, NULL, MS_REMOUNT|MS_RDONLY, NULL);
108 bb_error_msg(curstat ? "Cannot remount %s read-only" : 114 bb_error_msg(curstat ? "Cannot remount %s read-only" :
109 "%s busy - remounted read-only", m->device); 115 "%s busy - remounted read-only", m->device);
110 } 116 }
111 117
112 if (curstat) { 118 if (curstat) {
113 status = EXIT_FAILURE; 119 status = EXIT_FAILURE;
114 bb_perror_msg("Couldn't umount %s", path); 120 bb_perror_msg("Couldn't umount %s", zapit);
115 } else { 121 } else {
116 /* De-allocate the loop device. This ioctl should be ignored on 122 /* De-allocate the loop device. This ioctl should be ignored on
117 * any non-loop block devices. */ 123 * any non-loop block devices. */
@@ -121,9 +127,9 @@ int umount_main(int argc, char **argv)
121 erase_mtab(m->dir); 127 erase_mtab(m->dir);
122 } 128 }
123 129
124
125
126 // Find next matching mtab entry for -a or umount /dev 130 // Find next matching mtab entry for -a or umount /dev
131 // Note this means that "umount /dev/blah" will unmount all instances
132 // of /dev/blah, not just the most recent.
127 while (m && (m = m->next)) 133 while (m && (m = m->next))
128 if ((opt & OPT_ALL) || !strcmp(path,m->device)) 134 if ((opt & OPT_ALL) || !strcmp(path,m->device))
129 break; 135 break;