- Improved /etc/mtab lock - fix for the mount command and am-utils using different mtab locking --- util-linux-2.12p/mount/fstab.c.mtab-lock 2005-03-22 14:05:22.481297072 +0100 +++ util-linux-2.12p/mount/fstab.c 2005-03-22 14:50:55.719781664 +0100 @@ -395,6 +395,7 @@ /* Flag for already existing lock file. */ static int we_created_lockfile = 0; +static int lockfile_fd = -1; /* Flag to indicate that signals have been set up. */ static int signals_have_been_setup = 0; @@ -416,6 +417,8 @@ void unlock_mtab (void) { if (we_created_lockfile) { + close(lockfile_fd); + lockfile_fd = -1; unlink (MOUNTED_LOCK); we_created_lockfile = 0; } @@ -443,7 +446,7 @@ void lock_mtab (void) { - int tries = 3; + int tries = 100000, i; char linktargetfile[MOUNTLOCK_LINKTARGET_LTH]; at_die = unlock_mtab; @@ -469,45 +472,48 @@ sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ()); + i = open (linktargetfile, O_WRONLY|O_CREAT, 0); + if (i < 0) { + int errsv = errno; + /* linktargetfile does not exist (as a file) + and we cannot create it. Read-only filesystem? + Too many files open in the system? + Filesystem full? */ + die (EX_FILEIO, _("can't create lock file %s: %s " + "(use -n flag to override)"), + linktargetfile, strerror (errsv)); + } + close(i); + /* Repeat until it was us who made the link */ while (!we_created_lockfile) { struct flock flock; - int errsv, fd, i, j; - - i = open (linktargetfile, O_WRONLY|O_CREAT, 0); - if (i < 0) { - int errsv = errno; - /* linktargetfile does not exist (as a file) - and we cannot create it. Read-only filesystem? - Too many files open in the system? - Filesystem full? */ - die (EX_FILEIO, _("can't create lock file %s: %s " - "(use -n flag to override)"), - linktargetfile, strerror (errsv)); - } - close(i); + int errsv, j; j = link(linktargetfile, MOUNTED_LOCK); errsv = errno; - (void) unlink(linktargetfile); - if (j == 0) we_created_lockfile = 1; if (j < 0 && errsv != EEXIST) { + (void) unlink(linktargetfile); die (EX_FILEIO, _("can't link lock file %s: %s " "(use -n flag to override)"), MOUNTED_LOCK, strerror (errsv)); } - fd = open (MOUNTED_LOCK, O_WRONLY); + lockfile_fd = open (MOUNTED_LOCK, O_WRONLY); - if (fd < 0) { + if (lockfile_fd < 0) { int errsv = errno; /* Strange... Maybe the file was just deleted? */ - if (errno == ENOENT && tries-- > 0) + if (errno == ENOENT && tries-- > 0) { + if (tries % 200 == 0) + usleep(30); continue; + } + (void) unlink(linktargetfile); die (EX_FILEIO, _("can't open lock file %s: %s " "(use -n flag to override)"), MOUNTED_LOCK, strerror (errsv)); @@ -520,7 +526,7 @@ if (j == 0) { /* We made the link. Now claim the lock. */ - if (fcntl (fd, F_SETLK, &flock) == -1) { + if (fcntl (lockfile_fd, F_SETLK, &flock) == -1) { if (verbose) { int errsv = errno; printf(_("Can't lock lock file %s: %s\n"), @@ -528,13 +534,15 @@ } /* proceed anyway */ } + (void) unlink(linktargetfile); } else { static int tries = 0; /* Someone else made the link. Wait. */ alarm(LOCK_TIMEOUT); - if (fcntl (fd, F_SETLKW, &flock) == -1) { + if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) { int errsv = errno; + (void) unlink(linktargetfile); die (EX_FILEIO, _("can't lock lock file %s: %s"), MOUNTED_LOCK, (errno == EINTR) ? _("timed out") : strerror (errsv)); @@ -542,16 +550,18 @@ alarm(0); /* Limit the number of iterations - maybe there still is some old /etc/mtab~ */ - if (tries++ > 3) { - if (tries > 5) - die (EX_FILEIO, _("Cannot create link %s\n" - "Perhaps there is a stale lock file?\n"), - MOUNTED_LOCK); - sleep(1); - } + ++tries; + if (tries % 200 == 0) + usleep(30); + if (tries > 100000) { + (void) unlink(linktargetfile); + close(lockfile_fd); + die (EX_FILEIO, _("Cannot create link %s\n" + "Perhaps there is a stale lock file?\n"), + MOUNTED_LOCK); + } + close(lockfile_fd); } - - close(fd); } }