From fa7428d0baf2c310c852b1ece41736b21ea441f9 Mon Sep 17 00:00:00 2001 From: zhangxiaoyu Date: Fri, 9 Dec 2022 17:26:10 +0800 Subject: [PATCH 61/65] check file system ro before merge network for syscontainer Signed-off-by: zhangxiaoyu --- .../executor/container_cb/execution_network.c | 29 +++++++++++++++++++ src/utils/cutils/utils_fs.c | 27 +++++++++++++++++ src/utils/cutils/utils_fs.h | 1 + 3 files changed, 57 insertions(+) diff --git a/src/daemon/executor/container_cb/execution_network.c b/src/daemon/executor/container_cb/execution_network.c index bbc35e80..b738d02f 100644 --- a/src/daemon/executor/container_cb/execution_network.c +++ b/src/daemon/executor/container_cb/execution_network.c @@ -761,9 +761,38 @@ out: return ret; } +static int check_readonly_fs_for_etc(const char *rootfs, bool *ro) +{ + char *path = NULL; + + if (util_realpath_in_scope(rootfs, "/etc", &path) < 0) { + SYSERROR("Failed to get real path '/etc' under rootfs '%s'", rootfs); + isulad_set_error_message("Failed to get real path '/etc' under rootfs '%s'", rootfs); + return -1; + } + + *ro = util_check_readonly_fs(path); + + free(path); + return 0; +} + +// modify network file in rootfs +// make sure network file saved if rootfs migrate to another host static int merge_network_for_syscontainer(const host_config *host_spec, const char *rootfs, const char *hostname) { int ret = 0; + bool ro = false; + + if (check_readonly_fs_for_etc(rootfs, &ro) != 0) { + ERROR("Failed to check network path"); + return -1; + } + + if (ro) { + WARN("Readonly filesystem for etc under %s. Skip merge network for syscontainer", rootfs); + return 0; + } ret = write_hostname_to_file(rootfs, hostname); if (ret) { diff --git a/src/utils/cutils/utils_fs.c b/src/utils/cutils/utils_fs.c index 218e2fe8..e7165f26 100644 --- a/src/utils/cutils/utils_fs.c +++ b/src/utils/cutils/utils_fs.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -620,3 +621,29 @@ child_out: cleanup: return ret; } + +bool util_check_readonly_fs(const char *path) +{ + int i; + const int max_retry = 10; + struct statfs fsbuf; + + for (i = 0; i < max_retry; i++) { + if (statfs(path, &fsbuf) == 0) { + break; + } + if (errno == EINTR) { + continue; + } + + ERROR("Stat fs failed: %s", strerror(errno)); + return false; + } + + if (i >= max_retry) { + ERROR("Too much interrupted"); + return false; + } + + return (fsbuf.f_flags & ST_RDONLY) != 0; +} diff --git a/src/utils/cutils/utils_fs.h b/src/utils/cutils/utils_fs.h index 6ab6b78e..6ad64a1a 100644 --- a/src/utils/cutils/utils_fs.h +++ b/src/utils/cutils/utils_fs.h @@ -38,6 +38,7 @@ int util_ensure_mounted_as(const char *dst, const char *mntopts); int util_mount_from(const char *base, const char *src, const char *dst, const char *mtype, const char *mntopts); typedef int (*mount_info_call_back_t)(const char *, const char *); bool util_deal_with_mount_info(mount_info_call_back_t cb, const char *); +bool util_check_readonly_fs(const char *path); #ifdef __cplusplus } #endif -- 2.25.1