diff options
| -rw-r--r-- | lib/libc/gen/sysctl.3 | 88 | ||||
| -rw-r--r-- | sbin/sysctl/sysctl.8 | 24 | ||||
| -rw-r--r-- | sbin/sysctl/sysctl.c | 74 | ||||
| -rw-r--r-- | sys/arch/alpha/alpha/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/amiga/amiga/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/hp300/hp300/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/i386/i386/machdep.c | 21 | ||||
| -rw-r--r-- | sys/arch/mac68k/mac68k/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/macppc/macppc/machdep.c | 19 | ||||
| -rw-r--r-- | sys/arch/mvme68k/mvme68k/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/mvme88k/mvme88k/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/mvmeppc/mvmeppc/machdep.c | 19 | ||||
| -rw-r--r-- | sys/arch/sparc/sparc/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/sparc64/sparc64/machdep.c | 19 | ||||
| -rw-r--r-- | sys/arch/sun3/sun3/machdep.c | 20 | ||||
| -rw-r--r-- | sys/arch/vax/vax/machdep.c | 21 | ||||
| -rw-r--r-- | sys/compat/common/kern_ipc_23.c | 134 | ||||
| -rw-r--r-- | sys/kern/kern_sysctl.c | 45 | ||||
| -rw-r--r-- | sys/kern/sysv_sem.c | 660 | ||||
| -rw-r--r-- | sys/kern/sysv_shm.c | 443 | ||||
| -rw-r--r-- | sys/sys/malloc.h | 7 | ||||
| -rw-r--r-- | sys/sys/sem.h | 51 | ||||
| -rw-r--r-- | sys/sys/shm.h | 76 | ||||
| -rw-r--r-- | sys/sys/sysctl.h | 8 | ||||
| -rw-r--r-- | usr.bin/ipcs/ipcs.c | 130 |
26 files changed, 1104 insertions, 915 deletions
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3 index 5ba3f08b7b9..de1053d42aa 100644 --- a/lib/libc/gen/sysctl.3 +++ b/lib/libc/gen/sysctl.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sysctl.3,v 1.95 2002/11/25 03:04:48 wcobb Exp $ +.\" $OpenBSD: sysctl.3,v 1.96 2002/12/17 23:11:32 millert Exp $ .\" .\" Copyright (c) 1993 .\" The Regents of the University of California. All rights reserved. @@ -304,6 +304,8 @@ information. .It Dv KERN_RND No " struct rndstats no" .It Dv KERN_SAVED_IDS No " integer no" .It Dv KERN_SECURELVL No " integer raise only" +.It Dv KERN_SEMINFO No " node not applicable" +.It Dv KERN_SHMINFO No " node not applicable" .It Dv KERN_SOMINCONN No " integer yes" .It Dv KERN_SOMAXCONN No " integer yes" .It Dv KERN_SYSVIPC_INFO No " node not applicable" @@ -535,6 +537,90 @@ Returns 1 if saved set-group-ID and saved set-user-ID are available. The system security level. This level may be raised by processes with appropriate privileges. It may only be lowered by process 1. +.It Dv KERN_SEMINFO +Return the elements of +.Li struct seminfo . +If the kernel is not compiled with System V style semaphore support, +attempts to retrieve any of the +.Dv KERN_SEMINFO +values will fail with +.Er EOPNOTSUPP . +The third level names for the elements of +.Li struct seminfo +are detailed below. +The changeable column shows whether a process with appropriate +privileges may change the value. +.Bl -column "KERN_SEMINFO_SEMMNI" "integer" "yes" -offset indent +.It Sy "Third level name" Type Changeable +.It Dv KERN_SEMINFO_SEMMNI integer yes +.It Dv KERN_SEMINFO_SEMMNS integer yes +.It Dv KERN_SEMINFO_SEMMNU integer yes +.It Dv KERN_SEMINFO_SEMMSL integer yes +.It Dv KERN_SEMINFO_SEMOPM integer yes +.It Dv KERN_SEMINFO_SEMUME integer no +.It Dv KERN_SEMINFO_SEMUSZ integer no +.It Dv KERN_SEMINFO_SEMVMX integer no +.It Dv KERN_SEMINFO_SEMAEM integer no +.El +.Pp +The variables are as follows: +.Bl -tag -width "123456" +.It Dv KERN_SEMINFO_SEMMNI +The maximum number of semaphore identifiers allowed. +.It Dv KERN_SEMINFO_SEMMNS +The maximum number of semaphores allowed in the system. +.It Dv KERN_SEMINFO_SEMMNU +The maximum number of semaphore undo structures allowed in the system. +.It Dv KERN_SEMINFO_SEMMSL +The maximum number of semaphores allowed per id. +.It Dv KERN_SEMINFO_SEMOPM +The maximum number of operations per +.Xr semop 2 +call. +.It Dv KERN_SEMINFO_SEMUME +The maximum number of undo entries per process. +.It Dv KERN_SEMINFO_SEMUSZ +The size (in bytes) of the undo structure. +.It Dv KERN_SEMINFO_SEMVMX +The semaphore maximum value. +.It Dv KERN_SEMINFO_SEMAEM +The adjust on exit maximum value. +.El +.It Dv KERN_SHMINFO +Return the elements of +.Li struct shminfo . +If the kernel is not compiled with System V style shared memory support, +attempts to retrieve any of the +.Dv KERN_SHMINFO +values will fail with +.Er EOPNOTSUPP . +The third level names for the elements of +.Li struct shminfo +are detailed below. +The changeable column shows whether a process with appropriate +privileges may change the value. +.Bl -column "KERN_SHMINFO_SHMMAX" "integer" "yes" -offset indent +.It Sy "Third level name" Type Changeable +.It Dv KERN_SHMINFO_SHMMAX integer yes +.It Dv KERN_SHMINFO_SHMMIN integer yes +.It Dv KERN_SHMINFO_SHMMNI integer yes +.It Dv KERN_SHMINFO_SHMSEG integer yes +.It Dv KERN_SHMINFO_SHMALL integer yes +.El +.Pp +The variables are as follows: +.Bl -tag -width "123456" +.It Dv KERN_SHMINFO_SHMMAX +The maximum shared memory segment size (in bytes). +.It Dv KERN_SHMINFO_SHMMIN +The minimum shared memory segment size (in bytes). +.It Dv KERN_SHMINFO_SHMMNI +The maximum number of shared memory identifiers in the system. +.It Dv KERN_SHMINFO_SHMSEG +The maximum number of shared memory segments per process. +.It Dv KERN_SHMINFO_SHMALL +The maximum amount of total shared memory allowed in the system (in pages). +.El .It Dv KERN_SOMAXCONN Upper bound on the number of half-open connections a process can allow to be associated with a socket, using diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8 index 912817eb280..a10afeead75 100644 --- a/sbin/sysctl/sysctl.8 +++ b/sbin/sysctl/sysctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sysctl.8,v 1.91 2002/11/25 03:04:48 wcobb Exp $ +.\" $OpenBSD: sysctl.8,v 1.92 2002/12/17 23:11:32 millert Exp $ .\" $NetBSD: sysctl.8,v 1.4 1995/09/30 07:12:49 thorpej Exp $ .\" .\" Copyright (c) 1993 @@ -123,6 +123,7 @@ privilege can change the value. .It kern.nchstats struct no .It kern.forkstat struct no .It kern.somaxconn integer yes +.It kern.somaxconn integer yes .It kern.sominconn integer yes .It kern.usermount integer yes .It kern.random struct no @@ -153,6 +154,20 @@ privilege can change the value. .It kern.ttycount integer no .It kern.numvnodes integer no .It kern.mbstat struct no +.It kern.seminfo.semmni integer yes +.It kern.seminfo.semmns integer yes +.It kern.seminfo.semmnu integer yes +.It kern.seminfo.semmsl integer yes +.It kern.seminfo.semopm integer yes +.It kern.seminfo.semume integer no +.It kern.seminfo.semusz integer no +.It kern.seminfo.semvmx integer no +.It kern.seminfo.semaem integer no +.It kern.shminfo.shmmax integer yes +.It kern.shminfo.shmmin integer yes +.It kern.shminfo.shmmni integer yes +.It kern.shminfo.shmseg integer yes +.It kern.shminfo.shmall integer yes .It vm.loadavg struct no .It vm.psstrings struct no .It vm.swapencrypt.enable integer yes @@ -397,6 +412,13 @@ See and .Xr nfsd 8 for futher discussion. +.Pp +To set the amount of shared memory available in the system and +the maximum number of shared memory segments: +.Bd -literal noffset indent +# sysctl -w kern.shminfo.shmmax=33554432 +# sysctl -w kern.shminfo.shmseg=32 +.Ed .Sh FILES .Bl -tag -width <ufs/ffs/ffs_extern.h> -compact .It Pa <sys/sysctl.h> diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c index 89d1c4d2e40..114c7d1d21c 100644 --- a/sbin/sysctl/sysctl.c +++ b/sbin/sysctl/sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.c,v 1.84 2002/07/06 19:14:20 nordin Exp $ */ +/* $OpenBSD: sysctl.c,v 1.85 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */ /* @@ -35,16 +35,16 @@ */ #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint #if 0 -static char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95"; +static const char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95"; #else -static char *rcsid = "$OpenBSD: sysctl.c,v 1.84 2002/07/06 19:14:20 nordin Exp $"; +static char *rcsid = "$OpenBSD: sysctl.c,v 1.85 2002/12/17 23:11:32 millert Exp $"; #endif #endif /* not lint */ @@ -52,6 +52,8 @@ static char *rcsid = "$OpenBSD: sysctl.c,v 1.84 2002/07/06 19:14:20 nordin Exp $ #include <sys/gmon.h> #include <sys/mount.h> #include <sys/stat.h> +#include <sys/sem.h> +#include <sys/shm.h> #include <sys/sysctl.h> #include <sys/socket.h> #include <sys/malloc.h> @@ -128,6 +130,8 @@ struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES; struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES; struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES; struct ctlname ttyname[] = CTL_KERN_TTY_NAMES; +struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES; +struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES; struct ctlname *vfsname; #ifdef CTL_MACHDEP_NAMES struct ctlname machdepname[] = CTL_MACHDEP_NAMES; @@ -199,6 +203,8 @@ int sysctl_forkstat(char *, char **, int *, int, int *); int sysctl_tty(char *, char **, int *, int, int *); int sysctl_nchstats(char *, char **, int *, int, int *); int sysctl_malloc(char *, char **, int *, int, int *); +int sysctl_seminfo(char *, char **, int *, int, int *); +int sysctl_shminfo(char *, char **, int *, int, int *); #ifdef CPU_CHIPSET int sysctl_chipset(char *, char **, int *, int, int *); #endif @@ -403,6 +409,16 @@ parse(char *string, int flags) special |= LONGARRAY; lal = CPUSTATES; break; + case KERN_SEMINFO: + len = sysctl_seminfo(string, &bufp, mib, flags, &type); + if (len < 0) + return; + break; + case KERN_SHMINFO: + len = sysctl_shminfo(string, &bufp, mib, flags, &type); + if (len < 0) + return; + break; } break; @@ -1319,6 +1335,8 @@ struct list kernmalloclist = { kernmallocname, KERN_MALLOC_MAXID }; struct list forkstatlist = { forkstatname, KERN_FORKSTAT_MAXID }; struct list nchstatslist = { nchstatsname, KERN_NCHSTATS_MAXID }; struct list ttylist = { ttyname, KERN_TTY_MAXID }; +struct list semlist = { semname, KERN_SEMINFO_MAXID }; +struct list shmlist = { shmname, KERN_SHMINFO_MAXID }; /* * handle vfs namei cache statistics @@ -1785,6 +1803,54 @@ sysctl_ipx(char *string, char **bufpp, int mib[], int flags, int *typep) } /* + * Handle SysV semaphore info requests + */ +int +sysctl_seminfo(string, bufpp, mib, flags, typep) + char *string; + char **bufpp; + int mib[]; + int flags; + int *typep; +{ + int indx; + + if (*bufpp == NULL) { + listall(string, &semlist); + return(-1); + } + if ((indx = findname(string, "third", bufpp, &semlist)) == -1) + return(-1); + mib[2] = indx; + *typep = CTLTYPE_INT; + return(3); +} + +/* + * Handle SysV shared memory info requests + */ +int +sysctl_shminfo(string, bufpp, mib, flags, typep) + char *string; + char **bufpp; + int mib[]; + int flags; + int *typep; +{ + int indx; + + if (*bufpp == NULL) { + listall(string, &shmlist); + return(-1); + } + if ((indx = findname(string, "third", bufpp, &shmlist)) == -1) + return(-1); + mib[2] = indx; + *typep = CTLTYPE_INT; + return(3); +} + +/* * Scan a list of names searching for a particular name. */ int diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index 1b8ffce6245..1713c846d21 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.78 2002/11/07 04:31:59 art Exp $ */ +/* $OpenBSD: machdep.c,v 1.79 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */ /*- @@ -96,12 +96,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <sys/mount.h> #include <sys/syscallargs.h> @@ -816,18 +810,6 @@ allocsys(v) #define valloc(name, type, num) \ (name) = (type *)v; v = (caddr_t)ALIGN((name)+(num)) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/amiga/amiga/machdep.c b/sys/arch/amiga/amiga/machdep.c index 2e23c438755..356437175b1 100644 --- a/sys/arch/amiga/amiga/machdep.c +++ b/sys/arch/amiga/amiga/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.70 2002/06/11 03:25:31 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.71 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: machdep.c,v 1.95 1997/08/27 18:31:17 is Exp $ */ /* @@ -65,15 +65,9 @@ #include <sys/syscallargs.h> #include <sys/core.h> #include <sys/kcore.h> -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif #include <net/netisr.h> #define MAXMEM 64*1024 /* XXX - from cmap.h */ @@ -362,18 +356,6 @@ again: (name) = (type *)v; v = (caddr_t)((name)+(num)) #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/hp300/hp300/machdep.c b/sys/arch/hp300/hp300/machdep.c index ddd2c838c4b..baf81ceefcf 100644 --- a/sys/arch/hp300/hp300/machdep.c +++ b/sys/arch/hp300/hp300/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.82 2002/12/10 23:34:36 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.83 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: machdep.c,v 1.121 1999/03/26 23:41:29 mycroft Exp $ */ /* @@ -73,12 +73,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <machine/db_machdep.h> #ifdef DDB @@ -417,18 +411,6 @@ allocsys(v) #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index 3302475881a..41dc7fd648f 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.90 2002/11/27 21:47:14 mickey Exp $ */ +/* $OpenBSD: machdep.c,v 1.91 2002/12/17 23:11:32 millert Exp $ */ /* * Copyright (c) 1999-2002 Michael Shalayeff @@ -56,12 +56,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <sys/mount.h> #include <sys/syscallargs.h> @@ -545,18 +539,6 @@ hppa_init(start) valloc(buf, struct buf, nbuf); -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 33300474984..dc913b17665 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.216 2002/10/07 18:35:56 mickey Exp $ */ +/* $OpenBSD: machdep.c,v 1.217 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -104,12 +104,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #ifdef KGDB #include <sys/kgdb.h> @@ -466,18 +460,7 @@ allocsys(v) #define valloc(name, type, num) \ v = (caddr_t)(((name) = (type *)v) + (num)) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif + #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/mac68k/mac68k/machdep.c b/sys/arch/mac68k/mac68k/machdep.c index d3a78aab825..c670ae8731f 100644 --- a/sys/arch/mac68k/mac68k/machdep.c +++ b/sys/arch/mac68k/mac68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.100 2002/04/29 23:43:03 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.101 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: machdep.c,v 1.207 1998/07/08 04:39:34 thorpej Exp $ */ /* @@ -103,12 +103,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <machine/db_machdep.h> #include <ddb/db_sym.h> @@ -478,18 +472,6 @@ allocsys(v) #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c index ed69475ba2c..2705c576fac 100644 --- a/sys/arch/macppc/macppc/machdep.c +++ b/sys/arch/macppc/macppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.46 2002/10/18 03:39:35 drahn Exp $ */ +/* $OpenBSD: machdep.c,v 1.47 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -54,12 +54,6 @@ #include <uvm/uvm_extern.h> -#ifdef SYSVSHM -#include <sys/shm.h> -#endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif #ifdef SYSVMSG #include <sys/msg.h> #endif @@ -630,17 +624,6 @@ allocsys(v) #define valloc(name, type, num) \ v = (caddr_t)(((name) = (type *)v) + (num)) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c index bfc6a613518..8ca076e1926 100644 --- a/sys/arch/mvme68k/mvme68k/machdep.c +++ b/sys/arch/mvme68k/mvme68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.71 2002/04/28 14:47:53 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.72 2002/12/17 23:11:32 millert Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -99,12 +99,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <machine/autoconf.h> #include <machine/bugio.h> @@ -314,18 +308,6 @@ again: (name) = (type *)v; v = (caddr_t)((name)+(num)) #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c index bef12775503..ff06ac9b980 100644 --- a/sys/arch/mvme88k/mvme88k/machdep.c +++ b/sys/arch/mvme88k/mvme88k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.96 2002/10/12 02:03:45 krw Exp $ */ +/* $OpenBSD: machdep.c,v 1.97 2002/12/17 23:11:32 millert Exp $ */ /* * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -63,12 +63,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <sys/ioctl.h> #include <sys/exec.h> #include <sys/sysctl.h> @@ -704,18 +698,6 @@ allocsys(v) #define valloc(name, type, num) \ v = (caddr_t)(((name) = (type *)v) + (num)) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/mvmeppc/mvmeppc/machdep.c b/sys/arch/mvmeppc/mvmeppc/machdep.c index 588b8fc8620..566ae6e779e 100644 --- a/sys/arch/mvmeppc/mvmeppc/machdep.c +++ b/sys/arch/mvmeppc/mvmeppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.28 2002/10/13 18:26:12 krw Exp $ */ +/* $OpenBSD: machdep.c,v 1.29 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -54,12 +54,6 @@ #include <uvm/uvm_extern.h> -#ifdef SYSVSHM -#include <sys/shm.h> -#endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif #ifdef SYSVMSG #include <sys/msg.h> #endif @@ -620,17 +614,6 @@ allocsys(v) #define valloc(name, type, num) \ v = (caddr_t)(((name) = (type *)v) + (num)) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c index ae1d4243e55..b143af5f4af 100644 --- a/sys/arch/sparc/sparc/machdep.c +++ b/sys/arch/sparc/sparc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.89 2002/11/22 23:08:49 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.90 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: machdep.c,v 1.85 1997/09/12 08:55:02 pk Exp $ */ /* @@ -66,12 +66,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <sys/exec.h> #include <sys/sysctl.h> #include <sys/extent.h> @@ -311,18 +305,6 @@ allocsys(v) #define valloc(name, type, num) \ v = (caddr_t)(((name) = (type *)v) + (num)) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c index 8d027cf2321..bc85519af57 100644 --- a/sys/arch/sparc64/sparc64/machdep.c +++ b/sys/arch/sparc64/sparc64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.53 2002/11/03 01:59:28 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.54 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */ /*- @@ -113,12 +113,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #define _SPARC_BUS_DMA_PRIVATE #include <machine/autoconf.h> @@ -385,17 +379,6 @@ allocsys(caddr_t v) { #define valloc(name, type, num) \ v = (caddr_t)(((name) = (type *)v) + (num)) -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/sun3/sun3/machdep.c b/sys/arch/sun3/sun3/machdep.c index be8280512ff..6191c1162a7 100644 --- a/sys/arch/sun3/sun3/machdep.c +++ b/sys/arch/sun3/sun3/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.55 2002/03/23 13:28:34 espie Exp $ */ +/* $OpenBSD: machdep.c,v 1.56 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: machdep.c,v 1.77 1996/10/13 03:47:51 christos Exp $ */ /* @@ -71,12 +71,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <uvm/uvm_extern.h> @@ -183,18 +177,6 @@ allocsys(v) register caddr_t v; { -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - valloc(sema, struct semid_ds, seminfo.semmni); - valloc(sem, struct sem, seminfo.semmns); - /* This is pretty disgusting! */ - valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/arch/vax/vax/machdep.c b/sys/arch/vax/vax/machdep.c index 22cb80785a9..0d52dd531c3 100644 --- a/sys/arch/vax/vax/machdep.c +++ b/sys/arch/vax/vax/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.62 2002/11/08 01:33:28 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.63 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: machdep.c,v 1.108 2000/09/13 15:00:23 thorpej Exp $ */ /* @@ -81,12 +81,6 @@ #ifdef SYSVMSG #include <sys/msg.h> #endif -#ifdef SYSVSEM -#include <sys/sem.h> -#endif -#ifdef SYSVSHM -#include <sys/shm.h> -#endif #include <net/netisr.h> #include <net/if.h> @@ -798,19 +792,6 @@ allocsys(v) register caddr_t v; { -#ifdef SYSVSHM - shminfo.shmmax = shmmaxpgs; - shminfo.shmall = shmmaxpgs; - shminfo.shmseg = shmseg; - VALLOC(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif -#ifdef SYSVSEM - VALLOC(sema, struct semid_ds, seminfo.semmni); - VALLOC(sem, struct sem, seminfo.semmns); - - /* This is pretty disgusting! */ - VALLOC(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); -#endif #ifdef SYSVMSG VALLOC(msgpool, char, msginfo.msgmax); VALLOC(msgmaps, struct msgmap, msginfo.msgseg); diff --git a/sys/compat/common/kern_ipc_23.c b/sys/compat/common/kern_ipc_23.c index 3b004a817d6..9b092daff93 100644 --- a/sys/compat/common/kern_ipc_23.c +++ b/sys/compat/common/kern_ipc_23.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_ipc_23.c,v 1.2 2002/03/14 01:26:49 millert Exp $ */ +/* $OpenBSD: kern_ipc_23.c,v 1.3 2002/12/17 23:11:31 millert Exp $ */ /* * Implementation of SVID semaphores @@ -64,6 +64,7 @@ #include <sys/sem.h> #include <sys/shm.h> #include <sys/malloc.h> +#include <sys/pool.h> #include <sys/mount.h> #include <sys/syscallargs.h> @@ -87,7 +88,7 @@ compat_23_sys_msgctl(p, v, retval) int cmd = SCARG(uap, cmd); struct omsqid_ds *user_msqptr = SCARG(uap, buf); struct ucred *cred = p->p_ucred; - int rval, eval; + int rval, error; struct omsqid_ds omsqbuf; register struct msqid_ds *msqptr; @@ -120,16 +121,15 @@ compat_23_sys_msgctl(p, v, retval) return(EINVAL); } - eval = 0; - rval = 0; + error = rval = 0; switch (cmd) { case IPC_RMID: { struct msg *msghdr; - if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M)) != 0) - return(eval); + if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_M)) != 0) + return(error); /* Free the message headers */ msghdr = msqptr->msg_first; while (msghdr != NULL) { @@ -158,10 +158,10 @@ compat_23_sys_msgctl(p, v, retval) break; case IPC_SET: - if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M))) - return(eval); - if ((eval = copyin(user_msqptr, &omsqbuf, sizeof(omsqbuf))) != 0) - return(eval); + if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_M))) + return(error); + if ((error = copyin(user_msqptr, &omsqbuf, sizeof(omsqbuf))) != 0) + return(error); if (omsqbuf.msg_qbytes > msqptr->msg_qbytes && cred->cr_uid != 0) return(EPERM); if (omsqbuf.msg_qbytes > msginfo.msgmnb) { @@ -186,14 +186,14 @@ compat_23_sys_msgctl(p, v, retval) break; case IPC_STAT: - if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) { + if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_R))) { #ifdef MSG_DEBUG_OK printf("requester doesn't have read access\n"); #endif - return(eval); + return(error); } msqid_n2o(msqptr, &omsqbuf); - eval = copyout((caddr_t)&omsqbuf, user_msqptr, sizeof omsqbuf); + error = copyout((caddr_t)&omsqbuf, user_msqptr, sizeof omsqbuf); break; default: @@ -203,9 +203,9 @@ compat_23_sys_msgctl(p, v, retval) return(EINVAL); } - if (eval == 0) + if (error == 0) *retval = rval; - return(eval); + return(error); } #endif /* SYSVMSG */ @@ -281,6 +281,7 @@ compat_23_sys_shmctl(p, v, retval) #ifdef SYSVSEM +extern struct pool sema_pool; void semundo_clear(int, int); int @@ -301,7 +302,7 @@ compat_23_sys___semctl(p, v, retval) union semun *arg = SCARG(uap, arg); union semun real_arg; struct ucred *cred = p->p_ucred; - int i, rval, eval; + int i, rval, error; struct semid_ds *semaptr; struct osemid_ds osbuf; extern int semtot; @@ -314,41 +315,34 @@ compat_23_sys___semctl(p, v, retval) if (semid < 0 || semid >= seminfo.semmsl) return(EINVAL); - semaptr = &sema[semid]; - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || + if ((semaptr = sema[semid]) == NULL || semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid))) return(EINVAL); - eval = 0; - rval = 0; + error = rval = 0; switch (cmd) { case IPC_RMID: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0) + return(error); semaptr->sem_perm.cuid = cred->cr_uid; semaptr->sem_perm.uid = cred->cr_uid; semtot -= semaptr->sem_nsems; - for (i = semaptr->sem_base - sem; i < semtot; i++) - sem[i] = sem[i + semaptr->sem_nsems]; - for (i = 0; i < seminfo.semmni; i++) { - if ((sema[i].sem_perm.mode & SEM_ALLOC) && - sema[i].sem_base > semaptr->sem_base) - sema[i].sem_base -= semaptr->sem_nsems; - } - semaptr->sem_perm.mode = 0; + free(semaptr->sem_base, M_SHM); + pool_put(&sema_pool, semaptr); + sema[semid] = NULL; semundo_clear(semid, -1); - wakeup((caddr_t)semaptr); + wakeup((caddr_t)&sema[semid]); break; case IPC_SET: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M))) - return(eval); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); - if ((eval = copyin(real_arg.buf, (caddr_t)&osbuf, + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M))) + return(error); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(error); + if ((error = copyin(real_arg.buf, (caddr_t)&osbuf, sizeof(osbuf))) != 0) - return(eval); + return(error); semaptr->sem_perm.uid = osbuf.sem_perm.uid; semaptr->sem_perm.gid = osbuf.sem_perm.gid; semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) | @@ -357,93 +351,93 @@ compat_23_sys___semctl(p, v, retval) break; case IPC_STAT: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(error); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(error); semid_n2o(semaptr, &osbuf); - eval = copyout((caddr_t)&osbuf, real_arg.buf, sizeof osbuf); + error = copyout((caddr_t)&osbuf, real_arg.buf, sizeof(osbuf)); break; case GETNCNT: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(error); if (semnum < 0 || semnum >= semaptr->sem_nsems) return(EINVAL); rval = semaptr->sem_base[semnum].semncnt; break; case GETPID: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(error); if (semnum < 0 || semnum >= semaptr->sem_nsems) return(EINVAL); rval = semaptr->sem_base[semnum].sempid; break; case GETVAL: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(error); if (semnum < 0 || semnum >= semaptr->sem_nsems) return(EINVAL); rval = semaptr->sem_base[semnum].semval; break; case GETALL: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(error); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(error); for (i = 0; i < semaptr->sem_nsems; i++) { - eval = copyout((caddr_t)&semaptr->sem_base[i].semval, + error = copyout((caddr_t)&semaptr->sem_base[i].semval, &real_arg.array[i], sizeof(real_arg.array[0])); - if (eval != 0) + if (error != 0) break; } break; case GETZCNT: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(error); if (semnum < 0 || semnum >= semaptr->sem_nsems) return(EINVAL); rval = semaptr->sem_base[semnum].semzcnt; break; case SETVAL: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W))) + return(error); if (semnum < 0 || semnum >= semaptr->sem_nsems) return(EINVAL); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(error); semaptr->sem_base[semnum].semval = real_arg.val; semundo_clear(semid, semnum); - wakeup((caddr_t)semaptr); + wakeup((caddr_t)&sema[semid]); break; case SETALL: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) - return(eval); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W))) + return(error); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(error); for (i = 0; i < semaptr->sem_nsems; i++) { - eval = copyin(&real_arg.array[i], + error = copyin(&real_arg.array[i], (caddr_t)&semaptr->sem_base[i].semval, sizeof(real_arg.array[0])); - if (eval != 0) + if (error != 0) break; } semundo_clear(semid, -1); - wakeup((caddr_t)semaptr); + wakeup((caddr_t)&sema[semid]); break; default: return(EINVAL); } - if (eval == 0) + if (error == 0) *retval = rval; - return(eval); + return(error); } #endif /* SYSVSEM */ diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 7cfc0910383..cd07eeb4ae7 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.75 2002/09/01 11:35:52 art Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.76 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -256,11 +256,22 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) #endif /* all sysctl names at this level are terminal except a ton of them */ - if (namelen != 1 && !(name[0] == KERN_PROC || name[0] == KERN_PROF || - name[0] == KERN_MALLOCSTATS || name[0] == KERN_TTY || - name[0] == KERN_POOL || name[0] == KERN_SYSVIPC_INFO || - name[0] == KERN_PROC_ARGS)) - return (ENOTDIR); /* overloaded */ + if (namelen != 1) { + switch (name[0]) { + case KERN_PROC: + case KERN_PROF: + case KERN_MALLOCSTATS: + case KERN_TTY: + case KERN_POOL: + case KERN_PROC_ARGS: + case KERN_SYSVIPC_INFO: + case KERN_SEMINFO: + case KERN_SHMINFO: + break; + default: + return (ENOTDIR); /* overloaded */ + } + } switch (name[0]) { case KERN_OSTYPE: @@ -455,6 +466,16 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) case KERN_SPLASSERT: return (sysctl_int(oldp, oldlenp, newp, newlen, &splassert_ctl)); +#ifdef SYSVSEM + case KERN_SEMINFO: + return (sysctl_sysvsem(name + 1, namelen - 1, oldp, oldlenp, + newp, newlen)); +#endif +#ifdef SYSVSHM + case KERN_SHMINFO: + return (sysctl_sysvshm(name + 1, namelen - 1, oldp, oldlenp, + newp, newlen)); +#endif default: return (EOPNOTSUPP); } @@ -1395,12 +1416,20 @@ sysctl_sysvipc(name, namelen, where, sizep) #endif #ifdef SYSVSEM case KERN_SYSVIPC_SEM_INFO: - bcopy(&sema[i], &semsi->semids[i], dssize); + if (sema[i] != NULL) + bcopy(sema[i], &semsi->semids[i], + dssize); + else + bzero(&semsi->semids[i], dssize); break; #endif #ifdef SYSVSHM case KERN_SYSVIPC_SHM_INFO: - bcopy(&shmsegs[i], &shmsi->shmids[i], dssize); + if (shmsegs[i] != NULL) + bcopy(shmsegs[i], &shmsi->shmids[i], + dssize); + else + bzero(&shmsi->shmids[i], dssize); break; #endif } diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index 60290511b3b..e84b43a36cb 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sysv_sem.c,v 1.9 2002/03/14 01:27:05 millert Exp $ */ +/* $OpenBSD: sysv_sem.c,v 1.10 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: sysv_sem.c,v 1.26 1996/02/09 19:00:25 christos Exp $ */ /* @@ -14,39 +14,44 @@ #include <sys/kernel.h> #include <sys/proc.h> #include <sys/sem.h> +#include <sys/sysctl.h> #include <sys/malloc.h> +#include <sys/pool.h> #include <sys/mount.h> #include <sys/syscallargs.h> +/* SVID defines EIDRM but BSD does not */ +#ifndef EIDRM +#define EIDRM EINVAL +#endif + int semtot = 0; -struct semid_ds *sema; /* semaphore id pool */ -struct sem *sem; /* semaphore pool */ -struct sem_undo *semu_list; /* list of active undo structures */ -int *semu; /* undo structure pool */ +int semutot = 0; +struct semid_ds **sema; /* semaphore id list */ +struct sem_undo *semu_list; /* list of undo structures */ +struct pool sema_pool; /* pool for struct semid_ds */ +struct pool semu_pool; /* pool for struct sem_undo (SEMUSZ) */ +unsigned short *semseqs; /* array of sem sequence numbers */ struct sem_undo *semu_alloc(struct proc *); int semundo_adjust(struct proc *, struct sem_undo **, int, int, int); void semundo_clear(int, int); void -seminit() +seminit(void) { - register int i; - if (sema == NULL) - panic("sema is NULL"); - if (semu == NULL) - panic("semu is NULL"); - - for (i = 0; i < seminfo.semmni; i++) { - sema[i].sem_base = 0; - sema[i].sem_perm.mode = 0; - } - for (i = 0; i < seminfo.semmnu; i++) { - register struct sem_undo *suptr = SEMU(i); - suptr->un_proc = NULL; - } + pool_init(&sema_pool, sizeof(struct semid_ds), 0, 0, 0, "semapl", + &pool_allocator_nointr); + pool_init(&semu_pool, SEMUSZ, 0, 0, 0, "semupl", + &pool_allocator_nointr); + sema = malloc(seminfo.semmni * sizeof(struct semid_ds *), + M_SEM, M_WAITOK); + bzero(sema, seminfo.semmni * sizeof(struct semid_ds *)); + semseqs = malloc(seminfo.semmni * sizeof(unsigned short), + M_SEM, M_WAITOK); + bzero(semseqs, seminfo.semmni * sizeof(unsigned short)); semu_list = NULL; } @@ -55,88 +60,36 @@ seminit() * (returns ptr to structure or NULL if no more room) */ struct sem_undo * -semu_alloc(p) - struct proc *p; +semu_alloc(struct proc *p) { - register int i; - register struct sem_undo *suptr; - register struct sem_undo **supptr; - int attempt; - - /* - * Try twice to allocate something. - * (we'll purge any empty structures after the first pass so - * two passes are always enough) - */ - - for (attempt = 0; attempt < 2; attempt++) { - /* - * Look for a free structure. - * Fill it in and return it if we find one. - */ - - for (i = 0; i < seminfo.semmnu; i++) { - suptr = SEMU(i); - if (suptr->un_proc == NULL) { - suptr->un_next = semu_list; - semu_list = suptr; - suptr->un_cnt = 0; - suptr->un_proc = p; - return(suptr); - } - } - - /* - * We didn't find a free one, if this is the first attempt - * then try to free some structures. - */ - - if (attempt == 0) { - /* All the structures are in use - try to free some */ - int did_something = 0; - - supptr = &semu_list; - while ((suptr = *supptr) != NULL) { - if (suptr->un_cnt == 0) { - suptr->un_proc = NULL; - *supptr = suptr->un_next; - did_something = 1; - } else - supptr = &(suptr->un_next); - } - - /* If we didn't free anything then just give-up */ - if (!did_something) - return(NULL); - } else { - /* - * The second pass failed even though we freed - * something after the first pass! - * This is IMPOSSIBLE! - */ - panic("semu_alloc - second attempt failed"); - } - } - return NULL; + struct sem_undo *suptr; + + if (semutot == seminfo.semmnu || + (suptr = pool_get(&semu_pool, 0)) == NULL) + return (NULL); /* no space */ + + semutot++; + suptr->un_cnt = 0; + suptr->un_proc = p; + suptr->un_next = semu_list; + semu_list = suptr; + return (suptr); } /* * Adjust a particular entry for a particular proc */ int -semundo_adjust(p, supptr, semid, semnum, adjval) - register struct proc *p; - struct sem_undo **supptr; - int semid, semnum; - int adjval; +semundo_adjust(struct proc *p, struct sem_undo **supptr, int semid, int semnum, + int adjval) { - register struct sem_undo *suptr; - register struct undo *sunptr; + struct sem_undo *suptr; + struct undo *sunptr; int i; - /* Look for and remember the sem_undo if the caller doesn't provide - it */ - + /* + * Look for and remember the sem_undo if the caller doesn't provide it. + */ suptr = *supptr; if (suptr == NULL) { for (suptr = semu_list; suptr != NULL; suptr = suptr->un_next) { @@ -147,10 +100,10 @@ semundo_adjust(p, supptr, semid, semnum, adjval) } if (suptr == NULL) { if (adjval == 0) - return(0); + return (0); suptr = semu_alloc(p); if (suptr == NULL) - return(ENOSPC); + return (ENOSPC); *supptr = suptr; } } @@ -167,39 +120,56 @@ semundo_adjust(p, supptr, semid, semnum, adjval) sunptr->un_adjval = 0; else sunptr->un_adjval += adjval; - if (sunptr->un_adjval == 0) { - suptr->un_cnt--; - if (i < suptr->un_cnt) - suptr->un_ent[i] = - suptr->un_ent[suptr->un_cnt]; - } - return(0); + if (sunptr->un_adjval != 0) + return (0); + + if (--suptr->un_cnt == 0) { + struct sem_undo *suprev; + + if (semu_list == suptr) + semu_list = suptr->un_next; + else { + /* this code path should be rare */ + for (suprev = semu_list; suprev != NULL && + suprev->un_next != suptr; + suprev = suprev->un_next) + /* NOTHING */; +#ifdef DIAGNOSTIC + if (suprev == NULL) + panic("semundo_adjust: " + "suptr not in semu_list"); +#endif + suprev->un_next = suptr->un_next; + } + pool_put(&semu_pool, suptr); + } else if (i < suptr->un_cnt) + suptr->un_ent[i] = + suptr->un_ent[suptr->un_cnt]; + return (0); } /* Didn't find the right entry - create it */ if (adjval == 0) - return(0); + return (0); if (suptr->un_cnt == SEMUME) - return(EINVAL); + return (EINVAL); sunptr = &suptr->un_ent[suptr->un_cnt]; suptr->un_cnt++; sunptr->un_adjval = adjval; sunptr->un_id = semid; sunptr->un_num = semnum; - return(0); + return (0); } void -semundo_clear(semid, semnum) - int semid, semnum; +semundo_clear(int semid, int semnum) { - register struct sem_undo *suptr; - - for (suptr = semu_list; suptr != NULL; suptr = suptr->un_next) { - register struct undo *sunptr; - register int i; + struct sem_undo *suptr, *suprev, *tmp; + struct undo *sunptr; + int i; + for (suptr = semu_list; suptr != NULL; ) { sunptr = &suptr->un_ent[0]; for (i = 0; i < suptr->un_cnt; i++, sunptr++) { if (sunptr->un_id == semid) { @@ -215,13 +185,22 @@ semundo_clear(semid, semnum) break; } } + if (suptr->un_cnt == 0) { + tmp = suptr; + if (suptr == semu_list) + suptr = semu_list = suptr->un_next; + else + suptr = suprev->un_next = suptr->un_next; + pool_put(&semu_pool, tmp); + } else { + suprev = suptr; + suptr = suptr->un_next; + } } } void -semid_n2o(n, o) - struct semid_ds *n; - struct osemid_ds *o; +semid_n2o(struct semid_ds *n, struct osemid_ds *o) { o->sem_base = n->sem_base; o->sem_nsems = n->sem_nsems; @@ -234,12 +213,9 @@ semid_n2o(n, o) } int -sys___semctl(p, v, retval) - struct proc *p; - register void *v; - register_t *retval; +sys___semctl(struct proc *p, void *v, register_t *retval) { - register struct sys___semctl_args /* { + struct sys___semctl_args /* { syscallarg(int) semid; syscallarg(int) semnum; syscallarg(int) cmd; @@ -251,9 +227,9 @@ sys___semctl(p, v, retval) union semun *arg = SCARG(uap, arg); union semun real_arg; struct ucred *cred = p->p_ucred; - int i, rval, eval; + int i, rval, error; struct semid_ds sbuf; - register struct semid_ds *semaptr; + struct semid_ds *semaptr; #ifdef SEM_DEBUG printf("call to semctl(%d, %d, %d, %p)\n", semid, semnum, cmd, arg); @@ -261,43 +237,36 @@ sys___semctl(p, v, retval) semid = IPCID_TO_IX(semid); if (semid < 0 || semid >= seminfo.semmsl) - return(EINVAL); + return (EINVAL); - semaptr = &sema[semid]; - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || + if ((semaptr = sema[semid]) == NULL || semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid))) - return(EINVAL); + return (EINVAL); - eval = 0; - rval = 0; + error = rval = 0; switch (cmd) { case IPC_RMID: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0) + return (error); semaptr->sem_perm.cuid = cred->cr_uid; semaptr->sem_perm.uid = cred->cr_uid; semtot -= semaptr->sem_nsems; - for (i = semaptr->sem_base - sem; i < semtot; i++) - sem[i] = sem[i + semaptr->sem_nsems]; - for (i = 0; i < seminfo.semmni; i++) { - if ((sema[i].sem_perm.mode & SEM_ALLOC) && - sema[i].sem_base > semaptr->sem_base) - sema[i].sem_base -= semaptr->sem_nsems; - } - semaptr->sem_perm.mode = 0; + free(semaptr->sem_base, M_SEM); + pool_put(&sema_pool, semaptr); + sema[semid] = NULL; semundo_clear(semid, -1); - wakeup((caddr_t)semaptr); + wakeup((caddr_t)&sema[semid]); break; case IPC_SET: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M))) - return(eval); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); - if ((eval = copyin(real_arg.buf, (caddr_t)&sbuf, + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M))) + return (error); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return (error); + if ((error = copyin(real_arg.buf, (caddr_t)&sbuf, sizeof(sbuf))) != 0) - return(eval); + return (error); semaptr->sem_perm.uid = sbuf.sem_perm.uid; semaptr->sem_perm.gid = sbuf.sem_perm.gid; semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) | @@ -306,141 +275,153 @@ sys___semctl(p, v, retval) break; case IPC_STAT: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); - eval = copyout((caddr_t)semaptr, real_arg.buf, + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return (error); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return (error); + error = copyout((caddr_t)semaptr, real_arg.buf, sizeof(struct semid_ds)); break; case GETNCNT: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return (error); if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + return (EINVAL); rval = semaptr->sem_base[semnum].semncnt; break; case GETPID: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return (error); if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + return (EINVAL); rval = semaptr->sem_base[semnum].sempid; break; case GETVAL: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return (error); if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + return (EINVAL); rval = semaptr->sem_base[semnum].semval; break; case GETALL: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return (error); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return (error); for (i = 0; i < semaptr->sem_nsems; i++) { - eval = copyout((caddr_t)&semaptr->sem_base[i].semval, + error = copyout((caddr_t)&semaptr->sem_base[i].semval, &real_arg.array[i], sizeof(real_arg.array[0])); - if (eval != 0) + if (error != 0) break; } break; case GETZCNT: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return (error); if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); + return (EINVAL); rval = semaptr->sem_base[semnum].semzcnt; break; case SETVAL: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W))) + return (error); if (semnum < 0 || semnum >= semaptr->sem_nsems) - return(EINVAL); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + return (EINVAL); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return (error); semaptr->sem_base[semnum].semval = real_arg.val; semundo_clear(semid, semnum); - wakeup((caddr_t)semaptr); + wakeup((caddr_t)&sema[semid]); break; case SETALL: - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) - return(eval); - if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return(eval); + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W))) + return (error); + if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return (error); for (i = 0; i < semaptr->sem_nsems; i++) { - eval = copyin(&real_arg.array[i], + error = copyin(&real_arg.array[i], (caddr_t)&semaptr->sem_base[i].semval, sizeof(real_arg.array[0])); - if (eval != 0) + if (error != 0) break; } semundo_clear(semid, -1); - wakeup((caddr_t)semaptr); + wakeup((caddr_t)&sema[semid]); break; default: - return(EINVAL); + return (EINVAL); } - if (eval == 0) + if (error == 0) *retval = rval; - return(eval); + return (error); } int -sys_semget(p, v, retval) - struct proc *p; - void *v; - register_t *retval; +sys_semget(struct proc *p, void *v, register_t *retval) { - register struct sys_semget_args /* { + struct sys_semget_args /* { syscallarg(key_t) key; syscallarg(int) nsems; syscallarg(int) semflg; } */ *uap = v; - int semid, eval; + int semid, error; int key = SCARG(uap, key); int nsems = SCARG(uap, nsems); int semflg = SCARG(uap, semflg); + struct semid_ds *semaptr, *semaptr_new = NULL; struct ucred *cred = p->p_ucred; #ifdef SEM_DEBUG printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg); #endif + /* + * Preallocate space for the new semaphore. If we are going + * to sleep, we want to sleep now to elliminate any race + * condition in allocating a semaphore with a specific key. + */ + if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) { + semaptr_new = pool_get(&sema_pool, PR_WAITOK); + semaptr_new->sem_base = malloc(nsems * sizeof(struct sem), + M_SEM, M_WAITOK); + bzero(semaptr_new->sem_base, nsems * sizeof(struct sem)); + } + if (key != IPC_PRIVATE) { - for (semid = 0; semid < seminfo.semmni; semid++) { - if ((sema[semid].sem_perm.mode & SEM_ALLOC) && - sema[semid].sem_perm.key == key) + for (semid = 0, semaptr = NULL; semid < seminfo.semmni; semid++) { + if ((semaptr = sema[semid]) != NULL && + semaptr->sem_perm.key == key) break; } - if (semid < seminfo.semmni) { + if (semaptr != NULL) { #ifdef SEM_DEBUG printf("found public key\n"); #endif - if ((eval = ipcperm(cred, &sema[semid].sem_perm, + if ((error = ipcperm(cred, &semaptr->sem_perm, semflg & 0700))) - return(eval); - if (nsems > 0 && sema[semid].sem_nsems < nsems) { + goto error; + if (nsems > 0 && semaptr->sem_nsems < nsems) { #ifdef SEM_DEBUG printf("too small\n"); #endif - return(EINVAL); + error = EINVAL; + goto error; } if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) { #ifdef SEM_DEBUG printf("not exclusive\n"); #endif - return(EEXIST); + error = EEXIST; + goto error; } goto found; } @@ -455,79 +436,78 @@ sys_semget(p, v, retval) printf("nsems out of range (0<%d<=%d)\n", nsems, seminfo.semmsl); #endif - return(EINVAL); + error = EINVAL; + goto error; } if (nsems > seminfo.semmns - semtot) { #ifdef SEM_DEBUG printf("not enough semaphores left (need %d, got %d)\n", nsems, seminfo.semmns - semtot); #endif - return(ENOSPC); + error = ENOSPC; + goto error; } for (semid = 0; semid < seminfo.semmni; semid++) { - if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0) + if ((semaptr = sema[semid]) == NULL) break; } if (semid == seminfo.semmni) { #ifdef SEM_DEBUG printf("no more semid_ds's available\n"); #endif - return(ENOSPC); + error = ENOSPC; + goto error; } #ifdef SEM_DEBUG printf("semid %d is available\n", semid); #endif - sema[semid].sem_perm.key = key; - sema[semid].sem_perm.cuid = cred->cr_uid; - sema[semid].sem_perm.uid = cred->cr_uid; - sema[semid].sem_perm.cgid = cred->cr_gid; - sema[semid].sem_perm.gid = cred->cr_gid; - sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC; - sema[semid].sem_perm.seq = - (sema[semid].sem_perm.seq + 1) & 0x7fff; - sema[semid].sem_nsems = nsems; - sema[semid].sem_otime = 0; - sema[semid].sem_ctime = time.tv_sec; - sema[semid].sem_base = &sem[semtot]; - semtot += nsems; - bzero(sema[semid].sem_base, - sizeof(sema[semid].sem_base[0])*nsems); -#ifdef SEM_DEBUG - printf("sembase = %p, next = %p\n", sema[semid].sem_base, - &sem[semtot]); -#endif + semaptr_new->sem_perm.key = key; + semaptr_new->sem_perm.cuid = cred->cr_uid; + semaptr_new->sem_perm.uid = cred->cr_uid; + semaptr_new->sem_perm.cgid = cred->cr_gid; + semaptr_new->sem_perm.gid = cred->cr_gid; + semaptr_new->sem_perm.mode = (semflg & 0777); + semaptr_new->sem_perm.seq = semseqs[semid] = + (semseqs[semid] + 1) & 0x7fff; + semaptr_new->sem_nsems = nsems; + semaptr_new->sem_otime = 0; + semaptr_new->sem_ctime = time.tv_sec; + sema[semid] = semaptr_new; } else { #ifdef SEM_DEBUG printf("didn't find it and wasn't asked to create it\n"); #endif - return(ENOENT); + return (ENOENT); } found: - *retval = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm); - return(0); + *retval = IXSEQ_TO_IPCID(semid, sema[semid]->sem_perm); + return (0); +error: + if (semaptr_new != NULL) { + free(semaptr_new->sem_base, M_SEM); + pool_put(&sema_pool, semaptr_new); + } + return (error); } int -sys_semop(p, v, retval) - struct proc *p; - void *v; - register_t *retval; +sys_semop(struct proc *p, void *v, register_t *retval) { - register struct sys_semop_args /* { + struct sys_semop_args /* { syscallarg(int) semid; syscallarg(struct sembuf *) sops; syscallarg(u_int) nsops; } */ *uap = v; int semid = SCARG(uap, semid); u_int nsops = SCARG(uap, nsops); - struct sembuf sops[MAX_SOPS]; - register struct semid_ds *semaptr; - register struct sembuf *sopptr = NULL; - register struct sem *semptr = NULL; + struct sembuf *sops; + struct semid_ds *semaptr; + struct sembuf *sopptr = NULL; + struct sem *semptr = NULL; struct sem_undo *suptr = NULL; struct ucred *cred = p->p_ucred; - int i, j, eval; + int i, j, error; int do_wakeup, do_undos; #ifdef SEM_DEBUG @@ -537,34 +517,35 @@ sys_semop(p, v, retval) semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ if (semid < 0 || semid >= seminfo.semmsl) - return(EINVAL); + return (EINVAL); - semaptr = &sema[semid]; - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || + if ((semaptr = sema[semid]) == NULL || semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid))) - return(EINVAL); + return (EINVAL); - if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) { + if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W))) { #ifdef SEM_DEBUG - printf("eval = %d from ipaccess\n", eval); + printf("error = %d from ipaccess\n", error); #endif - return(eval); + return (error); } - if (nsops > MAX_SOPS) { + if (nsops > seminfo.semopm) { #ifdef SEM_DEBUG - printf("too many sops (max=%d, nsops=%d)\n", MAX_SOPS, nsops); + printf("too many sops (max=%d, nsops=%d)\n", seminfo.semopm, nsops); #endif - return(E2BIG); + return (E2BIG); } - if ((eval = copyin(SCARG(uap, sops), sops, nsops * sizeof(sops[0]))) - != 0) { + sops = malloc(nsops * sizeof(struct sembuf), M_SEM, M_WAITOK); + error = copyin(SCARG(uap, sops), sops, nsops * sizeof(struct sembuf)); + if (error != 0) { #ifdef SEM_DEBUG - printf("eval = %d from copyin(%p, %p, %d)\n", eval, - SCARG(uap, sops), &sops, nsops * sizeof(sops[0])); + printf("error = %d from copyin(%p, %p, %d)\n", error, + SCARG(uap, sops), &sops, nsops * sizeof(struct sembuf)); #endif - return(eval); + free(sops, M_SEM); + return (error); } /* @@ -584,8 +565,10 @@ sys_semop(p, v, retval) for (i = 0; i < nsops; i++) { sopptr = &sops[i]; - if (sopptr->sem_num >= semaptr->sem_nsems) - return(EFBIG); + if (sopptr->sem_num >= semaptr->sem_nsems) { + free(sops, M_SEM); + return (EFBIG); + } semptr = &semaptr->sem_base[sopptr->sem_num]; @@ -647,8 +630,10 @@ sys_semop(p, v, retval) * If the request that we couldn't satisfy has the * NOWAIT flag set then return with EAGAIN. */ - if (sopptr->sem_flg & IPC_NOWAIT) - return(EAGAIN); + if (sopptr->sem_flg & IPC_NOWAIT) { + free(sops, M_SEM); + return (EAGAIN); + } if (sopptr->sem_op == 0) semptr->semzcnt++; @@ -658,16 +643,18 @@ sys_semop(p, v, retval) #ifdef SEM_DEBUG printf("semop: good night!\n"); #endif - eval = tsleep((caddr_t)semaptr, (PZERO - 4) | PCATCH, + error = tsleep((caddr_t)&sema[semid], (PZERO - 4) | PCATCH, "semwait", 0); #ifdef SEM_DEBUG - printf("semop: good morning (eval=%d)!\n", eval); + printf("semop: good morning (error=%d)!\n", error); #endif suptr = NULL; /* sem_undo may have been reallocated */ - if (eval != 0) - return(EINTR); + if (error != 0) { + free(sops, M_SEM); + return (EINTR); + } #ifdef SEM_DEBUG printf("semop: good morning!\n"); #endif @@ -675,15 +662,10 @@ sys_semop(p, v, retval) /* * Make sure that the semaphore still exists */ - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || + if (sema[semid] == NULL || semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid))) { - /* The man page says to return EIDRM. */ - /* Unfortunately, BSD doesn't define that code! */ -#ifdef EIDRM - return(EIDRM); -#else - return(EINVAL); -#endif + free(sops, M_SEM); + return (EIDRM); } /* @@ -713,13 +695,13 @@ done: adjval = sops[i].sem_op; if (adjval == 0) continue; - eval = semundo_adjust(p, &suptr, semid, + error = semundo_adjust(p, &suptr, semid, sops[i].sem_num, -adjval); - if (eval == 0) + if (error == 0) continue; /* - * Oh-Oh! We ran out of either sem_undo's or undo's. + * Uh-Oh! We ran out of either sem_undo's or undo's. * Rollback the adjustments to this point and then * rollback the semaphore ups and down so we can return * with an error with all structures restored. We @@ -743,9 +725,10 @@ done: sops[j].sem_op; #ifdef SEM_DEBUG - printf("eval = %d from semundo_adjust\n", eval); + printf("error = %d from semundo_adjust\n", error); #endif - return(eval); + free(sops, M_SEM); + return (error); } /* loop through the sops */ } /* if (do_undos) */ @@ -755,26 +738,23 @@ done: semptr = &semaptr->sem_base[sopptr->sem_num]; semptr->sempid = p->p_pid; } + free(sops, M_SEM); /* Do a wakeup if any semaphore was up'd. */ if (do_wakeup) { #ifdef SEM_DEBUG printf("semop: doing wakeup\n"); -#ifdef SEM_WAKEUP - sem_wakeup((caddr_t)semaptr); -#else - wakeup((caddr_t)semaptr); #endif + wakeup((caddr_t)&sema[semid]); +#ifdef SEM_DEBUG printf("semop: back from wakeup\n"); -#else - wakeup((caddr_t)semaptr); #endif } #ifdef SEM_DEBUG printf("semop: done\n"); #endif *retval = 0; - return(0); + return (0); } /* @@ -782,17 +762,15 @@ done: * semaphores. */ void -semexit(p) - struct proc *p; +semexit(struct proc *p) { - register struct sem_undo *suptr; - register struct sem_undo **supptr; + struct sem_undo *suptr; + struct sem_undo **supptr; /* * Go through the chain of undo vectors looking for one associated with * this process. */ - for (supptr = &semu_list; (suptr = *supptr) != NULL; supptr = &suptr->un_next) { if (suptr->un_proc == p) @@ -812,7 +790,6 @@ semexit(p) * We are now in case 1 or 2, and we have an undo vector for this * process. */ - #ifdef SEM_DEBUG printf("proc @%p has undo structure with %d entries\n", p, suptr->un_cnt); @@ -830,8 +807,7 @@ semexit(p) int adjval = suptr->un_ent[ix].un_adjval; struct semid_ds *semaptr; - semaptr = &sema[semid]; - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) + if ((semaptr = sema[semid]) == NULL) panic("semexit - semid not allocated"); if (semnum >= semaptr->sem_nsems) panic("semexit - semnum out of range"); @@ -850,11 +826,7 @@ semexit(p) else semaptr->sem_base[semnum].semval += adjval; -#ifdef SEM_WAKEUP - sem_wakeup((caddr_t)semaptr); -#else - wakeup((caddr_t)semaptr); -#endif + wakeup((caddr_t)&sema[semid]); #ifdef SEM_DEBUG printf("semexit: back from wakeup\n"); #endif @@ -867,6 +839,112 @@ semexit(p) #ifdef SEM_DEBUG printf("removing vector\n"); #endif - suptr->un_proc = NULL; *supptr = suptr->un_next; + pool_put(&semu_pool, suptr); +} + +/* + * Userland access to struct seminfo. + */ +int +sysctl_sysvsem(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int error, val; + struct semid_ds **sema_new; + unsigned short *newseqs; + + if (namelen != 2) { + switch (name[0]) { + case KERN_SEMINFO_SEMMNI: + case KERN_SEMINFO_SEMMNS: + case KERN_SEMINFO_SEMMNU: + case KERN_SEMINFO_SEMMSL: + case KERN_SEMINFO_SEMOPM: + case KERN_SEMINFO_SEMUME: + case KERN_SEMINFO_SEMUSZ: + case KERN_SEMINFO_SEMVMX: + case KERN_SEMINFO_SEMAEM: + break; + default: + return (ENOTDIR); /* overloaded */ + } + } + + switch (name[0]) { + case KERN_SEMINFO_SEMMNI: + val = seminfo.semmni; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == seminfo.semmni) + return (error); + + if (val < seminfo.semmni) + return (EINVAL); /* can't decrease semmni */ + + /* Expand semsegs and semseqs arrays */ + sema_new = malloc(val * sizeof(struct semid_ds *), + M_SEM, M_WAITOK); + bcopy(sema, sema_new, + seminfo.semmni * sizeof(struct semid_ds *)); + bzero(sema_new + seminfo.semmni, + (val - seminfo.semmni) * sizeof(struct semid_ds *)); + newseqs = malloc(val * sizeof(unsigned short), M_SEM, M_WAITOK); + bcopy(semseqs, newseqs, + seminfo.semmni * sizeof(unsigned short)); + bzero(newseqs + seminfo.semmni, + (val - seminfo.semmni) * sizeof(unsigned short)); + free(sema, M_SEM); + free(semseqs, M_SEM); + sema = sema_new; + semseqs = newseqs; + seminfo.semmni = val; + return (0); + case KERN_SEMINFO_SEMMNS: + val = seminfo.semmns; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == seminfo.semmns) + return (error); + if (val < seminfo.semmns) + return (EINVAL); /* can't decrease semmns */ + seminfo.semmns = val; + return (0); + case KERN_SEMINFO_SEMMNU: + val = seminfo.semmnu; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == seminfo.semmnu) + return (error); + if (val < seminfo.semmnu) + return (EINVAL); /* can't decrease semmnu */ + seminfo.semmnu = val; + return (0); + case KERN_SEMINFO_SEMMSL: + val = seminfo.semmsl; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == seminfo.semmsl) + return (error); + if (val < seminfo.semmsl) + return (EINVAL); /* can't decrease semmsl */ + seminfo.semmsl = val; + return (0); + case KERN_SEMINFO_SEMOPM: + val = seminfo.semopm; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == seminfo.semopm) + return (error); + if (val <= 0) + return (EINVAL); /* semopm must be >= 1 */ + seminfo.semopm = val; + return (0); + case KERN_SEMINFO_SEMUME: + return (sysctl_rdint(oldp, oldlenp, newp, seminfo.semume)); + case KERN_SEMINFO_SEMUSZ: + return (sysctl_rdint(oldp, oldlenp, newp, seminfo.semusz)); + case KERN_SEMINFO_SEMVMX: + return (sysctl_rdint(oldp, oldlenp, newp, seminfo.semvmx)); + case KERN_SEMINFO_SEMAEM: + return (sysctl_rdint(oldp, oldlenp, newp, seminfo.semaem)); + default: + return (EOPNOTSUPP); + } + /* NOTREACHED */ } diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 4dce0048b20..e016dc33df7 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sysv_shm.c,v 1.29 2002/11/06 00:17:28 art Exp $ */ +/* $OpenBSD: sysv_shm.c,v 1.30 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: sysv_shm.c,v 1.50 1998/10/21 22:24:29 tron Exp $ */ /* @@ -40,7 +40,9 @@ #include <sys/time.h> #include <sys/malloc.h> #include <sys/mman.h> +#include <sys/pool.h> #include <sys/systm.h> +#include <sys/sysctl.h> #include <sys/stat.h> #include <sys/mount.h> @@ -49,7 +51,9 @@ #include <uvm/uvm_extern.h> struct shminfo shminfo; -struct shmid_ds *shmsegs; +struct shmid_ds **shmsegs; /* linear mapping of shmid -> shmseg */ +struct pool shm_pool; +unsigned short *shmseqs; /* array of shm sequence numbers */ struct shmid_ds *shm_find_segment_by_shmid(int); @@ -62,14 +66,11 @@ struct shmid_ds *shm_find_segment_by_shmid(int); * shmsys(arg1, arg2, arg3, arg4); shm{at,ctl,dt,get}(arg2, arg3, arg4) * * Structures: - * shmsegs (an array of 'struct shmid_ds') - * per proc array of 'struct shmmap_state' + * shmsegs (an array of 'struct shmid_ds *') + * per proc 'struct shmmap_head' with an array of 'struct shmmap_state' */ -#define SHMSEG_FREE 0x0200 -#define SHMSEG_REMOVED 0x0400 -#define SHMSEG_ALLOCATED 0x0800 -#define SHMSEG_WANTED 0x1000 +#define SHMSEG_REMOVED 0x0200 /* can't overlap ACCESSPERMS */ int shm_last_free, shm_nused, shm_committed; @@ -82,6 +83,11 @@ struct shmmap_state { int shmid; }; +struct shmmap_head { + int shmseg; + struct shmmap_state state[1]; +}; + int shm_find_segment_by_key(key_t); void shm_deallocate_segment(struct shmid_ds *); int shm_delete_mapping(struct vmspace *, struct shmmap_state *); @@ -91,39 +97,37 @@ int shmget_allocate_segment(struct proc *, struct sys_shmget_args *, int, register_t *); int -shm_find_segment_by_key(key) - key_t key; +shm_find_segment_by_key(key_t key) { + struct shmid_ds *shmseg; int i; - for (i = 0; i < shminfo.shmmni; i++) - if ((shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED) && - shmsegs[i].shm_perm.key == key) - return i; - return -1; + for (i = 0; i < shminfo.shmmni; i++) { + shmseg = shmsegs[i]; + if (shmseg != NULL && shmseg->shm_perm.key == key) + return (i); + } + return (-1); } struct shmid_ds * -shm_find_segment_by_shmid(shmid) - int shmid; +shm_find_segment_by_shmid(int shmid) { int segnum; struct shmid_ds *shmseg; segnum = IPCID_TO_IX(shmid); - if (segnum < 0 || segnum >= shminfo.shmmni) - return NULL; - shmseg = &shmsegs[segnum]; - if ((shmseg->shm_perm.mode & (SHMSEG_ALLOCATED | SHMSEG_REMOVED)) - != SHMSEG_ALLOCATED || + if (segnum < 0 || segnum >= shminfo.shmmni || + (shmseg = shmsegs[segnum]) == NULL) + return (NULL); + if ((shmseg->shm_perm.mode & SHMSEG_REMOVED) || shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid)) - return NULL; - return shmseg; + return (NULL); + return (shmseg); } void -shm_deallocate_segment(shmseg) - struct shmid_ds *shmseg; +shm_deallocate_segment(struct shmid_ds *shmseg) { struct shm_handle *shm_handle; size_t size; @@ -131,24 +135,22 @@ shm_deallocate_segment(shmseg) shm_handle = shmseg->shm_internal; size = round_page(shmseg->shm_segsz); uao_detach(shm_handle->shm_object); - free((caddr_t)shm_handle, M_SHM); - shmseg->shm_internal = NULL; + pool_put(&shm_pool, shmseg); shm_committed -= btoc(size); - shmseg->shm_perm.mode = SHMSEG_FREE; shm_nused--; } int -shm_delete_mapping(vm, shmmap_s) - struct vmspace *vm; - struct shmmap_state *shmmap_s; +shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s) { struct shmid_ds *shmseg; int segnum; size_t size; segnum = IPCID_TO_IX(shmmap_s->shmid); - shmseg = &shmsegs[segnum]; + if (segnum < 0 || segnum >= shminfo.shmmni || + (shmseg = shmsegs[segnum]) == NULL) + return (EINVAL); size = round_page(shmseg->shm_segsz); uvm_deallocate(&vm->vm_map, shmmap_s->va, size); shmmap_s->shmid = -1; @@ -157,40 +159,37 @@ shm_delete_mapping(vm, shmmap_s) (shmseg->shm_perm.mode & SHMSEG_REMOVED)) { shm_deallocate_segment(shmseg); shm_last_free = segnum; + shmsegs[shm_last_free] = NULL; } - return 0; + return (0); } int -sys_shmdt(p, v, retval) - struct proc *p; - void *v; - register_t *retval; +sys_shmdt(struct proc *p, void *v, register_t *retval) { struct sys_shmdt_args /* { syscallarg(const void *) shmaddr; } */ *uap = v; + struct shmmap_head *shmmap_h; struct shmmap_state *shmmap_s; int i; - shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; - if (shmmap_s == NULL) - return EINVAL; + shmmap_h = (struct shmmap_head *)p->p_vmspace->vm_shm; + if (shmmap_h == NULL) + return (EINVAL); - for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) + for (i = 0, shmmap_s = shmmap_h->state; i < shmmap_h->shmseg; + i++, shmmap_s++) if (shmmap_s->shmid != -1 && shmmap_s->va == (vaddr_t)SCARG(uap, shmaddr)) break; - if (i == shminfo.shmseg) - return EINVAL; - return shm_delete_mapping(p->p_vmspace, shmmap_s); + if (i == shmmap_h->shmseg) + return (EINVAL); + return (shm_delete_mapping(p->p_vmspace, shmmap_s)); } int -sys_shmat(p, v, retval) - struct proc *p; - void *v; - register_t *retval; +sys_shmat(struct proc *p, void *v, register_t *retval) { struct sys_shmat_args /* { syscallarg(int) shmid; @@ -200,34 +199,38 @@ sys_shmat(p, v, retval) int error, i, flags; struct ucred *cred = p->p_ucred; struct shmid_ds *shmseg; - struct shmmap_state *shmmap_s = NULL; + struct shmmap_head *shmmap_h; + struct shmmap_state *shmmap_s; struct shm_handle *shm_handle; vaddr_t attach_va; vm_prot_t prot; vsize_t size; - shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; - if (shmmap_s == NULL) { - size = shminfo.shmseg * sizeof(struct shmmap_state); - shmmap_s = malloc(size, M_SHM, M_WAITOK); - for (i = 0; i < shminfo.shmseg; i++) - shmmap_s[i].shmid = -1; - p->p_vmspace->vm_shm = (caddr_t)shmmap_s; + shmmap_h = (struct shmmap_head *)p->p_vmspace->vm_shm; + if (shmmap_h == NULL) { + size = sizeof(int) + + shminfo.shmseg * sizeof(struct shmmap_state); + shmmap_h = malloc(size, M_SHM, M_WAITOK); + shmmap_h->shmseg = shminfo.shmseg; + for (i = 0, shmmap_s = shmmap_h->state; i < shmmap_h->shmseg; + i++, shmmap_s++) + shmmap_s->shmid = -1; + p->p_vmspace->vm_shm = (caddr_t)shmmap_h; } shmseg = shm_find_segment_by_shmid(SCARG(uap, shmid)); if (shmseg == NULL) - return EINVAL; + return (EINVAL); error = ipcperm(cred, &shmseg->shm_perm, (SCARG(uap, shmflg) & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W); if (error) - return error; - for (i = 0; i < shminfo.shmseg; i++) { + return (error); + for (i = 0, shmmap_s = shmmap_h->state; i < shmmap_h->shmseg; i++) { if (shmmap_s->shmid == -1) break; shmmap_s++; } - if (i >= shminfo.shmseg) - return EMFILE; + if (i >= shmmap_h->shmseg) + return (EMFILE); size = round_page(shmseg->shm_segsz); prot = VM_PROT_READ; if ((SCARG(uap, shmflg) & SHM_RDONLY) == 0) @@ -241,7 +244,7 @@ sys_shmat(p, v, retval) else if (((vaddr_t)SCARG(uap, shmaddr) & (SHMLBA-1)) == 0) attach_va = (vaddr_t)SCARG(uap, shmaddr); else - return EINVAL; + return (EINVAL); } else { /* This is just a hint to uvm_map() about where to put it. */ attach_va = round_page((vaddr_t)p->p_vmspace->vm_taddr + @@ -261,14 +264,11 @@ sys_shmat(p, v, retval) shmseg->shm_atime = time.tv_sec; shmseg->shm_nattch++; *retval = attach_va; - return 0; + return (0); } int -sys_shmctl(p, v, retval) - struct proc *p; - void *v; - register_t *retval; +sys_shmctl(struct proc *p, void *v, register_t *retval) { struct sys_shmctl_args /* { syscallarg(int) shmid; @@ -282,23 +282,23 @@ sys_shmctl(p, v, retval) shmseg = shm_find_segment_by_shmid(SCARG(uap, shmid)); if (shmseg == NULL) - return EINVAL; + return (EINVAL); switch (SCARG(uap, cmd)) { case IPC_STAT: if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_R)) != 0) - return error; + return (error); error = copyout((caddr_t)shmseg, SCARG(uap, buf), sizeof(inbuf)); if (error) - return error; + return (error); break; case IPC_SET: if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) != 0) - return error; + return (error); error = copyin(SCARG(uap, buf), (caddr_t)&inbuf, sizeof(inbuf)); if (error) - return error; + return (error); shmseg->shm_perm.uid = inbuf.shm_perm.uid; shmseg->shm_perm.gid = inbuf.shm_perm.gid; shmseg->shm_perm.mode = @@ -308,74 +308,59 @@ sys_shmctl(p, v, retval) break; case IPC_RMID: if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) != 0) - return error; + return (error); shmseg->shm_perm.key = IPC_PRIVATE; shmseg->shm_perm.mode |= SHMSEG_REMOVED; if (shmseg->shm_nattch <= 0) { shm_deallocate_segment(shmseg); shm_last_free = IPCID_TO_IX(SCARG(uap, shmid)); + shmsegs[shm_last_free] = NULL; } break; case SHM_LOCK: case SHM_UNLOCK: default: - return EINVAL; + return (EINVAL); } - return 0; + return (0); } int -shmget_existing(p, uap, mode, segnum, retval) - struct proc *p; +shmget_existing(struct proc *p, struct sys_shmget_args /* { syscallarg(key_t) key; syscallarg(size_t) size; syscallarg(int) shmflg; - } */ *uap; - int mode; - int segnum; - register_t *retval; + } */ *uap, + int mode, int segnum, register_t *retval) { struct shmid_ds *shmseg; struct ucred *cred = p->p_ucred; int error; - shmseg = &shmsegs[segnum]; - if (shmseg->shm_perm.mode & SHMSEG_REMOVED) { - /* - * This segment is in the process of being allocated. Wait - * until it's done, and look the key up again (in case the - * allocation failed or it was freed). - */ - shmseg->shm_perm.mode |= SHMSEG_WANTED; - error = tsleep((caddr_t)shmseg, PLOCK | PCATCH, "shmget", 0); - if (error) - return error; - return EAGAIN; - } + shmseg = shmsegs[segnum]; /* We assume the segnum is valid */ if ((error = ipcperm(cred, &shmseg->shm_perm, mode)) != 0) - return error; + return (error); if (SCARG(uap, size) && SCARG(uap, size) > shmseg->shm_segsz) - return EINVAL; + return (EINVAL); if ((SCARG(uap, shmflg) & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL)) - return EEXIST; + return (EEXIST); *retval = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm); - return 0; + return (0); } int -shmget_allocate_segment(p, uap, mode, retval) - struct proc *p; +shmget_allocate_segment(struct proc *p, struct sys_shmget_args /* { syscallarg(key_t) key; syscallarg(size_t) size; syscallarg(int) shmflg; - } */ *uap; - int mode; - register_t *retval; + } */ *uap, + int mode, register_t *retval) { - int i, segnum, shmid, size; + key_t key; + int segnum, size; struct ucred *cred = p->p_ucred; struct shmid_ds *shmseg; struct shm_handle *shm_handle; @@ -383,68 +368,67 @@ shmget_allocate_segment(p, uap, mode, retval) if (SCARG(uap, size) < shminfo.shmmin || SCARG(uap, size) > shminfo.shmmax) - return EINVAL; + return (EINVAL); if (shm_nused >= shminfo.shmmni) /* any shmids left? */ - return ENOSPC; + return (ENOSPC); size = round_page(SCARG(uap, size)); if (shm_committed + btoc(size) > shminfo.shmall) - return ENOMEM; + return (ENOMEM); + shm_nused++; + shm_committed += btoc(size); + + /* + * If a key has been specified and we had to wait for memory + * to be freed up we need to verify that no one has allocated + * the key we want in the meantime. Yes, this is ugly. + */ + key = SCARG(uap, key); + shmseg = pool_get(&shm_pool, key == IPC_PRIVATE ? PR_WAITOK : 0); + if (shmseg == NULL) { + shmseg = pool_get(&shm_pool, PR_WAITOK); + if (shm_find_segment_by_key(key) != -1) { + pool_put(&shm_pool, shmseg); + shm_nused--; + shm_committed -= btoc(size); + return (EAGAIN); + } + } + + /* XXX - hash shmids instead */ if (shm_last_free < 0) { - for (i = 0; i < shminfo.shmmni; i++) - if (shmsegs[i].shm_perm.mode & SHMSEG_FREE) - break; - if (i == shminfo.shmmni) + for (segnum = 0; segnum < shminfo.shmmni && shmsegs[segnum]; + segnum++) + ; + if (segnum == shminfo.shmmni) panic("shmseg free count inconsistent"); - segnum = i; - } else { + } else { segnum = shm_last_free; - shm_last_free = -1; + if (++shm_last_free >= shminfo.shmmni || shmsegs[shm_last_free]) + shm_last_free = -1; } - shmseg = &shmsegs[segnum]; - /* - * In case we sleep in malloc(), mark the segment present but deleted - * so that noone else tries to create the same key. - */ - shmseg->shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED; - shmseg->shm_perm.key = SCARG(uap, key); - shmseg->shm_perm.seq = (shmseg->shm_perm.seq + 1) & 0x7fff; - shm_handle = (struct shm_handle *) - malloc(sizeof(struct shm_handle), M_SHM, M_WAITOK); - shmid = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm); - + shmsegs[segnum] = shmseg; + shm_handle = (struct shm_handle *)((caddr_t)shmseg + sizeof(*shmseg)); shm_handle->shm_object = uao_create(size, 0); - shmseg->shm_internal = shm_handle; shmseg->shm_perm.cuid = shmseg->shm_perm.uid = cred->cr_uid; shmseg->shm_perm.cgid = shmseg->shm_perm.gid = cred->cr_gid; - shmseg->shm_perm.mode = (shmseg->shm_perm.mode & SHMSEG_WANTED) | - (mode & ACCESSPERMS) | SHMSEG_ALLOCATED; + shmseg->shm_perm.mode = (mode & ACCESSPERMS); + shmseg->shm_perm.seq = shmseqs[segnum] = (shmseqs[segnum] + 1) & 0x7fff; + shmseg->shm_perm.key = key; shmseg->shm_segsz = SCARG(uap, size); shmseg->shm_cpid = p->p_pid; shmseg->shm_lpid = shmseg->shm_nattch = 0; shmseg->shm_atime = shmseg->shm_dtime = 0; shmseg->shm_ctime = time.tv_sec; - shm_committed += btoc(size); - shm_nused++; + shmseg->shm_internal = shm_handle; - *retval = shmid; - if (shmseg->shm_perm.mode & SHMSEG_WANTED) { - /* - * Somebody else wanted this key while we were asleep. Wake - * them up now. - */ - shmseg->shm_perm.mode &= ~SHMSEG_WANTED; - wakeup((caddr_t)shmseg); - } - return error; + *retval = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm); + return (error); } int -sys_shmget(p, v, retval) - struct proc *p; - void *v; - register_t *retval; +sys_shmget(struct proc *p, void *v, register_t *retval) { struct sys_shmget_args /* { syscallarg(key_t) key; @@ -457,23 +441,23 @@ sys_shmget(p, v, retval) if (SCARG(uap, key) != IPC_PRIVATE) { again: segnum = shm_find_segment_by_key(SCARG(uap, key)); - if (segnum >= 0) { - error = shmget_existing(p, uap, mode, segnum, retval); - if (error == EAGAIN) - goto again; - return error; - } + if (segnum >= 0) + return (shmget_existing(p, uap, mode, segnum, retval)); if ((SCARG(uap, shmflg) & IPC_CREAT) == 0) - return ENOENT; + return (ENOENT); } - return shmget_allocate_segment(p, uap, mode, retval); + error = shmget_allocate_segment(p, uap, mode, retval); + if (error == EAGAIN) + goto again; + return (error); } void -shmfork(vm1, vm2) - struct vmspace *vm1, *vm2; +shmfork(struct vmspace *vm1, struct vmspace *vm2) { + struct shmmap_head *shmmap_h; struct shmmap_state *shmmap_s; + struct shmid_ds *shmseg; size_t size; int i; @@ -482,26 +466,30 @@ shmfork(vm1, vm2) return; } - size = shminfo.shmseg * sizeof(struct shmmap_state); - shmmap_s = malloc(size, M_SHM, M_WAITOK); - bcopy(vm1->vm_shm, shmmap_s, size); - vm2->vm_shm = (caddr_t)shmmap_s; - for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) - if (shmmap_s->shmid != -1) - shmsegs[IPCID_TO_IX(shmmap_s->shmid)].shm_nattch++; + shmmap_h = (struct shmmap_head *)vm1->vm_shm; + size = sizeof(int) + shmmap_h->shmseg * sizeof(struct shmmap_state); + vm2->vm_shm = malloc(size, M_SHM, M_WAITOK); + bcopy(vm1->vm_shm, vm2->vm_shm, size); + for (i = 0, shmmap_s = shmmap_h->state; i < shmmap_h->shmseg; + i++, shmmap_s++) { + if (shmmap_s->shmid != -1 && + (shmseg = shmsegs[IPCID_TO_IX(shmmap_s->shmid)]) != NULL) + shmseg->shm_nattch++; + } } void -shmexit(vm) - struct vmspace *vm; +shmexit(struct vmspace *vm) { + struct shmmap_head *shmmap_h; struct shmmap_state *shmmap_s; int i; - shmmap_s = (struct shmmap_state *)vm->vm_shm; - if (shmmap_s == NULL) + shmmap_h = (struct shmmap_head *)vm->vm_shm; + if (shmmap_h == NULL) return; - for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) + for (i = 0, shmmap_s = shmmap_h->state; i < shmmap_h->shmseg; + i++, shmmap_s++) if (shmmap_s->shmid != -1) shm_delete_mapping(vm, shmmap_s); free(vm->vm_shm, M_SHM); @@ -509,26 +497,29 @@ shmexit(vm) } void -shminit() +shminit(void) { - int i; - shminfo.shmmax *= PAGE_SIZE; - - for (i = 0; i < shminfo.shmmni; i++) { - shmsegs[i].shm_perm.mode = SHMSEG_FREE; - shmsegs[i].shm_perm.seq = 0; - } + pool_init(&shm_pool, sizeof(struct shmid_ds) + + sizeof(struct shm_handle), 0, 0, 0, "shmpl", + &pool_allocator_nointr); + shmsegs = malloc(shminfo.shmmni * sizeof(struct shmid_ds *), + M_SHM, M_WAITOK); + bzero(shmsegs, shminfo.shmmni * sizeof(struct shmid_ds *)); + shmseqs = malloc(shminfo.shmmni * sizeof(unsigned short), + M_SHM, M_WAITOK); + bzero(shmseqs, shminfo.shmmni * sizeof(unsigned short)); + + shminfo.shmmax *= PAGE_SIZE; /* actually in pages */ shm_last_free = 0; shm_nused = 0; shm_committed = 0; } void -shmid_n2o(n, o) - struct shmid_ds *n; - struct oshmid_ds *o; +shmid_n2o(struct shmid_ds *n, struct oshmid_ds *o) { + o->shm_segsz = n->shm_segsz; o->shm_lpid = n->shm_lpid; o->shm_cpid = n->shm_cpid; @@ -539,3 +530,97 @@ shmid_n2o(n, o) o->shm_internal = n->shm_internal; ipc_n2o(&n->shm_perm, &o->shm_perm); } + +/* + * Userland access to struct shminfo. + */ +int +sysctl_sysvshm(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int error, val; + struct shmid_ds **newsegs; + unsigned short *newseqs; + + if (namelen != 2) { + switch (name[0]) { + case KERN_SHMINFO_SHMMAX: + case KERN_SHMINFO_SHMMIN: + case KERN_SHMINFO_SHMMNI: + case KERN_SHMINFO_SHMSEG: + case KERN_SHMINFO_SHMALL: + break; + default: + return (ENOTDIR); /* overloaded */ + } + } + + switch (name[0]) { + case KERN_SHMINFO_SHMMAX: + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, + &shminfo.shmmax)) || newp == NULL) + return (error); + + /* If new shmmax > shmall, crank shmall */ + if (btoc(round_page(shminfo.shmmax)) > shminfo.shmall) + shminfo.shmall = btoc(round_page(shminfo.shmmax)); + return (0); + case KERN_SHMINFO_SHMMIN: + val = shminfo.shmmin; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == shminfo.shmmin) + return (error); + if (val <= 0) + return (EINVAL); /* shmmin must be >= 1 */ + shminfo.shmmin = val; + return (0); + case KERN_SHMINFO_SHMMNI: + val = shminfo.shmmni; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == shminfo.shmmni) + return (error); + + if (val < shminfo.shmmni) + return (EINVAL); /* can't decrease shmmni */ + + /* Expand shmsegs and shmseqs arrays */ + newsegs = malloc(val * sizeof(struct shmid_ds *), + M_SHM, M_WAITOK); + bcopy(shmsegs, newsegs, + shminfo.shmmni * sizeof(struct shmid_ds *)); + bzero(newsegs + shminfo.shmmni, + (val - shminfo.shmmni) * sizeof(struct shmid_ds *)); + newseqs = malloc(val * sizeof(unsigned short), M_SHM, M_WAITOK); + bcopy(shmseqs, newseqs, + shminfo.shmmni * sizeof(unsigned short)); + bzero(newseqs + shminfo.shmmni, + (val - shminfo.shmmni) * sizeof(unsigned short)); + free(shmsegs, M_SHM); + free(shmseqs, M_SHM); + shmsegs = newsegs; + shmseqs = newseqs; + shminfo.shmmni = val; + return (0); + case KERN_SHMINFO_SHMSEG: + val = shminfo.shmseg; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == shminfo.shmseg) + return (error); + if (val <= 0) + return (EINVAL); /* shmseg must be >= 1 */ + shminfo.shmseg = val; + return (0); + case KERN_SHMINFO_SHMALL: + val = shminfo.shmall; + if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || + val == shminfo.shmall) + return (error); + if (val < shminfo.shmall) + return (EINVAL); /* can't decrease shmall */ + shminfo.shmall = val; + return (0); + default: + return (EOPNOTSUPP); + } + /* NOTREACHED */ +} diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h index d94a15e1a64..2355be15970 100644 --- a/sys/sys/malloc.h +++ b/sys/sys/malloc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: malloc.h,v 1.61 2002/08/28 08:28:03 tdeval Exp $ */ +/* $OpenBSD: malloc.h,v 1.62 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: malloc.h,v 1.39 1998/07/12 19:52:01 augustss Exp $ */ /* @@ -90,7 +90,8 @@ #define M_UFSMNT 28 /* UFS mount structure */ #define M_SHM 29 /* SVID compatible shared memory segments */ #define M_VMMAP 30 /* VM map structures */ -/* 31-33 - free */ +#define M_SEM 31 /* SVID compatible semaphores */ +/* 32-33 - free */ #define M_VMPMAP 34 /* VM pmap */ #define M_VMPVENT 35 /* VM phys-virt mapping entry */ /* 36-37 - free */ @@ -200,7 +201,7 @@ "UFS mount", /* 28 M_UFSMNT */ \ "shm", /* 29 M_SHM */ \ "VM map", /* 30 M_VMMAP */ \ - NULL, \ + "sem", /* 31 M_SEM */ \ NULL, \ NULL, \ "VM pmap", /* 34 M_VMPMAP */ \ diff --git a/sys/sys/sem.h b/sys/sys/sem.h index eaeb5babfa2..270d7eabc20 100644 --- a/sys/sys/sem.h +++ b/sys/sys/sem.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sem.h,v 1.12 2002/03/14 01:27:14 millert Exp $ */ +/* $OpenBSD: sem.h,v 1.13 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: sem.h,v 1.8 1996/02/09 18:25:29 christos Exp $ */ /* @@ -10,7 +10,38 @@ #ifndef _SYS_SEM_H_ #define _SYS_SEM_H_ +#ifndef _SYS_IPC_H_ #include <sys/ipc.h> +#endif + +#if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) + +/* sem-specific sysctl variables corresponding to members of struct seminfo */ +#define KERN_SEMINFO_SEMMNI 1 /* int: # of semaphore identifiers */ +#define KERN_SEMINFO_SEMMNS 2 /* int: # of semaphores in system */ +#define KERN_SEMINFO_SEMMNU 3 /* int: # of undo structures in system */ +#define KERN_SEMINFO_SEMMSL 4 /* int: max semaphores per id */ +#define KERN_SEMINFO_SEMOPM 5 /* int: max operations per semop call */ +#define KERN_SEMINFO_SEMUME 6 /* int: max undo entries per process */ +#define KERN_SEMINFO_SEMUSZ 7 /* int: size in bytes of struct undo */ +#define KERN_SEMINFO_SEMVMX 8 /* int: semaphore maximum value */ +#define KERN_SEMINFO_SEMAEM 9 /* int: adjust on exit max value */ +#define KERN_SEMINFO_MAXID 10 /* number of valid semaphore sysctls */ + +#define CTL_KERN_SEMINFO_NAMES { \ + { 0, 0 }, \ + { "semmni", CTLTYPE_INT }, \ + { "semmns", CTLTYPE_INT }, \ + { "semmnu", CTLTYPE_INT }, \ + { "semmsl", CTLTYPE_INT }, \ + { "semopm", CTLTYPE_INT }, \ + { "semume", CTLTYPE_INT }, \ + { "semusz", CTLTYPE_INT }, \ + { "semvmx", CTLTYPE_INT }, \ + { "semaem", CTLTYPE_INT }, \ +} + +#endif /* !_POSIX_C_SOURCE && !_XOPEN_SOURCE */ struct sem { unsigned short semval; /* semaphore value */ @@ -57,8 +88,6 @@ struct sembuf { }; #define SEM_UNDO 010000 -#define MAX_SOPS 5 /* maximum # of sembuf's per semop call */ - /* * semctl's arg parameter structure */ @@ -130,10 +159,6 @@ struct sem_sysctl_info { extern struct seminfo seminfo; -/* internal "mode" bits */ -#define SEM_ALLOC 01000 /* semaphore is allocated */ -#define SEM_DEST 02000 /* semaphore will be destroyed on last detach */ - /* * Configuration parameters */ @@ -164,15 +189,8 @@ extern struct seminfo seminfo; /* * Structures allocated in machdep.c, defined/initialized in sysv_sem.c */ -extern struct semid_ds *sema; /* semaphore id pool */ -extern struct sem *sem; /* semaphore pool */ -extern struct sem_undo *semu_list; /* list of active undo structures */ -extern int *semu; /* undo structure pool */ - -/* - * Macro to find a particular sem_undo vector - */ -#define SEMU(ix) ((struct sem_undo *)(((long)semu)+ix * SEMUSZ)) +extern struct semid_ds **sema; /* semaphore id list */ +extern struct sem_undo *semu_list; /* list of undo structures */ #endif /* _KERNEL */ @@ -190,6 +208,7 @@ __END_DECLS void seminit(void); void semexit(struct proc *); void semid_n2o(struct semid_ds *, struct osemid_ds *); +int sysctl_sysvsem(int *, u_int, void *, size_t *, void *, size_t); #endif /* !_KERNEL */ #endif /* !_SEM_H_ */ diff --git a/sys/sys/shm.h b/sys/sys/shm.h index 55db6b0dda1..e9a5cad56c4 100644 --- a/sys/sys/shm.h +++ b/sys/sys/shm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: shm.h,v 1.13 2002/03/23 13:28:34 espie Exp $ */ +/* $OpenBSD: shm.h,v 1.14 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: shm.h,v 1.20 1996/04/09 20:55:35 cgd Exp $ */ /* @@ -39,27 +39,73 @@ #ifndef _SYS_SHM_H_ #define _SYS_SHM_H_ +#ifndef _SYS_IPC_H_ #include <sys/ipc.h> +#endif + +#if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) + +/* shm-specific sysctl variables corresponding to members of struct shminfo */ +#define KERN_SHMINFO_SHMMAX 1 /* int: max shm segment size (bytes) */ +#define KERN_SHMINFO_SHMMIN 2 /* int: min shm segment size (bytes) */ +#define KERN_SHMINFO_SHMMNI 3 /* int: max number of shm identifiers */ +#define KERN_SHMINFO_SHMSEG 4 /* int: max shm segments per process */ +#define KERN_SHMINFO_SHMALL 5 /* int: max amount of shm (pages) */ +#define KERN_SHMINFO_MAXID 6 /* number of valid shared memory ids */ + +#define CTL_KERN_SHMINFO_NAMES { \ + { 0, 0 }, \ + { "shmmax", CTLTYPE_INT }, \ + { "shmmin", CTLTYPE_INT }, \ + { "shmmni", CTLTYPE_INT }, \ + { "shmseg", CTLTYPE_INT }, \ + { "shmall", CTLTYPE_INT }, \ +} + +/* + * Old (deprecated) access mode definitions--do not use. + * Provided for compatibility with old code only. + */ +#define SHM_R IPC_R +#define SHM_W IPC_W + +#endif /* !_POSIX_C_SOURCE && !_XOPEN_SOURCE */ +/* + * Shared memory operation flags for shmat(2). + */ #define SHM_RDONLY 010000 /* Attach read-only (else read-write) */ #define SHM_RND 020000 /* Round attach address to SHMLBA */ -#define SHMLBA PAGE_SIZE /* Segment low boundry address multiple */ -/* "official" access mode definitions; somewhat braindead since you have - to specify (SHM_* >> 3) for group and (SHM_* >> 6) for world permissions */ -#define SHM_R (IPC_R) -#define SHM_W (IPC_W) +/* + * Shared memory specific control commands for shmctl(). + * We accept but ignore these (XXX). + */ +#define SHM_LOCK 3 /* Lock segment in memory. */ +#define SHM_UNLOCK 4 /* Unlock a segment locked by SHM_LOCK. */ + +/* + * Segment low boundry address multiple + * Use PAGE_SIZE for kernel but for userland query the kernel for the value. + */ +#if defined(_KERNEL) || defined(_STANDALONE) || defined(_LKM) +#define SHMLBA PAGE_SIZE +#else +#define SHMLBA (getpagesize()) +#endif /* _KERNEL || _STANDALONE || _LKM */ + +typedef short shmatt_t; struct shmid_ds { struct ipc_perm shm_perm; /* operation permission structure */ int shm_segsz; /* size of segment in bytes */ pid_t shm_lpid; /* process ID of last shm op */ pid_t shm_cpid; /* process ID of creator */ - short shm_nattch; /* number of current attaches */ + shmatt_t shm_nattch; /* number of current attaches */ time_t shm_atime; /* time of last shmat() */ time_t shm_dtime; /* time of last shmdt() */ time_t shm_ctime; /* time of last change by shmctl() */ - void *shm_internal; /* sysv stupidity */ + void *shm_internal; /* implementation specific data */ }; #ifdef _KERNEL @@ -72,16 +118,11 @@ struct oshmid_ds { time_t shm_atime; /* time of last shmat() */ time_t shm_dtime; /* time of last shmdt() */ time_t shm_ctime; /* time of last change by shmctl() */ - void *shm_internal; /* sysv stupidity */ + void *shm_internal; /* implementation specific data */ }; #endif -#ifdef _KERNEL - -/* Some systems (e.g. HP-UX) take these as the second (cmd) arg to shmctl(). */ -#define SHM_LOCK 3 /* Lock segment in memory. */ -#define SHM_UNLOCK 4 /* Unlock a segment locked by SHM_LOCK. */ - +#if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) /* * System V style catch-all structure for shared memory constants that * might be of interest to user programs. Do we really want/need this? @@ -98,9 +139,11 @@ struct shm_sysctl_info { struct shminfo shminfo; struct shmid_ds shmids[1]; }; +#endif /* !_POSIX_C_SOURCE && !_XOPEN_SOURCE */ +#ifdef _KERNEL extern struct shminfo shminfo; -extern struct shmid_ds *shmsegs; +extern struct shmid_ds **shmsegs; /* initial values for machdep.c */ extern int shmseg; @@ -112,6 +155,7 @@ void shminit(void); void shmfork(struct vmspace *, struct vmspace *); void shmexit(struct vmspace *); void shmid_n2o(struct shmid_ds *, struct oshmid_ds *); +int sysctl_sysvshm(int *, u_int, void *, size_t *, void *, size_t); #else /* !_KERNEL */ diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 26cc22fba36..5b1a2ca39aa 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.59 2002/07/07 22:06:33 deraadt Exp $ */ +/* $OpenBSD: sysctl.h,v 1.60 2002/12/17 23:11:31 millert Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -177,7 +177,9 @@ struct ctlname { #define KERN_NUMVNODES 58 /* int: number of vnodes in use */ #define KERN_MBSTAT 59 /* struct: mbuf statistics */ #define KERN_USERASYMCRYPTO 60 /* int: usercrypto */ -#define KERN_MAXID 61 /* number of valid kern ids */ +#define KERN_SEMINFO 61 /* struct: SysV struct seminfo */ +#define KERN_SHMINFO 62 /* struct: SysV struct shminfo */ +#define KERN_MAXID 63 /* number of valid kern ids */ #define CTL_KERN_NAMES { \ { 0, 0 }, \ @@ -241,6 +243,8 @@ struct ctlname { { "numvnodes", CTLTYPE_INT }, \ { "mbstat", CTLTYPE_STRUCT }, \ { "userasymcrypto", CTLTYPE_INT }, \ + { "seminfo", CTLTYPE_STRUCT }, \ + { "shminfo", CTLTYPE_STRUCT }, \ } /* diff --git a/usr.bin/ipcs/ipcs.c b/usr.bin/ipcs/ipcs.c index acae0b9362b..2c7c6494b61 100644 --- a/usr.bin/ipcs/ipcs.c +++ b/usr.bin/ipcs/ipcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipcs.c,v 1.18 2002/06/15 18:47:50 matthieu Exp $ */ +/* $OpenBSD: ipcs.c,v 1.19 2002/12/17 23:11:32 millert Exp $ */ /* $NetBSD: ipcs.c,v 1.25 2000/06/16 03:58:20 simonb Exp $ */ /*- @@ -66,7 +66,7 @@ #include <sys/param.h> #include <sys/sysctl.h> -#define _KERNEL +#define _KERNEL /* XXX */ #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> @@ -523,8 +523,7 @@ shm_sysctl(void) char *buf; int mib[3]; size_t len; - int i /*, valid */; - long valid; + int i, valid; mib[0] = CTL_KERN; mib[1] = KERN_SYSVSHM; @@ -568,7 +567,7 @@ shm_sysctl(void) show_shminfo_hdr(); for (i = 0; i < shmsi->shminfo.shmmni; i++) { struct shmid_ds *shmptr = &shmsi->shmids[i]; - if (shmptr->shm_perm.mode & 0x0800) + if (shmptr->shm_internal) show_shminfo(shmptr->shm_atime, shmptr->shm_dtime, shmptr->shm_ctime, @@ -639,7 +638,8 @@ sem_sysctl(void) show_seminfo_hdr(); for (i = 0; i < semsi->seminfo.semmni; i++) { struct semid_ds *semaptr = &semsi->semids[i]; - if ((semaptr->sem_perm.mode & SEM_ALLOC) != 0) + + if (semaptr->sem_base != NULL) show_seminfo(semaptr->sem_otime, semaptr->sem_ctime, IXSEQ_TO_IPCID(i, semaptr->sem_perm), @@ -661,11 +661,12 @@ ipcs_kvm(void) struct msginfo msginfo; struct msqid_ds *msqids; struct seminfo seminfo; - struct semid_ds *sema; + struct semid_ds sem, **sema; struct shminfo shminfo; - struct shmid_ds *shmsegs; - kvm_t *kd; + struct shmid_ds shmseg, **shmsegs; char errbuf[_POSIX2_LINE_MAX]; + u_long addr; + kvm_t *kd; int i; struct nlist symbols[] = { {"_sema"}, @@ -714,17 +715,17 @@ ipcs_kvm(void) show_msgtotal(&msginfo); if (display & MSGINFO) { - struct msqid_ds *xmsqids; - if (kvm_read(kd, symbols[X_MSQIDS].n_value, - &msqids, sizeof(msqids)) != sizeof(msqids)) + &addr, sizeof(addr)) != sizeof(addr)) errx(1, "kvm_read (%s): %s", symbols[X_MSQIDS].n_name, kvm_geterr(kd)); - xmsqids = malloc(sizeof(struct msqid_ds) * + msqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni); + if (msqids == NULL) + err(1, "malloc"); - if (kvm_read(kd, (u_long)msqids, xmsqids, + if (kvm_read(kd, addr, msqids, sizeof(struct msqid_ds) * msginfo.msgmni) != sizeof(struct msqid_ds) * msginfo.msgmni) errx(1, "kvm_read (msqids): %s", @@ -732,7 +733,7 @@ ipcs_kvm(void) show_msginfo_hdr(); for (i = 0; i < msginfo.msgmni; i++) { - struct msqid_ds *msqptr = &xmsqids[i]; + struct msqid_ds *msqptr = &msqids[i]; if (msqptr->msg_qbytes != 0) show_msginfo(msqptr->msg_stime, msqptr->msg_rtime, @@ -766,40 +767,45 @@ ipcs_kvm(void) show_shmtotal(&shminfo); if (display & SHMINFO) { - struct shmid_ds *xshmids; - - if (kvm_read(kd, symbols[X_SHMSEGS].n_value, &shmsegs, - sizeof(shmsegs)) != sizeof(shmsegs)) + if (kvm_read(kd, symbols[X_SHMSEGS].n_value, &addr, + sizeof(addr)) != sizeof(addr)) errx(1, "kvm_read (%s): %s", symbols[X_SHMSEGS].n_name, kvm_geterr(kd)); - xshmids = malloc(sizeof(struct shmid_ds) * + shmsegs = malloc(sizeof(struct shmid_ds *) * shminfo.shmmni); + if (shmsegs == NULL) + err(1, "malloc"); - if (kvm_read(kd, (u_long)shmsegs, xshmids, - sizeof(struct shmid_ds) * shminfo.shmmni) != - sizeof(struct shmid_ds) * shminfo.shmmni) + if (kvm_read(kd, addr, shmsegs, + sizeof(struct shmid_ds *) * shminfo.shmmni) != + sizeof(struct shmid_ds *) * shminfo.shmmni) errx(1, "kvm_read (shmsegs): %s", kvm_geterr(kd)); show_shminfo_hdr(); for (i = 0; i < shminfo.shmmni; i++) { - struct shmid_ds *shmptr = &xshmids[i]; - if (shmptr->shm_perm.mode & 0x0800) - show_shminfo(shmptr->shm_atime, - shmptr->shm_dtime, - shmptr->shm_ctime, - IXSEQ_TO_IPCID(i, shmptr->shm_perm), - shmptr->shm_perm.key, - shmptr->shm_perm.mode, - shmptr->shm_perm.uid, - shmptr->shm_perm.gid, - shmptr->shm_perm.cuid, - shmptr->shm_perm.cgid, - shmptr->shm_nattch, - shmptr->shm_segsz, - shmptr->shm_cpid, - shmptr->shm_lpid); + if (shmsegs[i] == NULL) + continue; + + if (kvm_read(kd, (u_long)shmsegs[i], &shmseg, + sizeof(shmseg)) != sizeof(shmseg)) + errx(1, "kvm_read (shmseg): %s", + kvm_geterr(kd)); + show_shminfo(shmseg.shm_atime, + shmseg.shm_dtime, + shmseg.shm_ctime, + IXSEQ_TO_IPCID(i, shmseg.shm_perm), + shmseg.shm_perm.key, + shmseg.shm_perm.mode, + shmseg.shm_perm.uid, + shmseg.shm_perm.gid, + shmseg.shm_perm.cuid, + shmseg.shm_perm.cgid, + shmseg.shm_nattch, + shmseg.shm_segsz, + shmseg.shm_cpid, + shmseg.shm_lpid); } printf("\n"); } @@ -811,42 +817,46 @@ ipcs_kvm(void) if ((display & (SEMINFO | SEMTOTAL)) && (kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo, sizeof(seminfo)) == sizeof(seminfo))) { - struct semid_ds *xsema; - if (display & SEMTOTAL) show_semtotal(&seminfo); if (display & SEMINFO) { - if (kvm_read(kd, symbols[X_SEMA].n_value, &sema, - sizeof(sema)) != sizeof(sema)) + if (kvm_read(kd, symbols[X_SEMA].n_value, &addr, + sizeof(addr)) != sizeof(addr)) errx(1, "kvm_read (%s): %s", symbols[X_SEMA].n_name, kvm_geterr(kd)); - xsema = malloc(sizeof(struct semid_ds) * + sema = malloc(sizeof(struct semid_ds *) * seminfo.semmni); + if (sema == NULL) + err(1, "malloc"); - if (kvm_read(kd, (u_long)sema, xsema, - sizeof(struct semid_ds) * seminfo.semmni) != - sizeof(struct semid_ds) * seminfo.semmni) + if (kvm_read(kd, addr, sema, + sizeof(struct semid_ds *) * seminfo.semmni) != + sizeof(struct semid_ds *) * seminfo.semmni) errx(1, "kvm_read (sema): %s", kvm_geterr(kd)); show_seminfo_hdr(); for (i = 0; i < seminfo.semmni; i++) { - struct semid_ds *semaptr = &xsema[i]; - if ((semaptr->sem_perm.mode & SEM_ALLOC) != 0) - show_seminfo(semaptr->sem_otime, - semaptr->sem_ctime, - IXSEQ_TO_IPCID(i, semaptr->sem_perm), - semaptr->sem_perm.key, - semaptr->sem_perm.mode, - semaptr->sem_perm.uid, - semaptr->sem_perm.gid, - semaptr->sem_perm.cuid, - semaptr->sem_perm.cgid, - semaptr->sem_nsems); + if (sema[i] == NULL) + continue; + + if (kvm_read(kd, (u_long)sema[i], &sem, + sizeof(sem)) != sizeof(sem)) + errx(1, "kvm_read (sem): %s", + kvm_geterr(kd)); + show_seminfo(sem.sem_otime, + sem.sem_ctime, + IXSEQ_TO_IPCID(i, sem.sem_perm), + sem.sem_perm.key, + sem.sem_perm.mode, + sem.sem_perm.uid, + sem.sem_perm.gid, + sem.sem_perm.cuid, + sem.sem_perm.cgid, + sem.sem_nsems); } - printf("\n"); } } else |
