Module Name:    src
Committed By:   jmcneill
Date:           Sun Sep  4 17:32:10 UTC 2011

Modified Files:
        src/sys/miscfs/procfs: procfs.h procfs_linux.c procfs_subr.c
            procfs_vnops.c

Log Message:
PR# kern/45021: Please support /emul/linux/proc/version

Add /proc/version for procfs with -o linux. The version reported depends
on the emulation type of the calling process:

$ cat /proc/version
NetBSD version 5.99.55 (netbsd@localhost) (gcc version 4.1.3 20080704 
prerelease (NetBSD nb2 20081120)) NetBSD 5.99.55 (GENERIC) #39: Sun Sep  4 
09:10:05 EDT 2011

$ /emul/linux/bin/cat /proc/version
Linux version 2.6.18 (linux@localhost) (gcc version 4.1.3 20080704 prerelease 
(NetBSD nb2 20081120)) #0 Wed Mar 3 03:03:03 PST 2010

$ /emul/linux32/bin/cat /proc/version
Linux version 2.6.18 (linux32@localhost) (gcc version 4.1.3 20080704 prerelease 
(NetBSD nb2 20081120)) #0 Wed Mar 3 03:03:03 PST 2010


To generate a diff of this commit:
cvs rdiff -u -r1.65 -r1.66 src/sys/miscfs/procfs/procfs.h
cvs rdiff -u -r1.60 -r1.61 src/sys/miscfs/procfs/procfs_linux.c
cvs rdiff -u -r1.99 -r1.100 src/sys/miscfs/procfs/procfs_subr.c
cvs rdiff -u -r1.181 -r1.182 src/sys/miscfs/procfs/procfs_vnops.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.h
diff -u src/sys/miscfs/procfs/procfs.h:1.65 src/sys/miscfs/procfs/procfs.h:1.66
--- src/sys/miscfs/procfs/procfs.h:1.65	Sat Jun 28 01:34:06 2008
+++ src/sys/miscfs/procfs/procfs.h	Sun Sep  4 17:32:10 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs.h,v 1.65 2008/06/28 01:34:06 rumble Exp $	*/
+/*	$NetBSD: procfs.h,v 1.66 2011/09/04 17:32:10 jmcneill Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -108,6 +108,7 @@
 	PFScpustat,	/* status info (if -o linux) */
 	PFSloadavg,	/* load average (if -o linux) */
 	PFSstatm,	/* process memory info (if -o linux) */
+	PFSversion,	/* kernel version (if -o linux) */
 #ifdef __HAVE_PROCFS_MACHDEP
 	PROCFS_MACHDEP_NODE_TYPES
 #endif
@@ -225,6 +226,8 @@
     struct uio *);
 int procfs_doemul(struct lwp *, struct proc *, struct pfsnode *,
     struct uio *);
+int procfs_doversion(struct lwp *, struct proc *, struct pfsnode *,
+    struct uio *);
 
 void procfs_revoke_vnodes(struct proc *, void *);
 void procfs_hashinit(void);

Index: src/sys/miscfs/procfs/procfs_linux.c
diff -u src/sys/miscfs/procfs/procfs_linux.c:1.60 src/sys/miscfs/procfs/procfs_linux.c:1.61
--- src/sys/miscfs/procfs/procfs_linux.c:1.60	Sun Aug 28 18:48:14 2011
+++ src/sys/miscfs/procfs/procfs_linux.c	Sun Sep  4 17:32:10 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: procfs_linux.c,v 1.60 2011/08/28 18:48:14 jmcneill Exp $      */
+/*      $NetBSD: procfs_linux.c,v 1.61 2011/09/04 17:32:10 jmcneill Exp $      */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.60 2011/08/28 18:48:14 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.61 2011/09/04 17:32:10 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,10 +53,12 @@
 #include <sys/malloc.h>
 #include <sys/mount.h>
 #include <sys/conf.h>
+#include <sys/sysctl.h>
 
 #include <miscfs/procfs/procfs.h>
 
 #include <compat/linux/common/linux_exec.h>
+#include <compat/linux32/common/linux32_sysctl.h>
 
 #include <uvm/uvm_extern.h>
 #include <uvm/uvm.h>
@@ -610,3 +612,102 @@
 
 	return error;
 }
