Introduce the "ruleset=number" option for devfs(5) mounts.

Add support for updating the devfs mount (currently only changing the
ruleset number is supported).
Check mnt_optnew with vfs_filteropt(9).

This new option sets the specified ruleset number as the active ruleset
of the new devfs mount and applies all its rules at mount time. If the
specified ruleset doesn't exist, a new empty ruleset is created.

MFC after:	1 month
This commit is contained in:
Martin Matuska 2012-02-09 10:09:12 +00:00
parent 870a6d5181
commit 17d84d611f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=231265
4 changed files with 103 additions and 2 deletions

View file

@ -38,7 +38,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 18, 2010
.Dd February 9, 2012
.Dt DEVFS 5
.Os
.Sh NAME
@ -90,6 +90,29 @@ and
.Pa 2 .
.Xr fdescfs 5
creates files for all open descriptors.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl o Ar options
Use the specified mount
.Ar options ,
as described in
.Xr mount 8 .
The following devfs file system-specific options are available:
.Bl -tag -width indent
.It Cm ruleset Ns No = Ns Ar ruleset
Set ruleset number
.Ar ruleset
as the current ruleset for the mount-point and apply all its rules. If the
ruleset number
.Ar ruleset
does not exist, an empty ruleset with the number
.Ar ruleset
is created. See
.Xr devfs 8
for more information on working with devfs rulesets.
.El
.El
.Sh FILES
.Bl -tag -width /dev/XXXX -compact
.It Pa /dev

View file

@ -182,6 +182,8 @@ void devfs_rules_apply(struct devfs_mount *, struct devfs_dirent *);
void devfs_rules_cleanup(struct devfs_mount *);
int devfs_rules_ioctl(struct devfs_mount *, u_long, caddr_t,
struct thread *);
void devfs_ruleset_set(devfs_rsnum rsnum, struct devfs_mount *dm);
void devfs_ruleset_apply(struct devfs_mount *dm);
int devfs_allocv(struct devfs_dirent *, struct mount *, int,
struct vnode **);
char *devfs_fqpn(char *, struct devfs_mount *, struct devfs_dirent *,

View file

@ -771,3 +771,38 @@ devfs_rules_cleanup(struct devfs_mount *dm)
devfs_ruleset_reap(ds);
}
}
/*
* Make rsnum the active ruleset for dm (locked)
*/
void
devfs_ruleset_set(devfs_rsnum rsnum, struct devfs_mount *dm)
{
sx_assert(&dm->dm_lock, SX_XLOCKED);
sx_xlock(&sx_rules);
devfs_ruleset_use(rsnum, dm);
sx_xunlock(&sx_rules);
}
/*
* Apply the current active ruleset on a mount
*/
void
devfs_ruleset_apply(struct devfs_mount *dm)
{
struct devfs_ruleset *ds;
sx_assert(&dm->dm_lock, SX_XLOCKED);
sx_xlock(&sx_rules);
if (dm->dm_ruleset == 0) {
sx_xunlock(&sx_rules);
return;
}
ds = devfs_ruleset_bynum(dm->dm_ruleset);
if (ds != NULL)
devfs_ruleset_applydm(ds, dm);
sx_xunlock(&sx_rules);
}

View file

@ -56,6 +56,10 @@ static vfs_unmount_t devfs_unmount;
static vfs_root_t devfs_root;
static vfs_statfs_t devfs_statfs;
static const char *devfs_opts[] = {
"from", "ruleset", NULL
};
/*
* Mount the filesystem
*/
@ -65,15 +69,46 @@ devfs_mount(struct mount *mp)
int error;
struct devfs_mount *fmp;
struct vnode *rvp;
int rsnum;
if (devfs_unr == NULL)
devfs_unr = new_unrhdr(0, INT_MAX, NULL);
error = 0;
if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS))
if (mp->mnt_flag & MNT_ROOTFS)
return (EOPNOTSUPP);
rsnum = 0;
if (mp->mnt_optnew != NULL) {
if (vfs_filteropt(mp->mnt_optnew, devfs_opts))
return (EINVAL);
if (vfs_getopt(mp->mnt_optnew, "ruleset", NULL, NULL) == 0 &&
(vfs_scanopt(mp->mnt_optnew, "ruleset", "%d",
&rsnum) != 1 || rsnum < 0 || rsnum > 65535))
error = EINVAL;
}
if (error) {
vfs_mount_error(mp, "%s", "invalid ruleset specification");
return (error);
}
if (mp->mnt_flag & MNT_UPDATE) {
if (rsnum != 0) {
fmp = mp->mnt_data;
if (fmp != NULL) {
sx_xlock(&fmp->dm_lock);
devfs_ruleset_set((devfs_rsnum)rsnum, fmp);
devfs_ruleset_apply(fmp);
sx_xunlock(&fmp->dm_lock);
}
}
return (0);
}
fmp = malloc(sizeof *fmp, M_DEVFS, M_WAITOK | M_ZERO);
fmp->dm_idx = alloc_unr(devfs_unr);
sx_init(&fmp->dm_lock, "devfsmount");
@ -101,6 +136,12 @@ devfs_mount(struct mount *mp)
return (error);
}
if (rsnum != 0) {
sx_xlock(&fmp->dm_lock);
devfs_ruleset_set((devfs_rsnum)rsnum, fmp);
sx_xunlock(&fmp->dm_lock);
}
VOP_UNLOCK(rvp, 0);
vfs_mountedfrom(mp, "devfs");