Boris Popov <[EMAIL PROTECTED]> writes:
> This is not a bikeshed, but sysctl is the wrong interface to do
> this. Use VFSs/VOPs instead. This isn't a big problem with passing string
> from kernel to userland.
I like your idea of using the extattr interface. It isn't a perfect
match, since ideally this would be a VFS operation, but it works quite
well. The only modifications required are to mount(8) to try to get
this attribute, and then to any filesystem which wishes to support it.
Below is a patch which makes the necessary changes to mount(8), and
adds support for this to NFS. It's amazingly simple, and doesn't
interfere with anything else (i.e., you don't have to rebuild half the
world to use it). The only thing I don't like is that the "mountopts"
and "mountopts_verbose" constants aren't macroized, but that can be
easily solved (I just didn't know where to put them). With it,
mount(8) outputs stuff like this:
dima@spike% /sbin/mount -vt nfs
pid295@spike:/host on /host (nfs, v2, udp, hard, intr)
pid295@spike:/st on /st (nfs, v2, udp, hard, intr)
bazooka:/a on /.amd/bazooka/host/a (nfs, nodev, nosuid, v3, tcp, hard, intr)
bazooka:/b on /.amd/bazooka/host/b (nfs, nodev, nosuid, v3, tcp, hard, intr)
Comments? Suggestions?
Thanks in advance
Dima Dorfman
[EMAIL PROTECTED]
P.S. Would anyone have a fit if I wrote man pages for
extattr_get_file, extattr_set_file, and extattr_delete_file?
Index: sbin/mount/mount.c
===================================================================
RCS file: /st/src/FreeBSD/src/sbin/mount/mount.c,v
retrieving revision 1.41
diff -u -r1.41 mount.c
--- sbin/mount/mount.c 2000/11/22 17:54:56 1.41
+++ sbin/mount/mount.c 2001/03/25 22:16:14
@@ -49,6 +49,7 @@
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#include <sys/uio.h>
#include <err.h>
#include <errno.h>
@@ -505,6 +506,8 @@
int flags;
struct opt *o;
struct passwd *pw;
+ struct iovec iov;
+ char buf[128];
(void)printf("%s on %s (%s", sfp->f_mntfromname, sfp->f_mntonname,
sfp->f_fstypename);
@@ -515,6 +518,11 @@
(void)printf(", %s", o->o_name);
flags &= ~o->o_opt;
}
+ iov.iov_base = buf;
+ iov.iov_len = sizeof(buf);
+ if (extattr_get_file(sfp->f_mntonname,
+ verbose ? "mountopts_verbose" : "mountopts", &iov, 1) > 0)
+ (void)printf(", %s", iov.iov_base);
if (sfp->f_owner) {
(void)printf(", mounted by ");
if ((pw = getpwuid(sfp->f_owner)) != NULL)
Index: sys/nfs/nfs_vnops.c
===================================================================
RCS file: /st/src/FreeBSD/src/sys/nfs/nfs_vnops.c,v
retrieving revision 1.164
diff -u -r1.164 nfs_vnops.c
--- sys/nfs/nfs_vnops.c 2001/02/28 04:13:11 1.164
+++ sys/nfs/nfs_vnops.c 2001/03/25 22:16:14
@@ -62,6 +62,7 @@
#include <sys/lockf.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <sys/sbuf.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -130,6 +131,7 @@
static int nfs_print __P((struct vop_print_args *));
static int nfs_advlock __P((struct vop_advlock_args *));
static int nfs_bwrite __P((struct vop_bwrite_args *));
+static int nfs_getextattr __P((struct vop_getextattr_args *));
/*
* Global vfs data structures for nfs
*/
@@ -169,6 +171,7 @@
{ &vop_symlink_desc, (vop_t *) nfs_symlink },
{ &vop_unlock_desc, (vop_t *) vop_stdunlock },
{ &vop_write_desc, (vop_t *) nfs_write },
+ { &vop_getextattr_desc, (vop_t *) nfs_getextattr },
{ NULL, NULL }
};
static struct vnodeopv_desc nfsv2_vnodeop_opv_desc =
@@ -3397,4 +3400,51 @@
}
}
return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap));
+}
+
+/*
+ * Get extended attributes. Currently this is only used to retrieve
+ * filesystem-specific mount options for consumption by mount(8).
+ */
+static int
+nfs_getextattr(ap)
+ struct vop_getextattr_args /*{
+ IN struct vnode *a_vp;
+ IN const char *a_name;
+ INOUT struct uio *a_uio;
+ IN struct ucred *a_cred;
+ IN struct proc *a_p;
+ }; */ *ap;
+{
+ struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount);
+ struct sbuf sb;
+ char *outp;
+ int outl, verbose = 0, error = 0;
+
+ /* XXX macroize "mountopts" and "mountopts_verbose"! */
+ if (strncmp(ap->a_name, "mountopts", 9) != 0)
+ return (ENOENT);
+ if (strncmp(ap->a_name, "mountopts_verbose", 17) == 0)
+ verbose = 1;
+
+ sbuf_new(&sb, NULL, 128, 0);
+ sbuf_printf(&sb, "%s", nmp->nm_flag & NFSMNT_NFSV3 ? "v3" : "v2");
+ sbuf_printf(&sb, ", %s",
+ (nmp->nm_sotype == SOCK_DGRAM) ? "udp" : "tcp");
+ if (nmp->nm_flag & NFSMNT_SOFT)
+ sbuf_cat(&sb, ", soft");
+ else if (verbose)
+ sbuf_cat(&sb, ", hard");
+ if (nmp->nm_flag & NFSMNT_INT)
+ sbuf_cat(&sb, ", intr");
+ sbuf_finish(&sb);
+
+ outp = sbuf_data(&sb);
+ outl = sbuf_len(&sb) + 1;
+ if (outl > ap->a_uio->uio_resid)
+ outl = ap->a_uio->uio_resid;
+ if (outl > 0)
+ error = uiomove(outp, outl, ap->a_uio);
+ sbuf_delete(&sb);
+ return (error);
}
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message