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
This commit is contained in:
parent
1a6f6eba38
commit
e656d3b0f6
|
@ -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 @@ typedef enum {
|
|||
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 @@ int procfs_domounts(struct lwp *, struct proc *, struct pfsnode *,
|
|||
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);
|
||||
|
|
|
@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.60 2011/08/28 18:48:14 jmcneill E
|
|||
#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 @@ procfs_domounts(struct lwp *curl, struct proc *p,
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 @@ procfs_allocvp(struct mount *mp, struct vnode **vpp, pid_t pid,
|
|||
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 @@ procfs_rw(void *v)
|
|||
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);
|
||||
|
|
|
@ -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 @@ static const struct proc_target proc_root_targets[] = {
|
|||
{ 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 @@ procfs_getattr(void *v)
|
|||
case PFSmounts:
|
||||
case PFScpustat:
|
||||
case PFSloadavg:
|
||||
case PFSversion:
|
||||
vap->va_nlink = 1;
|
||||
vap->va_uid = vap->va_gid = 0;
|
||||
break;
|
||||
|
@ -845,6 +847,7 @@ procfs_getattr(void *v)
|
|||
case PFScpustat:
|
||||
case PFSloadavg:
|
||||
case PFSstatm:
|
||||
case PFSversion:
|
||||
vap->va_bytes = vap->va_size = 0;
|
||||
break;
|
||||
case PFSmap:
|
||||
|
|
Loading…
Reference in New Issue