Changeset View
Changeset View
Standalone View
Standalone View
sbin/fsck_ffs/main.c
Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
#include "fsck.h" | #include "fsck.h" | ||||
static int restarts; | static int restarts; | ||||
static void usage(void) __dead2; | static void usage(void) __dead2; | ||||
static intmax_t argtoimax(int flag, const char *req, const char *str, int base); | static intmax_t argtoimax(int flag, const char *req, const char *str, int base); | ||||
static int checkfilesys(char *filesys); | static int checkfilesys(char *filesys); | ||||
static int setup_bkgrdchk(struct statfs *mntp, int sbrdfailed, char **filesys); | static int setup_bkgrdchk(struct statfs *mntp, int sbrdfailed, char **filesys); | ||||
static int chkdoreload(struct statfs *mntp); | |||||
static struct statfs *getmntpt(const char *); | |||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
int ch; | int ch; | ||||
struct rlimit rlimit; | struct rlimit rlimit; | ||||
struct itimerval itimerval; | struct itimerval itimerval; | ||||
int fsret; | int fsret; | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | checkfilesys(char *filesys) | ||||
cdevname = filesys; | cdevname = filesys; | ||||
if (debug && ckclean) | if (debug && ckclean) | ||||
pwarn("starting\n"); | pwarn("starting\n"); | ||||
/* | /* | ||||
* Make best effort to get the disk name. Check first to see | * Make best effort to get the disk name. Check first to see | ||||
* if it is listed among the mounted file systems. Failing that | * if it is listed among the mounted file systems. Failing that | ||||
* check to see if it is listed in /etc/fstab. | * check to see if it is listed in /etc/fstab. | ||||
*/ | */ | ||||
mntp = getmntpt(filesys); | mntp = getmntpoint(filesys); | ||||
if (mntp != NULL) | if (mntp != NULL) | ||||
filesys = mntp->f_mntfromname; | filesys = mntp->f_mntfromname; | ||||
else | else | ||||
filesys = blockcheck(filesys); | filesys = blockcheck(filesys); | ||||
/* | /* | ||||
* If -F flag specified, check to see whether a background check | * If -F flag specified, check to see whether a background check | ||||
* is possible and needed. If possible and needed, exit with | * is possible and needed. If possible and needed, exit with | ||||
* status zero. Otherwise exit with status non-zero. A non-zero | * status zero. Otherwise exit with status non-zero. A non-zero | ||||
Show All 36 Lines | if ((sblock.fs_flags & FS_GJOURNAL) != 0) { | ||||
if (sblock.fs_clean == 1) { | if (sblock.fs_clean == 1) { | ||||
pwarn("FILE SYSTEM CLEAN; SKIPPING CHECKS\n"); | pwarn("FILE SYSTEM CLEAN; SKIPPING CHECKS\n"); | ||||
exit(0); | exit(0); | ||||
} | } | ||||
if ((sblock.fs_flags & | if ((sblock.fs_flags & | ||||
(FS_UNCLEAN | FS_NEEDSFSCK)) == 0) { | (FS_UNCLEAN | FS_NEEDSFSCK)) == 0) { | ||||
bufinit(); | bufinit(); | ||||
gjournal_check(filesys); | gjournal_check(filesys); | ||||
if (chkdoreload(mntp) == 0) | if (chkdoreload(mntp, pwarn) == 0) | ||||
exit(0); | exit(0); | ||||
exit(4); | exit(4); | ||||
} else { | } else { | ||||
pfatal("FULL FSCK NEEDED, CANNOT RUN FAST " | pfatal("FULL FSCK NEEDED, CANNOT RUN FAST " | ||||
"FSCK\n"); | "FSCK\n"); | ||||
} | } | ||||
} | } | ||||
close(fswritefd); | close(fswritefd); | ||||
Show All 29 Lines | checkfilesys(char *filesys) | ||||
/* | /* | ||||
* Determine if we can and should do journal recovery. | * Determine if we can and should do journal recovery. | ||||
*/ | */ | ||||
if ((sblock.fs_flags & FS_SUJ) == FS_SUJ) { | if ((sblock.fs_flags & FS_SUJ) == FS_SUJ) { | ||||
if ((sblock.fs_flags & FS_NEEDSFSCK) != FS_NEEDSFSCK && skipclean) { | if ((sblock.fs_flags & FS_NEEDSFSCK) != FS_NEEDSFSCK && skipclean) { | ||||
sujrecovery = 1; | sujrecovery = 1; | ||||
if (suj_check(filesys) == 0) { | if (suj_check(filesys) == 0) { | ||||
printf("\n***** FILE SYSTEM MARKED CLEAN *****\n"); | printf("\n***** FILE SYSTEM MARKED CLEAN *****\n"); | ||||
if (chkdoreload(mntp) == 0) | if (chkdoreload(mntp, pwarn) == 0) | ||||
exit(0); | exit(0); | ||||
exit(4); | exit(4); | ||||
} | } | ||||
sujrecovery = 0; | sujrecovery = 0; | ||||
printf("** Skipping journal, falling through to full fsck\n\n"); | printf("** Skipping journal, falling through to full fsck\n\n"); | ||||
} | } | ||||
if (fswritefd != -1) { | if (fswritefd != -1) { | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 187 Lines • ▼ Show 20 Lines | #endif /* notyet */ | ||||
if (fsmodified && !preen) | if (fsmodified && !preen) | ||||
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); | printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); | ||||
if (rerun) { | if (rerun) { | ||||
if (wantrestart && (restarts++ < 10) && | if (wantrestart && (restarts++ < 10) && | ||||
(preen || reply("RESTART"))) | (preen || reply("RESTART"))) | ||||
return (ERESTART); | return (ERESTART); | ||||
printf("\n***** PLEASE RERUN FSCK *****\n"); | printf("\n***** PLEASE RERUN FSCK *****\n"); | ||||
} | } | ||||
if (chkdoreload(mntp) != 0) { | if (chkdoreload(mntp, pwarn) != 0) { | ||||
if (!fsmodified) | if (!fsmodified) | ||||
return (0); | return (0); | ||||
if (!preen) | if (!preen) | ||||
printf("\n***** REBOOT NOW *****\n"); | printf("\n***** REBOOT NOW *****\n"); | ||||
sync(); | sync(); | ||||
return (4); | return (4); | ||||
} | } | ||||
return (rerun ? ERERUN : 0); | return (rerun ? ERERUN : 0); | ||||
▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | setup_bkgrdchk(struct statfs *mntp, int sbreadfailed, char **filesys) | ||||
} | } | ||||
free(sblock.fs_csp); | free(sblock.fs_csp); | ||||
free(sblock.fs_si); | free(sblock.fs_si); | ||||
havesb = 0; | havesb = 0; | ||||
*filesys = snapname; | *filesys = snapname; | ||||
cmd.version = FFS_CMD_VERSION; | cmd.version = FFS_CMD_VERSION; | ||||
cmd.handle = fsreadfd; | cmd.handle = fsreadfd; | ||||
return (1); | return (1); | ||||
} | |||||
static int | |||||
chkdoreload(struct statfs *mntp) | |||||
{ | |||||
struct iovec *iov; | |||||
int iovlen; | |||||
char errmsg[255]; | |||||
if (mntp == NULL) | |||||
return (0); | |||||
iov = NULL; | |||||
iovlen = 0; | |||||
errmsg[0] = '\0'; | |||||
/* | |||||
* We modified a mounted file system. Do a mount update on | |||||
* it unless it is read-write, so we can continue using it | |||||
* as safely as possible. | |||||
*/ | |||||
if (mntp->f_flags & MNT_RDONLY) { | |||||
build_iovec(&iov, &iovlen, "fstype", "ffs", 4); | |||||
build_iovec(&iov, &iovlen, "from", mntp->f_mntfromname, | |||||
(size_t)-1); | |||||
build_iovec(&iov, &iovlen, "fspath", mntp->f_mntonname, | |||||
(size_t)-1); | |||||
build_iovec(&iov, &iovlen, "errmsg", errmsg, | |||||
sizeof(errmsg)); | |||||
build_iovec(&iov, &iovlen, "update", NULL, 0); | |||||
build_iovec(&iov, &iovlen, "reload", NULL, 0); | |||||
/* | |||||
* XX: We need the following line until we clean up | |||||
* nmount parsing of root mounts and NFS root mounts. | |||||
*/ | |||||
build_iovec(&iov, &iovlen, "ro", NULL, 0); | |||||
if (nmount(iov, iovlen, mntp->f_flags) == 0) { | |||||
return (0); | |||||
} | |||||
pwarn("mount reload of '%s' failed: %s %s\n\n", | |||||
mntp->f_mntonname, strerror(errno), errmsg); | |||||
return (1); | |||||
} | |||||
return (0); | |||||
} | |||||
/* | |||||
* Get the mount point information for name. | |||||
*/ | |||||
static struct statfs * | |||||
getmntpt(const char *name) | |||||
{ | |||||
struct stat devstat, mntdevstat; | |||||
char device[sizeof(_PATH_DEV) - 1 + MNAMELEN]; | |||||
char *ddevname; | |||||
struct statfs *mntbuf, *statfsp; | |||||
int i, mntsize, isdev; | |||||
if (stat(name, &devstat) != 0) | |||||
return (NULL); | |||||
if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode)) | |||||
isdev = 1; | |||||
else | |||||
isdev = 0; | |||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); | |||||
for (i = 0; i < mntsize; i++) { | |||||
statfsp = &mntbuf[i]; | |||||
ddevname = statfsp->f_mntfromname; | |||||
if (*ddevname != '/') { | |||||
if (strlen(_PATH_DEV) + strlen(ddevname) + 1 > | |||||
sizeof(statfsp->f_mntfromname)) | |||||
continue; | |||||
strcpy(device, _PATH_DEV); | |||||
strcat(device, ddevname); | |||||
strcpy(statfsp->f_mntfromname, device); | |||||
} | |||||
if (isdev == 0) { | |||||
if (strcmp(name, statfsp->f_mntonname)) | |||||
continue; | |||||
return (statfsp); | |||||
} | |||||
if (stat(ddevname, &mntdevstat) == 0 && | |||||
mntdevstat.st_rdev == devstat.st_rdev) | |||||
return (statfsp); | |||||
} | |||||
statfsp = NULL; | |||||
return (statfsp); | |||||
} | } | ||||
static void | static void | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
(void) fprintf(stderr, | (void) fprintf(stderr, | ||||
"usage: %s [-BCdEFfnpRrSyZ] [-b block] [-c level] [-m mode] filesystem ...\n", | "usage: %s [-BCdEFfnpRrSyZ] [-b block] [-c level] [-m mode] filesystem ...\n", | ||||
getprogname()); | getprogname()); | ||||
Show All 14 Lines |