From 191dcdf3d472da6a9174c5cffc7a7e7452f76fd4 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 9 Oct 2011 23:41:08 +0200 Subject: [PATCH] Adds the --find-by-name option to find files by path instead than by inode. --- HISTORY | 3 + Makefile.am | 8 ++- TODO | 4 ++ elem.c | 9 +++ elem.h | 15 +++++ scan.c | 57 ++++++++++++++--- snapraid.1 | 86 ++++++++++++++++++++++++++ snapraid.c | 11 +++- snapraid.conf.example | 1 + snapraid.conf.example.windows | 1 + snapraid.d | 73 ++++++++++++++++++++++ snapraid.txt | 112 ++++++++++++++++++++++++++++------ state.c | 5 +- state.h | 3 +- 14 files changed, 356 insertions(+), 32 deletions(-) diff --git a/HISTORY b/HISTORY index ec1b5dfa..5e67750e 100644 --- a/HISTORY +++ b/HISTORY @@ -21,6 +21,9 @@ SnapRAID HISTORY recreated from scratch. * When getting unrecoverable errors, the printed log line now starts with 'unrecoverable:' instead of 'error:' to allow an easier identification. +* Added a new option '--find-by-name' to allow to sync using only the + file path and not the inode. This is useful to avoid long sync + when you replace one disk with another copying manually the files. 1.6 2011/9 - THIS UPDATE IS HIGHLY RECOMMENDED! =============================================== diff --git a/Makefile.am b/Makefile.am index 5b4a855c..48ffb244 100644 --- a/Makefile.am +++ b/Makefile.am @@ -149,6 +149,9 @@ check-local: $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf check 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf fix 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check + echo --- Sync after all the fixes with an empty drive to test --force-empty + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v --force-empty -c $(srcdir)/test-raid6.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo --- Delete two disks, fix and check with raid6 rm -r test/disk1 mkdir test/disk1 @@ -159,8 +162,9 @@ check-local: $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf check $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check - echo --- Sync after all the fixes with an empty drive to test -E - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -E -c $(srcdir)/test-raid6.conf sync + echo --- Sync after all the fixes with an empty drive to test --find-by-name + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v --find-by-name -c $(srcdir)/test-raid6.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo --- Delete some files and create some new, sync and check in multiple steps rm test/disk1/4* rm test/disk2/5* diff --git a/TODO b/TODO index 6cdf723c..51e02e0b 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,10 @@ This is the list of TODO items for SnapRAID. * When scanning, ensure that each file is in the expected disk. +* If fix fails for unrecoverable parts, rename such files adding ".unrecoverable". + +* Check and fix also empty file. + * When fixing, before overwriting the present file, make a copy of it just in case that the original file cannot be completely recovered. We can always open files in read-only mode, if a write is required, we close it, diff --git a/elem.c b/elem.c index 23094003..e76c91ce 100644 --- a/elem.c +++ b/elem.c @@ -297,6 +297,13 @@ int file_inode_compare(const void* void_arg, const void* void_data) return 0; } +int file_path_compare(const void* void_arg, const void* void_data) +{ + const char* arg = void_arg; + const struct snapraid_file* file = void_data; + return strcmp(arg, file->sub); +} + struct snapraid_link* link_alloc(const char* sub, const char* linkto) { struct snapraid_link* link; @@ -336,6 +343,7 @@ struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev disk->first_free_block = 0; tommy_list_init(&disk->filelist); tommy_hashdyn_init(&disk->inodeset); + tommy_hashdyn_init(&disk->pathset); tommy_list_init(&disk->linklist); tommy_hashdyn_init(&disk->linkset); tommy_array_init(&disk->blockarr); @@ -352,6 +360,7 @@ void disk_free(struct snapraid_disk* disk) file_free(file); } tommy_hashdyn_done(&disk->inodeset); + tommy_hashdyn_done(&disk->pathset); node = disk->linklist; while (node) { struct snapraid_link* link = node->data; diff --git a/elem.h b/elem.h index 0b5b5f7e..3bdec883 100644 --- a/elem.h +++ b/elem.h @@ -100,6 +100,7 @@ struct snapraid_file { /* nodes for data structures */ tommy_node nodelist; tommy_hashdyn_node nodeset; + tommy_hashdyn_node pathset; }; /** @@ -125,6 +126,7 @@ struct snapraid_disk { block_off_t first_free_block; /**< First free searching block. */ tommy_list filelist; /**< List of all the files. */ tommy_hashdyn inodeset; /**< Hashtable by inode of all the files. */ + tommy_hashdyn pathset; /**< Hashtable by path of all the files. */ tommy_list linklist; /**< List of all the links. */ tommy_hashdyn linkset; /**< Hashtable by name of all the links. */ tommy_array blockarr; /**< Block array of the disk. */ @@ -274,6 +276,19 @@ static inline tommy_uint32_t file_inode_hash(uint64_t inode) return (tommy_uint32_t)tommy_inthash_u64(inode); } +/** + * Compares a file with a path. + */ +int file_path_compare(const void* void_arg, const void* void_data); + +/** + * Computes the hash of a file path. + */ +static inline tommy_uint32_t file_path_hash(const char* sub) +{ + return tommy_hash_u32(0, sub, strlen(sub)); +} + static inline int link_flag_has(struct snapraid_link* link, unsigned mask) { return (link->flag & mask) == mask; diff --git a/scan.c b/scan.c index b5cb7fc1..2a0d71c9 100644 --- a/scan.c +++ b/scan.c @@ -73,6 +73,7 @@ static void scan_file_remove(struct snapraid_state* state, struct snapraid_disk* /* remove the file from the file containers */ tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); tommy_list_remove_existing(&disk->filelist, &file->nodelist); /* deallocate */ @@ -116,6 +117,7 @@ static void scan_file_insert(struct snapraid_state* state, struct snapraid_disk* /* insert the file in the file containers */ tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); } @@ -125,11 +127,16 @@ static void scan_file_insert(struct snapraid_state* state, struct snapraid_disk* static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, int output, struct snapraid_disk* disk, const char* sub, const struct stat* st) { struct snapraid_file* file; - uint64_t inode; - /* check if the file already exists */ - inode = st->st_ino; - file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare, &inode, file_inode_hash(inode)); + if (state->find_by_name) { + /* check if the file path already exists */ + file = tommy_hashdyn_search(&disk->pathset, file_path_compare, sub, file_path_hash(sub)); + } else { + /* check if the file inode already exists */ + uint64_t inode = st->st_ino; + file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare, &inode, file_inode_hash(inode)); + } + if (file) { /* check if multiple files have the same inode */ if (file_flag_has(file, FILE_IS_PRESENT)) { @@ -137,7 +144,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, printf("warning: Ignored hardlink '%s%s'\n", disk->dir, sub); return; } else { - fprintf(stderr, "Internal inode '%"PRIu64"' inconsistency for file '%s%s'\n", inode, disk->dir, sub); + fprintf(stderr, "Internal inode '%"PRIu64"' inconsistency for file '%s%s'\n", st->st_ino, disk->dir, sub); exit(EXIT_FAILURE); } } @@ -147,8 +154,36 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, /* mark as present */ file_flag_set(file, FILE_IS_PRESENT); - /* if the path is different, it means a moved file */ if (strcmp(file->sub, sub) != 0) { + /* if the path is different, it means a moved file with the same inode */ + ++scan->count_moved; + + if (file->inode != st->st_ino) { + fprintf(stderr, "Internal inode inconsistency for file '%s%s'\n", disk->dir, sub); + exit(EXIT_FAILURE); + } + + if (state->gui) { + fprintf(stderr, "scan:move:%s:%s:%s\n", disk->name, file->sub, sub); + fflush(stderr); + } + if (output) { + printf("Move '%s%s' '%s%s'\n", disk->dir, file->sub, disk->dir, sub); + } + + /* remove from the set */ + tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); + + /* save the new name */ + pathcpy(file->sub, sizeof(file->sub), sub); + + /* reinsert in the set */ + tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); + + /* we have to save the new name */ + state->need_write = 1; + } else if (file->inode != st->st_ino) { + /* if the inode is different, it means a rewritten file with the same path */ ++scan->count_moved; if (state->gui) { @@ -159,8 +194,14 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, printf("Move '%s%s' '%s%s'\n", disk->dir, file->sub, disk->dir, sub); } - /* save the new name */ - pathcpy(file->sub, sizeof(file->sub), sub); + /* remove from the set */ + tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + + /* save the new inode */ + file->inode = st->st_ino; + + /* reinsert in the set */ + tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); /* we have to save the new name */ state->need_write = 1; diff --git a/snapraid.1 b/snapraid.1 index f3c17ed7..c377de5a 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -5,6 +5,10 @@ snapraid \(hy SnapRAID Backup For Disk Arrays snapraid [\(hyc, \(hy\(hyconf CONFIG] [\(hyf, \(hy\(hyfilter PATTERN] .PD 0 .PP +.PD + [\(hyN, \(hy\(hyfind\(hyby\(hyname] +.PD 0 +.PP .PD [\(hyZ, \(hy\(hyforce\(hyzero] [\(hyE, \(hy\(hyforce\(hyempty] .PD 0 @@ -333,6 +337,17 @@ pattern specifications. This option can be used many times. In Unix, ensure to quote globbing chars if used. .TP +.B \(hyN, \(hy\(hyfind\(hyby\(hyname +When syncing finds the files by name instead than by inode. +This option allows a fast sync command after having replaced +one physical disk with another copying manually the files. +Without this option the \(cqsync\(cq command would recognize that +the files were copied to a different disk, and will resync +them all. Instead, with this option a file with the correct +name, size and time will be assumed identical at the previous +one. +This option has effect only on the \(cqsync\(cq and \(cqdiff\(cq commands. +.TP .B \(hyZ, \(hy\(hyforce\(hyzero Forces the insecure operation of syncing a file with zero size that before was not. @@ -698,6 +713,77 @@ snapraid \(hyf \(a"*.mp3\(a" check .PP In Unix, when using globbing chars in the command line, you have to quote them. Otherwise the shell will try to expand them. +.SH RECOVERING +The worst happened, and you lost a disk! +.PP +DO NOT PANIC! You will be able to recover it! +.PP +The first thing you have to do is to avoid futher changes at you disk array. +Disable any remote connections to it, any scheduled processes, including any +scheduled SnapRAID nightly sync. +.PP +Then proceed with the following steps. +.SS STEP 1 \(hy> Reconfigure +You need some space to recover, even better if you have already an additional +disk, but in case also an external USB or remote one is enough. +.PP +Change the SnapRAID configuration and change the \(cqdisk\(cq directory +of the failed disk to point to the new empty space. +.SS STEP 2 \(hy> Fix +Run the fix command, storing the log in an external file with: +.PP +.RS 4 +snapraid fix 2>fix.log +.PD 0 +.PP +.PD +.RE +.PP +This command will take a long time. +.PP +Take care that you need also few GB free to store the fix.log file, so run it +from a disk with some free space. +.PP +Now you have recovered all the recoverable. If some file is partly or totally +unrecoverable, it will be renamed adding the \(a".unrecoverable\(a" extension. +.PP +You can get a detailed list of all the unrecoverable blocks in the fix.log file +checking all the lines starting with \(a"unrecoverable:\(a" +.PP +If you are not satified of the recovering, you can retry it as many time you wish. +For example, if you have moved away some files from other disks after the last \(cqsync\(cq, +you can retry to put them inplace, and retry the \(cqfix\(cq. +.PP +If you are satisfied of the recovering, you can now proceed synching the array, +but take care that after synching you will no more able to retry the +\(cqfix\(cq command! +.SS STEP 3 \(hy> Sync +Run the \(cqsync\(cq command to resyncronize the array with the new disk. +.PP +To avoid a long time sync you have to use the \(cq\(hy\(hyfind\(hyby\(hyname\(cq option to +tell SnapRAID to ignore the fact that all the recovered files are now in +a different physical disk, and they don\(cqt need to be synched. +.PP +.RS 4 +snapraid \(hy\(hyfind\(hyby\(hyname sync +.PD 0 +.PP +.PD +.RE +.PP +If everything was recovered, this command is immediate. +.SS STEP 4 \(hy> Check +As paranoid check, you can now run a whole \(cqcheck\(cq command to ensure that +everything is OK. +.PP +.RS 4 +snapraid check +.PD 0 +.PP +.PD +.RE +.PP +This command will take a long time. .SH CONTENT SnapRAID stores the list and checksums of your files in the content file. .PP diff --git a/snapraid.c b/snapraid.c index 50ab6c4b..2f78fd59 100644 --- a/snapraid.c +++ b/snapraid.c @@ -55,6 +55,7 @@ void usage(void) printf("Options:\n"); printf(" " SWITCH_GETOPT_LONG("-c, --conf FILE ", "-c") " Configuration file (default " CONF ")\n"); printf(" " SWITCH_GETOPT_LONG("-f, --filter PATTERN", "-f") " Filter the files to processs\n"); + printf(" " SWITCH_GETOPT_LONG("-N, --find-by-name ", "-N") " Find the file by name instead than by inode\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("-s, --start BLKSTART", "-s") " Start from the specified block number\n"); @@ -78,6 +79,7 @@ struct option long_options[] = { { "count", 1, 0, 't' }, { "force-zero", 0, 0, 'Z' }, { "force-empty", 0, 0, 'E' }, + { "find-by-name", 0, 0, 'N' }, { "speed-test", 0, 0, 'T' }, { "verbose", 0, 0, 'v' }, { "gui", 0, 0, 'G' }, /* undocumented GUI interface command */ @@ -93,7 +95,7 @@ struct option long_options[] = { }; #endif -#define OPTIONS "c:f:s:t:ZETvhVG" +#define OPTIONS "c:f:s:t:ZENTvhVG" volatile int global_interrupt = 0; @@ -119,6 +121,7 @@ int main(int argc, char* argv[]) int gui; int force_zero; int force_empty; + int find_by_name; int test_expect_unrecoverable; int test_expect_recoverable; int test_kill_after_sync; @@ -139,6 +142,7 @@ int main(int argc, char* argv[]) gui = 0; force_zero = 0; force_empty = 0; + find_by_name = 0; test_expect_unrecoverable = 0; test_expect_recoverable = 0; test_kill_after_sync = 0; @@ -188,6 +192,9 @@ int main(int argc, char* argv[]) case 'E' : force_empty = 1; break; + case 'N' : + find_by_name = 1; + break; case 'v' : verbose = 1; break; @@ -251,7 +258,7 @@ int main(int argc, char* argv[]) state_init(&state); - state_config(&state, conf, verbose, gui, force_zero, force_empty, test_expect_unrecoverable, test_expect_recoverable, test_skip_device); + state_config(&state, conf, verbose, gui, force_zero, force_empty, find_by_name, test_expect_unrecoverable, test_expect_recoverable, test_skip_device); if (operation == OPERATION_DIFF) { state_read(&state); diff --git a/snapraid.conf.example b/snapraid.conf.example index f8454d84..8a040d19 100644 --- a/snapraid.conf.example +++ b/snapraid.conf.example @@ -35,6 +35,7 @@ disk d3 /mnt/disk3/ # Format: "exclude /PATH/FILE" # Format: "exclude /PATH/DIR/" exclude *.bak +exclude *.unrecoverable exclude /tmp/ exclude /lost+found/ diff --git a/snapraid.conf.example.windows b/snapraid.conf.example.windows index e75c0db3..a6f1d85e 100644 --- a/snapraid.conf.example.windows +++ b/snapraid.conf.example.windows @@ -35,6 +35,7 @@ disk d3 I:\array\ # Format: "exclude \PATH\FILE" # Format: "exclude \PATH\DIR\" exclude *.bak +exclude *.unrecoverable exclude Thumbs.db exclude \$RECYCLE.BIN exclude \System Volume Information diff --git a/snapraid.d b/snapraid.d index d9462c62..45fc778a 100644 --- a/snapraid.d +++ b/snapraid.d @@ -3,6 +3,7 @@ Name{number} Synopsis :snapraid [-c, --conf CONFIG] [-f, --filter PATTERN] + : [-N, --find-by-name] : [-Z, --force-zero] [-E, --force-empty] : [-s, --start BLKSTART] [-t, --count BLKCOUNT] : [-v, --verbose] @@ -226,6 +227,17 @@ Options This option can be used many times. In Unix, ensure to quote globbing chars if used. + -N, --find-by-name + When syncing finds the files by name instead than by inode. + This option allows a fast sync command after having replaced + one physical disk with another copying manually the files. + Without this option the 'sync' command would recognize that + the files were copied to a different disk, and will resync + them all. Instead, with this option a file with the correct + name, size and time will be assumed identical at the previous + one. + This option has effect only on the 'sync' and 'diff' commands. + -Z, --force-zero Forces the insecure operation of syncing a file with zero size that before was not. @@ -466,6 +478,67 @@ Pattern In Unix, when using globbing chars in the command line, you have to quote them. Otherwise the shell will try to expand them. +Recovering + The worst happened, and you lost a disk! + + DO NOT PANIC! You will be able to recover it! + + The first thing you have to do is to avoid futher changes at you disk array. + Disable any remote connections to it, any scheduled processes, including any + scheduled SnapRAID nightly sync. + + Then proceed with the following steps. + + STEP 1 -> Reconfigure + You need some space to recover, even better if you have already an additional + disk, but in case also an external USB or remote one is enough. + + Change the SnapRAID configuration and change the 'disk' directory + of the failed disk to point to the new empty space. + + STEP 2 -> Fix + Run the fix command, storing the log in an external file with: + + :snapraid fix 2>fix.log + + This command will take a long time. + + Take care that you need also few GB free to store the fix.log file, so run it + from a disk with some free space. + + Now you have recovered all the recoverable. If some file is partly or totally + unrecoverable, it will be renamed adding the ".unrecoverable" extension. + + You can get a detailed list of all the unrecoverable blocks in the fix.log file + checking all the lines starting with "unrecoverable:" + + If you are not satified of the recovering, you can retry it as many time you wish. + For example, if you have moved away some files from other disks after the last 'sync', + you can retry to put them inplace, and retry the 'fix'. + + If you are satisfied of the recovering, you can now proceed synching the array, + but take care that after synching you will no more able to retry the + 'fix' command! + + STEP 3 -> Sync + Run the 'sync' command to resyncronize the array with the new disk. + + To avoid a long time sync you have to use the '--find-by-name' option to + tell SnapRAID to ignore the fact that all the recovered files are now in + a different physical disk, and they don't need to be synched. + + :snapraid --find-by-name sync + + If everything was recovered, this command is immediate. + + STEP 4 -> Check + As paranoid check, you can now run a whole 'check' command to ensure that + everything is OK. + + :snapraid check + + This command will take a long time. + Content SnapRAID stores the list and checksums of your files in the content file. diff --git a/snapraid.txt b/snapraid.txt index 5ad108d2..8569a214 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -7,6 +7,7 @@ ========== snapraid [-c, --conf CONFIG] [-f, --filter PATTERN] + [-N, --find-by-name] [-Z, --force-zero] [-E, --force-empty] [-s, --start BLKSTART] [-t, --count BLKCOUNT] [-v, --verbose] @@ -253,6 +254,17 @@ SnapRAID provides the following options: This option can be used many times. In Unix, ensure to quote globbing chars if used. + -N, --find-by-name + When syncing finds the files by name instead than by inode. + This option allows a fast sync command after having replaced + one physical disk with another copying manually the files. + Without this option the 'sync' command would recognize that + the files were copied to a different disk, and will resync + them all. Instead, with this option a file with the correct + name, size and time will be assumed identical at the previous + one. + This option has effect only on the 'sync' and 'diff' commands. + -Z, --force-zero Forces the insecure operation of syncing a file with zero size that before was not. @@ -514,8 +526,72 @@ In Unix, when using globbing chars in the command line, you have to quote them. Otherwise the shell will try to expand them. -9 CONTENT -========= +9 RECOVERING +============ + +The worst happened, and you lost a disk! + +DO NOT PANIC! You will be able to recover it! + +The first thing you have to do is to avoid futher changes at you disk array. +Disable any remote connections to it, any scheduled processes, including any +scheduled SnapRAID nightly sync. + +Then proceed with the following steps. + +---- 9.0.1 STEP 1 -> Reconfigure ---- +You need some space to recover, even better if you have already an additional +disk, but in case also an external USB or remote one is enough. + +Change the SnapRAID configuration and change the 'disk' directory +of the failed disk to point to the new empty space. + +---- 9.0.2 STEP 2 -> Fix ---- +Run the fix command, storing the log in an external file with: + + snapraid fix 2>fix.log + +This command will take a long time. + +Take care that you need also few GB free to store the fix.log file, so run it +from a disk with some free space. + +Now you have recovered all the recoverable. If some file is partly or totally +unrecoverable, it will be renamed adding the ".unrecoverable" extension. + +You can get a detailed list of all the unrecoverable blocks in the fix.log file +checking all the lines starting with "unrecoverable:" + +If you are not satified of the recovering, you can retry it as many time you wish. +For example, if you have moved away some files from other disks after the last 'sync', +you can retry to put them inplace, and retry the 'fix'. + +If you are satisfied of the recovering, you can now proceed synching the array, +but take care that after synching you will no more able to retry the +'fix' command! + +---- 9.0.3 STEP 3 -> Sync ---- +Run the 'sync' command to resyncronize the array with the new disk. + +To avoid a long time sync you have to use the '--find-by-name' option to +tell SnapRAID to ignore the fact that all the recovered files are now in +a different physical disk, and they don't need to be synched. + + snapraid --find-by-name sync + +If everything was recovered, this command is immediate. + +---- 9.0.4 STEP 4 -> Check ---- +As paranoid check, you can now run a whole 'check' command to ensure that +everything is OK. + + snapraid check + +This command will take a long time. + + +10 CONTENT +========== SnapRAID stores the list and checksums of your files in the content file. @@ -528,24 +604,24 @@ for documentation. This file is read and written by the "sync" command, and only read by "fix" and "check". -9.1 blk_size SIZE ------------------ +10.1 blk_size SIZE +------------------ Defines the size of the block in bytes. It must match the size defined in the configuration file. -9.2 checksum CHECKSUM ---------------------- +10.2 checksum CHECKSUM +---------------------- Defines the checksum kind used. It can be "md5" or "murmur3". -9.3 map NAME INDEX ------------------- +10.3 map NAME INDEX +------------------- Defines the position INDEX of the disk NAME in the parity computation. -9.4 file DISK SIZE TIME INODE PATH ----------------------------------- +10.4 file DISK SIZE TIME INODE PATH +----------------------------------- Defines a file in the specified DISK. @@ -560,8 +636,8 @@ to recompute the parity. The PATH information is used in the "check" and "fix" commands to identify the file. -9.5 blk BLOCK HASH ------------------- +10.5 blk BLOCK HASH +------------------- Defines the ordered parity block list used by the last defined file. @@ -571,8 +647,8 @@ BLOCK is the block position in the "parity" file. HASH is the hash of the block. In the last block of the file, the HASH is the hash of only the used part of the block. -9.6 inv BLOCK [HASH] --------------------- +10.6 inv BLOCK [HASH] +--------------------- Like "blk", but inform that the parity of this block is invalid. @@ -582,7 +658,7 @@ This field is used only when you interrupt manually the "sync" command. -10 PARITY +11 PARITY ========= SnapRAID stores the redundancy information of your array in the parity @@ -607,7 +683,7 @@ because it's the last block of a file, it's assumed as filled with 0 at the end. -11 ENCODING +12 ENCODING =========== SnapRAID in Unix ignores any encoding. It simply read and stores the @@ -624,13 +700,13 @@ redirect the console output to a file, the resulting file is always in the UTF-8 format. -12 COPYRIGHT +13 COPYRIGHT ============ This file is Copyright (C) 2011 Andrea Mazzoleni -13 SEE ALSO +14 SEE ALSO =========== rsync(1) diff --git a/state.c b/state.c index ec23ad75..2f2130a8 100644 --- a/state.c +++ b/state.c @@ -27,6 +27,7 @@ void state_init(struct snapraid_state* state) state->gui = 0; state->force_zero = 0; state->force_empty = 0; + state->find_by_name = 0; state->expect_unrecoverable = 0; state->expect_recoverable = 0; state->need_write = 0; @@ -129,7 +130,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, i } } -void state_config(struct snapraid_state* state, const char* path, int verbose, int gui, int force_zero, int force_empty, int expect_unrecoverable, int expect_recoverable, int skip_device) +void state_config(struct snapraid_state* state, const char* path, int verbose, int gui, int force_zero, int force_empty, int find_by_name, int expect_unrecoverable, int expect_recoverable, int skip_device) { STREAM* f; unsigned line; @@ -138,6 +139,7 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i state->gui = gui; state->force_zero = force_zero; state->force_empty = force_empty; + state->find_by_name = find_by_name; state->expect_unrecoverable = expect_unrecoverable; state->expect_recoverable = expect_recoverable; @@ -757,6 +759,7 @@ void state_read(struct snapraid_state* state) /* insert the file in the file containers */ tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); /* start the block allocation of the file */ diff --git a/state.h b/state.h index ed2bd77c..1d620469 100644 --- a/state.h +++ b/state.h @@ -34,6 +34,7 @@ struct snapraid_state { int gui; /**< Gui output. */ int force_zero; /**< Forced dangerous operations of synching file now with zero size. */ int force_empty; /**< Forced dangerous operations of synching disk now empty. */ + int find_by_name; /**< Forced dangerous operations of synching a rewritten disk. */ int expect_unrecoverable; /**< Expect presence of unrecoverable error in checking or fixing. */ int expect_recoverable; /**< Expect presence of recoverable error in checking. */ int need_write; /**< If the state is changed. */ @@ -65,7 +66,7 @@ void state_done(struct snapraid_state* state); /** * Read the configuration file. */ -void state_config(struct snapraid_state* state, const char* path, int verbose, int gui, int force_zero, int force_empty, int expect_unrecoverable, int expect_recoverable, int skip_device); +void state_config(struct snapraid_state* state, const char* path, int verbose, int gui, int force_zero, int force_empty, int find_by_name, int expect_unrecoverable, int expect_recoverable, int skip_device); /** * Read the state.