[CRIU] [PATCHv3 3/4] libcriu: add criu_dump_me() and libcriu header

Ruslan Kuprieiev kupruser at gmail.com
Mon Sep 2 10:35:56 EDT 2013


This patch requires:
"[CRIU] [PATCH 0/4] Extend make engine to compile source files with 
different flags" by Cyrill Gorcunov.

criu_dump_me() can be used by program to dump itself.
Program need to call criu_allocate_args() to prepare arguments and then 
it can set them using criu_set* functions. criu_set* functions are used 
instead of give user access to arguments itself, so user will not mess 
with protobuf.

libcriu.h is to be used by user program.

-------------- next part --------------
diff --git a/include/libcriu.h b/include/libcriu.h
new file mode 100644
index 0000000..bc16ab5
--- /dev/null
+++ b/include/libcriu.h
@@ -0,0 +1,40 @@
+#ifndef __CRIU_LIB__
+#define __CRIU_LIB__
+#include <stdint.h>
+
+#define CR_DEFAULT_SERVICE_ADDRESS "/tmp/criu_service.socket"
+
+/* dump flags */
+#define CRIU_DUMP_AND_KILL	0
+#define CRIU_DUMP_AND_CONTINUE	(1 << 0)
+
+/* return codes */
+#define CRIU_DUMP_FAIL		-1
+#define CRIU_RESUME		1	/* when program is restored */
+#define CRIU_DUMP_SUCCESS	0	/* when CRIU_DUMP_AND_CONTINUE is set */
+#define CRIU_OLD_VERSION	-2
+
+/* MUST be called BEFORE using criu_set* functions */
+int criu_alloc_args(void); /* 0 if succes, -1 if fail*/
+
+/* criu_set_* functions are to be used to set dump arguments */
+
+/*---------- REQUIRED arguments ----------*/
+
+/* opened dir fd for images */
+void criu_set_images_dir_fd(int32_t fd);
+
+/*----------------------------------------*/
+
+/*---------- OPTIONAL arguments ----------*/
+
+/* dump flags. see macros above */
+void criu_set_flags(uint64_t flags);	/* def: CRIU_DUMP_AND_KILL */
+/* service socket address */
+void criu_set_service_addr(char *addr); /* def: CR_DEFAUL_SERVICE_ADDRESS */
+
+/*----------------------------------------*/
+
+int criu_dump_me(void);
+
+#endif
diff --git a/lib/Makefile b/lib/Makefile
index 3156eb1..16737be 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,6 +1,7 @@
 lib-so			+= libcriu
 obj-y			+= criu.o
 obj-ext-src-y		+= pie/util-fd.o
+obj-ext-src-y		+= protobuf/criu-dump-args.pb-c.o
 
 includes		+= -iquote $(obj)/../arch/$(ARCH)/include -iquote $(obj)/../include -iquote $(obj)/..
 cflags-y		+= $(includes) -fPIC -Wa,--noexecstack -fno-stack-protector
diff --git a/lib/criu.c b/lib/criu.c
index be629d9..93212f4 100644
--- a/lib/criu.c
+++ b/lib/criu.c
@@ -1,3 +1,159 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <google/protobuf-c/protobuf-c.h>
+
+#include "libcriu.h"
 #include "version.h"
+#include "util-pie.h"
+
+#include "protobuf/criu-dump-args.pb-c.h"
 
 const char *criu_lib_version = version;
