From d766442be1dca15cff162671f367fa867ba74c94 Mon Sep 17 00:00:00 2001 From: liuhao Date: Thu, 2 May 2019 11:23:50 +0800 Subject: [PATCH 093/139] optimize isulad_kit operator parse group add start container Signed-off-by: liuhao Signed-off-by: LiFeng --- src/lxc/Makefile.am | 2 + src/lxc/json/container_start_generate_config.c | 245 +++++++++++++++++++++++++ src/lxc/json/container_start_generate_config.h | 43 +++++ src/lxc/tools/lxc_start.c | 58 ++++++ 4 files changed, 348 insertions(+) create mode 100644 src/lxc/json/container_start_generate_config.c create mode 100644 src/lxc/json/container_start_generate_config.h diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index 698f8f9..4ec2081 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -45,6 +45,7 @@ noinst_HEADERS = attach.h \ storage/storage_utils.h \ json/defs.h \ json/json_common.h \ + json/container_start_generate_config.h \ json/oci_runtime_hooks.h \ json/oci_runtime_spec.h \ json/logger_json_file.h \ @@ -152,6 +153,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ json/oci_runtime_hooks.c json/oci_runtime_hooks.h \ json/logger_json_file.c json/logger_json_file.h \ json/oci_runtime_spec.c json/oci_runtime_spec.h \ + json/container_start_generate_config.c json/container_start_generate_config.h \ json/read-file.c json/read-file.h \ $(LSM_SOURCES) diff --git a/src/lxc/json/container_start_generate_config.c b/src/lxc/json/container_start_generate_config.c new file mode 100644 index 0000000..5ec8311 --- /dev/null +++ b/src/lxc/json/container_start_generate_config.c @@ -0,0 +1,245 @@ +// Generated from start-generate-config.json. Do not edit! +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include "read-file.h" +#include "container_start_generate_config.h" + +container_start_generate_config *make_container_start_generate_config(yajl_val tree, struct parser_context *ctx, parser_error *err) { + container_start_generate_config *ret = NULL; + *err = 0; + if (tree == NULL) + return ret; + ret = safe_malloc(sizeof(*ret)); + { + yajl_val val = get_val(tree, "uid", yajl_t_number); + if (val != NULL) { + int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->uid); + if (invalid) { + if (asprintf(err, "Invalid value '%s' with type 'UID' for key 'uid': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) + *err = safe_strdup("error allocating memory"); + free_container_start_generate_config(ret); + return NULL; + } + } + } + { + yajl_val val = get_val(tree, "gid", yajl_t_number); + if (val != NULL) { + int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->gid); + if (invalid) { + if (asprintf(err, "Invalid value '%s' with type 'GID' for key 'gid': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) + *err = safe_strdup("error allocating memory"); + free_container_start_generate_config(ret); + return NULL; + } + } + } + { + yajl_val tmp = get_val(tree, "additionalGids", yajl_t_array); + if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { + size_t i; + ret->additional_gids_len = YAJL_GET_ARRAY(tmp)->len; + ret->additional_gids = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->additional_gids)); + for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { + yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; + if (val != NULL) { + int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->additional_gids[i]); + if (invalid) { + if (asprintf(err, "Invalid value '%s' with type 'GID' for key 'additionalGids': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) + *err = safe_strdup("error allocating memory"); + free_container_start_generate_config(ret); + return NULL; + } + } + } + } + } + + if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { + int i; + for (i = 0; i < tree->u.object.len; i++) + if (strcmp(tree->u.object.keys[i], "uid") && + strcmp(tree->u.object.keys[i], "gid") && + strcmp(tree->u.object.keys[i], "additionalGids")) { + if (ctx->stderr > 0) + fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); + } + } + return ret; +} + +void free_container_start_generate_config(container_start_generate_config *ptr) { + if (ptr == NULL) + return; + free(ptr->additional_gids); + ptr->additional_gids = NULL; + free(ptr); +} + +yajl_gen_status gen_container_start_generate_config(yajl_gen g, container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err) { + yajl_gen_status stat = yajl_gen_status_ok; + *err = 0; + stat = reformat_start_map(g); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->uid)) { + long long unsigned int num = 0; + stat = reformat_map_key(g, "uid", strlen("uid")); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + if (ptr != NULL && ptr->uid) { + num = (long long unsigned int)ptr->uid; + } + stat = reformat_uint(g, num); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + } + if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->gid)) { + long long unsigned int num = 0; + stat = reformat_map_key(g, "gid", strlen("gid")); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + if (ptr != NULL && ptr->gid) { + num = (long long unsigned int)ptr->gid; + } + stat = reformat_uint(g, num); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + } + if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->additional_gids != NULL)) { + size_t len = 0, i; + stat = reformat_map_key(g, "additionalGids", strlen("additionalGids")); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + if (ptr != NULL && ptr->additional_gids != NULL) { + len = ptr->additional_gids_len; + } + if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) + yajl_gen_config(g, yajl_gen_beautify, 0); + stat = reformat_start_array(g); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + for (i = 0; i < len; i++) { + stat = reformat_uint(g, ptr->additional_gids[i]); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + } + stat = reformat_end_array(g); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) + yajl_gen_config(g, yajl_gen_beautify, 1); + } + stat = reformat_end_map(g); + if (yajl_gen_status_ok != stat) + GEN_SET_ERROR_AND_RETURN(stat, err); + return yajl_gen_status_ok; +} + + +container_start_generate_config *container_start_generate_config_parse_file(const char *filename, struct parser_context *ctx, parser_error *err) { + container_start_generate_config *ptr = NULL; + size_t filesize; + char *content = NULL; + + if (filename == NULL || err == NULL) + return NULL; + + *err = NULL; + content = read_file(filename, &filesize); + if (content == NULL) { + if (asprintf(err, "cannot read the file: %s", filename) < 0) + *err = safe_strdup("error allocating memory"); + return NULL; + } + ptr = container_start_generate_config_parse_data(content, ctx, err); + free(content); + return ptr; +} + +container_start_generate_config *container_start_generate_config_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err) { + container_start_generate_config *ptr = NULL; + size_t filesize; + char *content = NULL ; + + if (stream == NULL || err == NULL) + return NULL; + + *err = NULL; + content = fread_file(stream, &filesize); + if (content == NULL) { + *err = safe_strdup("cannot read the file"); + return NULL; + } + ptr = container_start_generate_config_parse_data(content, ctx, err); + free(content); + return ptr; +} + +container_start_generate_config *container_start_generate_config_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err) { + container_start_generate_config *ptr = NULL; + yajl_val tree; + char errbuf[1024]; + struct parser_context tmp_ctx; + + if (jsondata == NULL || err == NULL) + return NULL; + + *err = NULL; + if (ctx == NULL) { + ctx = &tmp_ctx; + (void)memset(&tmp_ctx, 0, sizeof(tmp_ctx)); + } + tree = yajl_tree_parse(jsondata, errbuf, sizeof(errbuf)); + if (tree == NULL) { + if (asprintf(err, "cannot parse the data: %s", errbuf) < 0) + *err = safe_strdup("error allocating memory"); + return NULL; + } + ptr = make_container_start_generate_config(tree, ctx, err); + yajl_tree_free(tree); + return ptr; +} +char *container_start_generate_config_generate_json(container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err) { + yajl_gen g = NULL; + struct parser_context tmp_ctx; + const unsigned char *gen_buf = NULL; + char *json_buf = NULL; + size_t gen_len = 0; + + if (ptr == NULL || err == NULL) + return NULL; + + *err = NULL; + if (ctx == NULL) { + ctx = &tmp_ctx; + (void)memset(&tmp_ctx, 0, sizeof(tmp_ctx)); + } + + if (!json_gen_init(&g, ctx)) { + *err = safe_strdup("Json_gen init failed"); + goto out; + } + if (yajl_gen_status_ok != gen_container_start_generate_config(g, ptr, ctx, err)) { + if (*err == NULL) + *err = safe_strdup("Failed to generate json"); + goto free_out; + } + yajl_gen_get_buf(g, &gen_buf, &gen_len); + if (gen_buf == NULL) { + *err = safe_strdup("Error to get generated json"); + goto free_out; + } + + json_buf = safe_malloc(gen_len + 1); + (void)memcpy(json_buf, gen_buf, gen_len); + json_buf[gen_len] = '\0'; + +free_out: + yajl_gen_clear(g); + yajl_gen_free(g); +out: + return json_buf; +} diff --git a/src/lxc/json/container_start_generate_config.h b/src/lxc/json/container_start_generate_config.h new file mode 100644 index 0000000..e1dcf56 --- /dev/null +++ b/src/lxc/json/container_start_generate_config.h @@ -0,0 +1,43 @@ +// Generated from start-generate-config.json. Do not edit! +#ifndef CONTAINER_START_GENERATE_CONFIG_SCHEMA_H +#define CONTAINER_START_GENERATE_CONFIG_SCHEMA_H + +#include +#include +#include "json_common.h" +#include "defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uid_t uid; + + gid_t gid; + + gid_t *additional_gids; + size_t additional_gids_len; + +} +container_start_generate_config; + +void free_container_start_generate_config(container_start_generate_config *ptr); + +container_start_generate_config *make_container_start_generate_config(yajl_val tree, struct parser_context *ctx, parser_error *err); + +yajl_gen_status gen_container_start_generate_config(yajl_gen g, container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err); + +container_start_generate_config *container_start_generate_config_parse_file(const char *filename, struct parser_context *ctx, parser_error *err); + +container_start_generate_config *container_start_generate_config_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err); + +container_start_generate_config *container_start_generate_config_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err); + +char *container_start_generate_config_generate_json(container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c index af63f58..4069204 100644 --- a/src/lxc/tools/lxc_start.c +++ b/src/lxc/tools/lxc_start.c @@ -50,6 +50,7 @@ #include "confile.h" #include "log.h" #include "utils.h" +#include "container_start_generate_config.h" lxc_log_define(lxc_start, lxc); @@ -213,6 +214,57 @@ static int ensure_path(char **confpath, const char *path) return 0; } +static int set_start_extral_configs(const char *lxcpath, const char *name, struct lxc_container *c) +{ +#define START_GENERATE_CONFIG "start_generate_config.json" + char fpath[PATH_MAX] = {0}; + parser_error jerr = NULL; + int ret = -1; + container_start_generate_config *start_conf = NULL; + struct lxc_conf *lconf = c->lxc_conf; + size_t i = 0; + + if (sprintf(fpath, "%s/%s/%s", lxcpath, name, START_GENERATE_CONFIG) < 0) { + ERROR("Sprintf config path failed"); + return -1; + } + if (!file_exists(fpath)) { + return 0; + } + start_conf = container_start_generate_config_parse_file(fpath, NULL, &jerr); + if (start_conf == NULL) { + ERROR("Parse start generate config file: %s failed", fpath); + goto out; + } + if (start_conf->uid != 0) { + lconf->init_uid = start_conf->uid; + } + if (start_conf->gid != 0) { + lconf->init_gid = start_conf->gid; + } + if (start_conf->additional_gids != NULL && start_conf->additional_gids_len > 0) { + gid_t *tmp; + tmp = realloc(lconf->init_groups, (lconf->init_groups_len + start_conf->additional_gids_len) * sizeof(gid_t)); + if (tmp == NULL) { + ERROR("Out of memory"); + goto out; + } + lconf->init_groups = tmp; + for (; i < start_conf->additional_gids_len; i++) { + tmp[lconf->init_groups_len] = start_conf->additional_gids[i]; + lconf->init_groups_len++; + } + } + + ret = 0; +out: + free(jerr); + if (start_conf != NULL) { + free_container_start_generate_config(start_conf); + } + return ret; +} + int main(int argc, char *argv[]) { const char *lxcpath; @@ -358,6 +410,12 @@ int main(int argc, char *argv[]) } } + /* isulad: load extral config for start container */ + if (set_start_extral_configs(lxcpath, my_args.name, c) != 0) { + ERROR("Failed to load extral config for container"); + goto out; + } + /* isulad: fifo used to monitor state of monitor process */ if (my_args.exit_monitor_fifo != NULL) { c->exit_fifo = strdup(my_args.exit_monitor_fifo); -- 1.8.3.1