Check if the file operation failed by lack of disk space 63/232463/3
authorMateusz Moscicki <m.moscicki2@partner.samsung.com>
Tue, 5 May 2020 15:41:39 +0000 (17:41 +0200)
committerMateusz Moscicki <m.moscicki2@partner.samsung.com>
Wed, 6 May 2020 08:48:48 +0000 (10:48 +0200)
Change-Id: I3921e4631d9d2a84110af0681777bae15e62cfbc

src/crash-manager/crash-manager.c

index 27929af..9f46a97 100644 (file)
@@ -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++;