[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