diff --git a/cmdline/scan.c b/cmdline/scan.c index 4bec861e..3427cd35 100644 --- a/cmdline/scan.c +++ b/cmdline/scan.c @@ -8,6 +8,14 @@ #include "state.h" #include "parity.h" +static const char* es(int err) +{ + if (is_hw(err)) + return "error_io"; + else + return "error"; +} + struct snapraid_scan { struct snapraid_state* state; /**< State used. */ struct snapraid_disk* disk; /**< Disk used. */ @@ -379,6 +387,7 @@ static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_fil static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file) { + char esc_buffer[ESC_MAX]; struct snapraid_state* state = scan->state; struct snapraid_disk* disk = scan->disk; @@ -392,6 +401,7 @@ static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapra if (filephy(path_next, file->size, &file->physical) != 0) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: File physycal offset error. %s.\n", es(errno), 0, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); log_fatal(errno, "Error in getting the physical offset of file '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ @@ -512,6 +522,7 @@ static int file_is_full_hashed_and_stable(struct snapraid_state* state, struct s static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical) { #if HAVE_LSTAT_SYNC + char esc_buffer[ESC_MAX]; struct snapraid_state* state = scan->state; struct snapraid_disk* disk = scan->disk; @@ -533,6 +544,7 @@ static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struc if (lstat_sync(path_next, &synced_st, physical) != 0) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Stat error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next, esc_buffer), strerror(errno)); log_fatal(errno, "Error in stat file '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ @@ -555,6 +567,7 @@ static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struc * Why is the file size reported incorrectly for files that are still being written to? * http://blogs.msdn.com/b/oldnewthing/archive/2011/12/26/10251026.aspx */ + log_tag("%s:%u:%s:%s: Uncached time change error.\n", es(ESOFT), 0, disk->name, esc_tag(sub, esc_buffer)); log_fatal(ESOFT, "WARNING! Detected uncached time change from %" PRIu64 ".%09u to %" PRIu64 ".%09u for file '%s'\n", (uint64_t)st->st_mtime, (uint32_t)st->st_mtimensec, (uint64_t)synced_st.st_mtime, (uint32_t)synced_st.st_mtimensec, sub); log_fatal(ESOFT, "It's better if you run SnapRAID without other processes running.\n"); @@ -565,6 +578,7 @@ static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struc if (st->st_size != synced_st.st_size) { #ifndef _WIN32 + log_tag("%s:%u:%s:%s: Uncached size change error.\n", es(ESOFT), 0, disk->name, esc_tag(sub, esc_buffer)); log_fatal(ESOFT, "WARNING! Detected uncached size change from %" PRIu64 " to %" PRIu64 " for file '%s'\n", (uint64_t)st->st_size, (uint64_t)synced_st.st_size, sub); log_fatal(ESOFT, "It's better if you run SnapRAID without other processes running.\n"); @@ -574,6 +588,7 @@ static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struc if (st->st_nlink != synced_st.st_nlink) { #ifndef _WIN32 + log_tag("%s:%u:%s:%s: Uncached nlink change error.\n", es(ESOFT), 0, disk->name, esc_tag(sub, esc_buffer)); log_fatal(ESOFT, "WARNING! Detected uncached nlink change from %u to %u for file '%s'\n", (uint32_t)st->st_nlink, (uint32_t)synced_st.st_nlink, sub); log_fatal(ESOFT, "It's better if you run SnapRAID without other processes running.\n"); @@ -582,6 +597,7 @@ static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struc } if (st->st_ino != synced_st.st_ino) { + log_tag("%s:%u:%s:%s: Uncached inode change error.\n", es(ESOFT), 0, disk->name, esc_tag(sub, esc_buffer)); log_fatal(ESOFT, "DANGER! Detected uncached inode change from %" PRIu64 " to %" PRIu64 " for file '%s'\n", (uint64_t)st->st_ino, (uint64_t)synced_st.st_ino, sub); log_fatal(ESOFT, "It's better if you run SnapRAID without other processes running.\n"); @@ -1230,11 +1246,13 @@ struct stat* dstat(struct dirent_sorted* dd) return &dd->d_stat; } #else -#define DSTAT(file, dd, buf) dstat(file, buf) -struct stat* dstat(const char* file, struct stat* st) +#define DSTAT(file, dd, buf) dstat(disk, file, buf) +struct stat* dstat(struct snapraid_disk* disk, const char* file, struct stat* st) { + char esc_buffer[ESC_MAX]; if (lstat(file, st) != 0) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Stat error. %s.\n", es(errno), 0, disk->name, esc_tag(file, esc_buffer), strerror(errno)); log_fatal(errno, "Error in stat file/directory '%s'. %s.\n", file, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ @@ -1249,6 +1267,7 @@ struct stat* dstat(const char* file, struct stat* st) */ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* path_next, char* sub_next, char* tmp) { + char esc_buffer[ESC_MAX]; struct snapraid_state* state = scan->state; struct snapraid_disk* disk = scan->disk; int processed = 0; @@ -1266,11 +1285,12 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa d = opendir(path_next); if (!d) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Open dir error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next, esc_buffer), strerror(errno)); log_fatal(errno, "Error opening directory '%s'. %s.\n", path_next, strerror(errno)); if (level == 0) log_fatal(errno, "If this is the disk mount point, remember to create it manually\n"); else - log_fatal(errno, "If it's a permission problem, you can exclude it in the config file with:\n\texclude /%s\n", sub_next); + log_fatal(errno, "If it's a permission problem, you can exclude it in the config file with: exclude /%s\n", sub_next); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } @@ -1296,8 +1316,9 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa /* restore removing additions */ path_next[path_len] = 0; sub_next[sub_len] = 0; + log_tag("%s:%u:%s:%s: Read dir error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next, esc_buffer), strerror(errno)); log_fatal(errno, "Error reading directory '%s'. %s.\n", path_next, strerror(errno)); - log_fatal(errno, "You can exclude it in the config file with:\n\texclude /%s\n", sub_next); + log_fatal(errno, "You can exclude it in the config file with: exclude /%s\n", sub_next); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } @@ -1315,6 +1336,7 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa /* check for not supported file names */ if (name[0] == 0) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Unsupported name error.\n", es(ESOFT), 0, disk->name, esc_tag(path_next, esc_buffer)); log_fatal(ESOFT, "Unsupported name '%s' in file '%s'.\n", name, path_next); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ @@ -1362,6 +1384,7 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa /* LCOV_EXCL_START */ /* restore removing additions */ path_next[path_len] = 0; + log_tag("%s:%u:%s:%s: Close dir error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next, esc_buffer), strerror(errno)); log_fatal(errno, "Error closing directory '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ @@ -1426,6 +1449,7 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa if (st->st_mode == 0) { if (lstat(path_next, st) != 0) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Stat error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next, esc_buffer), strerror(errno)); log_fatal(errno, "Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ @@ -1457,6 +1481,7 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa if (st->st_ino == 0 || st->st_nlink == 0) { if (lstat_sync(path_next, st, 0) != 0) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Stat error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next, esc_buffer), strerror(errno)); log_fatal(errno, "Error in stat file '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ @@ -1477,12 +1502,14 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa ret = readlink(path_next, tmp, PATH_MAX); if (ret >= PATH_MAX) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Readlink error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next, esc_buffer), strerror(errno)); log_fatal(EINTERNAL, "Error in readlink file '%s'. Symlink too long.\n", path_next); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } if (ret < 0) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Readlink error. %s.\n", es(errno), 0, disk->name, esc_tag(path_next, esc_buffer), strerror(errno)); log_fatal(errno, "Error in readlink file '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ @@ -1507,9 +1534,12 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa if (!st) st = DSTAT(path_next, dd, &st_buf); - /* in Unix don't follow mount points in different devices */ - /* in Windows we are already skipping them reporting them as special files */ + /* + * In Unix don't follow mount points in different devices + * in Windows we are already skipping them reporting them as special files + */ if ((uint64_t)st->st_dev != disk->device) { + log_tag("%s:%u:%s:%s: Ignoring mount point.\n", es(ESOFT), 0, disk->name, esc_tag(path_next, esc_buffer)); log_fatal(ESOFT, "WARNING! Ignoring mount point '%s' because it appears to be in a different device\n", path_next); } else #endif @@ -1536,6 +1566,7 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa if (!st) st = DSTAT(path_next, dd, &st_buf); + log_tag("%s:%u:%s:%s: Ignoring special file.\n", es(ESOFT), 0, disk->name, esc_tag(path_next, esc_buffer)); log_fatal(ESOFT, "WARNING! Ignoring special '%s' file '%s'\n", stat_desc(st), path_next); } else { msg_verbose("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, tmp, PATH_MAX)); @@ -1571,6 +1602,7 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch static void* scan_disk(void* arg) { + char esc_buffer[ESC_MAX]; struct snapraid_scan* scan = arg; struct snapraid_disk* disk = scan->disk; int ret; @@ -1582,6 +1614,7 @@ static void* scan_disk(void* arg) ret = fsinfo(disk->dir, &has_persistent_inodes, &has_syncronized_hardlinks, 0, 0, 0, 0, 0, 0); if (ret < 0) { /* LCOV_EXCL_START */ + log_tag("%s:%u:%s:%s: Filesystem info error. %s.\n", es(errno), 0, disk->name, esc_tag(disk->dir, esc_buffer), strerror(errno)); log_fatal(errno, "Error accessing disk '%s' to get file-system info. %s.\n", disk->dir, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */