Introduce a new module linux_common.ko which is intended for the

following primary purposes:

1. Remove the dependency of linsysfs and linprocfs modules from linux.ko,
which will be architecture specific on amd64.

2. Incorporate into linux_common.ko general code for platforms on which
we'll support two Linuxulator modules (for both instruction set - 32 & 64 bit).

3. Move malloc(9) declaration to linux_common.ko, to enable getting memory
usage statistics properly.

Currently linux_common.ko incorporates a code from linux_mib.c and linux_util.c
and linprocfs, linsysfs and linux kernel modules depend on linux_common.ko.

Temporarily remove dtrace garbage from linux_mib.c and linux_util.c

Differential Revision:	https://reviews.freebsd.org/D1072
In collaboration with:	Vassilis Laganakos.

Reviewed by:	trasz
This commit is contained in:
Dmitry Chagin 2015-05-24 15:51:18 +00:00
parent 606bcc1741
commit 67d3974849
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=283421
21 changed files with 274 additions and 525 deletions

View File

@ -46,10 +46,6 @@ extern u_char linux_debug_map[];
(long)td->td_proc->p_pid, (long)td->td_tid
#define LINUX_DTRACE linuxulator32
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_LINUX);
#endif
#define LINUX32_MAXUSER ((1ul << 32) - PAGE_SIZE)
#define LINUX32_SHAREDPAGE (LINUX32_MAXUSER - PAGE_SIZE)
#define LINUX32_USRSTACK LINUX32_SHAREDPAGE

View File

@ -87,8 +87,6 @@ __FBSDID("$FreeBSD$");
MODULE_VERSION(linux, 1);
MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
#define AUXARGS_ENTRY_32(pos, id, val) \
do { \
suword32(pos++, id); \
@ -120,7 +118,6 @@ extern char _binary_linux32_locore_o_end;
extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
static int elf_linux_fixup(register_t **stack_base,
struct image_params *iparams);
@ -976,6 +973,13 @@ static u_long linux32_maxvmem = LINUX32_MAXVMEM;
SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW,
&linux32_maxvmem, 0, "");
#if defined(DEBUG)
SYSCTL_PROC(_compat_linux32, OID_AUTO, debug,
CTLTYPE_STRING | CTLFLAG_RW,
0, 0, linux_sysctl_debug, "A",
"Linux debugging control");
#endif
static void
linux32_fixlimit(struct rlimit *rl, int which)
{
@ -1152,7 +1156,6 @@ linux_elf_modevent(module_t mod, int type, void *data)
Elf32_Brandinfo **brandinfo;
int error;
struct linux_ioctl_handler **lihp;
struct linux_device_handler **ldhp;
error = 0;
@ -1165,8 +1168,6 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (error == 0) {
SET_FOREACH(lihp, linux_ioctl_handler_set)
linux_ioctl_register_handler(*lihp);
SET_FOREACH(ldhp, linux_device_handler_set)
linux_device_register_handler(*ldhp);
LIST_INIT(&futex_list);
mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF);
linux_exit_tag = EVENTHANDLER_REGISTER(process_exit,
@ -1175,7 +1176,6 @@ linux_elf_modevent(module_t mod, int type, void *data)
linux_proc_exec, NULL, 1000);
linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor,
linux_thread_dtor, NULL, EVENTHANDLER_PRI_ANY);
linux_osd_jail_register();
stclohz = (stathz ? stathz : hz);
if (bootverbose)
printf("Linux ELF exec handler installed\n");
@ -1196,13 +1196,10 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (error == 0) {
SET_FOREACH(lihp, linux_ioctl_handler_set)
linux_ioctl_unregister_handler(*lihp);
SET_FOREACH(ldhp, linux_device_handler_set)
linux_device_unregister_handler(*ldhp);
mtx_destroy(&futex_mtx);
EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag);
linux_osd_jail_deregister();
if (bootverbose)
printf("Linux ELF exec handler removed\n");
} else
@ -1221,3 +1218,4 @@ static moduledata_t linux_elf_mod = {
};
DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
MODULE_DEPEND(linuxelf, linux_common, 1, 1, 1);

View File

@ -39,8 +39,6 @@
* @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
*/
#include "opt_compat.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -69,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/tty.h>
@ -80,7 +79,7 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <net/if_var.h>
#include <net/vnet.h>
#include <net/if_types.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@ -100,11 +99,6 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#endif /* __i386__ || __amd64__ */
#ifdef COMPAT_FREEBSD32
#include <compat/freebsd32/freebsd32_util.h>
#endif
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_util.h>
@ -1113,6 +1107,35 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
return (error);
}
/*
* Criteria for interface name translation
*/
#define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER)
static int
linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen)
{
struct ifnet *ifscan;
int ethno;
IFNET_RLOCK_ASSERT();
/* Short-circuit non ethernet interfaces */
if (!IFP_IS_ETH(ifp))
return (strlcpy(buffer, ifp->if_xname, buflen));
/* Determine the (relative) unit number for ethernet interfaces */
ethno = 0;
TAILQ_FOREACH(ifscan, &V_ifnet, if_link) {
if (ifscan == ifp)
return (snprintf(buffer, buflen, "eth%d", ethno));
if (IFP_IS_ETH(ifscan))
ethno++;
}
return (0);
}
/*
* Filler function for proc/net/dev
*/
@ -1261,8 +1284,6 @@ linprocfs_doscsiscsi(PFS_FILL_ARGS)
return (0);
}
extern struct cdevsw *cdevsw[];
/*
* Filler function for proc/devices
*/
@ -1477,7 +1498,11 @@ linprocfs_uninit(PFS_INIT_ARGS)
}
PSEUDOFS(linprocfs, 1, 0);
#if defined(__amd64__)
MODULE_DEPEND(linprocfs, linux_common, 1, 1, 1);
#else
MODULE_DEPEND(linprocfs, linux, 1, 1, 1);
#endif
MODULE_DEPEND(linprocfs, procfs, 1, 1, 1);
MODULE_DEPEND(linprocfs, sysvmsg, 1, 1, 1);
MODULE_DEPEND(linprocfs, sysvsem, 1, 1, 1);

