* Copyright (c) 1990 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* Neither the name of the University nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)preen.c 5.5 (Berkeley) 7/20/90";
char *rawname(), *unrawname(), *blockcheck();
struct part
*next
; /* forward link of partitions on disk */
char *name
; /* device name */
char *fsname
; /* mounted filesystem name */
long auxdata
; /* auxillary data for application */
} *badlist
, **badnext
= &badlist
;
char *name
; /* disk base name */
struct disk
*next
; /* forward link for list of disks */
struct part
*part
; /* head of list of partitions on disk */
int pid
; /* If != 0, pid of proc working on */
checkfstab(preen
, maxrun
, docheck
, chkit
)
int (*docheck
)(), (*chkit
)();
register struct fstab
*fsp
;
register struct disk
*dk
, *nextdisk
;
register struct part
*pt
;
int ret
, pid
, retcode
, passno
, sumstatus
, status
;
for (passno
= 1; passno
<= 2; passno
++) {
fprintf(stderr
, "Can't open checklist file: %s\n",
while ((fsp
= getfsent()) != 0) {
if ((auxdata
= (*docheck
)(fsp
)) == 0)
if (preen
== 0 || passno
== 1 && fsp
->fs_passno
== 1) {
if (name
= blockcheck(fsp
->fs_spec
)) {
if (sumstatus
= (*chkit
)(name
,
} else if (passno
== 2 && fsp
->fs_passno
> 1) {
if ((name
= blockcheck(fsp
->fs_spec
)) == NULL
) {
fprintf(stderr
, "BAD DISK NAME %s\n",
addpart(name
, fsp
->fs_file
, auxdata
);
for (passno
= 0; passno
< maxrun
; ++passno
) {
while (ret
= startdisk(nextdisk
, chkit
) && nrun
> 0)
nextdisk
= nextdisk
->next
;
while ((pid
= wait(&status
)) != -1) {
for (dk
= disks
; dk
; dk
= dk
->next
)
printf("Unknown pid %d\n", pid
);
retcode
= WEXITSTATUS(status
);
if (WIFSIGNALED(status
)) {
printf("%s (%s): EXITED WITH SIGNAL %d\n",
dk
->part
->name
, dk
->part
->fsname
,
badnext
= &dk
->part
->next
;
dk
->part
= dk
->part
->next
;
dk
->part
= dk
->part
->next
;
while (ret
= startdisk(dk
, chkit
) &&
} else if (nrun
< maxrun
&& nrun
< ndisks
) {
if ((nextdisk
= nextdisk
->next
) == NULL
)
if (nextdisk
->part
!= NULL
&&
while (ret
= startdisk(nextdisk
, chkit
) &&
fprintf(stderr
, "THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t",
badlist
->next
? "S" : "", "UNEXPECTED INCONSISTENCY:");
for (pt
= badlist
; pt
; pt
= pt
->next
)
fprintf(stderr
, "%s (%s)%s", pt
->name
, pt
->fsname
,
register struct disk
*dk
, **dkp
;
for (p
= name
+ strlen(name
) - 1; p
>= name
; --p
)
for (dk
= disks
, dkp
= &disks
; dk
; dkp
= &dk
->next
, dk
= dk
->next
) {
if (strncmp(dk
->name
, name
, len
) == 0 &&
if ((*dkp
= (struct disk
*)malloc(sizeof(struct disk
))) == NULL
) {
fprintf(stderr
, "out of memory");
if ((dk
->name
= malloc(len
+ 1)) == NULL
) {
fprintf(stderr
, "out of memory");
(void)strncpy(dk
->name
, name
, len
);
addpart(name
, fsname
, auxdata
)
struct disk
*dk
= finddisk(name
);
register struct part
*pt
, **ppt
= &dk
->part
;
for (pt
= dk
->part
; pt
; ppt
= &pt
->next
, pt
= pt
->next
)
if (strcmp(pt
->name
, name
) == 0) {
printf("%s in fstab more than once!\n", name
);
if ((*ppt
= (struct part
*)malloc(sizeof(struct part
))) == NULL
) {
fprintf(stderr
, "out of memory");
if ((pt
->name
= malloc(strlen(name
) + 1)) == NULL
) {
fprintf(stderr
, "out of memory");
(void)strcpy(pt
->name
, name
);
if ((pt
->fsname
= malloc(strlen(fsname
) + 1)) == NULL
) {
fprintf(stderr
, "out of memory");
(void)strcpy(pt
->fsname
, fsname
);
register struct disk
*dk
;
register struct part
*pt
= dk
->part
;
exit((*checkit
)(pt
->name
, pt
->fsname
, pt
->auxdata
));
struct stat stslash
, stblock
, stchar
;
if (stat("/", &stslash
) < 0) {
printf("Can't stat root\n");
if (stat(name
, &stblock
) < 0) {
printf("Can't stat %s\n", name
);
if ((stblock
.st_mode
& S_IFMT
) == S_IFBLK
) {
if (stslash
.st_dev
== stblock
.st_rdev
)
if (stat(raw
, &stchar
) < 0) {
printf("Can't stat %s\n", raw
);
if ((stchar
.st_mode
& S_IFMT
) == S_IFCHR
) {
printf("%s is not a character device\n", raw
);
} else if ((stblock
.st_mode
& S_IFMT
) == S_IFCHR
&& !retried
) {
printf("Can't make sense out of name %s\n", name
);
if ((dp
= rindex(name
, '/')) == 0)
if (stat(name
, &stb
) < 0)
if ((stb
.st_mode
& S_IFMT
) != S_IFCHR
)
(void)strcpy(dp
+ 1, dp
+ 2);
if ((dp
= rindex(name
, '/')) == 0)
(void)strcpy(rawbuf
, name
);
(void)strcat(rawbuf
, "/r");
(void)strcat(rawbuf
, dp
+ 1);