MFp4 (111746+):
Redo the checking for 2.6 emulation. We now cache the value of use26 and replace calls to linux_get_osrelease() + parsing with a call to linux_use26(). Typical path is lockless now. Pointed out by: kib This allows to ship RELENG_7_0 with a default osrelease of 2.4.2 and the possibility to enable 2.6.x emulation without the possible performance impact of the previous version of the check. Submitted by: rdivacky
This commit is contained in:
parent
ef95cfeab9
commit
9ce8f9bcdd
@ -52,6 +52,7 @@ struct linux_prison {
|
||||
char pr_osname[LINUX_MAX_UTSNAME];
|
||||
char pr_osrelease[LINUX_MAX_UTSNAME];
|
||||
int pr_oss_version;
|
||||
int pr_use_linux26; /* flag to determine whether to use 2.6 emulation */
|
||||
};
|
||||
|
||||
SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0,
|
||||
@ -82,6 +83,7 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, osname,
|
||||
"Linux kernel OS name");
|
||||
|
||||
static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.4.2";
|
||||
static int linux_use_linux26 = 0;
|
||||
|
||||
static int
|
||||
linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS)
|
||||
@ -226,20 +228,46 @@ linux_get_osrelease(struct thread *td, char *dst)
|
||||
mtx_unlock(&osname_lock);
|
||||
}
|
||||
|
||||
int
|
||||
linux_use26(struct thread *td)
|
||||
{
|
||||
struct prison *pr;
|
||||
struct linux_prison *lpr;
|
||||
int use26 = 0; /* defaults to off */
|
||||
|
||||
pr = td->td_ucred->cr_prison;
|
||||
if (pr != NULL) {
|
||||
mtx_lock(&pr->pr_mtx);
|
||||
if (pr->pr_linux != NULL) {
|
||||
lpr = (struct linux_prison *)pr->pr_linux;
|
||||
use26 = lpr->pr_use_linux26;
|
||||
}
|
||||
mtx_unlock(&pr->pr_mtx);
|
||||
} else
|
||||
use26 = linux_use_linux26;
|
||||
|
||||
return (use26);
|
||||
}
|
||||
|
||||
int
|
||||
linux_set_osrelease(struct thread *td, char *osrelease)
|
||||
{
|
||||
struct prison *pr;
|
||||
struct linux_prison *lpr;
|
||||
int use26;
|
||||
|
||||
use26 = (strlen(osrelease) >= 3 && osrelease[2] == '6');
|
||||
|
||||
pr = linux_get_prison(td);
|
||||
if (pr != NULL) {
|
||||
lpr = (struct linux_prison *)pr->pr_linux;
|
||||
strcpy(lpr->pr_osrelease, osrelease);
|
||||
lpr->pr_use_linux26 = use26;
|
||||
mtx_unlock(&pr->pr_mtx);
|
||||
} else {
|
||||
mtx_lock(&osname_lock);
|
||||
strcpy(linux_osrelease, osrelease);
|
||||
linux_use_linux26 = use26;
|
||||
mtx_unlock(&osname_lock);
|
||||
}
|
||||
|
||||
|
@ -40,4 +40,6 @@ int linux_set_osrelease(struct thread *td, char *osrelease);
|
||||
int linux_get_oss_version(struct thread *td);
|
||||
int linux_set_oss_version(struct thread *td, int oss_version);
|
||||
|
||||
int linux_use26(struct thread *td);
|
||||
|
||||
#endif /* _LINUX_MIB_H_ */
|
||||
|
@ -1400,15 +1400,13 @@ int
|
||||
linux_getpid(struct thread *td, struct linux_getpid_args *args)
|
||||
{
|
||||
struct linux_emuldata *em;
|
||||
char osrel[LINUX_MAX_UTSNAME];
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(getpid))
|
||||
printf(ARGS(getpid, ""));
|
||||
#endif
|
||||
|
||||
linux_get_osrelease(td, osrel);
|
||||
if (strlen(osrel) >= 3 && osrel[2] == '6') {
|
||||
if (linux_use26(td)) {
|
||||
em = em_find(td->td_proc, EMUL_UNLOCKED);
|
||||
KASSERT(em != NULL, ("getpid: emuldata not found.\n"));
|
||||
td->td_retval[0] = em->shared->group_pid;
|
||||
@ -1438,15 +1436,13 @@ linux_getppid(struct thread *td, struct linux_getppid_args *args)
|
||||
{
|
||||
struct linux_emuldata *em;
|
||||
struct proc *p, *pp;
|
||||
char osrel[LINUX_MAX_UTSNAME];
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(getppid))
|
||||
printf(ARGS(getppid, ""));
|
||||
#endif
|
||||
|
||||
linux_get_osrelease(td, osrel);
|
||||
if (strlen(osrel) >= 3 && osrel[2] != '6') {
|
||||
if (!linux_use26(td)) {
|
||||
PROC_LOCK(td->td_proc);
|
||||
td->td_retval[0] = td->td_proc->p_pptr->p_pid;
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
@ -1573,15 +1569,13 @@ linux_exit_group(struct thread *td, struct linux_exit_group_args *args)
|
||||
{
|
||||
struct linux_emuldata *em, *td_em, *tmp_em;
|
||||
struct proc *sp;
|
||||
char osrel[LINUX_MAX_UTSNAME];
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(exit_group))
|
||||
printf(ARGS(exit_group, "%i"), args->error_code);
|
||||
#endif
|
||||
|
||||
linux_get_osrelease(td, osrel);
|
||||
if (strlen(osrel) >= 3 && osrel[2] == '6') {
|
||||
if (linux_use26(td)) {
|
||||
td_em = em_find(td->td_proc, EMUL_UNLOCKED);
|
||||
|
||||
KASSERT(td_em != NULL, ("exit_group: emuldata not found.\n"));
|
||||
|
Loading…
Reference in New Issue
Block a user