typo
[unix-history] / usr / src / sbin / fsck / main.c
CommitLineData
76797561 1/*
fe32782c
KM
2 * Copyright (c) 1980, 1986 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
76797561
DF
16 */
17
18#ifndef lint
19char copyright[] =
fe32782c 20"@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\
76797561 21 All rights reserved.\n";
fe32782c 22#endif /* not lint */
76797561 23
fa95fc59 24#ifndef lint
38dde0cd 25static char sccsid[] = "@(#)main.c 5.23 (Berkeley) %G%";
fe32782c 26#endif /* not lint */
07670f7d 27
4d308541 28#include <sys/param.h>
72e5286b 29#include <ufs/dinode.h>
4d7f4685 30#include <ufs/fs.h>
7718c0e6 31#include <fstab.h>
38dde0cd 32#include <string.h>
c689da7b 33#include <ctype.h>
304178c6 34#include <stdio.h>
f7635e39 35#include "fsck.h"
6e884967 36
392fe950 37void catch(), catchquit(), voidquit();
3cfe4689 38int returntosingle;
7718c0e6
KM
39
40main(argc, argv)
41 int argc;
42 char *argv[];
43{
304178c6 44 char ch;
e23b720f 45 int ret, maxrun = 0;
304178c6
KM
46 extern int docheck(), checkfilesys();
47 extern char *optarg;
48 extern int optind;
7718c0e6
KM
49
50 sync();
304178c6
KM
51 while ((ch = getopt(argc, argv, "cdpnNyYb:l:m:")) != EOF) {
52 switch (ch) {
7718c0e6
KM
53 case 'p':
54 preen++;
55 break;
56
57 case 'b':
304178c6
KM
58 if (!isdigit(*optarg))
59 errexit("-b flag requires a number\n");
60 bflag = atoi(optarg);
7718c0e6
KM
61 printf("Alternate super block location: %d\n", bflag);
62 break;
63
d3e80ec3
KM
64 case 'c':
65 cvtflag++;
66 break;
67
7718c0e6
KM
68 case 'd':
69 debug++;
70 break;
71
5eeaeb24 72 case 'l':
304178c6 73 if (!isdigit(*optarg))
5eeaeb24 74 errexit("-l flag requires a number\n");
304178c6 75 maxrun = atoi(optarg);
5eeaeb24
MK
76 break;
77
c689da7b 78 case 'm':
304178c6 79 if (!isdigit(*optarg))
c689da7b 80 errexit("-m flag requires a mode\n");
304178c6 81 sscanf(optarg, "%o", &lfmode);
c689da7b
KM
82 if (lfmode &~ 07777)
83 errexit("bad mode to -m: %o\n", lfmode);
c689da7b
KM
84 printf("** lost+found creation mode %o\n", lfmode);
85 break;
86
569ec282 87 case 'n':
7718c0e6
KM
88 case 'N':
89 nflag++;
90 yflag = 0;
91 break;
92
569ec282 93 case 'y':
7718c0e6
KM
94 case 'Y':
95 yflag++;
96 nflag = 0;
97 break;
98
99 default:
304178c6 100 errexit("%c option?\n", ch);
7718c0e6
KM
101 }
102 }
304178c6
KM
103 argc -= optind;
104 argv += optind;
7718c0e6
KM
105 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
106 (void)signal(SIGINT, catch);
3cfe4689
MK
107 if (preen)
108 (void)signal(SIGQUIT, catchquit);
7718c0e6 109 if (argc) {
304178c6 110 while (argc-- > 0)
cfbff64d 111 checkfilesys(*argv++);
7718c0e6
KM
112 exit(0);
113 }
e23b720f 114 ret = checkfstab(preen, maxrun, docheck, checkfilesys);
3cfe4689
MK
115 if (returntosingle)
116 exit(2);
e23b720f 117 exit(ret);
7718c0e6
KM
118}
119
e23b720f
KM
120/*
121 * Determine whether a filesystem should be checked.
122 */
123docheck(fsp)
124 register struct fstab *fsp;
5eeaeb24
MK
125{
126
e23b720f
KM
127 if (strcmp(fsp->fs_vfstype, "ufs") ||
128 (strcmp(fsp->fs_type, FSTAB_RW) &&
129 strcmp(fsp->fs_type, FSTAB_RO)) ||
130 fsp->fs_passno == 0)
131 return (0);
132 return (1);
5eeaeb24
MK
133}
134
e23b720f
KM
135/*
136 * Check the specified filesystem.
137 */
138/* ARGSUSED */
139checkfilesys(filesys, mntpt, auxdata)
140 char *filesys, *mntpt;
141 long auxdata;
6e884967 142{
993a756c 143 daddr_t n_ffree, n_bfree;
d4233021 144 struct dups *dp;
1a02fd3a 145 struct zlncnt *zlnp;
6e884967 146
e23b720f 147 (void)signal(SIGQUIT, voidquit);
d2c95d76 148 devname = filesys;
5eeaeb24
MK
149 if (debug && preen)
150 pwarn("starting\n");
d2c95d76 151 if (setup(filesys) == 0) {
6e884967 152 if (preen)
d2c95d76 153 pfatal("CAN'T CHECK FILE SYSTEM.");
e23b720f 154 return (0);
6e884967 155 }
993a756c
KM
156 /*
157 * 1: scan inodes tallying blocks used
158 */
690f77ba
KM
159 if (preen == 0) {
160 printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
6e884967
KM
161 if (hotroot)
162 printf("** Root file system\n");
163 printf("** Phase 1 - Check Blocks and Sizes\n");
164 }
d2c95d76
BJ
165 pass1();
166
993a756c
KM
167 /*
168 * 1b: locate first references to duplicates, if any
169 */
62e6c152 170 if (duplist) {
d2c95d76
BJ
171 if (preen)
172 pfatal("INTERNAL ERROR: dups with -p");
173 printf("** Phase 1b - Rescan For More DUPS\n");
174 pass1b();
175 }
176
993a756c
KM
177 /*
178 * 2: traverse directories from root to mark all connected directories
179 */
d2c95d76
BJ
180 if (preen == 0)
181 printf("** Phase 2 - Check Pathnames\n");
182 pass2();
183
993a756c
KM
184 /*
185 * 3: scan inodes looking for disconnected directories
186 */
d2c95d76
BJ
187 if (preen == 0)
188 printf("** Phase 3 - Check Connectivity\n");
189 pass3();
190
993a756c
KM
191 /*
192 * 4: scan inodes looking for disconnected files; check reference counts
193 */
d2c95d76
BJ
194 if (preen == 0)
195 printf("** Phase 4 - Check Reference Counts\n");
196 pass4();
197
993a756c
KM
198 /*
199 * 5: check and repair resource counts in cylinder groups
200 */
d2c95d76
BJ
201 if (preen == 0)
202 printf("** Phase 5 - Check Cyl groups\n");
203 pass5();
204
993a756c
KM
205 /*
206 * print out summary statistics
207 */
208 n_ffree = sblock.fs_cstotal.cs_nffree;
209 n_bfree = sblock.fs_cstotal.cs_nbfree;
8755a38b
KM
210 pwarn("%d files, %d used, %d free ",
211 n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree);
212 printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
213 n_ffree, n_bfree, (float)(n_ffree * 100) / sblock.fs_dsize);
569ec282
KM
214 if (debug &&
215 (n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree))
993a756c
KM
216 printf("%d files missing\n", n_files);
217 if (debug) {
218 n_blks += sblock.fs_ncg *
219 (cgdmin(&sblock, 0) - cgsblock(&sblock, 0));
220 n_blks += cgsblock(&sblock, 0) - cgbase(&sblock, 0);
221 n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize);
569ec282 222 if (n_blks -= maxfsblock - (n_ffree + sblock.fs_frag * n_bfree))
993a756c 223 printf("%d blocks missing\n", n_blks);
d4233021
KM
224 if (duplist != NULL) {
225 printf("The following duplicate blocks remain:");
226 for (dp = duplist; dp; dp = dp->next)
227 printf(" %d,", dp->dup);
228 printf("\n");
229 }
1a02fd3a
KM
230 if (zlnhead != NULL) {
231 printf("The following zero link count inodes remain:");
232 for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
233 printf(" %d,", zlnp->zlncnt);
234 printf("\n");
235 }
d2c95d76 236 }
1a02fd3a
KM
237 zlnhead = (struct zlncnt *)0;
238 duplist = (struct dups *)0;
57117c0f 239 inocleanup();
569ec282 240 if (fsmodified) {
1a724405 241 (void)time(&sblock.fs_time);
d2c95d76
BJ
242 sbdirty();
243 }
244 ckfini();
245 free(blockmap);
d2c95d76 246 free(statemap);
1a724405 247 free((char *)lncntp);
569ec282 248 if (!fsmodified)
e23b720f 249 return (0);
addfa1aa
BJ
250 if (!preen) {
251 printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
252 if (hotroot)
253 printf("\n***** REBOOT UNIX *****\n");
254 }
255 if (hotroot) {
256 sync();
e23b720f 257 return (4);
7718c0e6 258 }
7718c0e6
KM
259 return (0);
260}