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: