Minor background cleanups:
1) Set the FS_NEEDSFSCK flag when unexpected problems are encountered. 2) Clear the FS_NEEDSFSCK flag after a successful foreground cleanup. 3) Refuse to run in background when the FS_NEEDSFSCK flag is set. 4) Avoid taking and removing a snapshot when the filesystem is already clean. 5) Properly implement the force cleaning (-f) flag when in preen mode. Note that you need to have revision 1.21 (date: 2001/04/14 05:26:28) of fs.h installed in <ufs/ffs/fs.h> defining FS_NEEDSFSCK for this to compile.
This commit is contained in:
parent
3b359dad32
commit
8553bca948
@ -203,7 +203,6 @@ char snapname[BUFSIZ]; /* when doing snapshots, the name of the file */
|
||||
char *cdevname; /* name of device being checked */
|
||||
long dev_bsize; /* computed value of DEV_BSIZE */
|
||||
long secsize; /* actual disk sector size */
|
||||
char fflag; /* force check, ignore clean flag */
|
||||
char nflag; /* assume a no response */
|
||||
char yflag; /* assume a yes response */
|
||||
int bkgrdflag; /* use a snapshot to run on an active system */
|
||||
@ -313,6 +312,7 @@ void pfatal __P((const char *fmt, ...));
|
||||
void pinode __P((ino_t ino));
|
||||
void propagate __P((void));
|
||||
void pwarn __P((const char *fmt, ...));
|
||||
int readsb __P((int listerr));
|
||||
int reply __P((char *question));
|
||||
void rwerror __P((char *mesg, ufs_daddr_t blk));
|
||||
void setinodebuf __P((ino_t));
|
||||
|
@ -321,7 +321,8 @@ ckfini(markclean)
|
||||
errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt);
|
||||
pbp = pdirbp = (struct bufarea *)0;
|
||||
if (cursnapshot == 0 && sblock.fs_clean != markclean) {
|
||||
sblock.fs_clean = markclean;
|
||||
if ((sblock.fs_clean = markclean) != 0)
|
||||
sblock.fs_flags &= ~(FS_UNCLEAN | FS_NEEDSFSCK);
|
||||
sbdirty();
|
||||
ofsmodified = fsmodified;
|
||||
flush(fswritefd, &sblk);
|
||||
@ -336,7 +337,7 @@ ckfini(markclean)
|
||||
printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
|
||||
rerun = 1;
|
||||
}
|
||||
if (debug)
|
||||
if (debug && totalreads > 0)
|
||||
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
||||
totalreads, (int)(diskreads * 100 / totalreads));
|
||||
(void)close(fsreadfd);
|
||||
@ -649,6 +650,19 @@ pfatal(fmt, va_alist)
|
||||
if (usedsoftdep)
|
||||
(void)fprintf(stderr,
|
||||
"\nUNEXPECTED SOFT UPDATE INCONSISTENCY\n");
|
||||
/*
|
||||
* Force foreground fsck to clean up inconsistency.
|
||||
*/
|
||||
if (bkgrdflag) {
|
||||
cmd.value = FS_NEEDSFSCK;
|
||||
cmd.size = 1;
|
||||
if (sysctlbyname("vfs.ffs.setflags", 0, 0,
|
||||
&cmd, sizeof cmd) == -1)
|
||||
pwarn("CANNOT SET FS_NEEDSFSCK FLAG\n");
|
||||
fprintf(stderr, "CANNOT RUN IN BACKGROUND\n");
|
||||
ckfini(0);
|
||||
exit(EEXIT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (cdevname == NULL)
|
||||
@ -658,6 +672,16 @@ pfatal(fmt, va_alist)
|
||||
(void)fprintf(stderr,
|
||||
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
||||
cdevname, usedsoftdep ? " SOFT UPDATE " : " ");
|
||||
/*
|
||||
* Force foreground fsck to clean up inconsistency.
|
||||
*/
|
||||
if (bkgrdflag) {
|
||||
cmd.value = FS_NEEDSFSCK;
|
||||
cmd.size = 1;
|
||||
if (sysctlbyname("vfs.ffs.setflags", 0, 0,
|
||||
&cmd, sizeof cmd) == -1)
|
||||
pwarn("CANNOT SET FS_NEEDSFSCK FLAG\n");
|
||||
}
|
||||
ckfini(0);
|
||||
exit(EEXIT);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ static const char rcsid[] =
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/resource.h>
|
||||
@ -199,6 +200,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
cdevname = filesys;
|
||||
if (debug && preen)
|
||||
pwarn("starting\n");
|
||||
sblock_init();
|
||||
|
||||
/*
|
||||
* If we are to do a background check:
|
||||
@ -211,14 +213,35 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
if (bkgrdflag) {
|
||||
if (mntp == NULL) {
|
||||
bkgrdflag = 0;
|
||||
pwarn("NOT MOUNTED, CANNOT RUN IN BACKGROUND\n");
|
||||
pfatal("NOT MOUNTED, CANNOT RUN IN BACKGROUND\n");
|
||||
} else if ((mntp->f_flags & MNT_SOFTDEP) == 0) {
|
||||
bkgrdflag = 0;
|
||||
pwarn("NOT USING SOFT UPDATES, CANNOT RUN IN BACKGROUND\n");
|
||||
pfatal("NOT USING SOFT UPDATES, %s\n",
|
||||
"CANNOT RUN IN BACKGROUND");
|
||||
} else if ((mntp->f_flags & MNT_RDONLY) != 0) {
|
||||
bkgrdflag = 0;
|
||||
pwarn("MOUNTED READ-ONLY, CANNOT RUN IN BACKGROUND\n");
|
||||
} else {
|
||||
pfatal("MOUNTED READ-ONLY, CANNOT RUN IN BACKGROUND\n");
|
||||
} else if ((fsreadfd = open(filesys, O_RDONLY)) >= 0) {
|
||||
if (readsb(0) != 0) {
|
||||
if (sblock.fs_flags & FS_NEEDSFSCK) {
|
||||
bkgrdflag = 0;
|
||||
pfatal("UNEXPECTED INCONSISTENCY, %s\n",
|
||||
"CANNOT RUN IN BACKGROUND\n");
|
||||
}
|
||||
if ((sblock.fs_flags & FS_UNCLEAN) == 0 &&
|
||||
skipclean && preen) {
|
||||
/*
|
||||
* filesystem is clean;
|
||||
* skip snapshot and report it clean
|
||||
*/
|
||||
pwarn("FILESYSTEM CLEAN; %s\n",
|
||||
"SKIPPING CHECKS");
|
||||
goto clean;
|
||||
}
|
||||
}
|
||||
close(fsreadfd);
|
||||
}
|
||||
if (bkgrdflag) {
|
||||
snprintf(snapname, sizeof snapname, "%s/.fsck_snapshot",
|
||||
mntp->f_mntonname);
|
||||
args.fspec = snapname;
|
||||
@ -228,7 +251,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
if (errno == EEXIST && unlink(snapname) == 0)
|
||||
continue;
|
||||
bkgrdflag = 0;
|
||||
pwarn("CANNOT CREATE SNAPSHOT %s: %s\n",
|
||||
pfatal("CANNOT CREATE SNAPSHOT %s: %s\n",
|
||||
snapname, strerror(errno));
|
||||
break;
|
||||
}
|
||||
@ -243,6 +266,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
pfatal("CAN'T CHECK FILE SYSTEM.");
|
||||
return (0);
|
||||
case -1:
|
||||
clean:
|
||||
pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree +
|
||||
sblock.fs_frag * sblock.fs_cstotal.cs_nbfree);
|
||||
printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
|
||||
|
@ -377,7 +377,12 @@ check_maps(map1, map2, mapsize, startvalue, name, opcode, skip, limit)
|
||||
char buf[BUFSIZE];
|
||||
long i, j, k, l, m, n, size;
|
||||
int astart, aend, ustart, uend;
|
||||
void (*msg) __P((const char *fmt, ...));
|
||||
|
||||
if (bkgrdflag)
|
||||
msg = pfatal;
|
||||
else
|
||||
msg = pwarn;
|
||||
astart = ustart = aend = uend = -1;
|
||||
for (i = 0; i < mapsize; i++) {
|
||||
j = *map1++;
|
||||
@ -398,10 +403,10 @@ check_maps(map1, map2, mapsize, startvalue, name, opcode, skip, limit)
|
||||
continue;
|
||||
}
|
||||
if (astart == aend)
|
||||
pfatal("ALLOCATED %s %d MARKED FREE\n",
|
||||
(*msg)("ALLOCATED %s %d MARKED FREE\n",
|
||||
name, astart);
|
||||
else
|
||||
pfatal("%s %sS %d-%d MARKED FREE\n",
|
||||
(*msg)("%s %sS %d-%d MARKED FREE\n",
|
||||
"ALLOCATED", name, astart, aend);
|
||||
astart = aend = n;
|
||||
} else {
|
||||
@ -452,9 +457,9 @@ check_maps(map1, map2, mapsize, startvalue, name, opcode, skip, limit)
|
||||
}
|
||||
if (astart != -1)
|
||||
if (astart == aend)
|
||||
pfatal("ALLOCATED %s %d MARKED FREE\n", name, astart);
|
||||
(*msg)("ALLOCATED %s %d MARKED FREE\n", name, astart);
|
||||
else
|
||||
pfatal("ALLOCATED %sS %d-%d MARKED FREE\n",
|
||||
(*msg)("ALLOCATED %sS %d-%d MARKED FREE\n",
|
||||
name, astart, aend);
|
||||
if (ustart != -1) {
|
||||
size = uend - ustart + 1;
|
||||
|
@ -62,7 +62,6 @@ struct bufarea asblk;
|
||||
static void badsb __P((int listerr, char *s));
|
||||
static int calcsb __P((char *dev, int devfd, struct fs *fs));
|
||||
static struct disklabel *getdisklabel __P((char *s, int fd));
|
||||
static int readsb __P((int listerr));
|
||||
|
||||
/*
|
||||
* Read in a superblock finding an alternate if necessary.
|
||||
@ -74,8 +73,7 @@ setup(dev)
|
||||
char *dev;
|
||||
{
|
||||
long cg, size, asked, i, j;
|
||||
long skipclean, bmapsize;
|
||||
struct disklabel *lp;
|
||||
long bmapsize;
|
||||
off_t sizepb;
|
||||
struct stat statb;
|
||||
struct fs proto;
|
||||
@ -83,7 +81,6 @@ setup(dev)
|
||||
havesb = 0;
|
||||
fswritefd = -1;
|
||||
cursnapshot = 0;
|
||||
skipclean = fflag ? 0 : preen;
|
||||
if (stat(dev, &statb) < 0) {
|
||||
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
||||
if (bkgrdflag) {
|
||||
@ -160,18 +157,6 @@ setup(dev)
|
||||
}
|
||||
if (preen == 0)
|
||||
printf("\n");
|
||||
fsmodified = 0;
|
||||
lfdir = 0;
|
||||
initbarea(&sblk);
|
||||
initbarea(&asblk);
|
||||
sblk.b_un.b_buf = malloc(SBSIZE);
|
||||
asblk.b_un.b_buf = malloc(SBSIZE);
|
||||
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
|
||||
errx(EEXIT, "cannot allocate space for superblock");
|
||||
if ((lp = getdisklabel(NULL, fsreadfd)))
|
||||
dev_bsize = secsize = lp->d_secsize;
|
||||
else
|
||||
dev_bsize = secsize = DEV_BSIZE;
|
||||
/*
|
||||
* Read in the superblock, looking for alternates if necessary
|
||||
*/
|
||||
@ -200,7 +185,7 @@ setup(dev)
|
||||
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
||||
bflag = 0;
|
||||
}
|
||||
if (skipclean && sblock.fs_clean) {
|
||||
if (skipclean && preen && sblock.fs_clean) {
|
||||
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
|
||||
return (-1);
|
||||
}
|
||||
@ -372,7 +357,7 @@ badsb:
|
||||
/*
|
||||
* Read in the super block and its summary info.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
readsb(listerr)
|
||||
int listerr;
|
||||
{
|
||||
@ -490,6 +475,25 @@ badsb(listerr, s)
|
||||
pfatal("BAD SUPER BLOCK: %s\n", s);
|
||||
}
|
||||
|
||||
sblock_init()
|
||||
{
|
||||
struct disklabel *lp;
|
||||
|
||||
fswritefd = -1;
|
||||
fsmodified = 0;
|
||||
lfdir = 0;
|
||||
initbarea(&sblk);
|
||||
initbarea(&asblk);
|
||||
sblk.b_un.b_buf = malloc(SBSIZE);
|
||||
asblk.b_un.b_buf = malloc(SBSIZE);
|
||||
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
|
||||
errx(EEXIT, "cannot allocate space for superblock");
|
||||
if ((lp = getdisklabel(NULL, fsreadfd)))
|
||||
dev_bsize = secsize = lp->d_secsize;
|
||||
else
|
||||
dev_bsize = secsize = DEV_BSIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate a prototype superblock based on information in the disk label.
|
||||
* When done the cgsblock macro can be calculated and the fs_ncg field
|
||||
|
Loading…
x
Reference in New Issue
Block a user