[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