summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2001-09-28 01:42:55 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2001-09-28 01:42:55 +0000
commit4a814c58af93d785576dc2c587e8073aa663b82e (patch)
tree489483f2cb824abb69f87fae4cc649bfd1eee4e4
parent729be02b6710288385051ce0df83204172b85814 (diff)
sysctl() support for getting the SYSV *info structs and the associated
SYSV structs. To be used by ipcs(1). Based on work by simonb@netbsd.org
-rw-r--r--sys/kern/kern_sysctl.c149
-rw-r--r--sys/sys/msg.h9
-rw-r--r--sys/sys/sem.h8
-rw-r--r--sys/sys/shm.h8
-rw-r--r--sys/sys/sysctl.h16
5 files changed, 181 insertions, 9 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 05fb51eecf0..a316e271f56 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.57 2001/09/07 22:03:21 angelos Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.58 2001/09/28 01:42:54 millert Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -74,6 +74,16 @@
#include <ddb/db_var.h>
#endif
+#ifdef SYSVMSG
+#include <sys/msg.h>
+#endif
+#ifdef SYSVSEM
+#include <sys/sem.h>
+#endif
+#ifdef SYSVSHM
+#include <sys/shm.h>
+#endif
+
extern struct forkstat forkstat;
extern struct nchstats nchstats;
extern int nselcoll, fscale;
@@ -240,7 +250,7 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
/* all sysctl names at this level are terminal */
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_POOL || name[0] == KERN_SYSVIPC_INFO))
return (ENOTDIR); /* overloaded */
switch (name[0]) {
@@ -409,6 +419,10 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
return (EINVAL);
}
return (error);
+#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
+ case KERN_SYSVIPC_INFO:
+ return (sysctl_sysvipc(name + 1, namelen - 1, oldp, oldlenp));
+#endif
default:
return (EOPNOTSUPP);
}
@@ -1032,3 +1046,134 @@ sysctl_diskinit(update, p)
lockmgr(&sysctl_disklock, LK_RELEASE, NULL, p);
return 0;
}
+
+#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
+int
+sysctl_sysvipc(name, namelen, where, sizep)
+ int *name;
+ u_int namelen;
+ void *where;
+ size_t *sizep;
+{
+#ifdef SYSVMSG
+ struct msg_sysctl_info *msgsi;
+#endif
+#ifdef SYSVSEM
+ struct sem_sysctl_info *semsi;
+#endif
+#ifdef SYSVSHM
+ struct shm_sysctl_info *shmsi;
+#endif
+ size_t infosize, dssize, tsize, buflen;
+ int i, nds, error, ret;
+ void *buf;
+
+ if (namelen != 1)
+ return (EINVAL);
+
+ buflen = *sizep;
+
+ switch (*name) {
+ case KERN_SYSVIPC_MSG_INFO:
+#ifdef SYSVMSG
+ infosize = sizeof(msgsi->msginfo);
+ nds = msginfo.msgmni;
+ dssize = sizeof(msgsi->msgids[0]);
+ break;
+#else
+ return (EOPNOTSUPP);
+#endif
+ case KERN_SYSVIPC_SEM_INFO:
+#ifdef SYSVSEM
+ infosize = sizeof(semsi->seminfo);
+ nds = seminfo.semmni;
+ dssize = sizeof(semsi->semids[0]);
+ break;
+#else
+ return (EOPNOTSUPP);
+#endif
+ case KERN_SYSVIPC_SHM_INFO:
+#ifdef SYSVSHM
+ infosize = sizeof(shmsi->shminfo);
+ nds = shminfo.shmmni;
+ dssize = sizeof(shmsi->shmids[0]);
+ break;
+#else
+ return (EOPNOTSUPP);
+#endif
+ default:
+ return (EINVAL);
+ }
+ tsize = infosize + (nds * dssize);
+
+ /* Return just the total size required. */
+ if (where == NULL) {
+ *sizep = tsize;
+ return (0);
+ }
+
+ /* Not enough room for even the info struct. */
+ if (buflen < infosize) {
+ *sizep = 0;
+ return (ENOMEM);
+ }
+ buf = malloc(min(tsize, buflen), M_TEMP, M_WAITOK);
+ bzero(buf, min(tsize, buflen));
+
+ switch (*name) {
+#ifdef SYSVMSG
+ case KERN_SYSVIPC_MSG_INFO:
+ msgsi = (struct msg_sysctl_info *)buf;
+ msgsi->msginfo = msginfo;
+ break;
+#endif
+#ifdef SYSVSEM
+ case KERN_SYSVIPC_SEM_INFO:
+ semsi = (struct sem_sysctl_info *)buf;
+ semsi->seminfo = seminfo;
+ break;
+#endif
+#ifdef SYSVSHM
+ case KERN_SYSVIPC_SHM_INFO:
+ shmsi = (struct shm_sysctl_info *)buf;
+ shmsi->shminfo = shminfo;
+ break;
+#endif
+ }
+ buflen -= infosize;
+
+ ret = 0;
+ if (buflen > 0) {
+ /* Fill in the IPC data structures. */
+ for (i = 0; i < nds; i++) {
+ if (buflen < dssize) {
+ ret = ENOMEM;
+ break;
+ }
+ switch (*name) {
+#ifdef SYSVMSG
+ case KERN_SYSVIPC_MSG_INFO:
+ bcopy(&msqids[i], &msgsi->msgids[i], dssize);
+ break;
+#endif
+#ifdef SYSVSEM
+ case KERN_SYSVIPC_SEM_INFO:
+ bcopy(&sema[i], &semsi->semids[i], dssize);
+ break;
+#endif
+#ifdef SYSVSHM
+ case KERN_SYSVIPC_SHM_INFO:
+ bcopy(&shmsegs[i], &shmsi->shmids[i], dssize);
+ break;
+#endif
+ }
+ buflen -= dssize;
+ }
+ }
+ *sizep -= buflen;
+ error = copyout(buf, where, *sizep);
+ free(buf, M_TEMP);
+ /* If copyout succeeded, use return code set earlier. */
+ return (error ? error : ret);
+}
+#endif /* SYSVMSG || SYSVSEM || SYSVSHM */
diff --git a/sys/sys/msg.h b/sys/sys/msg.h
index 2a5bc568772..95ef0fde97b 100644
--- a/sys/sys/msg.h
+++ b/sys/sys/msg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: msg.h,v 1.6 2001/08/12 22:50:12 millert Exp $ */
+/* $OpenBSD: msg.h,v 1.7 2001/09/28 01:42:54 millert Exp $ */
/* $NetBSD: msg.h,v 1.9 1996/02/09 18:25:18 christos Exp $ */
/*
@@ -114,7 +114,12 @@ struct msginfo {
msgssz, /* size of a message segment (see notes above) */
msgseg; /* number of message segments */
};
-struct msginfo msginfo;
+struct msginfo msginfo; /* XXX */
+
+struct msg_sysctl_info {
+ struct msginfo msginfo;
+ struct msqid_ds msgids[1];
+};
#ifndef MSGSSZ
#define MSGSSZ 8 /* Each segment must be 2^N long */
diff --git a/sys/sys/sem.h b/sys/sys/sem.h
index 6d899d93c28..26334e0daa9 100644
--- a/sys/sys/sem.h
+++ b/sys/sys/sem.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sem.h,v 1.10 2001/08/12 23:58:34 millert Exp $ */
+/* $OpenBSD: sem.h,v 1.11 2001/09/28 01:42:54 millert Exp $ */
/* $NetBSD: sem.h,v 1.8 1996/02/09 18:25:29 christos Exp $ */
/*
@@ -122,6 +122,12 @@ struct seminfo {
semvmx, /* semaphore maximum value */
semaem; /* adjust on exit max value */
};
+
+struct sem_sysctl_info {
+ struct seminfo seminfo;
+ struct semid_ds semids[1];
+};
+
extern struct seminfo seminfo;
/* internal "mode" bits */
diff --git a/sys/sys/shm.h b/sys/sys/shm.h
index bc5de3428bc..a58a2db8a22 100644
--- a/sys/sys/shm.h
+++ b/sys/sys/shm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: shm.h,v 1.10 2001/08/12 22:50:12 millert Exp $ */
+/* $OpenBSD: shm.h,v 1.11 2001/09/28 01:42:54 millert Exp $ */
/* $NetBSD: shm.h,v 1.20 1996/04/09 20:55:35 cgd Exp $ */
/*
@@ -93,6 +93,12 @@ struct shminfo {
int shmseg; /* max shared memory segments per process */
int shmall; /* max amount of shared memory (pages) */
};
+
+struct shm_sysctl_info {
+ struct shminfo shminfo;
+ struct shmid_ds shmids[1];
+};
+
extern struct shminfo shminfo;
extern struct shmid_ds *shmsegs;
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 809fdad5b8c..fa056a7bd1a 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.42 2001/08/18 03:32:16 art Exp $ */
+/* $OpenBSD: sysctl.h,v 1.43 2001/09/28 01:42:54 millert Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -163,8 +163,9 @@ struct ctlname {
#define KERN_NPROCS 47 /* int: number of processes */
#define KERN_MSGBUF 48 /* message buffer, KERN_MSGBUFSIZE */
#define KERN_POOL 49 /* struct: pool information */
-#define KERN_STACKGAPRANDOM 50 /* int: stackgap_random */
-#define KERN_MAXID 51 /* number of valid kern ids */
+#define KERN_STACKGAPRANDOM 50 /* int: stackgap_random */
+#define KERN_SYSVIPC_INFO 51 /* struct: SysV sem/shm/msg info */
+#define KERN_MAXID 52 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
{ 0, 0 }, \
@@ -218,6 +219,7 @@ struct ctlname {
{ "msgbuf", CTLTYPE_STRUCT }, \
{ "pool", CTLTYPE_NODE }, \
{ "stackgap_random", CTLTYPE_INT }, \
+ { "sysvipc_info", CTLTYPE_INT }, \
}
/*
@@ -233,6 +235,13 @@ struct ctlname {
#define KERN_PROC_KTHREAD 7 /* also return kernel threads */
/*
+ * KERN_SYSVIPC_INFO subtypes
+ */
+#define KERN_SYSVIPC_MSG_INFO 1 /* msginfo and msqid_ds */
+#define KERN_SYSVIPC_SEM_INFO 2 /* seminfo and semid_ds */
+#define KERN_SYSVIPC_SHM_INFO 3 /* shminfo and shmid_ds */
+
+/*
* KERN_PROC subtype ops return arrays of augmented proc structures:
*/
struct kinfo_proc {
@@ -460,6 +469,7 @@ int cpu_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
struct proc *));
int vfs_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
struct proc *));
+int sysctl_sysvipc __P((int *, u_int, void *, size_t *));
void sysctl_init __P((void));