aboutsummaryrefslogtreecommitdiff
path: root/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'mount.c')
-rw-r--r--mount.c165
1 files changed, 89 insertions, 76 deletions
diff --git a/mount.c b/mount.c
index 709c7fc49..3c1568aad 100644
--- a/mount.c
+++ b/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 */