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
7d6505e64e
commit
38375c40b8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=75557
@ -203,7 +203,6 @@ char snapname[BUFSIZ]; /* when doing snapshots, the name of the file */
|
|||||||
char *cdevname; /* name of device being checked */
|
char *cdevname; /* name of device being checked */
|
||||||
long dev_bsize; /* computed value of DEV_BSIZE */
|
long dev_bsize; /* computed value of DEV_BSIZE */
|
||||||
long secsize; /* actual disk sector size */
|
long secsize; /* actual disk sector size */
|
||||||
char fflag; /* force check, ignore clean flag */
|
|
||||||
char nflag; /* assume a no response */
|
char nflag; /* assume a no response */
|
||||||
char yflag; /* assume a yes response */
|
char yflag; /* assume a yes response */
|
||||||
int bkgrdflag; /* use a snapshot to run on an active system */
|
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 pinode __P((ino_t ino));
|
||||||
void propagate __P((void));
|
void propagate __P((void));
|
||||||
void pwarn __P((const char *fmt, ...));
|
void pwarn __P((const char *fmt, ...));
|
||||||
|
int readsb __P((int listerr));
|
||||||
int reply __P((char *question));
|
int reply __P((char *question));
|
||||||
void rwerror __P((char *mesg, ufs_daddr_t blk));
|
void rwerror __P((char *mesg, ufs_daddr_t blk));
|
||||||
void setinodebuf __P((ino_t));
|
void setinodebuf __P((ino_t));
|
||||||
|
@ -321,7 +321,8 @@ ckfini(markclean)
|
|||||||
errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt);
|
errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt);
|
||||||
pbp = pdirbp = (struct bufarea *)0;
|
pbp = pdirbp = (struct bufarea *)0;
|
||||||
if (cursnapshot == 0 && sblock.fs_clean != markclean) {
|
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();
|
sbdirty();
|
||||||
ofsmodified = fsmodified;
|
ofsmodified = fsmodified;
|
||||||
flush(fswritefd, &sblk);
|
flush(fswritefd, &sblk);
|
||||||
@ -336,7 +337,7 @@ ckfini(markclean)
|
|||||||
printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
|
printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
|
||||||
rerun = 1;
|
rerun = 1;
|
||||||
}
|
}
|
||||||
if (debug)
|
if (debug && totalreads > 0)
|
||||||
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
||||||
totalreads, (int)(diskreads * 100 / totalreads));
|
totalreads, (int)(diskreads * 100 / totalreads));
|
||||||
(void)close(fsreadfd);
|
(void)close(fsreadfd);
|
||||||
@ -649,6 +650,19 @@ pfatal(fmt, va_alist)
|
|||||||
if (usedsoftdep)
|
if (usedsoftdep)
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"\nUNEXPECTED SOFT UPDATE INCONSISTENCY\n");
|
"\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;
|
return;
|
||||||
}
|
}
|
||||||
if (cdevname == NULL)
|
if (cdevname == NULL)
|
||||||
@ -658,6 +672,16 @@ pfatal(fmt, va_alist)
|
|||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
||||||
cdevname, usedsoftdep ? " SOFT UPDATE " : " ");
|
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);
|
ckfini(0);
|
||||||
exit(EEXIT);
|
exit(EEXIT);
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@ -199,6 +200,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
cdevname = filesys;
|
cdevname = filesys;
|
||||||
if (debug && preen)
|
if (debug && preen)
|
||||||
pwarn("starting\n");
|
pwarn("starting\n");
|
||||||
|
sblock_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are to do a background check:
|
* If we are to do a background check:
|
||||||
@ -211,14 +213,35 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
if (bkgrdflag) {
|
if (bkgrdflag) {
|
||||||
if (mntp == NULL) {
|
if (mntp == NULL) {
|
||||||
bkgrdflag = 0;
|
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) {
|
} else if ((mntp->f_flags & MNT_SOFTDEP) == 0) {
|
||||||
bkgrdflag = 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) {
|
} else if ((mntp->f_flags & MNT_RDONLY) != 0) {
|
||||||
bkgrdflag = 0;
|
bkgrdflag = 0;
|
||||||
pwarn("MOUNTED READ-ONLY, CANNOT RUN IN BACKGROUND\n");
|
pfatal("MOUNTED READ-ONLY, CANNOT RUN IN BACKGROUND\n");
|
||||||
} else {
|
} 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",
|
snprintf(snapname, sizeof snapname, "%s/.fsck_snapshot",
|
||||||
mntp->f_mntonname);
|
mntp->f_mntonname);
|
||||||
args.fspec = snapname;
|
args.fspec = snapname;
|
||||||
@ -228,7 +251,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
if (errno == EEXIST && unlink(snapname) == 0)
|
if (errno == EEXIST && unlink(snapname) == 0)
|
||||||
continue;
|
continue;
|
||||||
bkgrdflag = 0;
|
bkgrdflag = 0;
|
||||||
pwarn("CANNOT CREATE SNAPSHOT %s: %s\n",
|
pfatal("CANNOT CREATE SNAPSHOT %s: %s\n",
|
||||||
snapname, strerror(errno));
|
snapname, strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -243,6 +266,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
pfatal("CAN'T CHECK FILE SYSTEM.");
|
pfatal("CAN'T CHECK FILE SYSTEM.");
|
||||||
return (0);
|
return (0);
|
||||||
case -1:
|
case -1:
|
||||||
|
clean:
|
||||||
pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree +
|
pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree +
|
||||||
sblock.fs_frag * sblock.fs_cstotal.cs_nbfree);
|
sblock.fs_frag * sblock.fs_cstotal.cs_nbfree);
|
||||||
printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
|
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];
|
char buf[BUFSIZE];
|
||||||
long i, j, k, l, m, n, size;
|
long i, j, k, l, m, n, size;
|
||||||
int astart, aend, ustart, uend;
|
int astart, aend, ustart, uend;
|
||||||
|
void (*msg) __P((const char *fmt, ...));
|
||||||
|
|
||||||
|
if (bkgrdflag)
|
||||||
|
msg = pfatal;
|
||||||
|
else
|
||||||
|
msg = pwarn;
|
||||||
astart = ustart = aend = uend = -1;
|
astart = ustart = aend = uend = -1;
|
||||||
for (i = 0; i < mapsize; i++) {
|
for (i = 0; i < mapsize; i++) {
|
||||||
j = *map1++;
|
j = *map1++;
|
||||||
@ -398,10 +403,10 @@ check_maps(map1, map2, mapsize, startvalue, name, opcode, skip, limit)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (astart == aend)
|
if (astart == aend)
|
||||||
pfatal("ALLOCATED %s %d MARKED FREE\n",
|
(*msg)("ALLOCATED %s %d MARKED FREE\n",
|
||||||
name, astart);
|
name, astart);
|
||||||
else
|
else
|
||||||
pfatal("%s %sS %d-%d MARKED FREE\n",
|
(*msg)("%s %sS %d-%d MARKED FREE\n",
|
||||||
"ALLOCATED", name, astart, aend);
|
"ALLOCATED", name, astart, aend);
|
||||||
astart = aend = n;
|
astart = aend = n;
|
||||||
} else {
|
} else {
|
||||||
@ -452,9 +457,9 @@ check_maps(map1, map2, mapsize, startvalue, name, opcode, skip, limit)
|
|||||||
}
|
}
|
||||||
if (astart != -1)
|
if (astart != -1)
|
||||||
if (astart == aend)
|
if (astart == aend)
|
||||||
pfatal("ALLOCATED %s %d MARKED FREE\n", name, astart);
|
(*msg)("ALLOCATED %s %d MARKED FREE\n", name, astart);
|
||||||
else
|
else
|
||||||
pfatal("ALLOCATED %sS %d-%d MARKED FREE\n",
|
(*msg)("ALLOCATED %sS %d-%d MARKED FREE\n",
|
||||||
name, astart, aend);
|
name, astart, aend);
|
||||||
if (ustart != -1) {
|
if (ustart != -1) {
|
||||||
size = uend - ustart + 1;
|
size = uend - ustart + 1;
|
||||||
|
@ -62,7 +62,6 @@ struct bufarea asblk;
|
|||||||
static void badsb __P((int listerr, char *s));
|
static void badsb __P((int listerr, char *s));
|
||||||
static int calcsb __P((char *dev, int devfd, struct fs *fs));
|
static int calcsb __P((char *dev, int devfd, struct fs *fs));
|
||||||
static struct disklabel *getdisklabel __P((char *s, int fd));
|
static struct disklabel *getdisklabel __P((char *s, int fd));
|
||||||
static int readsb __P((int listerr));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read in a superblock finding an alternate if necessary.
|
* Read in a superblock finding an alternate if necessary.
|
||||||
@ -74,8 +73,7 @@ setup(dev)
|
|||||||
char *dev;
|
char *dev;
|
||||||
{
|
{
|
||||||
long cg, size, asked, i, j;
|
long cg, size, asked, i, j;
|
||||||
long skipclean, bmapsize;
|
long bmapsize;
|
||||||
struct disklabel *lp;
|
|
||||||
off_t sizepb;
|
off_t sizepb;
|
||||||
struct stat statb;
|
struct stat statb;
|
||||||
struct fs proto;
|
struct fs proto;
|
||||||
@ -83,7 +81,6 @@ setup(dev)
|
|||||||
havesb = 0;
|
havesb = 0;
|
||||||
fswritefd = -1;
|
fswritefd = -1;
|
||||||
cursnapshot = 0;
|
cursnapshot = 0;
|
||||||
skipclean = fflag ? 0 : preen;
|
|
||||||
if (stat(dev, &statb) < 0) {
|
if (stat(dev, &statb) < 0) {
|
||||||
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
||||||
if (bkgrdflag) {
|
if (bkgrdflag) {
|
||||||
@ -160,18 +157,6 @@ setup(dev)
|
|||||||
}
|
}
|
||||||
if (preen == 0)
|
if (preen == 0)
|
||||||
printf("\n");
|
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
|
* Read in the superblock, looking for alternates if necessary
|
||||||
*/
|
*/
|
||||||
@ -200,7 +185,7 @@ setup(dev)
|
|||||||
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
||||||
bflag = 0;
|
bflag = 0;
|
||||||
}
|
}
|
||||||
if (skipclean && sblock.fs_clean) {
|
if (skipclean && preen && sblock.fs_clean) {
|
||||||
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
|
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
@ -372,7 +357,7 @@ setup(dev)
|
|||||||
/*
|
/*
|
||||||
* Read in the super block and its summary info.
|
* Read in the super block and its summary info.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
readsb(listerr)
|
readsb(listerr)
|
||||||
int listerr;
|
int listerr;
|
||||||
{
|
{
|
||||||
@ -490,6 +475,25 @@ badsb(listerr, s)
|
|||||||
pfatal("BAD SUPER BLOCK: %s\n", 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.
|
* Calculate a prototype superblock based on information in the disk label.
|
||||||
* When done the cgsblock macro can be calculated and the fs_ncg field
|
* When done the cgsblock macro can be calculated and the fs_ncg field
|
||||||
|
Loading…
Reference in New Issue
Block a user