Introduce a new messaging system

This commit is contained in:
Andrea Mazzoleni 2015-02-22 14:31:03 +01:00
parent fa5f31ddf9
commit e56de653da
33 changed files with 1642 additions and 1518 deletions

41
HISTORY
View file

@ -3,32 +3,35 @@ SnapRAID HISTORY
8.0 2015/02 BETA
================
* Changes the log handling. If no log file is specified, all the
log goes to stderr. If a log file is specified, only the most
serious errors are printed on the screen.
This applies to all commands.
* Allows "sync" and "scrub" to continue after the first bunch of disk
errors. Blocks with errors are marked as bad, and you can fix them
with the "fix -e" command.
The fix is expected to force the disk firmware to reallocate the
bad sector, likely fixing the problem.
You can control the number of allowed errors with the new
-L, --error-limit option. The default is 100.
* The -e, --filter-error option doesn't write anymore fixes to
unsynced files. This helps in case you are running it on a not
synced array, removing the risk to revert some files to an old state.
* The -e, --filter-error option is now optimal and read only the minimal
amount of data necessary to fix the errors.
* Adds new "smart" command to print a SMART report of the array.
* Adds new "up" and "down" commands to spin up and down the disks of
the array.
* Allows "sync" and "scrub" to continue after the first
bunch of disk errors. Blocks with errors are marked as bad,
and you can fix them with the "fix -e" command.
The fix is expected to force the disk firmware to reallocate
the bad sector, likely fixing the problem.
You can control the number of allowed errors with the new
-L, --error-limit option. The default is 100.
* The -e, --filter-error option doesn't write anymore fixes
to unsynced files. This helps in case you are running it on a
not synced array, removing the risk to revert some files to an
old state.
* The -e, --filter-error option is more efficient and triggers
a lot less data to be read.
* Changes the log handling. If no log file is specified, all the
warnings and not fatal errors messages goes to stderr. If a log file
is specified, only fatal error messages are printed on the screen.
You can control the amount of informative messages on stdout with
the -q, --quiet and -v, --verbose options, that can be specified
multiple times to be more quiet or verbose.
* In the "status" command the "Wasted" column now shows a negative
number for the amount of space that you can still waste.
number for the amount of space that you can still waste without
filling up the parity.
* Renames the -s and -t options to -S and -B as they are intended to
be manual only operations.
* Windows binary built with gcc 4.8.1 using the MXE cross compiler 2.23,
with targets i686-w64-mingw32 and x86_64-w64-mingw32.
with targets i686-w64-mingw32 and x86_64-w64-mingw32. Before the x86
target was i686-pc-mingw32.
7.1 2015/01
===========

View file

@ -150,13 +150,13 @@ maintainer-clean-local:
CHECKFLAGS_BASE = --test-skip-device --test-skip-self --test-force-order-alpha --test-force-progress
# Physical offset options
CHECKFLAGS_PHYSICAL = --test-skip-device --test-skip-self --test-force-order-physical -q
CHECKFLAGS_PHYSICAL = --test-skip-device --test-skip-self --test-force-order-physical -q -q -q
# Verbose options
CHECKFLAGS_VERBOSE = $(CHECKFLAGS_BASE) -v -G
# Quiet options
CHECKFLAGS = $(CHECKFLAGS_BASE) -q
CHECKFLAGS = $(CHECKFLAGS_BASE) -q -q -q
# Number of files to create
CHECKCOUNT = 1000

View file

