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) {

Reply via email to