Rename error counters
Some checks are pending
Build / build-mac (push) Waiting to run
Build / build-linux (push) Waiting to run
Build / build-win (push) Waiting to run
CodeQL Advanced / Analyze (c-cpp) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run

This commit is contained in:
Andrea Mazzoleni 2026-01-25 21:25:03 +01:00
parent 2cbc172fd3
commit 622b796208
7 changed files with 326 additions and 271 deletions

View file

@ -899,7 +899,9 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
data_off_t countsize;
block_off_t countpos;
block_off_t countmax;
unsigned error;
unsigned soft_error;
unsigned io_error;
unsigned silent_error;
unsigned unrecoverable_error;
unsigned recovered_error;
struct failed_struct* failed;
@ -936,7 +938,9 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
failed = malloc_nofail(diskmax * sizeof(struct failed_struct));
failed_map = malloc_nofail(diskmax * sizeof(unsigned));
error = 0;
soft_error = 0;
io_error = 0;
silent_error = 0;
unrecoverable_error = 0;
recovered_error = 0;
@ -1125,7 +1129,12 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
++failed_count;
log_tag("%s:%u:%s:%s: Open error at position %u. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, strerror(errno));
++error;
if (errno == EIO) {
++io_error;
} else {
++soft_error;
}
/* mark the file as missing, to avoid to retry to open it again */
/* note that this can be done only if we are not fixing it */
@ -1158,7 +1167,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
) {
log_error("File '%s' is larger than expected.\n", handle[j].path);
log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc_tag(file->sub, esc_buffer));
++error;
++soft_error;
if (fix) {
ret = handle_truncate(&handle[j], file);
@ -1199,7 +1208,12 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
++failed_count;
log_tag("%s:%u:%s:%s: Read error at position %u. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, strerror(errno));
++error;
if (errno == EIO) {
++io_error;
} else {
++soft_error;
}
continue;
}
@ -1248,7 +1262,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
++failed_count;
log_tag("error:%u:%s:%s: Data error at position %u, diff hash bits %u/%u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);
++error;
++silent_error;
continue;
}
@ -1292,7 +1306,11 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
buffer_recov[l] = 0; /* no parity to use */
++error;
if (errno == EIO) {
++io_error;
} else {
++soft_error;
}
}
} else {
buffer_recov[l] = 0;
@ -1304,7 +1322,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (ret != 0) {
/* increment the number of errors */
if (ret > 0)
error += ret;
silent_error += ret;
++unrecoverable_error;
/* print a list of all the errors in files */
@ -1332,7 +1350,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
}
}
if (partial_recover_error != 0) {
error += partial_recover_error;
silent_error += partial_recover_error;
++unrecoverable_error;
}
@ -1355,7 +1373,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
buffer_recov[l] = 0;
log_tag("parity_error:%u:%s: Data error, diff parity bits %u/%u\n", i, lev_config_name(l), diff, state->block_size * 8);
++error;
++silent_error;
}
}
}
@ -1535,19 +1553,24 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno));
log_tag("empty_%s:%s:%s: Empty file stat error\n", es(errno), disk->name, esc_tag(file->sub, esc_buffer));
++error;
if (errno == EIO) {
++io_error;
} else {
++soft_error;
}
} else if (!S_ISREG(st.st_mode)) {
unsuccessful = 1;
log_error("Error stating empty file '%s' for not regular file.\n", path);
log_tag("empty_error:%s:%s: Empty file error for not regular file\n", disk->name, esc_tag(file->sub, esc_buffer));
++error;
++soft_error;
} else if (st.st_size != 0) {
unsuccessful = 1;
log_error("Error stating empty file '%s' for not empty file.\n", path);
log_tag("empty_error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc_tag(file->sub, esc_buffer), (uint64_t)st.st_size);
++error;
++soft_error;
}
if (fix && unsuccessful) {
@ -1650,13 +1673,18 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
log_error("Error stating hardlink '%s'. %s.\n", path, strerror(errno));
log_tag("hardlink_%s:%s:%s:%s: Hardlink stat error. %s.\n", es(errno), disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt), strerror(errno));
++error;
if (errno == EIO) {
++io_error;
} else {
++soft_error;
}
} else if (!S_ISREG(st.st_mode)) {
unsuccessful = 1;
log_error("Error stating hardlink '%s' for not regular file.\n", path);
log_tag("hardlink_error:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
++error;
++soft_error;
}
/* stat the "to" file */
@ -1671,29 +1699,32 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
/* if the target doesn't exist, it's unrecoverable */
/* because we cannot create an hardlink of a file that */
/* doesn't exists */
++unrecoverable_error;
} else {
/* but in check, we can assume that fixing will recover */
/* such missing file, so we assume a less drastic error */
++error;
++unrecoverable_error;
}
}
log_error("Error stating hardlink-to '%s'. %s.\n", pathto, strerror(errno));
log_tag("hardlink_%s:%s:%s:%s: Hardlink to stat error. %s.\n", es(errno), disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt), strerror(errno));
++error;
if (errno == EIO) {
++io_error;
} else {
++soft_error;
}
} else if (!S_ISREG(stto.st_mode)) {
unsuccessful = 1;
log_error("Error stating hardlink-to '%s' for not regular file.\n", path);
log_tag("hardlink_error:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
++error;
++soft_error;
} else if (!unsuccessful && st.st_ino != stto.st_ino) {
unsuccessful = 1;
log_error("Mismatch hardlink '%s' and '%s'. Different inode.\n", path, pathto);
log_tag("hardlink_error:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
++error;
++soft_error;
}
} else {
/* read the symlink */
@ -1704,13 +1735,18 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno));
log_tag("symlink_%s:%s:%s: Symlink read error. %s.\n", es(errno), disk->name, esc_tag(slink->sub, esc_buffer), strerror(errno));
++error;
if (errno == EIO) {
++io_error;
} else {
++soft_error;
}
} else if (ret >= PATH_MAX) {
unsuccessful = 1;
log_error("Error reading symlink '%s'. Symlink too long.\n", path);
log_tag("symlink_error:%s:%s: Symlink too long\n", disk->name, esc_tag(slink->sub, esc_buffer));
++error;
++soft_error;
} else {
linkto[ret] = 0;
@ -1718,7 +1754,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
unsuccessful = 1;
log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc_tag(slink->sub, esc_buffer), linkto, slink->linkto);
++error;
++soft_error;
}
}
}
@ -1819,12 +1855,17 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
log_error("Error stating dir '%s'. %s.\n", path, strerror(errno));
log_tag("dir_%s:%s:%s: Dir stat error. %s.\n", es(errno), disk->name, esc_tag(dir->sub, esc_buffer), strerror(errno));
++error;
if (errno == EIO) {
++io_error;
} else {
++soft_error;
}
} else if (!S_ISDIR(st.st_mode)) {
unsuccessful = 1;
log_tag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc_tag(dir->sub, esc_buffer));
++error;
++soft_error;
}
if (fix && unsuccessful) {
@ -1938,9 +1979,11 @@ bail:
}
}
if (error || recovered_error || unrecoverable_error) {
if (soft_error || io_error || silent_error || recovered_error || unrecoverable_error) {
msg_status("\n");
msg_status("%8u errors\n", error);
msg_status("%8u soft errors\n", soft_error);
msg_status("%8u io errors\n", io_error);
msg_status("%8u data errors\n", silent_error);
if (fix) {
msg_status("%8u recovered errors\n", recovered_error);
}
@ -1957,33 +2000,37 @@ bail:
msg_status("Everything OK\n");
}
if (error && !fix)
if ((soft_error || io_error || silent_error) && !fix)
log_fatal("WARNING! There are errors!\n");
if (unrecoverable_error)
log_fatal("DANGER! Unrecoverable errors detected!\n");
log_tag("summary:error:%u\n", error);
log_tag("summary:error_soft:%u\n", soft_error);
log_tag("summary:error_io:%u\n", io_error);
log_tag("summary:error_data:%u\n", silent_error);
if (fix)
log_tag("summary:error_recovered:%u\n", recovered_error);
if (!state->opt.auditonly)
log_tag("summary:error_unrecoverable:%u\n", unrecoverable_error);
if (fix) {
if (error + recovered_error + unrecoverable_error == 0)
if (soft_error + io_error + silent_error + recovered_error + unrecoverable_error == 0)
log_tag("summary:exit:ok\n");
else if (unrecoverable_error == 0)
log_tag("summary:exit:recovered\n");
else
log_tag("summary:exit:unrecoverable\n");
} else if (!state->opt.auditonly) {
if (error + unrecoverable_error == 0)
if (soft_error + io_error + silent_error + unrecoverable_error == 0)
log_tag("summary:exit:ok\n");
else if (unrecoverable_error == 0)
log_tag("summary:exit:recoverable\n");
else
log_tag("summary:exit:unrecoverable\n");
} else { /* audit only */
if (error == 0)
if (soft_error + silent_error + io_error == 0)
log_tag("summary:exit:ok\n");
else if (silent_error + io_error == 0)
log_tag("summary:exit:warning\n");
else
log_tag("summary:exit:error\n");
}
@ -2010,10 +2057,14 @@ bail:
if (unrecoverable_error == 0)
return -1;
} else if (state->opt.expect_recoverable) {
if (unrecoverable_error != 0 || error == 0)
if (unrecoverable_error != 0)
return -1;
if (soft_error + silent_error + io_error == 0)
return -1;
} else {
if (error != 0 || unrecoverable_error != 0)
if (unrecoverable_error != 0)
return -1;
if (soft_error + silent_error + io_error != 0)
return -1;
}
}
@ -2028,7 +2079,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
int ret;
struct snapraid_parity_handle parity[LEV_MAX];
struct snapraid_parity_handle* parity_ptr[LEV_MAX];
unsigned error;
unsigned process_error;
unsigned l;
msg_progress("Initializing...\n");
@ -2120,14 +2171,14 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
parity_ptr[l] = 0;
}
error = 0;
process_error = 0;
/* skip degenerated cases of empty parity, or skipping all */
if (blockstart < blockmax) {
ret = state_check_process(state, fix, parity_ptr, blockstart, blockmax);
if (ret == -1) {
/* LCOV_EXCL_START */
++error;
++process_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
@ -2144,7 +2195,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
log_tag("parity_%s:%u:%s: Truncate error. %s.\n", es(errno), blockmax, lev_config_name(l), strerror(errno));
log_fatal_errno(errno, lev_config_name(l));
++error;
++process_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
@ -2156,15 +2207,14 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
log_tag("parity_%s:%u:%s: Close error. %s.\n", es(errno), blockmax, lev_config_name(l), strerror(errno));
log_fatal_errno(errno, lev_config_name(l));
++error;
++process_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
}
}
/* abort if error are present */
if (error != 0)
if (process_error != 0)
return -1;
return 0;
}

