[CRIU] [PATCH 1/5] crtools: added command-line options for reading images over network socket

Adrian Reber adrian at lisas.de
Tue Aug 21 11:20:45 EDT 2012


Signed-off-by: Adrian Reber <adrian at lisas.de>
---
 crtools.c         |   24 +++++++++++++++++++++++-
 image.c           |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/crtools.h |    2 ++
 3 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/crtools.c b/crtools.c
index d59934f..fd1c0df 100644
--- a/crtools.c
+++ b/crtools.c
@@ -56,8 +56,10 @@ int main(int argc, char *argv[])
 	int opt, idx;
 	int log_inited = 0;
 	int log_level = 0;
+	char *host = NULL;
+	int port = -1;
 
-	static const char short_opts[] = "dsf:t:hcD:o:n:vxV";
+	static const char short_opts[] = "dsf:t:hcD:o:n:l:vxV";
 
 	BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
 
@@ -76,6 +78,7 @@ int main(int argc, char *argv[])
 			{ "file", required_argument, 0, 'f' },
 			{ "images-dir", required_argument, 0, 'D' },
 			{ "log-file", required_argument, 0, 'o' },
+			{ "listen", required_argument, 0, 'l' },
 			{ "namespaces", required_argument, 0, 'n' },
 			{ "ext-unix-sk", no_argument, 0, 'x' },
 			{ "help", no_argument, 0, 'h' },
@@ -122,6 +125,17 @@ int main(int argc, char *argv[])
 				return -1;
 			log_inited = 1;
 			break;
+		case 'l':
+			host = strchr(optarg, ':');
+			if (!host)
+				goto usage;
+			/* port needs to be at least one digit long after ':' */
+			if (strlen(optarg) < strchr(optarg, ':') - optarg + 2)
+				goto usage;
+			port = atoi(strchr(optarg, ':') + 1);
+			optarg[strchr(optarg, ':') - optarg] = 0;
+			host = strdup(optarg);
+			break;
 		case 'n':
 			if (parse_ns_string(optarg))
 				return -1;
@@ -197,6 +211,11 @@ int main(int argc, char *argv[])
 		ret = cr_dump_tasks(pid, &opts);
 		break;
 	case 'r':
+		if (host && (port > 0)) {
+			ret = open_listen_socket(host, port);
+			ret = cr_restore_tasks(pid, &opts);
+			break;
+		}
 		if (!pid)
 			goto opt_pid_missing;
 		ret = cr_restore_tasks(pid, &opts);
@@ -261,6 +280,9 @@ usage:
 	pr_msg("  -h|--help             show this text\n");
 	pr_msg("  -V|--version          show version\n");
 
+	pr_msg("\nRestore options:\n");
+	pr_msg("  -l|--listen <ip:port>  listen on ip:port for incoming restore objects\n");
+
 	return -1;
 
 opt_pid_missing:
diff --git a/image.c b/image.c
index bc63427..2115412 100644
--- a/image.c
+++ b/image.c
@@ -1,5 +1,7 @@
 #include <unistd.h>
 #include <stdarg.h>
+#include <string.h>
+#include <netdb.h>
 #include "crtools.h"
 #include "image.h"
 #include "eventpoll.h"
@@ -215,6 +217,7 @@ struct cr_fdset *cr_glob_fdset_open(int mode)
 }
 
 static int image_dir_fd = -1;
+static int sockfd = -1;
 
 int open_image(int type, unsigned long flags, ...)
 {
@@ -226,6 +229,15 @@ int open_image(int type, unsigned long flags, ...)
 	vsnprintf(path, PATH_MAX, fdset_template[type].fmt, args);
 	va_end(args);
 
+	if (sockfd != -1) {
+		ret = accept(sockfd, NULL, NULL);
+		if (ret < 0) {
+			pr_perror("Unable to accept()");
+			goto err;
+		}
+		goto net_only;
+	}
+
 	if (flags & O_EXCL) {
 		ret = unlinkat(image_dir_fd, path, 0);
 		if (ret && errno != ENOENT) {
@@ -240,6 +252,7 @@ int open_image(int type, unsigned long flags, ...)
 		goto err;
 	}
 
+net_only:
 	if (flags == O_RDONLY) {
 		u32 magic;
 
@@ -250,12 +263,17 @@ int open_image(int type, unsigned long flags, ...)
 			goto err;
 		}
 	} else {
+		if (sockfd != -1)
+			goto err;
 		if (write_img(ret, &fdset_template[type].magic))
 			goto err;
 	}
 
 	return ret;
 err:
+	close(ret);
+	if (sockfd !=-1)
+		close(sockfd);
 	return -1;
 }
 
@@ -285,3 +303,38 @@ void close_image_dir(void)
 	close(image_dir_fd);
 	image_dir_fd = -1;
 }
+
+int open_listen_socket(char *host, int port)
+{
+	struct hostent *server;
+	struct sockaddr_in serveraddr;
+
+	sockfd = socket(AF_INET, SOCK_STREAM, 0);
+	if (sockfd < 0) {
+		pr_perror("ERROR opening socket");
+		return -1;
+	}
+
+	server = gethostbyname(host);
+	if (server == NULL) {
+		pr_perror("ERROR, no such host as %s\n", host);
+		return -1;
+	}
+
+	memset((char *) &serveraddr, 0, sizeof(serveraddr));
+	serveraddr.sin_family = AF_INET;
+	memcpy((char *)&serveraddr.sin_addr.s_addr,(char *)server->h_addr, server->h_length);
+	serveraddr.sin_port = htons(port);
+
+	if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
+		pr_perror("ERROR connecting\n");
+		return -1;
+	}
+
+	if (listen(sockfd, 5) < 0) {
+		pr_perror("listen() failed");
+		return -1;
+	}
+
+	return sockfd;
+}
diff --git a/include/crtools.h b/include/crtools.h
index ded767d..c2ccbe0 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -132,6 +132,8 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
 extern int open_image_dir(void);
 extern void close_image_dir(void);
 
+extern int open_listen_socket(char *host, int port);
+
 int open_image(int type, unsigned long flags, ...);
 #define open_image_ro(type, ...) open_image(type, O_RDONLY, ##__VA_ARGS__)
 
-- 
1.7.6.5



More information about the CRIU mailing list