diff options
Diffstat (limited to '0019-2254-lcr-container-with-a-damaged-config-file-will-r.patch')
-rw-r--r-- | 0019-2254-lcr-container-with-a-damaged-config-file-will-r.patch | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/0019-2254-lcr-container-with-a-damaged-config-file-will-r.patch b/0019-2254-lcr-container-with-a-damaged-config-file-will-r.patch new file mode 100644 index 0000000..c371d1a --- /dev/null +++ b/0019-2254-lcr-container-with-a-damaged-config-file-will-r.patch @@ -0,0 +1,384 @@ +From 21bca2bb054ed7a1b9b78e01965f8a6d9c3fd28d Mon Sep 17 00:00:00 2001 +From: zhongtao <zhongtao17@huawei.com> +Date: Mon, 20 Nov 2023 12:58:26 +0000 +Subject: [PATCH 19/64] !2254 lcr container with a damaged config file will + rebuild the config during restore * lcr container with a damaged config file + will rebuild the config during restore + +--- + src/common/constants.h | 2 + + src/daemon/modules/api/runtime_api.h | 7 ++ + .../modules/container/restore/restore.c | 28 ++++-- + .../modules/runtime/engines/lcr/lcr_rt_ops.c | 99 ++++++++++++++++++- + .../modules/runtime/engines/lcr/lcr_rt_ops.h | 1 + + .../modules/runtime/isula/isula_rt_ops.c | 6 ++ + .../modules/runtime/isula/isula_rt_ops.h | 1 + + src/daemon/modules/runtime/runtime.c | 24 +++++ + src/daemon/modules/runtime/shim/shim_rt_ops.c | 6 ++ + src/daemon/modules/runtime/shim/shim_rt_ops.h | 2 + + 10 files changed, 167 insertions(+), 9 deletions(-) + +diff --git a/src/common/constants.h b/src/common/constants.h +index caf9b793..5f12ae25 100644 +--- a/src/common/constants.h ++++ b/src/common/constants.h +@@ -86,6 +86,8 @@ extern "C" { + + #define LOG_MAX_RETRIES 10 + ++#define INVALID_CONFIG_ERR_CODE 2 ++ + #define MAX_MSG_BUFFER_SIZE (32 * 1024) + + #define DEFAULT_WEBSOCKET_SERVER_LISTENING_PORT 10350 +diff --git a/src/daemon/modules/api/runtime_api.h b/src/daemon/modules/api/runtime_api.h +index 3c2100f5..08558f42 100644 +--- a/src/daemon/modules/api/runtime_api.h ++++ b/src/daemon/modules/api/runtime_api.h +@@ -41,6 +41,7 @@ typedef enum { + struct runtime_container_status_info { + bool has_pid; + uint32_t pid; ++ int error_code; + Runtime_Container_Status status; + }; + +@@ -197,6 +198,10 @@ typedef struct _rt_exec_resize_params_t { + unsigned int width; + } rt_exec_resize_params_t; + ++typedef struct _rt_runtime_rebuild_config_params_t { ++ const char *rootpath; ++} rt_rebuild_config_params_t; ++ + struct rt_ops { + /* detect whether runtime is of this runtime type */ + bool (*detect)(const char *runtime); +@@ -233,6 +238,7 @@ struct rt_ops { + rt_listpids_out_t *out); + int (*rt_resize)(const char *name, const char *runtime, const rt_resize_params_t *params); + int (*rt_exec_resize)(const char *name, const char *runtime, const rt_exec_resize_params_t *params); ++ int (*rt_rebuild_config)(const char *name, const char *runtime, const rt_rebuild_config_params_t *params); + }; + + int runtime_create(const char *name, const char *runtime, const rt_create_params_t *params); +@@ -253,6 +259,7 @@ int runtime_attach(const char *name, const char *runtime, const rt_attach_params + int runtime_update(const char *name, const char *runtime, const rt_update_params_t *params); + + int runtime_listpids(const char *name, const char *runtime, const rt_listpids_params_t *params, rt_listpids_out_t *out); ++int runtime_rebuild_config(const char *name, const char *runtime, const rt_rebuild_config_params_t *params); + void free_rt_listpids_out_t(rt_listpids_out_t *out); + int runtime_resize(const char *name, const char *runtime, const rt_resize_params_t *params); + int runtime_exec_resize(const char *name, const char *runtime, const rt_exec_resize_params_t *params); +diff --git a/src/daemon/modules/container/restore/restore.c b/src/daemon/modules/container/restore/restore.c +index c26cf561..f6218fe6 100644 +--- a/src/daemon/modules/container/restore/restore.c ++++ b/src/daemon/modules/container/restore/restore.c +@@ -16,15 +16,18 @@ + #include <stdio.h> + #include <unistd.h> + #include <limits.h> +-#include <isula_libutils/container_config_v2.h> +-#include <isula_libutils/host_config.h> + #include <stdbool.h> + #include <stdint.h> + #include <stdlib.h> + #include <string.h> + ++#include <isula_libutils/container_config_v2.h> ++#include <isula_libutils/host_config.h> ++#include <isula_libutils/log.h> ++#include <isula_libutils/auto_cleanup.h> ++ + #include "isulad_config.h" +-#include "isula_libutils/log.h" ++ + #include "container_api.h" + #include "supervisor.h" + #include "containers_gc.h" +@@ -276,9 +279,22 @@ static void restore_state(container_t *cont) + #endif + nret = runtime_status(id, runtime, ¶ms, &real_status); + if (nret != 0) { +- WARN("Failed to restore container %s, make real status to STOPPED. Due to can not load container with status %d", +- id, status); +- real_status.status = RUNTIME_CONTAINER_STATUS_STOPPED; ++ bool rebuild_config = (real_status.error_code == INVALID_CONFIG_ERR_CODE); ++ int tempret = -1; ++ // only the lcr container with a damaged config file will rebuild the config ++ if (rebuild_config) { ++ rt_rebuild_config_params_t rebuild_params = { 0 }; ++ rebuild_params.rootpath = cont->root_path; ++ nret = runtime_rebuild_config(id, runtime, &rebuild_params); ++ EVENT("Rebuild config for container: %s, result : %d", id, nret); ++ if (nret == 0) { ++ tempret = runtime_status(id, runtime, ¶ms, &real_status); ++ } ++ } ++ if (tempret != 0) { ++ WARN("Failed to restore container %s, make real status to STOPPED. Due to cannot load container with status %d", id, status); ++ real_status.status = RUNTIME_CONTAINER_STATUS_STOPPED; ++ } + } + + if (real_status.status == RUNTIME_CONTAINER_STATUS_STOPPED) { +diff --git a/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.c b/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.c +index f61316d0..2f42909b 100644 +--- a/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.c ++++ b/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.c +@@ -16,15 +16,18 @@ + #include <stdio.h> + #include <limits.h> + #include <errno.h> +-#include <isula_libutils/defs.h> +-#include <isula_libutils/host_config.h> + #include <stdint.h> + #include <stdlib.h> + #include <string.h> + #include <strings.h> + ++#include <isula_libutils/log.h> ++#include <isula_libutils/defs.h> ++#include <isula_libutils/host_config.h> ++#include <isula_libutils/auto_cleanup.h> ++#include <isula_libutils/oci_runtime_spec.h> ++ + #include "lcr_rt_ops.h" +-#include "isula_libutils/log.h" + #include "engine.h" + #include "error.h" + #include "isulad_config.h" +@@ -32,6 +35,8 @@ + #include "runtime_api.h" + #include "utils_file.h" + ++#define LCR_CONFIG_FILE "config" ++ + bool rt_lcr_detect(const char *runtime) + { + /* now we just support lcr engine */ +@@ -276,6 +281,17 @@ int rt_lcr_status(const char *name, const char *runtime, const rt_status_params_ + nret = engine_ops->engine_get_container_status_op(name, params->rootpath, status); + if (nret != 0) { + ret = -1; ++ const char *tmpmsg = NULL; ++ if (engine_ops->engine_get_errmsg_op != NULL) { ++ tmpmsg = engine_ops->engine_get_errmsg_op(); ++ } ++ if (tmpmsg != NULL && strstr(tmpmsg, "Failed to load config") != NULL) { ++ status->error_code = INVALID_CONFIG_ERR_CODE; ++ } ++ isulad_set_error_message("Runtime state container error: %s", ++ (tmpmsg != NULL && strcmp(tmpmsg, DEF_SUCCESS_STR)) != 0 ? tmpmsg : DEF_ERR_RUNTIME_STR); ++ ERROR("Runtime state container error: %s", ++ (tmpmsg != NULL && strcmp(tmpmsg, DEF_SUCCESS_STR)) != 0 ? tmpmsg : DEF_ERR_RUNTIME_STR); + goto out; + } + +@@ -756,3 +772,80 @@ int rt_lcr_kill(const char *id, const char *runtime, const rt_kill_params_t *par + + return 0; + } ++ ++int rt_lcr_rebuild_config(const char *name, const char *runtime, const rt_rebuild_config_params_t *params) ++{ ++ int ret = -1; ++ int nret = 0; ++ char config_file[PATH_MAX] = { 0 }; ++ char bak_config_file[PATH_MAX] = { 0 }; ++ char oci_config_file[PATH_MAX] = { 0 }; ++ struct engine_operation *engine_ops = NULL; ++ oci_runtime_spec *oci_spec = NULL; ++ __isula_auto_free char *json_container = NULL; ++ __isula_auto_free parser_error err = NULL; ++ ++ engine_ops = engines_get_handler(runtime); ++ if (engine_ops == NULL || engine_ops->engine_create_op == NULL) { ++ ERROR("Failed to get engine rebuild config operations"); ++ return -1; ++ } ++ ++ nret = snprintf(config_file, PATH_MAX, "%s/%s/%s", params->rootpath, name, LCR_CONFIG_FILE); ++ if (nret < 0 || (size_t)nret >= PATH_MAX) { ++ ERROR("Failed to snprintf config file for container %s", name); ++ return -1; ++ } ++ ++ nret = snprintf(bak_config_file, PATH_MAX, "%s/%s/%s", params->rootpath, name, ".tmp_config_bak"); ++ if (nret < 0 || (size_t)nret >= PATH_MAX) { ++ ERROR("Failed to snprintf bak config file for container %s", name); ++ return -1; ++ } ++ ++ nret = snprintf(oci_config_file, sizeof(oci_config_file), "%s/%s/%s", params->rootpath, name, OCI_CONFIG_JSON); ++ if (nret < 0 || (size_t)nret >= sizeof(oci_config_file)) { ++ ERROR("Failed to snprintf for config json"); ++ return -1; ++ } ++ ++ oci_spec = oci_runtime_spec_parse_file(oci_config_file, NULL, &err); ++ if (oci_spec == NULL) { ++ ERROR("Failed to parse oci config file:%s", err); ++ return -1; ++ } ++ ++ // delete the bak config file to prevent the remnants of the previous bak file ++ if (util_fileself_exists(bak_config_file) && util_path_remove(bak_config_file) != 0) { ++ ERROR("Failed to remove bak_config_file for container: %s", name); ++ goto out; ++ } ++ ++ if (util_fileself_exists(config_file) && rename(config_file, bak_config_file) != 0) { ++ ERROR("Failed to backup old config for container: %s", name); ++ goto out; ++ } ++ ++ nret = engine_ops->engine_create_op(name, params->rootpath, (void *)oci_spec); ++ if (nret != 0) { ++ // delete the invalid config file to prevent rename failed ++ if (util_fileself_exists(config_file) && util_path_remove(config_file) != 0) { ++ WARN("Failed to remove bak_config_file for container %s", name); ++ } ++ if (util_fileself_exists(bak_config_file) && rename(bak_config_file, config_file) != 0) { ++ WARN("Failed to rename backup old config to config for container %s", name); ++ } ++ } ++ ++ ret = 0; ++ ++out: ++ if (engine_ops != NULL && engine_ops->engine_clear_errmsg_op != NULL) { ++ engine_ops->engine_clear_errmsg_op(); ++ } ++ if (util_fileself_exists(bak_config_file) && util_path_remove(bak_config_file) != 0) { ++ WARN("Failed to remove bak_config_file for %s", name); ++ } ++ free_oci_runtime_spec(oci_spec); ++ return ret; ++} +diff --git a/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.h b/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.h +index 5b74ad6c..7403544d 100644 +--- a/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.h ++++ b/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.h +@@ -47,6 +47,7 @@ int rt_lcr_resources_stats(const char *name, const char *runtime, const rt_stats + int rt_lcr_resize(const char *id, const char *runtime, const rt_resize_params_t *params); + int rt_lcr_exec_resize(const char *id, const char *runtime, const rt_exec_resize_params_t *params); + int rt_lcr_kill(const char *id, const char *runtime, const rt_kill_params_t *params); ++int rt_lcr_rebuild_config(const char *name, const char *runtime, const rt_rebuild_config_params_t *params); + #ifdef __cplusplus + } + #endif +diff --git a/src/daemon/modules/runtime/isula/isula_rt_ops.c b/src/daemon/modules/runtime/isula/isula_rt_ops.c +index 1787170b..83214c1a 100644 +--- a/src/daemon/modules/runtime/isula/isula_rt_ops.c ++++ b/src/daemon/modules/runtime/isula/isula_rt_ops.c +@@ -2013,3 +2013,9 @@ int rt_isula_kill(const char *id, const char *runtime, const rt_kill_params_t *p + + return 0; + } ++ ++// the config file of oci runtime is config.json. If it is damaged, it cannot be rebuilt. ++int rt_isula_rebuild_config(const char *name, const char *runtime, const rt_rebuild_config_params_t *params) ++{ ++ return 0; ++} +\ No newline at end of file +diff --git a/src/daemon/modules/runtime/isula/isula_rt_ops.h b/src/daemon/modules/runtime/isula/isula_rt_ops.h +index 49b6cc0e..1e5e049a 100644 +--- a/src/daemon/modules/runtime/isula/isula_rt_ops.h ++++ b/src/daemon/modules/runtime/isula/isula_rt_ops.h +@@ -46,6 +46,7 @@ int rt_isula_resources_stats(const char *name, const char *runtime, const rt_sta + int rt_isula_resize(const char *id, const char *runtime, const rt_resize_params_t *params); + int rt_isula_exec_resize(const char *id, const char *runtime, const rt_exec_resize_params_t *params); + int rt_isula_kill(const char *id, const char *runtime, const rt_kill_params_t *params); ++int rt_isula_rebuild_config(const char *name, const char *runtime, const rt_rebuild_config_params_t *params); + + #ifdef __cplusplus + } +diff --git a/src/daemon/modules/runtime/runtime.c b/src/daemon/modules/runtime/runtime.c +index cb383970..d9a332af 100644 +--- a/src/daemon/modules/runtime/runtime.c ++++ b/src/daemon/modules/runtime/runtime.c +@@ -45,6 +45,7 @@ static const struct rt_ops g_lcr_rt_ops = { + .rt_resize = rt_lcr_resize, + .rt_exec_resize = rt_lcr_exec_resize, + .rt_kill = rt_lcr_kill, ++ .rt_rebuild_config = rt_lcr_rebuild_config, + }; + + static const struct rt_ops g_isula_rt_ops = { +@@ -65,6 +66,7 @@ static const struct rt_ops g_isula_rt_ops = { + .rt_resize = rt_isula_resize, + .rt_exec_resize = rt_isula_exec_resize, + .rt_kill = rt_isula_kill, ++ .rt_rebuild_config = rt_isula_rebuild_config, + }; + + #ifdef ENABLE_SHIM_V2 +@@ -86,6 +88,7 @@ static const struct rt_ops g_shim_rt_ops = { + .rt_resize = rt_shim_resize, + .rt_exec_resize = rt_shim_exec_resize, + .rt_kill = rt_shim_kill, ++ .rt_rebuild_config = rt_shim_rebuild_config, + }; + #endif + +@@ -465,6 +468,27 @@ out: + return ret; + } + ++int runtime_rebuild_config(const char *name, const char *runtime, const rt_rebuild_config_params_t *params) ++{ ++ int ret = 0; ++ const struct rt_ops *ops = NULL; ++ ++ if (name == NULL || runtime == NULL || params == NULL) { ++ ERROR("Invalid arguments for runtime rebuild config"); ++ return -1; ++ } ++ ++ ops = rt_ops_query(runtime); ++ if (ops == NULL) { ++ ERROR("Failed to get runtime ops"); ++ return -1; ++ } ++ ++ ret = ops->rt_rebuild_config(name, runtime, params); ++ ++ return ret; ++} ++ + int runtime_resize(const char *name, const char *runtime, const rt_resize_params_t *params) + { + int ret = 0; +diff --git a/src/daemon/modules/runtime/shim/shim_rt_ops.c b/src/daemon/modules/runtime/shim/shim_rt_ops.c +index 550b17f3..56fc43c2 100644 +--- a/src/daemon/modules/runtime/shim/shim_rt_ops.c ++++ b/src/daemon/modules/runtime/shim/shim_rt_ops.c +@@ -805,3 +805,9 @@ int rt_shim_kill(const char *id, const char *runtime, const rt_kill_params_t *pa + + return 0; + } ++ ++// the config file of oci runtime is config.json. If it is damaged, it cannot be rebuilt. ++int rt_shim_rebuild_config(const char *name, const char *runtime, const rt_rebuild_config_params_t *params) ++{ ++ return 0; ++} +\ No newline at end of file +diff --git a/src/daemon/modules/runtime/shim/shim_rt_ops.h b/src/daemon/modules/runtime/shim/shim_rt_ops.h +index 03b7c018..2df34f4c 100644 +--- a/src/daemon/modules/runtime/shim/shim_rt_ops.h ++++ b/src/daemon/modules/runtime/shim/shim_rt_ops.h +@@ -62,6 +62,8 @@ int rt_shim_exec_resize(const char *id, const char *runtime, const rt_exec_resiz + + bool is_valid_v2_runtime(const char* name); + ++int rt_shim_rebuild_config(const char *name, const char *runtime, const rt_rebuild_config_params_t *params); ++ + #ifdef __cplusplus + } + #endif +-- +2.42.0 + |