Commit e929b437 authored by Stanislav Kinsbursky's avatar Stanislav Kinsbursky Committed by Pavel Emelyanov

ipc: message queues dump update for new kernel API

Signed-off-by: 's avatarStanislav Kinsbursky <skinsbursky@openvz.org>
Tested-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent a0b497e0
...@@ -37,22 +37,18 @@ ...@@ -37,22 +37,18 @@
#define MSGMAX 8192 #define MSGMAX 8192
#endif #endif
#ifndef MSG_STEAL #ifndef MSG_COPY
#define MSG_COPY 040000
#define MSG_STEAL 040000
/* message buffer for msgrcv in case of array calls */
struct msgbuf_a {
long mtype; /* type of message */
int msize; /* size of message */
char mtext[0]; /* message text */
};
#endif #endif
#ifndef MSG_SET #ifndef MSG_SET
#define MSG_SET 13 #define MSG_SET 13
#endif #endif
#ifndef MSG_SET_COPY
#define MSG_SET_COPY 14
#endif
#ifndef SEM_SET #ifndef SEM_SET
#define SEM_SET 20 #define SEM_SET 20
#endif #endif
...@@ -190,54 +186,58 @@ static void pr_info_ipc_msg_entry(const IpcMsgEntry *msg) ...@@ -190,54 +186,58 @@ static void pr_info_ipc_msg_entry(const IpcMsgEntry *msg)
msg->qbytes, msg->qnum); msg->qbytes, msg->qnum);
} }
static int dump_ipc_msg_queue_messages(int fd, const IpcMsgEntry *entry, size_t cbytes) static int dump_ipc_msg_queue_messages(int fd, const IpcMsgEntry *entry,
unsigned int msg_nr)
{ {
void *msg_array, *ptr; struct msgbuf *message;
size_t array_size; unsigned int msgmax;
int ret, msg_nr = 0; int ret, msg_cnt = 0;
struct sysctl_req req[] = {
/* { "kernel/msgmax", &msgmax, CTL_U32 },
* Here we allocate memory for struct msgbuf_a twice becase messages in { },
* array will be aligned by struct msgbuf_a. };
*/
array_size = entry->qnum * sizeof(struct msgbuf_a) * 2 + cbytes;
msg_array = ptr = xmalloc(array_size);
if (msg_array == NULL) {
pr_err("Failed to allocate memory for IPC messages\n");
return -ENOMEM;
}
ret = msgrcv(entry->desc->id, msg_array, array_size, 0, IPC_NOWAIT | MSG_STEAL); ret = sysctl_op(req, CTL_READ);
if (ret < 0) { if (ret < 0) {
pr_perror("Failed to receive IPC messages array"); pr_err("Failed to read max IPC message size\n");
goto err; goto err;
} }
while (msg_nr < entry->qnum) { msgmax += sizeof(struct msgbuf);
struct msgbuf_a *data = ptr; message = xmalloc(msgmax);
if (message == NULL) {
pr_err("Failed to allocate memory for IPC message\n");
return -ENOMEM;
}
for (msg_cnt = 0; msg_cnt < msg_nr; msg_cnt++) {
IpcMsg msg = IPC_MSG__INIT; IpcMsg msg = IPC_MSG__INIT;
msg.msize = data->msize; ret = msgrcv(entry->desc->id, message, msgmax, msg_cnt, IPC_NOWAIT | MSG_COPY);
msg.mtype = data->mtype; if (ret < 0) {
pr_perror("Failed to copy IPC message");
goto err;
}
pr_info_ipc_msg(msg_nr, &msg); msg.msize = ret;
msg.mtype = message->mtype;
pr_info_ipc_msg(msg_cnt, &msg);
ret = pb_write_one(fd, &msg, PB_IPCNS_MSG); ret = pb_write_one(fd, &msg, PB_IPCNS_MSG);
if (ret < 0) { if (ret < 0) {
pr_err("Failed to write IPC message header\n"); pr_err("Failed to write IPC message header\n");
break; break;
} }
ret = write_img_buf(fd, data->mtext, round_up(msg.msize, sizeof(u64))); ret = write_img_buf(fd, message->mtext, round_up(msg.msize, sizeof(u64)));
if (ret < 0) { if (ret < 0) {
pr_err("Failed to write IPC message data\n"); pr_err("Failed to write IPC message data\n");
break; break;
} }
msg_nr++;
ptr += round_up(data->msize + sizeof(struct msgbuf_a), sizeof(struct msgbuf_a));
} }
ret = 0; ret = 0;
err: err:
xfree(msg_array); xfree(message);
return ret; return ret;
} }
...@@ -259,7 +259,7 @@ static int dump_ipc_msg_queue(int fd, int id, const struct msqid_ds *ds) ...@@ -259,7 +259,7 @@ static int dump_ipc_msg_queue(int fd, int id, const struct msqid_ds *ds)
pr_err("Failed to write IPC message queue\n"); pr_err("Failed to write IPC message queue\n");
return ret; return ret;
} }
return dump_ipc_msg_queue_messages(fd, &msg, ds->msg_cbytes); return dump_ipc_msg_queue_messages(fd, &msg, ds->msg_qnum);
} }
static int dump_ipc_msg(int fd) static int dump_ipc_msg(int fd)
...@@ -291,7 +291,7 @@ static int dump_ipc_msg(int fd) ...@@ -291,7 +291,7 @@ static int dump_ipc_msg(int fd)
slot++; slot++;
} }
if (slot != info.msgpool) { if (slot != info.msgpool) {
pr_err("Failed to collect %d (only %d succeeded)\n", info.msgpool, slot); pr_err("Failed to collect %d message queues (only %d succeeded)\n", info.msgpool, slot);
return -EFAULT; return -EFAULT;
} }
return info.msgpool; return info.msgpool;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment