[CRIU] [PATCH 13/22] compel: Add pack action and argv handling

Cyrill Gorcunov gorcunov at openvz.org
Wed Oct 19 12:21:28 PDT 2016


This is yet incomplete interface for future use -- the "pack" action
takes list of plugins to merge into one object blob and argv interface
prepares it for execution.

Still since it's incomplete I don't put any comments here until we have
objects file rt engine back so then one explicitly will see how all this
machinery works (including documentation).

For a while simply consider is as a scaffold for further development.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 compel/Makefile                     |  3 ++
 compel/include/compel/xmalloc.h     |  1 +
 compel/include/uapi/compel/compel.h |  8 ++++
 compel/src/lib/argv.c               | 41 ++++++++++++++++++
 compel/src/lib/pack-host.c          |  1 +
 compel/src/lib/pack.c               | 83 +++++++++++++++++++++++++++++++++++++
 compel/src/main.c                   | 28 ++++++++++++-
 7 files changed, 163 insertions(+), 2 deletions(-)
 create mode 120000 compel/include/compel/xmalloc.h
 create mode 100644 compel/src/lib/argv.c
 create mode 120000 compel/src/lib/pack-host.c
 create mode 100644 compel/src/lib/pack.c

diff --git a/compel/Makefile b/compel/Makefile
index 9cd86c554584..e2fca725175c 100644
--- a/compel/Makefile
+++ b/compel/Makefile
@@ -22,6 +22,7 @@ host-lib-y		+= arch/$(ARCH)/src/lib/handle-elf.o
 lib-y			+= src/lib/handle-elf.o
 host-lib-y		+= src/lib/handle-elf.o
 
+lib-y			+= src/lib/argv.o
 lib-y			+= src/lib/compel.o
 
 #
@@ -47,6 +48,8 @@ headers-y		+= $(obj)/include/uapi/compel/asm/types.h
 
 lib-y			+= src/lib/log.o
 host-lib-y		+= src/lib/log.o
+lib-y			+= src/lib/pack.o
+host-lib-y		+= src/lib/pack.o
 
 ifeq ($(ARCH),x86)
 lib-y			+= src/lib/handle-elf-32.o
diff --git a/compel/include/compel/xmalloc.h b/compel/include/compel/xmalloc.h
new file mode 120000
index 000000000000..09c0adb503b5
--- /dev/null
+++ b/compel/include/compel/xmalloc.h
@@ -0,0 +1 @@
+../../../criu/include/xmalloc.h
\ No newline at end of file
diff --git a/compel/include/uapi/compel/compel.h b/compel/include/uapi/compel/compel.h
index 85ea8214a21d..c0828fdfbb2d 100644
--- a/compel/include/uapi/compel/compel.h
+++ b/compel/include/uapi/compel/compel.h
@@ -18,6 +18,14 @@ typedef struct {
 extern void compel_version(unsigned int *major, unsigned int *minor, unsigned int *sublevel);
 
 /*
+ * Packing objects
+ */
+extern int compel_pack_objs(char **objs, size_t nobjs,
+			    const char *lib_path,
+			    char **libs, size_t nlibs,
+			    char *out);
+
+/*
  * Logging
  */
 extern int compel_log_init(const char *output);
diff --git a/compel/src/lib/argv.c b/compel/src/lib/argv.c
new file mode 100644
index 000000000000..c9cc68374690
--- /dev/null
+++ b/compel/src/lib/argv.c
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <compel/compel.h>
+
+#include "xmalloc.h"
+
+int compel_pack_argv(void *blob, size_t blob_size,
+		     int argc, char **argv,
+		     void **arg_p, size_t *arg_size)
+{
+	unsigned long *argv_packed;
+	size_t total_len;
+	int i, *argc_packed;
+	char *args_mem;
+
+	total_len = sizeof(int);
+	total_len += sizeof(unsigned long) + blob_size + 1;
+	for (i = 0; i < argc; i++)
+		total_len += sizeof(unsigned long) + strlen(argv[i]) + 1;
+
+	argc_packed = xmalloc(total_len);
+	if (!argc_packed)
+		return -ENOMEM;
+
+	*argc_packed = argc + 1;
+	argv_packed = (unsigned long *)(argc_packed + 1);
+	args_mem = (char *)(argv_packed + argc + 1);
+	argv_packed[0] = (void *)args_mem - (void *)argc_packed;
+	memcpy(args_mem, blob, blob_size);
+	args_mem += blob_size + 1;
+	for (i = 0; i < argc; i++) {
+		argv_packed[i + 1] = (void *)args_mem - (void *)argc_packed;
+		args_mem = stpcpy(args_mem, argv[i]) + 1;
+	}
+
+	*arg_p = argc_packed;
+	*arg_size = total_len;
+
+	return 0;
+}
diff --git a/compel/src/lib/pack-host.c b/compel/src/lib/pack-host.c
new file mode 120000
index 000000000000..e2900df18bd9
--- /dev/null
+++ b/compel/src/lib/pack-host.c
@@ -0,0 +1 @@
+pack.c
\ No newline at end of file
diff --git a/compel/src/lib/pack.c b/compel/src/lib/pack.c
new file mode 100644
index 000000000000..7178c0f9803c
--- /dev/null
+++ b/compel/src/lib/pack.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <linux/limits.h>
+
+#include <compel/compel.h>
+
+#include "log.h"
+
+#define COMPEL_DEFAULT_LIB_DIR	"/usr/share/compel"
+#define COMPEL_DEFAULT_PACK_OUT	"a.compel.o"
+
+#define COMPEL_LDS		"pack.lds.S"
+#define COMPEL_STD		"std.compel.o"
+
+int compel_pack_objs(char **objs, size_t nobjs,
+		     const char *lib_path,
+		     char **libs, size_t nlibs,
+		     char *out)
+{
+	char command[1024] = { 0 };
+	char data[1024] = { 0 };
+	int ret = -1, pos, i;
+	FILE *f;
+
+	/*
+	 * Figure out where the scripts we need are sitting.
+	 */
+	if (!lib_path) {
+		char *prefix = getenv("COMPEL_LIB_DIR");
+		char path[PATH_MAX];
+		if (!prefix)
+			prefix = COMPEL_DEFAULT_LIB_DIR;
+		snprintf(path, sizeof(path), "%s/%s", prefix, COMPEL_LDS);
+		if (access(path, R_OK)) {
+			snprintf(path, sizeof(path), "%s/%s", prefix, COMPEL_STD);
+			if (!access(path, R_OK)) {
+				pr_err("Can't access %s file\n", path);
+				goto err_no_res;
+			}
+			lib_path = prefix;
+		} else {
+			pr_err("Can't access %s file\n", path);
+			goto err_no_res;
+		}
+	}
+
+	pos = snprintf(command, sizeof(command),
+		       "ld -r -T %s/" COMPEL_LDS " -o %s %s/" COMPEL_STD,
+		       lib_path, out ? : COMPEL_DEFAULT_PACK_OUT, lib_path);
+
+	for (i = 0; pos < sizeof(command) - 1 && i < nobjs; i++) {
+		pos += snprintf(&command[pos], sizeof(command) - pos - 1,
+				" %s", objs[i]);
+	}
+
+	for (i = 0; pos < sizeof(command) - 1 && i < nlibs; i++) {
+		pos += snprintf(&command[pos], sizeof(command) - pos - 1,
+				" %s/%s.built-in.o", lib_path, libs[i]);
+	}
+
+	pr_debug("pack as: `%s'\n", command);
+
+	f = popen(command, "r");
+	if (f) {
+		if (fgets(data, sizeof(data), f))
+			ret = data[0] == '\0' ? 0 : -1;
+		else
+			ret = -1;
+		ret = (pclose(f) >= 0 ? 0 : -1);
+//		if (!ret)
+//			ret = compel_verify_packed(out ? : COMPEL_DEFAULT_PACK_OUT);
+	} else
+		pr_perror("Can't run pack");
+	if (ret)
+		pr_err("Pack failed\n");
+	return ret;
+
+err_no_res:
+	pr_err("Can't find resource files needed for `pack' action\n");
+	return -1;
+}
diff --git a/compel/src/main.c b/compel/src/main.c
index 734a51a58c3d..f2d09b06432e 100644
--- a/compel/src/main.c
+++ b/compel/src/main.c
@@ -15,6 +15,7 @@
 #include "uapi/compel/compel.h"
 
 #include "version.h"
+#include "xmalloc.h"
 #include "piegen.h"
 #include "log.h"
 
@@ -91,6 +92,10 @@ int main(int argc, char *argv[])
 	int opt, idx, i;
 	char *action;
 
+	char *libdir = NULL;
+	size_t nlibs = 0;
+	char *libs[512];
+
 	typedef struct {
 		const char	*arch;
 		const char	*cflags;
@@ -115,7 +120,7 @@ int main(int argc, char *argv[])
 		},
 	};
 
-	static const char short_opts[] = "a:f:o:s:p:v:r:u:h";
+	static const char short_opts[] = "a:f:o:s:p:v:r:u:hl:L:";
 	static struct option long_opts[] = {
 		{ "arch",	required_argument,	0, 'a' },
 		{ "file",	required_argument,	0, 'f' },
@@ -126,10 +131,12 @@ int main(int argc, char *argv[])
 		{ "variable",	required_argument,	0, 'v' },
 		{ "pcrelocs",	required_argument,	0, 'r' },
 		{ "help",	required_argument,	0, 'h' },
+		{ "library",	required_argument,	0, 'l' },
+		{ "library-path",required_argument,	0, 'L' },
 		{ },
 	};
 
-	if (argc < 3)
+	if (argc < 1)
 		goto usage;
 
 	while (1) {
@@ -172,6 +179,17 @@ int main(int argc, char *argv[])
 			break;
 		case 'h':
 			goto usage;
+		case 'L':
+			libdir = optarg;
+			break;
+		case 'l':
+			if (nlibs >= ARRAY_SIZE(libs)) {
+				pr_err("Too many libraries specified, max %d\n",
+				       (int)ARRAY_SIZE(libs));
+				exit(1);
+			}
+			libs[nlibs++] = optarg;
+			break;
 		default:
 			break;
 		}
@@ -200,6 +218,12 @@ int main(int argc, char *argv[])
 		return piegen();
 	}
 
+	if (!strcmp(action, "pack")) {
+		return compel_pack_objs(argv + optind, argc - optind,
+					libdir, libs, nlibs,
+					opts.output_filename);
+	}
+
 usage:
 	printf("Usage:\n");
 	printf("  compel --arch=(x86|ia32|aarch64|arm|ppc64) cflags\n");
-- 
2.7.4



More information about the CRIU mailing list