From 7c896efff5612aee15983b736554bb347eed76da Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Fri, 7 Nov 2014 21:40:57 +0300 Subject: [PATCH] page-xfer: receive information about presence of a parent from a page server (v2) We need to know this to insert holes. Currently xfer->parent isn't initialized for remote sessions. In most cases it has a non-zero value, so generate_iovs() is called with has_parent = true. bash test/zdtm.sh -p -P -i 3 ns/transition/fork (00.000106) Error (sysctl.c:194): Can't open sysctl net/ipv4/tcp_wmem: No such file or directory (00.017048) 420: Error (image.c:231): Unable to open pagemap-420.img: No such file or directory (00.017065) 420: Error (image.c:231): Unable to open pages-420.img: No such file or directory (00.017090) 420: Error (page-read.c:73): No parent for snapshot pagemap (00.017290) 86: Error (cr-restore.c:1185): 420 exited, status=1 (00.017317) Error (cr-restore.c:1831): Restoring FAILED. v2: add a new command to open a page server. It's required to save backward compatibility. If someone tries to use an old version of page server, he will get an error. Reported-by: Mr Jenkins Signed-off-by: Andrey Vagin Signed-off-by: Pavel Emelyanov --- page-xfer.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/page-xfer.c b/page-xfer.c index 86e26d87a..1a1fc000d 100644 --- a/page-xfer.c +++ b/page-xfer.c @@ -40,6 +40,7 @@ static int open_page_local_xfer(struct page_xfer *xfer, int fd_type, long id); #define PS_IOV_ADD 1 #define PS_IOV_HOLE 2 #define PS_IOV_OPEN 3 +#define PS_IOV_OPEN2 4 #define PS_IOV_FLUSH 0x1023 #define PS_IOV_FLUSH_N_CLOSE 0x1024 @@ -79,7 +80,8 @@ static void page_server_close(void) cxfer.loc_xfer.close(&cxfer.loc_xfer); } -static int page_server_open(struct page_server_iov *pi) +static void close_page_xfer(struct page_xfer *xfer); +static int page_server_open(int sk, struct page_server_iov *pi) { int type; long id; @@ -94,6 +96,17 @@ static int page_server_open(struct page_server_iov *pi) return -1; cxfer.dst_id = pi->dst_id; + + if (sk >= 0) { + char has_parent = !!cxfer.loc_xfer.parent; + + if (write(sk, &has_parent, 1) != 1) { + pr_perror("Unable to send reponse"); + close_page_xfer(&cxfer.loc_xfer); + return -1; + } + } + return 0; } @@ -101,7 +114,7 @@ static int prep_loc_xfer(struct page_server_iov *pi) { if (cxfer.dst_id != pi->dst_id) { pr_warn("Deprecated IO w/o open\n"); - return page_server_open(pi); + return page_server_open(-1, pi); } else return 0; } @@ -192,7 +205,10 @@ static int page_server_serve(int sk) switch (pi.cmd) { case PS_IOV_OPEN: - ret = page_server_open(&pi); + ret = page_server_open(-1, &pi); + break; + case PS_IOV_OPEN2: + ret = page_server_open(sk, &pi); break; case PS_IOV_ADD: ret = page_server_add(sk, &pi); @@ -482,6 +498,7 @@ static void close_server_xfer(struct page_xfer *xfer) static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) { struct page_server_iov pi; + char has_parent; xfer->sk = page_server_sk; xfer->write_pagemap = write_pagemap_to_server; @@ -489,8 +506,9 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) xfer->write_hole = write_hole_to_server; xfer->close = close_server_xfer; xfer->dst_id = encode_pm_id(fd_type, id); + xfer->parent = NULL; - pi.cmd = PS_IOV_OPEN; + pi.cmd = PS_IOV_OPEN2; pi.dst_id = xfer->dst_id; pi.vaddr = 0; pi.nr_pages = 0; @@ -500,6 +518,14 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) return -1; } + if (read(xfer->sk, &has_parent, 1) != 1) { + pr_perror("The page server doesn't answer"); + return -1; + } + + if (has_parent) + xfer->parent = (void *) 1; /* This is required for generate_iovs() */ + return 0; }