@ -112,7 +112,7 @@ static int is_hash_matching(struct snapraid_state* state, int rehash, unsigned d
) {
/* if a hash doesn't match, fail the check */
if (blockcmp(state, rehash, failed[failed_map[j]].block, buffer[failed[failed_map[j]].index], buffer_zero) != 0) {
ftag("hash_error: Hash mismatch on entry %u\n", failed_map[j]);
msg_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]);
return 0;
}
@ -223,13 +223,13 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
return 0;
/* log */
ftag("parity_error:%u:", pos);
msg_tag("parity_error:%u:", pos);
for (i = 0; i < r; ++i) {
if (i != 0)
ftag("/");
ftag("%s", lev_config_name(ip[i]));
msg_tag("/");
msg_tag("%s", lev_config_name(ip[i]));
}
ftag(":parity: Parity mismatch\n");
msg_tag(":parity: Parity mismatch\n");
++error;
} while (combination_next(r, n, ip));
}
@ -263,13 +263,13 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
return 0;
/* log */
ftag("parity_error:%u:", pos);
msg_tag("parity_error:%u:", pos);
for (i = 0; i < r; ++i) {
if (i != 0)
ftag("/");
ftag("%s", lev_config_name(ip[i]));
msg_tag("/");
msg_tag("%s", lev_config_name(ip[i]));
}
ftag(":hash: Hash mismatch\n");
msg_tag(":hash: Hash mismatch\n");
++error;
} while (combination_next(r, n, ip));
}
@ -278,7 +278,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
if (error)
return error;
ftag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n",
msg_tag("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;
}
@ -338,9 +338,9 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
disk = handle->disk->name;
sub = block_file_get(block)->sub;
ftag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, state, hash, data, disk, esc(sub), block_file_pos(block));
msg_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, state, hash, data, disk, esc(sub), block_file_pos(block));
} else {
ftag("entry:%u:%s:%s:%s:\n", j, state, hash, data);
msg_tag("entry:%u:%s:%s:%s:\n", j, state, hash, data);
}
}
@ -375,7 +375,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
|| state_search_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0)
) {
/* we already have corrected it! */
ftag("hash_import: Fixed entry %u\n", j);
msg_tag("hash_import: Fixed entry %u\n", j);
} else {
/* otherwise try to recover it */
failed_map[n] = j;
@ -389,7 +389,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
/* if nothing to fix */
if (!something_to_recover) {
ftag("recover_sync:%u:%u: Skipped for already recovered\n", pos, n);
msg_tag("recover_sync:%u:%u: Skipped for already recovered\n", pos, n);
/* recompute only the parity */
raid_gen(diskmax, state->level, state->block_size, buffer);
@ -423,7 +423,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
/* it may contain garbage */
failed[j].is_outofdate = 1;
ftag("hash_unknown: Unknown hash on entry %u\n", j);
msg_tag("hash_unknown: Unknown hash on entry %u\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' */
@ -434,7 +434,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
/* it may contain garbage */
failed[j].is_outofdate = 1;
ftag("hash_unknown: Maybe old zero on entry %u\n", j);
msg_tag("hash_unknown: Maybe old zero on entry %u\n", j);
}
} else {
/* if the hash is different than the previous one, we are sure to have */
@ -446,7 +446,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
/* it may contain garbage */
failed[j].is_outofdate = 1;
ftag("hash_unknown: Maybe old data on entry %u\n", j);
msg_tag("hash_unknown: Maybe old data on entry %u\n", j);
}
}
}
@ -458,9 +458,9 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
error += ret;
if (ret < 0)
ftag("recover_sync:%u:%u: Failed with no attempts\n", pos, n);
msg_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n);
else
ftag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret);
msg_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret);
/* Now assume that the parity IS NOT updated at the current state, */
/* but still represent the state before the last 'sync' process. */
@ -556,7 +556,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;
ftag("hash_unknown: Surely old data on entry %u\n", j);
msg_tag("hash_unknown: Surely old data on entry %u\n", j);
}
}
}
@ -567,11 +567,11 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
error += ret;
if (ret < 0)
ftag("recover_unsync:%u:%u: Failed with no attempts\n", pos, n);
msg_tag("recover_unsync:%u:%u: Failed with no attempts\n", pos, n);
else
ftag("recover_unsync:%u:%u: Failed with %d attempts\n", pos, n, ret);
msg_tag("recover_unsync:%u:%u: Failed with %d attempts\n", pos, n, ret);
} else {
ftag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n,
msg_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n,
!something_to_recover ? " nothing to recover" : "",
!something_unsynced ? " nothing unsynched" : ""
);
@ -636,7 +636,7 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s
/* or at least pointing to NULL, in case it cannot be opened. */
if (handle[j].file != 0 && handle[j].file != file) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency in opened file for block %u\n", block->parity_pos);
msg_error("Internal inconsistency in opened file for block %u\n", block->parity_pos);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -658,8 +658,8 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s
ret = handle_close(&handle[j]);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error closing '%s'. %s.\n", path, strerror(errno));
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Error closing '%s'. %s.\n", path, strerror(errno));
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
return -1;
/* LCOV_EXCL_STOP */
}
@ -667,16 +667,14 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s
ret = rename(path, path_to);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error renaming '%s' to '%s'. %s.\n", path, path_to, strerror(errno));
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Error renaming '%s' to '%s'. %s.\n", path, path_to, strerror(errno));
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
return -1;
/* LCOV_EXCL_STOP */
}
ftag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub));
if (!state->opt.quiet) {
fout("unrecoverable %s\n", path);
}
msg_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub));
msg_info("unrecoverable %s\n", path);
/* and do not set the time if damaged */
goto close_and_continue;
@ -688,10 +686,8 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s
goto close_and_continue;
}
ftag("status:recovered:%s:%s\n", disk->name, esc(file->sub));
if (!state->opt.quiet) {
fout("recovered %s\n", path);
}
msg_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub));
msg_info("recovered %s\n", path);
inode = handle[j].st.st_ino;
@ -718,38 +714,32 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s
/* LCOV_EXCL_START */
/* mark the file as damaged */
file_flag_set(file, FILE_IS_DAMAGED);
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
return -1;
/* LCOV_EXCL_STOP */
}
} else {
ftag("collision:%s:%s:%s: Not setting modification time to avoid inode collision\n", disk->name, esc(file->sub), esc(collide_file->sub));
msg_tag("collision:%s:%s:%s: Not setting modification time to avoid inode collision\n", disk->name, esc(file->sub), esc(collide_file->sub));
}
} else {
/* we are not fixing, but only checking */
/* print just the final status */
if (file_flag_has(file, FILE_IS_DAMAGED)) {
if (state->opt.auditonly) {
ftag("status:damaged:%s:%s\n", disk->name, esc(file->sub));
if (!state->opt.quiet) {
fout("damaged %s\n", path);
}
msg_tag("status:damaged:%s:%s\n", disk->name, esc(file->sub));
msg_info("damaged %s\n", path);
} else {
ftag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub));
if (!state->opt.quiet) {
fout("unrecoverable %s\n", path);
}
msg_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub));
msg_info("unrecoverable %s\n", path);
}
} else if (file_flag_has(file, FILE_IS_FIXED)) {
ftag("status:recoverable:%s:%s\n", disk->name, esc(file->sub));
if (!state->opt.quiet) {
fout("recoverable %s\n", path);
}
msg_tag("status:recoverable:%s:%s\n", disk->name, esc(file->sub));
msg_info("recoverable %s\n", path);
} else {
ftag("status:correct:%s:%s\n", disk->name, esc(file->sub));
if (state->opt.verbose) {
fout("correct %s\n", path);
}
msg_tag("status:correct:%s:%s\n", disk->name, esc(file->sub));
/* we don't use msg_verbose() because it also goes into the log */
if (msg_level >= MSG_VERBOSE)
msg_info("correct %s\n", path);
}
}
@ -762,8 +752,8 @@ close_and_continue:
ret = handle_close(&handle[j]);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error closing '%s'. %s.\n", path, strerror(errno));
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Error closing '%s'. %s.\n", path, strerror(errno));
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
return -1;
/* LCOV_EXCL_STOP */
}
@ -882,7 +872,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
/* post process the files */
ret = file_post(state, fix, i, handle, diskmax);
if (ret == -1) {
ferr("Stopping at block %u\n", i);
msg_error("Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
}
@ -977,8 +967,8 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
ret = handle_close(&handle[j]);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("DANGER! Unexpected close error in a data disk, it isn't possible to check.\n");
ferr("Stopping at block %u\n", i);
msg_error("DANGER! Unexpected close error in a data disk, it isn't possible to check.\n");
msg_error("Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -991,11 +981,11 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (ret == -1) {
/* LCOV_EXCL_START */
if (errno == EACCES) {
ferr("WARNING! Please give write permission to the file.\n");
msg_error("WARNING! Please give write permission to the file.\n");
} else {
ferr("DANGER! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("DANGER! Without a working data disk, it isn't possible to fix errors on it.\n");
}
ferr("Stopping at block %u\n", i);
msg_error("Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1009,7 +999,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
}
} else {
/* otherwise, open the file only for reading */
ret = handle_open(&handle[j], file, state->file_mode, flog);
ret = handle_open(&handle[j], file, state->file_mode, msg_warning);
if (ret == -1) {
/* save the failed block for the check/fix */
failed[failed_count].is_bad = 1;
@ -1019,7 +1009,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
failed[failed_count].handle = &handle[j];
++failed_count;
ftag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc(file->sub), block_file_pos(block));
msg_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc(file->sub), block_file_pos(block));
++error;
continue;
}
@ -1046,22 +1036,22 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
&& !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))
&& handle[j].st.st_size > file->size
) {
flog("File '%s' is larger than expected.\n", handle[j].path);
ftag("error:%u:%s:%s: Size error\n", i, disk->name, esc(file->sub));
msg_warning("File '%s' is larger than expected.\n", handle[j].path);
msg_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc(file->sub));
++error;
if (fix) {
ret = handle_truncate(&handle[j], file);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("DANGER! Unexpected truncate error in a data disk, it isn't possible to fix.\n");
ferr("Stopping at block %u\n", i);
msg_error("DANGER! Unexpected truncate error in a data disk, it isn't possible to fix.\n");
msg_error("Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
}
ftag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc(file->sub));
msg_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc(file->sub));
++recovered_error;
}
}
@ -1073,7 +1063,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
}
/* read from the file */
read_size = handle_read(&handle[j], block, buffer[j], state->block_size, flog);
read_size = handle_read(&handle[j], block, buffer[j], state->block_size, msg_warning);
if (read_size == -1) {
/* save the failed block for the check/fix */
failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */
@ -1083,7 +1073,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
failed[failed_count].handle = &handle[j];
++failed_count;
ftag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(file->sub), block_file_pos(block));
msg_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(file->sub), block_file_pos(block));
++error;
continue;
}
@ -1124,7 +1114,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
failed[failed_count].handle = &handle[j];
++failed_count;
ftag("error:%u:%s:%s: Data error at position %u\n", i, disk->name, esc(file->sub), block_file_pos(block));
msg_tag("error:%u:%s:%s: Data error at position %u\n", i, disk->name, esc(file->sub), block_file_pos(block));
++error;
continue;
}
@ -1160,11 +1150,11 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
/* read the parity */
for (l = 0; l < state->level; ++l) {
if (parity[l]) {
ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, flog);
ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, msg_warning);
if (ret == -1) {
buffer_recov[l] = 0; /* no parity to use */
ftag("parity_error:%u:%s: Read error\n", i, lev_config_name(l));
msg_tag("parity_error:%u:%s: Read error\n", i, lev_config_name(l));
++error;
}
} else {
@ -1183,7 +1173,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
/* print a list of all the errors in files */
for (j = 0; j < failed_count; ++j) {
if (failed[j].is_bad)
ftag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].handle->disk->name, esc(block_file_get(failed[j].block)->sub), block_file_pos(failed[j].block));
msg_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].handle->disk->name, esc(block_file_get(failed[j].block)->sub), block_file_pos(failed[j].block));
}
/* keep track of damaged files */
@ -1201,7 +1191,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
for (j = 0; j < failed_count; ++j) {
if (failed[j].is_bad && failed[j].is_outofdate) {
++partial_recover_error;
ftag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].handle->disk->name, esc(block_file_get(failed[j].block)->sub), block_file_pos(failed[j].block));
msg_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].handle->disk->name, esc(block_file_get(failed[j].block)->sub), block_file_pos(failed[j].block));
}
}
if (partial_recover_error != 0) {
@ -1218,7 +1208,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) {
buffer_recov[l] = 0;
ftag("parity_error:%u:%s: Data error\n", i, lev_config_name(l));
msg_tag("parity_error:%u:%s: Data error\n", i, lev_config_name(l));
++error;
}
}
@ -1244,12 +1234,12 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
file_flag_set(block_file_get(failed[j].block), FILE_IS_DAMAGED);
if (errno == EACCES) {
ferr("WARNING! Please give write permission to the file.\n");
msg_error("WARNING! Please give write permission to the file.\n");
} else {
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
}
ferr("Stopping at block %u\n", i);
msg_error("Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1266,7 +1256,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
/* note that it could be also marked as damaged in other iterations */
file_flag_set(block_file_get(failed[j].block), FILE_IS_FIXED);
ftag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].handle->disk->name, esc(block_file_get(failed[j].block)->sub), block_file_pos(failed[j].block));
msg_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].handle->disk->name, esc(block_file_get(failed[j].block)->sub), block_file_pos(failed[j].block));
++recovered_error;
}
@ -1281,14 +1271,14 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (ret == -1) {
/* LCOV_EXCL_START */
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
ferr("WARNING! Without a working %s disk, it isn't possible to fix errors on it.\n", lev_name(l));
ferr("Stopping at block %u\n", i);
msg_error("WARNING! Without a working %s disk, it isn't possible to fix errors on it.\n", lev_name(l));
msg_error("Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
}
ftag("parity_fixed:%u:%s: Fixed data error\n", i, lev_config_name(l));
msg_tag("parity_fixed:%u:%s: Fixed data error\n", i, lev_config_name(l));
++recovered_error;
}
}
@ -1316,7 +1306,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
/* post process the files */
ret = file_post(state, fix, i, handle, diskmax);
if (ret == -1) {
ferr("Stopping at block %u\n", i);
msg_error("Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
}
@ -1368,18 +1358,18 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (ret == -1) {
unsuccesful = 1;
flog("Error stating empty file '%s'. %s.\n", path, strerror(errno));
ftag("error:%s:%s: Empty file stat error\n", disk->name, esc(file->sub));
msg_warning("Error stating empty file '%s'. %s.\n", path, strerror(errno));
msg_tag("error:%s:%s: Empty file stat error\n", disk->name, esc(file->sub));
++error;
} else if (!S_ISREG(st.st_mode)) {
unsuccesful = 1;
ftag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc(file->sub));
msg_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc(file->sub));
++error;
} else if (st.st_size != 0) {
unsuccesful = 1;
ftag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc(file->sub), st.st_size);
msg_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc(file->sub), st.st_size);
++error;
}
@ -1390,8 +1380,8 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
ret = mkancestor(path);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
ferr("Stopping\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1402,14 +1392,14 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
if (f == -1) {
/* LCOV_EXCL_START */
ferr("Error creating empty file '%s'. %s.\n", path, strerror(errno));
msg_error("Error creating empty file '%s'. %s.\n", path, strerror(errno));
if (errno == EACCES) {
ferr("WARNING! Please give write permission to the file.\n");
msg_error("WARNING! Please give write permission to the file.\n");
} else {
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
}
ferr("Stopping\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1421,9 +1411,9 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
/* LCOV_EXCL_START */
close(f);
ferr("Error timing file '%s'. %s.\n", file->sub, strerror(errno));
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
ferr("Stopping\n");
msg_error("Error timing file '%s'. %s.\n", file->sub, strerror(errno));
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1433,20 +1423,18 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
ret = close(f);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
ferr("Stopping\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
}
ftag("fixed:%s:%s: Fixed empty file\n", disk->name, esc(file->sub));
msg_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc(file->sub));
++recovered_error;
ftag("status:recovered:%s:%s\n", disk->name, esc(file->sub));
if (!state->opt.quiet) {
fout("recovered %s%s\n", disk->dir, file->sub);
}
msg_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub));
msg_info("recovered %s%s\n", disk->dir, file->sub);
}
}
@ -1478,13 +1466,13 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (ret == -1) {
unsuccesful = 1;
flog("Error stating hardlink '%s'. %s.\n", path, strerror(errno));
ftag("hardlinkerror:%s:%s:%s: Hardlink stat error\n", disk->name, esc(link->sub), esc(link->linkto));
msg_warning("Error stating hardlink '%s'. %s.\n", path, strerror(errno));
msg_tag("hardlinkerror:%s:%s:%s: Hardlink stat error\n", disk->name, esc(link->sub), esc(link->linkto));
++error;
} else if (!S_ISREG(st.st_mode)) {
unsuccesful = 1;
ftag("hardlinkerror:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc(link->sub), esc(link->linkto));
msg_tag("hardlinkerror:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc(link->sub), esc(link->linkto));
++error;
}
@ -1508,19 +1496,19 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
}
}
flog("Error stating hardlink-to '%s'. %s.\n", pathto, strerror(errno));
ftag("hardlinkerror:%s:%s:%s: Hardlink to stat error\n", disk->name, esc(link->sub), esc(link->linkto));
msg_warning("Error stating hardlink-to '%s'. %s.\n", pathto, strerror(errno));
msg_tag("hardlinkerror:%s:%s:%s: Hardlink to stat error\n", disk->name, esc(link->sub), esc(link->linkto));
++error;
} else if (!S_ISREG(stto.st_mode)) {
unsuccesful = 1;
ftag("hardlinkerror:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc(link->sub), esc(link->linkto));
msg_tag("hardlinkerror:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc(link->sub), esc(link->linkto));
++error;
} else if (!unsuccesful && st.st_ino != stto.st_ino) {
unsuccesful = 1;
flog("Mismatch hardlink '%s' and '%s'. Different inode.\n", path, pathto);
ftag("hardlinkerror:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc(link->sub), esc(link->linkto));
msg_warning("Mismatch hardlink '%s' and '%s'. Different inode.\n", path, pathto);
msg_tag("hardlinkerror:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc(link->sub), esc(link->linkto));
++error;
}
} else {
@ -1530,14 +1518,14 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (ret < 0) {
unsuccesful = 1;
flog("Error reading symlink '%s'. %s.\n", path, strerror(errno));
ftag("symlinkerror:%s:%s: Symlink read error\n", disk->name, esc(link->sub));
msg_warning("Error reading symlink '%s'. %s.\n", path, strerror(errno));
msg_tag("symlinkerror:%s:%s: Symlink read error\n", disk->name, esc(link->sub));
++error;
} else if (ret >= PATH_MAX) {
unsuccesful = 1;
flog("Error reading symlink '%s'. Symlink too long.\n", path);
ftag("symlinkerror:%s:%s: Symlink read error\n", disk->name, esc(link->sub));
msg_warning("Error reading symlink '%s'. Symlink too long.\n", path);
msg_tag("symlinkerror:%s:%s: Symlink read error\n", disk->name, esc(link->sub));
++error;
} else {
linkto[ret] = 0;
@ -1545,7 +1533,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (strcmp(linkto, link->linkto) != 0) {
unsuccesful = 1;
ftag("symlinkerror:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc(link->sub), linkto, link->linkto);
msg_tag("symlinkerror:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc(link->sub), linkto, link->linkto);
++error;
}
}
@ -1556,8 +1544,8 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
ret = mkancestor(path);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
ferr("Stopping\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1567,9 +1555,9 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
ret = remove(path);
if (ret != 0 && errno != ENOENT) {
/* LCOV_EXCL_START */
ferr("Error removing '%s'. %s.\n", path, strerror(errno));
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
ferr("Stopping\n");
msg_error("Error removing '%s'. %s.\n", path, strerror(errno));
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1580,46 +1568,44 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
ret = hardlink(pathto, path);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error writing hardlink '%s' to '%s'. %s.\n", path, pathto, strerror(errno));
msg_error("Error writing hardlink '%s' to '%s'. %s.\n", path, pathto, strerror(errno));
if (errno == EACCES) {
ferr("WARNING! Please give write permission to the hardlink.\n");
msg_error("WARNING! Please give write permission to the hardlink.\n");
} else {
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
}
ferr("Stopping\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
}
ftag("hardlinkfixed:%s:%s: Fixed hardlink error\n", disk->name, esc(link->sub));
msg_tag("hardlinkfixed:%s:%s: Fixed hardlink error\n", disk->name, esc(link->sub));
++recovered_error;
} else {
ret = symlink(link->linkto, path);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error writing symlink '%s' to '%s'. %s.\n", path, link->linkto, strerror(errno));
msg_error("Error writing symlink '%s' to '%s'. %s.\n", path, link->linkto, strerror(errno));
if (errno == EACCES) {
ferr("WARNING! Please give write permission to the symlink.\n");
msg_error("WARNING! Please give write permission to the symlink.\n");
} else {
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
}
ferr("Stopping\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
}
ftag("symlinkfixed:%s:%s: Fixed symlink error\n", disk->name, esc(link->sub));
msg_tag("symlinkfixed:%s:%s: Fixed symlink error\n", disk->name, esc(link->sub));
++recovered_error;
}
ftag("status:recovered:%s:%s\n", disk->name, esc(link->sub));
if (!state->opt.quiet) {
fout("recovered %s%s\n", disk->dir, link->sub);
}
msg_tag("status:recovered:%s:%s\n", disk->name, esc(link->sub));
msg_info("recovered %s%s\n", disk->dir, link->sub);
}
}
@ -1646,13 +1632,13 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
if (ret == -1) {
unsuccesful = 1;
flog("Error stating dir '%s'. %s.\n", path, strerror(errno));
ftag("dir_error:%s:%s: Dir stat error\n", disk->name, esc(dir->sub));
msg_warning("Error stating dir '%s'. %s.\n", path, strerror(errno));
msg_tag("dir_error:%s:%s: Dir stat error\n", disk->name, esc(dir->sub));
++error;
} else if (!S_ISDIR(st.st_mode)) {
unsuccesful = 1;
ftag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc(dir->sub));
msg_tag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc(dir->sub));
++error;
}
@ -1661,8 +1647,8 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
ret = mkancestor(path);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
ferr("Stopping\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1672,26 +1658,24 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error creating dir '%s'. %s.\n", path, strerror(errno));
msg_error("Error creating dir '%s'. %s.\n", path, strerror(errno));
if (errno == EACCES) {
ferr("WARNING! Please give write permission to the dir.\n");
msg_error("WARNING! Please give write permission to the dir.\n");
} else {
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
}
ferr("Stopping\n");
msg_error("Stopping\n");
++unrecoverable_error;
goto bail;
/* LCOV_EXCL_STOP */
}
ftag("dir_fixed:%s:%s: Fixed dir error\n", disk->name, esc(dir->sub));
msg_tag("dir_fixed:%s:%s: Fixed dir error\n", disk->name, esc(dir->sub));
++recovered_error;
ftag("status:recovered:%s:%s\n", disk->name, esc(dir->sub));
if (!state->opt.quiet) {
fout("recovered %s%s\n", disk->dir, dir->sub);
}
msg_tag("status:recovered:%s:%s\n", disk->name, esc(dir->sub));
msg_info("recovered %s%s\n", disk->dir, dir->sub);
}
}
}
@ -1704,7 +1688,7 @@ bail:
ret = handle_close(&handle[j]);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("DANGER! Unexpected close error in a data disk.\n");
msg_error("DANGER! Unexpected close error in a data disk.\n");
++unrecoverable_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
@ -1752,8 +1736,8 @@ bail:
ret = remove(path);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error removing '%s'. %s.\n", path, strerror(errno));
ferr("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
msg_error("Error removing '%s'. %s.\n", path, strerror(errno));
msg_error("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
++unrecoverable_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
@ -1763,53 +1747,55 @@ bail:
}
if (error || recovered_error || unrecoverable_error) {
fout("\n");
fout("%8u read/data errors\n", error);
msg_status("\n");
msg_status("%8u errors\n", error);
if (fix) {
fout("%8u recovered errors\n", recovered_error);
msg_status("%8u recovered errors\n", recovered_error);
}
if (unrecoverable_error) {
fout("%8u UNRECOVERABLE errors\n", unrecoverable_error);
fout("DANGER! There are unrecoverable errors!\n");
msg_status("%8u UNRECOVERABLE errors\n", unrecoverable_error);
} else {
/* without checking, we don't know if they are really recoverable or not */
if (!state->opt.auditonly)
fout("%8u unrecoverable errors\n", unrecoverable_error);
msg_status("%8u unrecoverable errors\n", unrecoverable_error);
if (fix)
fout("Everything OK\n");
else
fout("WARNING! There are errors!\n");
msg_status("Everything OK\n");
}
} else {
fout("Everything OK\n");
msg_status("Everything OK\n");
}
ftag("summary:error:%u\n", error);
if (error && !fix)
msg_error("WARNING! There are errors!\n");
if (unrecoverable_error)
msg_error("DANGER! There are unrecoverable errors!\n");
msg_tag("summary:error:%u\n", error);
if (fix)
ftag("summary:error_recovered:%u\n", recovered_error);
msg_tag("summary:error_recovered:%u\n", recovered_error);
if (!state->opt.auditonly)
ftag("summary:error_unrecoverable:%u\n", unrecoverable_error);
msg_tag("summary:error_unrecoverable:%u\n", unrecoverable_error);
if (fix) {
if (error + recovered_error + unrecoverable_error == 0)
ftag("summary:exit:ok\n");
msg_tag("summary:exit:ok\n");
else if (unrecoverable_error == 0)
ftag("summary:exit:recovered\n");
msg_tag("summary:exit:recovered\n");
else
ftag("summary:exit:unrecoverable\n");
msg_tag("summary:exit:unrecoverable\n");
} else if (!state->opt.auditonly) {
if (error + unrecoverable_error == 0)
ftag("summary:exit:ok\n");
msg_tag("summary:exit:ok\n");
else if (unrecoverable_error == 0)
ftag("summary:exit:recoverable\n");
msg_tag("summary:exit:recoverable\n");
else
ftag("summary:exit:unrecoverable\n");
msg_tag("summary:exit:unrecoverable\n");
} else { /* audit only */
if (error == 0)
ftag("summary:exit:ok\n");
msg_tag("summary:exit:ok\n");
else
ftag("summary:exit:error\n");
msg_tag("summary:exit:error\n");
}
fflush_log();
msg_flush();
free(failed);
free(failed_map);
@ -1853,14 +1839,14 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
unsigned error;
unsigned l;
fout("Initializing...\n");
msg_progress("Initializing...\n");
blockmax = parity_allocated_size(state);
size = blockmax * (data_off_t)state->block_size;
if (blockstart > blockmax) {
/* LCOV_EXCL_START */
ferr("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
msg_error("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1878,7 +1864,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
ret = parity_create(parity_ptr[l], state->parity[l].path, &out_size, state->file_mode);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("WARNING! Without an accessible %s file, it isn't possible to fix any error.\n", lev_name(l));
msg_error("WARNING! Without an accessible %s file, it isn't possible to fix any error.\n", lev_name(l));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1886,7 +1872,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
ret = parity_chsize(parity_ptr[l], size, &out_size, state->opt.skip_fallocate);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
msg_error("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1898,7 +1884,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
parity_ptr[l] = &parity[l];
ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode);
if (ret == -1) {
fout("No accessible %s file, only files will be checked.\n", lev_name(l));
msg_status("No accessible %s file, only files will be checked.\n", lev_name(l));
/* continue anyway */
parity_ptr[l] = 0;
}
@ -1910,11 +1896,11 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
}
if (fix)
fout("Fixing...\n");
msg_progress("Fixing...\n");
else if (!state->opt.auditonly)
fout("Checking...\n");
msg_progress("Checking...\n");
else
fout("Hashing...\n");
msg_progress("Hashing...\n");
error = 0;
@ -1935,7 +1921,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
ret = parity_close(parity_ptr[l]);
/* LCOV_EXCL_START */
if (ret == -1) {
ferr("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
msg_error("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
++error;
/* continue, as we are already exiting */
}

View file

@ -710,7 +710,7 @@ static void printp(double v, size_t pad)
printl(buf, pad);
}
static void state_smart(int verbose, unsigned n, tommy_list* low)
static void state_smart(unsigned n, tommy_list* low)
{
tommy_node* i;
unsigned j;
@ -846,17 +846,17 @@ static void state_smart(int verbose, unsigned n, tommy_list* low)
printf("\n");
ftag("smart:%s:%s:%s:%g\n", devinfo->file, devinfo->name, esc(devinfo->smart_serial), afr);
msg_tag("smart:%s:%s:%s:%g\n", devinfo->file, devinfo->name, esc(devinfo->smart_serial), afr);
for (j = 0; j < 256; ++j) {
if (devinfo->smart[j] != SMART_UNASSIGNED)
ftag("attr:%s:%u:%" PRIu64 "\n", devinfo->file, j, devinfo->smart[j]);
msg_tag("attr:%s:%u:%" PRIu64 "\n", devinfo->file, j, devinfo->smart[j]);
}
if (devinfo->smart[SMART_SIZE] != SMART_UNASSIGNED)
ftag("attr:%s:size:%" PRIu64 "\n", devinfo->file, devinfo->smart[SMART_SIZE]);
msg_tag("attr:%s:size:%" PRIu64 "\n", devinfo->file, devinfo->smart[SMART_SIZE]);
if (devinfo->smart[SMART_ERROR] != SMART_UNASSIGNED)
ftag("attr:%s:error:%" PRIu64 "\n", devinfo->file, devinfo->smart[SMART_ERROR]);
msg_tag("attr:%s:error:%" PRIu64 "\n", devinfo->file, devinfo->smart[SMART_ERROR]);
if (devinfo->smart[SMART_ROTATION_RATE] != SMART_UNASSIGNED)
ftag("attr:%s:rotationrate:%" PRIu64 "\n", devinfo->file, devinfo->smart[SMART_ROTATION_RATE]);
msg_tag("attr:%s:rotationrate:%" PRIu64 "\n", devinfo->file, devinfo->smart[SMART_ROTATION_RATE]);
}
printf("\n");
@ -873,10 +873,10 @@ static void state_smart(int verbose, unsigned n, tommy_list* low)
p_at_least_one_failure = poisson_prob_n_or_more_failures(array_failure_rate, 1);
printf("Probability that one disk is going to fail in the next year is %.0f%%,\n", p_at_least_one_failure * 100);
ftag("summary:array_failure:%g:%g\n", array_failure_rate, p_at_least_one_failure);
msg_tag("summary:array_failure:%g:%g\n", array_failure_rate, p_at_least_one_failure);
/* prints extra stats only in verbose mode */
if (!verbose)
if (msg_level < MSG_VERBOSE)
return;
/* |<##################################################################72>|####80>| */
@ -923,8 +923,8 @@ void state_device(struct snapraid_state* state, int operation)
tommy_list low;
switch (operation) {
case DEVICE_UP : printf("Spinup...\n"); break;
case DEVICE_DOWN : printf("Spindown...\n"); break;
case DEVICE_UP : msg_progress("Spinup...\n"); break;
case DEVICE_DOWN : msg_progress("Spindown...\n"); break;
}
tommy_list_init(&high);
@ -966,7 +966,7 @@ void state_device(struct snapraid_state* state, int operation)
case DEVICE_LIST : ope = "List"; break;
case DEVICE_SMART : ope = "SMART"; break;
}
ferr("%s unsupported in this platform.\n", ope);
msg_error("%s unsupported in this platform.\n", ope);
} else {
if (operation == DEVICE_LIST) {
for (i = tommy_list_head(&low); i != 0; i = i->next) {
@ -981,7 +981,7 @@ void state_device(struct snapraid_state* state, int operation)
}
if (operation == DEVICE_SMART)
state_smart(state->opt.verbose, state->level + tommy_list_count(&state->disklist), &low);
state_smart(state->level + tommy_list_count(&state->disklist), &low);
}
tommy_list_foreach(&high, free);

View file

@ -82,20 +82,20 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
ret = handle_close(&handle[j]);
if (ret == -1) {
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected close error in a data disk, it isn't possible to dry.\n");
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected close error in a data disk, it isn't possible to dry.\n");
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
}
/* open the file only for reading */
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, ferr);
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, msg_error);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("DANGER! Unexpected open error in a data disk, it isn't possible to dry.\n");
ferr("Stopping at block %u\n", i);
msg_error("DANGER! Unexpected open error in a data disk, it isn't possible to dry.\n");
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -103,9 +103,9 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
}
/* read from the file */
read_size = handle_read(&handle[j], block, buffer_aligned, state->block_size, flog);
read_size = handle_read(&handle[j], block, buffer_aligned, state->block_size, msg_warning);
if (read_size == -1) {
ftag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(block_file_get(block)->sub), block_file_pos(block));
msg_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(block_file_get(block)->sub), block_file_pos(block));
++error;
continue;
}
@ -122,9 +122,9 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
/* until now is CPU */
state_usage_cpu(state);
ret = parity_read(parity[l], i, buffer_aligned, state->block_size, flog);
ret = parity_read(parity[l], i, buffer_aligned, state->block_size, msg_warning);
if (ret == -1) {
ftag("parity_error:%u:%s: Read error\n", i, lev_config_name(l));
msg_tag("parity_error:%u:%s: Read error\n", i, lev_config_name(l));
++error;
}
@ -156,8 +156,8 @@ bail:
ret = handle_close(&handle[j]);
if (ret == -1) {
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected close error in a data disk.\n");
msg_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected close error in a data disk.\n");
++error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
@ -165,11 +165,15 @@ bail:
}
if (error) {
fout("%u read errors\n", error);
msg_status("\n");
msg_status("%8u errors\n", error);
} else {
fout("Everything OK\n");
msg_status("Everything OK\n");
}
if (error)
msg_error("DANGER! Unexpected errors!\n");
free(handle);
free(buffer_alloc);
@ -189,13 +193,13 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
unsigned error;
unsigned l;
fout("Drying...\n");
msg_progress("Drying...\n");
blockmax = parity_allocated_size(state);
if (blockstart > blockmax) {
/* LCOV_EXCL_START */
ferr("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
msg_error("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -211,7 +215,7 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
parity_ptr[l] = &parity[l];
ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode);
if (ret == -1) {
fout("No accessible %s file.\n", lev_name(l));
msg_status("No accessible %s file.\n", lev_name(l));
/* continue anyway */
parity_ptr[l] = 0;
}

View file

@ -96,7 +96,7 @@ void state_dup(struct snapraid_state* state)
count = 0;
size = 0;
fout("Comparing...\n");
msg_progress("Comparing...\n");
/* for each disk */
for (i = state->disklist; i != 0; i = i->next) {
@ -125,8 +125,8 @@ void state_dup(struct snapraid_state* state)
if (dup) {
++count;
size += dup->file->size;
ftag("dup:%s:%s:%s:%s:%" PRIu64 ": dup\n", disk->name, esc(file->sub), dup->disk->name, esc(dup->file->sub), dup->file->size);
fout("%12" PRIu64 " %s%s = %s%s\n", file->size, disk->dir, file->sub, dup->disk->dir, dup->file->sub);
msg_tag("dup:%s:%s:%s:%s:%" PRIu64 ": dup\n", disk->name, esc(file->sub), dup->disk->name, esc(dup->file->sub), dup->file->size);
printf("%12" PRIu64 " %s%s = %s%s\n", file->size, disk->dir, file->sub, dup->disk->dir, dup->file->sub);
hash_free(hash);
} else {
tommy_hashdyn_insert(&hashset, &hash->node, hash, hash32);
@ -137,20 +137,20 @@ void state_dup(struct snapraid_state* state)
tommy_hashdyn_foreach(&hashset, (tommy_foreach_func*)hash_free);
tommy_hashdyn_done(&hashset);
fout("\n");
fout("%8u duplicates, for %" PRIu64 " MiB\n", count, size / (1024 * 1024));
msg_status("\n");
msg_status("%8u duplicates, for %" PRIu64 " MiB\n", count, size / (1024 * 1024));
if (count)
fout("There are duplicates!\n");
msg_status("There are duplicates!\n");
else
fout("No duplicates\n");
msg_status("No duplicates\n");
ftag("summary:dup_count:%u\n", count);
ftag("summary:dup_size:%" PRIu64 "\n", size);
msg_tag("summary:dup_count:%u\n", count);
msg_tag("summary:dup_size:%" PRIu64 "\n", size);
if (count == 0) {
ftag("summary:exit:unique\n");
msg_tag("summary:exit:unique\n");
} else {
ftag("summary:exit:dup\n");
msg_tag("summary:exit:dup\n");
}
fflush_log();
msg_flush();
}

View file

@ -277,7 +277,7 @@ int filter_existence(int filter_missing, const char* dir, const char* sub)
if (errno == ENOENT)
return 0;
/* LCOV_EXCL_START */
ferr("Error in stat file '%s'. %s.\n", path, strerror(errno));
msg_error("Error in stat file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -342,7 +342,7 @@ block_off_t block_file_pos(struct snapraid_block* block)
if (block < file->blockvec || block >= file->blockvec + file->blockmax) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency in block %u ownership\n", block->parity_pos);
msg_error("Internal inconsistency in block %u ownership\n", block->parity_pos);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -456,21 +456,21 @@ void file_copy(struct snapraid_file* src_file, struct snapraid_file* dst_file)
if (src_file->size != dst_file->size) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency in copy file with different size\n");
msg_error("Internal inconsistency in copy file with different size\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (src_file->mtime_sec != dst_file->mtime_sec) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency in copy file with different mtime_sec\n");
msg_error("Internal inconsistency in copy file with different mtime_sec\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (src_file->mtime_nsec != dst_file->mtime_nsec) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency in copy file with different mtime_nsec\n");
msg_error("Internal inconsistency in copy file with different mtime_nsec\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -747,7 +747,7 @@ int disk_is_empty(struct snapraid_disk* disk, block_off_t blockmax)
return 0;
default :
/* LCOV_EXCL_START */
ferr("Internal inconsistency for used block in disk '%s' without files\n", disk->name);
msg_error("Internal inconsistency for used block in disk '%s' without files\n", disk->name);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}

View file

@ -496,7 +496,7 @@ static inline void block_file_set(struct snapraid_block* block, struct snapraid_
/* ensure that the pointer doesn't use the flag space */
if ((ptr & (uintptr_t)BLOCK_STATE_MASK) != 0) {
/* LCOV_EXCL_START */
ferr("Internal error for pointer not aligned\n");
msg_error("Internal error for pointer not aligned\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -523,7 +523,7 @@ static inline void block_state_set(struct snapraid_block* block, unsigned state)
/* ensure that the state can be stored inside the file pointer */
if ((state & BLOCK_STATE_MASK) != state) {
/* LCOV_EXCL_START */
ferr("Internal error when setting the block state %u\n", state);
msg_error("Internal error when setting the block state %u\n", state);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}

View file

@ -90,7 +90,7 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
handle->f = -1;
handle->valid_size = 0;
ferr("Error opening file '%s'. %s.\n", handle->path, strerror(errno));
msg_error("Error opening file '%s'. %s.\n", handle->path, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -102,7 +102,7 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
ret = fstat(handle->f, &handle->st);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
msg_error("Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -116,7 +116,7 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error advising file '%s'. %s.\n", handle->path, strerror(ret));
msg_error("Error advising file '%s'. %s.\n", handle->path, strerror(ret));
return -1;
/* LCOV_EXCL_STOP */
}
@ -134,9 +134,9 @@ int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
if (ret != 0) {
/* LCOV_EXCL_START */
if (errno == EACCES) {
ferr("Failed to truncate file '%s' for missing write permission.\n", handle->path);
msg_error("Failed to truncate file '%s' for missing write permission.\n", handle->path);
} else {
ferr("Error truncating file '%s'. %s.\n", handle->path, strerror(errno));
msg_error("Error truncating file '%s'. %s.\n", handle->path, strerror(errno));
}
return -1;
/* LCOV_EXCL_STOP */
@ -223,7 +223,7 @@ int handle_close(struct snapraid_handle* handle)
ret = close(handle->f);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file '%s'. %s.\n", handle->file->sub, strerror(errno));
msg_error("Error closing file '%s'. %s.\n", handle->file->sub, strerror(errno));
/* invalidate for error */
handle->file = 0;
@ -325,7 +325,7 @@ int handle_write(struct snapraid_handle* handle, struct snapraid_block* block, u
#else
if (lseek(handle->f, offset, SEEK_SET) != offset) {
/* LCOV_EXCL_START */
ferr("Error seeking file '%s'. %s.\n", handle->path, strerror(errno));
msg_error("Error seeking file '%s'. %s.\n", handle->path, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -334,7 +334,7 @@ int handle_write(struct snapraid_handle* handle, struct snapraid_block* block, u
#endif
if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */
/* LCOV_EXCL_START */
ferr("Error writing file '%s'. %s.\n", handle->path, strerror(errno));
msg_error("Error writing file '%s'. %s.\n", handle->path, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -362,7 +362,7 @@ int handle_utime(struct snapraid_handle* handle)
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno));
msg_error("Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -410,7 +410,7 @@ struct snapraid_handle* handle_map(struct snapraid_state* state, unsigned* handl
}
if (k == 0) {
/* LCOV_EXCL_START */
ferr("Internal error for inconsistent disk mapping.\n");
msg_error("Internal error for inconsistent disk mapping.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}

View file

@ -78,7 +78,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
f = open(path, flags);
if (f == -1) {
/* LCOV_EXCL_START */
ferr("Error opening file '%s'. %s.\n", path, strerror(errno));
msg_error("Error opening file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -89,7 +89,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error advising file '%s'. %s.\n", path, strerror(ret));
msg_error("Error advising file '%s'. %s.\n", path, strerror(ret));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -106,7 +106,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
ret = read(f, buffer, read_size);
if (ret < 0 || (unsigned)ret != read_size) {
/* LCOV_EXCL_START */
ferr("Error reading file '%s'. %s.\n", path, strerror(errno));
msg_error("Error reading file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -132,7 +132,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
ret = close(f);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file '%s'. %s.\n", path, strerror(errno));
msg_error("Error closing file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -174,14 +174,14 @@ int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid
f = open(path, O_RDONLY | O_BINARY);
if (f == -1) {
/* LCOV_EXCL_START */
ferr("Error opening file '%s'. %s.\n", path, strerror(errno));
msg_error("Error opening file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (lseek(f, block->offset, SEEK_SET) != block->offset) {
/* LCOV_EXCL_START */
ferr("Error seeking file '%s'. %s.\n", path, strerror(errno));
msg_error("Error seeking file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -189,7 +189,7 @@ int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid
ret = read(f, buffer, read_size);
if (ret < 0 || (unsigned)ret != read_size) {
/* LCOV_EXCL_START */
ferr("Error reading file '%s'. %s.\n", path, strerror(errno));
msg_error("Error reading file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -197,7 +197,7 @@ int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid
ret = close(f);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file '%s'. %s.\n", path, strerror(errno));
msg_error("Error closing file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -215,8 +215,8 @@ int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid
if (memcmp(buffer_hash, hash, HASH_SIZE) != 0) {
/* LCOV_EXCL_START */
ferr("Error in data reading file '%s'.\n", path);
ferr("Please don't change imported files while running.\n");
msg_error("Error in data reading file '%s'.\n", path);
msg_error("Please don't change imported files while running.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -231,7 +231,7 @@ static void import_dir(struct snapraid_state* state, const char* dir)
d = opendir(dir);
if (!d) {
/* LCOV_EXCL_START */
ferr("Error opening directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error opening directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -247,7 +247,7 @@ static void import_dir(struct snapraid_state* state, const char* dir)
dd = readdir(d);
if (dd == 0 && errno != 0) {
/* LCOV_EXCL_START */
ferr("Error reading directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error reading directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -274,7 +274,7 @@ static void import_dir(struct snapraid_state* state, const char* dir)
if (st.st_mode == 0) {
if (lstat(path_next, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -283,7 +283,7 @@ static void import_dir(struct snapraid_state* state, const char* dir)
/* get lstat info about the file */
if (lstat(path_next, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -299,7 +299,7 @@ static void import_dir(struct snapraid_state* state, const char* dir)
if (closedir(d) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error closing directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -309,7 +309,7 @@ void state_import(struct snapraid_state* state, const char* dir)
{
char path[PATH_MAX];
fout("Importing...\n");
msg_progress("Importing...\n");
/* add the final slash */
pathimport(path, sizeof(path), dir);

View file

@ -37,7 +37,7 @@ void state_list(struct snapraid_state* state)
file_size = 0;
link_count = 0;
fout("Listing...\n");
msg_progress("Listing...\n");
/* for each disk */
for (i = state->disklist; i != 0; i = i->next) {
@ -59,7 +59,7 @@ void state_list(struct snapraid_state* state)
++file_count;
file_size += file->size;
ftag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc(file->sub), file->size, file->mtime_sec, file->mtime_nsec, file->inode);
msg_tag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc(file->sub), file->size, file->mtime_sec, file->mtime_nsec, file->inode);
t = file->mtime_sec;
#if HAVE_LOCALTIME_R
@ -71,9 +71,8 @@ void state_list(struct snapraid_state* state)
printf("%12" PRIu64 " ", file->size);
if (tm) {
printf("%04u/%02u/%02u %02u:%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
if (state->opt.verbose) {
if (msg_level >= MSG_VERBOSE)
printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000);
}
printf(" ");
}
printf("%s%s\n", disk->dir, file->sub);
@ -99,24 +98,24 @@ void state_list(struct snapraid_state* state)
++link_count;
ftag("link_%s:%s:%s:%s\n", type, disk->name, esc(link->sub), esc(link->linkto));
msg_tag("link_%s:%s:%s:%s\n", type, disk->name, esc(link->sub), esc(link->linkto));
printf("%12s ", type);
printf(" ");
if (state->opt.verbose) {
if (msg_level >= MSG_VERBOSE)
printf(" ");
}
printf("%s%s -> %s%s\n", disk->dir, link->sub, disk->dir, link->linkto);
}
}
fout("\n");
fout("%8u files, for %" PRIu64 " GiB\n", file_count, file_size / (1024 * 1024 * 1024));
fout("%8u links\n", link_count);
ftag("summary:file_count:%u\n", file_count);
ftag("summary:file_size:%" PRIu64 "\n", file_size);
ftag("summary:link_count:%u\n", link_count);
ftag("summary:exit:ok\n");
fflush_log();
msg_status("\n");
msg_status("%8u files, for %" PRIu64 " GiB\n", file_count, file_size / (1024 * 1024 * 1024));
msg_status("%8u links\n", link_count);
msg_tag("summary:file_count:%u\n", file_count);
msg_tag("summary:file_size:%" PRIu64 "\n", file_size);
msg_tag("summary:link_count:%u\n", link_count);
msg_tag("summary:exit:ok\n");
msg_flush();
}

View file

@ -185,19 +185,19 @@ void os_init(int opt)
ntdll = GetModuleHandle("NTDLL.DLL");
if (!ntdll) {
ferr("Error loading the NTDLL module.\n");
msg_error("Error loading the NTDLL module.\n");
exit(EXIT_FAILURE);
}
kernel32 = GetModuleHandle("KERNEL32.DLL");
if (!kernel32) {
ferr("Error loading the KERNEL32 module.\n");
msg_error("Error loading the KERNEL32 module.\n");
exit(EXIT_FAILURE);
}
dll_advapi32 = LoadLibrary("ADVAPI32.DLL");
if (!dll_advapi32) {
ferr("Error loading the ADVAPI32 module.\n");
msg_error("Error loading the ADVAPI32 module.\n");
exit(EXIT_FAILURE);
}
@ -210,7 +210,7 @@ void os_init(int opt)
ptr_RtlGenRandom = (void*)GetProcAddress(dll_advapi32, "SystemFunction036");
if (!ptr_RtlGenRandom) {
ferr("Error loading RtlGenRandom() from the ADVAPI32 module.\n");
msg_error("Error loading RtlGenRandom() from the ADVAPI32 module.\n");
exit(EXIT_FAILURE);
}
@ -280,7 +280,7 @@ static wchar_t* u8tou16(const char* src)
ret = MultiByteToWideChar(CP_UTF8, 0, src, -1, conv_utf16_buffer[roll], sizeof(conv_utf16_buffer[0]) / sizeof(wchar_t));
if (ret <= 0) {
ferr("Error converting name '%s' from UTF-8 to UTF-16\n", src);
msg_error("Error converting name '%s' from UTF-8 to UTF-16\n", src);
exit(EXIT_FAILURE);
}
@ -303,7 +303,7 @@ static char* u16tou8ex(const wchar_t* src, size_t number_of_wchar, size_t* resul
ret = WideCharToMultiByte(CP_UTF8, 0, src, number_of_wchar, conv_utf8_buffer[roll], sizeof(conv_utf8_buffer[0]), 0, 0);
if (ret <= 0) {
ferr("Error converting from UTF-16 to UTF-8\n");
msg_error("Error converting from UTF-16 to UTF-8\n");
exit(EXIT_FAILURE);
}
@ -398,7 +398,7 @@ static wchar_t* convert_arg(const char* src, int only_if_required)
ret = MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, sizeof(conv_utf16_buffer[0]) / sizeof(wchar_t) - count);
if (ret <= 0) {
ferr("Error converting name '%s' from UTF-8 to UTF-16\n", src);
msg_error("Error converting name '%s' from UTF-8 to UTF-16\n", src);
exit(EXIT_FAILURE);
}
@ -632,7 +632,7 @@ static void windows_finddata2dirent(const WIN32_FIND_DATAW* info, struct windows
name = u16tou8ex(info->cFileName, wcslen(info->cFileName), &len);
if (len + 1 >= sizeof(dirent->d_name)) {
ferr("Name too long\n");
msg_error("Name too long\n");
exit(EXIT_FAILURE);
}
@ -650,7 +650,7 @@ static void windows_stream2dirent(const BY_HANDLE_FILE_INFORMATION* info, const
name = u16tou8ex(stream->FileName, stream->FileNameLength / 2, &len);
if (len + 1 >= sizeof(dirent->d_name)) {
ferr("Name too long\n");
msg_error("Name too long\n");
exit(EXIT_FAILURE);
}
@ -701,7 +701,7 @@ static void windows_errno(DWORD error)
errno = EPERM;
break;
default :
ferr("Unexpected Windows error %d.\n", (int)error);
msg_error("Unexpected Windows error %d.\n", (int)error);
errno = EIO;
break;
}
@ -1005,8 +1005,8 @@ int windows_fsync(int fd)
* this error, but not enough sure to ignore it.
* So, we use now an extended error reporting.
*/
ferr("Unexpected Windows INVALID_HANDLE error in FlushFileBuffers().\n");
ferr("Are you using ATA-over-Ethernet ? Please report it.\n");
msg_error("Unexpected Windows INVALID_HANDLE error in FlushFileBuffers().\n");
msg_error("Are you using ATA-over-Ethernet ? Please report it.\n");
/* normal error processing */
windows_errno(error);
@ -1137,7 +1137,7 @@ static windows_dir* windows_opendir_find(const char* dir)
dirstream = malloc(sizeof(windows_dir));
if (!dirstream) {
ferr("Low memory\n");
msg_error("Low memory\n");
exit(EXIT_FAILURE);
}
@ -1274,7 +1274,7 @@ static windows_dir* windows_opendir_stream(const char* dir)
dirstream = malloc(sizeof(windows_dir));
if (!dirstream) {
ferr("Low memory\n");
msg_error("Low memory\n");
exit(EXIT_FAILURE);
}
@ -1284,7 +1284,7 @@ static windows_dir* windows_opendir_stream(const char* dir)
dirstream->buffer_size = 64 * 1024;
dirstream->buffer = malloc(dirstream->buffer_size);
if (!dirstream->buffer) {
ferr("Low memory\n");
msg_error("Low memory\n");
exit(EXIT_FAILURE);
}
@ -1761,7 +1761,7 @@ retry:
* https://sourceforge.net/p/snapraid/discussion/1677233/thread/a7c25ba9/
*/
if (err == ERROR_NO_SYSTEM_RESOURCES) {
ferr("Unexpected Windows ERROR_NO_SYSTEM_RESOURCES in pread(), retrying...\n");
msg_error("Unexpected Windows ERROR_NO_SYSTEM_RESOURCES in pread(), retrying...\n");
Sleep(50);
goto retry;
}
@ -1801,7 +1801,7 @@ retry:
DWORD err = GetLastError();
/* See windows_pread() for comments on this error management */
if (err == ERROR_NO_SYSTEM_RESOURCES) {
ferr("Unexpected Windows ERROR_NO_SYSTEM_RESOURCES in pwrite(), retrying...\n");
msg_error("Unexpected Windows ERROR_NO_SYSTEM_RESOURCES in pwrite(), retrying...\n");
Sleep(50);
goto retry;
}
@ -2046,7 +2046,7 @@ static int devscan(tommy_list* list)
f = _wpopen(cmd, L"rt");
if (!f) {
/* LCOV_EXCL_START */
ferr("Failed to run '%s' (from popen).\n", u16tou8(cmd));
msg_error("Failed to run '%s' (from popen).\n", u16tou8(cmd));
return -1;
/* LCOV_EXCL_STOP */
}
@ -2061,13 +2061,13 @@ static int devscan(tommy_list* list)
ret = pclose(f);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("Failed to run '%s' (from pclose).\n", u16tou8(cmd));
msg_error("Failed to run '%s' (from pclose).\n", u16tou8(cmd));
return -1;
/* LCOV_EXCL_STOP */
}
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Failed to run '%s' with return code %xh.\n", u16tou8(cmd), ret);
msg_error("Failed to run '%s' with return code %xh.\n", u16tou8(cmd), ret);
return -1;
/* LCOV_EXCL_STOP */
}
@ -2089,7 +2089,7 @@ static int devsmart(uint64_t device, uint64_t* smart, char* serial)
f = _wpopen(cmd, L"rt");
if (!f) {
/* LCOV_EXCL_START */
ferr("Failed to run '%s' (from popen).\n", u16tou8(cmd));
msg_error("Failed to run '%s' (from popen).\n", u16tou8(cmd));
return -1;
/* LCOV_EXCL_STOP */
}
@ -2104,7 +2104,7 @@ static int devsmart(uint64_t device, uint64_t* smart, char* serial)
ret = pclose(f);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("Failed to run '%s' (from pclose).\n", u16tou8(cmd));
msg_error("Failed to run '%s' (from pclose).\n", u16tou8(cmd));
return -1;
/* LCOV_EXCL_STOP */
}
@ -2128,13 +2128,13 @@ static int devdown(uint64_t device)
ret = _wsystem(cmd);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("Failed to run '%s' (from system).\n", u16tou8(cmd));
msg_error("Failed to run '%s' (from system).\n", u16tou8(cmd));
return -1;
/* LCOV_EXCL_STOP */
}
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Failed to run '%s' with return code %xh.\n", u16tou8(cmd), ret);
msg_error("Failed to run '%s' with return code %xh.\n", u16tou8(cmd), ret);
return -1;
/* LCOV_EXCL_STOP */
}
@ -2184,7 +2184,7 @@ static void* thread_spinup(void* arg)
if (lstat_sync(devinfo->mount, &st, 0) != 0) {
/* LCOV_EXCL_START */
pthread_mutex_lock(&io_lock);
ferr("Failed to stat path '%s'. %s.\n", devinfo->mount, strerror(errno));
msg_error("Failed to stat path '%s'. %s.\n", devinfo->mount, strerror(errno));
pthread_mutex_unlock(&io_lock);
return (void*)-1;
/* LCOV_EXCL_STOP */
@ -2196,7 +2196,7 @@ static void* thread_spinup(void* arg)
if (devresolve(devinfo->mount, devinfo->file, sizeof(devinfo->file), devinfo->wfile, sizeof(devinfo->wfile)) != 0) {
/* LCOV_EXCL_START */
pthread_mutex_lock(&io_lock);
ferr("Failed to resolve path '%s'.\n", devinfo->mount);
msg_error("Failed to resolve path '%s'.\n", devinfo->mount);
pthread_mutex_unlock(&io_lock);
return (void*)-1;
/* LCOV_EXCL_STOP */
@ -2209,7 +2209,7 @@ static void* thread_spinup(void* arg)
}
pthread_mutex_lock(&io_lock);
fprintf(stdout, "Spunup device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
msg_status("Spunup device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
pthread_mutex_unlock(&io_lock);
return 0;
@ -2232,7 +2232,7 @@ static void* thread_spindown(void* arg)
}
pthread_mutex_lock(&io_lock);
fprintf(stdout, "Spundown device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
msg_status("Spundown device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
pthread_mutex_unlock(&io_lock);
return 0;
@ -2265,7 +2265,7 @@ static int device_thread(tommy_list* list, void* (*func)(void* arg))
if (pthread_create(&devinfo->thread, 0, func, devinfo) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to create thread.\n");
msg_error("Failed to create thread.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -2278,7 +2278,7 @@ static int device_thread(tommy_list* list, void* (*func)(void* arg))
if (pthread_join(devinfo->thread, &retval) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to join thread.\n");
msg_error("Failed to join thread.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -2308,7 +2308,7 @@ int devquery(tommy_list* high, tommy_list* low, int operation)
if (devresolve(devinfo->mount, devinfo->file, sizeof(devinfo->file), devinfo->wfile, sizeof(devinfo->wfile)) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to resolve path '%s'.\n", devinfo->mount);
msg_error("Failed to resolve path '%s'.\n", devinfo->mount);
return -1;
/* LCOV_EXCL_STOP */
}
@ -2316,7 +2316,7 @@ int devquery(tommy_list* high, tommy_list* low, int operation)
/* expand the tree of devices */
if (devtree(devinfo->name, devinfo->wfile, devinfo, low) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to expand device '%s'.\n", devinfo->file);
msg_error("Failed to expand device '%s'.\n", devinfo->file);
return -1;
/* LCOV_EXCL_STOP */
}
@ -2344,7 +2344,7 @@ int devquery(tommy_list* high, tommy_list* low, int operation)
if (operation == DEVICE_SMART) {
if (devscan(low) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to list other devices.\n");
msg_error("Failed to list other devices.\n");
return -1;
/* LCOV_EXCL_STOP */
}

View file

@ -149,7 +149,7 @@ void cmd_generate_file(const char* path, int size)
if (remove(path) != 0) {
if (errno != ENOENT) {
/* LCOV_EXCL_START */
ferr("Error removing file %s\n", path);
msg_error("Error removing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -171,21 +171,21 @@ void cmd_generate_file(const char* path, int size)
f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
if (f < 0) {
/* LCOV_EXCL_START */
ferr("Error creating file %s\n", path);
msg_error("Error creating file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (write(f, data, size) != size) {
/* LCOV_EXCL_START */
ferr("Error writing file %s\n", path);
msg_error("Error writing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (close(f) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file %s\n", path);
msg_error("Error closing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -203,7 +203,7 @@ void cmd_generate_symlink(const char* path, const char* linkto)
if (remove(path) != 0) {
if (errno != ENOENT) {
/* LCOV_EXCL_START */
ferr("Error removing file %s\n", path);
msg_error("Error removing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -211,7 +211,7 @@ void cmd_generate_symlink(const char* path, const char* linkto)
if (symlink(linkto, path) != 0) {
/* LCOV_EXCL_START */
ferr("Error writing symlink %s\n", path);
msg_error("Error writing symlink %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -236,7 +236,7 @@ void cmd_generate(int disk, int size)
if (mkdir(path, 0777) != 0) {
if (errno != EEXIST) {
/* LCOV_EXCL_START */
ferr("Error creating directory %s\n", path);
msg_error("Error creating directory %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -294,7 +294,7 @@ void cmd_write(const char* path, int size)
if (lstat(path, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing %s\n", path);
msg_error("Error accessing %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -321,28 +321,28 @@ void cmd_write(const char* path, int size)
f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
if (f < 0) {
/* LCOV_EXCL_START */
ferr("Error creating file %s\n", path);
msg_error("Error creating file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (lseek(f, off, SEEK_SET) != off) {
/* LCOV_EXCL_START */
ferr("Error seeking file %s\n", path);
msg_error("Error seeking file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (write(f, data, size) != size) {
/* LCOV_EXCL_START */
ferr("Error writing file %s\n", path);
msg_error("Error writing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (close(f) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file %s\n", path);
msg_error("Error closing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -370,7 +370,7 @@ void cmd_damage(const char* path, int size)
if (lstat(path, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing %s\n", path);
msg_error("Error accessing %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -398,21 +398,21 @@ void cmd_damage(const char* path, int size)
f = open(path, O_RDWR | O_BINARY | O_NOFOLLOW);
if (f < 0) {
/* LCOV_EXCL_START */
ferr("Error creating file %s\n", path);
msg_error("Error creating file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (lseek(f, off, SEEK_SET) != off) {
/* LCOV_EXCL_START */
ferr("Error seeking file %s\n", path);
msg_error("Error seeking file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (read(f, data, size) != size) {
/* LCOV_EXCL_START */
ferr("Error writing file %s\n", path);
msg_error("Error writing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -421,28 +421,28 @@ void cmd_damage(const char* path, int size)
if (lseek(f, off, SEEK_SET) != off) {
/* LCOV_EXCL_START */
ferr("Error seeking file %s\n", path);
msg_error("Error seeking file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (write(f, data, size) != size) {
/* LCOV_EXCL_START */
ferr("Error writing file %s\n", path);
msg_error("Error writing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (fallback(f, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error setting time for file %s\n", path);
msg_error("Error setting time for file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (close(f) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file %s\n", path);
msg_error("Error closing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -462,7 +462,7 @@ void cmd_append(const char* path, int size)
if (lstat(path, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing %s\n", path);
msg_error("Error accessing %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -478,21 +478,21 @@ void cmd_append(const char* path, int size)
f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
if (f < 0) {
/* LCOV_EXCL_START */
ferr("Error opening file %s\n", path);
msg_error("Error opening file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (write(f, data, size) != size) {
/* LCOV_EXCL_START */
ferr("Error writing file %s\n", path);
msg_error("Error writing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (close(f) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file %s\n", path);
msg_error("Error closing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -513,7 +513,7 @@ void cmd_truncate(const char* path, int size)
if (lstat(path, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing %s\n", path);
msg_error("Error accessing %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -536,21 +536,21 @@ void cmd_truncate(const char* path, int size)
f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
if (f < 0) {
/* LCOV_EXCL_START */
ferr("Error opening file %s\n", path);
msg_error("Error opening file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (ftruncate(f, off) != 0) {
/* LCOV_EXCL_START */
ferr("Error truncating file %s\n", path);
msg_error("Error truncating file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (close(f) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file %s\n", path);
msg_error("Error closing file %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -565,7 +565,7 @@ void cmd_delete(const char* path)
{
if (remove(path) != 0) {
/* LCOV_EXCL_START */
ferr("Error removing %s\n", path);
msg_error("Error removing %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -584,7 +584,7 @@ void cmd_change(const char* path, int size)
if (lstat(path, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing %s\n", path);
msg_error("Error accessing %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -595,7 +595,7 @@ void cmd_change(const char* path, int size)
/* delete */
if (remove(path) != 0) {
/* LCOV_EXCL_START */
ferr("Error removing %s\n", path);
msg_error("Error removing %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -605,7 +605,7 @@ void cmd_change(const char* path, int size)
if (remove(path) != 0) {
/* LCOV_EXCL_START */
ferr("Error removing %s\n", path);
msg_error("Error removing %s\n", path);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -633,14 +633,14 @@ void cmd_change(const char* path, int size)
void help(void)
{
fout("Test for " PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
fout("Usage:\n");
fout("\tmktest generate SEED DISK_NUM FILE_NUM FILE_SIZE\n");
fout("\tmktest damage SEED NUM SIZE FILE\n");
fout("\tmktest write SEED NUM SIZE FILE\n");
fout("\tmktest change SEED SIZE FILE\n");
fout("\tmktest append SEED SIZE FILE\n");
fout("\tmktest truncate SEED SIZE FILE\n");
printf("Test for " PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
printf("Usage:\n");
printf("\tmktest generate SEED DISK_NUM FILE_NUM FILE_SIZE\n");
printf("\tmktest damage SEED NUM SIZE FILE\n");
printf("\tmktest write SEED NUM SIZE FILE\n");
printf("\tmktest change SEED SIZE FILE\n");
printf("\tmktest append SEED SIZE FILE\n");
printf("\tmktest truncate SEED SIZE FILE\n");
}
int main(int argc, char* argv[])

View file

@ -26,7 +26,7 @@ void state_nano(struct snapraid_state* state)
{
tommy_node* i;
fout("Setting nanosecond timestamps...\n");
msg_progress("Setting nanosecond timestamps...\n");
/* for all disks */
for (i = state->disklist; i != 0; i = i->next) {
@ -56,7 +56,7 @@ void state_nano(struct snapraid_state* state)
/* get a random nanosecond value */
if (randomize(&nano, sizeof(nano)) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to get random values.\n");
msg_error("Failed to get random values.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -69,7 +69,7 @@ void state_nano(struct snapraid_state* state)
f = open(path, O_RDONLY | O_BINARY | O_NOFOLLOW);
if (f == -1) {
/* LCOV_EXCL_START */
ferr("Error opening file '%s'. %s.\n", path, strerror(errno));
msg_error("Error opening file '%s'. %s.\n", path, strerror(errno));
continue;
/* LCOV_EXCL_STOP */
}
@ -80,7 +80,7 @@ void state_nano(struct snapraid_state* state)
if (ret == -1) {
/* LCOV_EXCL_START */
close(f);
ferr("Error accessing file '%s'. %s.\n", path, strerror(errno));
msg_error("Error accessing file '%s'. %s.\n", path, strerror(errno));
continue;
/* LCOV_EXCL_STOP */
}
@ -90,7 +90,7 @@ void state_nano(struct snapraid_state* state)
if (ret != 0) {
/* LCOV_EXCL_START */
close(f);
ferr("Error timing file '%s'. %s.\n", path, strerror(errno));
msg_error("Error timing file '%s'. %s.\n", path, strerror(errno));
continue;
/* LCOV_EXCL_STOP */
}
@ -102,7 +102,7 @@ void state_nano(struct snapraid_state* state)
if (ret == -1) {
/* LCOV_EXCL_START */
close(f);
ferr("Error accessing file '%s'. %s.\n", path, strerror(errno));
msg_error("Error accessing file '%s'. %s.\n", path, strerror(errno));
continue;
/* LCOV_EXCL_STOP */
}
@ -111,7 +111,7 @@ void state_nano(struct snapraid_state* state)
ret = close(f);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file '%s'. %s.\n", path, strerror(errno));
msg_error("Error closing file '%s'. %s.\n", path, strerror(errno));
continue;
/* LCOV_EXCL_STOP */
}
@ -125,8 +125,8 @@ void state_nano(struct snapraid_state* state)
/* state changed, we need to update it */
state->need_write = 1;
ftag("nano:%s:%s\n", disk->name, esc(file->sub));
fout("nano %s%s\n", disk->dir, file->sub);
msg_tag("nano:%s:%s\n", disk->name, esc(file->sub));
msg_info("nano %s%s\n", disk->dir, file->sub);
}
}
}

View file

@ -102,14 +102,14 @@ void parity_overflow(struct snapraid_state* state, data_off_t size)
if (file->blockmax > 0) {
if (file->blockvec[file->blockmax - 1].parity_pos >= blockalloc) {
ftag("outofparity:%s:%s\n", disk->name, esc(file->sub));
fflush_log();
msg_tag("outofparity:%s:%s\n", disk->name, esc(file->sub));
msg_flush();
if (first) {
first = 0;
fout("\nYour data requires more parity than the available space.\n");
fout("Please move the following files to another data disk:\n");
msg_warning("\nYour data requires more parity than the available space.\n");
msg_warning("Please move the files 'outofparity' to another data disk:\n");
}
fout("outofparity %s%s\n", disk->dir, file->sub);
msg_warning("outofparity %s%s\n", disk->dir, file->sub);
}
}
}
@ -131,7 +131,7 @@ int parity_create(struct snapraid_parity_handle* parity, const char* path, data_
parity->f = open(parity->path, flags, 0600);
if (parity->f == -1) {
/* LCOV_EXCL_START */
ferr("Error opening parity file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error opening parity file '%s'. %s.\n", parity->path, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -140,7 +140,7 @@ int parity_create(struct snapraid_parity_handle* parity, const char* path, data_
ret = fstat(parity->f, &parity->st);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno));
goto bail;
/* LCOV_EXCL_STOP */
}
@ -151,7 +151,7 @@ int parity_create(struct snapraid_parity_handle* parity, const char* path, data_
ret = posix_fadvise(parity->f, 0, 0, POSIX_FADV_SEQUENTIAL);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error advising parity file '%s'. %s.\n", parity->path, strerror(ret));
msg_error("Error advising parity file '%s'. %s.\n", parity->path, strerror(ret));
goto bail;
/* LCOV_EXCL_STOP */
}
@ -227,7 +227,7 @@ int parity_chsize(struct snapraid_parity_handle* parity, data_off_t size, data_o
ret = fstat(parity->f, &parity->st);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno));
goto bail;
/* LCOV_EXCL_STOP */
}
@ -239,9 +239,9 @@ int parity_chsize(struct snapraid_parity_handle* parity, data_off_t size, data_o
if (f_ret != 0) {
/* LCOV_EXCL_START */
if (f_errno == ENOSPC) {
ferr("Failed to grow parity file '%s' to size %" PRIu64 " using %s due lack of space.\n", parity->path, size, call);
msg_error("Failed to grow parity file '%s' to size %" PRIu64 " using %s due lack of space.\n", parity->path, size, call);
} else {
ferr("Error growing parity file '%s' to size %" PRIu64 " using %s. Do you have enough space? %s.\n", parity->path, size, call, strerror(f_errno));
msg_error("Error growing parity file '%s' to size %" PRIu64 " using %s. Do you have enough space? %s.\n", parity->path, size, call, strerror(f_errno));
}
goto bail;
/* LCOV_EXCL_STOP */
@ -261,7 +261,7 @@ int parity_chsize(struct snapraid_parity_handle* parity, data_off_t size, data_o
ret = fstat(parity->f, &parity->st);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno));
goto bail;
/* LCOV_EXCL_STOP */
}
@ -272,7 +272,7 @@ int parity_chsize(struct snapraid_parity_handle* parity, data_off_t size, data_o
/* now check the error */
if (f_ret != 0) {
/* LCOV_EXCL_START */
ferr("Error truncating parity file '%s' to size %" PRIu64 ". %s.\n", parity->path, size, strerror(f_errno));
msg_error("Error truncating parity file '%s' to size %" PRIu64 ". %s.\n", parity->path, size, strerror(f_errno));
goto bail;
/* LCOV_EXCL_STOP */
}
@ -305,7 +305,7 @@ int parity_open(struct snapraid_parity_handle* parity, const char* path, int mod
flags |= O_SEQUENTIAL;
parity->f = open_noatime(parity->path, flags);
if (parity->f == -1) {
ferr("Error opening parity file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error opening parity file '%s'. %s.\n", parity->path, strerror(errno));
return -1;
}
@ -313,7 +313,7 @@ int parity_open(struct snapraid_parity_handle* parity, const char* path, int mod
ret = fstat(parity->f, &parity->st);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno));
goto bail;
/* LCOV_EXCL_STOP */
}
@ -327,7 +327,7 @@ int parity_open(struct snapraid_parity_handle* parity, const char* path, int mod
ret = posix_fadvise(parity->f, 0, 0, POSIX_FADV_SEQUENTIAL);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error advising parity file '%s'. %s.\n", parity->path, strerror(ret));
msg_error("Error advising parity file '%s'. %s.\n", parity->path, strerror(ret));
goto bail;
/* LCOV_EXCL_STOP */
}
@ -356,7 +356,7 @@ int parity_sync(struct snapraid_parity_handle* parity)
ret = fsync(parity->f);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error synching parity file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error synching parity file '%s'. %s.\n", parity->path, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -379,7 +379,7 @@ int parity_close(struct snapraid_parity_handle* parity)
/* This is a serious error, as it may be the result of a failed write */
/* identified at later time. */
/* In a normal filesystem (not NFS) it should never happen */
ferr("Error closing parity file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error closing parity file '%s'. %s.\n", parity->path, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -404,9 +404,9 @@ int parity_write(struct snapraid_parity_handle* parity, block_off_t pos, unsigne
if (lseek(parity->f, offset, SEEK_SET) != offset) {
/* LCOV_EXCL_START */
if (errno == ENOSPC) {
ferr("Failed to grow parity file '%s' using lseek due lack of space.\n", parity->path);
msg_error("Failed to grow parity file '%s' using lseek due lack of space.\n", parity->path);
} else {
ferr("Error seeking file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error seeking file '%s'. %s.\n", parity->path, strerror(errno));
}
return -1;
/* LCOV_EXCL_STOP */
@ -417,9 +417,9 @@ int parity_write(struct snapraid_parity_handle* parity, block_off_t pos, unsigne
if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */
/* LCOV_EXCL_START */
if (errno == ENOSPC) {
ferr("Failed to grow parity file '%s' using write due lack of space.\n", parity->path);
msg_error("Failed to grow parity file '%s' using write due lack of space.\n", parity->path);
} else {
ferr("Error writing file '%s'. %s.\n", parity->path, strerror(errno));
msg_error("Error writing file '%s'. %s.\n", parity->path, strerror(errno));
}
return -1;
/* LCOV_EXCL_STOP */

View file

@ -33,7 +33,7 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
d = opendir(dir);
if (!d) {
/* LCOV_EXCL_START */
ferr("Error opening pool directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error opening pool directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -49,7 +49,7 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
dd = readdir(d);
if (dd == 0 && errno != 0) {
/* LCOV_EXCL_START */
ferr("Error reading pool directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error reading pool directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -73,7 +73,7 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
if (st.st_mode == 0) {
if (lstat(path_next, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -82,7 +82,7 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
/* get lstat info about the file */
if (lstat(path_next, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -95,7 +95,7 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
ret = remove(path_next);
if (ret < 0) {
/* LCOV_EXCL_START */
ferr("Error removing symlink '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error removing symlink '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -113,13 +113,13 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
/* in Windows just ignore EACCES errors removing directories */
/* because it could happen that the directory is in use */
/* and it cannot be removed */
ferr("Directory '%s' not removed because it's in use.\n", path_next);
msg_error("Directory '%s' not removed because it's in use.\n", path_next);
ignored = 1;
} else
#endif
{
/* LCOV_EXCL_START */
ferr("Error removing pool directory '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error removing pool directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -130,15 +130,13 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
}
} else {
ignored = 1;
if (state->opt.verbose) {
fout("Ignoring pool file '%s'\n", path_next);
}
msg_verbose("Ignoring pool file '%s'\n", path_next);
}
}
if (closedir(d) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing pool directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error closing pool directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -183,17 +181,17 @@ static void make_link(const char* pool_dir, const char* share_dir, struct snapra
ret = symlink(linkto_exported, path);
if (ret != 0) {
if (errno == EEXIST) {
ferr("WARNING! Duplicate pooling for '%s'\n", path);
msg_warning("WARNING! Duplicate pooling for '%s'\n", path);
#ifdef _WIN32
} else if (errno == EPERM) {
/* LCOV_EXCL_START */
ferr("You must run as Adminstrator to be able to create symlinks.\n");
msg_error("You must run as Adminstrator to be able to create symlinks.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
#endif
} else {
/* LCOV_EXCL_START */
ferr("Error writing symlink '%s'. %s.\n", path, strerror(errno));
msg_error("Error writing symlink '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -209,12 +207,12 @@ void state_pool(struct snapraid_state* state)
if (state->pool[0] == 0) {
/* LCOV_EXCL_START */
ferr("To use the 'pool' command you must set the pool directory in the configuration file\n");
msg_error("To use the 'pool' command you must set the pool directory in the configuration file\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
fout("Cleaning...\n");
msg_progress("Cleaning...\n");
/* pool directory with final slash */
pathprint(pool_dir, sizeof(pool_dir), "%s", state->pool);
@ -227,7 +225,7 @@ void state_pool(struct snapraid_state* state)
/* first clear the previous pool tree */
clean_dir(state, pool_dir);
fout("Pooling...\n");
msg_progress("Pooling...\n");
/* for each disk */
count = 0;
@ -253,12 +251,12 @@ void state_pool(struct snapraid_state* state)
}
if (count)
fout("%u links created\n", count);
msg_status("%u links created\n", count);
else
fout("No link created\n");
msg_status("No link created\n");
ftag("summary:link_count::%u\n", count);
ftag("summary:exit:ok\n");
fflush_log();
msg_tag("summary:link_count::%u\n", count);
msg_tag("summary:exit:ok\n");
msg_flush();
}

View file

@ -38,14 +38,14 @@ void state_rehash(struct snapraid_state* state)
/* check if a rehash is already in progress */
if (state->prevhash != HASH_UNDEFINED) {
/* LCOV_EXCL_START */
ferr("You already have a rehash in progress.\n");
msg_error("You already have a rehash in progress.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (state->hash == state->besthash) {
/* LCOV_EXCL_START */
ferr("You are already using the best hash for your platform.\n");
msg_error("You are already using the best hash for your platform.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -58,7 +58,7 @@ void state_rehash(struct snapraid_state* state)
state->hash = state->besthash;
if (randomize(state->hashseed, HASH_SIZE) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to get random values.\n");
msg_error("Failed to get random values.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -76,7 +76,7 @@ void state_rehash(struct snapraid_state* state)
if (info_get_rehash(info)) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency for a rehash already in progress\n");
msg_error("Internal inconsistency for a rehash already in progress\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -91,8 +91,8 @@ void state_rehash(struct snapraid_state* state)
/* save the new content file */
state->need_write = 1;
fout("A rehash is now scheduled. It will take place progressively in the next\n");
fout("'sync' and 'scrub' commands. You can check the rehash progress using the\n");
fout("'status' command.\n");
msg_status("A rehash is now scheduled. It will take place progressively in the next\n");
msg_status("'sync' and 'scrub' commands. You can check the rehash progress using the\n");
msg_status("'status' command.\n");
}

View file

@ -94,7 +94,7 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub,
/* check if multiple files have the same name */
if (link_flag_has(link, FILE_IS_PRESENT)) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency for link '%s%s'\n", disk->dir, sub);
msg_error("Internal inconsistency for link '%s%s'\n", disk->dir, sub);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -108,7 +108,7 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub,
++scan->count_equal;
if (state->opt.gui) {
ftag("scan:equal:%s:%s\n", disk->name, esc(link->sub));
msg_tag("scan:equal:%s:%s\n", disk->name, esc(link->sub));
}
} else {
/* it's an update */
@ -118,9 +118,9 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub,
++scan->count_change;
ftag("scan:update:%s:%s\n", disk->name, esc(link->sub));
msg_tag("scan:update:%s:%s\n", disk->name, esc(link->sub));
if (is_diff) {
fout("update %s%s\n", disk->dir, link->sub);
printf("update %s%s\n", disk->dir, link->sub);
}
/* update it */
@ -135,9 +135,9 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub,
/* create the new link */
++scan->count_insert;
ftag("scan:add:%s:%s\n", disk->name, esc(sub));
msg_tag("scan:add:%s:%s\n", disk->name, esc(sub));
if (is_diff) {
fout("add %s%s\n", disk->dir, sub);
printf("add %s%s\n", disk->dir, sub);
}
/* and continue to insert it */
@ -213,7 +213,7 @@ static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_fil
break;
default :
/* LCOV_EXCL_START */
ferr("Internal inconsistency in deallocating for block %u state %u\n", block->parity_pos, block_state);
msg_error("Internal inconsistency in deallocating for block %u state %u\n", block->parity_pos, block_state);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -305,7 +305,7 @@ static void scan_file_delayed_insert(struct snapraid_scan* scan, struct snapraid
if (filephy(path_next, file->size, &file->physical) != 0) {
/* LCOV_EXCL_START */
ferr("Error in getting the physical offset of file '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in getting the physical offset of file '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -347,7 +347,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 */
ferr("Error in stat file '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -365,8 +365,8 @@ 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
*/
ferr("WARNING! Detected uncached time change for file '%s'\n", sub);
ferr("It's better if you run SnapRAID without other processes running.\n");
msg_error("WARNING! Detected uncached time change for file '%s'\n", sub);
msg_error("It's better if you run SnapRAID without other processes running.\n");
#endif
st->st_mtime = synced_st.st_mtime;
st->st_mtimensec = synced_st.st_mtimensec;
@ -374,15 +374,15 @@ static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struc
if (st->st_size != synced_st.st_size) {
#ifndef _WIN32
ferr("WARNING! Detected uncached size change for file '%s'\n", sub);
ferr("It's better if you run SnapRAID without other processes running.\n");
msg_error("WARNING! Detected uncached size change for file '%s'\n", sub);
msg_error("It's better if you run SnapRAID without other processes running.\n");
#endif
st->st_size = synced_st.st_size;
}
if (st->st_ino != synced_st.st_ino) {
ferr("DANGER! Detected uncached inode change for file '%s'\n", sub);
ferr("Please ensure to run SnapRAID without other processes running.\n");
msg_error("DANGER! Detected uncached inode change for file '%s'\n", sub);
msg_error("Please ensure to run SnapRAID without other processes running.\n");
/* at this point, it's too late to change inode */
/* and having inconsistent inodes may result to internal failures */
/* so, it's better to abort */
@ -610,7 +610,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
#if HAVE_STRUCT_STAT_ST_NLINK
if (st->st_nlink <= 1) {
/* LCOV_EXCL_START */
ferr("Internal inode '%" PRIu64 "' inconsistency for file '%s%s' already present\n", (uint64_t)st->st_ino, disk->dir, sub);
msg_error("Internal inode '%" PRIu64 "' inconsistency for file '%s%s' already present\n", (uint64_t)st->st_ino, disk->dir, sub);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -638,9 +638,9 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
/* if the path is different, it means a moved file with the same inode */
++scan->count_move;
ftag("scan:move:%s:%s:%s\n", disk->name, esc(file->sub), esc(sub));
msg_tag("scan:move:%s:%s:%s\n", disk->name, esc(file->sub), esc(sub));
if (is_diff) {
fout("move %s%s -> %s%s\n", disk->dir, file->sub, disk->dir, sub);
printf("move %s%s -> %s%s\n", disk->dir, file->sub, disk->dir, sub);
}
/* remove from the name set */
@ -659,7 +659,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
++scan->count_equal;
if (state->opt.gui) {
ftag("scan:equal:%s:%s\n", disk->name, esc(file->sub));
msg_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub));
}
}
@ -678,7 +678,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
/* for sure it cannot be already present */
if (file_flag_has(file, FILE_IS_PRESENT)) {
/* LCOV_EXCL_START */
ferr("Internal inode '%" PRIu64 "' inconsistency for files '%s%s' and '%s%s' matching and already present but different\n", file->inode, disk->dir, sub, disk->dir, file->sub);
msg_error("Internal inode '%" PRIu64 "' inconsistency for files '%s%s' and '%s%s' matching and already present but different\n", file->inode, disk->dir, sub, disk->dir, file->sub);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -728,7 +728,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
/* here the inode has to be different, otherwise we would have found it before */
if (file->inode == st->st_ino) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub);
msg_error("Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -737,7 +737,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
/* for sure it cannot be already present */
if (file_flag_has(file, FILE_IS_PRESENT)) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub);
msg_error("Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -775,9 +775,9 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
/* like when restoring a backup that restores also the timestamp */
++scan->count_restore;
ftag("scan:restore:%s:%s\n", disk->name, esc(sub));
msg_tag("scan:restore:%s:%s\n", disk->name, esc(sub));
if (is_diff) {
fout("restore %s%s\n", disk->dir, sub);
printf("restore %s%s\n", disk->dir, sub);
}
/* remove from the inode set */
@ -798,7 +798,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
++scan->count_equal;
if (state->opt.gui) {
ftag("scan:equal:%s:%s\n", disk->name, esc(file->sub));
msg_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub));
}
}
@ -830,11 +830,11 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
if (is_original_file_size_different_than_zero && st->st_size == 0) {
if (!state->opt.force_zero) {
/* LCOV_EXCL_START */
ferr("The file '%s%s' has unexpected zero size!\n", disk->dir, sub);
ferr("It's possible that after a kernel crash this file was lost,\n");
ferr("and you can use 'snapraid --filter %s fix' to recover it.\n", sub);
msg_error("The file '%s%s' has unexpected zero size!\n", disk->dir, sub);
msg_error("It's possible that after a kernel crash this file was lost,\n");
msg_error("and you can use 'snapraid --filter %s fix' to recover it.\n", sub);
if (!is_diff) {
ferr("If this an expected condition you can '%s' anyway using 'snapraid --force-zero %s'\n", state->command, state->command);
msg_error("If this an expected condition you can '%s' anyway using 'snapraid --force-zero %s'\n", state->command, state->command);
exit(EXIT_FAILURE);
}
/* LCOV_EXCL_STOP */
@ -875,9 +875,9 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
/* revert old counter and use the copy one */
++scan->count_copy;
ftag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc(other_file->sub), disk->name, esc(file->sub));
msg_tag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc(other_file->sub), disk->name, esc(file->sub));
if (is_diff) {
fout("copy %s%s -> %s%s\n", other_disk->dir, other_file->sub, disk->dir, file->sub);
printf("copy %s%s -> %s%s\n", other_disk->dir, other_file->sub, disk->dir, file->sub);
}
/* mark it as reported */
@ -894,16 +894,16 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
if (is_file_already_present) {
++scan->count_change;
ftag("scan:update:%s:%s\n", disk->name, esc(sub));
msg_tag("scan:update:%s:%s\n", disk->name, esc(sub));
if (is_diff) {
fout("update %s%s\n", disk->dir, sub);
printf("update %s%s\n", disk->dir, sub);
}
} else {
++scan->count_insert;
ftag("scan:add:%s:%s\n", disk->name, esc(sub));
msg_tag("scan:add:%s:%s\n", disk->name, esc(sub));
if (is_diff) {
fout("add %s%s\n", disk->dir, sub);
printf("add %s%s\n", disk->dir, sub);
}
}
}
@ -966,7 +966,7 @@ static void scan_emptydir(struct snapraid_scan* scan, const char* sub)
/* check if multiple files have the same name */
if (dir_flag_has(dir, FILE_IS_PRESENT)) {
/* LCOV_EXCL_START */
ferr("Internal inconsistency for dir '%s%s'\n", disk->dir, sub);
msg_error("Internal inconsistency for dir '%s%s'\n", disk->dir, sub);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1044,7 +1044,7 @@ struct stat* dstat(const char* file, struct stat* st)
{
if (lstat(file, st) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file/directory '%s'. %s.\n", file, strerror(errno));
msg_error("Error in stat file/directory '%s'. %s.\n", file, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1070,8 +1070,8 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
d = opendir(dir);
if (!d) {
/* LCOV_EXCL_START */
ferr("Error opening directory '%s'. %s.\n", dir, strerror(errno));
ferr("You can exclude it in the config file with:\n\texclude /%s\n", sub);
msg_error("Error opening directory '%s'. %s.\n", dir, strerror(errno));
msg_error("You can exclude it in the config file with:\n\texclude /%s\n", sub);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1090,8 +1090,8 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
dd = readdir(d);
if (dd == 0 && errno != 0) {
/* LCOV_EXCL_START */
ferr("Error reading directory '%s'. %s.\n", dir, strerror(errno));
ferr("You can exclude it in the config file with:\n\texclude /%s\n", sub);
msg_error("Error reading directory '%s'. %s.\n", dir, strerror(errno));
msg_error("You can exclude it in the config file with:\n\texclude /%s\n", sub);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1110,24 +1110,20 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
/* check for not supported file names */
if (name[0] == 0) {
/* LCOV_EXCL_START */
ferr("Unsupported name '%s' in file '%s'.\n", name, path_next);
msg_error("Unsupported name '%s' in file '%s'.\n", name, path_next);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
/* exclude hidden files even before calling lstat() */
if (filter_hidden(state->filter_hidden, dd) != 0) {
if (state->opt.verbose) {
fout("Excluding hidden '%s'\n", path_next);
}
msg_verbose("Excluding hidden '%s'\n", path_next);
continue;
}
/* exclude content files even before calling lstat() */
if (filter_content(&state->contentlist, path_next) != 0) {
if (state->opt.verbose) {
fout("Excluding content '%s'\n", path_next);
}
msg_verbose("Excluding content '%s'\n", path_next);
continue;
}
@ -1155,7 +1151,7 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
if (closedir(d) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error closing directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1222,7 +1218,7 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
if (st->st_mode == 0) {
if (lstat(path_next, st) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1252,7 +1248,7 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
if (st->st_ino == 0) {
if (lstat_sync(path_next, st, 0) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1262,9 +1258,7 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET);
processed = 1;
} else {
if (state->opt.verbose) {
fout("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
} else if (type == 1) { /* LNK */
if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
@ -1274,13 +1268,13 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
ret = readlink(path_next, subnew, sizeof(subnew));
if (ret >= PATH_MAX) {
/* LCOV_EXCL_START */
ferr("Error in readlink file '%s'. Symlink too long.\n", path_next);
msg_error("Error in readlink file '%s'. Symlink too long.\n", path_next);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (ret < 0) {
/* LCOV_EXCL_START */
ferr("Error in readlink file '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in readlink file '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1292,9 +1286,7 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
scan_link(scan, is_diff, sub_next, subnew, FILE_IS_SYMLINK);
processed = 1;
} else {
if (state->opt.verbose) {
fout("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
} else if (type == 2) { /* DIR */
if (filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
@ -1306,7 +1298,7 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
/* 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) {
ferr("WARNING! Ignoring mount point '%s' because it appears to be in a different device\n", path_next);
msg_error("WARNING! Ignoring mount point '%s' because it appears to be in a different device\n", path_next);
} else
#endif
{
@ -1324,9 +1316,7 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
processed = 1;
}
} else {
if (state->opt.verbose) {
fout("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
} else {
if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
@ -1334,11 +1324,9 @@ static int scan_dir(struct snapraid_scan* scan, int is_diff, const char* dir, co
if (!st)
st = DSTAT(path_next, dd, &st_buf);
ferr("WARNING! Ignoring special '%s' file '%s'\n", stat_desc(st), path_next);
msg_error("WARNING! Ignoring special '%s' file '%s'\n", stat_desc(st), path_next);
} else {
if (state->opt.verbose) {
fout("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
msg_verbose("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
}
@ -1358,11 +1346,14 @@ void state_scan(struct snapraid_state* state, int is_diff)
tommy_node* j;
tommy_list scanlist;
int done;
fptr* msg;
struct snapraid_scan total;
int no_difference;
tommy_list_init(&scanlist);
if (is_diff)
fout("Comparing...\n");
msg_progress("Comparing...\n");
/* first scan all the directory and find new and deleted files */
for (i = state->disklist; i != 0; i = i->next) {
@ -1389,13 +1380,13 @@ void state_scan(struct snapraid_state* state, int is_diff)
tommy_list_insert_tail(&scanlist, &scan->node, scan);
if (!is_diff)
fout("Scanning disk %s...\n", disk->name);
msg_progress("Scanning disk %s...\n", disk->name);
/* check if the disk supports persistent inodes */
ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0);
if (ret < 0) {
/* LCOV_EXCL_START */
ferr("Error accessing disk '%s' to get filesystem info. %s.\n", disk->dir, strerror(errno));
msg_error("Error accessing disk '%s' to get filesystem info. %s.\n", disk->dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1455,9 +1446,9 @@ void state_scan(struct snapraid_state* state, int is_diff)
if (!file_flag_has(file, FILE_IS_PRESENT)) {
++scan->count_remove;
ftag("scan:remove:%s:%s\n", disk->name, esc(file->sub));
msg_tag("scan:remove:%s:%s\n", disk->name, esc(file->sub));
if (is_diff) {
fout("remove %s%s\n", disk->dir, file->sub);
printf("remove %s%s\n", disk->dir, file->sub);
}
scan_file_remove(scan, file);
@ -1476,9 +1467,9 @@ void state_scan(struct snapraid_state* state, int is_diff)
if (!link_flag_has(link, FILE_IS_PRESENT)) {
++scan->count_remove;
ftag("scan:remove:%s:%s\n", disk->name, esc(link->sub));
msg_tag("scan:remove:%s:%s\n", disk->name, esc(link->sub));
if (is_diff) {
fout("remove %s%s\n", disk->dir, link->sub);
printf("remove %s%s\n", disk->dir, link->sub);
}
scan_link_remove(scan, link);
@ -1536,8 +1527,8 @@ void state_scan(struct snapraid_state* state, int is_diff)
) {
/* if verbose, prints the list of duplicates real offsets */
/* other cases are for offsets not supported, so we don't need to report them file by file */
if (state->opt.verbose && phy_last >= FILEPHY_REAL_OFFSET) {
ferr("WARNING! Files '%s%s' and '%s%s' have the same physical offset %" PRId64 ".\n", disk->dir, phy_file_last->sub, disk->dir, file->sub, phy_last);
if (phy_last >= FILEPHY_REAL_OFFSET) {
msg_warning("WARNING! Files '%s%s' and '%s%s' have the same physical offset %" PRId64 ".\n", disk->dir, phy_file_last->sub, disk->dir, file->sub, phy_last);
}
++phy_dup;
}
@ -1594,20 +1585,20 @@ void state_scan(struct snapraid_state* state, int is_diff)
if (scan->count_equal == 0 && scan->count_move == 0 && scan->count_restore == 0 && (scan->count_remove != 0 || scan->count_change != 0)) {
if (!done) {
done = 1;
ferr("WARNING! All the files previously present in disk '%s' at dir '%s'", disk->name, disk->dir);
msg_error("WARNING! All the files previously present in disk '%s' at dir '%s'", disk->name, disk->dir);
} else {
ferr(", disk '%s' at dir '%s'", disk->name, disk->dir);
msg_error(", disk '%s' at dir '%s'", disk->name, disk->dir);
}
}
}
if (done) {
ferr("\nare now missing or rewritten!\n");
ferr("This could happen when deleting all the files from a disk,\n");
ferr("and restoring them with a program that it's not setting\n");
ferr("correctly the timestamps.\n");
ferr("It's also possible that you have some disks not mounted.\n");
msg_error("\nare now missing or rewritten!\n");
msg_error("This could happen when deleting all the files from a disk,\n");
msg_error("and restoring them with a program that it's not setting\n");
msg_error("correctly the timestamps.\n");
msg_error("It's also possible that you have some disks not mounted.\n");
if (!is_diff) {
ferr("If you want to '%s' anyway, use 'snapraid --force-empty %s'.", state->command, state->command);
msg_error("If you want to '%s' anyway, use 'snapraid --force-empty %s'.", state->command, state->command);
exit(EXIT_FAILURE);
}
}
@ -1622,14 +1613,14 @@ void state_scan(struct snapraid_state* state, int is_diff)
if (disk->has_unreliable_physical) {
if (!done) {
done = 1;
ferr("WARNING! Physical offsets not supported for disk '%s'", disk->name);
msg_error("WARNING! Physical offsets not supported for disk '%s'", disk->name);
} else {
ferr(", '%s'", disk->name);
msg_error(", '%s'", disk->name);
}
}
}
if (done) {
ferr(". Files order won't be optimal.\n");
msg_error(". Files order won't be optimal.\n");
}
}
@ -1641,14 +1632,14 @@ void state_scan(struct snapraid_state* state, int is_diff)
if (disk->has_volatile_inodes) {
if (!done) {
done = 1;
ferr("WARNING! Inodes are not persistent for disks: '%s'", disk->name);
msg_error("WARNING! Inodes are not persistent for disks: '%s'", disk->name);
} else {
ferr(", '%s'", disk->name);
msg_error(", '%s'", disk->name);
}
}
}
if (done) {
ferr(". Move operations won't be optimal.\n");
msg_error(". Move operations won't be optimal.\n");
}
/* checks for disks with changed UUID */
@ -1663,14 +1654,14 @@ void state_scan(struct snapraid_state* state, int is_diff)
if (disk->has_different_uuid && !disk->had_empty_uuid) {
if (!done) {
done = 1;
ferr("WARNING! UUID is changed for disks: '%s'", disk->name);
msg_error("WARNING! UUID is changed for disks: '%s'", disk->name);
} else {
ferr(", '%s'", disk->name);
msg_error(", '%s'", disk->name);
}
}
}
if (done) {
ferr(". Move operations won't be optimal.\n");
msg_error(". Move operations won't be optimal.\n");
}
/* checks for disks with unsupported UUID */
@ -1681,78 +1672,76 @@ void state_scan(struct snapraid_state* state, int is_diff)
if (disk->has_unsupported_uuid) {
if (!done) {
done = 1;
ferr("WARNING! UUID is unsupported for disks: '%s'", disk->name);
msg_error("WARNING! UUID is unsupported for disks: '%s'", disk->name);
} else {
ferr(", '%s'", disk->name);
msg_error(", '%s'", disk->name);
}
}
}
if (done) {
ferr(". Move operations won't be optimal.\n");
msg_error(". Move operations won't be optimal.\n");
}
if (state->opt.verbose || is_diff) {
struct snapraid_scan total;
int no_difference;
total.count_equal = 0;
total.count_move = 0;
total.count_copy = 0;
total.count_restore = 0;
total.count_change = 0;
total.count_remove = 0;
total.count_insert = 0;
total.count_equal = 0;
total.count_move = 0;
total.count_copy = 0;
total.count_restore = 0;
total.count_change = 0;
total.count_remove = 0;
total.count_insert = 0;
for (i = scanlist; i != 0; i = i->next) {
struct snapraid_scan* scan = i->data;
total.count_equal += scan->count_equal;
total.count_move += scan->count_move;
total.count_copy += scan->count_copy;
total.count_restore += scan->count_restore;
total.count_change += scan->count_change;
total.count_remove += scan->count_remove;
total.count_insert += scan->count_insert;
}
for (i = scanlist; i != 0; i = i->next) {
struct snapraid_scan* scan = i->data;
total.count_equal += scan->count_equal;
total.count_move += scan->count_move;
total.count_copy += scan->count_copy;
total.count_restore += scan->count_restore;
total.count_change += scan->count_change;
total.count_remove += scan->count_remove;
total.count_insert += scan->count_insert;
}
if (is_diff) {
msg_status("\n");
msg = msg_status;
} else {
msg = msg_verbose;
}
if (state->opt.verbose || is_diff) {
if (is_diff)
fout("\n");
fout("%8u equal\n", total.count_equal);
fout("%8u moved\n", total.count_move);
fout("%8u copied\n", total.count_copy);
fout("%8u restored\n", total.count_restore);
fout("%8u updated\n", total.count_change);
fout("%8u removed\n", total.count_remove);
fout("%8u added\n", total.count_insert);
}
msg("%8u equal\n", total.count_equal);
msg("%8u moved\n", total.count_move);
msg("%8u copied\n", total.count_copy);
msg("%8u restored\n", total.count_restore);
msg("%8u updated\n", total.count_change);
msg("%8u removed\n", total.count_remove);
msg("%8u added\n", total.count_insert);
ftag("summary:equal:%u\n", total.count_equal);
ftag("summary:moved:%u\n", total.count_move);
ftag("summary:copied:%u\n", total.count_copy);
ftag("summary:restored:%u\n", total.count_restore);
ftag("summary:updated:%u\n", total.count_change);
ftag("summary:removed:%u\n", total.count_remove);
ftag("summary:added:%u\n", total.count_insert);
msg_tag("summary:equal:%u\n", total.count_equal);
msg_tag("summary:moved:%u\n", total.count_move);
msg_tag("summary:copied:%u\n", total.count_copy);
msg_tag("summary:restored:%u\n", total.count_restore);
msg_tag("summary:updated:%u\n", total.count_change);
msg_tag("summary:removed:%u\n", total.count_remove);
msg_tag("summary:added:%u\n", total.count_insert);
no_difference = !total.count_move && !total.count_copy && !total.count_restore
&& !total.count_change && !total.count_remove && !total.count_insert;
if (is_diff) {
if (no_difference) {
fout("No differences\n");
} else {
fout("There are differences!\n");
}
}
no_difference = !total.count_move && !total.count_copy && !total.count_restore
&& !total.count_change && !total.count_remove && !total.count_insert;
if (is_diff) {
if (no_difference) {
ftag("summary:exit:equal\n");
msg_status("No differences\n");
} else {
ftag("summary:exit:diff\n");
msg_status("There are differences!\n");
}
fflush_log();
}
if (no_difference) {
msg_tag("summary:exit:equal\n");
} else {
msg_tag("summary:exit:diff\n");
}
msg_flush();
tommy_list_foreach(&scanlist, (tommy_foreach_func*)free);
}

View file

@ -228,40 +228,40 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
/* This one is really an unexpected error, because we are only reading */
/* and closing a descriptor should never fail */
if (errno == EIO) {
ftag("error:%u:%s:%s: Close EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected input/output close error in a data disk, it isn't possible to scrub.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Close EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected input/output close error in a data disk, it isn't possible to scrub.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
}
ftag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("WARNING! Unexpected close error in a data disk, it isn't possible to scrub.\n");
ferr("Ensure that file '%s' can be accessed.\n", handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("WARNING! Unexpected close error in a data disk, it isn't possible to scrub.\n");
msg_error("Ensure that file '%s' can be accessed.\n", handle[j].path);
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
}
}
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, flog);
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, msg_warning);
if (ret == -1) {
/* file we have tried to open for error reporting */
struct snapraid_file* file = block_file_get(block);
if (errno == EIO) {
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected input/output open error in a data disk, it isn't possible to scrub.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected input/output open error in a data disk, it isn't possible to scrub.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
/* LCOV_EXCL_STOP */
}
ftag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_tag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
++error;
error_on_this_block = 1;
continue;
@ -283,29 +283,29 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
/* from the last sync, as we are expected to return errors if running */
/* in an unsynced array. This is just like the check command. */
read_size = handle_read(&handle[j], block, buffer[j], state->block_size, flog);
read_size = handle_read(&handle[j], block, buffer[j], state->block_size, msg_warning);
if (read_size == -1) {
/* file we are processing for error reporting */
struct snapraid_file* file = block_file_get(block);
if (errno == EIO) {
ftag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
msg_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
if (io_error >= state->opt.io_error_limit) {
/* LCOV_EXCL_START */
ferr("DANGER! Unexpected input/output read error in a data disk, it isn't possible to scrub.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_error("DANGER! Unexpected input/output read error in a data disk, it isn't possible to scrub.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
/* LCOV_EXCL_STOP */
}
flog("Input/Output error in file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
msg_warning("Input/Output error in file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
++io_error;
io_error_on_this_block = 1;
continue;
}
ftag("error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
msg_tag("error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
++error;
error_on_this_block = 1;
continue;
@ -330,14 +330,14 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
if (block_has_updated_hash(block)) {
/* compare the hash */
if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
ftag("error:%u:%s:%s: Data error at position %u\n", i, disk->name, esc(handle[j].file->sub), block_file_pos(block));
msg_tag("error:%u:%s:%s: Data error at position %u\n", i, disk->name, esc(handle[j].file->sub), block_file_pos(block));
/* it's a silent error only if we are dealing with synced files */
if (file_is_unsynced) {
++error;
error_on_this_block = 1;
} else {
flog("Data error in file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
msg_warning("Data error in file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
++silent_error;
silent_error_on_this_block = 1;
}
@ -361,29 +361,29 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
/* read the parity */
for (l = 0; l < state->level; ++l) {
ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, flog);
ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, msg_warning);
if (ret == -1) {
buffer_recov[l] = 0;
if (errno == EIO) {
ftag("parity_error:%u:%s: Read EIO error. %s\n", i, lev_config_name(l), strerror(errno));
msg_tag("parity_error:%u:%s: Read EIO error. %s\n", i, lev_config_name(l), strerror(errno));
if (io_error >= state->opt.io_error_limit) {
/* LCOV_EXCL_START */
ferr("DANGER! Unexpected input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(l));
ferr("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(l));
ferr("Stopping at block %u\n", i);
msg_error("DANGER! Unexpected input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(l));
msg_error("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(l));
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
/* LCOV_EXCL_STOP */
}
flog("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), i);
msg_warning("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), i);
++io_error;
io_error_on_this_block = 1;
continue;
}
ftag("parity_error:%u:%s: Read error. %s\n", i, lev_config_name(l), strerror(errno));
msg_tag("parity_error:%u:%s: Read error. %s\n", i, lev_config_name(l), strerror(errno));
++error;
error_on_this_block = 1;
continue;
@ -399,14 +399,14 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
/* compare the parity */
for (l = 0; l < state->level; ++l) {
if (buffer_recov[l] && memcmp(buffer[diskmax + l], buffer_recov[l], state->block_size) != 0) {
ftag("parity_error:%u:%s: Data error\n", i, lev_config_name(l));
msg_tag("parity_error:%u:%s: Data error\n", i, lev_config_name(l));
/* it's a silent error only if we are dealing with synced blocks */
if (block_is_unsynced) {
++error;
error_on_this_block = 1;
} else {
ferr("Data error in parity '%s' at position '%u'\n", lev_config_name(l), i);
msg_error("Data error in parity '%s' at position '%u'\n", lev_config_name(l), i);
++silent_error;
silent_error_on_this_block = 1;
}
@ -460,7 +460,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
state_progress_stop(state);
fout("Autosaving...\n");
msg_progress("Autosaving...\n");
state_write(state);
state_progress_restart(state);
@ -474,35 +474,36 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
state_usage_print(state);
if (io_error)
ferr("WARNING! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
if (silent_error)
ferr("WARNING! Unexpected data errors! The failing blocks are now marked as bad!\n");
if (io_error || silent_error) {
ferr("Use 'snapraid status' to list the bad blocks.\n");
ferr("Use 'snapraid -e fix' to recover.\n");
}
if (error || silent_error || io_error) {
fout("\n");
fout("%8u file errors\n", error);
fout("%8u io errors\n", io_error);
fout("%8u data errors\n", silent_error);
fout("WARNING! There are errors!\n");
msg_status("\n");
msg_status("%8u file errors\n", error);
msg_status("%8u io errors\n", io_error);
msg_status("%8u data errors\n", silent_error);
} else {
/* print the result only if processed something */
if (countpos != 0)
fout("Everything OK\n");
msg_status("Everything OK\n");
}
ftag("summary:error_file:%u\n", error);
ftag("summary:error_io:%u\n", io_error);
ftag("summary:error_data:%u\n", silent_error);
if (error)
msg_error("WARNING! Unexpected file errors!\n");
if (io_error)
msg_error("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
if (silent_error)
msg_error("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n");
if (io_error || silent_error) {
msg_error("Use 'snapraid status' to list the bad blocks.\n");
msg_error("Use 'snapraid -e fix' to recover.\n");
}
msg_tag("summary:error_file:%u\n", error);
msg_tag("summary:error_io:%u\n", io_error);
msg_tag("summary:error_data:%u\n", silent_error);
if (error + silent_error + io_error == 0)
ftag("summary:exit:ok\n");
msg_tag("summary:exit:ok\n");
else
ftag("summary:exit:error\n");
fflush_log();
msg_tag("summary:exit:error\n");
msg_flush();
bail:
for (j = 0; j < diskmax; ++j) {
@ -511,8 +512,8 @@ bail:
ret = handle_close(&handle[j]);
if (ret == -1) {
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected close error in a data disk.\n");
msg_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected close error in a data disk.\n");
++error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
@ -568,7 +569,7 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
/* get the present time */
now = time(0);
fout("Initializing...\n");
msg_progress("Initializing...\n");
blockmax = parity_allocated_size(state);
@ -601,7 +602,7 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
/* copy the info in the temp vector */
count = 0;
ftag("block_count:%u\n", blockmax);
msg_tag("block_count:%u\n", blockmax);
for (i = 0; i < blockmax; ++i) {
snapraid_info info = info_get(&state->infoarr, i);
@ -614,7 +615,7 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
if (!count) {
/* LCOV_EXCL_START */
ferr("The array appears to be empty.\n");
msg_error("The array appears to be empty.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -624,12 +625,12 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
/* output the info map */
i = 0;
ftag("info_count:%u\n", count);
msg_tag("info_count:%u\n", count);
while (i < count) {
unsigned j = i + 1;
while (j < count && info_get_time(infomap[i]) == info_get_time(infomap[j]))
++j;
ftag("info_time:%" PRIu64 ":%u\n", (uint64_t)info_get_time(infomap[i]), j - i);
msg_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)info_get_time(infomap[i]), j - i);
i = j;
}
@ -657,9 +658,9 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
lastlimit = 0;
}
ftag("count_limit:%u\n", countlimit);
ftag("time_limit:%" PRIu64 "\n", (uint64_t)timelimit);
ftag("last_limit:%u\n", lastlimit);
msg_tag("count_limit:%u\n", countlimit);
msg_tag("time_limit:%" PRIu64 "\n", (uint64_t)timelimit);
msg_tag("last_limit:%u\n", lastlimit);
/* free the temp vector */
free(infomap);
@ -670,13 +671,13 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l));
msg_error("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
}
fout("Scrubbing...\n");
msg_progress("Scrubbing...\n");
error = 0;
@ -690,7 +691,7 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
ret = parity_close(parity_ptr[l]);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
msg_error("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
++error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */

View file

@ -79,14 +79,14 @@ int search_file_compare(const void* void_arg, const void* void_data)
f = open(path, O_RDONLY | O_BINARY);
if (f == -1) {
/* LCOV_EXCL_START */
ferr("Error opening file '%s'. %s.\n", path, strerror(errno));
msg_error("Error opening file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (lseek(f, arg->offset, SEEK_SET) != arg->offset) {
/* LCOV_EXCL_START */
ferr("Error seeking file '%s'. %s.\n", path, strerror(errno));
msg_error("Error seeking file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -94,7 +94,7 @@ int search_file_compare(const void* void_arg, const void* void_data)
ret = read(f, arg->buffer, arg->read_size);
if (ret < 0 || (unsigned)ret != arg->read_size) {
/* LCOV_EXCL_START */
ferr("Error reading file '%s'. %s.\n", path, strerror(errno));
msg_error("Error reading file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -102,7 +102,7 @@ int search_file_compare(const void* void_arg, const void* void_data)
ret = close(f);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error closing file '%s'. %s.\n", path, strerror(errno));
msg_error("Error closing file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -157,7 +157,7 @@ static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk,
d = opendir(dir);
if (!d) {
/* LCOV_EXCL_START */
ferr("Error opening directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error opening directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -176,7 +176,7 @@ static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk,
dd = readdir(d);
if (dd == 0 && errno != 0) {
/* LCOV_EXCL_START */
ferr("Error reading directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error reading directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -194,17 +194,13 @@ static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk,
/* exclude hidden files even before calling lstat() */
if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) {
if (state->opt.verbose) {
fout("Excluding hidden '%s'\n", path_next);
}
msg_verbose("Excluding hidden '%s'\n", path_next);
continue;
}
/* exclude content files even before calling lstat() */
if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) {
if (state->opt.verbose) {
fout("Excluding content '%s'\n", path_next);
}
msg_verbose("Excluding content '%s'\n", path_next);
continue;
}
@ -220,7 +216,7 @@ static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk,
if (st.st_mode == 0) {
if (lstat(path_next, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -229,7 +225,7 @@ static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk,
/* get lstat info about the file */
if (lstat(path_next, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -239,9 +235,7 @@ static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk,
if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
} else {
if (state->opt.verbose) {
fout("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
} else if (S_ISDIR(st.st_mode)) {
if (disk == 0 || filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
@ -249,16 +243,14 @@ static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk,
pathslash(sub_next, sizeof(sub_next));
search_dir(state, disk, path_next, sub_next);
} else {
if (state->opt.verbose) {
fout("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
}
}
}
if (closedir(d) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error closing directory '%s'. %s.\n", dir, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -268,7 +260,7 @@ void state_search(struct snapraid_state* state, const char* dir)
{
char path[PATH_MAX];
fout("Importing...\n");
msg_progress("Importing...\n");
/* add the final slash */
pathimport(path, sizeof(path), dir);
@ -285,7 +277,7 @@ void state_search_array(struct snapraid_state* state)
for (i = state->disklist; i != 0; i = i->next) {
struct snapraid_disk* disk = i->data;
fout("Scanning disk %s...\n", disk->name);
msg_progress("Scanning disk %s...\n", disk->name);
search_dir(state, disk, disk->dir, "");
}

View file

@ -160,7 +160,7 @@ static void test_hash(void)
digest = tommy_hash_u32(seed32, buffer_aligned, TEST_MURMUR3[i].len);
if (digest != TEST_HASH32[i].digest) {
/* LCOV_EXCL_START */
ferr("Failed hash32 test\n");
msg_error("Failed hash32 test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -172,7 +172,7 @@ static void test_hash(void)
digest = tommy_hash_u64(seed64, buffer_aligned, TEST_MURMUR3[i].len);
if (digest != TEST_HASH64[i].digest) {
/* LCOV_EXCL_START */
ferr("Failed hash64 test\n");
msg_error("Failed hash64 test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -185,7 +185,7 @@ static void test_hash(void)
memhash(HASH_MURMUR3, seed_aligned, digest, buffer_aligned, TEST_MURMUR3[i].len);
if (memcmp(digest, TEST_MURMUR3[i].digest, HASH_SIZE) != 0) {
/* LCOV_EXCL_START */
ferr("Failed Murmur3 test\n");
msg_error("Failed Murmur3 test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -197,7 +197,7 @@ static void test_hash(void)
memhash(HASH_SPOOKY2, seed_aligned, digest, buffer_aligned, TEST_SPOOKY2[i].len);
if (memcmp(digest, TEST_SPOOKY2[i].digest, HASH_SIZE) != 0) {
/* LCOV_EXCL_START */
ferr("Failed Spooky2 test\n");
msg_error("Failed Spooky2 test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -246,7 +246,7 @@ static void test_crc32c(void)
digest = crc32c(0, (const unsigned char*)TEST_CRC32C[i].data, TEST_CRC32C[i].len);
if (digest != TEST_CRC32C[i].digest) {
/* LCOV_EXCL_START */
ferr("Failed CRC32C test\n");
msg_error("Failed CRC32C test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -373,22 +373,22 @@ static void test_tommy(void)
return;
bail:
/* LCOV_EXCL_START */
ferr("Failed tommy test\n");
msg_error("Failed tommy test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
void selftest(void)
{
ftag("selftest:\n");
fflush_log();
msg_tag("selftest:\n");
msg_flush();
fout("Self test...\n");
msg_progress("Self test...\n");
/* large file check */
if (sizeof(off_t) < sizeof(uint64_t)) {
/* LCOV_EXCL_START */
ferr("Missing support for large files\n");
msg_error("Missing support for large files\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -398,55 +398,55 @@ void selftest(void)
test_tommy();
if (raid_selftest() != 0) {
/* LCOV_EXCL_START */
ferr("Failed SELF test\n");
msg_error("Failed SELF test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (raid_test_sort() != 0) {
/* LCOV_EXCL_START */
ferr("Failed SORT test\n");
msg_error("Failed SORT test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (raid_test_insert() != 0) {
/* LCOV_EXCL_START */
ferr("Failed INSERT test\n");
msg_error("Failed INSERT test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (raid_test_combo() != 0) {
/* LCOV_EXCL_START */
ferr("Failed COMBO test\n");
msg_error("Failed COMBO test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (raid_test_par(RAID_MODE_VANDERMONDE, 32, 256) != 0) {
/* LCOV_EXCL_START */
ferr("Failed GEN Vandermonde test\n");
msg_error("Failed GEN Vandermonde test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (raid_test_rec(RAID_MODE_VANDERMONDE, 12, 256) != 0) {
/* LCOV_EXCL_START */
ferr("Failed REC Vandermonde test\n");
msg_error("Failed REC Vandermonde test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (raid_test_par(RAID_MODE_CAUCHY, 32, 256) != 0) {
/* LCOV_EXCL_START */
ferr("Failed GEN Cauchy test\n");
msg_error("Failed GEN Cauchy test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (raid_test_rec(RAID_MODE_CAUCHY, 12, 256) != 0) {
/* LCOV_EXCL_START */
ferr("Failed REC Cauchy test\n");
msg_error("Failed REC Cauchy test\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (raid_test_par(RAID_MODE_CAUCHY, 1, 256) != 0) {
/* LCOV_EXCL_START */
ferr("Failed GEN Cauchy test sigle data disk\n");
msg_error("Failed GEN Cauchy test sigle data disk\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}

View file

@ -30,54 +30,54 @@
void version(void)
{
fout(PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
msg_status(PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
}
void usage(void)
{
version();
fout("Usage: " PACKAGE " status|diff|sync|scrub|list|dup|up|down|smart|pool|check|fix [options]\n");
fout("\n");
fout("Commands:\n");
fout(" status Print the status of the array\n");
fout(" diff Show the changes that needs to be syncronized\n");
fout(" sync Syncronize the state of the array\n");
fout(" scrub Scrub the array\n");
fout(" list List the array content\n");
fout(" dup Find duplicate files\n");
fout(" up Spinup the array\n");
fout(" down Spindown the array\n");
fout(" smart SMART attributes of the array\n");
fout(" pool Create or update the virtual view of the array\n");
fout(" check Check the array\n");
fout(" fix Fix the array\n");
fout("\n");
fout("Options:\n");
fout(" " SWITCH_GETOPT_LONG("-c, --conf FILE ", "-c") " Configuration file\n");
fout(" " SWITCH_GETOPT_LONG("-f, --filter PATTERN ", "-f") " Process only files matching the pattern\n");
fout(" " SWITCH_GETOPT_LONG("-d, --filter-disk NAME", "-f") " Process only files in the specified disk\n");
fout(" " SWITCH_GETOPT_LONG("-m, --filter-missing ", "-m") " Process only missing/deleted files\n");
fout(" " SWITCH_GETOPT_LONG("-e, --filter-error ", "-e") " Process only files with errors\n");
fout(" " SWITCH_GETOPT_LONG("-p, --percentage PERC ", "-p") " Process only a part of the array\n");
fout(" " SWITCH_GETOPT_LONG("-o, --older-than DAYS ", "-o") " Process only the older part of the array\n");
fout(" " SWITCH_GETOPT_LONG("-i, --import DIR ", "-i") " Import deleted files\n");
fout(" " SWITCH_GETOPT_LONG("-l, --log FILE ", "-l") " Log file. Default none\n");
fout(" " SWITCH_GETOPT_LONG("-a, --audit-only ", "-a") " Check only file data and not parity\n");
fout(" " SWITCH_GETOPT_LONG("-h, --pre-hash ", "-h") " Pre hash all the new data\n");
fout(" " SWITCH_GETOPT_LONG("-Z, --force-zero ", "-Z") " Force synching of files that get zero size\n");
fout(" " SWITCH_GETOPT_LONG("-E, --force-empty ", "-E") " Force synching of disks that get empty\n");
fout(" " SWITCH_GETOPT_LONG("-U, --force-uuid ", "-U") " Force commands on disks with uuid changed\n");
fout(" " SWITCH_GETOPT_LONG("-D, --force-device ", "-D") " Force commands on disks with same device id\n");
fout(" " SWITCH_GETOPT_LONG("-N, --force-nocopy ", "-N") " Force commands disabling the copy detection\n");
fout(" " SWITCH_GETOPT_LONG("-F, --force-full ", "-F") " Force commands requiring a full sync\n");
fout(" " SWITCH_GETOPT_LONG("-v, --verbose ", "-v") " Verbose\n");
printf("Usage: " PACKAGE " status|diff|sync|scrub|list|dup|up|down|smart|pool|check|fix [options]\n");
printf("\n");
printf("Commands:\n");
printf(" status Print the status of the array\n");
printf(" diff Show the changes that needs to be syncronized\n");
printf(" sync Syncronize the state of the array\n");
printf(" scrub Scrub the array\n");
printf(" list List the array content\n");
printf(" dup Find duplicate files\n");
printf(" up Spinup the array\n");
printf(" down Spindown the array\n");
printf(" smart SMART attributes of the array\n");
printf(" pool Create or update the virtual view of the array\n");
printf(" check Check the array\n");
printf(" fix Fix the array\n");
printf("\n");
printf("Options:\n");
printf(" " SWITCH_GETOPT_LONG("-c, --conf FILE ", "-c") " Configuration file\n");
printf(" " SWITCH_GETOPT_LONG("-f, --filter PATTERN ", "-f") " Process only files matching the pattern\n");
printf(" " SWITCH_GETOPT_LONG("-d, --filter-disk NAME", "-f") " Process only files in the specified disk\n");
printf(" " SWITCH_GETOPT_LONG("-m, --filter-missing ", "-m") " Process only missing/deleted files\n");
printf(" " SWITCH_GETOPT_LONG("-e, --filter-error ", "-e") " Process only files with errors\n");
printf(" " SWITCH_GETOPT_LONG("-p, --percentage PERC ", "-p") " Process only a part of the array\n");
printf(" " SWITCH_GETOPT_LONG("-o, --older-than DAYS ", "-o") " Process only the older part of the array\n");
printf(" " SWITCH_GETOPT_LONG("-i, --import DIR ", "-i") " Import deleted files\n");
printf(" " SWITCH_GETOPT_LONG("-l, --log FILE ", "-l") " Log file. Default none\n");
printf(" " SWITCH_GETOPT_LONG("-a, --audit-only ", "-a") " Check only file data and not parity\n");
printf(" " SWITCH_GETOPT_LONG("-h, --pre-hash ", "-h") " Pre hash all the new data\n");
printf(" " SWITCH_GETOPT_LONG("-Z, --force-zero ", "-Z") " Force synching of files that get zero size\n");
printf(" " SWITCH_GETOPT_LONG("-E, --force-empty ", "-E") " Force synching of disks that get empty\n");
printf(" " SWITCH_GETOPT_LONG("-U, --force-uuid ", "-U") " Force commands on disks with uuid changed\n");
printf(" " SWITCH_GETOPT_LONG("-D, --force-device ", "-D") " Force commands on disks with same device id\n");
printf(" " SWITCH_GETOPT_LONG("-N, --force-nocopy ", "-N") " Force commands disabling the copy detection\n");
printf(" " SWITCH_GETOPT_LONG("-F, --force-full ", "-F") " Force commands requiring a full sync\n");
printf(" " SWITCH_GETOPT_LONG("-v, --verbose ", "-v") " Verbose\n");
}
void memory(void)
{
ftag("memory:used:%" PRIu64 "\n", (uint64_t)malloc_counter());
fout("Using %u MiB of memory.\n", (unsigned)(malloc_counter() / 1024 / 1024));
msg_tag("memory:used:%" PRIu64 "\n", (uint64_t)malloc_counter());
msg_progress("Using %u MiB of memory.\n", (unsigned)(malloc_counter() / 1024 / 1024));
}
/****************************************************************************/
@ -146,7 +146,7 @@ void log_open(const char* log)
break;
default :
/* LCOV_EXCL_START */
ferr("Invalid type specifier '%c' in the log file.\n", *log);
msg_error("Invalid type specifier '%c' in the log file.\n", *log);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -161,7 +161,7 @@ void log_open(const char* log)
stdlog = fopen(path, mode);
if (!stdlog) {
/* LCOV_EXCL_START */
ferr("Error opening the log file '%s'. %s.\n", path, strerror(errno));
msg_error("Error opening the log file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -172,7 +172,7 @@ void log_close(const char* log)
if (stdlog != stdout && stdlog != stderr && stdlog != 0) {
if (fclose(stdlog) != 0) {
/* LCOV_EXCL_START */
ferr("Error closing the log file '%s'. %s.\n", log, strerror(errno));
msg_error("Error closing the log file '%s'. %s.\n", log, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -451,7 +451,7 @@ int main(int argc, char* argv[])
struct snapraid_filter* filter = filter_alloc_file(1, optarg);
if (!filter) {
/* LCOV_EXCL_START */
ferr("Invalid filter specification '%s'\n", optarg);
msg_error("Invalid filter specification '%s'\n", optarg);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -461,7 +461,7 @@ int main(int argc, char* argv[])
struct snapraid_filter* filter = filter_alloc_disk(1, optarg);
if (!filter) {
/* LCOV_EXCL_START */
ferr("Invalid filter specification '%s'\n", optarg);
msg_error("Invalid filter specification '%s'\n", optarg);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -481,7 +481,7 @@ int main(int argc, char* argv[])
percentage = strtoul(optarg, &e, 10);
if (!e || *e || percentage > 100) {
/* LCOV_EXCL_START */
ferr("Invalid percentage '%s'\n", optarg);
msg_error("Invalid percentage '%s'\n", optarg);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -490,7 +490,7 @@ int main(int argc, char* argv[])
olderthan = strtoul(optarg, &e, 10);
if (!e || *e || olderthan > 1000) {
/* LCOV_EXCL_START */
ferr("Invalid number of days '%s'\n", optarg);
msg_error("Invalid number of days '%s'\n", optarg);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -499,7 +499,7 @@ int main(int argc, char* argv[])
blockstart = strtoul(optarg, &e, 0);
if (!e || *e) {
/* LCOV_EXCL_START */
ferr("Invalid start position '%s'\n", optarg);
msg_error("Invalid start position '%s'\n", optarg);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -508,7 +508,7 @@ int main(int argc, char* argv[])
blockcount = strtoul(optarg, &e, 0);
if (!e || *e) {
/* LCOV_EXCL_START */
ferr("Invalid count number '%s'\n", optarg);
msg_error("Invalid count number '%s'\n", optarg);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -517,7 +517,7 @@ int main(int argc, char* argv[])
opt.io_error_limit = strtoul(optarg, &e, 0);
if (!e || *e) {
/* LCOV_EXCL_START */
ferr("Invalid error limit number '%s'\n", optarg);
msg_error("Invalid error limit number '%s'\n", optarg);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -525,7 +525,7 @@ int main(int argc, char* argv[])
case 'i' :
if (import_timestamp) {
/* LCOV_EXCL_START */
ferr("Import directory '%s' already specified as '%s'\n", optarg, import_timestamp);
msg_error("Import directory '%s' already specified as '%s'\n", optarg, import_timestamp);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -534,7 +534,7 @@ int main(int argc, char* argv[])
case OPT_TEST_IMPORT_CONTENT :
if (import_content) {
/* LCOV_EXCL_START */
ferr("Import directory '%s' already specified as '%s'\n", optarg, import_content);
msg_error("Import directory '%s' already specified as '%s'\n", optarg, import_content);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -543,7 +543,7 @@ int main(int argc, char* argv[])
case 'l' :
if (log) {
/* LCOV_EXCL_START */
ferr("Log file '%s' already specified as '%s'\n", optarg, log);
msg_error("Log file '%s' already specified as '%s'\n", optarg, log);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -574,10 +574,10 @@ int main(int argc, char* argv[])
opt.prehash = 1;
break;
case 'v' :
opt.verbose = 1;
++msg_level;
break;
case 'q' :
opt.quiet = 1;
--msg_level;
break;
case 'G' :
opt.gui = 1;
@ -680,7 +680,7 @@ int main(int argc, char* argv[])
break;
default :
/* LCOV_EXCL_START */
ferr("Unknown option '%c'\n", (char)c);
msg_error("Unknown option '%c'\n", (char)c);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -746,7 +746,7 @@ int main(int argc, char* argv[])
operation = OPERATION_SMART;
} else {
/* LCOV_EXCL_START */
ferr("Unknown command '%s'\n", argv[optind]);
msg_error("Unknown command '%s'\n", argv[optind]);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -758,7 +758,7 @@ int main(int argc, char* argv[])
default :
if (opt.auditonly) {
/* LCOV_EXCL_START */
ferr("You cannot use -a, --audit-only with the '%s' command\n", command);
msg_error("You cannot use -a, --audit-only with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -772,7 +772,7 @@ int main(int argc, char* argv[])
default :
if (opt.force_nocopy) {
/* LCOV_EXCL_START */
ferr("You cannot use -N, --force-nocopy with the '%s' command\n", command);
msg_error("You cannot use -N, --force-nocopy with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -784,14 +784,14 @@ int main(int argc, char* argv[])
default :
if (opt.prehash) {
/* LCOV_EXCL_START */
ferr("You cannot use -h, --pre-hash with the '%s' command\n", command);
msg_error("You cannot use -h, --pre-hash with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (opt.force_full) {
/* LCOV_EXCL_START */
ferr("You cannot use -F, --force-full with the '%s' command\n", command);
msg_error("You cannot use -F, --force-full with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -799,14 +799,14 @@ int main(int argc, char* argv[])
if (opt.force_full && opt.force_nocopy) {
/* LCOV_EXCL_START */
ferr("You cannot use the -F, --force-full and -N, --force-nocopy options at the same time\n");
msg_error("You cannot use the -F, --force-full and -N, --force-nocopy options at the same time\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (opt.prehash && opt.force_nocopy) {
/* LCOV_EXCL_START */
ferr("You cannot use the -h, --pre-hash and -N, --force-nocopy options at the same time\n");
msg_error("You cannot use the -h, --pre-hash and -N, --force-nocopy options at the same time\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -819,25 +819,25 @@ int main(int argc, char* argv[])
default :
if (!tommy_list_empty(&filterlist_file)) {
/* LCOV_EXCL_START */
ferr("You cannot use -f, --filter with the '%s' command\n", command);
msg_error("You cannot use -f, --filter with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (!tommy_list_empty(&filterlist_disk)) {
/* LCOV_EXCL_START */
ferr("You cannot use -d, --filter-disk with the '%s' command\n", command);
msg_error("You cannot use -d, --filter-disk with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (filter_missing != 0) {
/* LCOV_EXCL_START */
ferr("You cannot use -m, --filter-missing with the '%s' command\n", command);
msg_error("You cannot use -m, --filter-missing with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (filter_error != 0) {
/* LCOV_EXCL_START */
ferr("You cannot use -e, --filter-error with the '%s' command\n", command);
msg_error("You cannot use -e, --filter-error with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -850,7 +850,7 @@ int main(int argc, char* argv[])
default :
if (import_timestamp != 0 || import_content != 0) {
/* LCOV_EXCL_START */
ferr("You cannot import with the '%s' command\n", command);
msg_error("You cannot import with the '%s' command\n", command);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -911,17 +911,17 @@ int main(int argc, char* argv[])
/* print generic info into the log */
t = time(0);
tm = localtime(&t);
ftag("version:%s\n", PACKAGE_VERSION);
ftag("unixtime:%" PRIi64 "\n", (int64_t)t);
msg_tag("version:%s\n", PACKAGE_VERSION);
msg_tag("unixtime:%" PRIi64 "\n", (int64_t)t);
if (tm) {
char datetime[64];
strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", tm);
ftag("time:%s\n", datetime);
msg_tag("time:%s\n", datetime);
}
ftag("command:%s\n", command);
msg_tag("command:%s\n", command);
for (i = 0; i < argc; ++i)
ftag("argv:%u:%s\n", i, argv[i]);
fflush_log();
msg_tag("argv:%u:%s\n", i, argv[i]);
msg_flush();
if (!opt.skip_self)
selftest();
@ -941,10 +941,10 @@ int main(int argc, char* argv[])
if (lock == -1) {
/* LCOV_EXCL_START */
if (errno != EWOULDBLOCK) {
ferr("Error creating the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
msg_error("Error creating the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
} else {
ferr("The lock file '%s' is already locked!\n", state.lockfile);
ferr("SnapRAID is already in use!\n");
msg_error("The lock file '%s' is already locked!\n", state.lockfile);
msg_error("SnapRAID is already in use!\n");
}
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
@ -1002,7 +1002,7 @@ int main(int argc, char* argv[])
ret = system(run); /* ignore error */
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Error in running command '%s'.\n", run);
msg_error("Error in running command '%s'.\n", run);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1158,7 +1158,7 @@ int main(int argc, char* argv[])
if (!opt.skip_lock) {
if (lock_unlock(lock) == -1) {
/* LCOV_EXCL_START */
ferr("Error closing the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
msg_error("Error closing the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}

File diff suppressed because it is too large Load diff

View file

@ -61,8 +61,6 @@ extern volatile int global_interrupt;
* For all these options a value of 0 means nothing set, and to use the default.
*/
struct snapraid_option {
int verbose; /**< Verbose output. */
int quiet; /**< Quiet output. */
int gui; /**< Gui output. */
int auditonly; /**< In check, checks only the hash and not the parity. */
int badonly; /**< In fix, fixes only the blocks marked as bad. */

View file

@ -82,20 +82,20 @@ int state_status(struct snapraid_state* state)
blockmax = parity_allocated_size(state);
ftag("summary:block_size:%u\n", state->block_size);
ftag("summary:parity_block_count:%u\n", blockmax);
msg_tag("summary:block_size:%u\n", state->block_size);
msg_tag("summary:parity_block_count:%u\n", blockmax);
/* get the minimum parity free space */
parity_block_free = state->parity[0].free_blocks;
for (l = 0; l < state->level; ++l) {
ftag("summary:parity_block_total:%s:%u\n", lev_config_name(l), state->parity[l].total_blocks);
ftag("summary:parity_block_free:%s:%u\n", lev_config_name(l), state->parity[l].free_blocks);
msg_tag("summary:parity_block_total:%s:%u\n", lev_config_name(l), state->parity[l].total_blocks);
msg_tag("summary:parity_block_free:%s:%u\n", lev_config_name(l), state->parity[l].free_blocks);
if (state->parity[l].free_blocks < parity_block_free)
parity_block_free = state->parity[l].free_blocks;
if (state->parity[l].free_blocks != 0)
free_not_zero = 1;
}
ftag("summary:parity_block_free_min:%u\n", parity_block_free);
msg_tag("summary:parity_block_free_min:%u\n", parity_block_free);
printf("SnapRAID status report:\n");
printf("\n");
@ -211,18 +211,18 @@ int state_status(struct snapraid_state* state)
printf(" %3u%%", perc(disk_block_count, disk_block_max));
printf(" %s\n", disk->name);
ftag("summary:disk_file_count:%s:%u\n", disk->name, disk_file_count);
ftag("summary:disk_block_count:%s:%u\n", disk->name, disk_block_count);
ftag("summary:disk_fragmented_file_count:%s:%u\n", disk->name, disk_file_fragmented);
ftag("summary:disk_excess_fragment_count:%s:%u\n", disk->name, disk_extra_fragment);
ftag("summary:disk_file_size:%s:%" PRIu64 "\n", disk->name, disk_file_size);
ftag("summary:disk_block_allocated:%s:%u\n", disk->name, disk_block_latest_used + 1);
ftag("summary:disk_block_total:%s:%u\n", disk->name, disk->total_blocks);
ftag("summary:disk_block_free:%s:%u\n", disk->name, disk->free_blocks);
ftag("summary:disk_block_max_by_space:%s:%u\n", disk->name, disk_block_max_by_space);
ftag("summary:disk_block_max_by_parity:%s:%u\n", disk->name, disk_block_max_by_parity);
ftag("summary:disk_block_max:%s:%u\n", disk->name, disk_block_max);
ftag("summary:disk_space_wasted:%s:%" PRId64 "\n", disk->name, wasted);
msg_tag("summary:disk_file_count:%s:%u\n", disk->name, disk_file_count);
msg_tag("summary:disk_block_count:%s:%u\n", disk->name, disk_block_count);
msg_tag("summary:disk_fragmented_file_count:%s:%u\n", disk->name, disk_file_fragmented);
msg_tag("summary:disk_excess_fragment_count:%s:%u\n", disk->name, disk_extra_fragment);
msg_tag("summary:disk_file_size:%s:%" PRIu64 "\n", disk->name, disk_file_size);
msg_tag("summary:disk_block_allocated:%s:%u\n", disk->name, disk_block_latest_used + 1);
msg_tag("summary:disk_block_total:%s:%u\n", disk->name, disk->total_blocks);
msg_tag("summary:disk_block_free:%s:%u\n", disk->name, disk->free_blocks);
msg_tag("summary:disk_block_max_by_space:%s:%u\n", disk->name, disk_block_max_by_space);
msg_tag("summary:disk_block_max_by_parity:%s:%u\n", disk->name, disk_block_max_by_parity);
msg_tag("summary:disk_block_max:%s:%u\n", disk->name, disk_block_max);
msg_tag("summary:disk_space_wasted:%s:%" PRId64 "\n", disk->name, wasted);
}
/* totals */
@ -240,17 +240,17 @@ int state_status(struct snapraid_state* state)
if (!free_not_zero)
printf("\nWARNING! Free space info will be valid after the first sync.\n");
ftag("summary:file_count:%u\n", file_count);
ftag("summary:file_block_count:%" PRIu64 "\n", file_block_count);
ftag("summary:fragmented_file_count:%u\n", file_fragmented);
ftag("summary:excess_fragment_count:%u\n", extra_fragment);
ftag("summary:file_size:%" PRIu64 "\n", file_size);
ftag("summary:parity_size:%" PRIu64 "\n", blockmax * (uint64_t)state->block_size);
ftag("summary:parity_size_max:%" PRIu64 "\n", (blockmax + parity_block_free) * (uint64_t)state->block_size);
ftag("summary:hash:%s\n", hash_config_name(state->hash));
ftag("summary:prev_hash:%s\n", hash_config_name(state->prevhash));
ftag("summary:best_hash:%s\n", hash_config_name(state->besthash));
fflush_log();
msg_tag("summary:file_count:%u\n", file_count);
msg_tag("summary:file_block_count:%" PRIu64 "\n", file_block_count);
msg_tag("summary:fragmented_file_count:%u\n", file_fragmented);
msg_tag("summary:excess_fragment_count:%u\n", extra_fragment);
msg_tag("summary:file_size:%" PRIu64 "\n", file_size);
msg_tag("summary:parity_size:%" PRIu64 "\n", blockmax * (uint64_t)state->block_size);
msg_tag("summary:parity_size_max:%" PRIu64 "\n", (blockmax + parity_block_free) * (uint64_t)state->block_size);
msg_tag("summary:hash:%s\n", hash_config_name(state->hash));
msg_tag("summary:prev_hash:%s\n", hash_config_name(state->prevhash));
msg_tag("summary:best_hash:%s\n", hash_config_name(state->besthash));
msg_flush();
/* copy the info a temp vector, and count bad/rehash/unsynced blocks */
infomap = malloc_nofail(blockmax * sizeof(snapraid_info));
@ -260,7 +260,7 @@ int state_status(struct snapraid_state* state)
count = 0;
rehash = 0;
unsynced_blocks = 0;
ftag("block_count:%u\n", blockmax);
msg_tag("block_count:%u\n", blockmax);
for (i = 0; i < blockmax; ++i) {
int one_invalid;
int one_valid;
@ -302,19 +302,19 @@ int state_status(struct snapraid_state* state)
if (state->opt.gui) {
if (info != 0)
ftag("block:%u:%" PRIu64 ":%s:%s:%s:%s\n", i, (uint64_t)info_get_time(info), one_valid ? "used" : "", one_invalid ? "unsynced" : "", info_get_bad(info) ? "bad" : "", info_get_rehash(info) ? "rehash" : "");
msg_tag("block:%u:%" PRIu64 ":%s:%s:%s:%s\n", i, (uint64_t)info_get_time(info), one_valid ? "used" : "", one_invalid ? "unsynced" : "", info_get_bad(info) ? "bad" : "", info_get_rehash(info) ? "rehash" : "");
else
ftag("block_noinfo:%u:%s:%s\n", i, one_valid ? "used" : "", one_invalid ? "unsynced" : "");
msg_tag("block_noinfo:%u:%s:%s\n", i, one_valid ? "used" : "", one_invalid ? "unsynced" : "");
}
}
ftag("summary:has_unsynced:%u\n", unsynced_blocks);
ftag("summary:has_rehash:%u\n", rehash);
ftag("summary:has_bad:%u:%u:%u\n", bad, bad_first, bad_last);
fflush_log();
msg_tag("summary:has_unsynced:%u\n", unsynced_blocks);
msg_tag("summary:has_rehash:%u\n", rehash);
msg_tag("summary:has_bad:%u:%u:%u\n", bad, bad_first, bad_last);
msg_flush();
if (!count) {
ferr("The array is empty.\n");
msg_error("The array is empty.\n");
free(infomap);
return 0;
}
@ -324,12 +324,12 @@ int state_status(struct snapraid_state* state)
/* output the info map */
i = 0;
ftag("info_count:%u\n", count);
msg_tag("info_count:%u\n", count);
while (i < count) {
unsigned j = i + 1;
while (j < count && info_get_time(infomap[i]) == info_get_time(infomap[j]))
++j;
ftag("info_time:%" PRIu64 ":%u\n", (uint64_t)info_get_time(infomap[i]), j - i);
msg_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)info_get_time(infomap[i]), j - i);
i = j;
}

View file

@ -22,34 +22,18 @@
/****************************************************************************/
/* print */
void fout(const char* format, ...)
int msg_level = 0;
void msg_error(const char* format, ...)
{
va_list ap;
/* first output the same message to stdlog and flush it */
/* to have the same behaviour of stdout */
/* to avoid to mix messages in case streams are redirected */
/* to the same file */
if (stdlog) {
va_start(ap, format);
fprintf(stdlog, "stdout: ");
vfprintf(stdlog, format, ap);
va_end(ap);
fflush(stdlog);
}
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
}
void ferr(const char* format, ...)
{
va_list ap;
/* first output the same message to stdlog and flush it */
/* to have the same behaviour of stderr */
if (stdlog) {
va_start(ap, format);
fprintf(stdlog, "stderr: ");
fprintf(stdlog, "msg:error: ");
vfprintf(stdlog, format, ap);
fflush(stdlog);
va_end(ap);
@ -60,13 +44,13 @@ void ferr(const char* format, ...)
va_end(ap);
}
void flog(const char* format, ...)
void msg_warning(const char* format, ...)
{
va_list ap;
if (stdlog) {
va_start(ap, format);
fprintf(stdlog, "stdlog: ");
fprintf(stdlog, "msg:warning: ");
vfprintf(stdlog, format, ap);
va_start(ap, format);
} else {
@ -76,13 +60,7 @@ void flog(const char* format, ...)
}
}
void fflush_log(void)
{
if (stdlog)
fflush(stdlog);
}
void ftag(const char* format, ...)
void msg_tag(const char* format, ...)
{
va_list ap;
@ -93,6 +71,107 @@ void ftag(const char* format, ...)
}
}
void msg_status(const char* format, ...)
{
va_list ap;
/* first output the same message to stdlog and flush it */
/* to avoid to mix messages in case streams are redirected */
/* to the same file */
if (stdlog) {
va_start(ap, format);
fprintf(stdlog, "msg:status: ");
vfprintf(stdlog, format, ap);
va_end(ap);
fflush(stdlog);
}
if (msg_level >= MSG_STATUS) {
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
}
}
void msg_info(const char* format, ...)
{
va_list ap;
/* don't output in stdlog as these messages */
/* are always paired with a msg_tag() call */
if (msg_level >= MSG_INFO) {
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
}
}
void msg_progress(const char* format, ...)
{
va_list ap;
/* first output the same message to stdlog and flush it */
/* to avoid to mix messages in case streams are redirected */
/* to the same file */
if (stdlog) {
va_start(ap, format);
fprintf(stdlog, "msg:progress: ");
vfprintf(stdlog, format, ap);
va_end(ap);
fflush(stdlog);
}
if (msg_level >= MSG_PROGRESS) {
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
}
}
void msg_bar(const char* format, ...)
{
va_list ap;
/* don't output in stdlog as these messages */
/* are intended for screen only */
if (msg_level >= MSG_BAR) {
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
}
}
void msg_verbose(const char* format, ...)
{
va_list ap;
/* first output the same message to stdlog and flush it */
/* to avoid to mix messages in case streams are redirected */
/* to the same file */
if (stdlog) {
va_start(ap, format);
fprintf(stdlog, "msg:verbose: ");
vfprintf(stdlog, format, ap);
va_end(ap);
fflush(stdlog);
}
if (msg_level >= MSG_VERBOSE) {
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
}
}
void msg_flush(void)
{
if (stdlog)
fflush(stdlog);
fflush(stdout);
}
/**
* Number of buffers for esc().
*/
@ -157,7 +236,7 @@ const char* esc(const char* str)
bail:
/* LCOV_EXCL_START */
ferr("Escape too long\n");
msg_error("Escape too long\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -171,7 +250,7 @@ void pathcpy(char* dst, size_t size, const char* src)
if (len + 1 > size) {
/* LCOV_EXCL_START */
ferr("Path too long\n");
msg_error("Path too long\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -186,7 +265,7 @@ void pathcat(char* dst, size_t size, const char* src)
if (dst_len + src_len + 1 > size) {
/* LCOV_EXCL_START */
ferr("Path too long\n");
msg_error("Path too long\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -200,7 +279,7 @@ void pathcatc(char* dst, size_t size, char c)
if (dst_len + 2 > size) {
/* LCOV_EXCL_START */
ferr("Path too long\n");
msg_error("Path too long\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -248,7 +327,7 @@ void pathprint(char* dst, size_t size, const char* format, ...)
if (len >= size) {
/* LCOV_EXCL_START */
ferr("Path too long\n");
msg_error("Path too long\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -261,7 +340,7 @@ void pathslash(char* dst, size_t size)
if (len > 0 && dst[len - 1] != '/') {
if (len + 2 >= size) {
/* LCOV_EXCL_START */
ferr("Path too long\n");
msg_error("Path too long\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -356,7 +435,7 @@ int mkancestor(const char* file)
/* create it */
if (mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
/* LCOV_EXCL_START */
ferr("Error creating directory '%s'. %s.\n", dir, strerror(errno));
msg_error("Error creating directory '%s'. %s.\n", dir, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -612,14 +691,14 @@ int smartctl_attribute(FILE* f, uint64_t* smart, char* serial)
} else if (inside) {
if (sscanf(s, "%u %*s %*s %*s %*s %*s %*s %*s %*s %" SCNu64, &id, &raw) != 2) {
/* LCOV_EXCL_START */
ferr("Invalid smartctl line '%s'.\n", s);
msg_error("Invalid smartctl line '%s'.\n", s);
return -1;
/* LCOV_EXCL_STOP */
}
if (id >= 256) {
/* LCOV_EXCL_START */
ferr("Invalid SMART id '%u'.\n", id);
msg_error("Invalid SMART id '%u'.\n", id);
return -1;
/* LCOV_EXCL_STOP */
}

View file

@ -22,48 +22,106 @@
/* log */
/**
* Output messages targgeted for the screen.
* Fatal messages.
*
* Messages are in human readable format.
* They must include the full line output and terminate with '\n'.
* Messages printed before an early termination.
*
* These messages go in the log file and in stdout.
* These messages go in the log file and in stderr inconditionally.
*/
void fout(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
void msg_error(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Error messages printed before an early termination.
* Warning messages.
*
* Messages are in human readable format.
* They must include the full line output and terminate with '\n'.
* Messages reporting warnings or error conditions that don't prevent the program to run.
*
* These messages go in the log file and in stderr.
* Some of them could be also serious errors, like "silent errors".
* The summary results is anyway always printed with as errors.
*
* These messages go in the log file if specified, otherwise they go in stderr.
*/
void ferr(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Log messages printed after an error.
*
* Messages are in human readable format.
* They must include the full line output and terminate with '\n'.
*
* These messages go in the log file if specified, otherwise in stderr.
*/
void flog(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Flush the log output.
*/
void fflush_log(void);
void msg_warning(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Tag messages.
*
* Messages are in tag format, like "tag:entry:...".
*
* These messages go in the log file.
* These messages neves go on the screen, but only in the log file if specified.
*
* Note that this function, allows not \n terminated strings.
*/
void ftag(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
void msg_tag(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Message levels.
*
* The levels control the amount of information printed on the screen.
* Note that msg_error(), msg_warning() and msg_tag() are not influenced by this option.
*
* From the most quiet to the most verbose.
*/
#define MSG_STATUS -3
#define MSG_INFO -2
#define MSG_PROGRESS -1
#define MSG_BAR 0
#define MSG_VERBOSE 1
/**
* Selected message level.
*/
extern int msg_level;
/**
* State messages.
*
* Messages that tell what the program is doing or did, but limited to few lines.
* They are status information, and summary results.
*/
void msg_status(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Info messages.
*
* Messages that tell what was done.
* Potentially a lot of messages are possible. They can still be on the screen,
* as losing them we don't lose information.
*
* These messages never go in the log file, becauae there is always a corresponding msg_tag().
*/
void msg_info(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Progress messages.
*
* Message that tell the progress of program.
*
* These messages also go in the log file.
*/
void msg_progress(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Progress bar messages.
*
* Message that show the percentage of the progress.
*
* These messages never go in the log file.
*/
void msg_bar(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Verbose messages.
*
* Message that tell what is already expected.
*
* These messages also go in the log file.
*/
void msg_verbose(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
/**
* Flush the output.
*/
void msg_flush(void);
/**
* Pointer to log function.

View file

@ -132,44 +132,44 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
/* This one is really an unexpected error, because we are only reading */
/* and closing a descriptor should never fail */
if (errno == EIO) {
ftag("error:%u:%s:%s: Close EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Close EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
}
ftag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that file '%s' can be accessed.\n", handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that file '%s' can be accessed.\n", handle[j].path);
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
}
}
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, flog);
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, msg_warning);
if (ret == -1) {
/* file we have tried to open for error reporting */
struct snapraid_file* file = block_file_get(block);
if (errno == EIO) {
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected input/output open error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected input/output open error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
/* LCOV_EXCL_STOP */
}
if (errno == ENOENT) {
ftag("error:%u:%s:%s: Open ENOENT error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
flog("Missing file '%s'.\n", handle[j].path);
flog("WARNING! You cannot modify data disk during a sync.\n");
flog("Rerun the sync command when finished.\n");
msg_tag("error:%u:%s:%s: Open ENOENT error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_warning("Missing file '%s'.\n", handle[j].path);
msg_warning("WARNING! You cannot modify data disk during a sync.\n");
msg_warning("Rerun the sync command when finished.\n");
++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 */
@ -177,20 +177,20 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
}
if (errno == EACCES) {
ftag("error:%u:%s:%s: Open EACCES error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
flog("No access at file '%s'.\n", handle[j].path);
flog("WARNING! Please fix the access permission in the data disk.\n");
flog("Rerun the sync command when finished.\n");
msg_tag("error:%u:%s:%s: Open EACCES error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_warning("No access at file '%s'.\n", handle[j].path);
msg_warning("WARNING! Please fix the access permission in the data disk.\n");
msg_warning("Rerun the sync command when finished.\n");
++error;
/* this isn't a serious error, so we skip this block, and continue with others */
continue;
}
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("WARNING! Unexpected open error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that file '%s' can be accessed.\n", handle[j].path);
ferr("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
msg_tag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("WARNING! Unexpected open error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that file '%s' can be accessed.\n", handle[j].path);
msg_error("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -204,41 +204,41 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
) {
/* file we are processing for error reporting */
struct snapraid_file* file = block_file_get(block);
ftag("error:%u:%s:%s: Unexpected attribute change\n", i, disk->name, esc(file->sub));
msg_tag("error:%u:%s:%s: Unexpected attribute change\n", i, disk->name, esc(file->sub));
if (handle[j].st.st_size != file->size) {
flog("Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 ".\n", handle[j].path, file->size, handle[j].st.st_size);
msg_warning("Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 ".\n", handle[j].path, file->size, handle[j].st.st_size);
} else if (handle[j].st.st_mtime != file->mtime_sec
|| STAT_NSEC(&handle[j].st) != file->mtime_nsec) {
flog("Unexpected time change at file '%s' from %" PRIu64 ".%d to %" PRIu64 ".%d.\n", handle[j].path, file->mtime_sec, file->mtime_nsec, (uint64_t)handle[j].st.st_mtime, (uint32_t)STAT_NSEC(&handle[j].st));
msg_warning("Unexpected time change at file '%s' from %" PRIu64 ".%d to %" PRIu64 ".%d.\n", handle[j].path, file->mtime_sec, file->mtime_nsec, (uint64_t)handle[j].st.st_mtime, (uint32_t)STAT_NSEC(&handle[j].st));
} else {
flog("Unexpected inode change from %" PRIu64 " to %" PRIu64 " at file '%s'.\n", file->inode, (uint64_t)handle[j].st.st_ino, handle[j].path);
msg_warning("Unexpected inode change from %" PRIu64 " to %" PRIu64 " at file '%s'.\n", file->inode, (uint64_t)handle[j].st.st_ino, handle[j].path);
}
flog("WARNING! You cannot modify files during a sync.\n");
flog("Rerun the sync command when finished.\n");
msg_warning("WARNING! You cannot modify files during a sync.\n");
msg_warning("Rerun the sync command when finished.\n");
++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 */
continue;
}
read_size = handle_read(&handle[j], block, buffer, state->block_size, ferr);
read_size = handle_read(&handle[j], block, buffer, state->block_size, msg_error);
if (read_size == -1) {
/* LCOV_EXCL_START */
/* file we are processing for error reporting */
struct snapraid_file* file = block_file_get(block);
if (errno == EIO) {
ftag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
ferr("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
msg_error("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
}
ftag("error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
ferr("WARNING! Unexpected read error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that file '%s' can be read.\n", handle[j].path);
ferr("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
msg_tag("error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
msg_error("WARNING! Unexpected read error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that file '%s' can be read.\n", handle[j].path);
msg_error("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -287,18 +287,18 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
/* This one is really an unexpected error, because we are only reading */
/* and closing a descriptor should never fail */
if (errno == EIO) {
ftag("error:%u:%s:%s: Close EIO error. %s\n", blockmax, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", blockmax);
msg_tag("error:%u:%s:%s: Close EIO error. %s\n", blockmax, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", blockmax);
++io_error;
goto bail;
}
ftag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc(file->sub), strerror(errno));
ferr("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that file '%s' can be accessed.\n", handle[j].path);
ferr("Stopping at block %u\n", blockmax);
msg_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc(file->sub), strerror(errno));
msg_error("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that file '%s' can be accessed.\n", handle[j].path);
msg_error("Stopping at block %u\n", blockmax);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -310,18 +310,22 @@ end:
state_progress_end(state, countpos, countmax, countsize);
if (error || io_error) {
fout("\n");
fout("%8u file errors\n", error);
fout("%8u io errors\n", io_error);
fout("WARNING! There are errors!\n");
msg_status("\n");
msg_status("%8u file errors\n", error);
msg_status("%8u io errors\n", io_error);
} else {
/* print the result only if processed something */
if (countpos != 0)
fout("Everything OK\n");
msg_status("Everything OK\n");
}
ftag("hash_summary:error_file:%u\n", error);
ftag("hash_summary:error_io:%u\n", io_error);
if (error)
msg_error("WARNING! Unexpected file errors!\n");
if (io_error)
msg_error("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
msg_tag("hash_summary:error_file:%u\n", error);
msg_tag("hash_summary:error_io:%u\n", io_error);
/* proceed without bailing out */
goto finish;
@ -336,8 +340,8 @@ bail:
struct snapraid_disk* disk = handle[j].disk;
ret = handle_close(&handle[j]);
if (ret == -1) {
ftag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected close error in a data disk.\n");
msg_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected close error in a data disk.\n");
++error;
/* continue, as we are already exiting */
}
@ -602,44 +606,44 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
/* This one is really an unexpected error, because we are only reading */
/* and closing a descriptor should never fail */
if (errno == EIO) {
ftag("error:%u:%s:%s: Close EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Close EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
}
ftag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that file '%s' can be accessed.\n", handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that file '%s' can be accessed.\n", handle[j].path);
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
}
}
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, flog);
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, msg_warning);
if (ret == -1) {
/* file we have tried to open for error reporting */
struct snapraid_file* file = block_file_get(block);
if (errno == EIO) {
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected input/output open error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_tag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected input/output open error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
/* LCOV_EXCL_STOP */
}
if (errno == ENOENT) {
ftag("error:%u:%s:%s: Open ENOENT error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
flog("Missing file '%s'.\n", handle[j].path);
flog("WARNING! You cannot modify data disk during a sync.\n");
flog("Rerun the sync command when finished.\n");
msg_tag("error:%u:%s:%s: Open ENOENT error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_warning("Missing file '%s'.\n", handle[j].path);
msg_warning("WARNING! You cannot modify data disk during a sync.\n");
msg_warning("Rerun the sync command when finished.\n");
++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 */
@ -648,10 +652,10 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
}
if (errno == EACCES) {
ftag("error:%u:%s:%s: Open EACCES error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
flog("No access at file '%s'.\n", handle[j].path);
flog("WARNING! Please fix the access permission in the data disk.\n");
flog("Rerun the sync command when finished.\n");
msg_tag("error:%u:%s:%s: Open EACCES error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_warning("No access at file '%s'.\n", handle[j].path);
msg_warning("WARNING! Please fix the access permission in the data disk.\n");
msg_warning("Rerun the sync command when finished.\n");
++error;
/* this isn't a serious error, so we skip this block, and continue with others */
error_on_this_block = 1;
@ -659,10 +663,10 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
}
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("WARNING! Unexpected open error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that file '%s' can be accessed.\n", handle[j].path);
ferr("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
msg_tag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("WARNING! Unexpected open error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that file '%s' can be accessed.\n", handle[j].path);
msg_error("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -676,17 +680,17 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
) {
/* file we are processing for error reporting */
struct snapraid_file* file = block_file_get(block);
ftag("error:%u:%s:%s: Unexpected attribute change\n", i, disk->name, esc(file->sub));
msg_tag("error:%u:%s:%s: Unexpected attribute change\n", i, disk->name, esc(file->sub));
if (handle[j].st.st_size != file->size) {
flog("Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 ".\n", handle[j].path, file->size, handle[j].st.st_size);
msg_warning("Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 ".\n", handle[j].path, file->size, handle[j].st.st_size);
} else if (handle[j].st.st_mtime != file->mtime_sec
|| STAT_NSEC(&handle[j].st) != file->mtime_nsec) {
flog("Unexpected time change at file '%s' from %" PRIu64 ".%d to %" PRIu64 ".%d.\n", handle[j].path, file->mtime_sec, file->mtime_nsec, (uint64_t)handle[j].st.st_mtime, (uint32_t)STAT_NSEC(&handle[j].st));
msg_warning("Unexpected time change at file '%s' from %" PRIu64 ".%d to %" PRIu64 ".%d.\n", handle[j].path, file->mtime_sec, file->mtime_nsec, (uint64_t)handle[j].st.st_mtime, (uint32_t)STAT_NSEC(&handle[j].st));
} else {
flog("Unexpected inode change from %" PRIu64 " to %" PRIu64 " at file '%s'.\n", file->inode, (uint64_t)handle[j].st.st_ino, handle[j].path);
msg_warning("Unexpected inode change from %" PRIu64 " to %" PRIu64 " at file '%s'.\n", file->inode, (uint64_t)handle[j].st.st_ino, handle[j].path);
}
flog("WARNING! You cannot modify files during a sync.\n");
flog("Rerun the sync command when finished.\n");
msg_warning("WARNING! You cannot modify files during a sync.\n");
msg_warning("Rerun the sync command when finished.\n");
++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 */
@ -694,31 +698,31 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
continue;
}
read_size = handle_read(&handle[j], block, buffer[j], state->block_size, flog);
read_size = handle_read(&handle[j], block, buffer[j], state->block_size, msg_warning);
if (read_size == -1) {
/* LCOV_EXCL_START */
/* file we are processing for error reporting */
struct snapraid_file* file = block_file_get(block);
if (errno == EIO) {
ftag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
msg_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
if (io_error >= state->opt.io_error_limit) {
ferr("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, handle[j].path);
ferr("Stopping at block %u\n", i);
msg_error("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, handle[j].path);
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
}
flog("Input/Output error in file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
msg_warning("Input/Output error in file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
++io_error;
io_error_on_this_block = 1;
continue;
}
ftag("error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
ferr("WARNING! Unexpected read error in a data disk, it isn't possible to sync.\n");
ferr("Ensure that file '%s' can be read.\n", handle[j].path);
ferr("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
msg_tag("error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, esc(file->sub), block_file_pos(block), strerror(errno));
msg_error("WARNING! Unexpected read error in a data disk, it isn't possible to sync.\n");
msg_error("Ensure that file '%s' can be read.\n", handle[j].path);
msg_error("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -748,17 +752,17 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
/* if the file has invalid parity, it's a REP changed during the sync */
if (block_has_invalid_parity(block)) {
ftag("error:%u:%s:%s: Unexpected data change\n", i, disk->name, esc(file->sub));
flog("Data change at file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
flog("WARNING! Unexpected data modification of a file without parity!\n");
msg_tag("error:%u:%s:%s: Unexpected data change\n", i, disk->name, esc(file->sub));
msg_warning("Data change at file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
msg_warning("WARNING! Unexpected data modification of a file without parity!\n");
if (file_flag_has(file, FILE_IS_COPY)) {
flog("This file was detected as a copy of another file with the same name, size,\n");
flog("and timestamp, but the file data isn't matching the assumed copy.\n");
flog("If this is a false positive, and the files are expected to be different,\n");
flog("you can 'sync' anyway using 'snapraid --force-nocopy sync'\n");
msg_warning("This file was detected as a copy of another file with the same name, size,\n");
msg_warning("and timestamp, but the file data isn't matching the assumed copy.\n");
msg_warning("If this is a false positive, and the files are expected to be different,\n");
msg_warning("you can 'sync' anyway using 'snapraid --force-nocopy sync'\n");
} else {
flog("Try removing the file from the array and rerun the 'sync' command!\n");
msg_warning("Try removing the file from the array and rerun the 'sync' command!\n");
}
++error;
@ -768,8 +772,8 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
error_on_this_block = 1;
continue;
} else { /* otherwise it's a BLK with silent error */
ftag("error:%u:%s:%s: Data error at position %u\n", i, disk->name, esc(file->sub), block_file_pos(block));
flog("Data error in file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
msg_tag("error:%u:%s:%s: Data error at position %u\n", i, disk->name, esc(file->sub), block_file_pos(block));
msg_warning("Data error in file '%s' at position '%u'\n", handle[j].path, block_file_pos(block));
/* save the failed block for the fix */
failed[failed_count].index = j;
@ -862,29 +866,29 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
/* we are sure that parity exists because */
/* we have at least one BLK block */
for (l = 0; l < state->level; ++l) {
ret = parity_read(parity[l], i, buffer[diskmax + l], state->block_size, flog);
ret = parity_read(parity[l], i, buffer[diskmax + l], state->block_size, msg_warning);
if (ret == -1) {
/* LCOV_EXCL_START */
if (errno == EIO) {
ftag("parity_error:%u:%s: Read EIO error. %s\n", i, lev_config_name(l), strerror(errno));
msg_tag("parity_error:%u:%s: Read EIO error. %s\n", i, lev_config_name(l), strerror(errno));
if (io_error >= state->opt.io_error_limit) {
ferr("DANGER! Unexpected input/output read error in the %s disk, it isn't possible to sync.\n", lev_name(l));
ferr("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(l));
ferr("Stopping at block %u\n", i);
msg_error("DANGER! Unexpected input/output read error in the %s disk, it isn't possible to sync.\n", lev_name(l));
msg_error("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(l));
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
}
flog("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), i);
msg_warning("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), i);
++io_error;
io_error_on_this_block = 1;
continue;
}
ftag("parity_error:%u:%s: Read error. %s\n", i, lev_config_name(l), strerror(errno));
ferr("WARNING! Unexpected read error in the %s disk, it isn't possible to sync.\n", lev_name(l));
ferr("Ensure that disk '%s' can be read.\n", lev_config_name(l));
ferr("Stopping at block %u\n", i);
msg_tag("parity_error:%u:%s: Read error. %s\n", i, lev_config_name(l), strerror(errno));
msg_error("WARNING! Unexpected read error in the %s disk, it isn't possible to sync.\n", lev_name(l));
msg_error("Ensure that disk '%s' can be read.\n", lev_config_name(l));
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -961,25 +965,25 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
if (ret == -1) {
/* LCOV_EXCL_START */
if (errno == EIO) {
ftag("parity_error:%u:%s: Write EIO error. %s\n", i, lev_config_name(l), strerror(errno));
msg_tag("parity_error:%u:%s: Write EIO error. %s\n", i, lev_config_name(l), strerror(errno));
if (io_error >= state->opt.io_error_limit) {
ferr("DANGER! Unexpected input/output write error in the %s disk, it isn't possible to sync.\n", lev_name(l));
ferr("Ensure that disk '%s' is sane and can be written.\n", lev_config_name(l));
ferr("Stopping at block %u\n", i);
msg_error("DANGER! Unexpected input/output write error in the %s disk, it isn't possible to sync.\n", lev_name(l));
msg_error("Ensure that disk '%s' is sane and can be written.\n", lev_config_name(l));
msg_error("Stopping at block %u\n", i);
++io_error;
goto bail;
}
flog("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), i);
msg_warning("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), i);
++io_error;
io_error_on_this_block = 1;
continue;
}
ftag("parity_error:%u:%s: Write error. %s\n", i, lev_config_name(l), strerror(errno));
ferr("WARNING! Unexpected write error in the %s disk, it isn't possible to sync.\n", lev_name(l));
ferr("Ensure that disk '%s' has some free space available.\n", lev_config_name(l));
ferr("Stopping at block %u\n", i);
msg_tag("parity_error:%u:%s: Write error. %s\n", i, lev_config_name(l), strerror(errno));
msg_error("WARNING! Unexpected write error in the %s disk, it isn't possible to sync.\n", lev_name(l));
msg_error("Ensure that disk '%s' has some free space available.\n", lev_config_name(l));
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1074,7 +1078,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
state_progress_stop(state);
fout("Autosaving...\n");
msg_progress("Autosaving...\n");
/* before writing the new content file we ensure that */
/* the parity is really written flushing the disk cache */
@ -1082,10 +1086,10 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
ret = parity_sync(parity[l]);
if (ret == -1) {
/* LCOV_EXCL_START */
ftag("parity_error:%u:%s: Sync error\n", i, lev_config_name(l));
ferr("DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
ferr("Ensure that disk '%s' is sane.\n", lev_config_name(l));
ferr("Stopping at block %u\n", i);
msg_tag("parity_error:%u:%s: Sync error\n", i, lev_config_name(l));
msg_error("DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
msg_error("Ensure that disk '%s' is sane.\n", lev_config_name(l));
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
@ -1113,45 +1117,46 @@ end:
ret = parity_sync(parity[l]);
if (ret == -1) {
/* LCOV_EXCL_START */
ftag("parity_error:%u:%s: Sync error\n", i, lev_config_name(l));
ferr("DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
ferr("Ensure that disk '%s' is sane.\n", lev_config_name(l));
ferr("Stopping at block %u\n", i);
msg_tag("parity_error:%u:%s: Sync error\n", i, lev_config_name(l));
msg_error("DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
msg_error("Ensure that disk '%s' is sane.\n", lev_config_name(l));
msg_error("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
}
}
if (io_error)
ferr("WARNING! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
if (silent_error)
ferr("WARNING! Unexpected data errors! The failing blocks are now marked as bad!\n");
if (io_error || silent_error) {
ferr("Use 'snapraid status' to list the bad blocks.\n");
ferr("Use 'snapraid -e fix' to recover.\n");
}
if (error || silent_error || io_error) {
fout("\n");
fout("%8u file errors\n", error);
fout("%8u io errors\n", io_error);
fout("%8u data errors\n", silent_error);
fout("WARNING! There are errors!\n");
msg_status("\n");
msg_status("%8u file errors\n", error);
msg_status("%8u io errors\n", io_error);
msg_status("%8u data errors\n", silent_error);
} else {
/* print the result only if processed something */
if (countpos != 0)
fout("Everything OK\n");
msg_status("Everything OK\n");
}
ftag("summary:error_file:%u\n", error);
ftag("summary:error_io:%u\n", io_error);
ftag("summary:error_data:%u\n", silent_error);
if (error)
msg_error("WARNING! Unexpected file errors!\n");
if (io_error)
msg_error("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
if (silent_error)
msg_error("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n");
if (io_error || silent_error) {
msg_error("Use 'snapraid status' to list the bad blocks.\n");
msg_error("Use 'snapraid -e fix' to recover.\n");
}
msg_tag("summary:error_file:%u\n", error);
msg_tag("summary:error_io:%u\n", io_error);
msg_tag("summary:error_data:%u\n", silent_error);
if (error + silent_error + io_error == 0)
ftag("summary:exit:ok\n");
msg_tag("summary:exit:ok\n");
else
ftag("summary:exit:error\n");
fflush_log();
msg_tag("summary:exit:error\n");
msg_flush();
bail:
for (j = 0; j < diskmax; ++j) {
@ -1160,8 +1165,8 @@ bail:
ret = handle_close(&handle[j]);
if (ret == -1) {
/* LCOV_EXCL_START */
ftag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
ferr("DANGER! Unexpected close error in a data disk.\n");
msg_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
msg_error("DANGER! Unexpected close error in a data disk.\n");
++error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */
@ -1201,7 +1206,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
unsigned l;
int skip_sync = 0;
fout("Initializing...\n");
msg_progress("Initializing...\n");
blockmax = parity_allocated_size(state);
size = blockmax * (data_off_t)state->block_size;
@ -1214,7 +1219,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
if (blockstart > blockmax) {
/* LCOV_EXCL_START */
ferr("Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
msg_error("Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1232,7 +1237,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
ret = parity_create(parity_ptr[l], state->parity[l].path, &out_size, state->file_mode);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
msg_error("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1242,7 +1247,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
/* if the file is too small */
if (parityblocks < used_paritymax) {
ferr("WARNING! The %s file %s has data only %u blocks instead of %u.\n", lev_name(l), state->parity[l].path, parityblocks, used_paritymax);
msg_error("WARNING! The %s file %s has data only %u blocks instead of %u.\n", lev_name(l), state->parity[l].path, parityblocks, used_paritymax);
}
/* keep the smallest parity number of blocks */
@ -1255,15 +1260,15 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
/* if the parities are too small */
if (file_paritymax < used_paritymax) {
/* LCOV_EXCL_START */
ferr("DANGER! One or more the parity files are smaller than expected!\n");
msg_error("DANGER! One or more the parity files are smaller than expected!\n");
if (file_paritymax != 0) {
ferr("If this happens because you are using an old content file,\n");
ferr("you can 'sync' anyway using 'snapraid --force-full sync'\n");
ferr("to force a full rebuild of the parity.\n");
msg_error("If this happens because you are using an old content file,\n");
msg_error("you can 'sync' anyway using 'snapraid --force-full sync'\n");
msg_error("to force a full rebuild of the parity.\n");
} else {
ferr("It's possible that the parity disks are not mounted.\n");
ferr("If instead you are adding a new parity level, you can 'sync' using\n");
ferr("'snapraid --force-full sync' to force a full rebuild of the parity.\n");
msg_error("It's possible that the parity disks are not mounted.\n");
msg_error("If instead you are adding a new parity level, you can 'sync' using\n");
msg_error("'snapraid --force-full sync' to force a full rebuild of the parity.\n");
}
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
@ -1279,7 +1284,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
if (ret == -1) {
/* LCOV_EXCL_START */
parity_overflow(state, out_size);
ferr("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
msg_error("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1291,7 +1296,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
unrecoverable_error = 0;
if (state->opt.prehash) {
fout("Hashing...\n");
msg_progress("Hashing...\n");
ret = state_hash_process(state, blockstart, blockmax, &skip_sync);
if (ret == -1) {
@ -1306,7 +1311,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
}
if (!skip_sync) {
fout("Syncing...\n");
msg_progress("Syncing...\n");
/* skip degenerated cases of empty parity, or skipping all */
if (blockstart < blockmax) {
@ -1318,7 +1323,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
/* LCOV_EXCL_STOP */
}
} else {
fout("Nothing to do\n");
msg_status("Nothing to do\n");
}
}
@ -1326,7 +1331,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
ret = parity_close(parity_ptr[l]);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
msg_error("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
++unrecoverable_error;
/* continue, as we are already exiting */
/* LCOV_EXCL_STOP */

View file

@ -341,7 +341,7 @@ static dev_t devread(const char* path)
f = open(path, O_RDONLY);
if (f == -1) {
/* LCOV_EXCL_START */
ferr("Failed to open '%s'.\n", path);
msg_error("Failed to open '%s'.\n", path);
return 0;
/* LCOV_EXCL_STOP */
}
@ -350,14 +350,14 @@ static dev_t devread(const char* path)
if (ret < 0) {
/* LCOV_EXCL_START */
close(f);
ferr("Failed to read '%s'.\n", path);
msg_error("Failed to read '%s'.\n", path);
return 0;
/* LCOV_EXCL_STOP */
}
if (ret == sizeof(buf)) {
/* LCOV_EXCL_START */
close(f);
ferr("Too long read '%s'.\n", path);
msg_error("Too long read '%s'.\n", path);
return 0;
/* LCOV_EXCL_STOP */
}
@ -368,7 +368,7 @@ static dev_t devread(const char* path)
if (*e != ':') {
/* LCOV_EXCL_START */
close(f);
ferr("Invalid format in '%s' for '%s'.\n", path, buf);
msg_error("Invalid format in '%s' for '%s'.\n", path, buf);
return 0;
/* LCOV_EXCL_STOP */
}
@ -377,7 +377,7 @@ static dev_t devread(const char* path)
if (*e != 0 && !isspace(*e)) {
/* LCOV_EXCL_START */
close(f);
ferr("Invalid format in '%s' for '%s'.\n", path, buf);
msg_error("Invalid format in '%s' for '%s'.\n", path, buf);
return 0;
/* LCOV_EXCL_STOP */
}
@ -385,7 +385,7 @@ static dev_t devread(const char* path)
ret = close(f);
if (ret != 0) {
/* LCOV_EXCL_START */
ferr("Failed to close '%s'.\n", path);
msg_error("Failed to close '%s'.\n", path);
return 0;
/* LCOV_EXCL_STOP */
}
@ -411,13 +411,13 @@ static int devresolve(dev_t device, char* path, size_t path_size)
ret = readlink(path, buf, sizeof(buf));
if (ret < 0) {
/* LCOV_EXCL_START */
ferr("Failed to readlink '%s'.\n", path);
msg_error("Failed to readlink '%s'.\n", path);
return -1;
/* LCOV_EXCL_STOP */
}
if (ret == sizeof(buf)) {
/* LCOV_EXCL_START */
ferr("Too long readlink '%s'.\n", path);
msg_error("Too long readlink '%s'.\n", path);
return -1;
/* LCOV_EXCL_STOP */
}
@ -426,7 +426,7 @@ static int devresolve(dev_t device, char* path, size_t path_size)
if (buf[0] != '.' || buf[1] != '.' || buf[2] != '/') {
/* LCOV_EXCL_START */
ferr("Unexpected link '%s' at '%s'.\n", buf, path);
msg_error("Unexpected link '%s' at '%s'.\n", buf, path);
return -1;
/* LCOV_EXCL_STOP */
}
@ -437,13 +437,13 @@ static int devresolve(dev_t device, char* path, size_t path_size)
/* check the device */
if (stat(path, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to stat '%s'.\n", path);
msg_error("Failed to stat '%s'.\n", path);
return -1;
/* LCOV_EXCL_STOP */
}
if (st.st_rdev != device) {
/* LCOV_EXCL_START */
ferr("Unexpected device '%u:%u' instead of '%u:%u' for '%s'.\n", major(st.st_rdev), minor(st.st_rdev), major(device), minor(device), path);
msg_error("Unexpected device '%u:%u' instead of '%u:%u' for '%s'.\n", major(st.st_rdev), minor(st.st_rdev), major(device), minor(device), path);
return -1;
/* LCOV_EXCL_STOP */
}
@ -555,7 +555,7 @@ static int devscan(tommy_list* list)
d = opendir(dir);
if (d == 0) {
/* LCOV_EXCL_START */
ferr("Failed to open dir '%s'.\n", dir);
msg_error("Failed to open dir '%s'.\n", dir);
return -1;
/* LCOV_EXCL_STOP */
}
@ -631,7 +631,7 @@ static int devsmart(dev_t device, uint64_t* smart, char* serial)
f = popen(cmd, "r");
if (!f) {
/* LCOV_EXCL_START */
ferr("Failed to run smartctl -a on device '%u:%u' (from popen).\n", major(device), minor(device));
msg_error("Failed to run smartctl -a on device '%u:%u' (from popen).\n", major(device), minor(device));
return -1;
/* LCOV_EXCL_STOP */
}
@ -646,13 +646,13 @@ static int devsmart(dev_t device, uint64_t* smart, char* serial)
ret = pclose(f);
if (!WIFEXITED(ret)) {
/* LCOV_EXCL_START */
ferr("Failed to run smartctl -a on device '%u:%u' (not exited).\n", major(device), minor(device));
msg_error("Failed to run smartctl -a on device '%u:%u' (not exited).\n", major(device), minor(device));
return -1;
/* LCOV_EXCL_STOP */
}
if (WEXITSTATUS(ret) == 127) {
/* LCOV_EXCL_START */
ferr("Failed to run smartctl -a on device '%u:%u' (from sh).\n", major(device), minor(device));
msg_error("Failed to run smartctl -a on device '%u:%u' (from sh).\n", major(device), minor(device));
return -1;
/* LCOV_EXCL_STOP */
}
@ -677,25 +677,25 @@ static int devdown(dev_t device)
ret = system(cmd);
if (ret == -1) {
/* LCOV_EXCL_START */
ferr("Failed to run hdparm -y on device '%u:%u' (from system).\n", major(device), minor(device));
msg_error("Failed to run hdparm -y on device '%u:%u' (from system).\n", major(device), minor(device));
return -1;
/* LCOV_EXCL_STOP */
}
if (!WIFEXITED(ret)) {
/* LCOV_EXCL_START */
ferr("Failed to run hdparm -y on device '%u:%u' (not exited).\n", major(device), minor(device));
msg_error("Failed to run hdparm -y on device '%u:%u' (not exited).\n", major(device), minor(device));
return -1;
/* LCOV_EXCL_STOP */
}
if (WEXITSTATUS(ret) == 127) {
/* LCOV_EXCL_START */
ferr("Failed to run hdparm -y on device '%u:%u' (from sh).\n", major(device), minor(device));
msg_error("Failed to run hdparm -y on device '%u:%u' (from sh).\n", major(device), minor(device));
return -1;
/* LCOV_EXCL_STOP */
}
if (WEXITSTATUS(ret) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to run hdparm -y on device '%u:%u' with return code %xh.\n", major(device), minor(device), WEXITSTATUS(ret));
msg_error("Failed to run hdparm -y on device '%u:%u' with return code %xh.\n", major(device), minor(device), WEXITSTATUS(ret));
return -1;
/* LCOV_EXCL_STOP */
}
@ -722,7 +722,7 @@ static int devup(const char* mount)
ret = mkdir(path, 0);
if (ret != 0 && errno != EEXIST) {
/* LCOV_EXCL_START */
ferr("Failed to create dir '%s'.\n", path);
msg_error("Failed to create dir '%s'.\n", path);
return -1;
/* LCOV_EXCL_STOP */
}
@ -751,7 +751,7 @@ static void* thread_spinup(void* arg)
/* first get the device number, this usually doesn't trigger a thread_spinup */
if (stat(devinfo->mount, &st) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to stat device '%s'.\n", devinfo->mount);
msg_error("Failed to stat device '%s'.\n", devinfo->mount);
return (void*)-1;
/* LCOV_EXCL_STOP */
}
@ -772,7 +772,7 @@ static void* thread_spinup(void* arg)
/* LCOV_EXCL_STOP */
}
fout("Spunup device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
msg_status("Spunup device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
return 0;
}
@ -794,7 +794,7 @@ static void* thread_spindown(void* arg)
/* LCOV_EXCL_STOP */
}
fout("Spundown device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
msg_status("Spundown device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
return 0;
#else
@ -831,7 +831,7 @@ static int device_thread(tommy_list* list, void* (*func)(void* arg))
if (pthread_create(&devinfo->thread, 0, func, devinfo) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to create thread.\n");
msg_error("Failed to create thread.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -844,7 +844,7 @@ static int device_thread(tommy_list* list, void* (*func)(void* arg))
if (pthread_join(devinfo->thread, &retval) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to join thread.\n");
msg_error("Failed to join thread.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -880,13 +880,13 @@ int devquery(tommy_list* high, tommy_list* low, int operation)
/* sysfs and devfs interfaces are required */
if (stat("/sys/dev/block", &st) != 0) {
/* LCOV_EXCL_START */
ferr("Missing interface /sys/dev/block.\n");
msg_error("Missing interface /sys/dev/block.\n");
return -1;
/* LCOV_EXCL_STOP */
}
if (stat("/dev/block", &st) != 0) {
/* LCOV_EXCL_START */
ferr("Missing interface /dev/block.\n");
msg_error("Missing interface /dev/block.\n");
return -1;
/* LCOV_EXCL_STOP */
}
@ -898,7 +898,7 @@ int devquery(tommy_list* high, tommy_list* low, int operation)
/* get the device file */
if (devresolve(devinfo->device, devinfo->file, sizeof(devinfo->file)) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to resolve device '%u:%u'.\n", major(devinfo->device), minor(devinfo->device));
msg_error("Failed to resolve device '%u:%u'.\n", major(devinfo->device), minor(devinfo->device));
return -1;
/* LCOV_EXCL_STOP */
}
@ -906,7 +906,7 @@ int devquery(tommy_list* high, tommy_list* low, int operation)
/* expand the tree of devices */
if (devtree(devinfo->name, devinfo->device, devinfo, low) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to expand device '%u:%u'.\n", major(devinfo->device), minor(devinfo->device));
msg_error("Failed to expand device '%u:%u'.\n", major(devinfo->device), minor(devinfo->device));
return -1;
/* LCOV_EXCL_STOP */
}
@ -936,7 +936,7 @@ int devquery(tommy_list* high, tommy_list* low, int operation)
if (operation == DEVICE_SMART) {
if (devscan(low) != 0) {
/* LCOV_EXCL_START */
ferr("Failed to list other devices.\n");
msg_error("Failed to list other devices.\n");
return -1;
/* LCOV_EXCL_STOP */
}

View file

@ -72,8 +72,8 @@ void mtest_vector(int n, size_t size, void** vv)
{
if (raid_mtest_vector(n, size, vv) != 0) {
/* LCOV_EXCL_START */
ferr("DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n");
ferr("Try running a memory test like http://www.memtest86.com/\n");
msg_error("DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n");
msg_error("Try running a memory test like http://www.memtest86.com/\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -492,7 +492,7 @@ void memhash(unsigned kind, const unsigned char* seed, void* digest, const void*
break;
default :
/* LCOV_EXCL_START */
ferr("Internal inconsistency in hash function %u\n", kind);
msg_error("Internal inconsistency in hash function %u\n", kind);
exit(EXIT_FAILURE);
break;
/* LCOV_EXCL_STOP */

View file

@ -46,7 +46,7 @@ snapraid [\-c, \-\-conf CONFIG]
.PD 0
.PP
.PD
[\-v, \-\-verbose]
[\-v, \-\-verbose] [\-q, \-\-quiet]
.PD 0
.PP
.PD
@ -998,11 +998,11 @@ the old content file and the parity data you have.
This option can be used only with \[dq]sync\[dq].
.TP
.B \-l, \-\-log FILE
Write a detailed log of errors encoutered.
If this option is not specified, the errors are printed on
the screen, likely resulting in too much output in case
of many errors.
If the specified path starts with \'>>\' the file is opened
Write a detailed log in the specified file.
If this option is not specified, the warnings and not fatal
errors are printed on the screen, likely resulting in too much
output in case of many errors.
If the path starts with \'>>\' the file is opened
in append mode. Occurrences of \'%D\' and \'%T\' in the name are
replaced with the date and time in the format YYYYMMDD and
HHMMSS. Note that in Windows batch files, you\'ll have to double
@ -1041,7 +1041,14 @@ needed to reconstruct the disk mount points, in case you
lose the entire system.
.TP
.B \-v, \-\-verbose
Prints more information in the processing.
Prints more information on the screen.
.TP
.B \-q, \-\-quiet
Prints less information on the screen.
If specified one time, removes the progress bar, if two
times, the running operations, three times, the info
messages, four times the status messages.
Fatal errors are always printed.
.TP
.B \-H, \-\-help
Prints a short help screen.

View file

@ -13,7 +13,7 @@ Synopsis
: [-N, --force-nocopy] [-F, --force-full]
: [-S, --start BLKSTART] [-B, --count BLKCOUNT]
: [-L, --error-limit NUMBER]
: [-v, --verbose]
: [-v, --verbose] [-q, --quiet]
: status|smart|up|down|diff|sync|scrub|fix|check|list|dup|up|down|pool|rehash
:snapraid [-V, --version] [-H, --help] [-C, --gen-conf CONTENT]
@ -739,11 +739,11 @@ Options
This option can be used only with "sync".
-l, --log FILE
Write a detailed log of errors encoutered.
If this option is not specified, the errors are printed on
the screen, likely resulting in too much output in case
of many errors.
If the specified path starts with '>>' the file is opened
Write a detailed log in the specified file.
If this option is not specified, the warnings and not fatal
errors are printed on the screen, likely resulting in too much
output in case of many errors.
If the path starts with '>>' the file is opened
in append mode. Occurrences of '%D' and '%T' in the name are
replaced with the date and time in the format YYYYMMDD and
HHMMSS. Note that in Windows batch files, you'll have to double
@ -782,7 +782,14 @@ Options
lose the entire system.
-v, --verbose
Prints more information in the processing.
Prints more information on the screen.
-q, --quiet
Prints less information on the screen.
If specified one time, removes the progress bar, if two
times, the running operations, three times, the info
messages, four times the status messages.
Fatal errors are always printed.
-H, --help
Prints a short help screen.

View file

@ -17,7 +17,7 @@ snapraid [-c, --conf CONFIG]
[-N, --force-nocopy] [-F, --force-full]
[-S, --start BLKSTART] [-B, --count BLKCOUNT]
[-L, --error-limit NUMBER]
[-v, --verbose]
[-v, --verbose] [-q, --quiet]
status|smart|up|down|diff|sync|scrub|fix|check|list|dup|up|down|pool|rehash
snapraid [-V, --version] [-H, --help] [-C, --gen-conf CONTENT]
@ -796,11 +796,11 @@ SnapRAID provides the following options:
This option can be used only with "sync".
-l, --log FILE
Write a detailed log of errors encoutered.
If this option is not specified, the errors are printed on
the screen, likely resulting in too much output in case
of many errors.
If the specified path starts with '>>' the file is opened
Write a detailed log in the specified file.
If this option is not specified, the warnings and not fatal
errors are printed on the screen, likely resulting in too much
output in case of many errors.
If the path starts with '>>' the file is opened
in append mode. Occurrences of '%D' and '%T' in the name are
replaced with the date and time in the format YYYYMMDD and
HHMMSS. Note that in Windows batch files, you'll have to double
@ -839,7 +839,14 @@ SnapRAID provides the following options:
lose the entire system.
-v, --verbose
Prints more information in the processing.
Prints more information on the screen.
-q, --quiet
Prints less information on the screen.
If specified one time, removes the progress bar, if two
times, the running operations, three times, the info
messages, four times the status messages.
Fatal errors are always printed.
-H, --help
Prints a short help screen.