[CRIU] [PATCHv4 3/4] libcriu: add criu_dump_me() and libcriu header
Ruslan Kuprieiev
kupruser at gmail.com
Tue Sep 3 10:44:26 EDT 2013
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..aa8d6a8
--- /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 /* when libcriu ver. > criu ver. */
+
+/* MUST be called BEFORE using criu_set* functions */
+int criu_alloc_args(void); /* 0 if success, -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..e7e188d 100644
--- a/lib/criu.c
+++ b/lib/criu.c
@@ -1,3 +1,158 @@
+#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;
+static char *service_addr;
+
+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;
+
+ 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)
+{
+ 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(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