View file

@ -190,7 +190,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
data_off_t countsize;
block_off_t countpos;
block_off_t countmax;
unsigned error;
unsigned soft_error;
unsigned io_error;
unsigned l;
unsigned* waiting_map;
@ -209,7 +209,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX;
waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned));
error = 0;
soft_error = 0;
io_error = 0;
/* drop until now */
@ -278,12 +278,12 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
}
if (task->state == TASK_STATE_ERROR) {
/* LCOV_EXCL_START */
++error;
++soft_error;
goto bail;
/* LCOV_EXCL_STOP */
}
if (task->state == TASK_STATE_ERROR_CONTINUE) {
++error;
++soft_error;
continue;
}
if (task->state == TASK_STATE_IOERROR_CONTINUE) {
@ -331,12 +331,12 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
}
if (task->state == TASK_STATE_ERROR) {
/* LCOV_EXCL_START */
++error;
++soft_error;
goto bail;
/* LCOV_EXCL_STOP */
}
if (task->state == TASK_STATE_ERROR_CONTINUE) {
++error;
++soft_error;
continue;
}
if (task->state == TASK_STATE_IOERROR_CONTINUE) {
@ -405,29 +405,29 @@ bail:
if (errno == EIO) {
++io_error;
} else {
++error;
++soft_error;
}
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
}
if (error || io_error) {
if (soft_error || io_error) {
msg_status("\n");
msg_status("%8u file errors\n", error);
msg_status("%8u soft errors\n", soft_error);
msg_status("%8u io errors\n", io_error);
} else {
msg_status("Everything OK\n");
}
if (error)
if (soft_error)
log_fatal("DANGER! Unexpected errors!\n");
if (io_error)
log_fatal("DANGER! Unexpected input/output errors!\n");
log_tag("summary:error_file:%u\n", error);
log_tag("summary:error_soft:%u\n", soft_error);
log_tag("summary:error_io:%u\n", io_error);
if (error + io_error == 0)
if (soft_error + io_error == 0)
log_tag("summary:exit:ok\n");
else
log_tag("summary:exit:error\n");
@ -437,7 +437,7 @@ bail:
free(waiting_map);
io_done(&io);
if (error + io_error != 0)
if (soft_error + io_error != 0)
return -1;
return 0;
}
@ -447,7 +447,7 @@ int state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
block_off_t blockmax;
int ret;
struct snapraid_parity_handle parity_handle[LEV_MAX];
unsigned error;
unsigned process_error;
unsigned l;
msg_progress("Drying...\n");
@ -479,14 +479,14 @@ int state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
}
}
error = 0;
process_error = 0;
/* skip degenerated cases of empty parity, or skipping all */
if (blockstart < blockmax) {
ret = state_dry_process(state, parity_handle, blockstart, blockmax);
if (ret == -1) {
/* LCOV_EXCL_START */
++error;
++process_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
@ -500,13 +500,13 @@ int state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
log_tag("parity_%s:%u:%s: Close error. %s.\n", es(errno), blockmax, lev_config_name(l), strerror(errno));
log_fatal_errno(errno, lev_config_name(l));
++error;
++process_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
}
if (error != 0)
if (process_error != 0)
return -1;
return 0;
}

