From c1a25d60970fe027ade04ff351d7ecedf52bf81b Mon Sep 17 00:00:00 2001 From: rodrigc Date: Wed, 19 Sep 2007 01:24:19 +0000 Subject: Convert fsck_ffs to nmount(). This seems to solve an intermittent problem where MNT_RELOAD fails for the root file system. Reported and tested by: phk Approved by: re (bmah) --- sbin/fsck_ffs/Makefile | 7 ++--- sbin/fsck_ffs/main.c | 69 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 21 deletions(-) (limited to 'sbin') diff --git a/sbin/fsck_ffs/Makefile b/sbin/fsck_ffs/Makefile index ee164dd..aaae685 100644 --- a/sbin/fsck_ffs/Makefile +++ b/sbin/fsck_ffs/Makefile @@ -7,12 +7,13 @@ 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 utilities.c ffs_subr.c ffs_tables.c gjournal.c + pass4.c pass5.c setup.c utilities.c ffs_subr.c ffs_tables.c gjournal.c \ + getmntopts.c DPADD= ${LIBUFS} LDADD= -lufs WARNS?= 2 -CFLAGS+= -I${.CURDIR} +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../mount -.PATH: ${.CURDIR}/../../sys/ufs/ffs +.PATH: ${.CURDIR}/../../sys/ufs/ffs ${.CURDIR}/../mount .include diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index 9407739..578716f 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -48,16 +48,17 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -192,16 +193,23 @@ static int checkfilesys(char *filesys) { ufs2_daddr_t n_ffree, n_bfree; - struct ufs_args args; struct dups *dp; struct statfs *mntp; struct stat snapdir; struct group *grp; ufs2_daddr_t blks; + struct iovec *iov; + char errmsg[255]; + int iovlen; + int fflags; int cylno; ino_t files; size_t size; + iov = NULL; + iovlen = 0; + errmsg[0] = '\0'; + cdevname = filesys; if (debug && preen) pwarn("starting\n"); @@ -330,16 +338,27 @@ checkfilesys(char *filesys) if (bkgrdflag) { snprintf(snapname, sizeof snapname, "%s/.snap/fsck_snapshot", mntp->f_mntonname); - memset(&args, 0, sizeof args); - args.fspec = snapname; - while (mount("ffs", mntp->f_mntonname, - mntp->f_flags | MNT_UPDATE | MNT_SNAPSHOT, - &args) < 0) { + fflags = mntp->f_flags; + /* + * XXX: Need to kick out MNT_ROOTFS until we fix + * nmount(). + */ + fflags &= ~MNT_ROOTFS; + fflags = fflags | MNT_UPDATE | MNT_SNAPSHOT; + build_iovec(&iov, &iovlen, "fstype", "ffs", 4); + build_iovec(&iov, &iovlen, "from", snapname, + (size_t)-1); + build_iovec(&iov, &iovlen, "fspath", mntp->f_mntonname, + (size_t)-1); + build_iovec(&iov, &iovlen, "errmsg", errmsg, + sizeof(errmsg)); + + while (nmount(iov, iovlen, fflags) < 0) { if (errno == EEXIST && unlink(snapname) == 0) continue; bkgrdflag = 0; - pfatal("CANNOT CREATE SNAPSHOT %s: %s\n", - snapname, strerror(errno)); + pfatal("CANNOT CREATE SNAPSHOT %s: %s %s\n", + snapname, strerror(errno), errmsg); break; } if (bkgrdflag != 0) @@ -500,28 +519,42 @@ checkfilesys(char *filesys) static int chkdoreload(struct statfs *mntp) { - struct ufs_args args; + struct iovec *iov; + int iovlen; + int fflags; + char errmsg[255]; if (mntp == NULL) return (0); + + iov = NULL; + iovlen = 0; + errmsg[0] = '\0'; + fflags = mntp->f_flags; /* * 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) { - memset(&args, 0, sizeof args); /* - * args.fspec = 0; - * args.export.ex_flags = 0; - * args.export.ex_root = 0; + * XXX: Need to kick out MNT_ROOTFS until we fix + * nmount(). */ - if (mount("ufs", mntp->f_mntonname, - mntp->f_flags | MNT_UPDATE | MNT_RELOAD, &args) == 0) { + fflags &= ~MNT_ROOTFS; + fflags = fflags | MNT_UPDATE | MNT_RELOAD; + 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)); + if (nmount(iov, iovlen, fflags) == 0) { return (0); } - pwarn("mount reload of '%s' failed: %s\n\n", - mntp->f_mntonname, strerror(errno)); + pwarn("mount reload of '%s' failed: %s %s\n\n", + mntp->f_mntonname, strerror(errno), errmsg); return (1); } return (0); -- cgit v1.1