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

Pavel Emelyanov xemul at virtuozzo.com
Tue Mar 22 05:22:32 PDT 2016


On 03/21/2016 03:48 PM, Adrian Reber wrote:
> From: Adrian Reber <areber at redhat.com>

Adrian, please, meet Mike. He's from IBM research center and he's also
interested in playing with the UFFD stuff.

Maik, this is Adrian. He's been playing with UFFD for quite a while and
already have some patches merged in criu-dev branch.

> 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;
> +}
> 



More information about the CRIU mailing list