mirror of
https://git.FreeBSD.org/src.git
synced 2026-06-02 11:24:32 +00:00
Document the mntopts(3) functions.
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D37907
(cherry picked from commit 906c312bbf)
This commit is contained in:
@@ -4,6 +4,10 @@
|
||||
PACKAGE=runtime
|
||||
PROG= fsck
|
||||
SRCS= fsck.c fsutil.c preen.c
|
||||
SRCS+= getmntopts.c
|
||||
MAN= fsck.8
|
||||
MOUNT= ${SRCTOP}/sbin/mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
+3
-2
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <err.h>
|
||||
#include <fstab.h>
|
||||
#include <fcntl.h>
|
||||
#include <mntopts.h>
|
||||
#include <paths.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@@ -206,7 +207,7 @@ main(int argc, char *argv[])
|
||||
_PATH_DEV, spec);
|
||||
spec = device;
|
||||
}
|
||||
mntp = getmntpt(spec);
|
||||
mntp = getmntpoint(spec);
|
||||
if (mntp != NULL) {
|
||||
spec = mntp->f_mntfromname;
|
||||
mntpt = mntp->f_mntonname;
|
||||
@@ -269,7 +270,7 @@ isok(struct fstab *fs)
|
||||
if (flags & DO_BACKGRD) {
|
||||
if (!strcmp(fs->fs_type, FSTAB_RO))
|
||||
return (0);
|
||||
if (getmntpt(fs->fs_spec) == NULL)
|
||||
if (getmntpoint(fs->fs_spec) == NULL)
|
||||
return (0);
|
||||
if (checkfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, "-F", 0))
|
||||
return (0);
|
||||
|
||||
@@ -188,50 +188,6 @@ devcheck(const char *origname)
|
||||
return (origname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the mount point information for name.
|
||||
*/
|
||||
struct statfs *
|
||||
getmntpt(const char *name)
|
||||
{
|
||||
struct stat devstat, mntdevstat;
|
||||
char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
|
||||
char *dev_name;
|
||||
struct statfs *mntbuf, *statfsp;
|
||||
int i, mntsize, isdev;
|
||||
|
||||
if (stat(name, &devstat) != 0)
|
||||
return (NULL);
|
||||
if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))
|
||||
isdev = 1;
|
||||
else
|
||||
isdev = 0;
|
||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||
for (i = 0; i < mntsize; i++) {
|
||||
statfsp = &mntbuf[i];
|
||||
dev_name = statfsp->f_mntfromname;
|
||||
if (*dev_name != '/') {
|
||||
if (strlen(_PATH_DEV) + strlen(dev_name) + 1 >
|
||||
sizeof(statfsp->f_mntfromname))
|
||||
continue;
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, dev_name);
|
||||
strcpy(statfsp->f_mntfromname, device);
|
||||
}
|
||||
if (isdev == 0) {
|
||||
if (strcmp(name, statfsp->f_mntonname))
|
||||
continue;
|
||||
return (statfsp);
|
||||
}
|
||||
if (stat(dev_name, &mntdevstat) == 0 &&
|
||||
mntdevstat.st_rdev == devstat.st_rdev)
|
||||
return (statfsp);
|
||||
}
|
||||
statfsp = NULL;
|
||||
return (statfsp);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
emalloc(size_t s)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,6 @@ void panic(const char *, ...) __dead2 __printflike(1, 2);
|
||||
const char *devcheck(const char *);
|
||||
const char *cdevname(void);
|
||||
void setcdevname(const char *, int);
|
||||
struct statfs *getmntpt(const char *);
|
||||
void *emalloc(size_t);
|
||||
void *erealloc(void *, size_t);
|
||||
char *estrdup(const char *);
|
||||
|
||||
+4
-92
@@ -76,8 +76,6 @@ static void usage(void) __dead2;
|
||||
static intmax_t argtoimax(int flag, const char *req, const char *str, int base);
|
||||
static int checkfilesys(char *filesys);
|
||||
static int setup_bkgrdchk(struct statfs *mntp, int sbrdfailed, char **filesys);
|
||||
static int chkdoreload(struct statfs *mntp);
|
||||
static struct statfs *getmntpt(const char *);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
@@ -258,7 +256,7 @@ checkfilesys(char *filesys)
|
||||
* if it is listed among the mounted file systems. Failing that
|
||||
* check to see if it is listed in /etc/fstab.
|
||||
*/
|
||||
mntp = getmntpt(filesys);
|
||||
mntp = getmntpoint(filesys);
|
||||
if (mntp != NULL)
|
||||
filesys = mntp->f_mntfromname;
|
||||
else
|
||||
@@ -311,7 +309,7 @@ checkfilesys(char *filesys)
|
||||
(FS_UNCLEAN | FS_NEEDSFSCK)) == 0) {
|
||||
bufinit();
|
||||
gjournal_check(filesys);
|
||||
if (chkdoreload(mntp) == 0)
|
||||
if (chkdoreload(mntp, pwarn) == 0)
|
||||
exit(0);
|
||||
exit(4);
|
||||
} else {
|
||||
@@ -357,7 +355,7 @@ checkfilesys(char *filesys)
|
||||
sujrecovery = 1;
|
||||
if (suj_check(filesys) == 0) {
|
||||
printf("\n***** FILE SYSTEM MARKED CLEAN *****\n");
|
||||
if (chkdoreload(mntp) == 0)
|
||||
if (chkdoreload(mntp, pwarn) == 0)
|
||||
exit(0);
|
||||
exit(4);
|
||||
}
|
||||
@@ -561,7 +559,7 @@ checkfilesys(char *filesys)
|
||||
return (ERESTART);
|
||||
printf("\n***** PLEASE RERUN FSCK *****\n");
|
||||
}
|
||||
if (chkdoreload(mntp) != 0) {
|
||||
if (chkdoreload(mntp, pwarn) != 0) {
|
||||
if (!fsmodified)
|
||||
return (0);
|
||||
if (!preen)
|
||||
@@ -715,92 +713,6 @@ setup_bkgrdchk(struct statfs *mntp, int sbreadfailed, char **filesys)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
chkdoreload(struct statfs *mntp)
|
||||
{
|
||||
struct iovec *iov;
|
||||
int iovlen;
|
||||
char errmsg[255];
|
||||
|
||||
if (mntp == NULL)
|
||||
return (0);
|
||||
|
||||
iov = NULL;
|
||||
iovlen = 0;
|
||||
errmsg[0] = '\0';
|
||||
/*
|
||||
* 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) {
|
||||
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));
|
||||
build_iovec(&iov, &iovlen, "update", NULL, 0);
|
||||
build_iovec(&iov, &iovlen, "reload", NULL, 0);
|
||||
/*
|
||||
* XX: We need the following line until we clean up
|
||||
* nmount parsing of root mounts and NFS root mounts.
|
||||
*/
|
||||
build_iovec(&iov, &iovlen, "ro", NULL, 0);
|
||||
if (nmount(iov, iovlen, mntp->f_flags) == 0) {
|
||||
return (0);
|
||||
}
|
||||
pwarn("mount reload of '%s' failed: %s %s\n\n",
|
||||
mntp->f_mntonname, strerror(errno), errmsg);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the mount point information for name.
|
||||
*/
|
||||
static struct statfs *
|
||||
getmntpt(const char *name)
|
||||
{
|
||||
struct stat devstat, mntdevstat;
|
||||
char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
|
||||
char *ddevname;
|
||||
struct statfs *mntbuf, *statfsp;
|
||||
int i, mntsize, isdev;
|
||||
|
||||
if (stat(name, &devstat) != 0)
|
||||
return (NULL);
|
||||
if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))
|
||||
isdev = 1;
|
||||
else
|
||||
isdev = 0;
|
||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||
for (i = 0; i < mntsize; i++) {
|
||||
statfsp = &mntbuf[i];
|
||||
ddevname = statfsp->f_mntfromname;
|
||||
if (*ddevname != '/') {
|
||||
if (strlen(_PATH_DEV) + strlen(ddevname) + 1 >
|
||||
sizeof(statfsp->f_mntfromname))
|
||||
continue;
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, ddevname);
|
||||
strcpy(statfsp->f_mntfromname, device);
|
||||
}
|
||||
if (isdev == 0) {
|
||||
if (strcmp(name, statfsp->f_mntonname))
|
||||
continue;
|
||||
return (statfsp);
|
||||
}
|
||||
if (stat(ddevname, &mntdevstat) == 0 &&
|
||||
mntdevstat.st_rdev == devstat.st_rdev)
|
||||
return (statfsp);
|
||||
}
|
||||
statfsp = NULL;
|
||||
return (statfsp);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
+10
-100
@@ -118,7 +118,6 @@ static void updjcg(int, time_t, int, int, unsigned int);
|
||||
static void updcsloc(time_t, int, int, unsigned int);
|
||||
static void frag_adjust(ufs2_daddr_t, int);
|
||||
static void updclst(int);
|
||||
static void mount_reload(const struct statfs *stfs);
|
||||
static void cgckhash(struct cg *);
|
||||
|
||||
/*
|
||||
@@ -1263,76 +1262,11 @@ is_dev(const char *name)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return mountpoint on which the device is currently mounted.
|
||||
*/
|
||||
static const struct statfs *
|
||||
dev_to_statfs(const char *dev)
|
||||
{
|
||||
struct stat devstat, mntdevstat;
|
||||
struct statfs *mntbuf, *statfsp;
|
||||
char device[MAXPATHLEN];
|
||||
char *mntdevname;
|
||||
int i, mntsize;
|
||||
|
||||
/*
|
||||
* First check the mounted filesystems.
|
||||
*/
|
||||
if (stat(dev, &devstat) != 0)
|
||||
return (NULL);
|
||||
if (!S_ISCHR(devstat.st_mode) && !S_ISBLK(devstat.st_mode))
|
||||
return (NULL);
|
||||
|
||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||
for (i = 0; i < mntsize; i++) {
|
||||
statfsp = &mntbuf[i];
|
||||
mntdevname = statfsp->f_mntfromname;
|
||||
if (*mntdevname != '/') {
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, mntdevname);
|
||||
mntdevname = device;
|
||||
}
|
||||
if (stat(mntdevname, &mntdevstat) == 0 &&
|
||||
mntdevstat.st_rdev == devstat.st_rdev)
|
||||
return (statfsp);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static const char *
|
||||
mountpoint_to_dev(const char *mountpoint)
|
||||
{
|
||||
struct statfs *mntbuf, *statfsp;
|
||||
struct fstab *fs;
|
||||
int i, mntsize;
|
||||
|
||||
/*
|
||||
* First check the mounted filesystems.
|
||||
*/
|
||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||
for (i = 0; i < mntsize; i++) {
|
||||
statfsp = &mntbuf[i];
|
||||
|
||||
if (strcmp(statfsp->f_mntonname, mountpoint) == 0)
|
||||
return (statfsp->f_mntfromname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the fstab.
|
||||
*/
|
||||
fs = getfsfile(mountpoint);
|
||||
if (fs != NULL)
|
||||
return (fs->fs_spec);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static const char *
|
||||
getdev(const char *name)
|
||||
getdev(const char *name, struct statfs *statfsp)
|
||||
{
|
||||
static char device[MAXPATHLEN];
|
||||
const char *cp, *dev;
|
||||
const char *cp;
|
||||
|
||||
if (is_dev(name))
|
||||
return (name);
|
||||
@@ -1344,9 +1278,8 @@ getdev(const char *name)
|
||||
return (device);
|
||||
}
|
||||
|
||||
dev = mountpoint_to_dev(name);
|
||||
if (dev != NULL && is_dev(dev))
|
||||
return (dev);
|
||||
if (statfsp != NULL)
|
||||
return (statfsp->f_mntfromname);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
@@ -1378,7 +1311,7 @@ main(int argc, char **argv)
|
||||
DBG_FUNC("main")
|
||||
struct fs *fs;
|
||||
const char *device;
|
||||
const struct statfs *statfsp;
|
||||
struct statfs *statfsp;
|
||||
uint64_t size = 0;
|
||||
off_t mediasize;
|
||||
int error, j, fsi, fso, ch, ret, Nflag = 0, yflag = 0;
|
||||
@@ -1430,12 +1363,11 @@ main(int argc, char **argv)
|
||||
/*
|
||||
* Now try to guess the device name.
|
||||
*/
|
||||
device = getdev(*argv);
|
||||
statfsp = getmntpoint(*argv);
|
||||
device = getdev(*argv, statfsp);
|
||||
if (device == NULL)
|
||||
errx(1, "cannot find special device for %s", *argv);
|
||||
|
||||
statfsp = dev_to_statfs(device);
|
||||
|
||||
fsi = open(device, O_RDONLY);
|
||||
if (fsi < 0)
|
||||
err(1, "%s", device);
|
||||
@@ -1666,8 +1598,9 @@ main(int argc, char **argv)
|
||||
error = close(fso);
|
||||
if (error != 0)
|
||||
err(1, "close");
|
||||
if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) != 0)
|
||||
mount_reload(statfsp);
|
||||
if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) != 0 &&
|
||||
chkdoreload(statfsp, warn) != 0)
|
||||
exit(9);
|
||||
}
|
||||
|
||||
DBG_CLOSE;
|
||||
@@ -1734,29 +1667,6 @@ updclst(int block)
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_reload(const struct statfs *stfs)
|
||||
{
|
||||
char errmsg[255];
|
||||
struct iovec *iov;
|
||||
int iovlen;
|
||||
|
||||
iov = NULL;
|
||||
iovlen = 0;
|
||||
*errmsg = '\0';
|
||||
build_iovec(&iov, &iovlen, "fstype", __DECONST(char *, "ffs"), 4);
|
||||
build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, stfs->f_mntonname), (size_t)-1);
|
||||
build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));
|
||||
build_iovec(&iov, &iovlen, "update", NULL, 0);
|
||||
build_iovec(&iov, &iovlen, "reload", NULL, 0);
|
||||
|
||||
if (nmount(iov, iovlen, stfs->f_flags) < 0) {
|
||||
errmsg[sizeof(errmsg) - 1] = '\0';
|
||||
err(9, "%s: cannot reload filesystem%s%s", stfs->f_mntonname,
|
||||
*errmsg != '\0' ? ": " : "", errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the check-hash of the cylinder group.
|
||||
*/
|
||||
|
||||
+9
-2
@@ -4,8 +4,15 @@
|
||||
PACKAGE=runtime
|
||||
PROG= mount
|
||||
SRCS= mount.c mount_fs.c getmntopts.c vfslist.c
|
||||
MAN= mount.8
|
||||
# We do NOT install the getmntopts.3 man page.
|
||||
MAN= mntopts.3 mount.8
|
||||
MLINKS+= mntopts.3 getmntopts.3
|
||||
MLINKS+= mntopts.3 getmntpoint.3
|
||||
MLINKS+= mntopts.3 chkdoreload.3
|
||||
MLINKS+= mntopts.3 build_iovec.3
|
||||
MLINKS+= mntopts.3 build_iovec_argf.3
|
||||
MLINKS+= mntopts.3 free_iovec.3
|
||||
MLINKS+= mntopts.3 checkpath.3
|
||||
MLINKS+= mntopts.3 rmslashes.3
|
||||
|
||||
LIBADD= util xo
|
||||
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
.\" Copyright (c) 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)getmntopts.3 8.3 (Berkeley) 3/30/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 17, 2008
|
||||
.Dt GETMNTOPTS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm getmntopts
|
||||
.Nd scan mount options
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include \&"mntopts.h"
|
||||
.Ft void
|
||||
.Fo getmntopts
|
||||
.Fa "const char *options" "const struct mntopt *mopts"
|
||||
.Fa "int *flagp" "int *altflagp"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn getmntopts
|
||||
function takes a comma separated option list and a list
|
||||
of valid option names, and computes the bitmask
|
||||
corresponding to the requested set of options.
|
||||
.Pp
|
||||
The string
|
||||
.Fa options
|
||||
is broken down into a sequence of comma separated tokens.
|
||||
Each token is looked up in the table described by
|
||||
.Fa mopts
|
||||
and the bits in
|
||||
the word referenced by either
|
||||
.Fa flagp
|
||||
or
|
||||
.Fa altflagp
|
||||
(depending on the
|
||||
.Va m_altloc
|
||||
field of the option's table entry)
|
||||
are updated.
|
||||
The flag words are not initialized by
|
||||
.Fn getmntopts .
|
||||
The table,
|
||||
.Fa mopts ,
|
||||
has the following format:
|
||||
.Bd -literal
|
||||
struct mntopt {
|
||||
char *m_option; /* option name */
|
||||
int m_inverse; /* is this a negative option, e.g., "dev" */
|
||||
int m_flag; /* bit to set, e.g., MNT_RDONLY */
|
||||
int m_altloc; /* non-zero to use altflagp rather than flagp */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width m_inverse
|
||||
.It Va m_option
|
||||
the option name,
|
||||
for example
|
||||
.Dq Li suid .
|
||||
.It Va m_inverse
|
||||
tells
|
||||
.Fn getmntopts
|
||||
that the name has the inverse meaning of the
|
||||
bit.
|
||||
For example,
|
||||
.Dq Li suid
|
||||
is the string, whereas the
|
||||
mount flag is
|
||||
.Dv MNT_NOSUID .
|
||||
In this case, the sense of the string and the flag
|
||||
are inverted, so the
|
||||
.Va m_inverse
|
||||
flag should be set.
|
||||
.It Va m_flag
|
||||
the value of the bit to be set or cleared in
|
||||
the flag word when the option is recognized.
|
||||
The bit is set when the option is discovered,
|
||||
but cleared if the option name was preceded
|
||||
by the letters
|
||||
.Dq Li no .
|
||||
The
|
||||
.Va m_inverse
|
||||
flag causes these two operations to be reversed.
|
||||
.It Va m_altloc
|
||||
the bit should be set or cleared in
|
||||
.Fa altflagp
|
||||
rather than
|
||||
.Fa flagp .
|
||||
.El
|
||||
.Pp
|
||||
Each of the user visible
|
||||
.Dv MNT_
|
||||
flags has a corresponding
|
||||
.Dv MOPT_
|
||||
macro which defines an appropriate
|
||||
.Vt "struct mntopt"
|
||||
entry.
|
||||
To simplify the program interface and ensure consistency across all
|
||||
programs, a general purpose macro,
|
||||
.Dv MOPT_STDOPTS ,
|
||||
is defined which
|
||||
contains an entry for all the generic VFS options.
|
||||
In addition, the macros
|
||||
.Dv MOPT_FORCE
|
||||
and
|
||||
.Dv MOPT_UPDATE
|
||||
exist to enable the
|
||||
.Dv MNT_FORCE
|
||||
and
|
||||
.Dv MNT_UPDATE
|
||||
flags to be set.
|
||||
Finally, the table must be terminated by an entry with a
|
||||
.Dv NULL
|
||||
first element.
|
||||
.Sh EXAMPLES
|
||||
Most commands will use the standard option set.
|
||||
Local file systems which support the
|
||||
.Dv MNT_UPDATE
|
||||
flag, would also have an
|
||||
.Dv MOPT_UPDATE
|
||||
entry.
|
||||
This can be declared and used as follows:
|
||||
.Bd -literal
|
||||
#include "mntopts.h"
|
||||
|
||||
struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_UPDATE,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
...
|
||||
mntflags = mntaltflags = 0;
|
||||
...
|
||||
getmntopts(options, mopts, &mntflags, &mntaltflags);
|
||||
...
|
||||
.Ed
|
||||
.Sh DIAGNOSTICS
|
||||
If the external integer variable
|
||||
.Va getmnt_silent
|
||||
is zero, then the
|
||||
.Fn getmntopts
|
||||
function displays an error message and exits if an
|
||||
unrecognized option is encountered.
|
||||
Otherwise unrecognized options are silently ignored.
|
||||
By default
|
||||
.Va getmnt_silent
|
||||
is zero.
|
||||
.Sh SEE ALSO
|
||||
.Xr err 3 ,
|
||||
.Xr mount 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn getmntopts
|
||||
function appeared in
|
||||
.Bx 4.4 .
|
||||
+94
-1
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -153,6 +154,98 @@ checkpath_allow_file(const char *path, char *resolved)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the mount point information for name. Name may be mount point name
|
||||
* or device name (with or without /dev/ preprended).
|
||||
*/
|
||||
struct statfs *
|
||||
getmntpoint(const char *name)
|
||||
{
|
||||
struct stat devstat, mntdevstat;
|
||||
char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
|
||||
char *ddevname;
|
||||
struct statfs *mntbuf, *statfsp;
|
||||
int i, mntsize, isdev;
|
||||
|
||||
if (stat(name, &devstat) != 0)
|
||||
return (NULL);
|
||||
if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))
|
||||
isdev = 1;
|
||||
else
|
||||
isdev = 0;
|
||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||
for (i = 0; i < mntsize; i++) {
|
||||
statfsp = &mntbuf[i];
|
||||
ddevname = statfsp->f_mntfromname;
|
||||
if (*ddevname != '/') {
|
||||
if (strlen(_PATH_DEV) + strlen(ddevname) + 1 >
|
||||
sizeof(statfsp->f_mntfromname))
|
||||
continue;
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, ddevname);
|
||||
strcpy(statfsp->f_mntfromname, device);
|
||||
}
|
||||
if (isdev == 0) {
|
||||
if (strcmp(name, statfsp->f_mntonname))
|
||||
continue;
|
||||
return (statfsp);
|
||||
}
|
||||
if (stat(ddevname, &mntdevstat) == 0 &&
|
||||
mntdevstat.st_rdev == devstat.st_rdev)
|
||||
return (statfsp);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* If possible reload a mounted filesystem.
|
||||
* When prtmsg != NULL print a warning if a reload is attempted, but fails.
|
||||
* Return 0 on success, 1 on failure.
|
||||
*/
|
||||
int
|
||||
chkdoreload(struct statfs *mntp,
|
||||
void (*prtmsg)(const char *, ...) __printflike(1,2))
|
||||
{
|
||||
struct iovec *iov;
|
||||
int iovlen, error;
|
||||
char errmsg[255];
|
||||
|
||||
/*
|
||||
* If the filesystem is not mounted it does not need to be reloaded.
|
||||
* If it is mounted for writing, then it could not have been opened
|
||||
* for writing by a utility, so does not need to be reloaded.
|
||||
*/
|
||||
if (mntp == NULL || (mntp->f_flags & MNT_RDONLY) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* We modified a mounted file system. Do a mount update on
|
||||
* it so we can continue using it as safely as possible.
|
||||
*/
|
||||
iov = NULL;
|
||||
iovlen = 0;
|
||||
errmsg[0] = '\0';
|
||||
build_iovec(&iov, &iovlen, "fstype", __DECONST(void *, "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));
|
||||
build_iovec(&iov, &iovlen, "update", NULL, 0);
|
||||
build_iovec(&iov, &iovlen, "reload", NULL, 0);
|
||||
/*
|
||||
* XX: We need the following line until we clean up
|
||||
* nmount parsing of root mounts and NFS root mounts.
|
||||
*/
|
||||
build_iovec(&iov, &iovlen, "ro", NULL, 0);
|
||||
error = nmount(iov, iovlen, mntp->f_flags);
|
||||
free_iovec(&iov, &iovlen);
|
||||
if (error == 0)
|
||||
return (0);
|
||||
if (prtmsg != NULL)
|
||||
prtmsg("mount reload of '%s' failed: %s %s\n\n",
|
||||
mntp->f_mntonname, strerror(errno), errmsg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
|
||||
size_t len)
|
||||
@@ -207,7 +300,7 @@ free_iovec(struct iovec **iov, int *iovlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < *iovlen; i++)
|
||||
for (i = 0; i < *iovlen; i += 2)
|
||||
free((*iov)[i].iov_base);
|
||||
free(*iov);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,381 @@
|
||||
.\" Copyright (c) 2023 Marshall Kirk McKusick
|
||||
.\" Copyright (c) 1994 The Regents of the University of California.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)getmntopts.3 8.3 (Berkeley) 3/30/95
|
||||
.\"
|
||||
.Dd January 19, 2023
|
||||
.Dt MNTOPTS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm getmntopts ,
|
||||
.Nm getmntpoint ,
|
||||
.Nm chkdoreload ,
|
||||
.Nm build_iovec ,
|
||||
.Nm build_iovec_argf ,
|
||||
.Nm free_iovec ,
|
||||
.Nm checkpath ,
|
||||
.Nm rmslashes
|
||||
.Nd "mount point operations"
|
||||
.Sh SYNOPSIS
|
||||
.In mntopts.h
|
||||
.Ft void
|
||||
.Fo getmntopts
|
||||
.Fa "const char *options" "const struct mntopt *mopts"
|
||||
.Fa "int *flagp" "int *altflagp"
|
||||
.Fc
|
||||
.Ft struct statfs *
|
||||
.Fn getmntpoint "const char *name"
|
||||
.Ft int
|
||||
.Fo chkdoreload
|
||||
.Fa "struct statfs *mntp"
|
||||
.Fa "void (*prtmsg)(const char *fmt, ...)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo build_iovec
|
||||
.Fa "struct iovec **iov" "int *iovlen" "const char *name" "void *val"
|
||||
.Fa "size_t len"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo build_iovec_argf
|
||||
.Fa "struct iovec **iov" "int *iovlen" "const char *name"
|
||||
.Fa "const char *fmt" "..."
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn free_iovec "struct iovec **iov" "int *iovlen"
|
||||
.Ft int
|
||||
.Fn checkpath "const char *path" "char *resolved"
|
||||
.Ft void
|
||||
.Fn rmslashes "char *rrpin" "char *rrpout"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mntopts
|
||||
functions support operations associated with a mount point.
|
||||
For historic reasons are in a file in the sources for the
|
||||
.Xr mount 8
|
||||
program.
|
||||
Thus, to access them the following lines need to be added to the
|
||||
.Nm Makefile
|
||||
of the program wanting to use them:
|
||||
.Bd -literal
|
||||
SRCS+= getmntopts.c
|
||||
MOUNT= ${SRCTOP}/sbin/mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
\&.PATH: ${MOUNT}
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Fn getmntopts
|
||||
function takes a comma separated option list and a list
|
||||
of valid option names, and computes the bitmask
|
||||
corresponding to the requested set of options.
|
||||
.Pp
|
||||
The string
|
||||
.Fa options
|
||||
is broken down into a sequence of comma separated tokens.
|
||||
Each token is looked up in the table described by
|
||||
.Fa mopts
|
||||
and the bits in
|
||||
the word referenced by either
|
||||
.Fa flagp
|
||||
or
|
||||
.Fa altflagp
|
||||
(depending on the
|
||||
.Va m_altloc
|
||||
field of the option's table entry)
|
||||
are updated.
|
||||
The flag words are not initialized by
|
||||
.Fn getmntopts .
|
||||
The table,
|
||||
.Fa mopts ,
|
||||
has the following format:
|
||||
.Bd -literal
|
||||
struct mntopt {
|
||||
char *m_option; /* option name */
|
||||
int m_inverse; /* is this a negative option, e.g., "dev" */
|
||||
int m_flag; /* bit to set, e.g., MNT_RDONLY */
|
||||
int m_altloc; /* non-zero to use altflagp rather than flagp */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width m_inverse
|
||||
.It Va m_option
|
||||
the option name,
|
||||
for example
|
||||
.Dq Li suid .
|
||||
.It Va m_inverse
|
||||
tells
|
||||
.Fn getmntopts
|
||||
that the name has the inverse meaning of the
|
||||
bit.
|
||||
For example,
|
||||
.Dq Li suid
|
||||
is the string, whereas the
|
||||
mount flag is
|
||||
.Dv MNT_NOSUID .
|
||||
In this case, the sense of the string and the flag
|
||||
are inverted, so the
|
||||
.Va m_inverse
|
||||
flag should be set.
|
||||
.It Va m_flag
|
||||
the value of the bit to be set or cleared in
|
||||
the flag word when the option is recognized.
|
||||
The bit is set when the option is discovered,
|
||||
but cleared if the option name was preceded
|
||||
by the letters
|
||||
.Dq Li no .
|
||||
The
|
||||
.Va m_inverse
|
||||
flag causes these two operations to be reversed.
|
||||
.It Va m_altloc
|
||||
the bit should be set or cleared in
|
||||
.Fa altflagp
|
||||
rather than
|
||||
.Fa flagp .
|
||||
.El
|
||||
.Pp
|
||||
Each of the user visible
|
||||
.Dv MNT_
|
||||
flags has a corresponding
|
||||
.Dv MOPT_
|
||||
macro which defines an appropriate
|
||||
.Vt "struct mntopt"
|
||||
entry.
|
||||
To simplify the program interface and ensure consistency across all
|
||||
programs, a general purpose macro,
|
||||
.Dv MOPT_STDOPTS ,
|
||||
is defined which
|
||||
contains an entry for all the generic VFS options.
|
||||
In addition, the macros
|
||||
.Dv MOPT_FORCE
|
||||
and
|
||||
.Dv MOPT_UPDATE
|
||||
exist to enable the
|
||||
.Dv MNT_FORCE
|
||||
and
|
||||
.Dv MNT_UPDATE
|
||||
flags to be set.
|
||||
Finally, the table must be terminated by an entry with a
|
||||
.Dv NULL
|
||||
first element.
|
||||
.Pp
|
||||
The
|
||||
.Fn getmntpoint
|
||||
function takes the pathname of a possible mount point
|
||||
or of a device (with or without
|
||||
.Pa /dev/
|
||||
prepended to it).
|
||||
If the pathname is a directory or a file,
|
||||
.Fn getmntpoint
|
||||
checks to see if the mount point currently has a filesystem
|
||||
mounted on it.
|
||||
If the pathname is a device,
|
||||
.Fn getmntpoint
|
||||
checks to see if it is currently mounted.
|
||||
If there is an associated mount, a pointer to a
|
||||
.Vt "struct statfs"
|
||||
is returned.
|
||||
The returned result is stored in a static buffer that is over-written
|
||||
each time the
|
||||
.Fn getmntpoint
|
||||
function or the
|
||||
.Xr getmntinfo 3
|
||||
library routine is called.
|
||||
If no mount is found, NULL is returned.
|
||||
.Pp
|
||||
The
|
||||
.Fn chkdoreload
|
||||
function takes a pointer to a
|
||||
.Vt "struct statfs" .
|
||||
If the filesystem associated with the mount point is mounted read-only,
|
||||
.Fn chkdoreload
|
||||
requests the filesystem to reload all of its metadata from its backing store.
|
||||
The second parameter is the function to call to print an error message
|
||||
if the reload fails.
|
||||
If no error message is desired, a
|
||||
.Dv NULL
|
||||
can be passed as the second argument.
|
||||
The
|
||||
.Fn chkdoreload
|
||||
function returns zero on success or non-zero on failure.
|
||||
.Pp
|
||||
The
|
||||
.Fn build_iovec
|
||||
function adds a parameter to a list of parameters to be passed to the
|
||||
.Xr nmount 2
|
||||
system call.
|
||||
The parameter list is built up in
|
||||
.Va iov
|
||||
and its length is kept in
|
||||
.Va iovlen .
|
||||
Before the first call to
|
||||
.Fn build_iovec ,
|
||||
.Va iov
|
||||
should be set to
|
||||
.Dv NULL
|
||||
and
|
||||
.Va iovlen
|
||||
should be set to 0.
|
||||
The parameter name is passed in
|
||||
.Va name .
|
||||
The value of the parameter name is pointed to by
|
||||
.Va val .
|
||||
The size of the value is passed in
|
||||
.Va len .
|
||||
If the value is a string, a
|
||||
.Va len
|
||||
of -1 is passed to indicate that the length should be determined using
|
||||
.Xr strlen 3 .
|
||||
If the parameter has no value,
|
||||
.Va name
|
||||
should be
|
||||
.Dv NULL
|
||||
and
|
||||
.Va len
|
||||
should be 0.
|
||||
.Pp
|
||||
The
|
||||
.Fn build_iovec_argf
|
||||
function adds a formatted parameter to a list of parameters to be passed
|
||||
to the
|
||||
.Xr nmount 2
|
||||
system call.
|
||||
The parameter list is built up in
|
||||
.Va iov
|
||||
and its length is kept in
|
||||
.Va iovlen .
|
||||
Before the first call to
|
||||
.Fn build_iovec_argf ,
|
||||
.Va iov
|
||||
should be set to
|
||||
.Dv NULL
|
||||
and
|
||||
.Va iovlen
|
||||
should be set to 0.
|
||||
The parameter name is passed in
|
||||
.Va name .
|
||||
The value of the parameter name is described by a format string pointed to by
|
||||
.Va fmt .
|
||||
If the parameter has no value,
|
||||
.Va name
|
||||
should be
|
||||
.Dv NULL .
|
||||
.Pp
|
||||
The
|
||||
.Fn free_iovec
|
||||
function frees the memory in the
|
||||
.Va iov
|
||||
vector of the length specified in
|
||||
.Va iovlen
|
||||
that was previously allocated by the
|
||||
.Fn build_iovec
|
||||
and / or
|
||||
.Fn build_iovec_argf
|
||||
functions.
|
||||
The
|
||||
.Va iov
|
||||
is set to
|
||||
.Dv NULL
|
||||
and the
|
||||
.Va iovlen
|
||||
is set to 0 to indicate that the space has been freed.
|
||||
.Pp
|
||||
The
|
||||
.Fn checkpath
|
||||
function uses
|
||||
.Xr realpath 3
|
||||
to verify that its
|
||||
.Va path
|
||||
argument is valid and references a directory.
|
||||
The
|
||||
.Fn checkpath
|
||||
function returns zero on success or non-zero on failure.
|
||||
.Pp
|
||||
The
|
||||
.Fn rmslashes
|
||||
function removes all double slashes and trailing slashes from its
|
||||
.Va rrpin
|
||||
pathname parameter and returns the resulting pathname in its
|
||||
.Va rrpout
|
||||
parameter.
|
||||
.Sh EXAMPLES
|
||||
Most commands will use the standard option set.
|
||||
Local file systems which support the
|
||||
.Dv MNT_UPDATE
|
||||
flag, would also have an
|
||||
.Dv MOPT_UPDATE
|
||||
entry.
|
||||
This can be declared and used as follows:
|
||||
.Bd -literal
|
||||
#include "mntopts.h"
|
||||
|
||||
struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_UPDATE,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
...
|
||||
mntflags = mntaltflags = 0;
|
||||
...
|
||||
getmntopts(options, mopts, &mntflags, &mntaltflags);
|
||||
...
|
||||
.Ed
|
||||
.Sh DIAGNOSTICS
|
||||
If the external integer variable
|
||||
.Va getmnt_silent
|
||||
is zero, then the
|
||||
.Fn getmntopts
|
||||
function displays an error message and exits if an
|
||||
unrecognized option is encountered.
|
||||
Otherwise unrecognized options are silently ignored.
|
||||
By default
|
||||
.Va getmnt_silent
|
||||
is zero.
|
||||
.Sh SEE ALSO
|
||||
.Xr err 3 ,
|
||||
.Xr mount 8 ,
|
||||
.Xr nmount 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn getmntopts
|
||||
function appeared in
|
||||
.Bx 4.4 .
|
||||
The
|
||||
.Fn build_iovec ,
|
||||
.Fn build_iovec_argf ,
|
||||
.Fn free_iovec ,
|
||||
.Fn checkpath ,
|
||||
and
|
||||
.Fn rmslashes
|
||||
functions were added with
|
||||
.Xr nmount 8
|
||||
in
|
||||
.Fx 5.0 .
|
||||
The
|
||||
.Fn getmntpoint
|
||||
and
|
||||
.Fn chkdoreload
|
||||
functions were added in
|
||||
.Fx 14.0 .
|
||||
@@ -104,6 +104,8 @@ void getmntopts(const char *, const struct mntopt *, int *, int *);
|
||||
void rmslashes(char *, char *);
|
||||
int checkpath(const char *, char resolved_path[]);
|
||||
int checkpath_allow_file(const char *, char resolved_path[]);
|
||||
struct statfs *getmntpoint(const char *);
|
||||
int chkdoreload(struct statfs *, void (*)(const char *, ...) __printflike(1,2));
|
||||
extern int getmnt_silent;
|
||||
void build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, size_t len);
|
||||
void build_iovec_argf(struct iovec **iov, int *iovlen, const char *name, const char *fmt, ...);
|
||||
|
||||
+1
-17
@@ -85,7 +85,6 @@ struct cpa {
|
||||
};
|
||||
|
||||
char *catopt(char *, const char *);
|
||||
struct statfs *getmntpt(const char *);
|
||||
int hasopt(const char *, const char *);
|
||||
int ismounted(struct fstab *, struct statfs *, int);
|
||||
int isremountable(const char *);
|
||||
@@ -394,7 +393,7 @@ main(int argc, char *argv[])
|
||||
if (init_flags & MNT_UPDATE) {
|
||||
mntfromname = NULL;
|
||||
have_fstab = 0;
|
||||
if ((mntbuf = getmntpt(*argv)) == NULL)
|
||||
if ((mntbuf = getmntpoint(*argv)) == NULL)
|
||||
xo_errx(1, "not currently mounted %s", *argv);
|
||||
/*
|
||||
* Only get the mntflags from fstab if both mntpoint
|
||||
@@ -738,21 +737,6 @@ prmount(struct statfs *sfp)
|
||||
xo_emit("{D:)}\n");
|
||||
}
|
||||
|
||||
struct statfs *
|
||||
getmntpt(const char *name)
|
||||
{
|
||||
struct statfs *mntbuf;
|
||||
int i, mntsize;
|
||||
|
||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||
for (i = mntsize - 1; i >= 0; i--) {
|
||||
if (strcmp(mntbuf[i].f_mntfromname, name) == 0 ||
|
||||
strcmp(mntbuf[i].f_mntonname, name) == 0)
|
||||
return (&mntbuf[i]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
char *
|
||||
catopt(char *s0, const char *s1)
|
||||
{
|
||||
|
||||
+5
-28
@@ -89,18 +89,14 @@ main(int argc, char *argv[])
|
||||
{
|
||||
const char *avalue, *jvalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue;
|
||||
const char *tvalue;
|
||||
const char *special, *on;
|
||||
const char *special;
|
||||
const char *name;
|
||||
int active;
|
||||
char *diskname;
|
||||
int Aflag, aflag, eflag, evalue, fflag, fvalue, jflag, Jflag, kflag;
|
||||
int kvalue, Lflag, lflag, mflag, mvalue, Nflag, nflag, oflag, ovalue;
|
||||
int pflag, sflag, svalue, Svalue, tflag;
|
||||
int ch, found_arg, i;
|
||||
int iovlen = 0;
|
||||
const char *chg[2];
|
||||
struct statfs stfs;
|
||||
struct iovec *iov = NULL;
|
||||
char errmsg[255] = {0};
|
||||
|
||||
if (argc < 3)
|
||||
usage();
|
||||
@@ -108,7 +104,6 @@ main(int argc, char *argv[])
|
||||
lflag = mflag = Nflag = nflag = oflag = pflag = sflag = tflag = 0;
|
||||
avalue = jvalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL;
|
||||
evalue = fvalue = mvalue = ovalue = svalue = Svalue = 0;
|
||||
active = 0;
|
||||
found_arg = 0; /* At least one arg is required. */
|
||||
while ((ch = getopt(argc, argv, "Aa:e:f:j:J:k:L:l:m:N:n:o:ps:S:t:"))
|
||||
!= -1)
|
||||
@@ -307,7 +302,7 @@ main(int argc, char *argv[])
|
||||
if (found_arg == 0 || argc != 1)
|
||||
usage();
|
||||
|
||||
on = special = argv[0];
|
||||
special = argv[0];
|
||||
if (ufs_disk_fillout(&disk, special) == -1)
|
||||
goto err;
|
||||
/*
|
||||
@@ -317,13 +312,6 @@ main(int argc, char *argv[])
|
||||
(sblock.fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) != 0) &&
|
||||
(found_arg > 1 || !pflag))
|
||||
errx(1, "%s is not clean - run fsck.\n", special);
|
||||
if (disk.d_name != special) {
|
||||
if (statfs(special, &stfs) != 0)
|
||||
warn("Can't stat %s", special);
|
||||
if (strcmp(special, stfs.f_mntonname) == 0)
|
||||
active = 1;
|
||||
}
|
||||
|
||||
if (pflag) {
|
||||
printfs();
|
||||
exit(0);
|
||||
@@ -568,20 +556,9 @@ main(int argc, char *argv[])
|
||||
|
||||
if (sbwrite(&disk, Aflag) == -1)
|
||||
goto err;
|
||||
diskname = strdup(disk.d_name);
|
||||
ufs_disk_close(&disk);
|
||||
if (active) {
|
||||
build_iovec_argf(&iov, &iovlen, "fstype", "ufs");
|
||||
build_iovec_argf(&iov, &iovlen, "fspath", "%s", on);
|
||||
build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));
|
||||
if (nmount(iov, iovlen,
|
||||
stfs.f_flags | MNT_UPDATE | MNT_RELOAD) < 0) {
|
||||
if (errmsg[0])
|
||||
err(9, "%s: reload: %s", special, errmsg);
|
||||
else
|
||||
err(9, "%s: reload", special);
|
||||
}
|
||||
warnx("file system reloaded");
|
||||
}
|
||||
chkdoreload(getmntpoint(diskname), warnx);
|
||||
exit(0);
|
||||
err:
|
||||
if (disk.d_error != NULL)
|
||||
|
||||
Reference in New Issue
Block a user