View file

@ -283,7 +283,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
block_off_t autosavelimit;
block_off_t autosavemissing;
int ret;
unsigned error;
unsigned soft_error;
unsigned silent_error;
unsigned io_error;
unsigned l;
@ -308,7 +308,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX;
waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned));
error = 0;
soft_error = 0;
silent_error = 0;
io_error = 0;
@ -453,12 +453,12 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
}
if (task->state == TASK_STATE_ERROR) {
/* LCOV_EXCL_START */
++error;
++soft_error;
goto bail;
/* LCOV_EXCL_STOP */
}
if (task->state == TASK_STATE_ERROR_CONTINUE) {
++error;
++soft_error;
error_on_this_block = 1;
continue;
}
@ -507,7 +507,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
/* it's a silent error only if we are dealing with synced files */
if (file_is_unsynced) {
log_tag("error:%u:%s:%s: Data error at position %u, diff hash bits %u/%u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);
++error;
++soft_error;
error_on_this_block = 1;
} else {
log_tag("error_data:%u:%s:%s: Data error at position %u, diff hash bits %u/%u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);
@ -548,12 +548,12 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
}
if (task->state == TASK_STATE_ERROR) {
/* LCOV_EXCL_START */
++error;
++soft_error;
goto bail;
/* LCOV_EXCL_STOP */
}
if (task->state == TASK_STATE_ERROR_CONTINUE) {
++error;
++soft_error;
error_on_this_block = 1;
/* if continuing on error, clear the missing buffer */
@ -599,7 +599,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
/* it's a silent error only if we are dealing with synced blocks */
if (block_is_unsynced) {
log_tag("parity_error:%u:%s: Data error, diff parity bits %u/%u\n", blockcur, lev_config_name(l), diff, state->block_size * 8);
++error;
++soft_error;
error_on_this_block = 1;
} else {
log_tag("parity_error_data:%u:%s: Data error, diff parity bits %u/%u\n", blockcur, lev_config_name(l), diff, state->block_size * 8);
@ -694,9 +694,9 @@ end:
state_usage_print(state);
if (error || silent_error || io_error) {
if (soft_error || silent_error || io_error) {
msg_status("\n");
msg_status("%8u file errors\n", error);
msg_status("%8u soft errors\n", soft_error);
msg_status("%8u io errors\n", io_error);
msg_status("%8u data errors\n", silent_error);
} else {
@ -705,8 +705,8 @@ end:
msg_status("Everything OK\n");
}
if (error)
log_fatal("WARNING! Unexpected file errors!\n");
if (soft_error)
log_fatal("WARNING! Unexpected soft errors!\n");
if (io_error)
log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
if (silent_error)
@ -717,10 +717,10 @@ end:
log_fatal("Use 'snapraid -p bad scrub' to recheck after fixing to clear the bad state.\n");
}
log_tag("summary:error_file:%u\n", error);
log_tag("summary:error_soft:%u\n", soft_error);
log_tag("summary:error_io:%u\n", io_error);
log_tag("summary:error_data:%u\n", silent_error);
if (error + silent_error + io_error == 0)
if (soft_error + silent_error + io_error == 0)
log_tag("summary:exit:ok\n");
else if (silent_error + io_error == 0)
log_tag("summary:exit:warning\n");
@ -744,7 +744,7 @@ bail:
if (errno == EIO) {
++io_error;
} else {
++error;
++soft_error;
}
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
@ -758,10 +758,10 @@ bail:
free(block_enabled);
if (state->opt.expect_recoverable) {
if (error + silent_error + io_error == 0)
if (soft_error + silent_error + io_error == 0)
return -1;
} else {
if (error + silent_error + io_error != 0)
if (soft_error + silent_error + io_error != 0)
return -1;
}
return 0;
@ -792,7 +792,7 @@ int state_scrub(struct snapraid_state* state, int plan, int olderthan)
struct snapraid_parity_handle parity_handle[LEV_MAX];
struct snapraid_plan ps;
time_t* timemap;
unsigned error;
unsigned process_error;
time_t now;
unsigned l;
@ -950,11 +950,11 @@ int state_scrub(struct snapraid_state* state, int plan, int olderthan)
}
}
error = 0;
process_error = 0;
ret = state_scrub_process(state, parity_handle, 0, blockmax, &ps, now);
if (ret == -1) {
++error;
++process_error;
/* continue, as we are already exiting */
}
@ -965,14 +965,13 @@ int state_scrub(struct snapraid_state* state, int plan, int olderthan)
log_tag("parity_%s:%u:%s: Close error. %s.\n", es(errno), blockmax, lev_config_name(l), strerror(errno));
log_fatal_errno(errno, lev_config_name(l));
++error;
++process_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
}
/* abort if required */
if (error != 0)
if (process_error != 0)
return -1;
return 0;
}

