[1/2] skqueue: Check for SCM-s in queue and abort the dump

Submitted by Pavel Emelianov on Nov. 22, 2016, 11:57 a.m.

Details

Message ID 5834329D.5000407@virtuozzo.com
State Accepted
Series "Don't loose scm messages from unix queues"
Commit 3af570950377851452244b97e320d06d03230656
Headers show

Commit Message

Pavel Emelianov Nov. 22, 2016, 11:57 a.m.
We can MSG_PEEK those and can dump the files easily. The
problem is in restore -- we need to first pass through all
the fdinfo openings before sending the descriptors out, but
by that time some sending sockets may have already closed :(

So for now just detect SCM-s in queue and abort the dump,
otherwise we'd just have them lost and the state spoiled.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/sk-queue.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/sk-queue.c b/criu/sk-queue.c
index d4140ba..7b1da2d 100644
--- a/criu/sk-queue.c
+++ b/criu/sk-queue.c
@@ -58,6 +58,24 @@  struct collect_image_info sk_queues_cinfo = {
 	.collect = collect_one_packet,
 };
 
+/*
+ * Maximum size of the control messages. XXX -- is there any
+ * way to get this value out of the kernel?
+ * */
+#define CMSG_MAX_SIZE	1024
+
+static int dump_packet_cmsg(struct msghdr *mh, SkPacketEntry *pe)
+{
+	struct cmsghdr *ch;
+
+	for (ch = CMSG_FIRSTHDR(mh); ch; ch = CMSG_NXTHDR(mh, ch)) {
+		pr_err("Control messages in queue, not supported\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 int dump_sk_queue(int sock_fd, int sock_id)
 {
 	SkPacketEntry pe = SK_PACKET_ENTRY__INIT;
@@ -108,6 +126,7 @@  int dump_sk_queue(int sock_fd, int sock_id)
 	pe.id_for = sock_id;
 
 	while (1) {
+		char cmsg[CMSG_MAX_SIZE];
 		struct iovec iov = {
 			.iov_base	= data,
 			.iov_len	= size,
@@ -115,6 +134,8 @@  int dump_sk_queue(int sock_fd, int sock_id)
 		struct msghdr msg = {
 			.msg_iov	= &iov,
 			.msg_iovlen	= 1,
+			.msg_control	= &cmsg,
+			.msg_controllen	= sizeof(cmsg),
 		};
 
 		ret = pe.length = recvmsg(sock_fd, &msg, MSG_DONTWAIT | MSG_PEEK);
@@ -140,6 +161,9 @@  int dump_sk_queue(int sock_fd, int sock_id)
 			goto err_set_sock;
 		}
 
+		if (dump_packet_cmsg(&msg, &pe))
+			goto err_set_sock;
+
 		ret = pb_write_one(img_from_set(glob_imgset, CR_FD_SK_QUEUES), &pe, PB_SK_QUEUES);
 		if (ret < 0) {
 			ret = -EIO;