+
+/*
+ * Linux compatible /proc/version. Only active when the -o linux
+ * mountflag is used.
+ */
+int
+procfs_doversion(struct lwp *curl, struct proc *p,
+    struct pfsnode *pfs, struct uio *uio)
+{
+	char *bf;
+	char lostype[20], losrelease[20], lversion[80];
+	const char *postype, *posrelease, *pversion;
+	const char *emulname = curlwp->l_proc->p_emul->e_name;
+	int len;
+	int error = 0;
+	int nm[4];
+	size_t buflen;
+
+	CTASSERT(EMUL_LINUX_KERN_OSTYPE == EMUL_LINUX32_KERN_OSTYPE);
+	CTASSERT(EMUL_LINUX_KERN_OSRELEASE == EMUL_LINUX32_KERN_OSRELEASE);
+	CTASSERT(EMUL_LINUX_KERN_VERSION == EMUL_LINUX32_KERN_VERSION);
+
+	bf = malloc(LBFSZ, M_TEMP, M_WAITOK);
+
+	sysctl_lock(false);
+
+	if (strncmp(emulname, "linux", 5) == 0) {
+		/*
+		 * Lookup the emulation ostype, osrelease, and version.
+		 * Since compat_linux and compat_linux32 can be built as
+		 * modules, we use sysctl to obtain the values instead of
+		 * using the symbols directly.
+		 */
+
+		if (strcmp(emulname, "linux32") == 0) {
+			nm[0] = CTL_EMUL;
+			nm[1] = EMUL_LINUX32;
+			nm[2] = EMUL_LINUX32_KERN;
+		} else {
+			nm[0] = CTL_EMUL;
+			nm[1] = EMUL_LINUX;
+			nm[2] = EMUL_LINUX_KERN;
+		}
+
+		nm[3] = EMUL_LINUX_KERN_OSTYPE;
+		buflen = sizeof(lostype);
+		error = sysctl_dispatch(nm, __arraycount(nm),
+		    lostype, &buflen,
+		    NULL, 0, NULL, NULL, NULL);
+		if (error)
+			goto out;
+
+		nm[3] = EMUL_LINUX_KERN_OSRELEASE;
+		buflen = sizeof(losrelease);
+		error = sysctl_dispatch(nm, __arraycount(nm),
+		    losrelease, &buflen,
+		    NULL, 0, NULL, NULL, NULL);
+		if (error)
+			goto out;
+
+		nm[3] = EMUL_LINUX_KERN_VERSION;
+		buflen = sizeof(lversion);
+		error = sysctl_dispatch(nm, __arraycount(nm),
+		    lversion, &buflen,
+		    NULL, 0, NULL, NULL, NULL);
+		if (error)
+			goto out;
+
+		postype = lostype;
+		posrelease = losrelease;
+		pversion = lversion;
+	} else {
+		postype = ostype;
+		posrelease = osrelease;
+		strlcpy(lversion, version, sizeof(lversion));
+		if (strchr(lversion, '\n'))
+			*strchr(lversion, '\n') = '\0';
+		pversion = lversion;
+	}
+
+	len = snprintf(bf, LBFSZ,
+		"%s version %s (%s@localhost) (gcc version %s) %s\n",
+		postype, posrelease, emulname,
+#ifdef __VERSION__
+		__VERSION__,
+#else
+		"unknown",
+#endif
+		pversion);
+
+	if (len == 0)
+		goto out;
+
+	error = uiomove_frombuf(bf, len, uio);
+out:
+	free(bf, M_TEMP);
+	sysctl_unlock();
+	return error;
+}

Index: src/sys/miscfs/procfs/procfs_subr.c
diff -u src/sys/miscfs/procfs/procfs_subr.c:1.99 src/sys/miscfs/procfs/procfs_subr.c:1.100
--- src/sys/miscfs/procfs/procfs_subr.c:1.99	Sun Jun 12 03:35:58 2011
+++ src/sys/miscfs/procfs/procfs_subr.c	Sun Sep  4 17:32:10 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_subr.c,v 1.99 2011/06/12 03:35:58 rmind Exp $	*/
+/*	$NetBSD: procfs_subr.c,v 1.100 2011/09/04 17:32:10 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.99 2011/06/12 03:35:58 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.100 2011/09/04 17:32:10 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -288,6 +288,7 @@
 	case PFSmounts:	/* /proc/mounts = -r--r--r-- */
 	case PFSloadavg:	/* /proc/loadavg = -r--r--r-- */
 	case PFSstatm:	/* /proc/N/statm = -r--r--r-- */
+	case PFSversion:	/* /proc/version = -r--r--r-- */
 		pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
 		vp->v_type = VREG;
 		break;
@@ -462,6 +463,10 @@
 		error = procfs_doemul(curl, p, pfs, uio);
 		break;
 
+	case PFSversion:
+		error = procfs_doversion(curl, p, pfs, uio);
+		break;
+
 #ifdef __HAVE_PROCFS_MACHDEP
 	PROCFS_MACHDEP_NODETYPE_CASES
 		error = procfs_machdep_rw(curl, l, pfs, uio);

Index: src/sys/miscfs/procfs/procfs_vnops.c
diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.181 src/sys/miscfs/procfs/procfs_vnops.c:1.182
--- src/sys/miscfs/procfs/procfs_vnops.c:1.181	Thu Jun 23 17:06:38 2011
+++ src/sys/miscfs/procfs/procfs_vnops.c	Sun Sep  4 17:32:10 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_vnops.c,v 1.181 2011/06/23 17:06:38 christos Exp $	*/
+/*	$NetBSD: procfs_vnops.c,v 1.182 2011/09/04 17:32:10 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -105,7 +105,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.181 2011/06/23 17:06:38 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.182 2011/09/04 17:32:10 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -196,6 +196,7 @@
 	{ DT_REG, N("devices"),     PFSdevices,        procfs_validfile_linux },
 	{ DT_REG, N("stat"),	    PFScpustat,        procfs_validfile_linux },
 	{ DT_REG, N("loadavg"),	    PFSloadavg,        procfs_validfile_linux },
+	{ DT_REG, N("version"),     PFSversion,        procfs_validfile_linux },
 #undef N
 };
 static const int nproc_root_targets =
@@ -736,6 +737,7 @@
 	case PFSmounts:
 	case PFScpustat:
 	case PFSloadavg:
+	case PFSversion:
 		vap->va_nlink = 1;
 		vap->va_uid = vap->va_gid = 0;
 		break;
@@ -845,6 +847,7 @@
 	case PFScpustat:
 	case PFSloadavg:
 	case PFSstatm:
+	case PFSversion:
 		vap->va_bytes = vap->va_size = 0;
 		break;
 	case PFSmap:

Reply via email to