View File

@ -62,12 +62,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include "opt_compat.h"
#ifdef COMPAT_LINUX32 /* XXX */
#include <machine/../linux32/linux.h>
#else
#include <machine/../linux/linux.h>
#endif
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_util.h>
@ -282,4 +276,8 @@ linsysfs_uninit(PFS_INIT_ARGS)
}
PSEUDOFS(linsysfs, 1, 0);
#if defined(__amd64__)
MODULE_DEPEND(linsysfs, linux_common, 1, 1, 1);
#else
MODULE_DEPEND(linsysfs, linux, 1, 1, 1);
#endif

View File

@ -0,0 +1,74 @@
/*-
* Copyright (c) 2014 Vassilis Laganakos
* 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.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/types.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_util.h>
MODULE_VERSION(linux_common, 1);
SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
static int
linux_common_modevent(module_t mod, int type, void *data)
{
struct linux_device_handler **ldhp;
switch(type) {
case MOD_LOAD:
linux_osd_jail_register();
SET_FOREACH(ldhp, linux_device_handler_set)
linux_device_register_handler(*ldhp);
break;
case MOD_UNLOAD:
linux_osd_jail_deregister();
SET_FOREACH(ldhp, linux_device_handler_set)
linux_device_unregister_handler(*ldhp);
break;
default:
return (EOPNOTSUPP);
}
return (0);
}
static moduledata_t linux_common_mod = {
"linuxcommon",
linux_common_modevent,
0
};
DECLARE_MODULE(linuxcommon, linux_common_mod, SI_SUB_EXEC, SI_ORDER_ANY);

View File

@ -69,7 +69,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/vnet.h>
#include <dev/usb/usb_ioctl.h>
@ -2108,34 +2107,6 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
*/
#define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER)
/*
* Interface function used by linprocfs (at the time of writing). It's not
* used by the Linuxulator itself.
*/
int
linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen)
{
struct ifnet *ifscan;
int ethno;
IFNET_RLOCK_ASSERT();
/* Short-circuit non ethernet interfaces */
if (!IFP_IS_ETH(ifp))
return (strlcpy(buffer, ifp->if_xname, buflen));
/* Determine the (relative) unit number for ethernet interfaces */
ethno = 0;
TAILQ_FOREACH(ifscan, &V_ifnet, if_link) {
if (ifscan == ifp)
return (snprintf(buffer, buflen, "eth%d", ethno));
if (IFP_IS_ETH(ifscan))
ethno++;
}
return (0);
}
/*
* Translate a Linux interface name to a FreeBSD interface name,
* and return the associated ifnet structure

View File

@ -580,13 +580,6 @@
#define LINUX_IOCTL_DRM_MIN 0x6400
#define LINUX_IOCTL_DRM_MAX 0x64ff
/*
* This doesn't really belong here, but I can't think of a better
* place to put it.
*/
struct ifnet;
int linux_ifname(struct ifnet *, char *, size_t);
/*
* video
*/

View File

