[CRIU] [PATCH 4/5] check: Add check for remapable AIO rings

Pavel Emelyanov xemul at parallels.com
Fri Dec 19 05:03:00 PST 2014


Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 cr-check.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/cr-check.c b/cr-check.c
index d144e61..4eeb8a6 100644
--- a/cr-check.c
+++ b/cr-check.c
@@ -14,6 +14,7 @@
 #include <linux/if.h>
 #include <sys/ioctl.h>
 #include <termios.h>
+#include <sys/mman.h>
 
 #include "proc_parse.h"
 #include "sockets.h"
@@ -597,6 +598,80 @@ static int check_posix_timers(void)
 	return -1;
 }
 
+static unsigned long get_ring_len(unsigned long addr)
+{
+	FILE *maps;
+	char buf[256];
+
+	maps = fopen("/proc/self/maps", "r");
+	if (!maps) {
+		pr_perror("No maps proc file");
+		return 0;
+	}
+
+	while (fgets(buf, sizeof(buf), maps)) {
+		unsigned long start, end;
+		int r, tail;
+
+		r = sscanf(buf, "%lx-%lx %*s %*s %*s %*s %n\n", &start, &end, &tail);
+		if (r != 2) {
+			fclose(maps);
+			pr_err("Bad maps format %d.%d (%s)\n", r, tail, buf + tail);
+			return 0;
+		}
+
+		if (start == addr) {
+			fclose(maps);
+			if (strcmp(buf + tail, "/[aio] (deleted)\n"))
+				goto notfound;
+
+			return end - start;
+		}
+	}
+
+	fclose(maps);
+notfound:
+	pr_err("No AIO ring at expected location\n");
+	return 0;
+}
+
+static int check_aio_remap(void)
+{
+	aio_context_t ctx = 0;
+	unsigned long len;
+	void *naddr;
+	int r;
+
+	if (sys_io_setup(16, &ctx) < 0) {
+		pr_err("No AIO syscall");
+		return -1;
+	}
+
+	len = get_ring_len((unsigned long) ctx);
+	if (!len)
+		return -1;
+
+	naddr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
+	if (naddr == MAP_FAILED) {
+		pr_perror("Can't find place for new AIO ring\n");
+		return -1;
+	}
+
+	if (mremap((void *)ctx, len, len, MREMAP_FIXED | MREMAP_MAYMOVE, naddr) == MAP_FAILED) {
+		pr_perror("Can't remap AIO ring\n");
+		return -1;
+	}
+
+	ctx = (aio_context_t)naddr;
+	r = sys_io_getevents(ctx, 0, 1, NULL, NULL);
+	if (r < 0) {
+		pr_err("AIO remap doesn't work properly\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 int cr_check(void)
 {
 	struct ns_id ns = { .pid = getpid(), .nd = &mnt_ns_desc };
@@ -643,6 +718,7 @@ int cr_check(void)
 	ret |= check_tun();
 	ret |= check_timerfd();
 	ret |= check_mnt_id();
+	ret |= check_aio_remap();
 
 	if (!ret)
 		pr_msg("Looks good.\n");
-- 
1.8.4.2




More information about the CRIU mailing list