Module Name: src Committed By: christos Date: Fri Dec 16 20:45:07 UTC 2011
Modified Files: src/sys/miscfs/procfs: procfs_linux.c Log Message: provide a root entry if one was not found. To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sys/miscfs/procfs/procfs_linux.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/miscfs/procfs/procfs_linux.c diff -u src/sys/miscfs/procfs/procfs_linux.c:1.62 src/sys/miscfs/procfs/procfs_linux.c:1.63 --- src/sys/miscfs/procfs/procfs_linux.c:1.62 Thu Dec 15 15:55:02 2011 +++ src/sys/miscfs/procfs/procfs_linux.c Fri Dec 16 15:45:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_linux.c,v 1.62 2011/12/15 20:55:02 christos Exp $ */ +/* $NetBSD: procfs_linux.c,v 1.63 2011/12/16 20:45:07 christos Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.62 2011/12/15 20:55:02 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.63 2011/12/16 20:45:07 christos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_linux #include <sys/conf.h> #include <sys/sysctl.h> #include <sys/kauth.h> +#include <sys/filedesc.h> #include <miscfs/procfs/procfs.h> @@ -557,56 +558,73 @@ out: return error; } +static int +procfs_format_sfs(char **mtab, size_t *mlen, char *buf, size_t blen, + const struct statvfs *sfs, struct lwp *curl, int suser) +{ + const char *fsname; + + /* Linux uses different names for some filesystems */ + fsname = sfs->f_fstypename; + if (strcmp(fsname, "procfs") == 0) + fsname = "proc"; + else if (strcmp(fsname, "ext2fs") == 0) + fsname = "ext2"; + + blen = snprintf(buf, blen, "%s %s %s %s%s%s%s%s%s 0 0\n", + sfs->f_mntfromname, sfs->f_mntonname, fsname, + (sfs->f_flag & ST_RDONLY) ? "ro" : "rw", + (sfs->f_flag & ST_NOSUID) ? ",nosuid" : "", + (sfs->f_flag & ST_NOEXEC) ? ",noexec" : "", + (sfs->f_flag & ST_NODEV) ? ",nodev" : "", + (sfs->f_flag & ST_SYNCHRONOUS) ? ",sync" : "", + (sfs->f_flag & ST_NOATIME) ? ",noatime" : ""); + + *mtab = realloc(*mtab, *mlen + blen, M_TEMP, M_WAITOK); + memcpy(*mtab + *mlen, buf, blen); + *mlen += blen; + return sfs->f_mntonname[0] == '/' && sfs->f_mntonname[1] == '\0'; +} + int procfs_domounts(struct lwp *curl, struct proc *p, struct pfsnode *pfs, struct uio *uio) { char *bf, *mtab = NULL; - const char *fsname; - size_t len, mtabsz = 0; + size_t mtabsz = 0; struct mount *mp, *nmp; - struct statvfs sfs; - int error = 0, suser; + int error = 0, suser, root = 0; + struct cwdinfo *cwdi = curl->l_proc->p_cwdi; suser = kauth_authorize_generic(curl->l_cred, KAUTH_GENERIC_ISSUSER, NULL) == 0; bf = malloc(LBFSZ, M_TEMP, M_WAITOK); + mutex_enter(&mountlist_lock); for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist; - mp = nmp) { - if (vfs_busy(mp, &nmp)) - continue; + mp = nmp) { + struct statvfs sfs; - if (dostatvfs(mp, &sfs, curl, MNT_WAIT, suser) != 0) + if (vfs_busy(mp, &nmp)) continue; - /* Linux uses different names for some filesystems */ - fsname = sfs.f_fstypename; - if (strcmp(fsname, "procfs") == 0) - fsname = "proc"; - else if (strcmp(fsname, "ext2fs") == 0) - fsname = "ext2"; - - len = snprintf(bf, LBFSZ, "%s %s %s %s%s%s%s%s%s 0 0\n", - sfs.f_mntfromname, - sfs.f_mntonname, - fsname, - (sfs.f_flag & ST_RDONLY) ? "ro" : "rw", - (sfs.f_flag & ST_NOSUID) ? ",nosuid" : "", - (sfs.f_flag & ST_NOEXEC) ? ",noexec" : "", - (sfs.f_flag & ST_NODEV) ? ",nodev" : "", - (sfs.f_flag & ST_SYNCHRONOUS) ? ",sync" : "", - (sfs.f_flag & ST_NOATIME) ? ",noatime" : "" - ); - - mtab = realloc(mtab, mtabsz + len, M_TEMP, M_WAITOK); - memcpy(mtab + mtabsz, bf, len); - mtabsz += len; + if ((error = dostatvfs(mp, &sfs, curl, MNT_WAIT, suser)) == 0) + root |= procfs_format_sfs(&mtab, &mtabsz, bf, LBFSZ, + &sfs, curl, suser); vfs_unbusy(mp, false, &nmp); } mutex_exit(&mountlist_lock); + + /* + * If we are inside a chroot that is not itself a mount point, + * fake a root entry. + */ + if (!root && cwdi->cwdi_rdir) + (void)procfs_format_sfs(&mtab, &mtabsz, bf, LBFSZ, + &cwdi->cwdi_rdir->v_mount->mnt_stat, curl, 1); + free(bf, M_TEMP); if (mtabsz > 0) {