summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/gen/sysctl.388
-rw-r--r--sbin/sysctl/sysctl.824
-rw-r--r--sbin/sysctl/sysctl.c74
-rw-r--r--sys/arch/alpha/alpha/machdep.c20
-rw-r--r--sys/arch/amiga/amiga/machdep.c20
-rw-r--r--sys/arch/hp300/hp300/machdep.c20
-rw-r--r--sys/arch/hppa/hppa/machdep.c20
-rw-r--r--sys/arch/i386/i386/machdep.c21
-rw-r--r--sys/arch/mac68k/mac68k/machdep.c20
-rw-r--r--sys/arch/macppc/macppc/machdep.c19
-rw-r--r--sys/arch/mvme68k/mvme68k/machdep.c20
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c20
-rw-r--r--sys/arch/mvmeppc/mvmeppc/machdep.c19
-rw-r--r--sys/arch/sparc/sparc/machdep.c20
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c19
-rw-r--r--sys/arch/sun3/sun3/machdep.c20
-rw-r--r--sys/arch/vax/vax/machdep.c21
-rw-r--r--sys/compat/common/kern_ipc_23.c134
-rw-r--r--sys/kern/kern_sysctl.c45
-rw-r--r--sys/kern/sysv_sem.c660
-rw-r--r--sys/kern/sysv_shm.c443
-rw-r--r--sys/sys/malloc.h7
-rw-r--r--sys/sys/sem.h51
-rw-r--r--sys/sys/shm.h76
-rw-r--r--sys/sys/sysctl.h8
-rw-r--r--usr.bin/ipcs/ipcs.c130
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