From dd2d06b3b33244cffe4eb715cfe9ab4c898aa446 Mon Sep 17 00:00:00 2001 From: openeuler-sync-bot Date: Mon, 11 Dec 2023 14:34:37 +0000 Subject: [PATCH] !276 [sync] PR-273: sync from upstream * sync from upstream --- 0001-fix-update-cpu-rt-period-failed.patch | 4 +- 0002-fix-layer-size-type-as-int64.patch | 4 +- ...apt-to-repo-of-openeuler-url-changed.patch | 4 +- ...sources-json-schema-for-isula-update.patch | 4 +- ...-add-field-for-isulad-daemon-configs.patch | 4 +- 0006-add-files_limit-to-oci-spec.patch | 4 +- 0007-Fix-empty-pointer-and-overflow.patch | 2 +- 0008-CI-checkout-branch-of-lxc.patch | 2 +- ...ck-symbols-and-compile-code-in-cmake.patch | 2 +- 0010-remove-unnecessary-strerror.patch | 2 +- ...-258-improve-code-of-function-in-log.patch | 2 +- ...-to-avoid-invoke-lxc-binary-directly.patch | 4 +- 0013-improve-error-of-lcr-apis.patch | 169 +++++ ...rite-for-config-secomp-oci_hook-file.patch | 627 +++++++++++++++++ ...close-fd-if-fdopen-failed-and-add-ut.patch | 212 ++++++ 0016-290-fix-seccomp-write-error.patch | 25 + 0017-291-restore-using-dev-urandom.patch | 29 + ...e-fixed-tmp-file-to-write-config-etc.patch | 322 +++++++++ ...300-add-blkio-info-for-runtime-stats.patch | 64 ++ ...c-config-write-for-partial-file-does.patch | 658 ++++++++++++++++++ lcr.spec | 16 +- 21 files changed, 2140 insertions(+), 20 deletions(-) create mode 100644 0013-improve-error-of-lcr-apis.patch create mode 100644 0014-288-use-atomic-write-for-config-secomp-oci_hook-file.patch create mode 100644 0015-289-close-fd-if-fdopen-failed-and-add-ut.patch create mode 100644 0016-290-fix-seccomp-write-error.patch create mode 100644 0017-291-restore-using-dev-urandom.patch create mode 100644 0018-use-fixed-tmp-file-to-write-config-etc.patch create mode 100644 0019-300-add-blkio-info-for-runtime-stats.patch create mode 100644 0020-drop-atomic-config-write-for-partial-file-does.patch diff --git a/0001-fix-update-cpu-rt-period-failed.patch b/0001-fix-update-cpu-rt-period-failed.patch index 6fcfa18..a810321 100644 --- a/0001-fix-update-cpu-rt-period-failed.patch +++ b/0001-fix-update-cpu-rt-period-failed.patch @@ -1,7 +1,7 @@ From 42cf57e75e50457c1a4ee28d286aa4644c9c266a Mon Sep 17 00:00:00 2001 From: songbuhuang <544824346@qq.com> Date: Wed, 8 Feb 2023 10:40:20 +0800 -Subject: [PATCH 1/2] fix update cpu-rt period failed +Subject: [PATCH 01/20] fix update cpu-rt period failed Signed-off-by: songbuhuang <544824346@qq.com> --- @@ -33,5 +33,5 @@ index ac49c50..4c49a28 100644 err_out: return ret; -- -2.25.1 +2.33.0 diff --git a/0002-fix-layer-size-type-as-int64.patch b/0002-fix-layer-size-type-as-int64.patch index 35f55af..1d20177 100644 --- a/0002-fix-layer-size-type-as-int64.patch +++ b/0002-fix-layer-size-type-as-int64.patch @@ -1,7 +1,7 @@ From 9e9fbc213ce485a53b8dee07ad923369096ae899 Mon Sep 17 00:00:00 2001 From: "Neil.wrz" Date: Mon, 20 Feb 2023 22:24:30 -0800 -Subject: [PATCH 2/2] fix layer size type as int64 +Subject: [PATCH 02/20] fix layer size type as int64 Signed-off-by: Neil.wrz --- @@ -22,5 +22,5 @@ index 44f31db..78cc68c 100644 "digest": { "$ref": "../defs.json#/definitions/digest" -- -2.25.1 +2.33.0 diff --git a/0003-adapt-to-repo-of-openeuler-url-changed.patch b/0003-adapt-to-repo-of-openeuler-url-changed.patch index 7a5e112..24fe261 100644 --- a/0003-adapt-to-repo-of-openeuler-url-changed.patch +++ b/0003-adapt-to-repo-of-openeuler-url-changed.patch @@ -1,7 +1,7 @@ From 2e6991000d0e1e42db9f054400949543a1a44520 Mon Sep 17 00:00:00 2001 From: zhongtao Date: Mon, 6 Mar 2023 15:24:59 +0800 -Subject: [PATCH 3/6] adapt to repo of openeuler url changed +Subject: [PATCH 03/20] adapt to repo of openeuler url changed Signed-off-by: zhongtao --- @@ -29,5 +29,5 @@ index ae1e8ef..1a15461 100755 cd ~ -- -2.25.1 +2.33.0 diff --git a/0004-add-cgroup-resources-json-schema-for-isula-update.patch b/0004-add-cgroup-resources-json-schema-for-isula-update.patch index 338a27c..50e505b 100644 --- a/0004-add-cgroup-resources-json-schema-for-isula-update.patch +++ b/0004-add-cgroup-resources-json-schema-for-isula-update.patch @@ -1,7 +1,7 @@ From 3f1ef0eeb7fe469bfc42e1ea6726ec91a97e165d Mon Sep 17 00:00:00 2001 From: zhongtao Date: Wed, 15 Feb 2023 16:05:39 +0800 -Subject: [PATCH 4/6] add cgroup resources json schema for isula update +Subject: [PATCH 04/20] add cgroup resources json schema for isula update Signed-off-by: zhongtao --- @@ -96,5 +96,5 @@ index 6ed9473..ae77e9d 100644 "type": "object", "properties": { -- -2.25.1 +2.33.0 diff --git a/0005-add-field-for-isulad-daemon-configs.patch b/0005-add-field-for-isulad-daemon-configs.patch index 6e07a7b..dbf9676 100644 --- a/0005-add-field-for-isulad-daemon-configs.patch +++ b/0005-add-field-for-isulad-daemon-configs.patch @@ -1,7 +1,7 @@ From 558723cf5f1506538822e716b5b9ae7ee84736f6 Mon Sep 17 00:00:00 2001 From: "Neil.wrz" Date: Wed, 15 Feb 2023 19:11:45 -0800 -Subject: [PATCH 5/6] add field for isulad daemon configs +Subject: [PATCH 05/20] add field for isulad daemon configs Signed-off-by: Neil.wrz --- @@ -23,5 +23,5 @@ index 1332a73..b75e929 100644 "type": "string" }, -- -2.25.1 +2.33.0 diff --git a/0006-add-files_limit-to-oci-spec.patch b/0006-add-files_limit-to-oci-spec.patch index de03a8c..6ed0ef0 100644 --- a/0006-add-files_limit-to-oci-spec.patch +++ b/0006-add-files_limit-to-oci-spec.patch @@ -1,7 +1,7 @@ From fe5de86ac3df1ba26f50f0eacdfb525e52f33573 Mon Sep 17 00:00:00 2001 From: zhongtao Date: Sat, 8 Apr 2023 11:38:50 +0800 -Subject: [PATCH 6/6] add files_limit to oci spec +Subject: [PATCH 06/20] add files_limit to oci spec Signed-off-by: zhongtao --- @@ -33,5 +33,5 @@ index 317cab4..27b2de2 100644 "id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO", "type": "object", -- -2.25.1 +2.33.0 diff --git a/0007-Fix-empty-pointer-and-overflow.patch b/0007-Fix-empty-pointer-and-overflow.patch index cef10e6..54a2302 100644 --- a/0007-Fix-empty-pointer-and-overflow.patch +++ b/0007-Fix-empty-pointer-and-overflow.patch @@ -1,7 +1,7 @@ From 2df5066a9741e9534d13bc422dad69bb6a2c12ce Mon Sep 17 00:00:00 2001 From: jikai Date: Mon, 28 Aug 2023 12:59:08 +0000 -Subject: [PATCH 07/11] Fix empty pointer and overflow +Subject: [PATCH 07/20] Fix empty pointer and overflow Signed-off-by: jikai --- diff --git a/0008-CI-checkout-branch-of-lxc.patch b/0008-CI-checkout-branch-of-lxc.patch index 0f94cf9..31b3958 100644 --- a/0008-CI-checkout-branch-of-lxc.patch +++ b/0008-CI-checkout-branch-of-lxc.patch @@ -1,7 +1,7 @@ From 3ddbf5130eb24e7a2e9f70c3e6c494afa0015e92 Mon Sep 17 00:00:00 2001 From: jikai Date: Tue, 29 Aug 2023 02:38:14 +0000 -Subject: [PATCH 08/11] CI: checkout branch of lxc +Subject: [PATCH 08/20] CI: checkout branch of lxc Signed-off-by: jikai --- diff --git a/0009-support-check-symbols-and-compile-code-in-cmake.patch b/0009-support-check-symbols-and-compile-code-in-cmake.patch index 450cb5d..b89cf6b 100644 --- a/0009-support-check-symbols-and-compile-code-in-cmake.patch +++ b/0009-support-check-symbols-and-compile-code-in-cmake.patch @@ -1,7 +1,7 @@ From 2f0562d56032a563672ae105b7b3ca1b71878526 Mon Sep 17 00:00:00 2001 From: haozi007 Date: Sat, 26 Aug 2023 10:54:02 +0800 -Subject: [PATCH 09/11] support check symbols and compile code in cmake +Subject: [PATCH 09/20] support check symbols and compile code in cmake Signed-off-by: haozi007 --- diff --git a/0010-remove-unnecessary-strerror.patch b/0010-remove-unnecessary-strerror.patch index 2a21272..e0a997d 100644 --- a/0010-remove-unnecessary-strerror.patch +++ b/0010-remove-unnecessary-strerror.patch @@ -1,7 +1,7 @@ From 41aa94a5859755ed4ca181043dd442401fd068ea Mon Sep 17 00:00:00 2001 From: haozi007 Date: Tue, 5 Sep 2023 19:35:37 +0800 -Subject: [PATCH 10/11] remove unnecessary strerror +Subject: [PATCH 10/20] remove unnecessary strerror Signed-off-by: haozi007 --- diff --git a/0011-258-improve-code-of-function-in-log.patch b/0011-258-improve-code-of-function-in-log.patch index d2fab5c..6537fa4 100644 --- a/0011-258-improve-code-of-function-in-log.patch +++ b/0011-258-improve-code-of-function-in-log.patch @@ -1,7 +1,7 @@ From 67db677060c70aa23e6927e99cc2078e219b9d2d Mon Sep 17 00:00:00 2001 From: haozi007 Date: Wed, 6 Sep 2023 11:01:47 +0000 -Subject: [PATCH 11/11] !258 improve code of function in log Merge pull request +Subject: [PATCH 11/20] !258 improve code of function in log Merge pull request !258 from haozi007/stablefix --- diff --git a/0012-265-set-env-to-avoid-invoke-lxc-binary-directly.patch b/0012-265-set-env-to-avoid-invoke-lxc-binary-directly.patch index ffb6917..a06a1b6 100644 --- a/0012-265-set-env-to-avoid-invoke-lxc-binary-directly.patch +++ b/0012-265-set-env-to-avoid-invoke-lxc-binary-directly.patch @@ -1,7 +1,7 @@ From 235048833fbd12ddb19dee74df5a13a26bfe5e6b Mon Sep 17 00:00:00 2001 From: jake Date: Mon, 18 Sep 2023 11:07:42 +0000 -Subject: [PATCH 12/12] !265 set env to avoid invoke lxc binary directly * set +Subject: [PATCH 12/20] !265 set env to avoid invoke lxc binary directly * set env to avoid invoke lxc binary directly --- @@ -26,5 +26,5 @@ index f65f570..5c69c8e 100644 } -- -2.34.1 +2.33.0 diff --git a/0013-improve-error-of-lcr-apis.patch b/0013-improve-error-of-lcr-apis.patch new file mode 100644 index 0000000..a8487a0 --- /dev/null +++ b/0013-improve-error-of-lcr-apis.patch @@ -0,0 +1,169 @@ +From ffd58bff069d0d1bde6a6ad14f4c2b81fac237c8 Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Thu, 16 Nov 2023 10:58:52 +0800 +Subject: [PATCH 13/20] improve error of lcr apis + +Signed-off-by: haozi007 +--- + src/error.h | 1 + + src/lcrcontainer.c | 41 +++++++++++++++++++++++++++-------------- + 2 files changed, 28 insertions(+), 14 deletions(-) + +diff --git a/src/error.h b/src/error.h +index bc7bcb3..e2ad20b 100644 +--- a/src/error.h ++++ b/src/error.h +@@ -50,6 +50,7 @@ extern __thread engine_error_t g_lcr_error; + XX(ERR_FORMAT, "Error message is too long") \ + XX(ERR_INPUT, "Invalid input parameter") \ + XX(ERR_INTERNAL, "Server internal error") \ ++ XX(ERR_CONFIG, "Invalid container config") \ + \ + /* err in runtime module */ \ + XX(ERR_RUNTIME, DEF_ERR_RUNTIME_STR) \ +diff --git a/src/lcrcontainer.c b/src/lcrcontainer.c +index 5c69c8e..4256799 100644 +--- a/src/lcrcontainer.c ++++ b/src/lcrcontainer.c +@@ -353,7 +353,8 @@ bool lcr_kill(const char *name, const char *lcrpath, uint32_t signal) + + c = lxc_container_new(name, path); + if (c == NULL) { +- ERROR("Failed to stop container."); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for kill: %s", name); ++ ERROR("Failed to load config for kill: %s.", name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -401,7 +402,8 @@ bool lcr_delete(const char *name, const char *lcrpath) + isula_libutils_set_log_prefix(name); + c = lxc_container_new(name, path); + if (c == NULL) { +- ERROR("Failed to delete container."); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for delete: %s", name); ++ ERROR("Failed to load config for delete: %s.", name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -474,7 +476,8 @@ bool lcr_exec(const struct lcr_exec_request *request, int *exit_code) + + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to delete container."); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for exec: %s", name); ++ ERROR("Failed to load config for exec: %s.", name); + goto out; + } + +@@ -519,7 +522,8 @@ bool lcr_clean(const char *name, const char *lcrpath, const char *logpath, const + + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to delete container."); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for clean: %s", name); ++ ERROR("Failed to load config for clean: %s.", name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -563,7 +567,8 @@ bool lcr_state(const char *name, const char *lcrpath, struct lcr_container_state + isula_libutils_set_log_prefix(name); + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failure to retrieve state infomation on %s", tmp_path); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for state: %s", name); ++ ERROR("Failed to load config %s for state: %s", tmp_path, name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -600,7 +605,8 @@ bool lcr_get_container_pids(const char *name, const char *lcrpath, pid_t **pids, + isula_libutils_set_log_prefix(name); + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failure to retrieve state infomation on %s", tmp_path); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for get pids of: %s", name); ++ ERROR("Failed to load config for get pids of: %s", name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -651,7 +657,8 @@ bool lcr_pause(const char *name, const char *lcrpath) + isula_libutils_set_log_prefix(name); + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to pause container"); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for pause: %s", name); ++ ERROR("Failed to load config for pause: %s.", name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -694,7 +701,8 @@ bool lcr_resume(const char *name, const char *lcrpath) + isula_libutils_set_log_prefix(name); + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to resume container"); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for resume: %s", name); ++ ERROR("Failed to load config for resume: %s.", name); + goto out; + } + +@@ -738,7 +746,8 @@ bool lcr_resize(const char *name, const char *lcrpath, unsigned int height, unsi + isula_libutils_set_log_prefix(name); + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to pause container"); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for resize: %s", name); ++ ERROR("Failed to load config for resize: %s", name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -761,7 +770,7 @@ bool lcr_resize(const char *name, const char *lcrpath, unsigned int height, unsi + } + + if (!c->set_terminal_winch(c, height, width)) { +- ERROR("Failed to pause"); ++ ERROR("Failed to resize: %s", name); + bret = false; + goto out_put; + } +@@ -788,7 +797,8 @@ bool lcr_exec_resize(const char *name, const char *lcrpath, const char *suffix, + isula_libutils_set_log_prefix(name); + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to pause container"); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for exec resize: %s", name); ++ ERROR("Failed to load config for exec resize: %s.", name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -837,7 +847,8 @@ bool lcr_console(const char *name, const char *lcrpath, const char *in_fifo, con + + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to create container."); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for attach: %s", name); ++ ERROR("Failed to load config for attach: %s.", name); + bresult = false; + goto out; + } +@@ -977,7 +988,8 @@ bool lcr_get_console_config(const char *name, const char *lcrpath, struct lcr_co + isula_libutils_set_log_prefix(name); + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to create container."); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for get console config of: %s", name); ++ ERROR("Failed to load config for get config of: %s.", name); + isula_libutils_free_log_prefix(); + return false; + } +@@ -1027,7 +1039,8 @@ bool lcr_update(const char *name, const char *lcrpath, const struct lcr_cgroup_r + + c = lxc_container_new(name, tmp_path); + if (c == NULL) { +- ERROR("Failed to new container."); ++ lcr_set_error_message(LCR_ERR_CONFIG, "Failed to load config for udpate: %s", name); ++ ERROR("Failed to load config for update: %s.", name); + goto out_free; + } + +-- +2.33.0 + diff --git a/0014-288-use-atomic-write-for-config-secomp-oci_hook-file.patch b/0014-288-use-atomic-write-for-config-secomp-oci_hook-file.patch new file mode 100644 index 0000000..2a33d82 --- /dev/null +++ b/0014-288-use-atomic-write-for-config-secomp-oci_hook-file.patch @@ -0,0 +1,627 @@ +From 713d31dfeb4425cfb40f565436504f4056ebe548 Mon Sep 17 00:00:00 2001 +From: jake +Date: Tue, 21 Nov 2023 02:45:37 +0000 +Subject: [PATCH 14/20] !288 use atomic write for config, secomp, oci_hook + files * use atomic write for config, secomp, oci_hook files + +--- + src/conf.c | 2 +- + src/lcrcontainer_extend.c | 150 ++++++++++----------- + src/utils.c | 268 +++++++++++++++++++++++++++++++++++++- + src/utils.h | 6 +- + 4 files changed, 343 insertions(+), 83 deletions(-) + +diff --git a/src/conf.c b/src/conf.c +index 10214f0..bfbfe1a 100644 +--- a/src/conf.c ++++ b/src/conf.c +@@ -1241,7 +1241,7 @@ static int trans_one_oci_id_mapping(struct lcr_list *conf, const char *typ, cons + if (nret < 0 || (size_t)nret >= sizeof(subid)) { + return -1; + } +- nret = lcr_util_atomic_write_file(path, subid); ++ nret = lcr_util_flock_append_file(path, subid); + if (nret < 0) { + return -1; + } +diff --git a/src/lcrcontainer_extend.c b/src/lcrcontainer_extend.c +index 321be8c..b3202a7 100644 +--- a/src/lcrcontainer_extend.c ++++ b/src/lcrcontainer_extend.c +@@ -346,7 +346,7 @@ out: + return ret; + } + +-static int lcr_spec_write_seccomp_line(int fd, const char *seccomp) ++static int lcr_spec_write_seccomp_line(FILE *fp, const char *seccomp) + { + size_t len; + char *line = NULL; +@@ -371,14 +371,17 @@ static int lcr_spec_write_seccomp_line(int fd, const char *seccomp) + ERROR("Sprintf failed"); + goto cleanup; + } ++ + if ((size_t)nret > len - 1) { + nret = (int)(len - 1); + } ++ + line[nret] = '\n'; +- if (write(fd, line, len) == -1) { ++ if (fwrite(line, 1, len ,fp) != len) { + SYSERROR("Write file failed"); + goto cleanup; + } ++ + ret = 0; + cleanup: + free(line); +@@ -389,9 +392,7 @@ static char *lcr_save_seccomp_file(const char *bundle, const char *seccomp_conf) + { + char seccomp[PATH_MAX] = { 0 }; + char *real_seccomp = NULL; +- int fd = -1; + int nret; +- ssize_t written_cnt; + + nret = snprintf(seccomp, sizeof(seccomp), "%s/seccomp", bundle); + if (nret < 0 || (size_t)nret >= sizeof(seccomp)) { +@@ -404,16 +405,9 @@ static char *lcr_save_seccomp_file(const char *bundle, const char *seccomp_conf) + goto cleanup; + } + +- fd = lcr_util_open(real_seccomp, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); +- if (fd == -1) { +- SYSERROR("Create file %s failed", real_seccomp); +- goto cleanup; +- } +- +- written_cnt = write(fd, seccomp_conf, strlen(seccomp_conf)); +- close(fd); +- if (written_cnt == -1) { +- SYSERROR("write seccomp_conf failed"); ++ if (lcr_util_atomic_write_file(real_seccomp, seccomp_conf, strlen(seccomp_conf), ++ CONFIG_FILE_MODE, false) != -1) { ++ ERROR("write seccomp_conf failed"); + goto cleanup; + } + return real_seccomp; +@@ -605,34 +599,51 @@ out_free: + return NULL; + } + +- +-static int lcr_open_config_file(const char *bundle) ++static FILE *lcr_open_tmp_config_file(const char *bundle, char **config_file, char **tmp_file) + { + char config[PATH_MAX] = { 0 }; +- char *real_config = NULL; + int fd = -1; + int nret; ++ FILE *fp = NULL; + + nret = snprintf(config, sizeof(config), "%s/config", bundle); + if (nret < 0 || (size_t)nret >= sizeof(config)) { + goto out; + } + +- nret = lcr_util_ensure_path(&real_config, config); ++ nret = lcr_util_ensure_path(config_file, config); + if (nret < 0) { + ERROR("Failed to ensure path %s", config); + goto out; + } + +- fd = lcr_util_open(real_config, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); ++ *tmp_file = lcr_util_get_random_tmp_file(*config_file); ++ if (*tmp_file == NULL) { ++ ERROR("Failed to get random tmp file for %s", *config_file); ++ goto out; ++ } ++ ++ fd = lcr_util_open(*tmp_file, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); + if (fd == -1) { +- SYSERROR("Create file %s failed", real_config); +- lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed", real_config); ++ SYSERROR("Create file %s failed", *tmp_file); ++ lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed", *tmp_file); ++ goto out; ++ } ++ ++ fp = fdopen(fd, "w"); ++ if (fp == NULL) { ++ ERROR("FILE open failed"); + goto out; + } ++ + out: +- free(real_config); +- return fd; ++ if (fp == NULL) { ++ free(*tmp_file); ++ *tmp_file = NULL; ++ free(*config_file); ++ *config_file = NULL; ++ } ++ return fp; + } + + // escape_string_encode unzip some escape characters +@@ -698,18 +709,17 @@ static char *escape_string_encode(const char *src) + return dst; + } + +-static int lcr_spec_write_config(int fd, const struct lcr_list *lcr_conf) ++static int lcr_spec_write_config(FILE *fp, const struct lcr_list *lcr_conf) + { +- struct lcr_list *it = NULL; + size_t len; +- char *line = NULL; +- char *line_encode = NULL; + int ret = -1; ++ struct lcr_list *it = NULL; ++ char *line_encode = NULL; ++ char *line = NULL; + + lcr_list_for_each(it, lcr_conf) { + lcr_config_item_t *item = it->elem; + int nret; +- size_t encode_len; + if (item != NULL) { + if (strlen(item->value) > ((SIZE_MAX - strlen(item->name)) - 4)) { + goto cleanup; +@@ -722,7 +732,6 @@ static int lcr_spec_write_config(int fd, const struct lcr_list *lcr_conf) + } + + nret = snprintf(line, len, "%s = %s", item->name, item->value); +- + if (nret < 0 || (size_t)nret >= len) { + ERROR("Sprintf failed"); + goto cleanup; +@@ -734,19 +743,21 @@ static int lcr_spec_write_config(int fd, const struct lcr_list *lcr_conf) + goto cleanup; + } + +- encode_len = strlen(line_encode); ++ len = strlen(line_encode); ++ line_encode[len] = '\n'; + +- line_encode[encode_len] = '\n'; +- if (write(fd, line_encode, encode_len + 1) == -1) { ++ if (fwrite(line_encode, 1, len + 1, fp) != len + 1) { + SYSERROR("Write file failed"); + goto cleanup; + } ++ + free(line); + line = NULL; + free(line_encode); + line_encode = NULL; + } + } ++ + ret = 0; + cleanup: + free(line); +@@ -804,7 +815,9 @@ bool lcr_save_spec(const char *name, const char *lcrpath, const struct lcr_list + const char *path = lcrpath ? lcrpath : LCRPATH; + char *bundle = NULL; + char *seccomp = NULL; +- int fd = -1; ++ char *config_file = NULL; ++ char *tmp_file = NULL; ++ FILE *fp = NULL; + int nret = 0; + + if (name == NULL) { +@@ -829,71 +842,47 @@ bool lcr_save_spec(const char *name, const char *lcrpath, const struct lcr_list + } + } + +- fd = lcr_open_config_file(bundle); +- if (fd == -1) { ++ fp = lcr_open_tmp_config_file(bundle, &config_file, &tmp_file); ++ if (fp == NULL) { + goto out_free; + } + +- if (lcr_spec_write_config(fd, lcr_conf)) { ++ if (lcr_spec_write_config(fp, lcr_conf)) { + goto out_free; + } + + if (seccomp_conf != NULL) { +- nret = lcr_spec_write_seccomp_line(fd, seccomp); ++ nret = lcr_spec_write_seccomp_line(fp, seccomp); + if (nret) { + goto out_free; + } + } + +- bret = true; ++ fclose(fp); ++ fp = NULL; + +-out_free: +- free(bundle); +- free(seccomp); +- if (fd != -1) { +- close(fd); +- } +- +- return bret; +-} +- +-static int lcr_write_file(const char *path, const char *data, size_t len) +-{ +- char *real_path = NULL; +- int fd = -1; +- int ret = -1; +- +- if (path == NULL || strlen(path) == 0 || data == NULL || len == 0) { +- return -1; +- } +- +- if (lcr_util_ensure_path(&real_path, path) < 0) { +- ERROR("Failed to ensure path %s", path); ++ nret = rename(tmp_file, config_file); ++ if (nret != 0) { ++ ERROR("Failed to rename old file %s to target %s", tmp_file, config_file); + goto out_free; + } + +- fd = lcr_util_open(real_path, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); +- if (fd == -1) { +- ERROR("Create file %s failed", real_path); +- lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed", real_path); +- goto out_free; +- } +- +- if (write(fd, data, len) == -1) { +- SYSERROR("write data to %s failed", real_path); +- goto out_free; +- } +- +- ret = 0; ++ bret = true; + + out_free: +- if (fd != -1) { +- close(fd); ++ if (fp != NULL) { ++ fclose(fp); + } +- free(real_path); +- return ret; +-} ++ if (!bret && unlink(tmp_file) != 0 && errno != ENOENT) { ++ SYSERROR("Failed to remove temp file:%s", tmp_file); ++ } ++ free(config_file); ++ free(tmp_file); ++ free(seccomp); ++ free(bundle); + ++ return bret; ++} + + static bool lcr_write_ocihooks(const char *path, const oci_runtime_spec_hooks *hooks) + { +@@ -907,8 +896,9 @@ static bool lcr_write_ocihooks(const char *path, const oci_runtime_spec_hooks *h + goto out_free; + } + +- if (lcr_write_file(path, json_hooks, strlen(json_hooks)) == -1) { +- SYSERROR("write json hooks failed"); ++ if (lcr_util_atomic_write_file(path, json_hooks, strlen(json_hooks), ++ CONFIG_FILE_MODE, false) == -1) { ++ ERROR("write json hooks failed"); + goto out_free; + } + +diff --git a/src/utils.c b/src/utils.c +index df73985..68e9bc4 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -1248,7 +1248,7 @@ out: + return ret; + } + +-int lcr_util_atomic_write_file(const char *filepath, const char *content) ++int lcr_util_flock_append_file(const char *filepath, const char *content) + { + int fd; + int ret = 0; +@@ -1284,6 +1284,272 @@ out: + return ret; + } + ++static char *lcr_util_path_base(const char *path) ++{ ++ char *dir = NULL; ++ int len = 0; ++ int i = 0; ++ ++ if (path == NULL) { ++ ERROR("invalid NULL param"); ++ return NULL; ++ } ++ ++ len = (int)strlen(path); ++ if (len == 0) { ++ return lcr_util_strdup_s("."); ++ } ++ ++ dir = lcr_util_strdup_s(path); ++ ++ // strip last slashes ++ for (i = len - 1; i >= 0; i--) { ++ if (dir[i] != '/') { ++ break; ++ } ++ dir[i] = '\0'; ++ } ++ ++ len = (int)strlen(dir); ++ if (len == 0) { ++ free(dir); ++ return lcr_util_strdup_s("/"); ++ } ++ ++ for (i = len - 1; i >= 0; i--) { ++ if (dir[i] == '/') { ++ break; ++ } ++ } ++ ++ if (i < 0) { ++ return dir; ++ } ++ ++ char *result = lcr_util_strdup_s(&dir[i + 1]); ++ free(dir); ++ return result; ++} ++ ++static char *lcr_util_path_dir(const char *path) ++{ ++ char *dir = NULL; ++ int len = 0; ++ int i = 0; ++ ++ if (path == NULL) { ++ ERROR("invalid NULL param"); ++ return NULL; ++ } ++ ++ len = (int)strlen(path); ++ if (len == 0) { ++ return lcr_util_strdup_s("."); ++ } ++ ++ dir = lcr_util_strdup_s(path); ++ ++ for (i = len - 1; i > 0; i--) { ++ if (dir[i] == '/') { ++ dir[i] = 0; ++ break; ++ } ++ } ++ ++ if (i == 0 && dir[0] == '/') { ++ free(dir); ++ return lcr_util_strdup_s("/"); ++ } ++ ++ return dir; ++} ++ ++static int lcr_util_generate_random_str(char *id, size_t len) ++{ ++ int fd = -1; ++ int num = 0; ++ size_t i; ++ const int m = 256; ++ ++ if (id == NULL) { ++ return -1; ++ } ++ ++ len = len / 2; ++ fd = open("/dev/urandom", O_RDONLY); ++ if (fd == -1) { ++ ERROR("Failed to open /dev/urandom"); ++ return -1; ++ } ++ for (i = 0; i < len; i++) { ++ int nret; ++ if (lcr_util_read_nointr(fd, &num, sizeof(int)) < 0) { ++ ERROR("Failed to read urandom value"); ++ close(fd); ++ return -1; ++ } ++ unsigned char rs = (unsigned char)(num % m); ++ nret = snprintf((id + i * 2), ((len - i) * 2 + 1), "%02x", (unsigned int)rs); ++ if (nret < 0 || (size_t)nret >= ((len - i) * 2 + 1)) { ++ ERROR("Failed to snprintf random string"); ++ close(fd); ++ return -1; ++ } ++ } ++ close(fd); ++ id[i * 2] = '\0'; ++ return 0; ++} ++ ++static char *lcr_util_path_join(const char *dir, const char *file) ++{ ++ int nret = 0; ++ char path[PATH_MAX] = { 0 }; ++ char cleaned[PATH_MAX] = { 0 }; ++ ++ if (dir == NULL || file == NULL) { ++ ERROR("NULL dir or file failed"); ++ return NULL; ++ } ++ ++ nret = snprintf(path, PATH_MAX, "%s/%s", dir, file); ++ if (nret < 0 || (size_t)nret >= PATH_MAX) { ++ ERROR("dir or file too long failed"); ++ return NULL; ++ } ++ ++ if (cleanpath(path, cleaned, sizeof(cleaned)) == NULL) { ++ ERROR("Failed to clean path: %s", path); ++ return NULL; ++ } ++ ++ return lcr_util_strdup_s(cleaned); ++} ++ ++char *lcr_util_get_random_tmp_file(const char *fname) ++{ ++#define RANDOM_TMP_PATH 10 ++ int nret = 0; ++ char *result = NULL; ++ char *base = NULL; ++ char *dir = NULL; ++ char rpath[PATH_MAX] = { 0x00 }; ++ char random_tmp[RANDOM_TMP_PATH + 1] = { 0x00 }; ++ ++ if (fname == NULL) { ++ ERROR("Invalid NULL param"); ++ return NULL; ++ } ++ ++ base = lcr_util_path_base(fname); ++ if (base == NULL) { ++ ERROR("Failed to get base of %s", fname); ++ goto out; ++ } ++ ++ dir = lcr_util_path_dir(fname); ++ if (dir == NULL) { ++ ERROR("Failed to get dir of %s", fname); ++ goto out; ++ } ++ ++ if (lcr_util_generate_random_str(random_tmp, (size_t)RANDOM_TMP_PATH)) { ++ ERROR("Failed to generate random str for random path"); ++ goto out; ++ } ++ ++ nret = snprintf(rpath, PATH_MAX, ".tmp-%s-%s", base, random_tmp); ++ if (nret < 0 || (size_t)nret >= PATH_MAX) { ++ ERROR("Failed to generate tmp base file"); ++ goto out; ++ } ++ ++ result = lcr_util_path_join(dir, rpath); ++ ++out: ++ free(base); ++ free(dir); ++ return result; ++} ++ ++static int do_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, bool sync) ++{ ++ int ret = 0; ++ int dst_fd = -1; ++ ssize_t len = 0; ++ ++ dst_fd = lcr_util_open(fname, O_WRONLY | O_CREAT | O_TRUNC, mode); ++ if (dst_fd < 0) { ++ SYSERROR("Creat file: %s, failed", fname); ++ ret = -1; ++ goto free_out; ++ } ++ ++ len = lcr_util_write_nointr(dst_fd, content, content_len); ++ if (len < 0 || ((size_t)len) != content_len) { ++ ret = -1; ++ SYSERROR("Write file failed"); ++ goto free_out; ++ } ++ ++ if (sync && (fdatasync(dst_fd) != 0)) { ++ ret = -1; ++ SYSERROR("Failed to sync data of file:%s", fname); ++ goto free_out; ++ } ++ ++free_out: ++ if (dst_fd >= 0) { ++ close(dst_fd); ++ } ++ return ret; ++} ++ ++int lcr_util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, bool sync) ++{ ++ int ret = 0; ++ char *tmp_file = NULL; ++ char rpath[PATH_MAX] = { 0x00 }; ++ ++ if (fname == NULL) { ++ return -1; ++ } ++ if (content == NULL || content_len == 0) { ++ return 0; ++ } ++ ++ if (cleanpath(fname, rpath, sizeof(rpath)) == NULL) { ++ return -1; ++ } ++ ++ tmp_file = lcr_util_get_random_tmp_file(fname); ++ if (tmp_file == NULL) { ++ ERROR("Failed to get tmp file for %s", fname); ++ return -1; ++ } ++ ++ ret = do_atomic_write_file(tmp_file, content, content_len, mode, sync); ++ if (ret != 0) { ++ ERROR("Failed to write content to tmp file for %s", tmp_file); ++ ret = -1; ++ goto free_out; ++ } ++ ++ ret = rename(tmp_file, rpath); ++ if (ret != 0) { ++ ERROR("Failed to rename old file %s to target %s", tmp_file, rpath); ++ ret = -1; ++ goto free_out; ++ } ++ ++free_out: ++ if (ret != 0 && unlink(tmp_file) != 0 && errno != ENOENT) { ++ SYSERROR("Failed to remove temp file:%s", tmp_file); ++ } ++ free(tmp_file); ++ return ret; ++} ++ + /* swap in oci is memoy+swap, so here we need to get real swap */ + int lcr_util_get_real_swap(int64_t memory, int64_t memory_swap, int64_t *swap) + { +diff --git a/src/utils.h b/src/utils.h +index 6a3764b..51e0dea 100644 +--- a/src/utils.h ++++ b/src/utils.h +@@ -215,7 +215,11 @@ int lcr_util_safe_llong(const char *numstr, long long *converted); + char *lcr_util_strdup_s(const char *src); + int lcr_util_null_stdfds(void); + +-int lcr_util_atomic_write_file(const char *filepath, const char *content); ++int lcr_util_flock_append_file(const char *filepath, const char *content); ++ ++char *lcr_util_get_random_tmp_file(const char *fname); ++ ++int lcr_util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, bool sync); + + int lcr_util_get_real_swap(int64_t memory, int64_t memory_swap, int64_t *swap); + int lcr_util_trans_cpushare_to_cpuweight(int64_t cpu_share); +-- +2.33.0 + diff --git a/0015-289-close-fd-if-fdopen-failed-and-add-ut.patch b/0015-289-close-fd-if-fdopen-failed-and-add-ut.patch new file mode 100644 index 0000000..5ea125f --- /dev/null +++ b/0015-289-close-fd-if-fdopen-failed-and-add-ut.patch @@ -0,0 +1,212 @@ +From a83ebe1639b4fa33177254883477ed025fc024c2 Mon Sep 17 00:00:00 2001 +From: jake +Date: Tue, 21 Nov 2023 07:17:51 +0000 +Subject: [PATCH 15/20] !289 close fd if fdopen failed and add ut * close fd if + fdopen failed * add ut for atomic write + +--- + src/lcrcontainer_extend.c | 1 + + src/utils.c | 4 +- + tests/CMakeLists.txt | 3 +- + tests/utils_ut.cpp | 140 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 145 insertions(+), 3 deletions(-) + create mode 100644 tests/utils_ut.cpp + +diff --git a/src/lcrcontainer_extend.c b/src/lcrcontainer_extend.c +index b3202a7..9136613 100644 +--- a/src/lcrcontainer_extend.c ++++ b/src/lcrcontainer_extend.c +@@ -632,6 +632,7 @@ static FILE *lcr_open_tmp_config_file(const char *bundle, char **config_file, ch + + fp = fdopen(fd, "w"); + if (fp == NULL) { ++ close(fd); + ERROR("FILE open failed"); + goto out; + } +diff --git a/src/utils.c b/src/utils.c +index 68e9bc4..59d0cea 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -1376,9 +1376,9 @@ static int lcr_util_generate_random_str(char *id, size_t len) + } + + len = len / 2; +- fd = open("/dev/urandom", O_RDONLY); ++ fd = open("/dev/random", O_RDONLY); + if (fd == -1) { +- ERROR("Failed to open /dev/urandom"); ++ ERROR("Failed to open /dev/random"); + return -1; + } + for (i = 0; i < len; i++) { +diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt +index fada476..af267d7 100644 +--- a/tests/CMakeLists.txt ++++ b/tests/CMakeLists.txt +@@ -69,6 +69,7 @@ endif() + _DEFINE_NEW_TEST(log_ut log_testcase) + _DEFINE_NEW_TEST(libocispec_ut libocispec_testcase) + _DEFINE_NEW_TEST(go_crc64_ut go_crc64_testcase) ++_DEFINE_NEW_TEST(utils_ut utils_testcase) + + + # mock test for run lcov to generate html +@@ -81,7 +82,7 @@ target_link_libraries(mock_ut + ${GTEST_LIBRARY} + pthread + ) +-add_dependencies(mock_ut log_ut libocispec_ut go_crc64_ut) ++add_dependencies(mock_ut log_ut libocispec_ut go_crc64_ut utils_ut) + + IF(ENABLE_GCOV) + add_custom_target(coverage +diff --git a/tests/utils_ut.cpp b/tests/utils_ut.cpp +new file mode 100644 +index 0000000..8acba29 +--- /dev/null ++++ b/tests/utils_ut.cpp +@@ -0,0 +1,140 @@ ++/****************************************************************************** ++ * iSula-libutils: utils library for iSula ++ * ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. ++ * ++ * Authors: ++ * jikai ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ********************************************************************************/ ++ ++#include ++ ++#include ++#include ++ ++#include "utils.h" ++ ++char *test_read_text_file(const char *path) ++{ ++ char *buf = NULL; ++ long len = 0; ++ int f_fd = -1; ++ size_t readlen = 0; ++ FILE *filp = NULL; ++ char *rpath = NULL; ++ const long max_size = 10 * 1024 * 1024; /* 10M */ ++ ++ if (path == NULL) { ++ return NULL; ++ } ++ ++ if (lcr_util_ensure_path(&rpath, path) != 0) { ++ return NULL; ++ } ++ ++ f_fd = open(rpath, O_RDONLY | O_CLOEXEC, 0666); ++ if (f_fd < 0) { ++ goto err_out; ++ } ++ ++ filp = fdopen(f_fd, "r"); ++ if (filp == NULL) { ++ close(f_fd); ++ goto err_out; ++ } ++ ++ if (fseek(filp, 0, SEEK_END)) { ++ goto err_out; ++ } ++ ++ len = ftell(filp); ++ if (len > max_size) { ++ goto err_out; ++ } ++ ++ if (fseek(filp, 0, SEEK_SET)) { ++ goto err_out; ++ } ++ ++ buf = (char *)lcr_util_common_calloc_s((size_t)(len + 1)); ++ if (buf == NULL) { ++ goto err_out; ++ } ++ ++ readlen = fread(buf, 1, (size_t)len, filp); ++ if (((readlen < (size_t)len) && (!feof(filp))) || (readlen > (size_t)len)) { ++ free(buf); ++ buf = NULL; ++ goto err_out; ++ } ++ ++ buf[(size_t)len] = 0; ++ ++err_out: ++ ++ if (filp != NULL) { ++ fclose(filp); ++ } ++ ++ free(rpath); ++ ++ return buf; ++} ++ ++TEST(utils_testcase, test_get_random_tmp_file) ++{ ++#define RANDOM_TMP_PATH 10 ++ const char *fname = "/tmp/lcr-test/test"; ++ char *tmp_file = lcr_util_get_random_tmp_file(nullptr); ++ const char *prefix = "/tmp/lcr-test/.tmp-test-"; ++ ASSERT_EQ(tmp_file, nullptr); ++ ++ tmp_file = lcr_util_get_random_tmp_file(fname); ++ ASSERT_NE(tmp_file, nullptr); ++ ++ ASSERT_EQ(strlen(tmp_file), strlen("/tmp/lcr-test/.tmp-test-") + RANDOM_TMP_PATH); ++ ASSERT_EQ(memcmp(tmp_file, prefix, strlen(prefix)), 0); ++ free(tmp_file); ++} ++ ++TEST(utils_testcase, test_atomic_write_file) ++{ ++ const char *fname = "/tmp/lcr-test/test"; ++ const char *content = "line1\nline2\n"; ++ const char *new_content = "line1\nline2\nline3\n"; ++ char *readcontent = nullptr; ++ ++ ASSERT_EQ(lcr_util_atomic_write_file(NULL, content, strlen(content), 0644, false), -1); ++ ASSERT_EQ(lcr_util_atomic_write_file(fname, NULL, 0, 0644, false), 0); ++ ++ ASSERT_EQ(lcr_util_build_dir(fname), 0); ++ ++ ASSERT_EQ(lcr_util_atomic_write_file(fname, content, strlen(content), 0644, false), 0); ++ ++ readcontent = test_read_text_file(fname); ++ ASSERT_NE(readcontent, nullptr); ++ ASSERT_STREQ(readcontent, content); ++ free(readcontent); ++ ++ ASSERT_EQ(lcr_util_atomic_write_file(fname, new_content, strlen(new_content), 0644, false), 0); ++ readcontent = test_read_text_file(fname); ++ ASSERT_NE(readcontent, nullptr); ++ ASSERT_STREQ(readcontent, new_content); ++ free(readcontent); ++ ++ ASSERT_EQ(lcr_util_recursive_rmdir("/tmp/lcr-test/", 1), 0); ++} +-- +2.33.0 + diff --git a/0016-290-fix-seccomp-write-error.patch b/0016-290-fix-seccomp-write-error.patch new file mode 100644 index 0000000..3edf8a5 --- /dev/null +++ b/0016-290-fix-seccomp-write-error.patch @@ -0,0 +1,25 @@ +From 6eeab992e06fa74b027d922057cc6d5900d438be Mon Sep 17 00:00:00 2001 +From: jake +Date: Tue, 21 Nov 2023 12:54:50 +0000 +Subject: [PATCH 16/20] !290 fix seccomp write error * fix seccomp write error + +--- + src/lcrcontainer_extend.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lcrcontainer_extend.c b/src/lcrcontainer_extend.c +index 9136613..e3c081a 100644 +--- a/src/lcrcontainer_extend.c ++++ b/src/lcrcontainer_extend.c +@@ -406,7 +406,7 @@ static char *lcr_save_seccomp_file(const char *bundle, const char *seccomp_conf) + } + + if (lcr_util_atomic_write_file(real_seccomp, seccomp_conf, strlen(seccomp_conf), +- CONFIG_FILE_MODE, false) != -1) { ++ CONFIG_FILE_MODE, false) == -1) { + ERROR("write seccomp_conf failed"); + goto cleanup; + } +-- +2.33.0 + diff --git a/0017-291-restore-using-dev-urandom.patch b/0017-291-restore-using-dev-urandom.patch new file mode 100644 index 0000000..228fbbc --- /dev/null +++ b/0017-291-restore-using-dev-urandom.patch @@ -0,0 +1,29 @@ +From a28a87c9dbbc567eebc0eebcd1e7e34db2e68817 Mon Sep 17 00:00:00 2001 +From: jake +Date: Tue, 21 Nov 2023 13:46:30 +0000 +Subject: [PATCH 17/20] !291 restore using /dev/urandom * restore using + /dev/urandom + +--- + src/utils.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/utils.c b/src/utils.c +index 59d0cea..68e9bc4 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -1376,9 +1376,9 @@ static int lcr_util_generate_random_str(char *id, size_t len) + } + + len = len / 2; +- fd = open("/dev/random", O_RDONLY); ++ fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) { +- ERROR("Failed to open /dev/random"); ++ ERROR("Failed to open /dev/urandom"); + return -1; + } + for (i = 0; i < len; i++) { +-- +2.33.0 + diff --git a/0018-use-fixed-tmp-file-to-write-config-etc.patch b/0018-use-fixed-tmp-file-to-write-config-etc.patch new file mode 100644 index 0000000..0ea7628 --- /dev/null +++ b/0018-use-fixed-tmp-file-to-write-config-etc.patch @@ -0,0 +1,322 @@ +From 4c18c29522fc35f94cae6f1e34e28bbbedef2520 Mon Sep 17 00:00:00 2001 +From: jikai +Date: Tue, 28 Nov 2023 15:59:48 +0800 +Subject: [PATCH 18/20] use fixed tmp file to write config etc + +Signed-off-by: jikai +--- + src/lcrcontainer_extend.c | 8 +-- + src/utils.c | 127 +++----------------------------------- + src/utils.h | 4 +- + tests/utils_ut.cpp | 19 +++--- + 4 files changed, 21 insertions(+), 137 deletions(-) + +diff --git a/src/lcrcontainer_extend.c b/src/lcrcontainer_extend.c +index e3c081a..0e1d926 100644 +--- a/src/lcrcontainer_extend.c ++++ b/src/lcrcontainer_extend.c +@@ -406,7 +406,7 @@ static char *lcr_save_seccomp_file(const char *bundle, const char *seccomp_conf) + } + + if (lcr_util_atomic_write_file(real_seccomp, seccomp_conf, strlen(seccomp_conf), +- CONFIG_FILE_MODE, false) == -1) { ++ CONFIG_FILE_MODE, ".tmp_seccomp_save") == -1) { + ERROR("write seccomp_conf failed"); + goto cleanup; + } +@@ -617,7 +617,7 @@ static FILE *lcr_open_tmp_config_file(const char *bundle, char **config_file, ch + goto out; + } + +- *tmp_file = lcr_util_get_random_tmp_file(*config_file); ++ *tmp_file = lcr_util_get_tmp_file(*config_file, ".tmp_config_save"); + if (*tmp_file == NULL) { + ERROR("Failed to get random tmp file for %s", *config_file); + goto out; +@@ -874,7 +874,7 @@ out_free: + if (fp != NULL) { + fclose(fp); + } +- if (!bret && unlink(tmp_file) != 0 && errno != ENOENT) { ++ if (!bret && tmp_file != NULL && unlink(tmp_file) != 0 && errno != ENOENT) { + SYSERROR("Failed to remove temp file:%s", tmp_file); + } + free(config_file); +@@ -898,7 +898,7 @@ static bool lcr_write_ocihooks(const char *path, const oci_runtime_spec_hooks *h + } + + if (lcr_util_atomic_write_file(path, json_hooks, strlen(json_hooks), +- CONFIG_FILE_MODE, false) == -1) { ++ CONFIG_FILE_MODE, ".tmp_ocihooks_save") == -1) { + ERROR("write json hooks failed"); + goto out_free; + } +diff --git a/src/utils.c b/src/utils.c +index 68e9bc4..85874a7 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -1284,53 +1284,6 @@ out: + return ret; + } + +-static char *lcr_util_path_base(const char *path) +-{ +- char *dir = NULL; +- int len = 0; +- int i = 0; +- +- if (path == NULL) { +- ERROR("invalid NULL param"); +- return NULL; +- } +- +- len = (int)strlen(path); +- if (len == 0) { +- return lcr_util_strdup_s("."); +- } +- +- dir = lcr_util_strdup_s(path); +- +- // strip last slashes +- for (i = len - 1; i >= 0; i--) { +- if (dir[i] != '/') { +- break; +- } +- dir[i] = '\0'; +- } +- +- len = (int)strlen(dir); +- if (len == 0) { +- free(dir); +- return lcr_util_strdup_s("/"); +- } +- +- for (i = len - 1; i >= 0; i--) { +- if (dir[i] == '/') { +- break; +- } +- } +- +- if (i < 0) { +- return dir; +- } +- +- char *result = lcr_util_strdup_s(&dir[i + 1]); +- free(dir); +- return result; +-} +- + static char *lcr_util_path_dir(const char *path) + { + char *dir = NULL; +@@ -1364,43 +1317,6 @@ static char *lcr_util_path_dir(const char *path) + return dir; + } + +-static int lcr_util_generate_random_str(char *id, size_t len) +-{ +- int fd = -1; +- int num = 0; +- size_t i; +- const int m = 256; +- +- if (id == NULL) { +- return -1; +- } +- +- len = len / 2; +- fd = open("/dev/urandom", O_RDONLY); +- if (fd == -1) { +- ERROR("Failed to open /dev/urandom"); +- return -1; +- } +- for (i = 0; i < len; i++) { +- int nret; +- if (lcr_util_read_nointr(fd, &num, sizeof(int)) < 0) { +- ERROR("Failed to read urandom value"); +- close(fd); +- return -1; +- } +- unsigned char rs = (unsigned char)(num % m); +- nret = snprintf((id + i * 2), ((len - i) * 2 + 1), "%02x", (unsigned int)rs); +- if (nret < 0 || (size_t)nret >= ((len - i) * 2 + 1)) { +- ERROR("Failed to snprintf random string"); +- close(fd); +- return -1; +- } +- } +- close(fd); +- id[i * 2] = '\0'; +- return 0; +-} +- + static char *lcr_util_path_join(const char *dir, const char *file) + { + int nret = 0; +@@ -1426,53 +1342,30 @@ static char *lcr_util_path_join(const char *dir, const char *file) + return lcr_util_strdup_s(cleaned); + } + +-char *lcr_util_get_random_tmp_file(const char *fname) ++char *lcr_util_get_tmp_file(const char *fname, const char *tmp_name) + { +-#define RANDOM_TMP_PATH 10 +- int nret = 0; + char *result = NULL; +- char *base = NULL; + char *dir = NULL; +- char rpath[PATH_MAX] = { 0x00 }; +- char random_tmp[RANDOM_TMP_PATH + 1] = { 0x00 }; + +- if (fname == NULL) { ++ if (fname == NULL || tmp_name == NULL) { + ERROR("Invalid NULL param"); + return NULL; + } + +- base = lcr_util_path_base(fname); +- if (base == NULL) { +- ERROR("Failed to get base of %s", fname); +- goto out; +- } +- + dir = lcr_util_path_dir(fname); + if (dir == NULL) { + ERROR("Failed to get dir of %s", fname); + goto out; + } + +- if (lcr_util_generate_random_str(random_tmp, (size_t)RANDOM_TMP_PATH)) { +- ERROR("Failed to generate random str for random path"); +- goto out; +- } +- +- nret = snprintf(rpath, PATH_MAX, ".tmp-%s-%s", base, random_tmp); +- if (nret < 0 || (size_t)nret >= PATH_MAX) { +- ERROR("Failed to generate tmp base file"); +- goto out; +- } +- +- result = lcr_util_path_join(dir, rpath); ++ result = lcr_util_path_join(dir, tmp_name); + + out: +- free(base); + free(dir); + return result; + } + +-static int do_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, bool sync) ++static int do_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode) + { + int ret = 0; + int dst_fd = -1; +@@ -1492,12 +1385,6 @@ static int do_atomic_write_file(const char *fname, const char *content, size_t c + goto free_out; + } + +- if (sync && (fdatasync(dst_fd) != 0)) { +- ret = -1; +- SYSERROR("Failed to sync data of file:%s", fname); +- goto free_out; +- } +- + free_out: + if (dst_fd >= 0) { + close(dst_fd); +@@ -1505,7 +1392,7 @@ free_out: + return ret; + } + +-int lcr_util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, bool sync) ++int lcr_util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, const char *tmp_name) + { + int ret = 0; + char *tmp_file = NULL; +@@ -1522,13 +1409,13 @@ int lcr_util_atomic_write_file(const char *fname, const char *content, size_t co + return -1; + } + +- tmp_file = lcr_util_get_random_tmp_file(fname); ++ tmp_file = lcr_util_get_tmp_file(fname, tmp_name); + if (tmp_file == NULL) { + ERROR("Failed to get tmp file for %s", fname); + return -1; + } + +- ret = do_atomic_write_file(tmp_file, content, content_len, mode, sync); ++ ret = do_atomic_write_file(tmp_file, content, content_len, mode); + if (ret != 0) { + ERROR("Failed to write content to tmp file for %s", tmp_file); + ret = -1; +diff --git a/src/utils.h b/src/utils.h +index 51e0dea..69e0c28 100644 +--- a/src/utils.h ++++ b/src/utils.h +@@ -217,9 +217,9 @@ int lcr_util_null_stdfds(void); + + int lcr_util_flock_append_file(const char *filepath, const char *content); + +-char *lcr_util_get_random_tmp_file(const char *fname); ++char *lcr_util_get_tmp_file(const char *fname, const char *tmp_name); + +-int lcr_util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, bool sync); ++int lcr_util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, const char *tmp_name); + + int lcr_util_get_real_swap(int64_t memory, int64_t memory_swap, int64_t *swap); + int lcr_util_trans_cpushare_to_cpuweight(int64_t cpu_share); +diff --git a/tests/utils_ut.cpp b/tests/utils_ut.cpp +index 8acba29..17f60ed 100644 +--- a/tests/utils_ut.cpp ++++ b/tests/utils_ut.cpp +@@ -95,19 +95,16 @@ err_out: + return buf; + } + +-TEST(utils_testcase, test_get_random_tmp_file) ++TEST(utils_testcase, test_get_tmp_file) + { +-#define RANDOM_TMP_PATH 10 + const char *fname = "/tmp/lcr-test/test"; +- char *tmp_file = lcr_util_get_random_tmp_file(nullptr); +- const char *prefix = "/tmp/lcr-test/.tmp-test-"; ++ char *tmp_file = lcr_util_get_tmp_file(nullptr, ".tmp_test_file"); + ASSERT_EQ(tmp_file, nullptr); + +- tmp_file = lcr_util_get_random_tmp_file(fname); ++ tmp_file = lcr_util_get_tmp_file(fname, ".tmp_test_file"); + ASSERT_NE(tmp_file, nullptr); + +- ASSERT_EQ(strlen(tmp_file), strlen("/tmp/lcr-test/.tmp-test-") + RANDOM_TMP_PATH); +- ASSERT_EQ(memcmp(tmp_file, prefix, strlen(prefix)), 0); ++ ASSERT_STREQ(tmp_file, "/tmp/lcr-test/.tmp_test_file"); + free(tmp_file); + } + +@@ -118,19 +115,19 @@ TEST(utils_testcase, test_atomic_write_file) + const char *new_content = "line1\nline2\nline3\n"; + char *readcontent = nullptr; + +- ASSERT_EQ(lcr_util_atomic_write_file(NULL, content, strlen(content), 0644, false), -1); +- ASSERT_EQ(lcr_util_atomic_write_file(fname, NULL, 0, 0644, false), 0); ++ ASSERT_EQ(lcr_util_atomic_write_file(NULL, content, strlen(content), 0644, ".tmp_test"), -1); ++ ASSERT_EQ(lcr_util_atomic_write_file(fname, NULL, 0, 0644, ".tmp_test"), 0); + + ASSERT_EQ(lcr_util_build_dir(fname), 0); + +- ASSERT_EQ(lcr_util_atomic_write_file(fname, content, strlen(content), 0644, false), 0); ++ ASSERT_EQ(lcr_util_atomic_write_file(fname, content, strlen(content), 0644, ".tmp_test"), 0); + + readcontent = test_read_text_file(fname); + ASSERT_NE(readcontent, nullptr); + ASSERT_STREQ(readcontent, content); + free(readcontent); + +- ASSERT_EQ(lcr_util_atomic_write_file(fname, new_content, strlen(new_content), 0644, false), 0); ++ ASSERT_EQ(lcr_util_atomic_write_file(fname, new_content, strlen(new_content), 0644, ".tmp_test"), 0); + readcontent = test_read_text_file(fname); + ASSERT_NE(readcontent, nullptr); + ASSERT_STREQ(readcontent, new_content); +-- +2.33.0 + diff --git a/0019-300-add-blkio-info-for-runtime-stats.patch b/0019-300-add-blkio-info-for-runtime-stats.patch new file mode 100644 index 0000000..82bb3c4 --- /dev/null +++ b/0019-300-add-blkio-info-for-runtime-stats.patch @@ -0,0 +1,64 @@ +From 2bd09ffdb41844387685368497ff6ce8a9100102 Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Wed, 29 Nov 2023 09:32:54 +0000 +Subject: [PATCH 19/20] !300 add blkio info for runtime-stats * add blkio info + for runtime-stats + +--- + src/json/schema/defs.json | 17 +++++++++++++++++ + src/json/schema/shim/client/runtime-stats.json | 11 +++++++++++ + 2 files changed, 28 insertions(+) + +diff --git a/src/json/schema/defs.json b/src/json/schema/defs.json +index 27b2de2..1fca860 100644 +--- a/src/json/schema/defs.json ++++ b/src/json/schema/defs.json +@@ -128,6 +128,23 @@ + } + } + }, ++ "BlkioEntry": { ++ "type": "object", ++ "properties": { ++ "major": { ++ "$ref": "#/definitions/uint64" ++ }, ++ "minor": { ++ "$ref": "#/definitions/uint64" ++ }, ++ "op": { ++ "type": "string" ++ }, ++ "value": { ++ "$ref": "#/definitions/uint64" ++ } ++ } ++ }, + "ArrayOfBlkioWeightDevice": { + "type": "array", + "items": { +diff --git a/src/json/schema/shim/client/runtime-stats.json b/src/json/schema/shim/client/runtime-stats.json +index ae77e9d..18b34f1 100644 +--- a/src/json/schema/shim/client/runtime-stats.json ++++ b/src/json/schema/shim/client/runtime-stats.json +@@ -56,6 +56,17 @@ + } + } + } ++ }, ++ "blkio": { ++ "type": "object", ++ "properties": { ++ "ioServiceBytesRecursive": { ++ "type": "array", ++ "items": { ++ "$ref": "../../defs.json#/definitions/BlkioEntry" ++ } ++ } ++ } + } + } + } +-- +2.33.0 + diff --git a/0020-drop-atomic-config-write-for-partial-file-does.patch b/0020-drop-atomic-config-write-for-partial-file-does.patch new file mode 100644 index 0000000..4c20b5d --- /dev/null +++ b/0020-drop-atomic-config-write-for-partial-file-does.patch @@ -0,0 +1,658 @@ +From f1f938732403003206a83a641a0a02a7f82125f7 Mon Sep 17 00:00:00 2001 +From: jikai +Date: Thu, 30 Nov 2023 19:17:37 +0800 +Subject: [PATCH 20/20] drop atomic config write for partial file does + +Signed-off-by: jikai +--- + src/lcrcontainer_extend.c | 151 +++++++++++++++++++------------------ + src/utils.c | 153 -------------------------------------- + src/utils.h | 4 - + tests/CMakeLists.txt | 3 +- + tests/utils_ut.cpp | 137 ---------------------------------- + 5 files changed, 81 insertions(+), 367 deletions(-) + delete mode 100644 tests/utils_ut.cpp + +diff --git a/src/lcrcontainer_extend.c b/src/lcrcontainer_extend.c +index 0e1d926..321be8c 100644 +--- a/src/lcrcontainer_extend.c ++++ b/src/lcrcontainer_extend.c +@@ -346,7 +346,7 @@ out: + return ret; + } + +-static int lcr_spec_write_seccomp_line(FILE *fp, const char *seccomp) ++static int lcr_spec_write_seccomp_line(int fd, const char *seccomp) + { + size_t len; + char *line = NULL; +@@ -371,17 +371,14 @@ static int lcr_spec_write_seccomp_line(FILE *fp, const char *seccomp) + ERROR("Sprintf failed"); + goto cleanup; + } +- + if ((size_t)nret > len - 1) { + nret = (int)(len - 1); + } +- + line[nret] = '\n'; +- if (fwrite(line, 1, len ,fp) != len) { ++ if (write(fd, line, len) == -1) { + SYSERROR("Write file failed"); + goto cleanup; + } +- + ret = 0; + cleanup: + free(line); +@@ -392,7 +389,9 @@ static char *lcr_save_seccomp_file(const char *bundle, const char *seccomp_conf) + { + char seccomp[PATH_MAX] = { 0 }; + char *real_seccomp = NULL; ++ int fd = -1; + int nret; ++ ssize_t written_cnt; + + nret = snprintf(seccomp, sizeof(seccomp), "%s/seccomp", bundle); + if (nret < 0 || (size_t)nret >= sizeof(seccomp)) { +@@ -405,9 +404,16 @@ static char *lcr_save_seccomp_file(const char *bundle, const char *seccomp_conf) + goto cleanup; + } + +- if (lcr_util_atomic_write_file(real_seccomp, seccomp_conf, strlen(seccomp_conf), +- CONFIG_FILE_MODE, ".tmp_seccomp_save") == -1) { +- ERROR("write seccomp_conf failed"); ++ fd = lcr_util_open(real_seccomp, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); ++ if (fd == -1) { ++ SYSERROR("Create file %s failed", real_seccomp); ++ goto cleanup; ++ } ++ ++ written_cnt = write(fd, seccomp_conf, strlen(seccomp_conf)); ++ close(fd); ++ if (written_cnt == -1) { ++ SYSERROR("write seccomp_conf failed"); + goto cleanup; + } + return real_seccomp; +@@ -599,52 +605,34 @@ out_free: + return NULL; + } + +-static FILE *lcr_open_tmp_config_file(const char *bundle, char **config_file, char **tmp_file) ++ ++static int lcr_open_config_file(const char *bundle) + { + char config[PATH_MAX] = { 0 }; ++ char *real_config = NULL; + int fd = -1; + int nret; +- FILE *fp = NULL; + + nret = snprintf(config, sizeof(config), "%s/config", bundle); + if (nret < 0 || (size_t)nret >= sizeof(config)) { + goto out; + } + +- nret = lcr_util_ensure_path(config_file, config); ++ nret = lcr_util_ensure_path(&real_config, config); + if (nret < 0) { + ERROR("Failed to ensure path %s", config); + goto out; + } + +- *tmp_file = lcr_util_get_tmp_file(*config_file, ".tmp_config_save"); +- if (*tmp_file == NULL) { +- ERROR("Failed to get random tmp file for %s", *config_file); +- goto out; +- } +- +- fd = lcr_util_open(*tmp_file, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); ++ fd = lcr_util_open(real_config, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); + if (fd == -1) { +- SYSERROR("Create file %s failed", *tmp_file); +- lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed", *tmp_file); +- goto out; +- } +- +- fp = fdopen(fd, "w"); +- if (fp == NULL) { +- close(fd); +- ERROR("FILE open failed"); ++ SYSERROR("Create file %s failed", real_config); ++ lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed", real_config); + goto out; + } +- + out: +- if (fp == NULL) { +- free(*tmp_file); +- *tmp_file = NULL; +- free(*config_file); +- *config_file = NULL; +- } +- return fp; ++ free(real_config); ++ return fd; + } + + // escape_string_encode unzip some escape characters +@@ -710,17 +698,18 @@ static char *escape_string_encode(const char *src) + return dst; + } + +-static int lcr_spec_write_config(FILE *fp, const struct lcr_list *lcr_conf) ++static int lcr_spec_write_config(int fd, const struct lcr_list *lcr_conf) + { +- size_t len; +- int ret = -1; + struct lcr_list *it = NULL; +- char *line_encode = NULL; ++ size_t len; + char *line = NULL; ++ char *line_encode = NULL; ++ int ret = -1; + + lcr_list_for_each(it, lcr_conf) { + lcr_config_item_t *item = it->elem; + int nret; ++ size_t encode_len; + if (item != NULL) { + if (strlen(item->value) > ((SIZE_MAX - strlen(item->name)) - 4)) { + goto cleanup; +@@ -733,6 +722,7 @@ static int lcr_spec_write_config(FILE *fp, const struct lcr_list *lcr_conf) + } + + nret = snprintf(line, len, "%s = %s", item->name, item->value); ++ + if (nret < 0 || (size_t)nret >= len) { + ERROR("Sprintf failed"); + goto cleanup; +@@ -744,21 +734,19 @@ static int lcr_spec_write_config(FILE *fp, const struct lcr_list *lcr_conf) + goto cleanup; + } + +- len = strlen(line_encode); +- line_encode[len] = '\n'; ++ encode_len = strlen(line_encode); + +- if (fwrite(line_encode, 1, len + 1, fp) != len + 1) { ++ line_encode[encode_len] = '\n'; ++ if (write(fd, line_encode, encode_len + 1) == -1) { + SYSERROR("Write file failed"); + goto cleanup; + } +- + free(line); + line = NULL; + free(line_encode); + line_encode = NULL; + } + } +- + ret = 0; + cleanup: + free(line); +@@ -816,9 +804,7 @@ bool lcr_save_spec(const char *name, const char *lcrpath, const struct lcr_list + const char *path = lcrpath ? lcrpath : LCRPATH; + char *bundle = NULL; + char *seccomp = NULL; +- char *config_file = NULL; +- char *tmp_file = NULL; +- FILE *fp = NULL; ++ int fd = -1; + int nret = 0; + + if (name == NULL) { +@@ -843,48 +829,72 @@ bool lcr_save_spec(const char *name, const char *lcrpath, const struct lcr_list + } + } + +- fp = lcr_open_tmp_config_file(bundle, &config_file, &tmp_file); +- if (fp == NULL) { ++ fd = lcr_open_config_file(bundle); ++ if (fd == -1) { + goto out_free; + } + +- if (lcr_spec_write_config(fp, lcr_conf)) { ++ if (lcr_spec_write_config(fd, lcr_conf)) { + goto out_free; + } + + if (seccomp_conf != NULL) { +- nret = lcr_spec_write_seccomp_line(fp, seccomp); ++ nret = lcr_spec_write_seccomp_line(fd, seccomp); + if (nret) { + goto out_free; + } + } + +- fclose(fp); +- fp = NULL; ++ bret = true; + +- nret = rename(tmp_file, config_file); +- if (nret != 0) { +- ERROR("Failed to rename old file %s to target %s", tmp_file, config_file); +- goto out_free; ++out_free: ++ free(bundle); ++ free(seccomp); ++ if (fd != -1) { ++ close(fd); + } + +- bret = true; ++ return bret; ++} + +-out_free: +- if (fp != NULL) { +- fclose(fp); ++static int lcr_write_file(const char *path, const char *data, size_t len) ++{ ++ char *real_path = NULL; ++ int fd = -1; ++ int ret = -1; ++ ++ if (path == NULL || strlen(path) == 0 || data == NULL || len == 0) { ++ return -1; + } +- if (!bret && tmp_file != NULL && unlink(tmp_file) != 0 && errno != ENOENT) { +- SYSERROR("Failed to remove temp file:%s", tmp_file); ++ ++ if (lcr_util_ensure_path(&real_path, path) < 0) { ++ ERROR("Failed to ensure path %s", path); ++ goto out_free; + } +- free(config_file); +- free(tmp_file); +- free(seccomp); +- free(bundle); + +- return bret; ++ fd = lcr_util_open(real_path, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); ++ if (fd == -1) { ++ ERROR("Create file %s failed", real_path); ++ lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed", real_path); ++ goto out_free; ++ } ++ ++ if (write(fd, data, len) == -1) { ++ SYSERROR("write data to %s failed", real_path); ++ goto out_free; ++ } ++ ++ ret = 0; ++ ++out_free: ++ if (fd != -1) { ++ close(fd); ++ } ++ free(real_path); ++ return ret; + } + ++ + static bool lcr_write_ocihooks(const char *path, const oci_runtime_spec_hooks *hooks) + { + bool ret = false; +@@ -897,9 +907,8 @@ static bool lcr_write_ocihooks(const char *path, const oci_runtime_spec_hooks *h + goto out_free; + } + +- if (lcr_util_atomic_write_file(path, json_hooks, strlen(json_hooks), +- CONFIG_FILE_MODE, ".tmp_ocihooks_save") == -1) { +- ERROR("write json hooks failed"); ++ if (lcr_write_file(path, json_hooks, strlen(json_hooks)) == -1) { ++ SYSERROR("write json hooks failed"); + goto out_free; + } + +diff --git a/src/utils.c b/src/utils.c +index 85874a7..b999509 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -1284,159 +1284,6 @@ out: + return ret; + } + +-static char *lcr_util_path_dir(const char *path) +-{ +- char *dir = NULL; +- int len = 0; +- int i = 0; +- +- if (path == NULL) { +- ERROR("invalid NULL param"); +- return NULL; +- } +- +- len = (int)strlen(path); +- if (len == 0) { +- return lcr_util_strdup_s("."); +- } +- +- dir = lcr_util_strdup_s(path); +- +- for (i = len - 1; i > 0; i--) { +- if (dir[i] == '/') { +- dir[i] = 0; +- break; +- } +- } +- +- if (i == 0 && dir[0] == '/') { +- free(dir); +- return lcr_util_strdup_s("/"); +- } +- +- return dir; +-} +- +-static char *lcr_util_path_join(const char *dir, const char *file) +-{ +- int nret = 0; +- char path[PATH_MAX] = { 0 }; +- char cleaned[PATH_MAX] = { 0 }; +- +- if (dir == NULL || file == NULL) { +- ERROR("NULL dir or file failed"); +- return NULL; +- } +- +- nret = snprintf(path, PATH_MAX, "%s/%s", dir, file); +- if (nret < 0 || (size_t)nret >= PATH_MAX) { +- ERROR("dir or file too long failed"); +- return NULL; +- } +- +- if (cleanpath(path, cleaned, sizeof(cleaned)) == NULL) { +- ERROR("Failed to clean path: %s", path); +- return NULL; +- } +- +- return lcr_util_strdup_s(cleaned); +-} +- +-char *lcr_util_get_tmp_file(const char *fname, const char *tmp_name) +-{ +- char *result = NULL; +- char *dir = NULL; +- +- if (fname == NULL || tmp_name == NULL) { +- ERROR("Invalid NULL param"); +- return NULL; +- } +- +- dir = lcr_util_path_dir(fname); +- if (dir == NULL) { +- ERROR("Failed to get dir of %s", fname); +- goto out; +- } +- +- result = lcr_util_path_join(dir, tmp_name); +- +-out: +- free(dir); +- return result; +-} +- +-static int do_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode) +-{ +- int ret = 0; +- int dst_fd = -1; +- ssize_t len = 0; +- +- dst_fd = lcr_util_open(fname, O_WRONLY | O_CREAT | O_TRUNC, mode); +- if (dst_fd < 0) { +- SYSERROR("Creat file: %s, failed", fname); +- ret = -1; +- goto free_out; +- } +- +- len = lcr_util_write_nointr(dst_fd, content, content_len); +- if (len < 0 || ((size_t)len) != content_len) { +- ret = -1; +- SYSERROR("Write file failed"); +- goto free_out; +- } +- +-free_out: +- if (dst_fd >= 0) { +- close(dst_fd); +- } +- return ret; +-} +- +-int lcr_util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, const char *tmp_name) +-{ +- int ret = 0; +- char *tmp_file = NULL; +- char rpath[PATH_MAX] = { 0x00 }; +- +- if (fname == NULL) { +- return -1; +- } +- if (content == NULL || content_len == 0) { +- return 0; +- } +- +- if (cleanpath(fname, rpath, sizeof(rpath)) == NULL) { +- return -1; +- } +- +- tmp_file = lcr_util_get_tmp_file(fname, tmp_name); +- if (tmp_file == NULL) { +- ERROR("Failed to get tmp file for %s", fname); +- return -1; +- } +- +- ret = do_atomic_write_file(tmp_file, content, content_len, mode); +- if (ret != 0) { +- ERROR("Failed to write content to tmp file for %s", tmp_file); +- ret = -1; +- goto free_out; +- } +- +- ret = rename(tmp_file, rpath); +- if (ret != 0) { +- ERROR("Failed to rename old file %s to target %s", tmp_file, rpath); +- ret = -1; +- goto free_out; +- } +- +-free_out: +- if (ret != 0 && unlink(tmp_file) != 0 && errno != ENOENT) { +- SYSERROR("Failed to remove temp file:%s", tmp_file); +- } +- free(tmp_file); +- return ret; +-} +- + /* swap in oci is memoy+swap, so here we need to get real swap */ + int lcr_util_get_real_swap(int64_t memory, int64_t memory_swap, int64_t *swap) + { +diff --git a/src/utils.h b/src/utils.h +index 69e0c28..2fe4f1e 100644 +--- a/src/utils.h ++++ b/src/utils.h +@@ -217,10 +217,6 @@ int lcr_util_null_stdfds(void); + + int lcr_util_flock_append_file(const char *filepath, const char *content); + +-char *lcr_util_get_tmp_file(const char *fname, const char *tmp_name); +- +-int lcr_util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode, const char *tmp_name); +- + int lcr_util_get_real_swap(int64_t memory, int64_t memory_swap, int64_t *swap); + int lcr_util_trans_cpushare_to_cpuweight(int64_t cpu_share); + uint64_t lcr_util_trans_blkio_weight_to_io_weight(int weight); +diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt +index af267d7..fada476 100644 +--- a/tests/CMakeLists.txt ++++ b/tests/CMakeLists.txt +@@ -69,7 +69,6 @@ endif() + _DEFINE_NEW_TEST(log_ut log_testcase) + _DEFINE_NEW_TEST(libocispec_ut libocispec_testcase) + _DEFINE_NEW_TEST(go_crc64_ut go_crc64_testcase) +-_DEFINE_NEW_TEST(utils_ut utils_testcase) + + + # mock test for run lcov to generate html +@@ -82,7 +81,7 @@ target_link_libraries(mock_ut + ${GTEST_LIBRARY} + pthread + ) +-add_dependencies(mock_ut log_ut libocispec_ut go_crc64_ut utils_ut) ++add_dependencies(mock_ut log_ut libocispec_ut go_crc64_ut) + + IF(ENABLE_GCOV) + add_custom_target(coverage +diff --git a/tests/utils_ut.cpp b/tests/utils_ut.cpp +deleted file mode 100644 +index 17f60ed..0000000 +--- a/tests/utils_ut.cpp ++++ /dev/null +@@ -1,137 +0,0 @@ +-/****************************************************************************** +- * iSula-libutils: utils library for iSula +- * +- * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. +- * +- * Authors: +- * jikai +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- ********************************************************************************/ +- +-#include +- +-#include +-#include +- +-#include "utils.h" +- +-char *test_read_text_file(const char *path) +-{ +- char *buf = NULL; +- long len = 0; +- int f_fd = -1; +- size_t readlen = 0; +- FILE *filp = NULL; +- char *rpath = NULL; +- const long max_size = 10 * 1024 * 1024; /* 10M */ +- +- if (path == NULL) { +- return NULL; +- } +- +- if (lcr_util_ensure_path(&rpath, path) != 0) { +- return NULL; +- } +- +- f_fd = open(rpath, O_RDONLY | O_CLOEXEC, 0666); +- if (f_fd < 0) { +- goto err_out; +- } +- +- filp = fdopen(f_fd, "r"); +- if (filp == NULL) { +- close(f_fd); +- goto err_out; +- } +- +- if (fseek(filp, 0, SEEK_END)) { +- goto err_out; +- } +- +- len = ftell(filp); +- if (len > max_size) { +- goto err_out; +- } +- +- if (fseek(filp, 0, SEEK_SET)) { +- goto err_out; +- } +- +- buf = (char *)lcr_util_common_calloc_s((size_t)(len + 1)); +- if (buf == NULL) { +- goto err_out; +- } +- +- readlen = fread(buf, 1, (size_t)len, filp); +- if (((readlen < (size_t)len) && (!feof(filp))) || (readlen > (size_t)len)) { +- free(buf); +- buf = NULL; +- goto err_out; +- } +- +- buf[(size_t)len] = 0; +- +-err_out: +- +- if (filp != NULL) { +- fclose(filp); +- } +- +- free(rpath); +- +- return buf; +-} +- +-TEST(utils_testcase, test_get_tmp_file) +-{ +- const char *fname = "/tmp/lcr-test/test"; +- char *tmp_file = lcr_util_get_tmp_file(nullptr, ".tmp_test_file"); +- ASSERT_EQ(tmp_file, nullptr); +- +- tmp_file = lcr_util_get_tmp_file(fname, ".tmp_test_file"); +- ASSERT_NE(tmp_file, nullptr); +- +- ASSERT_STREQ(tmp_file, "/tmp/lcr-test/.tmp_test_file"); +- free(tmp_file); +-} +- +-TEST(utils_testcase, test_atomic_write_file) +-{ +- const char *fname = "/tmp/lcr-test/test"; +- const char *content = "line1\nline2\n"; +- const char *new_content = "line1\nline2\nline3\n"; +- char *readcontent = nullptr; +- +- ASSERT_EQ(lcr_util_atomic_write_file(NULL, content, strlen(content), 0644, ".tmp_test"), -1); +- ASSERT_EQ(lcr_util_atomic_write_file(fname, NULL, 0, 0644, ".tmp_test"), 0); +- +- ASSERT_EQ(lcr_util_build_dir(fname), 0); +- +- ASSERT_EQ(lcr_util_atomic_write_file(fname, content, strlen(content), 0644, ".tmp_test"), 0); +- +- readcontent = test_read_text_file(fname); +- ASSERT_NE(readcontent, nullptr); +- ASSERT_STREQ(readcontent, content); +- free(readcontent); +- +- ASSERT_EQ(lcr_util_atomic_write_file(fname, new_content, strlen(new_content), 0644, ".tmp_test"), 0); +- readcontent = test_read_text_file(fname); +- ASSERT_NE(readcontent, nullptr); +- ASSERT_STREQ(readcontent, new_content); +- free(readcontent); +- +- ASSERT_EQ(lcr_util_recursive_rmdir("/tmp/lcr-test/", 1), 0); +-} +-- +2.33.0 + diff --git a/lcr.spec b/lcr.spec index bfa1cf6..809644d 100644 --- a/lcr.spec +++ b/lcr.spec @@ -1,5 +1,5 @@ %global _version 2.0.9 -%global _release 7 +%global _release 8 %global _inner_name isula_libutils Name: lcr @@ -24,6 +24,14 @@ Patch0009: 0009-support-check-symbols-and-compile-code-in-cmake.patch Patch0010: 0010-remove-unnecessary-strerror.patch Patch0011: 0011-258-improve-code-of-function-in-log.patch Patch0012: 0012-265-set-env-to-avoid-invoke-lxc-binary-directly.patch +Patch0013: 0013-improve-error-of-lcr-apis.patch +Patch0014: 0014-288-use-atomic-write-for-config-secomp-oci_hook-file.patch +Patch0015: 0015-289-close-fd-if-fdopen-failed-and-add-ut.patch +Patch0016: 0016-290-fix-seccomp-write-error.patch +Patch0017: 0017-291-restore-using-dev-urandom.patch +Patch0018: 0018-use-fixed-tmp-file-to-write-config-etc.patch +Patch0019: 0019-300-add-blkio-info-for-runtime-stats.patch +Patch0020: 0020-drop-atomic-config-write-for-partial-file-does.patch %define lxcver_lower 4.0.3-2022102400 %define lxcver_upper 4.0.3-2022102500 @@ -107,6 +115,12 @@ rm -rf %{buildroot} %{_includedir}/%{_inner_name}/*.h %changelog +* Mon Dec 11 2023 jikai - 2.0.9-8 +- Type:enhancement +- CVE:NA +- SUG:NA +- DESC:sync from upstream + * Mon Sep 18 2023 jikai - 2.0.9-7 - Type:bugfix - CVE:NA