@ -29,8 +29,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/sdt.h>
@ -41,85 +39,11 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sx.h>
#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
#else
#include <machine/../linux/linux.h>
#endif
#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
/* DTrace init */
LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
/**
* DTrace probes in this module.
*/
LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_osname, entry);
LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osname, sysctl_string_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osname, return, "int");
LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_osrelease, entry);
LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osrelease, sysctl_string_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osrelease, return, "int");
LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_oss_version, entry);
LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_oss_version, sysctl_string_error,
"int");
LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_oss_version, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_map_osrel, entry, "char *", "int *");
LIN_SDT_PROBE_DEFINE1(mib, linux_map_osrel, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_get_prison, entry, "struct prison *",
"struct prison **");
LIN_SDT_PROBE_DEFINE1(mib, linux_get_prison, return, "struct linux_prison *");
LIN_SDT_PROBE_DEFINE2(mib, linux_alloc_prison, entry, "struct prison *",
"struct linux_prison **");
LIN_SDT_PROBE_DEFINE1(mib, linux_alloc_prison, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_prison_create, entry, "void *", "void *");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_create, vfs_copyopt_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_create, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_prison_check, entry, "void *", "void *");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, vfs_copyopt_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, vfs_getopt_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_prison_set, entry, "void *", "void *");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, vfs_copyopt_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, vfs_getopt_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_prison_get, entry, "void *", "void *");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, vfs_setopt_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, vfs_setopts_error, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, return, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_prison_destructor, entry, "void *");
LIN_SDT_PROBE_DEFINE0(mib, linux_prison_destructor, return);
LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_register, entry);
LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_register, return);
LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_deregister, entry);
LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_deregister, return);
LIN_SDT_PROBE_DEFINE2(mib, linux_get_osname, entry, "struct thread *",
"char *");
LIN_SDT_PROBE_DEFINE0(mib, linux_get_osname, return);
LIN_SDT_PROBE_DEFINE2(mib, linux_set_osname, entry, "struct thread *",
"char *");
LIN_SDT_PROBE_DEFINE1(mib, linux_set_osname, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_get_osrelease, entry, "struct thread *",
"char *");
LIN_SDT_PROBE_DEFINE0(mib, linux_get_osrelease, return);
LIN_SDT_PROBE_DEFINE1(mib, linux_kernver, entry, "struct thread *");
LIN_SDT_PROBE_DEFINE1(mib, linux_kernver, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_set_osrelease, entry, "struct thread *",
"char *");
LIN_SDT_PROBE_DEFINE1(mib, linux_set_osrelease, return, "int");
LIN_SDT_PROBE_DEFINE1(mib, linux_get_oss_version, entry, "struct thread *");
LIN_SDT_PROBE_DEFINE1(mib, linux_get_oss_version, return, "int");
LIN_SDT_PROBE_DEFINE2(mib, linux_set_oss_version, entry, "struct thread *",
"int");
LIN_SDT_PROBE_DEFINE1(mib, linux_set_oss_version, return, "int");
struct linux_prison {
char pr_osname[LINUX_MAX_UTSNAME];
char pr_osrelease[LINUX_MAX_UTSNAME];
@ -136,8 +60,7 @@ static struct linux_prison lprison0 = {
static unsigned linux_osd_jail_slot;
static SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0,
"Linux mode");
SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, "Linux mode");
static int linux_set_osname(struct thread *td, char *osname);
static int linux_set_osrelease(struct thread *td, char *osrelease);
@ -149,19 +72,12 @@ linux_sysctl_osname(SYSCTL_HANDLER_ARGS)
char osname[LINUX_MAX_UTSNAME];
int error;
LIN_SDT_PROBE0(mib, linux_sysctl_osname, entry);
linux_get_osname(req->td, osname);
error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req);
if (error != 0 || req->newptr == NULL) {
LIN_SDT_PROBE1(mib, linux_sysctl_osname, sysctl_string_error,
error);
LIN_SDT_PROBE1(mib, linux_sysctl_osname, return, error);
if (error != 0 || req->newptr == NULL)
return (error);
}
error = linux_set_osname(req->td, osname);
LIN_SDT_PROBE1(mib, linux_sysctl_osname, return, error);
return (error);
}
@ -176,19 +92,12 @@ linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS)
char osrelease[LINUX_MAX_UTSNAME];
int error;
LIN_SDT_PROBE0(mib, linux_sysctl_osrelease, entry);
linux_get_osrelease(req->td, osrelease);
error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req);
if (error != 0 || req->newptr == NULL) {
LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, sysctl_string_error,
error);
LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, return, error);
if (error != 0 || req->newptr == NULL)
return (error);
}
error = linux_set_osrelease(req->td, osrelease);
LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, return, error);
return (error);
}
@ -203,19 +112,12 @@ linux_sysctl_oss_version(SYSCTL_HANDLER_ARGS)
int oss_version;
int error;
LIN_SDT_PROBE0(mib, linux_sysctl_oss_version, entry);
oss_version = linux_get_oss_version(req->td);
error = sysctl_handle_int(oidp, &oss_version, 0, req);
if (error != 0 || req->newptr == NULL) {
LIN_SDT_PROBE1(mib, linux_sysctl_oss_version,
sysctl_string_error, error);
LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, return, error);
if (error != 0 || req->newptr == NULL)
return (error);
}
error = linux_set_oss_version(req->td, oss_version);
LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, return, error);
return (error);
}
@ -233,37 +135,26 @@ linux_map_osrel(char *osrelease, int *osrel)
char *sep, *eosrelease;
int len, v0, v1, v2, v;
LIN_SDT_PROBE2(mib, linux_map_osrel, entry, osrelease, osrel);
len = strlen(osrelease);
eosrelease = osrelease + len;
v0 = strtol(osrelease, &sep, 10);
if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') {
LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
return (EINVAL);
}
osrelease = sep + 1;
v1 = strtol(osrelease, &sep, 10);
if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') {
LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
return (EINVAL);
}
osrelease = sep + 1;
v2 = strtol(osrelease, &sep, 10);
if (osrelease == sep || sep != eosrelease) {
LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
if (osrelease == sep || sep != eosrelease)
return (EINVAL);
}
v = v0 * 1000000 + v1 * 1000 + v2;
if (v < 1000000) {
LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
if (v < 1000000)
return (EINVAL);
}
*osrel = v;
LIN_SDT_PROBE1(mib, linux_map_osrel, return, 0);
return (0);
}
@ -277,8 +168,6 @@ linux_find_prison(struct prison *spr, struct prison **prp)
struct prison *pr;
struct linux_prison *lpr;
LIN_SDT_PROBE2(mib, linux_get_prison, entry, spr, prp);
if (!linux_osd_jail_slot)
/* In case osd_register failed. */
spr = &prison0;
@ -293,7 +182,6 @@ linux_find_prison(struct prison *spr, struct prison **prp)
}
*prp = pr;
LIN_SDT_PROBE1(mib, linux_get_prison, return, lpr);
return (lpr);
}
@ -308,8 +196,6 @@ linux_alloc_prison(struct prison *pr, struct linux_prison **lprp)
struct linux_prison *lpr, *nlpr;
int error;
LIN_SDT_PROBE2(mib, linux_alloc_prison, entry, pr, lprp);
/* If this prison already has Linux info, return that. */
error = 0;
lpr = linux_find_prison(pr, &ppr);
@ -343,7 +229,6 @@ linux_alloc_prison(struct prison *pr, struct linux_prison **lprp)
else
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_alloc_prison, return, error);
return (error);
}
@ -355,26 +240,16 @@ linux_prison_create(void *obj, void *data)
{
struct prison *pr = obj;
struct vfsoptlist *opts = data;
int jsys, error;
int jsys;
LIN_SDT_PROBE2(mib, linux_prison_create, entry, obj, data);
error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_create, vfs_copyopt_error,
error);
} else if (jsys == JAIL_SYS_INHERIT) {
LIN_SDT_PROBE1(mib, linux_prison_create, return, 0);
if (vfs_copyopt(opts, "linux", &jsys, sizeof(jsys)) == 0 &&
jsys == JAIL_SYS_INHERIT)
return (0);
}
/*
* Inherit a prison's initial values from its parent
* (different from JAIL_SYS_INHERIT which also inherits changes).
*/
error = linux_alloc_prison(pr, NULL);
LIN_SDT_PROBE1(mib, linux_prison_create, return, error);
return (error);
return (linux_alloc_prison(pr, NULL));
}
static int
@ -384,80 +259,46 @@ linux_prison_check(void *obj __unused, void *data)
char *osname, *osrelease;
int error, jsys, len, osrel, oss_version;
LIN_SDT_PROBE2(mib, linux_prison_check, entry, obj, data);
/* Check that the parameters are correct. */
error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_check, vfs_copyopt_error,
error);
}
if (error != ENOENT) {
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
if (error != 0)
return (error);
}
if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT) {
LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT)
return (EINVAL);
}
}
error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len);
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_check, vfs_getopt_error,
error);
}
if (error != ENOENT) {
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
if (error != 0)
return (error);
}
if (len == 0 || osname[len - 1] != '\0') {
LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
if (len == 0 || osname[len - 1] != '\0')
return (EINVAL);
}
if (len > LINUX_MAX_UTSNAME) {
vfs_opterror(opts, "linux.osname too long");
LIN_SDT_PROBE1(mib, linux_prison_check, return,
ENAMETOOLONG);
return (ENAMETOOLONG);
}
}
error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len);
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_check, vfs_getopt_error,
error);
}
if (error != ENOENT) {
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
if (error != 0)
return (error);
}
if (len == 0 || osrelease[len - 1] != '\0') {
LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
if (len == 0 || osrelease[len - 1] != '\0')
return (EINVAL);
}
if (len > LINUX_MAX_UTSNAME) {
vfs_opterror(opts, "linux.osrelease too long");
LIN_SDT_PROBE1(mib, linux_prison_check, return,
ENAMETOOLONG);
return (ENAMETOOLONG);
}
error = linux_map_osrel(osrelease, &osrel);
if (error != 0) {
vfs_opterror(opts, "linux.osrelease format error");
LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
return (error);
}
}
error = vfs_copyopt(opts, "linux.oss_version", &oss_version,
sizeof(oss_version));
if (error != 0)
LIN_SDT_PROBE1(mib, linux_prison_check, vfs_copyopt_error, error);
if (error == ENOENT)
error = 0;
LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
return (error);
}
@ -470,32 +311,22 @@ linux_prison_set(void *obj, void *data)
char *osname, *osrelease;
int error, gotversion, jsys, len, oss_version;
LIN_SDT_PROBE2(mib, linux_prison_set, entry, obj, data);
/* Set the parameters, which should be correct. */
error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
if (error != 0)
LIN_SDT_PROBE1(mib, linux_prison_set, vfs_copyopt_error, error);
if (error == ENOENT)
jsys = -1;
error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len);
if (error != 0)
LIN_SDT_PROBE1(mib, linux_prison_set, vfs_getopt_error, error);
if (error == ENOENT)
osname = NULL;
else
jsys = JAIL_SYS_NEW;
error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len);
if (error != 0)
LIN_SDT_PROBE1(mib, linux_prison_set, vfs_getopt_error, error);
if (error == ENOENT)
osrelease = NULL;
else
jsys = JAIL_SYS_NEW;
error = vfs_copyopt(opts, "linux.oss_version", &oss_version,
sizeof(oss_version));
if (error != 0)
LIN_SDT_PROBE1(mib, linux_prison_set, vfs_copyopt_error, error);
if (error == ENOENT)
gotversion = 0;
else {
@ -517,15 +348,12 @@ linux_prison_set(void *obj, void *data)
error = linux_alloc_prison(pr, &lpr);
if (error) {
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_prison_set, return, error);
return (error);
}
if (osrelease) {
error = linux_map_osrel(osrelease, &lpr->pr_osrel);
if (error) {
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_prison_set, return,
error);
return (error);
}
strlcpy(lpr->pr_osrelease, osrelease,
@ -538,7 +366,6 @@ linux_prison_set(void *obj, void *data)
mtx_unlock(&pr->pr_mtx);
}
LIN_SDT_PROBE1(mib, linux_prison_set, return, 0);
return (0);
}
@ -561,74 +388,44 @@ linux_prison_get(void *obj, void *data)
static int version0;
LIN_SDT_PROBE2(mib, linux_prison_get, entry, obj, data);
/* See if this prison is the one with the Linux info. */
lpr = linux_find_prison(pr, &ppr);
i = (ppr == pr) ? JAIL_SYS_NEW : JAIL_SYS_INHERIT;
error = vfs_setopt(opts, "linux", &i, sizeof(i));
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error, error);
if (error != ENOENT)
goto done;
}
if (error != 0 && error != ENOENT)
goto done;
if (i) {
error = vfs_setopts(opts, "linux.osname", lpr->pr_osname);
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
error);
if (error != ENOENT)
goto done;
}
if (error != 0 && error != ENOENT)
goto done;
error = vfs_setopts(opts, "linux.osrelease", lpr->pr_osrelease);
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
error);
if (error != ENOENT)
goto done;
}
if (error != 0 && error != ENOENT)
goto done;
error = vfs_setopt(opts, "linux.oss_version",
&lpr->pr_oss_version, sizeof(lpr->pr_oss_version));
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error,
error);
if(error != ENOENT)
goto done;
}
if (error != 0 && error != ENOENT)
goto done;
} else {
/*
* If this prison is inheriting its Linux info, report
* empty/zero parameters.
*/
error = vfs_setopts(opts, "linux.osname", "");
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
error);
if(error != ENOENT)
goto done;
}
if (error != 0 && error != ENOENT)
goto done;
error = vfs_setopts(opts, "linux.osrelease", "");
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
error);
if(error != ENOENT)
goto done;
}
if (error != 0 && error != ENOENT)
goto done;
error = vfs_setopt(opts, "linux.oss_version", &version0,
sizeof(lpr->pr_oss_version));
if (error != 0) {
LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error,
error);
if(error != ENOENT)
goto done;
}
if (error != 0 && error != ENOENT)
goto done;
}
error = 0;
done:
mtx_unlock(&ppr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_prison_get, return, error);
return (error);
}
@ -636,9 +433,7 @@ static void
linux_prison_destructor(void *data)
{
LIN_SDT_PROBE1(mib, linux_prison_destructor, entry, data);
free(data, M_PRISON);
LIN_SDT_PROBE0(mib, linux_prison_destructor, return);
}
void
@ -652,8 +447,6 @@ linux_osd_jail_register(void)
[PR_METHOD_CHECK] = linux_prison_check
};
LIN_SDT_PROBE0(mib, linux_osd_jail_register, entry);
linux_osd_jail_slot =
osd_jail_register(linux_prison_destructor, methods);
if (linux_osd_jail_slot > 0) {
@ -663,20 +456,14 @@ linux_osd_jail_register(void)
(void)linux_alloc_prison(pr, NULL);
sx_xunlock(&allprison_lock);
}
LIN_SDT_PROBE0(mib, linux_osd_jail_register, return);
}
void
linux_osd_jail_deregister(void)
{
LIN_SDT_PROBE0(mib, linux_osd_jail_register, entry);
if (linux_osd_jail_slot)
osd_jail_deregister(linux_osd_jail_slot);
LIN_SDT_PROBE0(mib, linux_osd_jail_register, return);
}
void
@ -685,13 +472,9 @@ linux_get_osname(struct thread *td, char *dst)
struct prison *pr;
struct linux_prison *lpr;
LIN_SDT_PROBE2(mib, linux_get_osname, entry, td, dst);
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE0(mib, linux_get_osname, return);
}
static int
@ -700,13 +483,10 @@ linux_set_osname(struct thread *td, char *osname)
struct prison *pr;
struct linux_prison *lpr;
LIN_SDT_PROBE2(mib, linux_set_osname, entry, td, osname);
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_set_osname, return, 0);
return (0);
}
@ -716,13 +496,9 @@ linux_get_osrelease(struct thread *td, char *dst)
struct prison *pr;
struct linux_prison *lpr;
LIN_SDT_PROBE2(mib, linux_get_osrelease, entry, td, dst);
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
bcopy(lpr->pr_osrelease, dst, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE0(mib, linux_get_osrelease, return);
}
int
@ -732,13 +508,10 @@ linux_kernver(struct thread *td)
struct linux_prison *lpr;
int osrel;
LIN_SDT_PROBE1(mib, linux_kernver, entry, td);
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
osrel = lpr->pr_osrel;
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_kernver, return, osrel);
return (osrel);
}
@ -749,15 +522,12 @@ linux_set_osrelease(struct thread *td, char *osrelease)
struct linux_prison *lpr;
int error;
LIN_SDT_PROBE2(mib, linux_set_osrelease, entry, td, osrelease);
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
error = linux_map_osrel(osrelease, &lpr->pr_osrel);
if (error == 0)
strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_set_osrelease, return, error);
return (error);
}
@ -768,13 +538,10 @@ linux_get_oss_version(struct thread *td)
struct linux_prison *lpr;
int version;
LIN_SDT_PROBE1(mib, linux_get_oss_version, entry, td);
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
version = lpr->pr_oss_version;
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_get_oss_version, return, version);
return (version);
}
@ -784,74 +551,9 @@ linux_set_oss_version(struct thread *td, int oss_version)
struct prison *pr;
struct linux_prison *lpr;
LIN_SDT_PROBE2(mib, linux_set_oss_version, entry, td, oss_version);
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
lpr->pr_oss_version = oss_version;
mtx_unlock(&pr->pr_mtx);
LIN_SDT_PROBE1(mib, linux_set_oss_version, return, 0);
return (0);
}
#if defined(DEBUG) || defined(KTR)
/* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */
u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))];
static int
linux_debug(int syscall, int toggle, int global)
{
if (global) {
char c = toggle ? 0 : 0xff;
memset(linux_debug_map, c, sizeof(linux_debug_map));
return (0);
}
if (syscall < 0 || syscall >= LINUX_SYS_MAXSYSCALL)
return (EINVAL);
if (toggle)
clrbit(linux_debug_map, syscall);
else
setbit(linux_debug_map, syscall);
return (0);
}
/*
* Usage: sysctl linux.debug=<syscall_nr>.<0/1>
*
* E.g.: sysctl linux.debug=21.0
*
* As a special case, syscall "all" will apply to all syscalls globally.
*/
#define LINUX_MAX_DEBUGSTR 16
static int
linux_sysctl_debug(SYSCTL_HANDLER_ARGS)
{
char value[LINUX_MAX_DEBUGSTR], *p;
int error, sysc, toggle;
int global = 0;
value[0] = '\0';
error = sysctl_handle_string(oidp, value, LINUX_MAX_DEBUGSTR, req);
if (error || req->newptr == NULL)
return (error);
for (p = value; *p != '\0' && *p != '.'; p++);
if (*p == '\0')
return (EINVAL);
*p++ = '\0';
sysc = strtol(value, NULL, 0);
toggle = strtol(p, NULL, 0);
if (strcmp(value, "all") == 0)
global = 1;
error = linux_debug(sysc, toggle, global);
return (error);
}
SYSCTL_PROC(_compat_linux, OID_AUTO, debug,
CTLTYPE_STRING | CTLFLAG_RW,
0, 0, linux_sysctl_debug, "A",
"Linux debugging control");
#endif /* DEBUG || KTR */

