[CRIU] [PATCH] ipc: message queues dump update for new kernel API

Kinsbursky Stanislav skinsbursky at openvz.org
Wed Sep 19 09:42:29 EDT 2012


From: Stanislav Kinsbursky <skinsbursky at openvz.org>

Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
 ipc_ns.c |   76 +++++++++++++++++++++++++++++++-------------------------------
 1 files changed, 38 insertions(+), 38 deletions(-)
-------------- next part --------------
diff --git a/ipc_ns.c b/ipc_ns.c
index 76c1f35..0d0b039 100644
--- a/ipc_ns.c
+++ b/ipc_ns.c
@@ -37,22 +37,18 @@
 #define MSGMAX			8192
 #endif
 
-#ifndef MSG_STEAL
-
-#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 */
-};
+#ifndef MSG_COPY
+#define MSG_COPY		040000
 #endif
 
 #ifndef MSG_SET
 #define MSG_SET			13
 #endif
 
+#ifndef MSG_SET_COPY
+#define MSG_SET_COPY		14
+#endif
+
 #ifndef SEM_SET
 #define SEM_SET			20
 #endif
@@ -190,54 +186,58 @@ static void pr_info_ipc_msg_entry(const IpcMsgEntry *msg)
 		       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;
-	size_t array_size;
-	int ret, msg_nr = 0;
-
-	/*
-	 * 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;
-	}
+	struct msgbuf *message;
+	unsigned int msgmax;
+	int ret, msg_cnt = 0;
+	struct sysctl_req req[] = {
+		{ "kernel/msgmax", &msgmax, CTL_U32 },
+		{ },
+	};
 
-	ret = msgrcv(entry->desc->id, msg_array, array_size, 0, IPC_NOWAIT | MSG_STEAL);
+	ret = sysctl_op(req, CTL_READ);
 	if (ret < 0) {
-		pr_perror("Failed to receive IPC messages array");
+		pr_err("Failed to read max IPC message size\n");
 		goto err;
 	}
 
-	while (msg_nr < entry->qnum) {
-		struct msgbuf_a *data = ptr;
+	msgmax += sizeof(struct msgbuf);
+	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;
 
-		msg.msize = data->msize;
-		msg.mtype = data->mtype;
+		ret = msgrcv(entry->desc->id, message, msgmax, msg_cnt, IPC_NOWAIT | MSG_COPY);
+		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);
 		if (ret < 0) {
 			pr_err("Failed to write IPC message header\n");
 			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) {
 			pr_err("Failed to write IPC message data\n");
 			break;
 		}
-		msg_nr++;
-		ptr += round_up(data->msize + sizeof(struct msgbuf_a), sizeof(struct msgbuf_a));
 	}
 	ret = 0;
 err:
-	xfree(msg_array);
+	xfree(message);
 	return ret;
 }
 
@@ -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");
 		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)
@@ -291,7 +291,7 @@ static int dump_ipc_msg(int fd)
 			slot++;
 	}
 	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 info.msgpool;


More information about the CRIU mailing list