Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/miscfs/procfs PR# kern/45021: Please support /emul/linux...



details:   https://anonhg.NetBSD.org/src/rev/99fb04775ea8
branches:  trunk
changeset: 769238:99fb04775ea8
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Sep 04 17:32:10 2011 +0000

description:
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

diffstat:

 sys/miscfs/procfs/procfs.h       |    5 +-
 sys/miscfs/procfs/procfs_linux.c |  105 ++++++++++++++++++++++++++++++++++++++-
 sys/miscfs/procfs/procfs_subr.c  |    9 ++-
 sys/miscfs/procfs/procfs_vnops.c |    7 +-
 4 files changed, 119 insertions(+), 7 deletions(-)

diffs (239 lines):

diff -r f33815cb6f5a -r 99fb04775ea8 sys/miscfs/procfs/procfs.h
--- a/sys/miscfs/procfs/procfs.h        Sun Sep 04 16:09:18 2011 +0000
+++ b/sys/miscfs/procfs/procfs.h        Sun Sep 04 17:32:10 2011 +0000
@@ -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);
diff -r f33815cb6f5a -r 99fb04775ea8 sys/miscfs/procfs/procfs_linux.c
--- a/sys/miscfs/procfs/procfs_linux.c  Sun Sep 04 16:09:18 2011 +0000
+++ b/sys/miscfs/procfs/procfs_linux.c  Sun Sep 04 17:32:10 2011 +0000
@@ -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;
+}
diff -r f33815cb6f5a -r 99fb04775ea8 sys/miscfs/procfs/procfs_subr.c
--- a/sys/miscfs/procfs/procfs_subr.c   Sun Sep 04 16:09:18 2011 +0000
+++ b/sys/miscfs/procfs/procfs_subr.c   Sun Sep 04 17:32:10 2011 +0000
@@ -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);
diff -r f33815cb6f5a -r 99fb04775ea8 sys/miscfs/procfs/procfs_vnops.c
--- a/sys/miscfs/procfs/procfs_vnops.c  Sun Sep 04 16:09:18 2011 +0000
+++ b/sys/miscfs/procfs/procfs_vnops.c  Sun Sep 04 17:32:10 2011 +0000
@@ -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:



Home | Main Index | Thread Index | Old Index