Reworked recover tags

This commit is contained in:
Andrea Mazzoleni 2026-01-25 14:06:56 +01:00
parent e743e23555
commit 2cbc172fd3
4 changed files with 95 additions and 37 deletions

View file

@ -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));

View file

@ -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:<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.
@ -1833,7 +1857,7 @@ file containing the block (escaped).
.HP 4
.I <msg>
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 <pos>, diff bits <diff>/<bits>\`).
.PD
.RE
@ -1862,12 +1886,12 @@ The configuration name of the parity level (e.g.,
.HP 4
.I <msg>
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 <diff>/<bits>\`).
.PD
.RE
.TP
.B hardlink_error:<disk_name>:<link_path>:<target_path>:<msg>
.B hardlink_error[_io]:<disk_name>:<link_path>:<target_path>:<msg>
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:<disk_name>:<link_path>:<msg>
.B symlink_error[_io]:<disk_name>:<link_path>:<msg>
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:<disk_name>:<dir_path>:<msg>
.B dir_error[_io]:<disk_name>:<dir_path>:<msg>
Indicates an error when attempting to access a directory.
.RS 4
.PD 0

View file

@ -1146,6 +1146,24 @@ 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.
@ -1165,7 +1183,7 @@ Error Tags
<file> - The path (relative to the disk mount point) of the
file containing the block (escaped).
<msg> - 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 <pos>, diff bits <diff>/<bits>`).
=parity_error[_io|_data]:<block>:<level>:<msg>
@ -1181,10 +1199,10 @@ Error Tags
<level> - The configuration name of the parity level (e.g.,
`parity`, `2-parity`).
<msg> - 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 <diff>/<bits>`).
=hardlink_error:<disk_name>:<link_path>:<target_path>:<msg>
=hardlink_error[_io]:<disk_name>:<link_path>:<target_path>:<msg>
Indicates an error when attempting to access a hard link.
<disk_name> - 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:<disk_name>:<link_path>:<msg>
=symlink_error[_io]:<disk_name>:<link_path>:<msg>
Indicates an error when attempting to access a symbolic link.
<disk_name> - The name of the disk.
@ -1205,7 +1223,7 @@ Error Tags
error (e.g., `Symlink read error`,
`Symlink data error '<actual>' instead of '<expected>'`).
=dir_error:<disk_name>:<dir_path>:<msg>
=dir_error[_io]:<disk_name>:<dir_path>:<msg>
Indicates an error when attempting to access a directory.
<disk_name> - The name of the disk.

View file

@ -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:<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
=============
These tags report specific errors that occur on data disks during the
@ -1217,7 +1238,7 @@ commands that access files and parities.
<file> - The path (relative to the disk mount point) of the
file containing the block (escaped).
<msg> - 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 <pos>, diff bits <diff>/<bits>`).
parity_error[_io|_data]:<block>:<level>:<msg>
@ -1233,10 +1254,10 @@ commands that access files and parities.
<level> - The configuration name of the parity level (e.g.,
`parity`, `2-parity`).
<msg> - 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 <diff>/<bits>`).
hardlink_error:<disk_name>:<link_path>:<target_path>:<msg>
hardlink_error[_io]:<disk_name>:<link_path>:<target_path>:<msg>
Indicates an error when attempting to access a hard link.
<disk_name> - 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:<disk_name>:<link_path>:<msg>
symlink_error[_io]:<disk_name>:<link_path>:<msg>
Indicates an error when attempting to access a symbolic link.
<disk_name> - The name of the disk.
@ -1257,7 +1278,7 @@ commands that access files and parities.
error (e.g., `Symlink read error`,
`Symlink data error '<actual>' instead of '<expected>'`).
dir_error:<disk_name>:<dir_path>:<msg>
dir_error[_io]:<disk_name>:<dir_path>:<msg>
Indicates an error when attempting to access a directory.
<disk_name> - The name of the disk.