mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Extend the disk filtering to parity disk
You can now fix a specific parity disk, without touching the others.
This commit is contained in:
parent
3e83b15bbb
commit
2b69cfa073
9 changed files with 72 additions and 19 deletions
8
HISTORY
8
HISTORY
|
|
@ -16,17 +16,19 @@ SnapRAID HISTORY
|
|||
ensure to scrub all the synced blocks.
|
||||
* The -p, --percentage option supports the new the arguments:
|
||||
"bad", "sync" and "full" to define the kind of scrub to do.
|
||||
* Drastically reduced the memory usage. For each block, it now
|
||||
* Drastically reduces the memory usage. For each block, it now
|
||||
uses 17 bytes of memory, instead of the previous 28 bytes
|
||||
(for 32 bit) or 36 bytes (for 64 bit).
|
||||
This could result is a memory saving of up the 50%.
|
||||
* Extends the -D, --force-device option to ignore more
|
||||
erroneous conditions in the 'fix' command, like unaccessible
|
||||
disks, or disks sharing the same physical device.
|
||||
* Extends the -d, --filter-disk option to allow to filter also
|
||||
by parity disk.
|
||||
* Extends the -h, --pre-hash option to also verify moved and
|
||||
copied files into the array before running a 'sync'.
|
||||
* Update 'best' RAID functions for recent Atom CPUs.
|
||||
* Validate filters specifications rejecting relative paths.
|
||||
* Updates 'best' RAID functions for recent Atom CPUs.
|
||||
* Validates filters specifications rejecting relative paths.
|
||||
|
||||
8.1 2015/05
|
||||
===========
|
||||
|
|
|
|||
|
|
@ -366,8 +366,7 @@ if HAVE_SYMLINK
|
|||
endif
|
||||
echo --- Extend PAR1 to max parity with fix and check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(CONF) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(PAR1) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) fix -d 2-parity -d 3-parity -d 4-parity -d 5-parity -d 6-parity -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
#### SCRUB ####
|
||||
echo --- Scrub some times
|
||||
|
|
|
|||
|
|
@ -797,9 +797,9 @@ close_and_continue:
|
|||
*/
|
||||
static int block_is_enabled(struct snapraid_state* state, block_off_t i, struct snapraid_handle* handle, unsigned diskmax)
|
||||
{
|
||||
int one_tocheck;
|
||||
snapraid_info info;
|
||||
unsigned j;
|
||||
unsigned l;
|
||||
|
||||
/* get block specific info */
|
||||
info = info_get(&state->infoarr, i);
|
||||
|
|
@ -811,8 +811,14 @@ static int block_is_enabled(struct snapraid_state* state, block_off_t i, struct
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* for each parity */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
if (!state->parity[l].is_excluded) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* for each disk */
|
||||
one_tocheck = 0;
|
||||
for (j = 0; j < diskmax; ++j) {
|
||||
struct snapraid_block* block;
|
||||
|
||||
|
|
@ -827,17 +833,12 @@ static int block_is_enabled(struct snapraid_state* state, block_off_t i, struct
|
|||
if (block_has_file(block)) {
|
||||
struct snapraid_file* file = fs_par2file_get(handle[j].disk, i, 0);
|
||||
if (!file_flag_has(file, FILE_IS_EXCLUDED)) { /* only if the file is not filtered out */
|
||||
one_tocheck = 1;
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if no block to check skip */
|
||||
if (!one_tocheck)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int state_check_process(struct snapraid_state* state, int fix, struct snapraid_parity_handle** parity, block_off_t blockstart, block_off_t blockmax)
|
||||
|
|
@ -1270,6 +1271,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) {
|
||||
unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size);
|
||||
|
||||
/* mark that the read parity is wrong, setting ptr to 0 */
|
||||
buffer_recov[l] = 0;
|
||||
|
||||
log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff);
|
||||
|
|
@ -1330,7 +1332,13 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
|
|||
if (valid_parity) {
|
||||
/* update the parity */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
if (buffer_recov[l] == 0 && parity[l] != 0) {
|
||||
/* if the parity on disk is wrong */
|
||||
if (buffer_recov[l] == 0
|
||||
/* and we have access at the parity */
|
||||
&& parity[l] != 0
|
||||
/* and the parity is not excluded */
|
||||
&& !state->parity[l].is_excluded
|
||||
) {
|
||||
ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
|
|||
|
|
@ -409,6 +409,7 @@ struct snapraid_parity {
|
|||
block_off_t total_blocks; /**< Number of total blocks. */
|
||||
block_off_t free_blocks; /**< Number of free blocks at the last sync. */
|
||||
int skip_access; /**< If the disk is unaccessible and it should be skipped. */
|
||||
int is_excluded; /**< If the parity is excluded by disk filter. */
|
||||
|
||||
/**
|
||||
* Cumulative time used for parity disks.
|
||||
|
|
|
|||
|
|
@ -885,6 +885,15 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
/* errors must be always fixed on all disks */
|
||||
/* becasue we don't keep the information on what disk is the error */
|
||||
if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You cannot use -e, --filter-error and -d, --filter-disk at the same time\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case OPERATION_CHECK :
|
||||
case OPERATION_FIX :
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ void state_init(struct snapraid_state* state)
|
|||
state->parity[l].free_blocks = 0;
|
||||
state->parity[l].tick = 0;
|
||||
state->parity[l].skip_access = 0;
|
||||
state->parity[l].is_excluded = 0;
|
||||
}
|
||||
state->tick_io = 0;
|
||||
state->tick_cpu = 0;
|
||||
|
|
@ -437,10 +438,16 @@ static void state_config_check(struct snapraid_state* state, const char* path, t
|
|||
break;
|
||||
}
|
||||
if (j == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Option -d, --filter-disk %s doesn't match any disk.\n", filter->pattern);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
/* check matching with parity disks */
|
||||
for (l = 0; l < state->level; ++l)
|
||||
if (fnmatch(filter->pattern, lev_config_name(l), FNM_CASEINSENSITIVE_FOR_WIN) == 0)
|
||||
break;
|
||||
if (l == state->level) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Option -d, --filter-disk %s doesn't match any data or parity disk.\n", filter->pattern);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3234,6 +3241,7 @@ void state_skip(struct snapraid_state* state)
|
|||
void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tommy_list* filterlist_disk, int filter_missing, int filter_error)
|
||||
{
|
||||
tommy_node* i;
|
||||
unsigned l;
|
||||
|
||||
/* if no filter, include all */
|
||||
if (!filter_missing && !filter_error && tommy_list_empty(filterlist_file) && tommy_list_empty(filterlist_disk))
|
||||
|
|
@ -3300,6 +3308,26 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if we are filtering by disk */
|
||||
if (!tommy_list_empty(filterlist_disk)) {
|
||||
/* for each parity disk */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
/* check if the parity is excluded by name */
|
||||
if (filter_path(filterlist_disk, 0, lev_config_name(l), 0) != 0) {
|
||||
/* excluded the parity from further operation */
|
||||
state->parity[l].is_excluded = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* if we are filtering by file, exclude all parity */
|
||||
if (filter_missing || !tommy_list_empty(filterlist_file)) {
|
||||
/* for each parity disk */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
state->parity[l].is_excluded = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int state_progress_begin(struct snapraid_state* state, block_off_t blockstart, block_off_t blockmax, block_off_t countmax)
|
||||
|
|
|
|||
|
|
@ -956,6 +956,8 @@ In \[dq]check\[dq], you can make it faster, specifying also \-a, \-\-audit\-only
|
|||
option, to avoid to access other disks to check parity data.
|
||||
If you combine more \-\-filter, \-\-filter\-disk and \-\-filter\-missing options,
|
||||
only files matching all the set of filters are selected.
|
||||
You can also specify parity disks with the names: \[dq]parity\[dq], \[dq]2\-parity\[dq],
|
||||
\[dq]3\-parity\[dq], ... to limit the operations a specific parity disk.
|
||||
This option can be used many times.
|
||||
This option can be used only with \[dq]check\[dq] and \[dq]fix\[dq].
|
||||
Note that it cannot be used with \[dq]sync\[dq] and \[dq]scrub\[dq], because they always
|
||||
|
|
|
|||
|
|
@ -670,6 +670,8 @@ Options
|
|||
option, to avoid to access other disks to check parity data.
|
||||
If you combine more --filter, --filter-disk and --filter-missing options,
|
||||
only files matching all the set of filters are selected.
|
||||
You can also specify parity disks with the names: "parity", "2-parity",
|
||||
"3-parity", ... to limit the operations a specific parity disk.
|
||||
This option can be used many times.
|
||||
This option can be used only with "check" and "fix".
|
||||
Note that it cannot be used with "sync" and "scrub", because they always
|
||||
|
|
|
|||
|
|
@ -729,6 +729,8 @@ SnapRAID provides the following options:
|
|||
option, to avoid to access other disks to check parity data.
|
||||
If you combine more --filter, --filter-disk and --filter-missing options,
|
||||
only files matching all the set of filters are selected.
|
||||
You can also specify parity disks with the names: "parity", "2-parity",
|
||||
"3-parity", ... to limit the operations a specific parity disk.
|
||||
This option can be used many times.
|
||||
This option can be used only with "check" and "fix".
|
||||
Note that it cannot be used with "sync" and "scrub", because they always
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue