linprocfs - Introduce /proc/mounts
authorAlex Hornung <ahornung@gmail.com>
Sat, 13 Mar 2010 15:39:37 +0000 (15:39 +0000)
committerAlex Hornung <ahornung@gmail.com>
Sat, 13 Mar 2010 16:09:22 +0000 (16:09 +0000)
* Introudce the /proc/mounts entry to satisfy some installers, and df.

* NOTE: if you intend to chroot into the linux base, you'll have to
  change your /compat/linux/etc/mtab symlink to point to /proc/mounts
  instead. Also note that the paths are not relative to the linux
  chroot.

Reported-by: Sascha Wildner
sys/emulation/linux/i386/linprocfs/linprocfs.h
sys/emulation/linux/i386/linprocfs/linprocfs_misc.c
sys/emulation/linux/i386/linprocfs/linprocfs_subr.c
sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c

index 047da47..9651229 100644 (file)
@@ -74,6 +74,7 @@ typedef enum {
        Penviron,
        Pmaps,
        Pstatm,
+       Pmounts,
 } pfstype;
 
 /*
@@ -145,6 +146,7 @@ int linprocfs_write_dbregs (struct proc *, struct dbreg *);
 #endif
 int linprocfs_domeminfo (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
 int linprocfs_docpuinfo (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
+int linprocfs_domounts (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
 int linprocfs_dostat (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
 int linprocfs_douptime (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
 int linprocfs_doversion (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
index 6aa0591..04ed5b6 100644 (file)
@@ -54,6 +54,7 @@
 #include <sys/vnode.h>
 #include <sys/lock.h>
 #include <sys/sbuf.h>
+#include <sys/mount.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -263,6 +264,65 @@ cpucnt(int offset)
     return(count);
 }
 
+static int
+linprocfs_domounts_callback(struct mount *mp, void *data)
+{
+       struct statfs *st;
+       struct sbuf *sb = (struct sbuf *)data;
+       char *to, *from, *fs;
+
+       st = &mp->mnt_stat;
+
+       from = st->f_mntfromname;
+       to = st->f_mntonname;
+       fs = st->f_fstypename;
+
+       if (!strcmp(st->f_fstypename, "linprocfs"))
+               fs = "proc";
+       else if (!strcmp(st->f_fstypename, "ext2fs"))
+               fs = "ext2";
+       else if (!strcmp(st->f_fstypename, "msdos"))
+               fs = "vfat";
+       else if (!strcmp(st->f_fstypename, "msdosfs"))
+               fs = "vfat";
+
+       sbuf_printf(sb, "%s %s %s %s", from, to, fs,
+           st->f_flags & MNT_RDONLY ? "ro" : "rw");
+
+#define OPT_ADD(name, flag) if (st->f_flags & (flag)) sbuf_printf(sb, "," name)
+       OPT_ADD("sync",         MNT_SYNCHRONOUS);
+       OPT_ADD("noexec",       MNT_NOEXEC);
+       OPT_ADD("nosuid",       MNT_NOSUID);
+       OPT_ADD("nodev",        MNT_NODEV);
+       OPT_ADD("async",        MNT_ASYNC);
+       OPT_ADD("suiddir",      MNT_SUIDDIR);
+       OPT_ADD("nosymfollow",  MNT_NOSYMFOLLOW);
+       OPT_ADD("noatime",      MNT_NOATIME);
+#undef OPT_ADD
+
+       sbuf_printf(sb, " 0 0\n");
+
+       return 0;
+}
+
+int
+linprocfs_domounts(struct proc *curp, struct proc *p, struct pfsnode *pfs,
+                   struct uio *uio)
+{
+       struct sbuf *sb;
+       int error;
+
+       sb = sbuf_new_auto();
+
+       error = mountlist_scan(linprocfs_domounts_callback, sb, MNTSCAN_FORWARD);
+
+       sbuf_finish(sb);
+       if (error == 0)
+               error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio);
+       sbuf_delete(sb);
+       return (error);
+}
+
 int
 linprocfs_dostat(struct proc *curp, struct proc *p, struct pfsnode *pfs,
                 struct uio *uio)
index e1f52a8..ccda25d 100644 (file)
@@ -197,6 +197,7 @@ loop:
        case Pmaps:
        case Pmeminfo:
        case Pcpuinfo:
+       case Pmounts:
        case Pstat:
        case Puptime:
        case Pversion:
@@ -298,6 +299,9 @@ linprocfs_rw(struct vop_read_args *ap)
        case Pcpuinfo:
                rtval = linprocfs_docpuinfo(curp, p, pfs, uio);
                break;
+       case Pmounts:
+               rtval = linprocfs_domounts(curp, p, pfs, uio);
+               break;
        case Pstat:
                rtval = linprocfs_dostat(curp, p, pfs, uio);
                break;
index a0bde59..8f06b90 100644 (file)
@@ -563,6 +563,7 @@ linprocfs_getattr(struct vop_getattr_args *ap)
 
        case Pmeminfo:
        case Pcpuinfo:
+       case Pmounts:
        case Pstat:
        case Puptime:
        case Pversion:
@@ -778,6 +779,10 @@ linprocfs_lookup(struct vop_old_lookup_args *ap)
                        error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Pcpuinfo);
                        goto out;
                }
+               if (CNEQ(cnp, "mounts", 6)) {
+                       error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Pmounts);
+                       goto out;
+               }
                if (CNEQ(cnp, "stat", 4)) {
                        error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Pstat);
                        goto out;
@@ -1006,7 +1011,7 @@ linprocfs_readdir_root(struct vop_readdir_args *ap)
        info.uio = uio;
        info.cred = ap->a_cred;
 
-       while (info.pcnt < 11) {
+       while (info.pcnt < 12) {
                res = linprocfs_readdir_root_callback(NULL, &info);
                if (res < 0)
                        break;
@@ -1104,6 +1109,12 @@ linprocfs_readdir_root_callback(struct proc *p, void *data)
                d_name = "sys";
                d_type = DT_DIR;
                break;
+       case 11:
+               d_ino = PROCFS_FILENO(0, Pmounts);
+               d_namlen = 6;
+               d_name = "mounts";
+               d_type = DT_DIR;
+               break;
 #if 0
        case 11:
                d_ino = PROCFS_FILENO(0, Pdevices);