Return to BSD News archive
Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!nntp.coast.net!news.kei.com!newsfeed.internetmci.com!in1.uu.net!news.new-york.net!wlbr!sms
From: sms@wlv.iipo.gtegsc.com (Steven M. Schultz)
Subject: Parallel fsck runs conflict with each other (#302)
Sender: news@wlbr.iipo.gtegsc.com (Steven M. Schultz)
Organization: GTE Government Systems, Thousand Oaks CA USA
Message-ID: <DMFwM5.CIn@wlbr.iipo.gtegsc.com>
X-Nntp-Posting-Host: wlv.iipo.gtegsc.com
Date: Thu, 8 Feb 1996 04:32:29 GMT
Lines: 176
Subject: Parallel fsck runs conflict with each other (#302)
Index: etc/fsck/{setup,main}.c 2.11BSD
Description:
Parallel fsck runs (filesystems with the same 'passno' value
in /etc/fstab) will use the same tempfile name for their work
file resulting in total chaos.
Repeat-By:
Have more than one entry in /etc/fstab with the same sixth field:
/dev/ra1g /usr ufs rw 1 4
/dev/ra0g /u1 ufs rw 1 4
Fsck will prompt _once_ for a tmp file name but _both_ (parallel)
instances of fsck will use the name.
Fix:
Although fsck unlinks the tmp file after creating it there is a
race condition which can result in multiple fsck processes using
the same intermediate file. The results are not pretty.
The fix is to append ".XXXXX" to the filename provided by the
user and then call the 'mkstemp(3)' routine to generate a unique
temporary file.
Cut where indicated, saving to a file (/tmp/302) and then:
patch -p0 < /tmp/301
cd /usr/src/etc/fsck
make
make install
make clean
===========================cut here===================
*** /usr/src/etc/fsck/setup.c.old Wed Jun 13 08:45:47 1990
--- /usr/src/etc/fsck/setup.c Sat Feb 3 21:46:25 1996
***************
*** 5,11 ****
*/
#if !defined(lint) && defined(DOSCCS)
! static char sccsid[] = "@(#)setup.c 5.3 (Berkeley) 5/15/86";
#endif not lint
#include <stdio.h>
--- 5,11 ----
*/
#if !defined(lint) && defined(DOSCCS)
! static char sccsid[] = "@(#)setup.c 5.3.1 (2.11BSD) 1996/2/3";
#endif not lint
#include <stdio.h>
***************
*** 28,33 ****
--- 28,34 ----
int i, j, n;
long size;
BUFAREA *bp;
+ char junk[80 + sizeof (".XXXXX") + 1];
if (stat("/", &statb) < 0)
errexit("Can't stat root\n");
***************
*** 112,136 ****
pfatal("\nNEED SCRATCH FILE (%ld BLKS)\n",nscrblk);
do {
printf("ENTER FILENAME: ");
! if((n = getline(stdin,scrfile,sizeof(scrfile))) == EOF)
errexit("\n");
- if(stat(scrfile,&statb) == 0 &&
- (statb.st_mode & S_IFMT) != S_IFREG)
- errexit("Not a good scratch filename");
} while(n == 0);
}
! sfile.wfdes=open(scrfile, O_CREAT|O_TRUNC|O_WRONLY, 0666);
if ((sfile.wfdes < 0)
! || ((sfile.rfdes = open(scrfile,0)) < 0)) {
! printf("Can't create %s\n",scrfile);
ckfini();
return(0);
}
! unlink(scrfile); /* make it invisible incase we exit */
! if (hotroot && (stat(scrfile,&statb)==0)
&& ((statb.st_mode & S_IFMT) == S_IFREG)
&& (statb.st_dev==rootdev))
! pfatal("TMP FILE (%s) ON ROOT WHEN CHECKING ROOT",scrfile);
bp = &((BUFAREA *)mbase)[(msize/sizeof(BUFAREA))];
poolhead = NULL;
while(--bp >= (BUFAREA *)mbase) {
--- 113,137 ----
pfatal("\nNEED SCRATCH FILE (%ld BLKS)\n",nscrblk);
do {
printf("ENTER FILENAME: ");
! if((n = getline(stdin, scrfile,
! sizeof(scrfile) - 6)) == EOF)
errexit("\n");
} while(n == 0);
}
! strcpy(junk, scrfile);
! strcat(junk, ".XXXXX");
! sfile.wfdes = mkstemp(junk);
if ((sfile.wfdes < 0)
! || ((sfile.rfdes = open(junk,0)) < 0)) {
! printf("Can't create %s\n", junk);
ckfini();
return(0);
}
! unlink(junk); /* make it invisible incase we exit */
! if (hotroot && (fstat(sfile.wfdes,&statb)==0)
&& ((statb.st_mode & S_IFMT) == S_IFREG)
&& (statb.st_dev==rootdev))
! pfatal("TMP FILE (%s) ON ROOT WHEN CHECKING ROOT", junk);
bp = &((BUFAREA *)mbase)[(msize/sizeof(BUFAREA))];
poolhead = NULL;
while(--bp >= (BUFAREA *)mbase) {
*** /usr/src/etc/fsck/main.c.old Wed Jun 13 08:42:32 1990
--- /usr/src/etc/fsck/main.c Sat Feb 3 21:42:38 1996
***************
*** 9,15 ****
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
All rights reserved.\n";
! static char sccsid[] = "@(#)main.c 5.4 (Berkeley) 3/5/86";
#endif not lint
#include <sys/param.h>
--- 9,15 ----
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
All rights reserved.\n";
! static char sccsid[] = "@(#)main.c 5.4.1 (2.11BSD) 1996/2/3";
#endif not lint
#include <sys/param.h>
***************
*** 114,124 ****
do {
anygtr = 0;
if (setfsent() == 0)
! errexit("Can't open checklist file: %s\n", FSTAB);
while ((fsp = getfsent()) != 0) {
! if (strcmp(fsp->fs_type, FSTAB_RW) &&
strcmp(fsp->fs_type, FSTAB_RO) &&
! strcmp(fsp->fs_type, FSTAB_RQ))
continue;
if (preen == 0 ||
passno == 1 && fsp->fs_passno == passno) {
--- 114,126 ----
do {
anygtr = 0;
if (setfsent() == 0)
! errexit("Can't open %s\n", FSTAB);
while ((fsp = getfsent()) != 0) {
! if (strcmp(fsp->fs_vfstype, "ufs") ||
! (strcmp(fsp->fs_type, FSTAB_RW) &&
strcmp(fsp->fs_type, FSTAB_RO) &&
! strcmp(fsp->fs_type, FSTAB_RQ)) ||
! fsp->fs_passno == 0)
continue;
if (preen == 0 ||
passno == 1 && fsp->fs_passno == passno) {
*** /VERSION.old Wed Feb 7 19:51:21 1996
--- /VERSION Wed Feb 7 20:16:05 1996
***************
*** 1,4 ****
! Current Patch Level: 301
2.11 BSD
============
--- 1,4 ----
! Current Patch Level: 302
2.11 BSD
============