summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/man/man5/devfs.525
-rw-r--r--sys/fs/devfs/devfs.h2
-rw-r--r--sys/fs/devfs/devfs_rule.c35
-rw-r--r--sys/fs/devfs/devfs_vfsops.c43
4 files changed, 103 insertions, 2 deletions
diff --git a/share/man/man5/devfs.5 b/share/man/man5/devfs.5
index 8c7e598..7b483fc 100644
--- a/share/man/man5/devfs.5
+++ b/share/man/man5/devfs.5
@@ -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
diff --git a/sys/fs/devfs/devfs.h b/sys/fs/devfs/devfs.h
index d148f8e..d77baa8 100644
--- a/sys/fs/devfs/devfs.h
+++ b/sys/fs/devfs/devfs.h
@@ -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 *,
diff --git a/sys/fs/devfs/devfs_rule.c b/sys/fs/devfs/devfs_rule.c
index ea05797..f37dd9d 100644
--- a/sys/fs/devfs/devfs_rule.c
+++ b/sys/fs/devfs/devfs_rule.c
@@ -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);
+}
diff --git a/sys/fs/devfs/devfs_vfsops.c b/sys/fs/devfs/devfs_vfsops.c
index 87ec162..bba4bfc 100644
--- a/sys/fs/devfs/devfs_vfsops.c
+++ b/sys/fs/devfs/devfs_vfsops.c
@@ -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");
OpenPOWER on IntegriCloud