diff options
author | marcel <marcel@FreeBSD.org> | 1999-08-27 19:47:41 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 1999-08-27 19:47:41 +0000 |
commit | 421ba20de2168eca011b02a722a39a50edbcc3bb (patch) | |
tree | e76e287183d035dafec15693fbd1edc52428cd1e /sys/i386/linux | |
parent | 10d7165e451a9b3103b41e843fd883bc9f69e7bc (diff) | |
download | FreeBSD-src-421ba20de2168eca011b02a722a39a50edbcc3bb.zip FreeBSD-src-421ba20de2168eca011b02a722a39a50edbcc3bb.tar.gz |
Add sysctl variables for the Linuxulator. These reside under `compat.linux' as
discussed on current.
The following variables are defined (for now):
osname (defaults to "Linux")
Allow users to change the name of the OS as returned by uname(2),
specially added for all those Linux Netscape users and statistics
maniacs :-) We now have what we all wanted!
osrelease (defaults to "2.2.5")
Allow users to change the version of the OS as returned by uname(2).
Since -current supports glibc2.1 now, change the default to 2.2.5
(was 2.0.36).
oss_version (defaults to 198144 [0x030600])
This one will be used by the OSS_GETVERSION ioctl (PR 12917) which I
can commit now that we have the MIB. The default version number is the
lowest version possible with the current 'encoding'.
A note about imprisoned processes (see jail(2)):
These variables are copy-on-write (as suggested by phk). This means that
imprisoned processes will use the system wide value unless it is written/set
by the process. From that moment on, a copy local to the prison will be
used.
A note about the implementation:
I choose to add a single pointer to struct prison, because I didn't like the
idea of changing struct prison every time I come up with a new variable. As
a side effect, the extra storage is only needed when a variable is set from
within the prison. This also minimizes kernel bloat when the Linuxulator is
not used; both compiled in or as a module.
Reviewed by: bde (first version only) and phk
Diffstat (limited to 'sys/i386/linux')
-rw-r--r-- | sys/i386/linux/linux_mib.c | 231 | ||||
-rw-r--r-- | sys/i386/linux/linux_mib.h | 43 | ||||
-rw-r--r-- | sys/i386/linux/linux_misc.c | 11 |
3 files changed, 282 insertions, 3 deletions
diff --git a/sys/i386/linux/linux_mib.c b/sys/i386/linux/linux_mib.c new file mode 100644 index 0000000..98b4a94f --- /dev/null +++ b/sys/i386/linux/linux_mib.c @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 1999 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/sysctl.h> +#include <sys/proc.h> +#include <sys/malloc.h> +#include <sys/jail.h> + +#include <i386/linux/linux.h> +#include <i386/linux/linux_mib.h> + +struct linux_prison { + char pr_osname[LINUX_MAX_UTSNAME]; + char pr_osrelease[LINUX_MAX_UTSNAME]; + int pr_oss_version; +}; + +SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, + "Linux mode"); + +static char linux_osname[LINUX_MAX_UTSNAME] = "Linux"; + +static int +linux_sysctl_osname SYSCTL_HANDLER_ARGS +{ + char osname[LINUX_MAX_UTSNAME]; + int error; + + strcpy(osname, linux_get_osname(req->p)); + error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req); + if (error || req->newptr == NULL) + return (error); + error = linux_set_osname(req->p, osname); + return (error); +} + +SYSCTL_PROC(_compat_linux, OID_AUTO, osname, + CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON, + 0, 0, linux_sysctl_osname, "A", + "Linux kernel OS name"); + +static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.2.5"; + +static int +linux_sysctl_osrelease SYSCTL_HANDLER_ARGS +{ + char osrelease[LINUX_MAX_UTSNAME]; + int error; + + strcpy(osrelease, linux_get_osrelease(req->p)); + error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req); + if (error || req->newptr == NULL) + return (error); + error = linux_set_osrelease(req->p, osrelease); + return (error); +} + +SYSCTL_PROC(_compat_linux, OID_AUTO, osrelease, + CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON, + 0, 0, linux_sysctl_osrelease, "A", + "Linux kernel OS release"); + +static int linux_oss_version = 0x030600; + +static int +linux_sysctl_oss_version SYSCTL_HANDLER_ARGS +{ + int oss_version; + int error; + + oss_version = linux_get_oss_version(req->p); + error = sysctl_handle_int(oidp, &oss_version, 0, req); + if (error || req->newptr == NULL) + return (error); + error = linux_set_oss_version(req->p, oss_version); + return (error); +} + +SYSCTL_PROC(_compat_linux, OID_AUTO, oss_version, + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_PRISON, + 0, 0, linux_sysctl_oss_version, "I", + "Linux OSS version"); + +static struct linux_prison * +get_prison(struct proc *p) +{ + register struct prison *pr; + register struct linux_prison *lpr; + + pr = p->p_prison; + if (pr == NULL) + return (NULL); + + if (pr->pr_linux == NULL) { + MALLOC(lpr, struct linux_prison *, sizeof *lpr, + M_PRISON, M_WAITOK); + bzero((caddr_t)lpr, sizeof *lpr); + pr->pr_linux = lpr; + } + + return (pr->pr_linux); +} + +char * +linux_get_osname(p) + struct proc *p; +{ + register struct prison *pr; + register struct linux_prison *lpr; + + pr = p->p_prison; + if (pr != NULL && pr->pr_linux != NULL) { + lpr = pr->pr_linux; + if (lpr->pr_osname[0]) + return (lpr->pr_osname); + } + + return (linux_osname); +} + +int +linux_set_osname(p, osname) + struct proc *p; + char *osname; +{ + register struct linux_prison *lpr; + + lpr = get_prison(p); + if (lpr != NULL) + strcpy(lpr->pr_osname, osname); + else + strcpy(linux_osname, osname); + + return (0); +} + +char * +linux_get_osrelease(p) + struct proc *p; +{ + register struct prison *pr; + register struct linux_prison *lpr; + + pr = p->p_prison; + if (pr != NULL && pr->pr_linux != NULL) { + lpr = pr->pr_linux; + if (lpr->pr_osrelease[0]) + return (lpr->pr_osrelease); + } + + return (linux_osrelease); +} + +int +linux_set_osrelease(p, osrelease) + struct proc *p; + char *osrelease; +{ + register struct linux_prison *lpr; + + lpr = get_prison(p); + if (lpr != NULL) + strcpy(lpr->pr_osrelease, osrelease); + else + strcpy(linux_osrelease, osrelease); + + return (0); +} + +int +linux_get_oss_version(p) + struct proc *p; +{ + register struct prison *pr; + register struct linux_prison *lpr; + + pr = p->p_prison; + if (pr != NULL && pr->pr_linux != NULL) { + lpr = pr->pr_linux; + if (lpr->pr_oss_version) + return (lpr->pr_oss_version); + } + + return (linux_oss_version); +} + +int +linux_set_oss_version(p, oss_version) + struct proc *p; + int oss_version; +{ + register struct linux_prison *lpr; + + lpr = get_prison(p); + if (lpr != NULL) + lpr->pr_oss_version = oss_version; + else + linux_oss_version = oss_version; + + return (0); +} diff --git a/sys/i386/linux/linux_mib.h b/sys/i386/linux/linux_mib.h new file mode 100644 index 0000000..24c2548 --- /dev/null +++ b/sys/i386/linux/linux_mib.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 1999 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _LINUX_MIB_H_ +#define _LINUX_MIB_H_ + +char* linux_get_osname __P((struct proc *p)); +int linux_set_osname __P((struct proc *p, char *osname)); + +char* linux_get_osrelease __P((struct proc *p)); +int linux_set_osrelease __P((struct proc *p, char *osrelease)); + +int linux_get_oss_version __P((struct proc *p)); +int linux_set_oss_version __P((struct proc *p, int oss_version)); + +#endif /* _LINUX_MIB_H_ */ diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c index 929bfaa..74fb731 100644 --- a/sys/i386/linux/linux_misc.c +++ b/sys/i386/linux/linux_misc.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.66 1999/08/25 11:19:02 marcel Exp $ + * $Id: linux_misc.c,v 1.67 1999/08/25 14:11:01 marcel Exp $ */ #include "opt_compat.h" @@ -61,6 +61,7 @@ #include <i386/linux/linux.h> #include <i386/linux/linux_proto.h> #include <i386/linux/linux_util.h> +#include <i386/linux/linux_mib.h> #include <posix4/sched.h> @@ -880,15 +881,19 @@ int linux_newuname(struct proc *p, struct linux_newuname_args *args) { struct linux_new_utsname utsname; + char *osrelease, *osname; #ifdef DEBUG printf("Linux-emul(%ld): newuname(*)\n", (long)p->p_pid); #endif + osname = linux_get_osname(p); + osrelease = linux_get_osrelease(p); + bzero(&utsname, sizeof(struct linux_new_utsname)); - strncpy(utsname.sysname, "Linux", LINUX_MAX_UTSNAME-1); + strncpy(utsname.sysname, osname, LINUX_MAX_UTSNAME-1); strncpy(utsname.nodename, hostname, LINUX_MAX_UTSNAME-1); - strncpy(utsname.release, "2.0.36", LINUX_MAX_UTSNAME-1); + strncpy(utsname.release, osrelease, LINUX_MAX_UTSNAME-1); strncpy(utsname.version, version, LINUX_MAX_UTSNAME-1); strncpy(utsname.machine, machine, LINUX_MAX_UTSNAME-1); strncpy(utsname.domainname, domainname, LINUX_MAX_UTSNAME-1); |