iSulad/0019-2254-lcr-container-with-a-damaged-config-file-will-r.patch
zhongtao c36bc934aa !638 upgrade from upstream
* upgrade from upstream
2023-12-21 02:03:18 +00:00

385 lines
15 KiB
Diff

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