summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Kerola2012-11-11 23:10:54 +0100
committerKarel Zak2012-11-23 14:58:22 +0100
commit35118dfc31ac15e14380c3773334b5b7c10b423f (patch)
tree1eb997209f43992d089cbdff892d42511f97516f
parentipcs: make individual semaphore id printing to use /proc (diff)
downloadkernel-qcow2-util-linux-35118dfc31ac15e14380c3773334b5b7c10b423f.tar.gz
kernel-qcow2-util-linux-35118dfc31ac15e14380c3773334b5b7c10b423f.tar.xz
kernel-qcow2-util-linux-35118dfc31ac15e14380c3773334b5b7c10b423f.zip
ipcs: clean up do_msg(), and add ipc_msg_get_info()
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
-rw-r--r--sys-utils/ipcs.c89
-rw-r--r--sys-utils/ipcutils.c114
-rw-r--r--sys-utils/ipcutils.h20
3 files changed, 178 insertions, 45 deletions
diff --git a/sys-utils/ipcs.c b/sys-utils/ipcs.c
index 7f44aaf6f..78bec7d5f 100644
--- a/sys-utils/ipcs.c
+++ b/sys-utils/ipcs.c
@@ -35,8 +35,8 @@ static void do_shm (char format);
static void print_shm (int id);
static void do_sem (char format);
static void print_sem (int id);
+static void do_msg (char format);
-void do_msg (char format);
void print_msg (int id);
static void __attribute__ ((__noreturn__)) usage(FILE * out)
@@ -433,23 +433,16 @@ static void do_sem (char format)
return;
}
-void do_msg (char format)
+static void do_msg (char format)
{
- int maxid, msqid, id;
- struct msqid_ds msgque;
- struct msginfo msginfo;
- struct ipc_perm *ipcp = &msgque.msg_perm;
struct passwd *pw;
- struct ipc_limits lim;
-
- maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo);
- if (maxid < 0) {
- printf (_("kernel not configured for message queues\n"));
- return;
- }
+ struct msg_data *msgds, *msgdsp;
switch (format) {
case LIMITS:
+ {
+ struct ipc_limits lim;
+
if (ipc_msg_get_limits(&lim))
return;
printf (_("------ Messages Limits --------\n"));
@@ -457,14 +450,20 @@ void do_msg (char format)
printf (_("max size of message (bytes) = %zu\n"), lim.msgmax);
printf (_("default max size of queue (bytes) = %d\n"), lim.msgmnb);
return;
-
+ }
case STATUS:
+ {
+ struct msginfo msginfo;
+ if (msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo) < 0) {
+ printf (_("kernel not configured for message queues\n"));
+ return;
+ }
printf (_("------ Messages Status --------\n"));
printf (_("allocated queues = %d\n"), msginfo.msgpool);
printf (_("used headers = %d\n"), msginfo.msgmap);
printf (_("used space = %d bytes\n"), msginfo.msgtql);
return;
-
+ }
case CREATOR:
printf (_("------ Message Queues Creators/Owners --------\n"));
printf ("%-10s %-10s %-10s %-10s %-10s %-10s\n",
@@ -491,56 +490,56 @@ void do_msg (char format)
break;
}
- for (id = 0; id <= maxid; id++) {
- msqid = msgctl (id, MSG_STAT, &msgque);
- if (msqid < 0)
- continue;
- if (format == CREATOR) {
- print_perms (msqid, ipcp);
+ /*
+ * Print data
+ */
+ if (ipc_msg_get_info(-1, &msgds) < 1)
+ return;
+ msgdsp = msgds;
+
+ for (msgdsp = msgds; msgdsp->next != NULL; msgdsp = msgdsp->next) {
+ if (format == CREATOR) {
+ ipc_print_perms(stdout, &msgdsp->msg_perm);
continue;
}
- pw = getpwuid(ipcp->uid);
+ pw = getpwuid(msgdsp->msg_perm.uid);
switch (format) {
case TIME:
if (pw)
- printf ("%-8d %-10.10s", msqid, pw->pw_name);
+ printf ("%-8d %-10.10s", msgdsp->msg_perm.id, pw->pw_name);
else
- printf ("%-8d %-10u", msqid, ipcp->uid);
- printf (" %-20.16s", msgque.msg_stime
- ? ctime(&msgque.msg_stime) + 4 : _("Not set"));
- printf (" %-20.16s", msgque.msg_rtime
- ? ctime(&msgque.msg_rtime) + 4 : _("Not set"));
- printf (" %-20.16s\n", msgque.msg_ctime
- ? ctime(&msgque.msg_ctime) + 4 : _("Not set"));
+ printf ("%-8d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid);
+ printf (" %-20.16s", msgdsp->q_stime
+ ? ctime(&msgdsp->q_stime) + 4 : _("Not set"));
+ printf (" %-20.16s", msgdsp->q_rtime
+ ? ctime(&msgdsp->q_rtime) + 4 : _("Not set"));
+ printf (" %-20.16s\n", msgdsp->q_ctime
+ ? ctime(&msgdsp->q_ctime) + 4 : _("Not set"));
break;
case PID:
if (pw)
- printf ("%-8d %-10.10s", msqid, pw->pw_name);
+ printf ("%-8d %-10.10s", msgdsp->msg_perm.id, pw->pw_name);
else
- printf ("%-8d %-10u", msqid, ipcp->uid);
+ printf ("%-8d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid);
printf (" %5d %5d\n",
- msgque.msg_lspid, msgque.msg_lrpid);
+ msgdsp->q_lspid, msgdsp->q_lrpid);
break;
default:
- printf( "0x%08x ",ipcp->KEY );
+ printf( "0x%08x ",msgdsp->msg_perm.key );
if (pw)
- printf ("%-10d %-10.10s", msqid, pw->pw_name);
+ printf ("%-10d %-10.10s", msgdsp->msg_perm.id, pw->pw_name);
else
- printf ("%-10d %-10u", msqid, ipcp->uid);
+ printf ("%-10d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid);
printf (" %-10o %-12ld %-12ld\n",
- ipcp->mode & 0777,
- /*
- * glibc-2.1.3 and earlier has unsigned
- * short. glibc-2.1.91 has variation between
- * unsigned short, unsigned long. Austin has
- * msgqnum_t
- */
- (long) msgque.msg_cbytes,
- (long) msgque.msg_qnum);
+ msgdsp->msg_perm.mode & 0777,
+ msgdsp->q_cbytes,
+ msgdsp->q_qnum);
break;
}
}
+
+ ipc_msg_free_info(msgds);
return;
}
diff --git a/sys-utils/ipcutils.c b/sys-utils/ipcutils.c
index 80148ee63..772863c54 100644
--- a/sys-utils/ipcutils.c
+++ b/sys-utils/ipcutils.c
@@ -356,6 +356,120 @@ void ipc_sem_free_info(struct sem_data *semds)
}
}
+int ipc_msg_get_info(int id, struct msg_data **msgds)
+{
+ FILE *f;
+ int i, maxid;
+ struct msg_data *p;
+ struct msqid_ds dummy;
+
+ p = *msgds = xcalloc(1, sizeof(struct msg_data));
+ p->next = NULL;
+
+ f = path_fopen("r", 0, _PATH_PROC_SYSV_MSG);
+ if (!f)
+ goto msg_fallback;
+
+ while (fgetc(f) != '\n') ; /* skip header */
+
+ while (feof(f) == 0) {
+ if (fscanf(f,
+ "%d %d %o %" SCNu64 " %" SCNu64 " %u %u %u %u %u %u %" SCNu64 " %" SCNu64 " %" SCNu64 "\n",
+ &p->msg_perm.key,
+ &p->msg_perm.id,
+ &p->msg_perm.mode,
+ &p->q_cbytes,
+ &p->q_qnum,
+ &p->q_lspid,
+ &p->q_lrpid,
+ &p->msg_perm.uid,
+ &p->msg_perm.gid,
+ &p->msg_perm.cuid,
+ &p->msg_perm.cgid,
+ &p->q_stime,
+ &p->q_rtime,
+ &p->q_ctime) != 14)
+ continue;
+
+ if (id > -1) {
+ /* ID specified */
+ if (id == p->msg_perm.id) {
+ i = 1;
+ break;
+ } else
+ continue;
+ }
+
+ p->next = xcalloc(1, sizeof(struct msg_data));
+ p = p->next;
+ p->next = NULL;
+ i++;
+ }
+
+ if (i == 0)
+ free(*msgds);
+ fclose(f);
+ return i;
+
+ /* Fallback; /proc or /sys file(s) missing. */
+ msg_fallback:
+ i = id < 0 ? 0 : id;
+
+ maxid = msgctl(id, MSG_STAT, &dummy);
+ if (maxid < 0)
+ return 0;
+
+ while (i <= maxid) {
+ int msgid;
+ struct msqid_ds msgseg;
+ struct ipc_perm *ipcp = &msgseg.msg_perm;
+
+ msgid = msgctl(id, MSG_STAT, &msgseg);
+ if (msgid < 0) {
+ if (-1 < id) {
+ free(*msgds);
+ return 0;
+ }
+ i++;
+ continue;
+ }
+
+ p->msg_perm.key = ipcp->KEY;
+ p->msg_perm.id = msgid;
+ p->msg_perm.mode = ipcp->mode;
+ p->q_cbytes = msgseg.msg_cbytes;
+ p->q_qnum = msgseg.msg_qnum;
+ p->q_lspid = msgseg.msg_lspid;
+ p->q_lrpid = msgseg.msg_lrpid;
+ p->msg_perm.uid = ipcp->uid;
+ p->msg_perm.gid = ipcp->gid;
+ p->msg_perm.cuid = ipcp->cuid;
+ p->msg_perm.cgid = ipcp->cgid;
+ p->q_stime = msgseg.msg_stime;
+ p->q_rtime = msgseg.msg_rtime;
+ p->q_ctime = msgseg.msg_ctime;
+
+ if (id < 0) {
+ p->next = xcalloc(1, sizeof(struct msg_data));
+ p = p->next;
+ p->next = NULL;
+ i++;
+ } else
+ return 1;
+ }
+
+ return i;
+}
+
+void ipc_msg_free_info(struct msg_data *msgds)
+{
+ while (msgds) {
+ struct msg_data *next = msgds->next;
+ free(msgds);
+ msgds = next;
+ }
+}
+
void ipc_print_perms(FILE *f, struct ipc_stat *is)
{
struct passwd *pw;
diff --git a/sys-utils/ipcutils.h b/sys-utils/ipcutils.h
index f50e03c61..28b35c136 100644
--- a/sys-utils/ipcutils.h
+++ b/sys-utils/ipcutils.h
@@ -154,4 +154,24 @@ struct sem_data {
extern int ipc_sem_get_info(int id, struct sem_data **semds);
extern void ipc_sem_free_info(struct sem_data *semds);
+/* See 'struct msg_queue' in kernel sources
+ */
+struct msg_data {
+ struct ipc_stat msg_perm;
+
+ time_t q_stime;
+ time_t q_rtime;
+ time_t q_ctime;
+ uint64_t q_cbytes;
+ uint64_t q_qnum;
+ uint64_t q_qbytes;
+ pid_t q_lspid;
+ pid_t q_lrpid;
+
+ struct msg_data *next;
+};
+
+extern int ipc_msg_get_info(int id, struct msg_data **msgds);
+extern void ipc_msg_free_info(struct msg_data *msgds);
+
#endif /* UTIL_LINUX_IPCUTILS_H */