From 3a1a00dc1707ed6666bacf82b01d5c8444d5d9f3 Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Tue, 5 May 2020 17:41:39 +0200 Subject: [PATCH] Check if the file operation failed by lack of disk space Change-Id: I3921e4631d9d2a84110af0681777bae15e62cfbc --- src/crash-manager/crash-manager.c | 62 +++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index 27929af..9f46a97 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -62,6 +62,7 @@ #define APP_PATH_SUBDIR "/app/" #define WAIT_FOR_OPT_TIMEOUT_SEC 60 +#define SPACE_REQUIRED_KB 1024 #define MINICOREDUMPER_TIMEOUT_MS DEFAULT_COMMAND_TIMEOUT_MS #define LIVEDUMPER_TIMEOUT_MS DEFAULT_COMMAND_TIMEOUT_MS @@ -193,6 +194,27 @@ static bool set_appinfo(char *exepath, char **appid, char **pkgid) return false; } +static int check_disk_available(const char *path, int check_size) +{ + struct statfs lstatfs; + + if (!path) + return false; + + if (statfs(path, &lstatfs) < 0) { + _E("Error when checking free space (%d): %m", errno); + return false; + } + int avail_size = (int)(lstatfs.f_bavail * (lstatfs.f_bsize / 1024)); + + if (check_size > avail_size) { + _E("Available disk space (%d) is less than (%d)", avail_size, check_size); + return false; + } + + return true; +} + static int prepare_paths(struct crash_info* cinfo) { int tmp_len; @@ -818,11 +840,14 @@ static bool copy_application_data(struct crash_info *cinfo, const char *filename if (mkdir(dst_dirname, 0775) < 0 && errno != EEXIST) { _E("Failed to mkdir %s: %m", dst_dirname); + (void)check_disk_available(cinfo->pfx, SPACE_REQUIRED_KB); goto out; } - if (copy_file(dst_filepath, src_filepath)) + if (copy_file(dst_filepath, src_filepath)) { _E("Cannot copy %s file to: %s", src_filepath, dst_filepath); + (void)check_disk_available(cinfo->app_root_path, SPACE_REQUIRED_KB); + } else is_ok = true; out: @@ -850,6 +875,7 @@ static void copy_application_xmls(struct crash_info *cinfo) } if (mkdir(dst_dirpath, 0775) < 0 && errno != EEXIST) { _E("Failed to mkdir %s (%m)", dst_dirpath); + (void)check_disk_available(cinfo->pfx, SPACE_REQUIRED_KB); goto out; } if (snprintf(maps_path, sizeof(maps_path), "/proc/%d/maps", cinfo->pid_info) <= 0) { @@ -870,8 +896,11 @@ static void copy_application_xmls(struct crash_info *cinfo) continue; } if (file_exists(src_filepath)) { - if (copy_file(dst_filepath, src_filepath)) + if (copy_file(dst_filepath, src_filepath)) { _E("Cannot copy file from %s to: %s", src_filepath, dst_filepath); + (void)check_disk_available(dst_dirpath, SPACE_REQUIRED_KB); + } + } free(src_filepath); } @@ -893,6 +922,7 @@ static bool execute_crash_modules(struct crash_info *cinfo) return false; if (!execute_livedumper(cinfo, &exit_code) || exit_code != 0) { _E("Failed to run livedumper - can not continue"); + (void)check_disk_available(cinfo->pfx, SPACE_REQUIRED_KB); process_continue(cinfo->pid_info); return false; } @@ -900,6 +930,7 @@ static bool execute_crash_modules(struct crash_info *cinfo) _I("Starting the minicoredumper"); if (!execute_minicoredump(cinfo, &exit_code) || exit_code != 0) { _E("Failed to run minicoredumper - can not continue"); + (void)check_disk_available(cinfo->pfx, SPACE_REQUIRED_KB); return false; } } @@ -1038,26 +1069,6 @@ exit: return dump_num; } -static int check_disk_available(const char *path, int check_size) -{ - struct statfs lstatfs; - int avail_size = 0; - - if (!path) - return -1; - - if (statfs(path, &lstatfs) < 0) - return -1; - avail_size = (int)(lstatfs.f_bavail * (lstatfs.f_bsize / 1024)); - - if (check_size > avail_size) { - _I("avail_size is (%d)", avail_size); - return -1; - } - - return 0; -} - static bool remove_file_info(struct file_info file) { if (file.isdir) @@ -1130,8 +1141,8 @@ static void clean_dump(void) /* Check disk free space to keep */ if (config.system_keep_free && - check_disk_available(config.crash_root_path, - config.system_keep_free) < 0) { + !check_disk_available(config.crash_root_path, + config.system_keep_free)) { _I("Disk is not available! so set the maximum number of dump to 1"); config.max_crash_dump = 1; } @@ -1160,6 +1171,7 @@ static bool move_dump_data(const char *from_path, const struct crash_info *cinfo clean_dump(); else { _E("Failed to move %s to %s", from_path, cinfo->result_path); + (void)check_disk_available(crash_dump_path, SPACE_REQUIRED_KB); is_ok = false; } unlock_dir(lock_fd); @@ -1171,7 +1183,7 @@ static int wait_for_opt(unsigned int timeout) { unsigned int count = 0; - while (check_disk_available(config.crash_root_path, 0) < 0 && count < timeout) { + while (!check_disk_available(config.crash_root_path, 0) && count < timeout) { log_kmsg("crash-manager: path %s is not available\n", config.crash_root_path); sleep(1); count++; -- 2.7.4