diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2001-09-28 01:42:55 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2001-09-28 01:42:55 +0000 |
commit | 4a814c58af93d785576dc2c587e8073aa663b82e (patch) | |
tree | 489483f2cb824abb69f87fae4cc649bfd1eee4e4 | |
parent | 729be02b6710288385051ce0df83204172b85814 (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.c | 149 | ||||
-rw-r--r-- | sys/sys/msg.h | 9 | ||||
-rw-r--r-- | sys/sys/sem.h | 8 | ||||
-rw-r--r-- | sys/sys/shm.h | 8 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 16 |
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)); |