From 2cbc172fd38c32a479c69bc96eaf9f6a508426d1 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 25 Jan 2026 14:06:56 +0100 Subject: [PATCH] Reworked recover tags --- cmdline/check.c | 37 ++++++++++++++++--------------------- doc/snapraid_log.1 | 34 +++++++++++++++++++++++++++++----- doc/snapraid_log.d | 28 +++++++++++++++++++++++----- doc/snapraid_log.txt | 33 +++++++++++++++++++++++++++------ 4 files changed, 95 insertions(+), 37 deletions(-) diff --git a/cmdline/check.c b/cmdline/check.c index 6bde6266..596cdaca 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -134,7 +134,7 @@ static int is_hash_matching(struct snapraid_state* state, int rehash, unsigned d /* if a hash doesn't match, fail the check */ unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size); if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) { - log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]); + log_tag("repair_hash_error:%u: Hash mismatch\n", failed_map[j]); return 0; } @@ -245,13 +245,13 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u return 0; /* log */ - log_tag("parity_error:%u:", pos); + log_tag("recover_parity_error:%u:", pos); for (i = 0; i < r; ++i) { if (i != 0) - log_tag("/"); + log_tag(","); log_tag("%s", lev_config_name(ip[i])); } - log_tag(":parity: Parity mismatch\n"); + log_tag(": Parity mismatch\n"); ++error; } while (combination_next(r, n, ip)); } @@ -285,13 +285,13 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u return 0; /* log */ - log_tag("parity_error:%u:", pos); + log_tag("recover_hash_error:%u:", pos); for (i = 0; i < r; ++i) { if (i != 0) log_tag("/"); log_tag("%s", lev_config_name(ip[i])); } - log_tag(":hash: Hash mismatch\n"); + log_tag(": Hash mismatch\n"); ++error; } while (combination_next(r, n, ip)); } @@ -300,7 +300,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u if (error) return error; - log_tag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n", + log_tag("recover_strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n", pos, failed_count, n, has_hash ? "with" : "without"); return -1; } @@ -359,9 +359,9 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign struct snapraid_file* file = failed[j].file; block_off_t file_pos = failed[j].file_pos; - log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc_tag(file->sub, esc_buffer), file_pos); + log_tag("repair_entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc_tag(file->sub, esc_buffer), file_pos); } else { - log_tag("entry:%u:%s:%s:%s:\n", j, desc, hash, data); + log_tag("repair_entry:%u:%s:%s:%s:\n", j, desc, hash, data); } } @@ -396,7 +396,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0) ) { /* we already have corrected it! */ - log_tag("hash_import: Fixed entry %u\n", j); + log_tag("repair_hash_import:%u: Fixed by import\n", j); } else { /* otherwise try to recover it */ failed_map[n] = j; @@ -444,7 +444,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign /* it may contain garbage */ failed[j].is_outofdate = 1; - log_tag("hash_unknown: Unknown hash on entry %u\n", j); + log_tag("repair:hash_unknown:%u: Unknown hash\n", j); } else if (hash_is_zero(failed[j].block->hash)) { /* if the block is not filled with 0, we are sure to have */ /* restored it to the state after the 'sync' */ @@ -455,7 +455,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign /* it may contain garbage */ failed[j].is_outofdate = 1; - log_tag("hash_unknown: Maybe old zero on entry %u\n", j); + log_tag("repair_hash_unknown:%u: Maybe old zero\n", j); } } else { /* if the hash is different than the previous one, we are sure to have */ @@ -468,7 +468,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign /* it may contain garbage */ failed[j].is_outofdate = 1; - log_tag("hash_unknown: Maybe old data on entry %u\n", j); + log_tag("repair_hash_unknown:%u: Maybe old data\n", j); } } } @@ -578,7 +578,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign /* and we don't want to write it to the disk */ failed[j].is_outofdate = 1; - log_tag("hash_unknown: Surely old data on entry %u\n", j); + log_tag("repair_hash_unknown:%u: Surely old data\n", j); } } } @@ -778,13 +778,8 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s /* we are not fixing, but only checking */ /* print just the final status */ if (file_flag_has(file, FILE_IS_DAMAGED)) { - if (state->opt.auditonly) { - log_tag("status:damaged:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - msg_info("damaged %s\n", fmt_term(disk, file->sub, esc_buffer)); - } else { - log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); - } + log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); } else if (file_flag_has(file, FILE_IS_FIXED)) { log_tag("status:recoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); msg_info("recoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); diff --git a/doc/snapraid_log.1 b/doc/snapraid_log.1 index 2dc72cc6..8d0150a3 100644 --- a/doc/snapraid_log.1 +++ b/doc/snapraid_log.1 @@ -1801,6 +1801,30 @@ 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:: +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 +The name of the disk. +.HP 4 +.I +The file path relative to disk root (escaped). +.PD +.RE +.TP +.B status:recovered:: +The file was recovered by a \`fix\` command. +.TP +.B status:recoverable:: +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. @@ -1833,7 +1857,7 @@ file containing the block (escaped). .HP 4 .I A descriptive message indicating the nature of the -error (e.g., \`Open/Read/Write EIO error\`, \`Open/Read/Write error\`, +error (e.g., \`Open/Read/Write error\`, \`Data error at position , diff bits /\`). .PD .RE @@ -1862,12 +1886,12 @@ The configuration name of the parity level (e.g., .HP 4 .I A descriptive message indicating the nature of the -error (e.g., \`Read/Write EIO error\`, \`Read/Write error\`, +error (e.g., \`Read/Write error\`, \`Data error, diff bits /\`). .PD .RE .TP -.B hardlink_error:::: +.B hardlink_error[_io]:::: Indicates an error when attempting to access a hard link. .RS 4 .PD 0 @@ -1890,7 +1914,7 @@ error (e.g., \`Hardlink stat error\`, .PD .RE .TP -.B symlink_error::: +.B symlink_error[_io]::: Indicates an error when attempting to access a symbolic link. .RS 4 .PD 0 @@ -1908,7 +1932,7 @@ error (e.g., \`Symlink read error\`, .PD .RE .TP -.B dir_error::: +.B dir_error[_io]::: Indicates an error when attempting to access a directory. .RS 4 .PD 0 diff --git a/doc/snapraid_log.d b/doc/snapraid_log.d index 3b530728..39e2ed1b 100644 --- a/doc/snapraid_log.d +++ b/doc/snapraid_log.d @@ -1146,6 +1146,24 @@ Device Status Tags - 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:: + The file is not recoverable. If a `fix` command was run, it + was also renamed with the `.unrecoverable` extension. + + - The name of the disk. + - The file path relative to disk root (escaped). + + =status:recovered:: + The file was recovered by a `fix` command. + + =status:recoverable:: + 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. @@ -1165,7 +1183,7 @@ Error Tags - The path (relative to the disk mount point) of the file containing the block (escaped). - A descriptive message indicating the nature of the - error (e.g., `Open/Read/Write EIO error`, `Open/Read/Write error`, + error (e.g., `Open/Read/Write error`, `Data error at position , diff bits /`). =parity_error[_io|_data]::: @@ -1181,10 +1199,10 @@ Error Tags - The configuration name of the parity level (e.g., `parity`, `2-parity`). - A descriptive message indicating the nature of the - error (e.g., `Read/Write EIO error`, `Read/Write error`, + error (e.g., `Read/Write error`, `Data error, diff bits /`). - =hardlink_error:::: + =hardlink_error[_io]:::: Indicates an error when attempting to access a hard link. - The name of the disk. @@ -1196,7 +1214,7 @@ Error Tags `Hardlink-to error for not regular file`, `Hardlink mismatch for different inode`). - =symlink_error::: + =symlink_error[_io]::: Indicates an error when attempting to access a symbolic link. - The name of the disk. @@ -1205,7 +1223,7 @@ Error Tags error (e.g., `Symlink read error`, `Symlink data error '' instead of ''`). - =dir_error::: + =dir_error[_io]::: Indicates an error when attempting to access a directory. - The name of the disk. diff --git a/doc/snapraid_log.txt b/doc/snapraid_log.txt index ddfe90cc..a1023e2d 100644 --- a/doc/snapraid_log.txt +++ b/doc/snapraid_log.txt @@ -1196,7 +1196,28 @@ command execution with the `smartctl` command. process (int). -17 ERROR TAGS +17 STATUS TAGS +============== + +These tags log the recovery status of files after a `check` or `fix` +command. + + status:unrecoverable:: + The file is not recoverable. If a `fix` command was run, it + was also renamed with the `.unrecoverable` extension. + + - The name of the disk. + - The file path relative to disk root (escaped). + + status:recovered:: + The file was recovered by a `fix` command. + + status:recoverable:: + The file is recoverable, and will be recovered by a `fix` + command. + + +18 ERROR TAGS ============= These tags report specific errors that occur on data disks during the @@ -1217,7 +1238,7 @@ commands that access files and parities. - The path (relative to the disk mount point) of the file containing the block (escaped). - A descriptive message indicating the nature of the - error (e.g., `Open/Read/Write EIO error`, `Open/Read/Write error`, + error (e.g., `Open/Read/Write error`, `Data error at position , diff bits /`). parity_error[_io|_data]::: @@ -1233,10 +1254,10 @@ commands that access files and parities. - The configuration name of the parity level (e.g., `parity`, `2-parity`). - A descriptive message indicating the nature of the - error (e.g., `Read/Write EIO error`, `Read/Write error`, + error (e.g., `Read/Write error`, `Data error, diff bits /`). - hardlink_error:::: + hardlink_error[_io]:::: Indicates an error when attempting to access a hard link. - The name of the disk. @@ -1248,7 +1269,7 @@ commands that access files and parities. `Hardlink-to error for not regular file`, `Hardlink mismatch for different inode`). - symlink_error::: + symlink_error[_io]::: Indicates an error when attempting to access a symbolic link. - The name of the disk. @@ -1257,7 +1278,7 @@ commands that access files and parities. error (e.g., `Symlink read error`, `Symlink data error '' instead of ''`). - dir_error::: + dir_error[_io]::: Indicates an error when attempting to access a directory. - The name of the disk.