PR kern/27184: Have linux_sys_waitpid() call linux_sys_wait4() so the

supported options can't get out of sync.  This add support for the
  linux __WCLONE and __WALL options (NetBSD version: WALTSIG and WALLSIG)
Add a diagnostic check to see if the one unhandled option (__WNOTHREAD) is
  specified.
This should prevent linux processes from losing their children and creating
  tons of zombie processes.
This commit is contained in:
erh 2004-10-07 19:30:28 +00:00
parent 8f36adaafb
commit f747989e34
3 changed files with 34 additions and 44 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_misc.c,v 1.132 2004/09/20 18:41:07 jdolecek Exp $ */
/* $NetBSD: linux_misc.c,v 1.133 2004/10/07 19:30:28 erh Exp $ */
/*-
* Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.132 2004/09/20 18:41:07 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.133 2004/10/07 19:30:28 erh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -199,7 +199,9 @@ bsd_to_linux_wstat(st)
}
/*
* This is very much the same as waitpid()
* wait4(2). Passed on to the NetBSD call, surrounded by code to
* reserve some space for a NetBSD-style wait status, and converting
* it to what Linux wants.
*/
int
linux_sys_wait4(l, v, retval)
@ -226,9 +228,7 @@ linux_sys_wait4(l, v, retval)
linux_options = SCARG(uap, options);
options = 0;
if (linux_options &
~(LINUX_WAIT4_WNOHANG|LINUX_WAIT4_WUNTRACED|LINUX_WAIT4_WALL|
LINUX_WAIT4_WCLONE))
if (linux_options & ~(LINUX_WAIT4_KNOWNFLAGS))
return (EINVAL);
if (linux_options & LINUX_WAIT4_WNOHANG)
@ -239,6 +239,13 @@ linux_sys_wait4(l, v, retval)
options |= WALLSIG;
if (linux_options & LINUX_WAIT4_WCLONE)
options |= WALTSIG;
#ifdef DIAGNOSTIC
if (linux_options & LINUX_WAIT4_WNOTHREAD)
printf("WARNING: %s: linux process %d.%d called "
"waitpid with __WNOTHREAD set!",
__FILE__, p->p_pid, l->l_lid);
#endif
SCARG(&w4a, pid) = SCARG(uap, pid);
SCARG(&w4a, status) = status;

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_misc.h,v 1.9 2004/09/20 18:41:07 jdolecek Exp $ */
/* $NetBSD: linux_misc.h,v 1.10 2004/10/07 19:30:28 erh Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -42,10 +42,17 @@
/*
* Options passed to the Linux wait4() system call.
*/
#define LINUX_WAIT4_WNOHANG 0x00000001
#define LINUX_WAIT4_WUNTRACED 0x00000002
#define LINUX_WAIT4_WALL 0x40000000
#define LINUX_WAIT4_WCLONE 0x80000000
#define LINUX_WAIT4_WNOHANG 0x00000001
#define LINUX_WAIT4_WUNTRACED 0x00000002
#define LINUX_WAIT4_WNOTHREAD 0x20000000
#define LINUX_WAIT4_WALL 0x40000000
#define LINUX_WAIT4_WCLONE 0x80000000
#define LINUX_WAIT4_KNOWNFLAGS (LINUX_WAIT4_WNOHANG | \
LINUX_WAIT4_WUNTRACED | \
LINUX_WAIT4_WNOTHREAD | \
LINUX_WAIT4_WALL | \
LINUX_WAIT4_WCLONE)
/* This looks very unportable to me, but this is how Linux defines it. */
struct linux_sysinfo {

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_misc_notalpha.c,v 1.71 2004/09/24 13:10:46 he Exp $ */
/* $NetBSD: linux_misc_notalpha.c,v 1.72 2004/10/07 19:30:28 erh Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.71 2004/09/24 13:10:46 he Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.72 2004/10/07 19:30:28 erh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -292,9 +292,7 @@ linux_sys_utime(l, v, retval)
}
/*
* waitpid(2). Passed on to the NetBSD call, surrounded by code to
* reserve some space for a NetBSD-style wait status, and converting
* it to what Linux wants.
* waitpid(2). Just forward on to linux_sys_wait4 with a NULL rusage.
*/
int
linux_sys_waitpid(l, v, retval)
@ -307,36 +305,14 @@ linux_sys_waitpid(l, v, retval)
syscallarg(int *) status;
syscallarg(int) options;
} */ *uap = v;
struct proc *p = l->l_proc;
struct sys_wait4_args w4a;
int error, *status, tstat;
caddr_t sg;
struct linux_sys_wait4_args linux_w4a;
if (SCARG(uap, status) != NULL) {
sg = stackgap_init(p, 0);
status = (int *) stackgap_alloc(p, &sg, sizeof status);
} else
status = NULL;
SCARG(&linux_w4a, pid) = SCARG(uap, pid);
SCARG(&linux_w4a, status) = SCARG(uap, status);
SCARG(&linux_w4a, options) = SCARG(uap, options);
SCARG(&linux_w4a, rusage) = NULL;
SCARG(&w4a, pid) = SCARG(uap, pid);
SCARG(&w4a, status) = status;
SCARG(&w4a, options) = SCARG(uap, options);
SCARG(&w4a, rusage) = NULL;
if ((error = sys_wait4(l, &w4a, retval)))
return error;
sigdelset(&p->p_sigctx.ps_siglist, SIGCHLD);
if (status != NULL) {
if ((error = copyin(status, &tstat, sizeof tstat)))
return error;
bsd_to_linux_wstat(&tstat);
return copyout(&tstat, SCARG(uap, status), sizeof tstat);
}
return 0;
return linux_sys_wait4(l, &linux_w4a, retval);
}
int