View File

@ -31,6 +31,10 @@
#ifndef _LINUX_MIB_H_
#define _LINUX_MIB_H_
#ifdef SYSCTL_DECL
SYSCTL_DECL(_compat_linux);
#endif
void linux_osd_jail_register(void);
void linux_osd_jail_deregister(void);

View File

@ -2197,6 +2197,63 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
return (error);
}
#if defined(DEBUG) || defined(KTR)
/* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */
u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))];
static int
linux_debug(int syscall, int toggle, int global)
{
if (global) {
char c = toggle ? 0 : 0xff;
memset(linux_debug_map, c, sizeof(linux_debug_map));
return (0);
}
if (syscall < 0 || syscall >= LINUX_SYS_MAXSYSCALL)
return (EINVAL);
if (toggle)
clrbit(linux_debug_map, syscall);
else
setbit(linux_debug_map, syscall);
return (0);
}
/*
* Usage: sysctl linux.debug=<syscall_nr>.<0/1>
*
* E.g.: sysctl linux.debug=21.0
*
* As a special case, syscall "all" will apply to all syscalls globally.
*/
#define LINUX_MAX_DEBUGSTR 16
int
linux_sysctl_debug(SYSCTL_HANDLER_ARGS)
{
char value[LINUX_MAX_DEBUGSTR], *p;
int error, sysc, toggle;
int global = 0;
value[0] = '\0';
error = sysctl_handle_string(oidp, value, LINUX_MAX_DEBUGSTR, req);
if (error || req->newptr == NULL)
return (error);
for (p = value; *p != '\0' && *p != '.'; p++);
if (*p == '\0')
return (EINVAL);
*p++ = '\0';
sysc = strtol(value, NULL, 0);
toggle = strtol(p, NULL, 0);
if (strcmp(value, "all") == 0)
global = 1;
error = linux_debug(sysc, toggle, global);
return (error);
}
#endif /* DEBUG || KTR */
int
linux_sched_rr_get_interval(struct thread *td,
struct linux_sched_rr_get_interval_args *uap)

View File

@ -31,6 +31,8 @@
#ifndef _LINUX_MISC_H_
#define _LINUX_MISC_H_
#include <sys/sysctl.h>
/*
* Miscellaneous
*/
@ -141,4 +143,6 @@ int linux_set_upcall_kse(struct thread *td, register_t stack);
int linux_set_cloned_tls(struct thread *td, void *desc);
struct thread *linux_tdfind(struct thread *, lwpid_t, pid_t);
int linux_sysctl_debug(SYSCTL_HANDLER_ARGS);
#endif /* _LINUX_MISC_H_ */

View File

@ -52,48 +52,11 @@ __FBSDID("$FreeBSD$");
#include <machine/stdarg.h>
#include <compat/linux/linux_util.h>
#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
#else
#include <machine/../linux/linux.h>
#endif
#include <compat/linux/linux_dtrace.h>
MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
const char linux_emul_path[] = "/compat/linux";
/* DTrace init */
LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
/**
* DTrace probes in this module.
*/
LIN_SDT_PROBE_DEFINE5(util, linux_emul_convpath, entry, "const char *",
"enum uio_seg", "char **", "int", "int");
LIN_SDT_PROBE_DEFINE1(util, linux_emul_convpath, return, "int");
LIN_SDT_PROBE_DEFINE1(util, linux_msg, entry, "const char *");
LIN_SDT_PROBE_DEFINE0(util, linux_msg, return);
LIN_SDT_PROBE_DEFINE2(util, linux_driver_get_name_dev, entry, "device_t",
"const char *");
LIN_SDT_PROBE_DEFINE0(util, linux_driver_get_name_dev, nullcall);
LIN_SDT_PROBE_DEFINE1(util, linux_driver_get_name_dev, return, "char *");
LIN_SDT_PROBE_DEFINE3(util, linux_driver_get_major_minor, entry, "char *",
"int *", "int *");
LIN_SDT_PROBE_DEFINE0(util, linux_driver_get_major_minor, nullcall);
LIN_SDT_PROBE_DEFINE1(util, linux_driver_get_major_minor, notfound, "char *");
LIN_SDT_PROBE_DEFINE3(util, linux_driver_get_major_minor, return, "int",
"int", "int");
LIN_SDT_PROBE_DEFINE0(util, linux_get_char_devices, entry);
LIN_SDT_PROBE_DEFINE1(util, linux_get_char_devices, return, "char *");
LIN_SDT_PROBE_DEFINE1(util, linux_free_get_char_devices, entry, "char *");
LIN_SDT_PROBE_DEFINE0(util, linux_free_get_char_devices, return);
LIN_SDT_PROBE_DEFINE1(util, linux_device_register_handler, entry,
"struct linux_device_handler *");
LIN_SDT_PROBE_DEFINE1(util, linux_device_register_handler, return, "int");
LIN_SDT_PROBE_DEFINE1(util, linux_device_unregister_handler, entry,
"struct linux_device_handler *");
LIN_SDT_PROBE_DEFINE1(util, linux_device_unregister_handler, return, "int");
/*
* Search an alternate path before passing pathname arguments on to
* system calls. Useful for keeping a separate 'emulation tree'.
@ -107,13 +70,9 @@ linux_emul_convpath(struct thread *td, const char *path, enum uio_seg pathseg,
{
int retval;
LIN_SDT_PROBE5(util, linux_emul_convpath, entry, path, pathseg, pbuf,
cflag, dfd);
retval = kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf,
cflag, dfd);
LIN_SDT_PROBE1(util, linux_emul_convpath, return, retval);
return (retval);
}
@ -123,16 +82,12 @@ linux_msg(const struct thread *td, const char *fmt, ...)
va_list ap;
struct proc *p;
LIN_SDT_PROBE1(util, linux_msg, entry, fmt);
p = td->td_proc;
printf("linux: pid %d (%s): ", (int)p->p_pid, p->p_comm);
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
printf("\n");
LIN_SDT_PROBE0(util, linux_msg, return);
}
struct device_element
@ -155,24 +110,14 @@ linux_driver_get_name_dev(device_t dev)
struct device_element *de;
const char *device_name = device_get_name(dev);
LIN_SDT_PROBE2(util, linux_driver_get_name_dev, entry, dev,
device_name);
if (device_name == NULL) {
LIN_SDT_PROBE0(util, linux_driver_get_name_dev, nullcall);
LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, NULL);
if (device_name == NULL)
return NULL;
}
TAILQ_FOREACH(de, &devices, list) {
if (strcmp(device_name, de->entry.bsd_driver_name) == 0) {
LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return,
de->entry.linux_driver_name);
if (strcmp(device_name, de->entry.bsd_driver_name) == 0)
return (de->entry.linux_driver_name);
}
}
LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, NULL);
return NULL;
return (NULL);
}
int
@ -180,15 +125,8 @@ linux_driver_get_major_minor(const char *node, int *major, int *minor)
{
struct device_element *de;
LIN_SDT_PROBE3(util, linux_driver_get_major_minor, entry, node, major,
minor);
if (node == NULL || major == NULL || minor == NULL) {
LIN_SDT_PROBE0(util, linux_driver_get_major_minor, nullcall);
LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 1,
0, 0);
if (node == NULL || major == NULL || minor == NULL)
return 1;
}
if (strlen(node) > strlen("pts/") &&
strncmp(node, "pts/", strlen("pts/")) == 0) {
@ -203,25 +141,18 @@ linux_driver_get_major_minor(const char *node, int *major, int *minor)
*major = 136 + (devno / 256);
*minor = devno % 256;
LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 0,
*major, *minor);
return 0;
return (0);
}
TAILQ_FOREACH(de, &devices, list) {
if (strcmp(node, de->entry.bsd_device_name) == 0) {
*major = de->entry.linux_major;
*minor = de->entry.linux_minor;
LIN_SDT_PROBE3(util, linux_driver_get_major_minor,
return, 0, *major, *minor);
return 0;
return (0);
}
}
LIN_SDT_PROBE1(util, linux_driver_get_major_minor, notfound, node);
LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 1, 0, 0);
return 1;
return (1);
}
char *
@ -232,8 +163,6 @@ linux_get_char_devices()
char formated[256];
int current_size = 0, string_size = 1024;
LIN_SDT_PROBE0(util, linux_get_char_devices, entry);
string = malloc(string_size, M_LINUX, M_WAITOK);
string[0] = '\000';
last = "";
@ -260,19 +189,14 @@ linux_get_char_devices()
}
}
LIN_SDT_PROBE1(util, linux_get_char_devices, return, string);
return string;
return (string);
}
void
linux_free_get_char_devices(char *string)
{
LIN_SDT_PROBE1(util, linux_get_char_devices, entry, string);
free(string, M_LINUX);
LIN_SDT_PROBE0(util, linux_get_char_devices, return);
}
static int linux_major_starting = 200;
@ -282,13 +206,8 @@ linux_device_register_handler(struct linux_device_handler *d)
{
struct device_element *de;
LIN_SDT_PROBE1(util, linux_device_register_handler, entry, d);
if (d == NULL) {
LIN_SDT_PROBE1(util, linux_device_register_handler, return,
EINVAL);
if (d == NULL)
return (EINVAL);
}
de = malloc(sizeof(*de), M_LINUX, M_WAITOK);
if (d->linux_major < 0) {
@ -299,7 +218,6 @@ linux_device_register_handler(struct linux_device_handler *d)
/* Add the element to the list, sorted on span. */
TAILQ_INSERT_TAIL(&devices, de, list);
LIN_SDT_PROBE1(util, linux_device_register_handler, return, 0);
return (0);
}
@ -308,25 +226,17 @@ linux_device_unregister_handler(struct linux_device_handler *d)
{
struct device_element *de;
LIN_SDT_PROBE1(util, linux_device_unregister_handler, entry, d);
if (d == NULL) {
LIN_SDT_PROBE1(util, linux_device_unregister_handler, return,
EINVAL);
if (d == NULL)
return (EINVAL);
}
TAILQ_FOREACH(de, &devices, list) {
if (bcmp(d, &de->entry, sizeof(*d)) == 0) {
TAILQ_REMOVE(&devices, de, list);
free(de, M_LINUX);
LIN_SDT_PROBE1(util, linux_device_unregister_handler,
return, 0);
return (0);
}
}
LIN_SDT_PROBE1(util, linux_device_unregister_handler, return, EINVAL);
return (EINVAL);
}

