FreeBSD Bugzilla – Attachment 82693 Details for
Bug 118292
[sysvipc] [patch] Add support to remove all msg/shm/sem ids with ipcrm
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 13.86 KB, created by
Callum Gibson
on 2007-11-28 00:30:01 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
Callum Gibson
Created:
2007-11-28 00:30:01 UTC
Size:
13.86 KB
patch
obsolete
>--- usr.bin/ipcrm/Makefile.orig 2007-11-26 11:16:27.000000000 +1100 >+++ usr.bin/ipcrm/Makefile 2007-11-26 12:02:24.000000000 +1100 >@@ -1,5 +1,7 @@ > # $FreeBSD: src/usr.bin/ipcrm/Makefile,v 1.6 2002/02/08 22:31:40 markm Exp $ > > PROG= ipcrm >+DPADD= ${LIBKVM} >+LDADD= -lkvm > > .include <bsd.prog.mk> >--- usr.bin/ipcrm/ipcrm.c.orig 2002-09-05 09:29:02.000000000 +1000 >+++ usr.bin/ipcrm/ipcrm.c 2007-11-26 13:32:33.000000000 +1100 >@@ -32,23 +32,107 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD: src/usr.bin/ipcrm/ipcrm.c,v 1.11 2002/09/04 23:29:02 dwmalone Exp $"); > >+#include <sys/types.h> >+#include <sys/sysctl.h> >+#include <sys/cdefs.h> >+#define _KERNEL >+#include <sys/ipc.h> >+#include <sys/msg.h> >+#include <sys/sem.h> >+#include <sys/shm.h> >+#undef _KERNEL > #include <ctype.h> > #include <err.h> > #include <signal.h> > #include <stdio.h> > #include <stdlib.h> > #include <unistd.h> >-#include <sys/types.h> >-#include <sys/ipc.h> >-#include <sys/msg.h> >-#include <sys/sem.h> >-#include <sys/shm.h> >+#include <assert.h> >+#include <limits.h> >+#include <fcntl.h> >+#include <nlist.h> >+#include <kvm.h> > > #define IPC_TO_STR(x) (x == 'Q' ? "msq" : (x == 'M' ? "shm" : "sem")) > #define IPC_TO_STRING(x) (x == 'Q' ? "message queue" : \ >- (x == 'M' ? "shared memory segment" : "semaphore")) >+ (x == 'M' ? "shared memory segment" : "semaphore")) > >-int signaled; >+/* Copied from ipcs/ipcs.c */ >+/* SysCtlGatherStruct structure. */ >+struct scgs_vector { >+ const char *sysctl; >+ off_t offset; >+ size_t size; >+}; >+ >+static struct semid_kernel *sema; >+static struct seminfo seminfo; >+static struct msginfo msginfo; >+static struct msqid_kernel *msqids; >+static struct shminfo shminfo; >+static struct shmid_kernel *shmsegs; >+ >+void kget(int idx, void *addr, size_t size); >+void sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vec); >+ >+static struct nlist symbols[] = { >+ {"sema"}, >+#define X_SEMA 0 >+ {"seminfo"}, >+#define X_SEMINFO 1 >+ {"msginfo"}, >+#define X_MSGINFO 2 >+ {"msqids"}, >+#define X_MSQIDS 3 >+ {"shminfo"}, >+#define X_SHMINFO 4 >+ {"shmsegs"}, >+#define X_SHMSEGS 5 >+ {NULL} >+}; >+ >+#define SHMINFO_XVEC \ >+ X(shmmax, sizeof(int)) \ >+ X(shmmin, sizeof(int)) \ >+ X(shmmni, sizeof(int)) \ >+ X(shmseg, sizeof(int)) \ >+ X(shmall, sizeof(int)) >+ >+#define SEMINFO_XVEC \ >+ X(semmap, sizeof(int)) \ >+ X(semmni, sizeof(int)) \ >+ X(semmns, sizeof(int)) \ >+ X(semmnu, sizeof(int)) \ >+ X(semmsl, sizeof(int)) \ >+ X(semopm, sizeof(int)) \ >+ X(semume, sizeof(int)) \ >+ X(semusz, sizeof(int)) \ >+ X(semvmx, sizeof(int)) \ >+ X(semaem, sizeof(int)) >+ >+#define MSGINFO_XVEC \ >+ X(msgmax, sizeof(int)) \ >+ X(msgmni, sizeof(int)) \ >+ X(msgmnb, sizeof(int)) \ >+ X(msgtql, sizeof(int)) \ >+ X(msgssz, sizeof(int)) \ >+ X(msgseg, sizeof(int)) >+ >+#define X(a, b) { "kern.ipc." #a, __offsetof(TYPEC, a), (b) }, >+#define TYPEC struct shminfo >+struct scgs_vector shminfo_scgsv[] = { SHMINFO_XVEC { NULL } }; >+#undef TYPEC >+#define TYPEC struct seminfo >+struct scgs_vector seminfo_scgsv[] = { SEMINFO_XVEC { NULL } }; >+#undef TYPEC >+#define TYPEC struct msginfo >+struct scgs_vector msginfo_scgsv[] = { MSGINFO_XVEC { NULL } }; >+#undef TYPEC >+#undef X >+ >+static int errflg; >+static int signaled; >+static int use_sysctl = 1; > > void usage(void); > int msgrm(key_t, int); >@@ -56,7 +140,8 @@ > int semrm(key_t, int); > void not_configured(int); > >-void usage(void) >+void >+usage(void) > { > fprintf(stderr, "%s\n%s\n", > "usage: ipcrm [-q msqid] [-m shmid] [-s semid]", >@@ -64,109 +149,302 @@ > exit(1); > } > >-int msgrm(key_t key, int id) >+int >+msgrm(key_t key, int id) >+{ >+ if (key) { >+ id = msgget(key, 0); >+ if (id == -1) >+ return -1; >+ } >+ if (id == -1) { >+ struct msqid_kernel *kxmsqids; >+ size_t kxmsqids_len; >+ int num; >+ >+ kget(X_MSGINFO, &msginfo, sizeof(msginfo)); >+ kxmsqids_len = sizeof(struct msqid_kernel) * msginfo.msgmni; >+ kxmsqids = malloc(kxmsqids_len); >+ kget(X_MSQIDS, kxmsqids, kxmsqids_len); >+ num = msginfo.msgmni; >+ while (num-- && !signaled) >+ if (kxmsqids[num].u.msg_qbytes != 0) { >+ id = IXSEQ_TO_IPCID(num, kxmsqids[num].u.msg_perm); >+ if (msgctl(id, IPC_RMID, NULL) < 0) { >+ warn("msqid(%d): ", id); >+ errflg++; >+ } >+ } >+ return signaled ? -1 : 0; /* errors maybe handled above */ >+ } >+ return msgctl(id, IPC_RMID, NULL); >+} >+ >+int >+shmrm(key_t key, int id) >+{ >+ if (key) { >+ id = shmget(key, 0, 0); >+ if (id == -1) >+ return -1; >+ } >+ if (id == -1) { >+ struct shmid_kernel *kxshmids; >+ size_t kxshmids_len; >+ int num; >+ >+ kget(X_SHMINFO, &shminfo, sizeof(shminfo)); >+ kxshmids_len = sizeof(struct shmid_kernel) * shminfo.shmmni; >+ kxshmids = malloc(kxshmids_len); >+ kget(X_SHMSEGS, kxshmids, kxshmids_len); >+ num = shminfo.shmmni; >+ while (num-- && !signaled) >+ if (kxshmids[num].u.shm_perm.mode & 0x0800) { >+ id = IXSEQ_TO_IPCID(num, kxshmids[num].u.shm_perm); >+ if (shmctl(id, IPC_RMID, NULL) < 0) { >+ warn("shmid(%d): ", id); >+ errflg++; >+ } >+ } >+ return signaled ? -1 : 0; /* errors maybe handled above */ >+ } >+ return shmctl(id, IPC_RMID, NULL); >+} >+ >+int >+semrm(key_t key, int id) > { >- if (key) { >- id = msgget(key, 0); >- if (id == -1) >- return -1; >- } >- return msgctl(id, IPC_RMID, NULL); >-} >- >-int shmrm(key_t key, int id) >-{ >- if (key) { >- id = shmget(key, 0, 0); >- if (id == -1) >- return -1; >- } >- return shmctl(id, IPC_RMID, NULL); >-} >- >-int semrm(key_t key, int id) >-{ >- union semun arg; >- >- if (key) { >- id = semget(key, 0, 0); >- if (id == -1) >- return -1; >- } >- return semctl(id, 0, IPC_RMID, arg); >-} >- >-void not_configured(int signo __unused) >-{ >- signaled++; >-} >- >-int main(int argc, char *argv[]) >-{ >- int c, result, errflg, target_id; >- key_t target_key; >- >- errflg = 0; >- signal(SIGSYS, not_configured); >- while ((c = getopt(argc, argv, ":q:m:s:Q:M:S:")) != -1) { >- >- signaled = 0; >- switch (c) { >- case 'q': >- case 'm': >- case 's': >- target_id = atoi(optarg); >- if (c == 'q') >- result = msgrm(0, target_id); >- else if (c == 'm') >- result = shmrm(0, target_id); >- else >- result = semrm(0, target_id); >- if (result < 0) { >- errflg++; >- if (!signaled) >- warn("%sid(%d): ", IPC_TO_STR(toupper(c)), target_id); >- else >- warnx("%ss are not configured in the running kernel", >- IPC_TO_STRING(toupper(c))); >- } >- break; >- case 'Q': >- case 'M': >- case 'S': >- target_key = atol(optarg); >- if (target_key == IPC_PRIVATE) { >- warnx("can't remove private %ss", IPC_TO_STRING(c)); >- continue; >- } >- if (c == 'Q') >- result = msgrm(target_key, 0); >- else if (c == 'M') >- result = shmrm(target_key, 0); >- else >- result = semrm(target_key, 0); >- if (result < 0) { >- errflg++; >- if (!signaled) >- warn("%ss(%ld): ", IPC_TO_STR(c), target_key); >- else >- warnx("%ss are not configured in the running kernel", >- IPC_TO_STRING(c)); >- } >- break; >- case ':': >- fprintf(stderr, "option -%c requires an argument\n", optopt); >- usage(); >- case '?': >- fprintf(stderr, "unrecognized option: -%c\n", optopt); >- usage(); >- } >- } >- >- if (optind != argc) { >- fprintf(stderr, "unknown argument: %s\n", argv[optind]); >- usage(); >- } >- exit(errflg); >+ union semun arg; >+ >+ if (key) { >+ id = semget(key, 0, 0); >+ if (id == -1) >+ return -1; >+ } >+ if (id == -1) { >+ struct semid_kernel *kxsema; >+ size_t kxsema_len; >+ int num; >+ >+ kget(X_SEMINFO, &seminfo, sizeof(seminfo)); >+ kxsema_len = sizeof(struct semid_kernel) * seminfo.semmni; >+ kxsema = malloc(kxsema_len); >+ kget(X_SEMA, kxsema, kxsema_len); >+ num = seminfo.semmni; >+ while (num-- && !signaled) >+ if ((kxsema[num].u.sem_perm.mode & SEM_ALLOC) != 0) { >+ id = IXSEQ_TO_IPCID(num, kxsema[num].u.sem_perm); >+ if (semctl(id, IPC_RMID, NULL) < 0) { >+ warn("semid(%d): ", id); >+ errflg++; >+ } >+ } >+ return signaled ? -1 : 0; /* errors maybe handled above */ >+ } >+ return semctl(id, 0, IPC_RMID, arg); >+} >+ >+void >+not_configured(int signo __unused) >+{ >+ signaled++; >+} >+ >+int >+main(int argc, char *argv[]) >+{ >+ int c, result, target_id; >+ key_t target_key; >+ >+ errflg = 0; >+ signal(SIGSYS, not_configured); >+ while ((c = getopt(argc, argv, ":q:m:s:Q:M:S:y")) != -1) { >+ >+ signaled = 0; >+ switch (c) { >+ case 'q': >+ case 'm': >+ case 's': >+ target_id = atoi(optarg); >+ if (c == 'q') >+ result = msgrm(0, target_id); >+ else if (c == 'm') >+ result = shmrm(0, target_id); >+ else >+ result = semrm(0, target_id); >+ if (result < 0) { >+ errflg++; >+ if (!signaled) >+ warn("%sid(%d): ", IPC_TO_STR(toupper(c)), target_id); >+ else >+ warnx("%ss are not configured in the running kernel", >+ IPC_TO_STRING(toupper(c))); >+ } >+ break; >+ case 'Q': >+ case 'M': >+ case 'S': >+ target_key = atol(optarg); >+ if (target_key == IPC_PRIVATE) { >+ warnx("can't remove private %ss", IPC_TO_STRING(c)); >+ continue; >+ } >+ if (c == 'Q') >+ result = msgrm(target_key, 0); >+ else if (c == 'M') >+ result = shmrm(target_key, 0); >+ else >+ result = semrm(target_key, 0); >+ if (result < 0) { >+ errflg++; >+ if (!signaled) >+ warn("%ss(%ld): ", IPC_TO_STR(c), target_key); >+ else >+ warnx("%ss are not configured in the running kernel", >+ IPC_TO_STRING(c)); >+ } >+ break; >+ case 'y': >+ use_sysctl = 0; >+ break; >+ case ':': >+ fprintf(stderr, "option -%c requires an argument\n", optopt); >+ usage(); >+ case '?': >+ fprintf(stderr, "unrecognized option: -%c\n", optopt); >+ usage(); >+ } >+ } >+ >+ if (optind != argc) { >+ fprintf(stderr, "unknown argument: %s\n", argv[optind]); >+ usage(); >+ } >+ exit(errflg); >+} >+ >+/* The remainder is from ipcs/ipcs.c */ >+void >+sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vecarr) >+{ >+ struct scgs_vector *xp; >+ size_t tsiz; >+ int rv; >+ >+ for (xp = vecarr; xp->sysctl != NULL; xp++) { >+ assert(xp->offset <= size); >+ tsiz = xp->size; >+ rv = sysctlbyname(xp->sysctl, (char *)addr + xp->offset, >+ &tsiz, NULL, 0); >+ if (rv == -1) >+ err(1, "sysctlbyname: %s", xp->sysctl); >+ if (tsiz != xp->size) >+ errx(1, "%s size mismatch (expected %d, got %d)", >+ xp->sysctl, xp->size, tsiz); >+ } >+} >+ >+void >+kget(int idx, void *addr, size_t size) >+{ >+ char *symn; /* symbol name */ >+ size_t tsiz; >+ int rv; >+ unsigned long kaddr; >+ const char *sym2sysctl[] = { /* symbol to sysctl name table */ >+ "kern.ipc.sema", >+ "kern.ipc.seminfo", >+ "kern.ipc.msginfo", >+ "kern.ipc.msqids", >+ "kern.ipc.shminfo", >+ "kern.ipc.shmsegs" }; >+ >+ assert((unsigned)idx <= sizeof(sym2sysctl) / sizeof(*sym2sysctl)); >+ if (!use_sysctl) { >+ kvm_t *kd; >+ char kvmoferr[_POSIX2_LINE_MAX]; /* Error buf for kvm_openfiles. */ >+ char *core = NULL, *namelist = NULL; >+ >+ kd = kvm_openfiles(namelist, core, NULL, O_RDONLY, kvmoferr); >+ if (kd == NULL) >+ errx(1, "kvm_openfiles: %s", kvmoferr); >+ switch (kvm_nlist(kd, symbols)) { >+ case 0: >+ break; >+ case -1: >+ errx(1, "unable to read kernel symbol table"); >+ default: >+#ifdef notdef /* they'll be told more civilly later */ >+ warnx("nlist failed"); >+ for (i = 0; symbols[i].n_name != NULL; i++) >+ if (symbols[i].n_value == 0) >+ warnx("symbol %s not found", >+ symbols[i].n_name); >+#endif >+ break; >+ } >+ symn = symbols[idx].n_name; >+ if (*symn == '_') >+ symn++; >+ if (symbols[idx].n_type == 0 || symbols[idx].n_value == 0) >+ errx(1, "symbol %s undefined", symn); >+ /* >+ * For some symbols, the value we retrieve is >+ * actually a pointer; since we want the actual value, >+ * we have to manually dereference it. >+ */ >+ switch (idx) { >+ case X_MSQIDS: >+ tsiz = sizeof(msqids); >+ rv = kvm_read(kd, symbols[idx].n_value, >+ &msqids, tsiz); >+ kaddr = (u_long)msqids; >+ break; >+ case X_SHMSEGS: >+ tsiz = sizeof(shmsegs); >+ rv = kvm_read(kd, symbols[idx].n_value, >+ &shmsegs, tsiz); >+ kaddr = (u_long)shmsegs; >+ break; >+ case X_SEMA: >+ tsiz = sizeof(sema); >+ rv = kvm_read(kd, symbols[idx].n_value, >+ &sema, tsiz); >+ kaddr = (u_long)sema; >+ break; >+ default: >+ rv = tsiz = 0; >+ kaddr = symbols[idx].n_value; >+ break; >+ } >+ if ((unsigned)rv != tsiz) >+ errx(1, "%s: %s", symn, kvm_geterr(kd)); >+ if ((unsigned)kvm_read(kd, kaddr, addr, size) != size) >+ errx(1, "%s: %s", symn, kvm_geterr(kd)); >+ kvm_close(kd); >+ } else { >+ switch (idx) { >+ case X_SHMINFO: >+ sysctlgatherstruct(addr, size, shminfo_scgsv); >+ break; >+ case X_SEMINFO: >+ sysctlgatherstruct(addr, size, seminfo_scgsv); >+ break; >+ case X_MSGINFO: >+ sysctlgatherstruct(addr, size, msginfo_scgsv); >+ break; >+ default: >+ tsiz = size; >+ rv = sysctlbyname(sym2sysctl[idx], addr, &tsiz, >+ NULL, 0); >+ if (rv == -1) >+ err(1, "sysctlbyname: %s", sym2sysctl[idx]); >+ if (tsiz != size) >+ errx(1, "%s size mismatch " >+ "(expected %d, got %d)", >+ sym2sysctl[idx], size, tsiz); >+ break; >+ } >+ } > } > >--- usr.bin/ipcrm/ipcrm.1.orig 2004-07-03 08:22:25.000000000 +1000 >+++ usr.bin/ipcrm/ipcrm.1 2007-11-26 13:07:19.000000000 +1100 >@@ -52,16 +52,17 @@ > .It Fl q Ar msqid > Remove the message queue associated with the id > .Ar msqid >-from the system. >+from the system. If msqid is -1 then attempt to remove all message queues. > .It Fl m Ar shmid > Mark the shared memory segment associated with id > .Ar shmid > for removal. > This marked segment will be destroyed after the last detach. >+If shmid is -1 then attempt to remove all shared memory segments. > .It Fl s Ar semid > Remove the semaphore set associated with id > .Ar semid >-from the system. >+from the system. If semid is -1 then attempt to remove all semaphores. > .It Fl Q Ar msgkey > Remove the message queue associated with key > .Ar msgkey >@@ -75,6 +76,19 @@ > Remove the semaphore set associated with key > .Ar semkey > from the system. >+.It Fl y >+Use the >+.Xr kvm 3 >+interface instead of the >+.Xr sysctl 3 >+interface to extract the required information. >+If >+.Nm >+is to operate on the running system, >+using >+.Xr kvm 3 >+will require read privileges to >+.Pa /dev/kmem . > .El > .Pp > The identifiers and keys associated with these System V IPC objects can be
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 118292
: 82693