From: Alex Hornung Date: Sat, 13 Mar 2010 15:39:37 +0000 (+0000) Subject: linprocfs - Introduce /proc/mounts X-Git-Tag: v2.7.0~88 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/a3c5067f1b59372a02c39080ba86a779ee6661e1 linprocfs - Introduce /proc/mounts * 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 --- diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs.h b/sys/emulation/linux/i386/linprocfs/linprocfs.h index 047da47006..96512299f0 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs.h +++ b/sys/emulation/linux/i386/linprocfs/linprocfs.h @@ -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); diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c b/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c index 6aa0591be7..04ed5b6abc 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c +++ b/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -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) diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c b/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c index e1f52a86df..ccda25d32a 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c +++ b/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c @@ -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; diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c b/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c index a0bde59805..8f06b906b3 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c +++ b/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c @@ -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);