View file

@ -76,7 +76,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
block_off_t countpos;
block_off_t countmax;
int ret;
unsigned error;
unsigned soft_error;
unsigned silent_error;
unsigned io_error;
char esc_buffer[ESC_MAX];
@ -89,7 +89,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
if (!state->opt.skip_self)
mtest_vector(1, state->block_size, &buffer);
error = 0;
soft_error = 0;
silent_error = 0;
io_error = 0;
@ -181,7 +181,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
if (errno == EIO) {
++io_error;
} else {
++error;
++soft_error;
}
goto bail;
/* LCOV_EXCL_STOP */
@ -194,7 +194,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
if (errno == ENOENT) {
log_error_errno(errno, disk->name);
++error;
++soft_error;
/* if the file is missing, it means that it was removed during sync */
/* this isn't a serious error, so we skip this block, and continue with others */
continue;
@ -203,7 +203,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
if (errno == EACCES) {
log_error_errno(errno, disk->name);
++error;
++soft_error;
/* this isn't a serious error, so we skip this block, and continue with others */
continue;
}
@ -216,7 +216,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
++io_error;
} else {
log_fatal("Stopping to allow recovery. Try with 'snapraid check -f /%s'\n", fmt_poll(disk, file->sub, esc_buffer));
++error;
++soft_error;
}
goto bail;
/* LCOV_EXCL_STOP */
@ -241,7 +241,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
}
log_error_errno(ENOENT, disk->name); /* same message for ENOENT */
++error;
++soft_error;
/* if the file is changed, it means that it was modified during sync */
/* this isn't a serious error, so we skip this block, and continue with others */
@ -259,7 +259,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
++io_error;
} else {
log_fatal("Stopping to allow recovery. Try with 'snapraid check -f /%s'\n", fmt_poll(disk, file->sub, esc_buffer));
++error;
++soft_error;
}
goto bail;
/* LCOV_EXCL_STOP */
@ -347,7 +347,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
if (errno == EIO) {
++io_error;
} else {
++error;
++soft_error;
}
goto bail;
/* LCOV_EXCL_STOP */
@ -362,9 +362,9 @@ end:
/* because at the first one we bail out */
assert(io_error == 0);
if (error || io_error || silent_error) {
if (soft_error || io_error || silent_error) {
msg_status("\n");
msg_status("%8u file errors\n", error);
msg_status("%8u soft errors\n", soft_error);
msg_status("%8u io errors\n", io_error);
msg_status("%8u data errors\n", silent_error);
} else {
@ -373,10 +373,10 @@ end:
msg_status("Everything OK\n");
}
if (error)
log_fatal("WARNING! Unexpected file errors!\n");
if (soft_error)
log_fatal("WARNING! Unexpected soft errors!\n");
log_tag("hash_summary:error_file:%u\n", error);
log_tag("hash_summary:error_soft:%u\n", soft_error);
/* proceed without bailing out */
goto finish;
@ -398,7 +398,7 @@ bail:
if (errno == EIO) {
++io_error;
} else {
++error;
++soft_error;
}
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
@ -409,7 +409,7 @@ finish:
free(handle);
free(buffer_alloc);
if (error + io_error + silent_error != 0)
if (soft_error + io_error + silent_error != 0)
return -1;
return 0;
}
@ -687,7 +687,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
block_off_t autosavelimit;
block_off_t autosavemissing;
int ret;
unsigned error;
unsigned soft_error;
unsigned silent_error;
unsigned io_error;
time_t now;
@ -733,7 +733,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX;
waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned));
error = 0;
soft_error = 0;
silent_error = 0;
io_error = 0;
@ -906,12 +906,12 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
}
if (task->state == TASK_STATE_ERROR) {
/* LCOV_EXCL_START */
++error;
++soft_error;
goto bail;
/* LCOV_EXCL_STOP */
}
if (task->state == TASK_STATE_ERROR_CONTINUE) {
++error;
++soft_error;
error_on_this_block = 1;
continue;
}
@ -970,7 +970,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
log_error("Try removing the file from the array and rerun the 'sync' command!\n");
}
++error;
++soft_error;
/* if the file is changed, it means that it was modified during sync */
/* this isn't a serious error, so we skip this block, and continue with others */
@ -1097,7 +1097,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
log_fatal_errno(errno, lev_config_name(l));
log_fatal("Stopping at block %u\n", blockcur);
++error;
++soft_error;
goto bail;
/* LCOV_EXCL_STOP */
}
@ -1270,7 +1270,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
}
break;
case TASK_STATE_ERROR_CONTINUE :
++error;
++soft_error;
break;
case TASK_STATE_IOERROR :
/* LCOV_EXCL_START */
@ -1279,7 +1279,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
/* LCOV_EXCL_STOP */
case TASK_STATE_ERROR :
/* LCOV_EXCL_START */
++error;
++soft_error;
goto bail;
/* LCOV_EXCL_STOP */
}
@ -1385,9 +1385,9 @@ end:
state_usage_print(state);
if (error || silent_error || io_error) {
if (soft_error || silent_error || io_error) {
msg_status("\n");
msg_status("%8u file errors\n", error);
msg_status("%8u soft errors\n", soft_error);
msg_status("%8u io errors\n", io_error);
msg_status("%8u data errors\n", silent_error);
} else {
@ -1396,21 +1396,21 @@ end:
msg_status("Everything OK\n");
}
if (error)
log_fatal("WARNING! Unexpected file errors!\n");
if (soft_error)
log_fatal("WARNING! Unexpected soft errors!\n");
if (io_error)
log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
if (silent_error)
log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n");
log_fatal("DANGER! Unexpected silent data errors! The failing blocks are now marked as bad!\n");
if (io_error || silent_error) {
log_fatal("Use 'snapraid status' to list the bad blocks.\n");
log_fatal("Use 'snapraid -e fix' to recover.\n");
}
log_tag("summary:error_file:%u\n", error);
log_tag("summary:error_soft:%u\n", soft_error);
log_tag("summary:error_io:%u\n", io_error);
log_tag("summary:error_data:%u\n", silent_error);
if (error + silent_error + io_error == 0)
if (soft_error + silent_error + io_error == 0)
log_tag("summary:exit:ok\n");
else if (silent_error + io_error == 0)
log_tag("summary:exit:warning\n");
@ -1434,7 +1434,7 @@ bail:
if (errno == EIO) {
++io_error;
} else {
++error;
++soft_error;
}
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
@ -1453,10 +1453,10 @@ bail:
free(block_enabled);
if (state->opt.expect_recoverable) {
if (error + silent_error + io_error == 0)
if (soft_error + silent_error + io_error == 0)
return -1;
} else {
if (error + silent_error + io_error != 0)
if (soft_error + silent_error + io_error != 0)
return -1;
}
return 0;
@ -1470,7 +1470,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
data_off_t size;
int ret;
struct snapraid_parity_handle parity_handle[LEV_MAX];
unsigned unrecoverable_error;
unsigned process_error;
unsigned l;
int skip_sync = 0;
@ -1545,7 +1545,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
}
}
unrecoverable_error = 0;
process_error = 0;
if (state->opt.prehash) {
msg_progress("Hashing...\n");
@ -1553,7 +1553,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
ret = state_hash_process(state, blockstart, blockmax, &skip_sync);
if (ret == -1) {
/* LCOV_EXCL_START */
++unrecoverable_error;
++process_error;
/* continue, in case also doing the sync if ::skip_sync is not set */
/* LCOV_EXCL_STOP */
}
@ -1619,7 +1619,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
ret = state_sync_process(state, parity_handle, blockstart, blockmax);
if (ret == -1) {
/* LCOV_EXCL_START */
++unrecoverable_error;
++process_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
@ -1635,14 +1635,13 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
log_tag("parity_%s:%u:%s: Close error. %s.\n", es(errno), blockmax, lev_config_name(l), strerror(errno));
log_fatal_errno(errno, lev_config_name(l));
++unrecoverable_error;
++process_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
}
}
/* abort if required */
if (unrecoverable_error != 0)
if (process_error != 0)
return -1;
return 0;
}

