summaryrefslogtreecommitdiff
path: root/0019-2254-lcr-container-with-a-damaged-config-file-will-r.patch
diff options
context:
space:
mode:
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.patch384
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, &params, &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, &params, &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
+