View File

@ -44,6 +44,8 @@
#include <sys/cdefs.h>
#include <sys/uio.h>
MALLOC_DECLARE(M_LINUX);
extern const char linux_emul_path[];
int linux_emul_convpath(struct thread *, const char *, enum uio_seg, char **, int, int);

View File

@ -508,6 +508,7 @@ compat/linux/linux_timer.c optional compat_linux32
compat/linux/linux_uid16.c optional compat_linux32
compat/linux/linux_util.c optional compat_linux32
compat/linux/linux_vdso.c optional compat_linux32
compat/linux/linux_common.c optional compat_linux32
dev/amr/amr_linux.c optional compat_linux32 amr
dev/mfi/mfi_linux.c optional compat_linux32 mfi
#

View File

@ -46,10 +46,6 @@ extern u_char linux_debug_map[];
(long)td->td_proc->p_pid, (long)td->td_tid
#define LINUX_DTRACE linuxulator
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_LINUX);
#endif
#define LINUX_SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE)
#define LINUX_USRSTACK LINUX_SHAREDPAGE

View File

@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/vnode.h>
@ -75,14 +76,19 @@ __FBSDID("$FreeBSD$");
MODULE_VERSION(linux, 1);
MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
#if BYTE_ORDER == LITTLE_ENDIAN
#define SHELLMAGIC 0x2123 /* #! */
#else
#define SHELLMAGIC 0x2321
#endif
#if defined(DEBUG)
SYSCTL_PROC(_compat_linux, OID_AUTO, debug,
CTLTYPE_STRING | CTLFLAG_RW,
0, 0, linux_sysctl_debug, "A",
"Linux debugging control");
#endif
/*
* Allow the sendsig functions to use the ldebug() facility
* even though they are not syscalls themselves. Map them
@ -103,7 +109,6 @@ extern char _binary_linux_locore_o_end;
extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
static int linux_fixup(register_t **stack_base,
struct image_params *iparams);
@ -1129,7 +1134,6 @@ linux_elf_modevent(module_t mod, int type, void *data)
Elf32_Brandinfo **brandinfo;
int error;
struct linux_ioctl_handler **lihp;
struct linux_device_handler **ldhp;
error = 0;
@ -1142,8 +1146,6 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (error == 0) {
SET_FOREACH(lihp, linux_ioctl_handler_set)
linux_ioctl_register_handler(*lihp);
SET_FOREACH(ldhp, linux_device_handler_set)
linux_device_register_handler(*ldhp);
LIST_INIT(&futex_list);
mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF);
linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
@ -1176,8 +1178,6 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (error == 0) {
SET_FOREACH(lihp, linux_ioctl_handler_set)
linux_ioctl_unregister_handler(*lihp);
SET_FOREACH(ldhp, linux_device_handler_set)
linux_device_unregister_handler(*ldhp);
mtx_destroy(&futex_mtx);
EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);

View File

@ -196,6 +196,7 @@ SUBDIR= \
${_linprocfs} \
${_linsysfs} \
${_linux} \
${_linux_common} \
${_linuxapi} \
lmc \
lpt \
@ -627,6 +628,7 @@ _sfxge= sfxge
.if ${MK_BHYVE} != "no" || defined(ALL_MODULES)
_vmm= vmm
_linux_common= linux_common
.endif
.endif

View File

@ -5,11 +5,6 @@
KMOD= linprocfs
SRCS= vnode_if.h \
device_if.h bus_if.h \
linprocfs.c \
opt_compat.h
.if ${MACHINE_CPUARCH} == "amd64"
CFLAGS+=-DCOMPAT_LINUX32
.endif
linprocfs.c
.include <bsd.kmod.mk>

View File

@ -5,11 +5,6 @@
KMOD= linsysfs
SRCS= vnode_if.h \
device_if.h bus_if.h pci_if.h \
linsysfs.c \
opt_compat.h
.if ${MACHINE_CPUARCH} == "amd64"
CFLAGS+=-DCOMPAT_LINUX32
.endif
linsysfs.c
.include <bsd.kmod.mk>

View File

@ -12,9 +12,9 @@ VDSO= linux${SFX}_vdso
KMOD= linux
SRCS= linux_fork.c linux${SFX}_dummy.c linux_emul.c linux_file.c \
linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \
linux${SFX}_machdep.c linux_mib.c linux_misc.c linux_signal.c \
linux${SFX}_machdep.c linux_misc.c linux_signal.c \
linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c \
linux${SFX}_sysvec.c linux_uid16.c linux_util.c linux_time.c \
linux${SFX}_sysvec.c linux_uid16.c linux_time.c \
linux_timer.c linux_vdso.c \
opt_inet6.h opt_compat.h opt_posix.h opt_usb.h vnode_if.h \
device_if.h bus_if.h assym.s \
@ -30,16 +30,17 @@ SRCS+= opt_apic.h
OBJS= ${VDSO}.so
.if ${MACHINE_CPUARCH} == "i386"
SRCS+= linux_ptrace.c imgact_linux.c opt_cpu.h
SRCS+= linux_ptrace.c imgact_linux.c linux_util.c linux_mib.c opt_cpu.h
.endif
.if ${MACHINE_CPUARCH} == "i386"
EXPORT_SYMS=
EXPORT_SYMS+= linux_emul_path
EXPORT_SYMS+= linux_get_osname
EXPORT_SYMS+= linux_get_osrelease
EXPORT_SYMS+= linux_ifname
EXPORT_SYMS+= linux_ioctl_register_handler
EXPORT_SYMS+= linux_ioctl_unregister_handler
.endif
CLEANFILES= linux${SFX}_assym.h linux${SFX}_genassym.o linux${SFX}_locore.o

View File

@ -0,0 +1,25 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../compat/linux
KMOD= linux_common
SRCS= linux_common.c linux_mib.c linux_util.c \
opt_compat.h device_if.h vnode_if.h bus_if.h
EXPORT_SYMS=
EXPORT_SYMS+= linux_emul_path
EXPORT_SYMS+= linux_ioctl_register_handler
EXPORT_SYMS+= linux_ioctl_unregister_handler
EXPORT_SYMS+= linux_get_osname
EXPORT_SYMS+= linux_get_osrelease
.if !defined(KERNBUILDDIR)
.if defined(DEBUG)
CFLAGS+=-DDEBUG
.endif
.if defined(KTR)
CFLAGS+=-DKTR
.endif
.endif
.include <bsd.kmod.mk>