xref: /minix3/sbin/fsck/preen.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: preen.c,v 1.32 2015/06/21 04:01:40 dholland Exp $	*/
24d4057d8SBen Gras 
34d4057d8SBen Gras /*
44d4057d8SBen Gras  * Copyright (c) 1990, 1993
54d4057d8SBen Gras  *	The Regents of the University of California.  All rights reserved.
64d4057d8SBen Gras  *
74d4057d8SBen Gras  * Redistribution and use in source and binary forms, with or without
84d4057d8SBen Gras  * modification, are permitted provided that the following conditions
94d4057d8SBen Gras  * are met:
104d4057d8SBen Gras  * 1. Redistributions of source code must retain the above copyright
114d4057d8SBen Gras  *    notice, this list of conditions and the following disclaimer.
124d4057d8SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
134d4057d8SBen Gras  *    notice, this list of conditions and the following disclaimer in the
144d4057d8SBen Gras  *    documentation and/or other materials provided with the distribution.
154d4057d8SBen Gras  * 3. Neither the name of the University nor the names of its contributors
164d4057d8SBen Gras  *    may be used to endorse or promote products derived from this software
174d4057d8SBen Gras  *    without specific prior written permission.
184d4057d8SBen Gras  *
194d4057d8SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
204d4057d8SBen Gras  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
214d4057d8SBen Gras  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
224d4057d8SBen Gras  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
234d4057d8SBen Gras  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
244d4057d8SBen Gras  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
254d4057d8SBen Gras  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
264d4057d8SBen Gras  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
274d4057d8SBen Gras  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
284d4057d8SBen Gras  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
294d4057d8SBen Gras  * SUCH DAMAGE.
304d4057d8SBen Gras  */
314d4057d8SBen Gras 
324d4057d8SBen Gras #include <sys/cdefs.h>
334d4057d8SBen Gras #ifndef lint
344d4057d8SBen Gras #if 0
354d4057d8SBen Gras static char sccsid[] = "@(#)preen.c	8.5 (Berkeley) 4/28/95";
364d4057d8SBen Gras #else
37*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: preen.c,v 1.32 2015/06/21 04:01:40 dholland Exp $");
384d4057d8SBen Gras #endif
394d4057d8SBen Gras #endif /* not lint */
404d4057d8SBen Gras 
41*0a6a1f1dSLionel Sambuc /*
42*0a6a1f1dSLionel Sambuc  * used by sbin/fsck
43*0a6a1f1dSLionel Sambuc  * used by usr.sbin/quotacheck
44*0a6a1f1dSLionel Sambuc  */
45*0a6a1f1dSLionel Sambuc 
464d4057d8SBen Gras #include <sys/param.h>
474d4057d8SBen Gras #include <sys/stat.h>
484d4057d8SBen Gras #include <sys/wait.h>
494d4057d8SBen Gras #include <sys/queue.h>
504d4057d8SBen Gras #include <sys/disk.h>
514d4057d8SBen Gras #include <sys/ioctl.h>
524d4057d8SBen Gras 
534d4057d8SBen Gras #include <err.h>
544d4057d8SBen Gras #include <ctype.h>
554d4057d8SBen Gras #include <fstab.h>
564d4057d8SBen Gras #include <fcntl.h>
574d4057d8SBen Gras #include <string.h>
584d4057d8SBen Gras #include <stdio.h>
594d4057d8SBen Gras #include <stdlib.h>
604d4057d8SBen Gras #include <unistd.h>
614d4057d8SBen Gras #include <util.h>
624d4057d8SBen Gras 
634d4057d8SBen Gras #include "fsutil.h"
644d4057d8SBen Gras #include "exitvalues.h"
654d4057d8SBen Gras 
664d4057d8SBen Gras struct partentry {
674d4057d8SBen Gras 	TAILQ_ENTRY(partentry)	 p_entries;
684d4057d8SBen Gras 	char		  	*p_devname;	/* device name */
694d4057d8SBen Gras 	char			*p_mntpt;	/* mount point */
704d4057d8SBen Gras 	char		  	*p_type;	/* file system type */
714d4057d8SBen Gras 	void			*p_auxarg;	/* auxiliary argument */
724d4057d8SBen Gras };
734d4057d8SBen Gras 
744d4057d8SBen Gras TAILQ_HEAD(part, partentry) badh;
754d4057d8SBen Gras 
764d4057d8SBen Gras struct diskentry {
774d4057d8SBen Gras 	TAILQ_ENTRY(diskentry) 	    d_entries;
784d4057d8SBen Gras 	char			   *d_name;	/* disk base name */
794d4057d8SBen Gras 	TAILQ_HEAD(prt, partentry)  d_part;	/* list of partitions on disk */
804d4057d8SBen Gras 	int			    d_pid;	/* 0 or pid of fsck proc */
814d4057d8SBen Gras };
824d4057d8SBen Gras 
834d4057d8SBen Gras TAILQ_HEAD(diskinfo, diskentry) diskh;
844d4057d8SBen Gras 
854d4057d8SBen Gras static int nrun = 0, ndisks = 0;
864d4057d8SBen Gras 
874d4057d8SBen Gras static struct diskentry *finddisk(const char *);
884d4057d8SBen Gras static void addpart(const char *, const char *, const char *, void *);
894d4057d8SBen Gras static int startdisk(struct diskentry *,
904d4057d8SBen Gras     int (*)(const char *, const char *, const char *, void *, pid_t *));
914d4057d8SBen Gras static void printpart(void);
924d4057d8SBen Gras 
934d4057d8SBen Gras int
checkfstab(int flags,int maxrun,void * (* docheck)(struct fstab *),int (* checkit)(const char *,const char *,const char *,void *,pid_t *))944d4057d8SBen Gras checkfstab(int flags, int maxrun, void *(*docheck)(struct fstab *),
954d4057d8SBen Gras     int (*checkit)(const char *, const char *, const char *, void *, pid_t *))
964d4057d8SBen Gras {
974d4057d8SBen Gras 	struct fstab *fs;
984d4057d8SBen Gras 	struct diskentry *d, *nextdisk;
994d4057d8SBen Gras 	struct partentry *p;
1004d4057d8SBen Gras 	int ret, pid, retcode, passno, sumstatus, status;
1014d4057d8SBen Gras 	void *auxarg;
1024d4057d8SBen Gras 	const char *name;
1034d4057d8SBen Gras 	int error = FSCK_EXIT_OK;
1044d4057d8SBen Gras 
1054d4057d8SBen Gras 	TAILQ_INIT(&badh);
1064d4057d8SBen Gras 	TAILQ_INIT(&diskh);
1074d4057d8SBen Gras 
1084d4057d8SBen Gras 	sumstatus = FSCK_EXIT_OK;
1094d4057d8SBen Gras 
1104d4057d8SBen Gras 	for (passno = 1; passno <= 2; passno++) {
1114d4057d8SBen Gras 		if (setfsent() == 0) {
1124d4057d8SBen Gras 			warnx("Can't open checklist file: %s", _PATH_FSTAB);
1134d4057d8SBen Gras 			return FSCK_EXIT_CHECK_FAILED;
1144d4057d8SBen Gras 		}
1154d4057d8SBen Gras 		while ((fs = getfsent()) != 0) {
11684d9c625SLionel Sambuc 			char buf[MAXPATHLEN];
11784d9c625SLionel Sambuc 			const char *fsspec;
1184d4057d8SBen Gras 			if ((auxarg = (*docheck)(fs)) == NULL)
1194d4057d8SBen Gras 				continue;
12084d9c625SLionel Sambuc 			fsspec = getfsspecname(buf, sizeof(buf), fs->fs_spec);
12184d9c625SLionel Sambuc 			if (fsspec == NULL) {
12284d9c625SLionel Sambuc 				warn("%s", buf);
12384d9c625SLionel Sambuc 				return FSCK_EXIT_CHECK_FAILED;
12484d9c625SLionel Sambuc 			}
12584d9c625SLionel Sambuc 			name = blockcheck(fsspec);
1264d4057d8SBen Gras 			if (flags & CHECK_DEBUG)
1274d4057d8SBen Gras 				printf("pass %d, name %s\n", passno, name);
1284d4057d8SBen Gras 
1294d4057d8SBen Gras 			if ((flags & CHECK_PREEN) == 0 ||
1304d4057d8SBen Gras 			    (passno == 1 && fs->fs_passno == 1)) {
1314d4057d8SBen Gras 				if (name == NULL) {
1324d4057d8SBen Gras 					if (flags & CHECK_PREEN)
1334d4057d8SBen Gras 						return FSCK_EXIT_CHECK_FAILED;
1344d4057d8SBen Gras 					else
1354d4057d8SBen Gras 						continue;
1364d4057d8SBen Gras 				}
1374d4057d8SBen Gras 				sumstatus = (*checkit)(fs->fs_vfstype,
1384d4057d8SBen Gras 				    name, fs->fs_file, auxarg, NULL);
1394d4057d8SBen Gras 
1404d4057d8SBen Gras 				if (sumstatus) {
1414d4057d8SBen Gras 					if ((flags & CHECK_NOFIX) == 0)
1424d4057d8SBen Gras 						return sumstatus;
1434d4057d8SBen Gras 					else if (error < sumstatus)
1444d4057d8SBen Gras 						error = sumstatus;
1454d4057d8SBen Gras 				}
1464d4057d8SBen Gras 			} else if (passno == 2 && fs->fs_passno > 1) {
1474d4057d8SBen Gras 				if (name == NULL) {
1484d4057d8SBen Gras 					(void) fprintf(stderr,
14984d9c625SLionel Sambuc 					    "BAD DISK NAME %s\n", fsspec);
1504d4057d8SBen Gras 					sumstatus = FSCK_EXIT_CHECK_FAILED;
1514d4057d8SBen Gras 					continue;
1524d4057d8SBen Gras 				}
1534d4057d8SBen Gras 				addpart(fs->fs_vfstype, name, fs->fs_file,
1544d4057d8SBen Gras 				    auxarg);
1554d4057d8SBen Gras 			}
1564d4057d8SBen Gras 		}
1574d4057d8SBen Gras 		if ((flags & CHECK_PREEN) == 0)
1584d4057d8SBen Gras 			return error;
1594d4057d8SBen Gras 	}
1604d4057d8SBen Gras 
1614d4057d8SBen Gras 	if (flags & CHECK_DEBUG)
1624d4057d8SBen Gras 		printpart();
1634d4057d8SBen Gras 
1644d4057d8SBen Gras 	if (flags & CHECK_PREEN) {
1654d4057d8SBen Gras 		if (maxrun == 0)
1664d4057d8SBen Gras 			maxrun = ndisks;
1674d4057d8SBen Gras 		if (maxrun > ndisks)
1684d4057d8SBen Gras 			maxrun = ndisks;
1694d4057d8SBen Gras 		nextdisk = TAILQ_FIRST(&diskh);
1704d4057d8SBen Gras 		for (passno = 0; passno < maxrun; ++passno) {
1714d4057d8SBen Gras 			if ((ret = startdisk(nextdisk, checkit)) != 0) {
1724d4057d8SBen Gras 				if ((flags & CHECK_NOFIX) == 0)
1734d4057d8SBen Gras 					return ret;
1744d4057d8SBen Gras 				else if (error < ret)
1754d4057d8SBen Gras 					error = ret;
1764d4057d8SBen Gras 			}
1774d4057d8SBen Gras 			nextdisk = TAILQ_NEXT(nextdisk, d_entries);
1784d4057d8SBen Gras 		}
1794d4057d8SBen Gras 
1804d4057d8SBen Gras 		while ((pid = wait(&status)) != -1) {
1814d4057d8SBen Gras 			TAILQ_FOREACH(d, &diskh, d_entries)
1824d4057d8SBen Gras 				if (d->d_pid == pid)
1834d4057d8SBen Gras 					break;
1844d4057d8SBen Gras 
1854d4057d8SBen Gras 			if (d == NULL) {
1864d4057d8SBen Gras 				warnx("Unknown pid %d", pid);
1874d4057d8SBen Gras 				continue;
1884d4057d8SBen Gras 			}
1894d4057d8SBen Gras 
1904d4057d8SBen Gras 
1914d4057d8SBen Gras 			if (WIFEXITED(status))
1924d4057d8SBen Gras 				retcode = WEXITSTATUS(status);
1934d4057d8SBen Gras 			else
1944d4057d8SBen Gras 				retcode = 0;
1954d4057d8SBen Gras 
1964d4057d8SBen Gras 			p = TAILQ_FIRST(&d->d_part);
1974d4057d8SBen Gras 
1984d4057d8SBen Gras 			if (flags & (CHECK_DEBUG|CHECK_VERBOSE))
1994d4057d8SBen Gras 				(void) printf("done %s: %s (%s) = 0x%x\n",
2004d4057d8SBen Gras 				    p->p_type, p->p_devname, p->p_mntpt,
2014d4057d8SBen Gras 				    status);
2024d4057d8SBen Gras 
2034d4057d8SBen Gras 			if (WIFSIGNALED(status)) {
2044d4057d8SBen Gras 				(void) fprintf(stderr,
2054d4057d8SBen Gras 				    "%s: %s (%s): EXITED WITH SIGNAL %d\n",
2064d4057d8SBen Gras 				    p->p_type, p->p_devname, p->p_mntpt,
2074d4057d8SBen Gras 				    WTERMSIG(status));
2084d4057d8SBen Gras 				retcode = FSCK_EXIT_SIGNALLED;
2094d4057d8SBen Gras 			}
2104d4057d8SBen Gras 
2114d4057d8SBen Gras 			TAILQ_REMOVE(&d->d_part, p, p_entries);
2124d4057d8SBen Gras 
2134d4057d8SBen Gras 			if (retcode != 0) {
2144d4057d8SBen Gras 				TAILQ_INSERT_TAIL(&badh, p, p_entries);
2154d4057d8SBen Gras 				sumstatus |= retcode;
2164d4057d8SBen Gras 			} else {
2174d4057d8SBen Gras 				free(p->p_type);
2184d4057d8SBen Gras 				free(p->p_devname);
2194d4057d8SBen Gras 				free(p);
2204d4057d8SBen Gras 			}
2214d4057d8SBen Gras 			d->d_pid = 0;
2224d4057d8SBen Gras 			nrun--;
2234d4057d8SBen Gras 
2244d4057d8SBen Gras 			if (TAILQ_FIRST(&d->d_part) == NULL)
2254d4057d8SBen Gras 				ndisks--;
2264d4057d8SBen Gras 
2274d4057d8SBen Gras 			if (nextdisk == NULL) {
2284d4057d8SBen Gras 				if (TAILQ_FIRST(&d->d_part) != NULL) {
2294d4057d8SBen Gras 					if ((ret = startdisk(d, checkit)) != 0)
2304d4057d8SBen Gras 					{
2314d4057d8SBen Gras 						if ((flags & CHECK_NOFIX) == 0)
2324d4057d8SBen Gras 							return ret;
2334d4057d8SBen Gras 						else if (error < ret)
2344d4057d8SBen Gras 							error = ret;
2354d4057d8SBen Gras 					}
2364d4057d8SBen Gras 				}
2374d4057d8SBen Gras 			} else if (nrun < maxrun && nrun < ndisks) {
2384d4057d8SBen Gras 				for ( ;; ) {
2394d4057d8SBen Gras 					nextdisk = TAILQ_NEXT(nextdisk,
2404d4057d8SBen Gras 					    d_entries);
2414d4057d8SBen Gras 					if (nextdisk == NULL)
2424d4057d8SBen Gras 						nextdisk = TAILQ_FIRST(&diskh);
2434d4057d8SBen Gras 					if (TAILQ_FIRST(&nextdisk->d_part)
2444d4057d8SBen Gras 					    != NULL && nextdisk->d_pid == 0)
2454d4057d8SBen Gras 						break;
2464d4057d8SBen Gras 				}
2474d4057d8SBen Gras 				if ((ret = startdisk(nextdisk, checkit)) != 0)
2484d4057d8SBen Gras 				{
2494d4057d8SBen Gras 					if ((flags & CHECK_NOFIX) == 0)
2504d4057d8SBen Gras 						return ret;
2514d4057d8SBen Gras 					else if (error < ret)
2524d4057d8SBen Gras 						error = ret;
2534d4057d8SBen Gras 				}
2544d4057d8SBen Gras 			}
2554d4057d8SBen Gras 		}
2564d4057d8SBen Gras 	}
2574d4057d8SBen Gras 	if (sumstatus) {
2584d4057d8SBen Gras 		p = TAILQ_FIRST(&badh);
2594d4057d8SBen Gras 		if (p == NULL)
2604d4057d8SBen Gras 			return sumstatus;
2614d4057d8SBen Gras 
2624d4057d8SBen Gras 		(void) fprintf(stderr,
2634d4057d8SBen Gras 			"THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t",
2644d4057d8SBen Gras 			TAILQ_NEXT(p, p_entries) ? "S" : "",
2654d4057d8SBen Gras 			"UNEXPECTED INCONSISTENCY:");
2664d4057d8SBen Gras 
2674d4057d8SBen Gras 		TAILQ_FOREACH(p, &badh, p_entries)
2684d4057d8SBen Gras 			(void) fprintf(stderr,
2694d4057d8SBen Gras 			    "%s: %s (%s)%s", p->p_type, p->p_devname,
2704d4057d8SBen Gras 			    p->p_mntpt, TAILQ_NEXT(p, p_entries) ? ", " : "\n");
2714d4057d8SBen Gras 
2724d4057d8SBen Gras 		return sumstatus;
2734d4057d8SBen Gras 	}
2744d4057d8SBen Gras 	(void) endfsent();
2754d4057d8SBen Gras 	return error;
2764d4057d8SBen Gras }
2774d4057d8SBen Gras 
2784d4057d8SBen Gras 
2794d4057d8SBen Gras static struct diskentry *
finddisk(const char * name)2804d4057d8SBen Gras finddisk(const char *name)
2814d4057d8SBen Gras {
2824d4057d8SBen Gras 	const char *p;
2834d4057d8SBen Gras 	size_t len, dlen;
2844d4057d8SBen Gras 	struct diskentry *d;
28584d9c625SLionel Sambuc #if !defined(__minix)
2864d4057d8SBen Gras 	char buf[MAXPATHLEN];
2874d4057d8SBen Gras 	struct dkwedge_info dkw;
2884d4057d8SBen Gras 	int fd;
2894d4057d8SBen Gras 
2904d4057d8SBen Gras 	if ((fd = opendisk(name, O_RDONLY, buf, sizeof(buf), 0)) != -1) {
2914d4057d8SBen Gras 		if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1)
2924d4057d8SBen Gras 			name = dkw.dkw_parent;
2934d4057d8SBen Gras 		(void)close(fd);
2944d4057d8SBen Gras 	}
29584d9c625SLionel Sambuc #endif /* !defined(__minix) */
2964d4057d8SBen Gras 
2974d4057d8SBen Gras 	for (dlen = len = strlen(name), p = name + len - 1; p >= name; --p)
2984d4057d8SBen Gras 		if (isdigit((unsigned char)*p)) {
2994d4057d8SBen Gras 			len = p - name + 1;
3004d4057d8SBen Gras 			break;
3014d4057d8SBen Gras 		}
3024d4057d8SBen Gras 	if (p < name)
3034d4057d8SBen Gras 		len = dlen;
3044d4057d8SBen Gras 
3054d4057d8SBen Gras 	TAILQ_FOREACH(d, &diskh, d_entries)
3064d4057d8SBen Gras 		if (strncmp(d->d_name, name, len) == 0 && d->d_name[len] == 0)
3074d4057d8SBen Gras 			return d;
3084d4057d8SBen Gras 
3094d4057d8SBen Gras 	d = emalloc(sizeof(*d));
3104d4057d8SBen Gras 	d->d_name = estrdup(name);
3114d4057d8SBen Gras 	d->d_name[len] = '\0';
3124d4057d8SBen Gras 	TAILQ_INIT(&d->d_part);
3134d4057d8SBen Gras 	d->d_pid = 0;
3144d4057d8SBen Gras 
3154d4057d8SBen Gras 	TAILQ_INSERT_TAIL(&diskh, d, d_entries);
3164d4057d8SBen Gras 	ndisks++;
3174d4057d8SBen Gras 
3184d4057d8SBen Gras 	return d;
3194d4057d8SBen Gras }
3204d4057d8SBen Gras 
3214d4057d8SBen Gras 
3224d4057d8SBen Gras static void
printpart(void)3234d4057d8SBen Gras printpart(void)
3244d4057d8SBen Gras {
3254d4057d8SBen Gras 	struct diskentry *d;
3264d4057d8SBen Gras 	struct partentry *p;
3274d4057d8SBen Gras 
3284d4057d8SBen Gras 	TAILQ_FOREACH(d, &diskh, d_entries) {
3294d4057d8SBen Gras 		(void) printf("disk %s:", d->d_name);
3304d4057d8SBen Gras 		TAILQ_FOREACH(p, &d->d_part, p_entries)
3314d4057d8SBen Gras 			(void) printf(" %s", p->p_devname);
3324d4057d8SBen Gras 		(void) printf("\n");
3334d4057d8SBen Gras 	}
3344d4057d8SBen Gras }
3354d4057d8SBen Gras 
3364d4057d8SBen Gras 
3374d4057d8SBen Gras static void
addpart(const char * type,const char * dev,const char * mntpt,void * auxarg)3384d4057d8SBen Gras addpart(const char *type, const char *dev, const char *mntpt, void *auxarg)
3394d4057d8SBen Gras {
3404d4057d8SBen Gras 	struct diskentry *d = finddisk(dev);
3414d4057d8SBen Gras 	struct partentry *p;
3424d4057d8SBen Gras 
3434d4057d8SBen Gras 	TAILQ_FOREACH(p, &d->d_part, p_entries)
3444d4057d8SBen Gras 		if (strcmp(p->p_devname, dev) == 0) {
3454d4057d8SBen Gras 			warnx("%s in fstab more than once!", dev);
3464d4057d8SBen Gras 			return;
3474d4057d8SBen Gras 		}
3484d4057d8SBen Gras 
3494d4057d8SBen Gras 	p = emalloc(sizeof(*p));
3504d4057d8SBen Gras 	p->p_devname = estrdup(dev);
3514d4057d8SBen Gras 	p->p_mntpt = estrdup(mntpt);
3524d4057d8SBen Gras 	p->p_type = estrdup(type);
3534d4057d8SBen Gras 	p->p_auxarg = auxarg;
3544d4057d8SBen Gras 
3554d4057d8SBen Gras 	TAILQ_INSERT_TAIL(&d->d_part, p, p_entries);
3564d4057d8SBen Gras }
3574d4057d8SBen Gras 
3584d4057d8SBen Gras 
3594d4057d8SBen Gras static int
startdisk(struct diskentry * d,int (* checkit)(const char *,const char *,const char *,void *,pid_t *))3604d4057d8SBen Gras startdisk(struct diskentry *d,
3614d4057d8SBen Gras     int (*checkit)(const char *, const char *, const char *, void *, pid_t *))
3624d4057d8SBen Gras {
3634d4057d8SBen Gras 	struct partentry *p = TAILQ_FIRST(&d->d_part);
3644d4057d8SBen Gras 	int rv;
3654d4057d8SBen Gras 
3664d4057d8SBen Gras 	while ((rv = (*checkit)(p->p_type, p->p_devname, p->p_mntpt,
3674d4057d8SBen Gras 	    p->p_auxarg, &d->d_pid)) != 0 && nrun > 0)
3684d4057d8SBen Gras 		sleep(10);
3694d4057d8SBen Gras 
3704d4057d8SBen Gras 	if (rv == 0)
3714d4057d8SBen Gras 		nrun++;
3724d4057d8SBen Gras 
3734d4057d8SBen Gras 	return rv;
3744d4057d8SBen Gras }
375