View file

@ -956,7 +956,7 @@ Also the error tags are possible.
.SS Summary Tags
These tags provide summary statistics at the end of the command.
.TP
.B hash_summary:error_file:<count>
.B hash_summary:error_soft:<count>
Logs the total count of file\-related errors that caused a
block to be skipped during the hashing phase. These are often
due to file changes (missing, size/time change) during the
@ -969,7 +969,7 @@ Total number of file errors (uint).
.PD
.RE
.TP
.B summary:error_file:<count>
.B summary:error_soft:<count>
Logs the total count of file\-related errors encountered during
the process (e.g., missing files, file attribute changes).
.RS 4
@ -1013,8 +1013,8 @@ one of the following:
No issues. The array is fully synchronized and healthy.
.HP 4
.I warning
Some files were skipped due to modifications during
execution or permission issues. No hardware risk.
Some files were skipped due to likely intentional
modifications. No hardware risk.
.HP 4
.I error
Critical failure. Indicates serious issues like I/O failures
@ -1023,7 +1023,8 @@ or filesystem inspection.
.PD
.RE
.SH COMMAND CHECK/FIX TAGS
Tags specific for the \`check\` and \`fix\` commands.
Tags specific for the \`check\` and \`fix\` commands. For \`audit\` mode,
it\'s inteded \`check\` with the \`\-\-audit\-only\` option.
Also the error tags are possible.
.SS Fixed/Recovered Tags
These tags log successful repairs during fix operations.
@ -1184,7 +1185,7 @@ These tags log the final status of files after processing.
.TP
.B status:unrecoverable:<disk_name>:<file_path>
Indicates that a file has unrecoverable errors and was renamed to
\`.unrecoverable\` (in fix mode) or cannot be recovered (in check mode).
\`.unrecoverable\` (fix) or cannot be recovered (check).
.RS 4
.PD 0
.HP 4
@ -1209,21 +1210,9 @@ The file path relative to disk root (escaped).
.PD
.RE
.TP
.B status:damaged:<disk_name>:<file_path>
Indicates that a file is damaged (in audit\-only mode, e.g., using \`check\`).
.RS 4
.PD 0
.HP 4
.I <disk_name>
The name of the disk.
.HP 4
.I <file_path>
The file path relative to disk root (escaped).
.PD
.RE
.TP
.B status:recoverable:<disk_name>:<file_path>
Logs that a file has errors but could be recovered in fix mode.
Logs that a file has errors but could be recovered with a
\`fix\` (check).
.RS 4
.PD 0
.HP 4
@ -1236,7 +1225,7 @@ The file path relative to disk root (escaped).
.RE
.TP
.B status:correct:<disk_name>:<file_path>
Indicates that a file passed all checks successfully (verbose mode only).
Indicates that a file passed all checks successfully (verbose).
.RS 4
.PD 0
.HP 4
@ -1250,18 +1239,42 @@ The file path relative to disk root (escaped).
.SS Summary Tags
These tags provide summary statistics at the end of the command.
.TP
.B summary:error:<error_count>
Logs the total number of errors encountered.
.B summary:error_soft:<count>
Logs the total count of file\-related errors encountered during
the process (e.g., missing files, file attribute changes).
.RS 4
.PD 0
.HP 4
.I <error_count>
Total number of errors (uint).
.I <count>
The total number of file errors encountered (uint).
.PD
.RE
.TP
.B summary:error_io:<count>
Logs the total count of input/output errors encountered on
data or parity disks.
.RS 4
.PD 0
.HP 4
.I <count>
The total number of I/O errors encountered (uint).
.PD
.RE
.TP
.B summary:error_data:<count>
Logs the total count of \`silent data errors\` (data blocks
not matching their expected hash) encountered during the sync
process.
.RS 4
.PD 0
.HP 4
.I <count>
The total number of silent data errors encountered (uint).
.PD
.RE
.TP
.B summary:error_recovered:<recovered_count>
Logs the total number of errors successfully recovered (fix mode only).
Logs the total number of errors successfully recovered (fix).
.RS 4
.PD 0
.HP 4
@ -1270,8 +1283,18 @@ Number of recovered errors (uint).
.PD
.RE
.TP
.B summary:error_recoverable:<recoverable_count>
Logs the total number of errors that can be recovered (check).
.RS 4
.PD 0
.HP 4
.I <recoverable_count>
Number of recoverable errors (uint).
.PD
.RE
.TP
.B summary:error_unrecoverable:<unrecoverable_count>
Logs the total number of unrecoverable errors (not in audit\-only mode).
Logs the total number of unrecoverable errors (fix/check).
.RS 4
.PD 0
.HP 4
@ -1287,22 +1310,29 @@ the following:
.PD 0
.HP 4
.I ok
Indicates that the operation completed with no errors.
Indicates that the operation completed with no errors (audit).
.HP 4
.I warning
Some files were different than expected, likely caused
by intentional modification of the files.
No hardware risk (audit).
.HP 4
.I error
Critical failure. Indicates serious issues like I/O failures
or silent data corruption. Requires immediate hardware
or filesystem inspection (audit).
.HP 4
.I recovered
Indicates that the operation completed with all
errors successfully recovered (fix mode only).
errors successfully recovered (fix).
.HP 4
.I recoverable
Indicates that errors were found but are all
recoverable (check mode only).
recoverable (check).
.HP 4
.I unrecoverable
Indicates that unrecoverable errors were
found.
.HP 4
.I error
Indicates that errors were found (audit\-only mode).
found (check/fix).
.PD
.RE
.SH COMMAND LIST TAGS
@ -1801,30 +1831,6 @@ The integer exit status returned by the
process (int).
.PD
.RE
.SH STATUS TAGS
These tags log the recovery status of files after a \`check\` or \`fix\`
command.
.TP
.B status:unrecoverable:<disk_name>:<file_path>
The file is not recoverable. If a \`fix\` command was run, it
was also renamed with the \`.unrecoverable\` extension.
.RS 4
.PD 0
.HP 4
.I <disk_name>
The name of the disk.
.HP 4
.I <file_path>
The file path relative to disk root (escaped).
.PD
.RE
.TP
.B status:recovered:<disk_name>:<file_path>
The file was recovered by a \`fix\` command.
.TP
.B status:recoverable:<disk_name>:<file_path>
The file is recoverable, and will be recovered by a \`fix\`
command.
.SH ERROR TAGS
These tags report specific errors that occur on data disks during the
commands that access files and parities.

View file

@ -636,7 +636,7 @@ Command Sync/Scrub Tags
Summary Tags
These tags provide summary statistics at the end of the command.
=hash_summary:error_file:<count>
=hash_summary:error_soft:<count>
Logs the total count of file-related errors that caused a
block to be skipped during the hashing phase. These are often
due to file changes (missing, size/time change) during the
@ -644,7 +644,7 @@ Command Sync/Scrub Tags
<count> - Total number of file errors (uint).
=summary:error_file:<count>
=summary:error_soft:<count>
Logs the total count of file-related errors encountered during
the process (e.g., missing files, file attribute changes).
@ -668,14 +668,15 @@ Command Sync/Scrub Tags
one of the following:
ok - No issues. The array is fully synchronized and healthy.
warning - Some files were skipped due to modifications during
execution or permission issues. No hardware risk.
warning - Some files were skipped due to likely intentional
modifications. No hardware risk.
error - Critical failure. Indicates serious issues like I/O failures
or silent data corruption. Requires immediate hardware
or filesystem inspection.
Command Check/Fix Tags
Tags specific for the `check` and `fix` commands.
Tags specific for the `check` and `fix` commands. For `audit` mode,
it's inteded `check` with the `--audit-only` option.
Also the error tags are possible.
Fixed/Recovered Tags
@ -761,7 +762,7 @@ Command Check/Fix Tags
=status:unrecoverable:<disk_name>:<file_path>
Indicates that a file has unrecoverable errors and was renamed to
`.unrecoverable` (in fix mode) or cannot be recovered (in check mode).
`.unrecoverable` (fix) or cannot be recovered (check).
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
@ -772,20 +773,15 @@ Command Check/Fix Tags
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
=status:damaged:<disk_name>:<file_path>
Indicates that a file is damaged (in audit-only mode, e.g., using `check`).
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
=status:recoverable:<disk_name>:<file_path>
Logs that a file has errors but could be recovered in fix mode.
Logs that a file has errors but could be recovered with a
`fix` (check).
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
=status:correct:<disk_name>:<file_path>
Indicates that a file passed all checks successfully (verbose mode only).
Indicates that a file passed all checks successfully (verbose).
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
@ -793,33 +789,57 @@ Command Check/Fix Tags
Summary Tags
These tags provide summary statistics at the end of the command.
=summary:error:<error_count>
Logs the total number of errors encountered.
=summary:error_soft:<count>
Logs the total count of file-related errors encountered during
the process (e.g., missing files, file attribute changes).
<count> - The total number of file errors encountered (uint).
<error_count> - Total number of errors (uint).
=summary:error_io:<count>
Logs the total count of input/output errors encountered on
data or parity disks.
<count> - The total number of I/O errors encountered (uint).
=summary:error_data:<count>
Logs the total count of `silent data errors` (data blocks
not matching their expected hash) encountered during the sync
process.
<count> - The total number of silent data errors encountered (uint).
=summary:error_recovered:<recovered_count>
Logs the total number of errors successfully recovered (fix mode only).
Logs the total number of errors successfully recovered (fix).
<recovered_count> - Number of recovered errors (uint).
=summary:error_recoverable:<recoverable_count>
Logs the total number of errors that can be recovered (check).
<recoverable_count> - Number of recoverable errors (uint).
=summary:error_unrecoverable:<unrecoverable_count>
Logs the total number of unrecoverable errors (not in audit-only mode).
Logs the total number of unrecoverable errors (fix/check).
<unrecoverable_count> - Number of unrecoverable errors (uint).
=summary:exit:<status>
Logs the overall exit status of the command. The `status` is one of
the following:
ok - Indicates that the operation completed with no errors.
ok - Indicates that the operation completed with no errors (audit).
warning - Some files were different than expected, likely caused
by intentional modification of the files.
No hardware risk (audit).
error - Critical failure. Indicates serious issues like I/O failures
or silent data corruption. Requires immediate hardware
or filesystem inspection (audit).
recovered - Indicates that the operation completed with all
errors successfully recovered (fix mode only).
errors successfully recovered (fix).
recoverable - Indicates that errors were found but are all
recoverable (check mode only).
recoverable (check).
unrecoverable - Indicates that unrecoverable errors were
found.
error - Indicates that errors were found (audit-only mode).
found (check/fix).
Command List Tags
This section describes the tags output with the `list` command.
@ -1146,24 +1166,6 @@ Device Status Tags
<exit_code> - The integer exit status returned by the
process (int).
Status Tags
These tags log the recovery status of files after a `check` or `fix`
command.
=status:unrecoverable:<disk_name>:<file_path>
The file is not recoverable. If a `fix` command was run, it
was also renamed with the `.unrecoverable` extension.
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
=status:recovered:<disk_name>:<file_path>
The file was recovered by a `fix` command.
=status:recoverable:<disk_name>:<file_path>
The file is recoverable, and will be recovered by a `fix`
command.
Error Tags
These tags report specific errors that occur on data disks during the
commands that access files and parities.

View file

@ -664,7 +664,7 @@ Also the error tags are possible.
---- 9.0.1 Summary Tags ----
These tags provide summary statistics at the end of the command.
hash_summary:error_file:<count>
hash_summary:error_soft:<count>
Logs the total count of file-related errors that caused a
block to be skipped during the hashing phase. These are often
due to file changes (missing, size/time change) during the
@ -672,7 +672,7 @@ These tags provide summary statistics at the end of the command.
<count> - Total number of file errors (uint).
summary:error_file:<count>
summary:error_soft:<count>
Logs the total count of file-related errors encountered during
the process (e.g., missing files, file attribute changes).
@ -696,8 +696,8 @@ These tags provide summary statistics at the end of the command.
one of the following:
ok - No issues. The array is fully synchronized and healthy.
warning - Some files were skipped due to modifications during
execution or permission issues. No hardware risk.
warning - Some files were skipped due to likely intentional
modifications. No hardware risk.
error - Critical failure. Indicates serious issues like I/O failures
or silent data corruption. Requires immediate hardware
or filesystem inspection.
@ -706,7 +706,8 @@ These tags provide summary statistics at the end of the command.
10 COMMAND CHECK/FIX TAGS
=========================
Tags specific for the `check` and `fix` commands.
Tags specific for the `check` and `fix` commands. For `audit` mode,
it's inteded `check` with the `--audit-only` option.
Also the error tags are possible.
---- 10.0.1 Fixed/Recovered Tags ----
@ -792,7 +793,7 @@ These tags log the final status of files after processing.
status:unrecoverable:<disk_name>:<file_path>
Indicates that a file has unrecoverable errors and was renamed to
`.unrecoverable` (in fix mode) or cannot be recovered (in check mode).
`.unrecoverable` (fix) or cannot be recovered (check).
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
@ -803,20 +804,15 @@ These tags log the final status of files after processing.
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
status:damaged:<disk_name>:<file_path>
Indicates that a file is damaged (in audit-only mode, e.g., using `check`).
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
status:recoverable:<disk_name>:<file_path>
Logs that a file has errors but could be recovered in fix mode.
Logs that a file has errors but could be recovered with a
`fix` (check).
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
status:correct:<disk_name>:<file_path>
Indicates that a file passed all checks successfully (verbose mode only).
Indicates that a file passed all checks successfully (verbose).
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
@ -824,18 +820,37 @@ These tags log the final status of files after processing.
---- 10.0.4 Summary Tags ----
These tags provide summary statistics at the end of the command.
summary:error:<error_count>
Logs the total number of errors encountered.
summary:error_soft:<count>
Logs the total count of file-related errors encountered during
the process (e.g., missing files, file attribute changes).
<error_count> - Total number of errors (uint).
<count> - The total number of file errors encountered (uint).
summary:error_io:<count>
Logs the total count of input/output errors encountered on
data or parity disks.
<count> - The total number of I/O errors encountered (uint).
summary:error_data:<count>
Logs the total count of `silent data errors` (data blocks
not matching their expected hash) encountered during the sync
process.
<count> - The total number of silent data errors encountered (uint).
summary:error_recovered:<recovered_count>
Logs the total number of errors successfully recovered (fix mode only).
Logs the total number of errors successfully recovered (fix).
<recovered_count> - Number of recovered errors (uint).
summary:error_recoverable:<recoverable_count>
Logs the total number of errors that can be recovered (check).
<recoverable_count> - Number of recoverable errors (uint).
summary:error_unrecoverable:<unrecoverable_count>
Logs the total number of unrecoverable errors (not in audit-only mode).
Logs the total number of unrecoverable errors (fix/check).
<unrecoverable_count> - Number of unrecoverable errors (uint).
@ -843,14 +858,19 @@ These tags provide summary statistics at the end of the command.
Logs the overall exit status of the command. The `status` is one of
the following:
ok - Indicates that the operation completed with no errors.
ok - Indicates that the operation completed with no errors (audit).
warning - Some files were different than expected, likely caused
by intentional modification of the files.
No hardware risk (audit).
error - Critical failure. Indicates serious issues like I/O failures
or silent data corruption. Requires immediate hardware
or filesystem inspection (audit).
recovered - Indicates that the operation completed with all
errors successfully recovered (fix mode only).
errors successfully recovered (fix).
recoverable - Indicates that errors were found but are all
recoverable (check mode only).
recoverable (check).
unrecoverable - Indicates that unrecoverable errors were
found.
error - Indicates that errors were found (audit-only mode).
found (check/fix).
11 COMMAND LIST TAGS
@ -1196,28 +1216,7 @@ command execution with the `smartctl` command.
process (int).
17 STATUS TAGS
==============
These tags log the recovery status of files after a `check` or `fix`
command.
status:unrecoverable:<disk_name>:<file_path>
The file is not recoverable. If a `fix` command was run, it
was also renamed with the `.unrecoverable` extension.
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
status:recovered:<disk_name>:<file_path>
The file was recovered by a `fix` command.
status:recoverable:<disk_name>:<file_path>
The file is recoverable, and will be recovered by a `fix`
command.
18 ERROR TAGS
17 ERROR TAGS
=============
These tags report specific errors that occur on data disks during the