diff --git a/build/busybox b/build/busybox new file mode 100755 index 0000000..1c8b2b8 Binary files /dev/null and b/build/busybox differ diff --git a/build/make-initrd.sh b/build/make-initrd.sh index de28d77..9258c59 100755 --- a/build/make-initrd.sh +++ b/build/make-initrd.sh @@ -4,6 +4,7 @@ rm -rf root mkdir root cp ../src/init ./root +cp busybox ./root ldd ./root/init | while read line do diff --git a/src/container.c b/src/container.c index dd2e281..7a776b8 100644 --- a/src/container.c +++ b/src/container.c @@ -19,6 +19,14 @@ #include "parse.h" #include "syscall.h" +static int container_populate_volume(char *src, char *dest) +{ + fprintf(stdout, "populate volumes from %s to %s\n", src, dest); + /* FIXME: check if has data in volume, (except lost+found) */ + + return hyper_copy_dir(src, dest); +} + static int container_setup_volume(struct hyper_container *container) { int i; @@ -46,6 +54,12 @@ static int container_setup_volume(struct hyper_container *container) return -1; } + if (vol->docker && container->initialize && + (container_populate_volume(vol->mountpoint, path) < 0)) { + fprintf(stderr, "fail to populate volume %s\n", vol->mountpoint); + return -1; + } + if (mount(path, vol->mountpoint, NULL, MS_BIND, NULL) < 0) { perror("mount volume device faled"); return -1; @@ -158,6 +172,12 @@ static int container_setup_mount(struct hyper_container *container) perror("create map dir failed"); continue; } + + if (map->docker && container->initialize && + (container_populate_volume(map->path, src) < 0)) { + fprintf(stderr, "fail to populate volume %s\n", map->path); + continue; + } } else { fd = open(map->path, O_CREAT|O_WRONLY, 0755); if (fd < 0) { @@ -256,6 +276,11 @@ static int container_setup_dns(struct hyper_container *container) static int container_setup_workdir(struct hyper_container *container) { + if (container->initialize) { + // create workdir + hyper_mkdir(container->workdir); + } + if (container->workdir && chdir(container->workdir) < 0) { perror("change work directory failed"); return -1; diff --git a/src/container.h b/src/container.h index a3a6bd2..f8f0144 100644 --- a/src/container.h +++ b/src/container.h @@ -14,12 +14,14 @@ struct volume { char *mountpoint; char *fstype; int readonly; + int docker; }; struct fsmap { char *source; char *path; int readonly; + int docker; }; struct sysctl { @@ -43,6 +45,7 @@ struct hyper_container { int maps_num; int sys_num; int ns; + int initialize; uint32_t code; struct list_head list; struct hyper_exec exec; diff --git a/src/parse.c b/src/parse.c index a7513f6..99773df 100644 --- a/src/parse.c +++ b/src/parse.c @@ -233,6 +233,10 @@ static int container_parse_volumes(struct hyper_container *c, char *json, jsmnto if (!json_token_streq(json, &toks[++i], "false")) c->vols[j].readonly = 1; fprintf(stdout, "volume %d readonly %d\n", j, c->vols[j].readonly); + } else if (json_token_streq(json, &toks[i], "dockerVolume")) { + if (!json_token_streq(json, &toks[++i], "false")) + c->vols[j].docker = 1; + fprintf(stdout, "volume %d docker volume %d\n", j, c->vols[j].docker); } else { fprintf(stdout, "get unknown section %s in voulmes\n", json_token_str(json, &toks[i])); @@ -298,6 +302,10 @@ static int container_parse_fsmap(struct hyper_container *c, char *json, jsmntok_ if (!json_token_streq(json, &toks[++i], "false")) c->maps[j].readonly = 1; fprintf(stdout, "maps %d readonly %d\n", j, c->maps[j].readonly); + } else if (json_token_streq(json, &toks[i], "dockerVolume")) { + if (!json_token_streq(json, &toks[++i], "false")) + c->maps[j].docker = 1; + fprintf(stdout, "maps %d docker volume %d\n", j, c->maps[j].docker); } else { fprintf(stdout, "in maps incorrect %s\n", json_token_str(json, &toks[i])); @@ -554,6 +562,12 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * } else if (json_token_streq(json, t, "restartPolicy") && t->size == 1) { fprintf(stdout, "restart policy %s\n", json_token_str(json, &toks[++i])); i++; + } else if (json_token_streq(json, t, "initialize") && t->size == 1) { + if (!json_token_streq(json, &toks[++i], "false")) { + c->initialize = 1; + fprintf(stdout, "need to initialize container\n"); + } + i++; } else { fprintf(stdout, "get unknown section %s in container\n", json_token_str(json, t)); diff --git a/src/util.c b/src/util.c index 9e7d953..28e7563 100644 --- a/src/util.c +++ b/src/util.c @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -64,6 +66,39 @@ int hyper_list_dir(char *path) return 0; } +int hyper_copy_dir(char *src, char *dest) { + int pid, status; + + pid = fork(); + if (pid < 0) { + perror("fail to fork to copy directory"); + return -1; + } else if (pid > 0) { + if (waitpid(pid, &status, 0) <= 0) { + perror("waiting copy directroy finish failed"); + return -1; + } + if (WIFEXITED(status)) { + int ret = WEXITSTATUS(status); + fprintf(stdout, "copy directroy exit normally, status %" PRIu8 "\n", ret); + if (ret == 0) + return 0; + } + + fprintf(stderr, "copy directroy exit unexpectedly, status %" PRIu8 "\n", status); + return -1; + } else { + char cmd[512]; + snprintf(cmd, sizeof(cmd), "tar zcf - -C %s . | tar zfx - -C %s", src, dest); + fprintf(stdout, "command for copy is %s\n", cmd); + + execlp("/.oldroot/busybox", "sh", "-c", cmd, NULL); + perror("exec copy directroy command failed"); + } + + return 0; +} + int hyper_find_sd(char *prefix, char *addr, char **dev) { struct dirent **list; struct dirent *dir; diff --git a/src/util.h b/src/util.h index 02fdb08..026ac71 100644 --- a/src/util.h +++ b/src/util.h @@ -18,6 +18,7 @@ char *read_cmdline(void); int hyper_setup_env(struct env *envs, int num); int hyper_find_sd(char *prefix, char *addr, char **dev); int hyper_list_dir(char *path); +int hyper_copy_dir(char *src, char *dst); void online_cpu(void); void online_memory(void); int hyper_mkdir(char *path);