aboutsummaryrefslogtreecommitdiff
path: root/util-linux
diff options
context:
space:
mode:
Diffstat (limited to 'util-linux')
-rw-r--r--util-linux/fdflush.c2
-rw-r--r--util-linux/fsck_minix.c3
-rw-r--r--util-linux/swaponoff.c5
-rw-r--r--util-linux/umount.c197
4 files changed, 147 insertions, 60 deletions
diff --git a/util-linux/fdflush.c b/util-linux/fdflush.c
index 51b0c2bac..a244e8def 100644
--- a/util-linux/fdflush.c
+++ b/util-linux/fdflush.c
@@ -31,7 +31,7 @@ extern int fdflush_main(int argc, char **argv)
31{ 31{
32 int value; 32 int value;
33 int fd; 33 int fd;
34 if ( **(argv+1) == '-' ) { 34 if ( argc <= 1 || **(argv++) == '-' ) {
35 usage( "fdflush device\n"); 35 usage( "fdflush device\n");
36 } 36 }
37 37
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index d31de20a8..09111c5dc 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -96,6 +96,7 @@
96#include <termios.h> 96#include <termios.h>
97#include <mntent.h> 97#include <mntent.h>
98#include <sys/stat.h> 98#include <sys/stat.h>
99#include <sys/param.h> /* for PATH_MAX */
99 100
100#include <linux/fs.h> 101#include <linux/fs.h>
101#include <linux/minix_fs.h> 102#include <linux/minix_fs.h>
@@ -143,7 +144,7 @@ static int termios_set = 0;
143/* File-name data */ 144/* File-name data */
144#define MAX_DEPTH 50 145#define MAX_DEPTH 50
145static int name_depth = 0; 146static int name_depth = 0;
146static char name_list[MAX_DEPTH][NAME_MAX+1]; 147static char name_list[MAX_DEPTH][PATH_MAX + 1];
147 148
148static char * inode_buffer = NULL; 149static char * inode_buffer = NULL;
149#define Inode (((struct minix_inode *) inode_buffer)-1) 150#define Inode (((struct minix_inode *) inode_buffer)-1)
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c
index 8eaf9797c..3c02bdd42 100644
--- a/util-linux/swaponoff.c
+++ b/util-linux/swaponoff.c
@@ -65,7 +65,6 @@ static void
65do_em_all() 65do_em_all()
66{ 66{
67 struct mntent *m; 67 struct mntent *m;
68 char swapName[NAME_MAX];
69 FILE *f = setmntent ("/etc/fstab", "r"); 68 FILE *f = setmntent ("/etc/fstab", "r");
70 69
71 if (f == NULL) { 70 if (f == NULL) {
@@ -73,8 +72,8 @@ do_em_all()
73 exit( FALSE); 72 exit( FALSE);
74 } 73 }
75 while ((m = getmntent (f)) != NULL) { 74 while ((m = getmntent (f)) != NULL) {
76 if (!strstr (m->mnt_type, "swap")) { 75 if (!strstr (m->mnt_type, MNTTYPE_SWAP)) {
77 swap_enable_disable( swapName); 76 swap_enable_disable( m->mnt_fsname);
78 } 77 }
79 } 78 }
80 endmntent (f); 79 endmntent (f);
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 68b27e385..b65caf76e 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -37,11 +37,24 @@ static const char umount_usage[] =
37#else 37#else
38"\n" 38"\n"
39#endif 39#endif
40#ifdef BB_FEATURE_REMOUNT
41"\t-r:\tTry to remount devices as read-only if mount is busy\n"
42#endif
40; 43;
41 44
45struct _mtab_entry_t {
46 char *device;
47 char *mountpt;
48 struct _mtab_entry_t *next;
49};
50
51static struct _mtab_entry_t *mtab_cache = NULL;
52
53
42 54
43static int useMtab = TRUE; 55static int useMtab = TRUE;
44static int umountAll = FALSE; 56static int umountAll = FALSE;
57static int doRemount = FALSE;
45extern const char mtab_file[]; /* Defined in utility.c */ 58extern const char mtab_file[]; /* Defined in utility.c */
46 59
47#define MIN(x,y) (x > y ? x : y) 60#define MIN(x,y) (x > y ? x : y)
@@ -50,21 +63,10 @@ static int
50do_umount(const char* name, int useMtab) 63do_umount(const char* name, int useMtab)
51{ 64{
52 int status; 65 int status;
53 struct mntent *m; 66 char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
54 FILE *mountTable; 67
55 const char *blockDevice = NULL; 68 if (blockDevice && strcmp(blockDevice, name) == 0)
56 69 name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
57 if ((mountTable = setmntent (mtab_file, "r"))) {
58 while ((m = getmntent (mountTable)) != 0) {
59 if (strncmp(m->mnt_dir, name,
60 MIN(strlen(m->mnt_dir),strlen(name))) == 0)
61 blockDevice = m->mnt_fsname;
62 else if (strcmp(m->mnt_fsname, name) == 0) {
63 blockDevice = name;
64 name = m->mnt_dir;
65 }
66 }
67 }
68 70
69 status = umount(name); 71 status = umount(name);
70 72
@@ -73,57 +75,53 @@ do_umount(const char* name, int useMtab)
73 /* this was a loop device, delete it */ 75 /* this was a loop device, delete it */
74 del_loop(blockDevice); 76 del_loop(blockDevice);
75#endif 77#endif
76#if defined BB_MTAB 78#if defined BB_FEATURE_REMOUNT
79 if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
80 status = mount(blockDevice, name, NULL,
81 MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
82 if (status == 0) {
83 fprintf(stderr, "umount: %s busy - remounted read-only\n",
84 blockDevice);
85 /* TODO: update mtab if BB_MTAB is defined */
86 } else {
87 fprintf(stderr, "umount: Cannot remount %s read-only\n",
88 blockDevice);
89 }
90 }
91#endif
77 if ( status == 0 ) { 92 if ( status == 0 ) {
93#if defined BB_MTAB
78 if ( useMtab==TRUE ) 94 if ( useMtab==TRUE )
79 erase_mtab(name); 95 erase_mtab(name);
80 return 0;
81 }
82 else
83#endif 96#endif
84 return(status); 97 return( TRUE);
98 }
99 return(FALSE);
85} 100}
86 101
87static int 102static int
88umount_all(int useMtab) 103umount_all(int useMtab)
89{ 104{
90 int status; 105 int status = TRUE;
91 struct mntent *m; 106 char *mountpt;
92 FILE *mountTable; 107 void *iter;
93 108
94 if ((mountTable = setmntent (mtab_file, "r"))) { 109 for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
95 while ((m = getmntent (mountTable)) != 0) { 110 status=do_umount (mountpt, useMtab);
96 char *blockDevice = m->mnt_fsname; 111 if (status != 0) {
97#if ! defined BB_MTAB 112 /* Don't bother retrying the umount on busy devices */
98 if (strcmp (blockDevice, "/dev/root") == 0) { 113 if (errno == EBUSY) {
99 struct fstab* fstabItem; 114 perror(mountpt);
100 fstabItem = getfsfile ("/"); 115 continue;
101 if (fstabItem != NULL) {
102 blockDevice = fstabItem->fs_spec;
103 }
104 } 116 }
105#endif 117 status = do_umount (mountpt, useMtab);
106 /* Don't umount /proc when doing umount -a */ 118 if (status != 0) {
107 if (strcmp (blockDevice, "proc") == 0) 119 printf ("Couldn't umount %s on %s: %s\n",
108 continue; 120 mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
109
110 status=do_umount (m->mnt_dir, useMtab);
111 if (status!=0) {
112 /* Don't bother retrying the umount on busy devices */
113 if (errno==EBUSY) {
114 perror(m->mnt_dir);
115 continue;
116 }
117 status=do_umount (blockDevice, useMtab);
118 if (status!=0) {
119 printf ("Couldn't umount %s on %s (type %s): %s\n",
120 blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
121 }
122 } 121 }
123 } 122 }
124 endmntent (mountTable);
125 } 123 }
126 return( TRUE); 124 return (status);
127} 125}
128 126
129extern int 127extern int
@@ -144,13 +142,18 @@ umount_main(int argc, char** argv)
144 useMtab = FALSE; 142 useMtab = FALSE;
145 break; 143 break;
146#endif 144#endif
145#ifdef BB_FEATURE_REMOUNT
146 case 'r':
147 doRemount = TRUE;
148 break;
149#endif
147 default: 150 default:
148 usage( umount_usage); 151 usage( umount_usage);
149 } 152 }
150 } 153 }
151 154
152 155 mtab_read();
153 if(umountAll==TRUE) { 156 if (umountAll==TRUE) {
154 exit(umount_all(useMtab)); 157 exit(umount_all(useMtab));
155 } 158 }
156 if ( do_umount(*argv,useMtab) == 0 ) 159 if ( do_umount(*argv,useMtab) == 0 )
@@ -161,3 +164,87 @@ umount_main(int argc, char** argv)
161 } 164 }
162} 165}
163 166
167
168
169/* These functions are here because the getmntent functions do not appear
170 * to be re-entrant, which leads to all sorts of problems when we try to
171 * use them recursively - randolph
172 */
173void mtab_read(void)
174{
175 struct _mtab_entry_t *entry = NULL;
176 struct mntent *e;
177 FILE *fp;
178
179 if (mtab_cache != NULL) return;
180
181 if ((fp = setmntent(mtab_file, "r")) == NULL) {
182 fprintf(stderr, "Cannot open %s\n", mtab_file);
183 return;
184 }
185 while ((e = getmntent(fp))) {
186 entry = malloc(sizeof(struct _mtab_entry_t));
187 entry->device = strdup(e->mnt_fsname);
188 entry->mountpt = strdup(e->mnt_dir);
189 entry->next = mtab_cache;
190 mtab_cache = entry;
191 }
192 endmntent(fp);
193}
194
195char *mtab_getinfo(const char *match, const char which)
196{
197 struct _mtab_entry_t *cur = mtab_cache;
198 while (cur) {
199 if (strcmp(cur->mountpt, match) == 0 ||
200 strcmp(cur->device, match) == 0) {
201 if (which == MTAB_GETMOUNTPT) {
202 return cur->mountpt;
203 } else {
204#if !defined BB_MTAB
205 if (strcmp(cur->device, "/dev/root") == 0) {
206 struct fstab* fstabItem;
207 fstabItem = getfsfile ("/");
208 if (fstabItem != NULL) return fstabItem->fs_spec;
209 }
210#endif
211 return cur->device;
212 }
213 }
214 cur = cur->next;
215 }
216 return NULL;
217}
218
219char *mtab_first(void **iter)
220{
221 struct _mtab_entry_t *mtab_iter;
222 if (!iter) return NULL;
223 mtab_iter = mtab_cache;
224 *iter = (void *)mtab_iter;
225 return mtab_next(iter);
226}
227
228char *mtab_next(void **iter)
229{
230 char *mp;
231 if (iter == NULL || *iter == NULL) return NULL;
232 mp = ((struct _mtab_entry_t *)(*iter))->mountpt;
233 *iter = (void *)((struct _mtab_entry_t *)(*iter))->next;
234 return mp;
235}
236
237void mtab_free(void)
238{
239 struct _mtab_entry_t *this, *next;
240
241 this = mtab_cache;
242 while (this) {
243 next = this->next;
244 if (this->device) free(this->device);
245 if (this->mountpt) free(this->mountpt);
246 free(this);
247 this = next;
248 }
249}
250