aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2013-12-30 01:16:08 +0000
committerScott Long <scottl@FreeBSD.org>2013-12-30 01:16:08 +0000
commit7703a6ff27b154f2048c96fe0dc2f0297188768a (patch)
tree3f5b4ba557bcb5004e79798d6d96972dfe7d2e45
parenta48e1f224c561c156d130496638b5defbb3081d0 (diff)
downloadsrc-7703a6ff27b154f2048c96fe0dc2f0297188768a.tar.gz
src-7703a6ff27b154f2048c96fe0dc2f0297188768a.zip
Add the -R option to allow fsck_ffs to restart itself when too many critical
errors have been detected in a particular run. Clean up the global state variables so that a restart can happen correctly. Separate the global variables in fsck_ffs and fsdb to their own file. This fixes header sharing with fscd. Correctly initialize, static-ize, and remove global variables as needed in dir.c. This fixes a problem with lost+found directories that was causing a segfault. Correctly initialize, static-ize, and remove global variables as needed in suj.c. Initialize the suj globals before allocating the disk object, not after. Also ensure that 'preen' mode doesn't conflict with 'restart' mode Submitted by: scottl, max Reviewed by: max, mckusick (earlier version) Obtained from: Netflix MFC after: 3 days
Notes
Notes: svn path=/head/; revision=260068
-rw-r--r--sbin/fsck_ffs/Makefile3
-rw-r--r--sbin/fsck_ffs/dir.c11
-rw-r--r--sbin/fsck_ffs/fsck.h136
-rw-r--r--sbin/fsck_ffs/fsck_ffs.87
-rw-r--r--sbin/fsck_ffs/fsutil.c19
-rw-r--r--sbin/fsck_ffs/main.c35
-rw-r--r--sbin/fsck_ffs/pass1.c5
-rw-r--r--sbin/fsck_ffs/pass1b.c8
-rw-r--r--sbin/fsck_ffs/suj.c56
-rw-r--r--sbin/fsck_ffs/utilities.c11
10 files changed, 183 insertions, 108 deletions
diff --git a/sbin/fsck_ffs/Makefile b/sbin/fsck_ffs/Makefile
index db2930bea627..028a4867c85d 100644
--- a/sbin/fsck_ffs/Makefile
+++ b/sbin/fsck_ffs/Makefile
@@ -7,7 +7,8 @@ LINKS+= ${BINDIR}/fsck_ffs ${BINDIR}/fsck_4.2bsd
MAN= fsck_ffs.8
MLINKS= fsck_ffs.8 fsck_ufs.8 fsck_ffs.8 fsck_4.2bsd.8
SRCS= dir.c ea.c fsutil.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c \
- pass4.c pass5.c setup.c suj.c utilities.c gjournal.c getmntopts.c
+ pass4.c pass5.c setup.c suj.c utilities.c gjournal.c getmntopts.c \
+ globs.c
DPADD= ${LIBUFS}
LDADD= -lufs
WARNS?= 2
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c
index 965e3e398215..7640f704b76a 100644
--- a/sbin/fsck_ffs/dir.c
+++ b/sbin/fsck_ffs/dir.c
@@ -48,20 +48,14 @@ __FBSDID("$FreeBSD$");
#include "fsck.h"
-const char *lfname = "lost+found";
-int lfmode = 0700;
-struct dirtemplate emptydir = {
+static struct dirtemplate emptydir = {
0, DIRBLKSIZ, DT_UNKNOWN, 0, "",
0, 0, DT_UNKNOWN, 0, ""
};
-struct dirtemplate dirhead = {
+static struct dirtemplate dirhead = {
0, 12, DT_DIR, 1, ".",
0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
};
-struct odirtemplate odirhead = {
- 0, 12, 1, ".",
- 0, DIRBLKSIZ - 12, 2, ".."
-};
static int chgino(struct inodesc *);
static int dircheck(struct inodesc *, struct direct *);
@@ -133,6 +127,7 @@ dirscan(struct inodesc *idesc)
(size_t)dsize);
dirty(bp);
sbdirty();
+ rerun = 1;
}
if (n & STOP)
return (n);
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index 632d45433da2..a7b5961a574d 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -192,15 +192,15 @@ struct bufarea {
"Inode Block", \
"Directory Contents", \
"User Data" }
-long readcnt[BT_NUMBUFTYPES];
-long totalreadcnt[BT_NUMBUFTYPES];
-struct timespec readtime[BT_NUMBUFTYPES];
-struct timespec totalreadtime[BT_NUMBUFTYPES];
-struct timespec startprog;
+extern long readcnt[BT_NUMBUFTYPES];
+extern long totalreadcnt[BT_NUMBUFTYPES];
+extern struct timespec readtime[BT_NUMBUFTYPES];
+extern struct timespec totalreadtime[BT_NUMBUFTYPES];
+extern struct timespec startprog;
-struct bufarea sblk; /* file system superblock */
-struct bufarea *pdirbp; /* current directory contents */
-struct bufarea *pbp; /* current inode block */
+extern struct bufarea sblk; /* file system superblock */
+extern struct bufarea *pdirbp; /* current directory contents */
+extern struct bufarea *pbp; /* current inode block */
#define dirty(bp) do { \
if (fswritefd < 0) \
@@ -219,7 +219,7 @@ struct bufarea *pbp; /* current inode block */
#define sblock (*sblk.b_un.b_fs)
enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE};
-ino_t cursnapshot;
+extern ino_t cursnapshot;
struct inodesc {
enum fixstate id_fix; /* policy on fixing errors */
@@ -282,63 +282,64 @@ struct inoinfo {
u_int i_numblks; /* size of block array in bytes */
ufs2_daddr_t i_blks[1]; /* actually longer */
} **inphead, **inpsort;
-long numdirs, dirhash, listmax, inplast;
-long countdirs; /* number of directories we actually found */
+extern long numdirs, dirhash, listmax, inplast;
+extern long countdirs; /* number of directories we actually found */
#define MIBSIZE 3 /* size of fsck sysctl MIBs */
-int adjrefcnt[MIBSIZE]; /* MIB command to adjust inode reference cnt */
-int adjblkcnt[MIBSIZE]; /* MIB command to adjust inode block count */
-int adjndir[MIBSIZE]; /* MIB command to adjust number of directories */
-int adjnbfree[MIBSIZE]; /* MIB command to adjust number of free blocks */
-int adjnifree[MIBSIZE]; /* MIB command to adjust number of free inodes */
-int adjnffree[MIBSIZE]; /* MIB command to adjust number of free frags */
-int adjnumclusters[MIBSIZE]; /* MIB command to adjust number of free clusters */
-int freefiles[MIBSIZE]; /* MIB command to free a set of files */
-int freedirs[MIBSIZE]; /* MIB command to free a set of directories */
-int freeblks[MIBSIZE]; /* MIB command to free a set of data blocks */
-struct fsck_cmd cmd; /* sysctl file system update commands */
-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 */
-u_int real_dev_bsize; /* actual disk sector size, not overriden */
-char nflag; /* assume a no response */
-char yflag; /* assume a yes response */
-int bkgrdflag; /* use a snapshot to run on an active system */
-int bflag; /* location of alternate super block */
-int debug; /* output debugging info */
-int Eflag; /* delete empty data blocks */
-int Zflag; /* zero empty data blocks */
-int inoopt; /* trim out unused inodes */
-char ckclean; /* only do work if not cleanly unmounted */
-int cvtlevel; /* convert to newer file system format */
-int bkgrdcheck; /* determine if background check is possible */
-int bkgrdsumadj; /* whether the kernel have ability to adjust superblock summary */
-char usedsoftdep; /* just fix soft dependency inconsistencies */
-char preen; /* just fix normal inconsistencies */
-char rerun; /* rerun fsck. Only used in non-preen mode */
-int returntosingle; /* 1 => return to single user mode on exit */
-char resolved; /* cleared if unresolved changes => not clean */
-char havesb; /* superblock has been read */
-char skipclean; /* skip clean file systems if preening */
-int fsmodified; /* 1 => write done to file system */
-int fsreadfd; /* file descriptor for reading file system */
-int fswritefd; /* file descriptor for writing file system */
-int surrender; /* Give up if reads fail */
-
-ufs2_daddr_t maxfsblock; /* number of blocks in the file system */
-char *blockmap; /* ptr to primary blk allocation map */
-ino_t maxino; /* number of inodes in file system */
-
-ino_t lfdir; /* lost & found directory inode number */
-const char *lfname; /* lost & found directory name */
-int lfmode; /* lost & found directory creation mode */
-
-ufs2_daddr_t n_blks; /* number of blocks in use */
-ino_t n_files; /* number of files in use */
-
-volatile sig_atomic_t got_siginfo; /* received a SIGINFO */
-volatile sig_atomic_t got_sigalarm; /* received a SIGALRM */
+extern int adjrefcnt[MIBSIZE]; /* MIB command to adjust inode reference cnt */
+extern int adjblkcnt[MIBSIZE]; /* MIB command to adjust inode block count */
+extern int adjndir[MIBSIZE]; /* MIB command to adjust number of directories */
+extern int adjnbfree[MIBSIZE]; /* MIB command to adjust number of free blocks */
+extern int adjnifree[MIBSIZE]; /* MIB command to adjust number of free inodes */
+extern int adjnffree[MIBSIZE]; /* MIB command to adjust number of free frags */
+extern int adjnumclusters[MIBSIZE]; /* MIB command to adjust number of free clusters */
+extern int freefiles[MIBSIZE]; /* MIB command to free a set of files */
+extern int freedirs[MIBSIZE]; /* MIB command to free a set of directories */
+extern int freeblks[MIBSIZE]; /* MIB command to free a set of data blocks */
+extern struct fsck_cmd cmd; /* sysctl file system update commands */
+extern char snapname[BUFSIZ]; /* when doing snapshots, the name of the file */
+extern char *cdevname; /* name of device being checked */
+extern long dev_bsize; /* computed value of DEV_BSIZE */
+extern long secsize; /* actual disk sector size */
+extern u_int real_dev_bsize; /* actual disk sector size, not overriden */
+extern char nflag; /* assume a no response */
+extern char yflag; /* assume a yes response */
+extern int bkgrdflag; /* use a snapshot to run on an active system */
+extern int bflag; /* location of alternate super block */
+extern int debug; /* output debugging info */
+extern int Eflag; /* delete empty data blocks */
+extern int Zflag; /* zero empty data blocks */
+extern int inoopt; /* trim out unused inodes */
+extern char ckclean; /* only do work if not cleanly unmounted */
+extern int cvtlevel; /* convert to newer file system format */
+extern int bkgrdcheck; /* determine if background check is possible */
+extern int bkgrdsumadj; /* whether the kernel have ability to adjust superblock summary */
+extern char usedsoftdep; /* just fix soft dependency inconsistencies */
+extern char preen; /* just fix normal inconsistencies */
+extern char rerun; /* rerun fsck. Only used in non-preen mode */
+extern int returntosingle; /* 1 => return to single user mode on exit */
+extern char resolved; /* cleared if unresolved changes => not clean */
+extern char havesb; /* superblock has been read */
+extern char skipclean; /* skip clean file systems if preening */
+extern int fsmodified; /* 1 => write done to file system */
+extern int fsreadfd; /* file descriptor for reading file system */
+extern int fswritefd; /* file descriptor for writing file system */
+extern int surrender; /* Give up if reads fail */
+extern int wantrestart; /* Restart fsck on early termination */
+
+extern ufs2_daddr_t maxfsblock; /* number of blocks in the file system */
+extern char *blockmap; /* ptr to primary blk allocation map */
+extern ino_t maxino; /* number of inodes in file system */
+
+extern ino_t lfdir; /* lost & found directory inode number */
+extern const char *lfname; /* lost & found directory name */
+extern int lfmode; /* lost & found directory creation mode */
+
+extern ufs2_daddr_t n_blks; /* number of blocks in use */
+extern ino_t n_files; /* number of files in use */
+
+extern volatile sig_atomic_t got_siginfo; /* received a SIGINFO */
+extern volatile sig_atomic_t got_sigalarm; /* received a SIGALRM */
#define clearinode(dp) \
if (sblock.fs_magic == FS_UFS1_MAGIC) { \
@@ -346,8 +347,8 @@ volatile sig_atomic_t got_sigalarm; /* received a SIGALRM */
} else { \
(dp)->dp2 = ufs2_zino; \
}
-struct ufs1_dinode ufs1_zino;
-struct ufs2_dinode ufs2_zino;
+extern struct ufs1_dinode ufs1_zino;
+extern struct ufs2_dinode ufs2_zino;
#define setbmap(blkno) setbit(blockmap, blkno)
#define testbmap(blkno) isset(blockmap, blkno)
@@ -360,6 +361,7 @@ struct ufs2_dinode ufs2_zino;
#define FOUND 0x10
#define EEXIT 8 /* Standard error exit. */
+#define ERESTART -1
int flushentry(void);
/*
@@ -428,6 +430,7 @@ void flush(int fd, struct bufarea *bp);
void freeblk(ufs2_daddr_t blkno, long frags);
void freeino(ino_t ino);
void freeinodebuf(void);
+void fsutilinit(void);
int ftypeok(union dinode *dp);
void getblk(struct bufarea *bp, ufs2_daddr_t blk, long size);
struct bufarea *cgget(int cg);
@@ -466,5 +469,6 @@ int setup(char *dev);
void gjournal_check(const char *filesys);
int suj_check(const char *filesys);
void update_maps(struct cg *, struct cg*, int);
+void fsckinit(void);
#endif /* !_FSCK_H_ */
diff --git a/sbin/fsck_ffs/fsck_ffs.8 b/sbin/fsck_ffs/fsck_ffs.8
index adf08d7bb434..828df2756997 100644
--- a/sbin/fsck_ffs/fsck_ffs.8
+++ b/sbin/fsck_ffs/fsck_ffs.8
@@ -38,7 +38,7 @@
.Nd file system consistency check and interactive repair
.Sh SYNOPSIS
.Nm
-.Op Fl BEFfnpryZ
+.Op Fl BEFfnpRryZ
.Op Fl b Ar block
.Op Fl c Ar level
.Op Fl m Ar mode
@@ -266,6 +266,11 @@ which is assumed to be affirmative;
do not open the file system for writing.
.It Fl p
Preen file systems (see above).
+.It Fl R
+Instruct fsck_ffs to restart itself if it encounters certain errors that
+warrant another run. It will limit itself to a maximum of 10 restarts
+in a given run in order to avoid an endless loop with extremely corrupted
+filesystems.
.It Fl r
Free up excess unused inodes.
Decreasing the number of preallocated inodes reduces the
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index 16ef8193fd89..4b44fd4ec856 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -74,6 +74,25 @@ static struct bufarea cgblk; /* backup buffer for cylinder group blocks */
static TAILQ_HEAD(buflist, bufarea) bufhead; /* head of buffer cache list */
static int numbufs; /* size of buffer cache */
static char *buftype[BT_NUMBUFTYPES] = BT_NAMES;
+static struct bufarea *cgbufs; /* header for cylinder group cache */
+static int flushtries; /* number of tries to reclaim memory */
+
+void
+fsutilinit(void)
+{
+ diskreads = totaldiskreads = totalreads = 0;
+ bzero(&startpass, sizeof(struct timespec));
+ bzero(&finishpass, sizeof(struct timespec));
+ bzero(&slowio_starttime, sizeof(struct timeval));
+ slowio_delay_usec = 10000;
+ slowio_pollcnt = 0;
+ bzero(&cgblk, sizeof(struct bufarea));
+ TAILQ_INIT(&bufhead);
+ numbufs = 0;
+ /* buftype ? */
+ cgbufs = NULL;
+ flushtries = 0;
+}
int
ftypeok(union dinode *dp)
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index 1a1c03bc7d85..08c7745727e4 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$");
#include "fsck.h"
+int restarts;
+
static void usage(void) __dead2;
static int argtoi(int flag, const char *req, const char *str, int base);
static int checkfilesys(char *filesys);
@@ -82,7 +84,7 @@ main(int argc, char *argv[])
sync();
skipclean = 1;
inoopt = 0;
- while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:nprSyZ")) != -1) {
+ while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:npRrSyZ")) != -1) {
switch (ch) {
case 'b':
skipclean = 0;
@@ -138,6 +140,9 @@ main(int argc, char *argv[])
ckclean++;
break;
+ case 'R':
+ wantrestart = 1;
+ break;
case 'r':
inoopt++;
break;
@@ -186,8 +191,12 @@ main(int argc, char *argv[])
rlimit.rlim_cur = rlimit.rlim_max;
(void)setrlimit(RLIMIT_DATA, &rlimit);
}
- while (argc-- > 0)
- (void)checkfilesys(*argv++);
+ while (argc > 0) {
+ if (checkfilesys(*argv) == ERESTART)
+ continue;
+ argc--;
+ argv++;
+ }
if (returntosingle)
ret = 2;
@@ -228,6 +237,8 @@ checkfilesys(char *filesys)
iov = NULL;
iovlen = 0;
errmsg[0] = '\0';
+ fsutilinit();
+ fsckinit();
cdevname = filesys;
if (debug && ckclean)
@@ -550,8 +561,12 @@ checkfilesys(char *filesys)
inostathead = NULL;
if (fsmodified && !preen)
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
- if (rerun)
+ if (rerun) {
+ if (wantrestart && (restarts++ < 10) &&
+ (preen || reply("RESTART")))
+ return (ERESTART);
printf("\n***** PLEASE RERUN FSCK *****\n");
+ }
if (chkdoreload(mntp) != 0) {
if (!fsmodified)
return (0);
@@ -654,3 +669,15 @@ usage(void)
getprogname());
exit(1);
}
+
+void
+infohandler(int sig __unused)
+{
+ got_siginfo = 1;
+}
+
+void
+alarmhandler(int sig __unused)
+{
+ got_sigalarm = 1;
+}
diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c
index 319954122863..67fba6eaa35c 100644
--- a/sbin/fsck_ffs/pass1.c
+++ b/sbin/fsck_ffs/pass1.c
@@ -68,6 +68,8 @@ pass1(void)
u_int8_t *cp;
int c, rebuildcg;
+ badblk = dupblk = lastino = 0;
+
/*
* Set file system reserved blocks in used block map.
*/
@@ -463,6 +465,7 @@ pass1check(struct inodesc *idesc)
ckfini(0);
exit(EEXIT);
}
+ rerun = 1;
return (STOP);
}
}
@@ -483,6 +486,7 @@ pass1check(struct inodesc *idesc)
ckfini(0);
exit(EEXIT);
}
+ rerun = 1;
return (STOP);
}
new = (struct dups *)Malloc(sizeof(struct dups));
@@ -492,6 +496,7 @@ pass1check(struct inodesc *idesc)
ckfini(0);
exit(EEXIT);
}
+ rerun = 1;
return (STOP);
}
new->dup = blkno;
diff --git a/sbin/fsck_ffs/pass1b.c b/sbin/fsck_ffs/pass1b.c
index e635935fca00..69a23c207ecd 100644
--- a/sbin/fsck_ffs/pass1b.c
+++ b/sbin/fsck_ffs/pass1b.c
@@ -80,8 +80,10 @@ pass1b(void)
continue;
idesc.id_number = inumber;
if (inoinfo(inumber)->ino_state != USTATE &&
- (ckinode(dp, &idesc) & STOP))
+ (ckinode(dp, &idesc) & STOP)) {
+ rerun = 1;
return;
+ }
}
}
}
@@ -106,8 +108,10 @@ pass1bcheck(struct inodesc *idesc)
if (dlp == muldup)
break;
}
- if (muldup == 0 || duphead == muldup->next)
+ if (muldup == 0 || duphead == muldup->next) {
+ rerun = 1;
return (STOP);
+ }
}
return (res);
}
diff --git a/sbin/fsck_ffs/suj.c b/sbin/fsck_ffs/suj.c
index 5fca0f5fbfdf..9d6a2eccdc97 100644
--- a/sbin/fsck_ffs/suj.c
+++ b/sbin/fsck_ffs/suj.c
@@ -125,26 +125,26 @@ struct suj_cg {
int sc_cgx;
};
-LIST_HEAD(cghd, suj_cg) cghash[SUJ_HASHSIZE];
-LIST_HEAD(dblkhd, data_blk) dbhash[SUJ_HASHSIZE];
-struct suj_cg *lastcg;
-struct data_blk *lastblk;
+static LIST_HEAD(cghd, suj_cg) cghash[SUJ_HASHSIZE];
+static LIST_HEAD(dblkhd, data_blk) dbhash[SUJ_HASHSIZE];
+static struct suj_cg *lastcg;
+static struct data_blk *lastblk;
-TAILQ_HEAD(seghd, suj_seg) allsegs;
-uint64_t oldseq;
+static TAILQ_HEAD(seghd, suj_seg) allsegs;
+static uint64_t oldseq;
static struct uufsd *disk = NULL;
static struct fs *fs = NULL;
-ino_t sujino;
+static ino_t sujino;
/*
* Summary statistics.
*/
-uint64_t freefrags;
-uint64_t freeblocks;
-uint64_t freeinos;
-uint64_t freedir;
-uint64_t jbytes;
-uint64_t jrecs;
+static uint64_t freefrags;
+static uint64_t freeblocks;
+static uint64_t freeinos;
+static uint64_t freedir;
+static uint64_t jbytes;
+static uint64_t jrecs;
static jmp_buf jmpbuf;
@@ -155,6 +155,7 @@ static void ino_decr(ino_t);
static void ino_adjust(struct suj_ino *);
static void ino_build(struct suj_ino *);
static int blk_isfree(ufs2_daddr_t);
+static void initsuj(void);
static void *
errmalloc(size_t n)
@@ -2413,7 +2414,7 @@ struct jextent {
int je_blocks; /* Disk block count. */
};
-struct jblocks *suj_jblocks;
+static struct jblocks *suj_jblocks;
static struct jblocks *
jblocks_create(void)
@@ -2673,8 +2674,8 @@ suj_check(const char *filesys)
struct suj_seg *seg;
struct suj_seg *segn;
+ initsuj();
opendisk(filesys);
- TAILQ_INIT(&allsegs);
/*
* Set an exit point when SUJ check failed
@@ -2763,3 +2764,28 @@ suj_check(const char *filesys)
return (0);
}
+
+static void
+initsuj(void)
+{
+ int i;
+
+ for (i = 0; i < SUJ_HASHSIZE; i++) {
+ LIST_INIT(&cghash[i]);
+ LIST_INIT(&dbhash[i]);
+ }
+ lastcg = NULL;
+ lastblk = NULL;
+ TAILQ_INIT(&allsegs);
+ oldseq = 0;
+ disk = NULL;
+ fs = NULL;
+ sujino = 0;
+ freefrags = 0;
+ freeblocks = 0;
+ freeinos = 0;
+ freedir = 0;
+ jbytes = 0;
+ jrecs = 0;
+ suj_jblocks = NULL;
+}
diff --git a/sbin/fsck_ffs/utilities.c b/sbin/fsck_ffs/utilities.c
index 5e7d69c1ff6a..4e82c31640da 100644
--- a/sbin/fsck_ffs/utilities.c
+++ b/sbin/fsck_ffs/utilities.c
@@ -108,14 +108,3 @@ retry:
return (origname);
}
-void
-infohandler(int sig __unused)
-{
- got_siginfo = 1;
-}
-
-void
-alarmhandler(int sig __unused)
-{
- got_sigalarm = 1;
-}