Document the mntopts(3) functions.
The mntopts(3) functions support operations associated with a mount point. The main purpose of this commit is to document the mntopts(3) functions that now appear in 18 utilities in the base system. See mntopts(3) for the documentation details. The getmntopts() function appeared in 4.4BSD. The build_iovec(), build_iovec_argf(), free_iovec(), checkpath(), and rmslashes() functions were added with nmount(8) in FreeBSD 5.0. The getmntpoint() and chkdoreload() functions are being added in this commit. These functions should be in a library but for historic reasons are in a file in the sources for the mount(8) program. Thus, to access them the following lines need to be added to the Makefile of the program wanting to use them: SRCS+= getmntopts.c MOUNT= ${SRCTOP}/sbin/mount CFLAGS+= -I${MOUNT} .PATH: ${MOUNT} Once these changes have been MFC'ed to 13 they may be made into a library. Reviewed by: kib, gbe MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D37907
This commit is contained in:
parent
6468b6b23e
commit
906c312bbf
@ -4,6 +4,10 @@
|
|||||||
PACKAGE=runtime
|
PACKAGE=runtime
|
||||||
PROG= fsck
|
PROG= fsck
|
||||||
SRCS= fsck.c fsutil.c preen.c
|
SRCS= fsck.c fsutil.c preen.c
|
||||||
|
SRCS+= getmntopts.c
|
||||||
MAN= fsck.8
|
MAN= fsck.8
|
||||||
|
MOUNT= ${SRCTOP}/sbin/mount
|
||||||
|
CFLAGS+= -I${MOUNT}
|
||||||
|
.PATH: ${MOUNT}
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <fstab.h>
|
#include <fstab.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <mntopts.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -206,7 +207,7 @@ main(int argc, char *argv[])
|
|||||||
_PATH_DEV, spec);
|
_PATH_DEV, spec);
|
||||||
spec = device;
|
spec = device;
|
||||||
}
|
}
|
||||||
mntp = getmntpt(spec);
|
mntp = getmntpoint(spec);
|
||||||
if (mntp != NULL) {
|
if (mntp != NULL) {
|
||||||
spec = mntp->f_mntfromname;
|
spec = mntp->f_mntfromname;
|
||||||
mntpt = mntp->f_mntonname;
|
mntpt = mntp->f_mntonname;
|
||||||
@ -269,7 +270,7 @@ isok(struct fstab *fs)
|
|||||||
if (flags & DO_BACKGRD) {
|
if (flags & DO_BACKGRD) {
|
||||||
if (!strcmp(fs->fs_type, FSTAB_RO))
|
if (!strcmp(fs->fs_type, FSTAB_RO))
|
||||||
return (0);
|
return (0);
|
||||||
if (getmntpt(fs->fs_spec) == NULL)
|
if (getmntpoint(fs->fs_spec) == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
if (checkfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, "-F", 0))
|
if (checkfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, "-F", 0))
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -188,50 +188,6 @@ devcheck(const char *origname)
|
|||||||
return (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 *
|
void *
|
||||||
emalloc(size_t s)
|
emalloc(size_t s)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,6 @@ void panic(const char *, ...) __dead2 __printflike(1, 2);
|
|||||||
const char *devcheck(const char *);
|
const char *devcheck(const char *);
|
||||||
const char *cdevname(void);
|
const char *cdevname(void);
|
||||||
void setcdevname(const char *, int);
|
void setcdevname(const char *, int);
|
||||||
struct statfs *getmntpt(const char *);
|
|
||||||
void *emalloc(size_t);
|
void *emalloc(size_t);
|
||||||
void *erealloc(void *, size_t);
|
void *erealloc(void *, size_t);
|
||||||
char *estrdup(const char *);
|
char *estrdup(const char *);
|
||||||
|
@ -76,8 +76,6 @@ static void usage(void) __dead2;
|
|||||||
static intmax_t argtoimax(int flag, const char *req, const char *str, int base);
|
static intmax_t argtoimax(int flag, const char *req, const char *str, int base);
|
||||||
static int checkfilesys(char *filesys);
|
static int checkfilesys(char *filesys);
|
||||||
static int setup_bkgrdchk(struct statfs *mntp, int sbrdfailed, 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
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
@ -258,7 +256,7 @@ checkfilesys(char *filesys)
|
|||||||
* if it is listed among the mounted file systems. Failing that
|
* if it is listed among the mounted file systems. Failing that
|
||||||
* check to see if it is listed in /etc/fstab.
|
* check to see if it is listed in /etc/fstab.
|
||||||
*/
|
*/
|
||||||
mntp = getmntpt(filesys);
|
mntp = getmntpoint(filesys);
|
||||||
if (mntp != NULL)
|
if (mntp != NULL)
|
||||||
filesys = mntp->f_mntfromname;
|
filesys = mntp->f_mntfromname;
|
||||||
else
|
else
|
||||||
@ -311,7 +309,7 @@ checkfilesys(char *filesys)
|
|||||||
(FS_UNCLEAN | FS_NEEDSFSCK)) == 0) {
|
(FS_UNCLEAN | FS_NEEDSFSCK)) == 0) {
|
||||||
bufinit();
|
bufinit();
|
||||||
gjournal_check(filesys);
|
gjournal_check(filesys);
|
||||||
if (chkdoreload(mntp) == 0)
|
if (chkdoreload(mntp, pwarn) == 0)
|
||||||
exit(0);
|
exit(0);
|
||||||
exit(4);
|
exit(4);
|
||||||
} else {
|
} else {
|
||||||
@ -357,7 +355,7 @@ checkfilesys(char *filesys)
|
|||||||
sujrecovery = 1;
|
sujrecovery = 1;
|
||||||
if (suj_check(filesys) == 0) {
|
if (suj_check(filesys) == 0) {
|
||||||
printf("\n***** FILE SYSTEM MARKED CLEAN *****\n");
|
printf("\n***** FILE SYSTEM MARKED CLEAN *****\n");
|
||||||
if (chkdoreload(mntp) == 0)
|
if (chkdoreload(mntp, pwarn) == 0)
|
||||||
exit(0);
|
exit(0);
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
@ -561,7 +559,7 @@ checkfilesys(char *filesys)
|
|||||||
return (ERESTART);
|
return (ERESTART);
|
||||||
printf("\n***** PLEASE RERUN FSCK *****\n");
|
printf("\n***** PLEASE RERUN FSCK *****\n");
|
||||||
}
|
}
|
||||||
if (chkdoreload(mntp) != 0) {
|
if (chkdoreload(mntp, pwarn) != 0) {
|
||||||
if (!fsmodified)
|
if (!fsmodified)
|
||||||
return (0);
|
return (0);
|
||||||
if (!preen)
|
if (!preen)
|
||||||
@ -715,92 +713,6 @@ setup_bkgrdchk(struct statfs *mntp, int sbreadfailed, char **filesys)
|
|||||||
return (1);
|
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
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
|
@ -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 updcsloc(time_t, int, int, unsigned int);
|
||||||
static void frag_adjust(ufs2_daddr_t, int);
|
static void frag_adjust(ufs2_daddr_t, int);
|
||||||
static void updclst(int);
|
static void updclst(int);
|
||||||
static void mount_reload(const struct statfs *stfs);
|
|
||||||
static void cgckhash(struct cg *);
|
static void cgckhash(struct cg *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1263,76 +1262,11 @@ is_dev(const char *name)
|
|||||||
return (1);
|
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 *
|
static const char *
|
||||||
mountpoint_to_dev(const char *mountpoint)
|
getdev(const char *name, struct statfs *statfsp)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
static char device[MAXPATHLEN];
|
static char device[MAXPATHLEN];
|
||||||
const char *cp, *dev;
|
const char *cp;
|
||||||
|
|
||||||
if (is_dev(name))
|
if (is_dev(name))
|
||||||
return (name);
|
return (name);
|
||||||
@ -1344,9 +1278,8 @@ getdev(const char *name)
|
|||||||
return (device);
|
return (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = mountpoint_to_dev(name);
|
if (statfsp != NULL)
|
||||||
if (dev != NULL && is_dev(dev))
|
return (statfsp->f_mntfromname);
|
||||||
return (dev);
|
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -1378,7 +1311,7 @@ main(int argc, char **argv)
|
|||||||
DBG_FUNC("main")
|
DBG_FUNC("main")
|
||||||
struct fs *fs;
|
struct fs *fs;
|
||||||
const char *device;
|
const char *device;
|
||||||
const struct statfs *statfsp;
|
struct statfs *statfsp;
|
||||||
uint64_t size = 0;
|
uint64_t size = 0;
|
||||||
off_t mediasize;
|
off_t mediasize;
|
||||||
int error, j, fsi, fso, ch, ret, Nflag = 0, yflag = 0;
|
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.
|
* Now try to guess the device name.
|
||||||
*/
|
*/
|
||||||
device = getdev(*argv);
|
statfsp = getmntpoint(*argv);
|
||||||
|
device = getdev(*argv, statfsp);
|
||||||
if (device == NULL)
|
if (device == NULL)
|
||||||
errx(1, "cannot find special device for %s", *argv);
|
errx(1, "cannot find special device for %s", *argv);
|
||||||
|
|
||||||
statfsp = dev_to_statfs(device);
|
|
||||||
|
|
||||||
fsi = open(device, O_RDONLY);
|
fsi = open(device, O_RDONLY);
|
||||||
if (fsi < 0)
|
if (fsi < 0)
|
||||||
err(1, "%s", device);
|
err(1, "%s", device);
|
||||||
@ -1666,8 +1598,9 @@ main(int argc, char **argv)
|
|||||||
error = close(fso);
|
error = close(fso);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
err(1, "close");
|
err(1, "close");
|
||||||
if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) != 0)
|
if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) != 0 &&
|
||||||
mount_reload(statfsp);
|
chkdoreload(statfsp, warn) != 0)
|
||||||
|
exit(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_CLOSE;
|
DBG_CLOSE;
|
||||||
@ -1734,29 +1667,6 @@ updclst(int block)
|
|||||||
return;
|
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.
|
* Calculate the check-hash of the cylinder group.
|
||||||
*/
|
*/
|
||||||
|
@ -4,8 +4,15 @@
|
|||||||
PACKAGE=runtime
|
PACKAGE=runtime
|
||||||
PROG= mount
|
PROG= mount
|
||||||
SRCS= mount.c mount_fs.c getmntopts.c vfslist.c
|
SRCS= mount.c mount_fs.c getmntopts.c vfslist.c
|
||||||
MAN= mount.8
|
MAN= mntopts.3 mount.8
|
||||||
# We do NOT install the getmntopts.3 man page.
|
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
|
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 .
|
|
@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <paths.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -153,6 +154,98 @@ checkpath_allow_file(const char *path, char *resolved)
|
|||||||
return (0);
|
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
|
void
|
||||||
build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
|
build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
|
||||||
size_t len)
|
size_t len)
|
||||||
@ -207,7 +300,7 @@ free_iovec(struct iovec **iov, int *iovlen)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < *iovlen; i++)
|
for (i = 0; i < *iovlen; i += 2)
|
||||||
free((*iov)[i].iov_base);
|
free((*iov)[i].iov_base);
|
||||||
free(*iov);
|
free(*iov);
|
||||||
}
|
}
|
||||||
|
381
sbin/mount/mntopts.3
Normal file
381
sbin/mount/mntopts.3
Normal file
@ -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 *);
|
void rmslashes(char *, char *);
|
||||||
int checkpath(const char *, char resolved_path[]);
|
int checkpath(const char *, char resolved_path[]);
|
||||||
int checkpath_allow_file(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;
|
extern int getmnt_silent;
|
||||||
void build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, size_t len);
|
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, ...);
|
void build_iovec_argf(struct iovec **iov, int *iovlen, const char *name, const char *fmt, ...);
|
||||||
|
@ -85,7 +85,6 @@ struct cpa {
|
|||||||
};
|
};
|
||||||
|
|
||||||
char *catopt(char *, const char *);
|
char *catopt(char *, const char *);
|
||||||
struct statfs *getmntpt(const char *);
|
|
||||||
int hasopt(const char *, const char *);
|
int hasopt(const char *, const char *);
|
||||||
int ismounted(struct fstab *, struct statfs *, int);
|
int ismounted(struct fstab *, struct statfs *, int);
|
||||||
int isremountable(const char *);
|
int isremountable(const char *);
|
||||||
@ -369,7 +368,7 @@ main(int argc, char *argv[])
|
|||||||
if (init_flags & MNT_UPDATE) {
|
if (init_flags & MNT_UPDATE) {
|
||||||
mntfromname = NULL;
|
mntfromname = NULL;
|
||||||
have_fstab = 0;
|
have_fstab = 0;
|
||||||
if ((mntbuf = getmntpt(*argv)) == NULL)
|
if ((mntbuf = getmntpoint(*argv)) == NULL)
|
||||||
xo_errx(1, "not currently mounted %s", *argv);
|
xo_errx(1, "not currently mounted %s", *argv);
|
||||||
/*
|
/*
|
||||||
* Only get the mntflags from fstab if both mntpoint
|
* Only get the mntflags from fstab if both mntpoint
|
||||||
@ -719,21 +718,6 @@ prmount(struct statfs *sfp)
|
|||||||
xo_emit("{D:)}\n");
|
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 *
|
char *
|
||||||
catopt(char *s0, const char *s1)
|
catopt(char *s0, const char *s1)
|
||||||
{
|
{
|
||||||
|
@ -91,18 +91,14 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
const char *avalue, *jvalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue;
|
const char *avalue, *jvalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue;
|
||||||
const char *tvalue;
|
const char *tvalue;
|
||||||
const char *special, *on;
|
const char *special;
|
||||||
const char *name;
|
const char *name;
|
||||||
int active;
|
char *diskname;
|
||||||
int Aflag, aflag, eflag, evalue, fflag, fvalue, jflag, Jflag, kflag;
|
int Aflag, aflag, eflag, evalue, fflag, fvalue, jflag, Jflag, kflag;
|
||||||
int kvalue, Lflag, lflag, mflag, mvalue, Nflag, nflag, oflag, ovalue;
|
int kvalue, Lflag, lflag, mflag, mvalue, Nflag, nflag, oflag, ovalue;
|
||||||
int pflag, sflag, svalue, Svalue, tflag;
|
int pflag, sflag, svalue, Svalue, tflag;
|
||||||
int ch, found_arg, i;
|
int ch, found_arg, i;
|
||||||
int iovlen = 0;
|
|
||||||
const char *chg[2];
|
const char *chg[2];
|
||||||
struct statfs stfs;
|
|
||||||
struct iovec *iov = NULL;
|
|
||||||
char errmsg[255] = {0};
|
|
||||||
|
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
usage();
|
usage();
|
||||||
@ -110,7 +106,6 @@ main(int argc, char *argv[])
|
|||||||
lflag = mflag = Nflag = nflag = oflag = pflag = sflag = tflag = 0;
|
lflag = mflag = Nflag = nflag = oflag = pflag = sflag = tflag = 0;
|
||||||
avalue = jvalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL;
|
avalue = jvalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL;
|
||||||
evalue = fvalue = mvalue = ovalue = svalue = Svalue = 0;
|
evalue = fvalue = mvalue = ovalue = svalue = Svalue = 0;
|
||||||
active = 0;
|
|
||||||
found_arg = 0; /* At least one arg is required. */
|
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:"))
|
while ((ch = getopt(argc, argv, "Aa:e:f:j:J:k:L:l:m:N:n:o:ps:S:t:"))
|
||||||
!= -1)
|
!= -1)
|
||||||
@ -309,7 +304,7 @@ main(int argc, char *argv[])
|
|||||||
if (found_arg == 0 || argc != 1)
|
if (found_arg == 0 || argc != 1)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
on = special = argv[0];
|
special = argv[0];
|
||||||
if (ufs_disk_fillout(&disk, special) == -1)
|
if (ufs_disk_fillout(&disk, special) == -1)
|
||||||
goto err;
|
goto err;
|
||||||
/*
|
/*
|
||||||
@ -319,13 +314,6 @@ main(int argc, char *argv[])
|
|||||||
(sblock.fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) != 0) &&
|
(sblock.fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) != 0) &&
|
||||||
(found_arg > 1 || !pflag))
|
(found_arg > 1 || !pflag))
|
||||||
errx(1, "%s is not clean - run fsck.\n", special);
|
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) {
|
if (pflag) {
|
||||||
printfs();
|
printfs();
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -570,20 +558,9 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sbwrite(&disk, Aflag) == -1)
|
if (sbwrite(&disk, Aflag) == -1)
|
||||||
goto err;
|
goto err;
|
||||||
|
diskname = strdup(disk.d_name);
|
||||||
ufs_disk_close(&disk);
|
ufs_disk_close(&disk);
|
||||||
if (active) {
|
chkdoreload(getmntpoint(diskname), warnx);
|
||||||
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");
|
|
||||||
}
|
|
||||||
exit(0);
|
exit(0);
|
||||||
err:
|
err:
|
||||||
if (disk.d_error != NULL)
|
if (disk.d_error != NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user