+
+static CriuDumpArgs *args;
+
+int criu_alloc_args(void)
+{
+	args = malloc(sizeof(CriuDumpArgs));
+	if (args == NULL) {
+		perror("Can't allocate memory");
+		return -1;
+	}
+
+	criu_dump_args__init(args);
+
+	args->version_major = CRIU_VERSION_MAJOR;
+	args->version_minor = CRIU_VERSION_MINOR;
+	args->images_dir_fd = 0;
+	args->flags = CRIU_DUMP_AND_KILL;
+	args->service_addr = CR_DEFAULT_SERVICE_ADDRESS;
+
+	return 0;
+}
+
+void criu_set_images_dir_fd(int32_t images_dir_fd)
+{
+	args->images_dir_fd = images_dir_fd;
+}
+
+void criu_set_flags(uint64_t flags)
+{
+	args->flags = flags;
+}
+
+void criu_set_service_addr(char *service_addr)
+{
+	args->service_addr = service_addr;
+}
+
+static int send_dump_args(int socket_fd)
+{
+	int len;
+	unsigned char *buf;
+
+	len = criu_dump_args__get_packed_size(args);
+	if (send(socket_fd, &len, sizeof(len), 0) == -1) {
+		perror("Can't send size of args");
+		return CRIU_DUMP_FAIL;
+	}
+
+	buf = malloc(len);
+	if (buf == NULL) {
+		perror("Can't allocate memory");
+		return CRIU_DUMP_FAIL;
+	}
+
+	criu_dump_args__pack(args, buf);
+
+	if (send(socket_fd, buf, len, 0) == -1) {
+		perror("Can't send args");
+		return CRIU_DUMP_FAIL;
+	}
+
+	if (send_fd(socket_fd, NULL, 0, args->images_dir_fd) == -1) {
+		perror("Can't send file descriptor");
+		return CRIU_DUMP_FAIL;
+	}
+
+	return 0;
+}
+
+static int connect_to_socket(char *addr)
+{
+	int socket_fd;
+	struct sockaddr_un server_addr;
+	socklen_t server_addr_len;
+
+	socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+	if (socket_fd == -1) {
+		perror("Can't create socket");
+		return CRIU_DUMP_FAIL;
+	}
+
+	memset(&server_addr, 0, sizeof(server_addr));
+	server_addr.sun_family = AF_LOCAL;
+
+	if (!addr)
+		addr = CR_DEFAULT_SERVICE_ADDRESS;
+
+	strcpy(server_addr.sun_path, addr);
+
+	server_addr_len = strlen(server_addr.sun_path)
+			+ sizeof(server_addr.sun_family);
+
+	if (connect(socket_fd, (struct sockaddr *) &server_addr,
+						server_addr_len) != 0) {
+		perror("Can't connect to socket");
+		close(socket_fd);
+		return CRIU_DUMP_FAIL;
+	}
+
+	return socket_fd;
+}
+
+int criu_dump_me(void)
+{
+	int socket_fd;
+	int ret, c;
+
+	socket_fd = connect_to_socket(args->service_addr);
+	if (socket_fd < 0) {
+		perror("Can't connect to service socket");
+		ret = socket_fd;
+		goto exit;
+	}
+
+	ret = send_dump_args(socket_fd);
+	if (ret) {
+		perror("Can't send dump arg");
+		goto exit;
+	}
+
+	/* getting flag from criu */
+	c = read(socket_fd, &ret, sizeof(ret));
+	if (c == -1) {
+		ret = CRIU_DUMP_FAIL;
+		goto exit;
+	}
+
+exit:
+	if (ret == CRIU_OLD_VERSION) {
+		fprintf(stderr,
+			"libcriu version(%s) is greater than criu version. "
+			"Please, upgrade criu to libcriu version",
+			criu_lib_version);
+	}
+
+	close(socket_fd);
+	return ret;
+}
+
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 5c4ff43..295983f 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -184,7 +184,7 @@ endif
 ifneq ($(lib-so),)
 $(obj)/$(lib-so).so: $(all-objs) $(libs-e)
 	$(E) "  LINK    " $@
-	$(Q) $(CC) -shared $(cflags-so) -o $@ $^
+	$(Q) $(CC) -shared $(cflags-so) -o $@ $^ $(LIBS)
 
 _all += $(obj)/$(lib-so).so
 endif



More information about the CRIU mailing list