[CRIU] [PATCH] Move TCP server/client setup code util.c

Adrian Reber adrian at lisas.de
Mon Mar 21 05:48:11 PDT 2016


From: Adrian Reber <areber at redhat.com>

The page server already knows how to create a TCP server and client. The
code has been hidden behind static-s in page-xfer.c. This commit moves
the common TCP server/client code to util.c to be able to also use it
in the upcoming remote lazy-server/lazy-client userfaultfd enhanced criu.

Signed-off-by: Adrian Reber <areber at redhat.com>
---
 criu/include/util.h |   4 ++
 criu/page-xfer.c    | 113 ++++-----------------------------------------
 criu/util.c         | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+), 103 deletions(-)

diff --git a/criu/include/util.h b/criu/include/util.h
index ac5d9a3..2d6fa59 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -283,4 +283,8 @@ char *xsprintf(const char *fmt, ...)
 
 void print_data(unsigned long addr, unsigned char *data, size_t size);
 
+int setup_tcp_server(char *type);
+int run_tcp_server(bool daemon_mode, int *ask, int cfd, int sk);
+int setup_tcp_client(char *addr);
+
 #endif /* __CR_UTIL_H__ */
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index 143e898..2ebe8cc 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -285,28 +285,11 @@ static int page_server_serve(int sk)
 	return ret;
 }
 
-static int get_sockaddr_in(struct sockaddr_in *addr)
-{
-	memset(addr, 0, sizeof(*addr));
-	addr->sin_family = AF_INET;
-
-	if (!opts.addr)
-		addr->sin_addr.s_addr = INADDR_ANY;
-	else if (!inet_aton(opts.addr, &addr->sin_addr)) {
-		pr_perror("Bad page server address");
-		return -1;
-	}
-
-	addr->sin_port = opts.port;
-	return 0;
-}
-
 int cr_page_server(bool daemon_mode, int cfd)
 {
-	int sk = -1, ask = -1, ret;
-	struct sockaddr_in saddr, caddr;
-	socklen_t slen = sizeof(saddr);
-	socklen_t clen = sizeof(caddr);
+	int ask = -1;
+	int sk = -1;
+	int ret;
 
 	up_page_ids_base();
 
@@ -317,70 +300,13 @@ int cr_page_server(bool daemon_mode, int cfd)
 		goto no_server;
 	}
 
-	pr_info("Starting page server on port %u\n", (int)ntohs(opts.port));
-
-	sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-	if (sk < 0) {
-		pr_perror("Can't init page server");
+	sk = setup_tcp_server("page");
+	if (sk == -1)
 		return -1;
-	}
-
-	if (get_sockaddr_in(&saddr))
-		goto out;
-
-	if (bind(sk, (struct sockaddr *)&saddr, slen)) {
-		pr_perror("Can't bind page server");
-		goto out;
-	}
-
-	if (listen(sk, 1)) {
-		pr_perror("Can't listen on page server socket");
-		goto out;
-	}
-
-	/* Get socket port in case of autobind */
-	if (opts.port == 0) {
-		if (getsockname(sk, (struct sockaddr *)&saddr, &slen)) {
-			pr_perror("Can't get page server name");
-			goto out;
-		}
-
-		opts.port = ntohs(saddr.sin_port);
-		pr_info("Using %u port\n", opts.port);
-	}
-
 no_server:
-	if (daemon_mode) {
-		ret = cr_daemon(1, 0, &ask, cfd);
-		if (ret == -1) {
-			pr_err("Can't run in the background\n");
-			goto out;
-		}
-		if (ret > 0) { /* parent task, daemon started */
-			close_safe(&sk);
-			if (opts.pidfile) {
-				if (write_pidfile(ret) == -1) {
-					pr_perror("Can't write pidfile");
-					kill(ret, SIGKILL);
-					waitpid(ret, NULL, 0);
-					return -1;
-				}
-			}
-
-			return ret;
-		}
-	}
-
-	if (sk >= 0) {
-		ret = ask = accept(sk, (struct sockaddr *)&caddr, &clen);
-		if (ask < 0)
-			pr_perror("Can't accept connection to server");
-		else
-			pr_info("Accepted connection from %s:%u\n",
-					inet_ntoa(caddr.sin_addr),
-					(int)ntohs(caddr.sin_port));
-		close(sk);
-	}
+	ret = run_tcp_server(daemon_mode, &ask, cfd, sk);
+	if (ret != 0)
+		return ret;
 
 	if (ask >= 0)
 		ret = page_server_serve(ask);
@@ -390,17 +316,12 @@ no_server:
 
 	return ret;
 
-out:
-	close(sk);
-	return -1;
 }
 
 static int page_server_sk = -1;
 
 int connect_to_page_server(void)
 {
-	struct sockaddr_in saddr;
-
 	if (!opts.use_page_server)
 		return 0;
 
@@ -410,23 +331,9 @@ int connect_to_page_server(void)
 		goto out;
 	}
 
