diff -urpN busybox.0/util-linux/mount.c busybox.1/util-linux/mount.c --- busybox.0/util-linux/mount.c 2006-09-17 17:47:35.000000000 +0200 +++ busybox.1/util-linux/mount.c 2006-09-17 17:50:07.000000000 +0200 @@ -234,6 +234,43 @@ static int mount_it_now(struct mntent *m if (fakeIt) return 0; + if (useMtab && !(vfsflags & MS_REMOUNT)) { + int flags; + rc = 30; /* 3 second timeout */ + + // If /etc/mtab is a symlink, do not update it + + USE_FEATURE_MTAB_SUPPORT( { char dummy; useMtab = (readlink(bb_path_mtab_file, &dummy, 1) < 0); } ) + if (!useMtab) rc = -1; + + flags = O_WRONLY|O_CREAT|O_TRUNC|O_EXCL; + while (rc >= 0) { + int fd = open("/etc/mtab.new", flags, 0444); + if (fd >= 0) { + int src = open(bb_path_mtab_file, O_RDONLY); + if (src >= 0) { + if (bb_copyfd_eof(src, fd) < 0) + bb_error_msg("problem copying %s to %s", bb_path_mtab_file, "/etc/mtab.new"); + close(src); + } + close(fd); + break; + } + if (errno != EEXIST) { + bb_perror_msg("error opening %s", "/etc/mtab.new"); + break; + } else { /* mtab.new exists - parallel (u)mount is running? */ + struct timespec sec10 = { 0, 100*1000*1000 }; + /* pause for 1/10 sec */ + while (nanosleep(&sec10, &sec10) < 0) /* repeat */; + if (!--rc) { + flags = O_WRONLY|O_CREAT|O_TRUNC; + bb_error_msg("warning: overwriting stale %s", "/etc/mtab.new"); + } + } + } + } + // Mount, with fallback to read-only if necessary. for (;;) { @@ -254,13 +291,15 @@ static int mount_it_now(struct mntent *m /* If the mount was successful, and we're maintaining an old-style * mtab file by hand, add the new entry to it now. */ - if (ENABLE_FEATURE_MTAB_SUPPORT && useMtab && !rc && !(vfsflags & MS_REMOUNT)) { + if (useMtab && !rc && !(vfsflags & MS_REMOUNT)) { char *fsname; - FILE *mountTable = setmntent(bb_path_mtab_file, "a+"); + FILE *mountTable = setmntent("/etc/mtab.new", "a+"); int i; - if (!mountTable) - bb_error_msg("no %s",bb_path_mtab_file); + if (!mountTable) { + bb_error_msg("no %s", "/etc/mtab.new"); + goto ret; + } // Add vfs string flags @@ -287,12 +326,16 @@ static int mount_it_now(struct mntent *m addmntent(mountTable, mp); endmntent(mountTable); + if (rename("/etc/mtab.new", bb_path_mtab_file) < 0) { + bb_perror_msg("rename %s to %s", "/etc/mtab.new", bb_path_mtab_file); + unlink("/etc/mtab.new"); + } if (ENABLE_FEATURE_CLEAN_UP) { free(mp->mnt_dir); free(fsname); } } - +ret: return rc; }