-	pr_info("Connecting to server %s:%u\n",
-			opts.addr, (int)ntohs(opts.port));
-
-	page_server_sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-	if (page_server_sk < 0) {
-		pr_perror("Can't create socket");
-		return -1;
-	}
-
-	if (get_sockaddr_in(&saddr))
-		return -1;
-
-	if (connect(page_server_sk, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
-		pr_perror("Can't connect to server");
+	page_server_sk = setup_tcp_client(opts.addr);
+	if (page_server_sk == -1)
 		return -1;
-	}
-
 out:
 	/*
 	 * CORK the socket at the very beginning. As per ANK
diff --git a/criu/util.c b/criu/util.c
index cbc525d..8207821 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -14,6 +14,7 @@
 #include <sys/sendfile.h>
 #include <fcntl.h>
 #include <poll.h>
+#include <arpa/inet.h>
 #include <sys/mount.h>
 #include <sys/param.h>
 #include <sys/types.h>
@@ -1074,3 +1075,131 @@ void print_data(unsigned long addr, unsigned char *data, size_t size)
 		pr_msg("|\n");
 	}
 }
+
+static int get_sockaddr_in(struct sockaddr_in *addr, char *host)
+{
+	memset(addr, 0, sizeof(*addr));
+	addr->sin_family = AF_INET;
+
+	if (!host)
+		addr->sin_addr.s_addr = INADDR_ANY;
+	else if (!inet_aton(host, &addr->sin_addr)) {
+		pr_perror("Bad server address");
+		return -1;
+	}
+
+	addr->sin_port = opts.port;
+	return 0;
+}
+
+int setup_tcp_server(char *type)
+{
+	int sk = -1;
+	struct sockaddr_in saddr;
+	socklen_t slen = sizeof(saddr);
+
+	pr_info("Starting %s server on port %u\n", type, (int)ntohs(opts.port));
+
+	sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+	if (sk < 0) {
+		pr_perror("Can't init %s server", type);
+		return -1;
+	}
+
+	if (get_sockaddr_in(&saddr, opts.addr))
+		goto out;
+
+	if (bind(sk, (struct sockaddr *)&saddr, slen)) {
+		pr_perror("Can't bind %s server", type);
+		goto out;
+	}
+
+	if (listen(sk, 1)) {
+		pr_perror("Can't listen on %s server socket", type);
+		goto out;
+	}
+
+	/* Get socket port in case of autobind */
+	if (opts.port == 0) {
+		if (getsockname(sk, (struct sockaddr *)&saddr, &slen)) {
+			pr_perror("Can't get %s server name", type);
+			goto out;
+		}
+
+		opts.port = ntohs(saddr.sin_port);
+		pr_info("Using %u port\n", opts.port);
+	}
+
+	return sk;
+out:
+	close(sk);
+	return -1;
+}
+
+int run_tcp_server(bool daemon_mode, int *ask, int cfd, int sk)
+{
+	int ret;
+	struct sockaddr_in caddr;
+	socklen_t clen = sizeof(caddr);
+
+	if (daemon_mode) {
+		ret = cr_daemon(1, 0, ask, cfd);
+		if (ret == -1) {
+			pr_err("Can't run in the background\n");
+			goto out;
+		}
+		if (ret > 0) { /* parent task, daemon started */
+			close_safe(&sk);
+			if (opts.pidfile) {
+				if (write_pidfile(ret) == -1) {
+					pr_perror("Can't write pidfile");
+					kill(ret, SIGKILL);
+					waitpid(ret, NULL, 0);
+					return -1;
+				}
+			}
+
+			return ret;
+		}
+	}
+
+	if (sk >= 0) {
+		ret = *ask = accept(sk, (struct sockaddr *)&caddr, &clen);
+		if (*ask < 0)
+			pr_perror("Can't accept connection to server");
+		else
+			pr_info("Accepted connection from %s:%u\n",
+					inet_ntoa(caddr.sin_addr),
+					(int)ntohs(caddr.sin_port));
+		close(sk);
+	}
+
+	return 0;
+out:
+	close(sk);
+	return -1;
+}
+
+int setup_tcp_client(char *addr)
+{
+	struct sockaddr_in saddr;
+	int sk;
+
+	pr_info("Connecting to server %s:%u\n", addr, (int)ntohs(opts.port));
+
+	sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+	if (sk < 0) {
+		pr_perror("Can't create socket");
+		return -1;
+	}
+
+	if (get_sockaddr_in(&saddr, addr))
+		return -1;
+
+	if (connect(sk, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
+		pr_perror("Can't connect to server");
+		return -1;
+	}
+
+	return sk;
+}
-- 
1.8.3.1



More information about the CRIU mailing list