From 1c07ed86f8907c514709fb21a83a7573ec8c2ab4 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sat, 19 Oct 2013 13:24:35 +0200 Subject: [PATCH] Changes the output format to make it more consistent between commands. --- HISTORY | 16 +++++++++------- check.c | 40 ++++++++++++++++++++-------------------- dup.c | 11 +++++++---- elem.c | 9 ++++++++- elem.h | 7 ++++++- list.c | 28 +++++++++++++++++++++------- scan.c | 50 ++++++++++++++++++++++++++++---------------------- scrub.c | 6 ++++-- snapraid.1 | 7 ++++++- snapraid.d | 8 +++++++- snapraid.txt | 20 ++++++++++++++------ state.c | 40 ++++++++++++++++++++-------------------- sync.c | 6 ++++-- 13 files changed, 154 insertions(+), 94 deletions(-) diff --git a/HISTORY b/HISTORY index 831c55c4..9afb8127 100644 --- a/HISTORY +++ b/HISTORY @@ -9,20 +9,22 @@ SnapRAID HISTORY high performant parity generator matrix used. Extensions supporting more disks and more parities are possible, but not yet implemented. - * New parity computation using SSSE3 and AVX instructions for the - best performance. + * Faster parity computation for SSSE3 and AVX CPUs. + * Faster parity computation for ARM 64 bit CPUs. * In sync, if a silent error is found, directly mark the block as bad like in scrub, and continue with the sync process. * Sort files by inode when listing the directory. This improves - performance when listing directories. + the scanning performance. + * For files with changes only in some blocks, updates the parity + only for blocks that really are changed. + This improves the performance in sync for edited files. + * Added a new "list" command to see the stored list of files. * Removed the detailed list of errors from the screen output. To get it you must explicitely use the -l, --log option. It's now too detailed for the screen, because it contains a lot of info. - * For files with changes only in some blocks, updates the parity - only for blocks that really are changed. - This improves the performance in sync for edited files. - * Faster parity computation for ARM 64 bit CPU. + * Changed the output format of some commands to make it similar + at the new "list" one. * Reduced memory usage avoiding to allocate unnecessary memory. 4.3 2013/10 diff --git a/check.c b/check.c index 4da95d2b..a9429f59 100644 --- a/check.c +++ b/check.c @@ -1130,7 +1130,7 @@ static int state_check_process(struct snapraid_state* state, int check, int fix, fprintf(stdlog, "status:recovered:%s:%s\n", handle[j].disk->name, file->sub); if (state->opt.verbose) { - printf("Recovered '%s'\n", path); + printf("recovered %s\n", path); } inode = handle[j].st.st_ino; @@ -1172,23 +1172,23 @@ static int state_check_process(struct snapraid_state* state, int check, int fix, if (!check) { fprintf(stdlog, "status:damaged:%s:%s\n", handle[j].disk->name, file->sub); if (state->opt.verbose) { - printf("Damaged '%s'\n", path); + printf("damaged %s\n", path); } } else { fprintf(stdlog, "status:unrecoverable:%s:%s\n", handle[j].disk->name, file->sub); if (state->opt.verbose) { - printf("Unrecoverable '%s'\n", path); + printf("unrecoverable %s\n", path); } } } else if (file_flag_has(file, FILE_IS_FIXED)) { fprintf(stdlog, "status:recoverable:%s:%s\n", handle[j].disk->name, file->sub); if (state->opt.verbose) { - printf("Recoverable '%s'\n", path); + printf("recoverable %s\n", path); } } else { fprintf(stdlog, "status:correct:%s:%s\n", handle[j].disk->name, file->sub); if (state->opt.verbose) { - printf("Correct '%s'\n", path); + printf("correct %s\n", path); } } } @@ -1318,7 +1318,7 @@ close_and_continue: fprintf(stdlog, "status:recovered:%s:%s\n", disk->name, file->sub); if (state->opt.verbose) { - printf("Recovered '%s%s'\n", disk->dir, file->sub); + printf("recovered %s%s\n", disk->dir, file->sub); } } } @@ -1483,7 +1483,7 @@ close_and_continue: fprintf(stdlog, "status:recovered:%s:%s\n", disk->name, link->sub); if (state->opt.verbose) { - printf("Recovered '%s%s'\n", disk->dir, link->sub); + printf("recovered %s%s\n", disk->dir, link->sub); } } } @@ -1551,7 +1551,7 @@ close_and_continue: fprintf(stdlog, "status:ok:%s:%s\n", disk->name, dir->sub); if (state->opt.verbose) { - printf("Recovered '%s%s'\n", disk->dir, dir->sub); + printf("recovered %s%s\n", disk->dir, dir->sub); } } } @@ -1620,22 +1620,22 @@ bail: } if (error || recovered_error || unrecoverable_error) { - if (error) - printf("%u read/data errors\n", error); - else - printf("No read/data errors\n"); + printf("\n"); + printf("%8u read/data errors\n", error); if (fix) { - if (recovered_error) - printf("%u recovered errors\n", recovered_error); - else - printf("No recovered errors\n"); + printf("%8u recovered errors\n", recovered_error); } - if (unrecoverable_error) - printf("%u UNRECOVERABLE errors\n", unrecoverable_error); - else { + if (unrecoverable_error) { + printf("%8u UNRECOVERABLE errors\n", unrecoverable_error); + printf("DANGER! There are unrecoverable errors!\n"); + } else { /* without checking, we don't know if they are really recoverable or not */ if (check) - printf("No unrecoverable errors\n"); + printf("%8u unrecoverable errors\n", unrecoverable_error); + if (fix) + printf("Everything RECOVERED\n"); + else + printf("WARNING! There are errors!\n"); } } else { printf("Everything OK\n"); diff --git a/dup.c b/dup.c index 0c92eec6..0434ba6f 100644 --- a/dup.c +++ b/dup.c @@ -96,6 +96,8 @@ void state_dup(struct snapraid_state* state) count = 0; size = 0; + printf("Comparing...\n"); + /* for each disk */ for(i=state->disklist;i!=0;i=i->next) { tommy_node* j; @@ -124,8 +126,7 @@ void state_dup(struct snapraid_state* state) ++count; size += dup->file->size; fprintf(stdlog, "dup:%s:%s:%s:%s:%"PRIu64": dup\n", disk->name, file->sub, dup->disk->name, dup->file->sub, dup->file->size); - printf("%"PRIu64" '%s%s'\n", file->size / (1024*1024), disk->dir, file->sub); - printf("dup '%s%s'\n", dup->disk->dir, dup->file->sub); + 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->nodeset, hash, hash32); @@ -137,10 +138,12 @@ void state_dup(struct snapraid_state* state) tommy_list_foreach(&hashlist, (tommy_foreach_func*)hash_free); tommy_hashdyn_done(&hashset); + printf("\n"); + printf("%8u duplicates, for %"PRIu64" MiB\n", count, size / (1024*1024)); if (count) - printf("%u duplicates, for %"PRIu64" MiB.\n", count, size / (1024*1024)); + printf("There are duplicates!\n"); else - printf("No duplicate\n"); + printf("No duplicates\n"); fprintf(stdlog, "summary:dup_count:%u\n", count); fprintf(stdlog, "summary:dup_size:%"PRIu64"\n", size); diff --git a/elem.c b/elem.c index 3cb551cb..324e6c41 100644 --- a/elem.c +++ b/elem.c @@ -479,13 +479,20 @@ void link_free(struct snapraid_link* link) free(link); } -int link_name_compare(const void* void_arg, const void* void_data) +int link_name_compare_to_arg(const void* void_arg, const void* void_data) { const char* arg = void_arg; const struct snapraid_link* link = void_data; return strcmp(arg, link->sub); } +int link_alpha_compare(const void* void_a, const void* void_b) +{ + const struct snapraid_link* link_a = void_a; + const struct snapraid_link* link_b = void_b; + return strcmp(link_a->sub, link_b->sub); +} + struct snapraid_dir* dir_alloc(const char* sub) { struct snapraid_dir* dir; diff --git a/elem.h b/elem.h index 8079ebb6..7acf0ca1 100644 --- a/elem.h +++ b/elem.h @@ -685,7 +685,12 @@ void link_free(struct snapraid_link* link); /** * Compare a link with a name. */ -int link_name_compare(const void* void_arg, const void* void_data); +int link_name_compare_to_arg(const void* void_arg, const void* void_data); + +/** + * Compares links by path. + */ +int link_alpha_compare(const void* void_a, const void* void_b); /** * Computes the hash of a link name. diff --git a/list.c b/list.c index ed3a3fc4..26815da2 100644 --- a/list.c +++ b/list.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Andrea Mazzoleni + * Copyright (C) 2013 Andrea Mazzoleni * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,6 +37,8 @@ void state_list(struct snapraid_state* state) file_size = 0; link_count = 0; + printf("Listing...\n"); + /* for each disk */ for(i=state->disklist;i!=0;i=i->next) { tommy_node* j; @@ -68,18 +70,25 @@ 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); + 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) { + printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000); + } + printf(" "); } printf("%s%s\n", disk->dir, file->sub); } + /* sort by name */ + tommy_list_sort(&disk->linklist, link_alpha_compare); + /* for each link */ for(j=disk->linklist;j!=0;j=j->next) { struct snapraid_link* link = j->data; const char* type; - switch (link->flag &FILE_IS_LINK_MASK) { - case FILE_IS_HARDLINK : type = "link"; break; + switch (link->flag & FILE_IS_LINK_MASK) { + case FILE_IS_HARDLINK : type = "hardlink"; break; case FILE_IS_SYMLINK : type = "symlink"; break; case FILE_IS_SYMDIR : type = "symdir"; break; case FILE_IS_JUNCTION : type = "junction"; break; @@ -90,12 +99,17 @@ void state_list(struct snapraid_state* state) fprintf(stdlog, "link_%s:%s:%s:%s\n", type, disk->name, link->sub, link->linkto); - printf("%12s %s%s -> %s%s\n", type, disk->dir, link->sub, disk->dir, link->linkto); + printf("%12s ", type); + printf(" "); + if (state->opt.verbose) { + printf(" "); + } + printf("%s%s -> %s%s\n", disk->dir, link->sub, disk->dir, link->linkto); } } printf("\n"); - printf("%u files, for %"PRIu64" MiB.\n", file_count, file_size / (1024*1024)); - printf("%u links.\n", link_count); + printf("%8u files, for %"PRIu64" GiB\n", file_count, file_size / (1024*1024*1024)); + printf("%8u links\n", link_count); fprintf(stdlog, "summary:file_count:%u\n", file_count); fprintf(stdlog, "summary:file_size:%"PRIu64"\n", file_size); diff --git a/scan.c b/scan.c index 8fbc6ae6..f0f022e4 100644 --- a/scan.c +++ b/scan.c @@ -77,7 +77,7 @@ static void scan_link(struct snapraid_scan* scan, struct snapraid_state* state, struct snapraid_link* link; /* check if the link already exists */ - link = tommy_hashdyn_search(&disk->linkset, link_name_compare, sub, link_name_hash(sub)); + link = tommy_hashdyn_search(&disk->linkset, link_name_compare_to_arg, sub, link_name_hash(sub)); if (link) { /* check if multiple files have the same name */ if (link_flag_has(link, FILE_IS_PRESENT)) { @@ -106,7 +106,7 @@ static void scan_link(struct snapraid_scan* scan, struct snapraid_state* state, fprintf(stdlog, "scan:update:%s:%s\n", disk->name, link->sub); if (output) { - printf("Update '%s%s'\n", disk->dir, link->sub); + printf("update %s%s\n", disk->dir, link->sub); } /* update it */ @@ -123,7 +123,7 @@ static void scan_link(struct snapraid_scan* scan, struct snapraid_state* state, fprintf(stdlog, "scan:add:%s:%s\n", disk->name, sub); if (output) { - printf("Add '%s%s'\n", disk->dir, sub); + printf("add %s%s\n", disk->dir, sub); } /* and continue to insert it */ @@ -360,7 +360,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, fprintf(stdlog, "scan:move:%s:%s:%s\n", disk->name, file->sub, sub); if (output) { - printf("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 */ @@ -481,7 +481,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, fprintf(stdlog, "scan:restore:%s:%s\n", disk->name, sub); if (output) { - printf("Restore '%s%s'\n", disk->dir, sub); + printf("restore %s%s\n", disk->dir, sub); } /* remove from the inode set */ @@ -530,9 +530,9 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, fprintf(stdlog, "scan:update:%s:%s\n", disk->name, file->sub); if (output) { if (file->size != st->st_size) - printf("Update '%s%s' new size\n", disk->dir, file->sub); + printf("resize %s%s\n", disk->dir, file->sub); else - printf("Update '%s%s' new modification time\n", disk->dir, file->sub); + printf("update %s%s\n", disk->dir, file->sub); } /* remove it */ @@ -545,7 +545,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, fprintf(stdlog, "scan:add:%s:%s\n", disk->name, sub); if (output) { - printf("Add '%s%s'\n", disk->dir, sub); + printf("add %s%s\n", disk->dir, sub); } /* and continue to insert it */ @@ -628,7 +628,7 @@ static void scan_emptydir(struct snapraid_scan* scan, struct snapraid_state* sta fprintf(stdlog, "scan:add:%s:%s\n", disk->name, sub); if (output) { - printf("Add '%s%s'\n", disk->dir, sub); + printf("add %s%s\n", disk->dir, sub); } /* and continue to insert it */ @@ -965,6 +965,9 @@ void state_scan(struct snapraid_state* state, int output) tommy_list_init(&scanlist); + if (output) + printf("Comparing...\n"); + for(i=state->disklist;i!=0;i=i->next) { struct snapraid_disk* disk = i->data; struct snapraid_scan* scan; @@ -988,7 +991,8 @@ void state_scan(struct snapraid_state* state, int output) tommy_list_insert_tail(&scanlist, &scan->node, scan); - printf("Scanning disk %s...\n", disk->name); + if (!output) + printf("Scanning disk %s...\n", disk->name); /* check if the disk supports persistent inodes */ ret = fsinfo(disk->dir, &has_persistent_inode); @@ -1037,7 +1041,7 @@ void state_scan(struct snapraid_state* state, int output) fprintf(stdlog, "scan:remove:%s:%s\n", disk->name, file->sub); if (output) { - printf("Remove '%s%s'\n", disk->dir, file->sub); + printf("remove %s%s\n", disk->dir, file->sub); } scan_file_remove(state, disk, file); @@ -1058,7 +1062,7 @@ void state_scan(struct snapraid_state* state, int output) fprintf(stdlog, "scan:remove:%s:%s\n", disk->name, link->sub); if (output) { - printf("Remove '%s%s'\n", disk->dir, link->sub); + printf("remove %s%s\n", disk->dir, link->sub); } scan_link_remove(state, disk, link); @@ -1079,7 +1083,7 @@ void state_scan(struct snapraid_state* state, int output) fprintf(stdlog, "scan:remove:%s:%s\n", disk->name, dir->sub); if (output) { - printf("Remove '%s%s'\n", disk->dir, dir->sub); + printf("remove %s%s\n", disk->dir, dir->sub); } scan_emptydir_remove(state, disk, dir); @@ -1247,13 +1251,15 @@ void state_scan(struct snapraid_state* state, int output) total.count_insert += scan->count_insert; } - if (state->opt.verbose) { - printf("\tequal %d\n", total.count_equal); - printf("\tmoved %d\n", total.count_move); - printf("\trestored %d\n", total.count_restore); - printf("\tchanged %d\n", total.count_change); - printf("\tremoved %d\n", total.count_remove); - printf("\tadded %d\n", total.count_insert); + if (state->opt.verbose || output) { + if (output) + printf("\n"); + printf("%8u equal\n", total.count_equal); + printf("%8u moved\n", total.count_move); + printf("%8u restored\n", total.count_restore); + printf("%8u changed\n", total.count_change); + printf("%8u removed\n", total.count_remove); + printf("%8u added\n", total.count_insert); } fprintf(stdlog, "summary:equal:%u\n", total.count_equal); @@ -1267,9 +1273,9 @@ void state_scan(struct snapraid_state* state, int output) if (output) { if (no_difference) { - printf("No difference\n"); + printf("No differences\n"); } else { - printf("There are differences\n"); + printf("There are differences!\n"); } } diff --git a/scrub.c b/scrub.c index 24ee1c88..32b24c1d 100644 --- a/scrub.c +++ b/scrub.c @@ -385,8 +385,10 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par state_progress_end(state, countpos, countmax, countsize); if (error || silent_error) { - printf("%u read errors\n", error); - printf("%u data errors\n", silent_error); + printf("\n"); + printf("%8u read errors\n", error); + printf("%8u data errors\n", silent_error); + printf("WARNING! There are errors!\n"); } else { /* print the result only if processed something */ if (countpos != 0) diff --git a/snapraid.1 b/snapraid.1 index db91995a..f1509be8 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -38,7 +38,7 @@ snapraid [\(hyc, \(hy\(hyconf CONFIG] .PD 0 .PP .PD - sync|status|scrub|diff|dup|pool|check|fix|rehash + sync|status|scrub|list|diff|dup|pool|check|fix|rehash .PD 0 .PP .PD @@ -560,6 +560,11 @@ are the blocks without checking, and all the recorded silent errors encoutered while scrubbing. .PP Nothing is modified. +.SS list +Lists all the files contained in the array at the time of the +last \(a"sync\(a" command. +.PP +Nothing is modified. .SS diff Lists all the files modified from the last \(a"sync\(a" command that have to recompute their redundancy data. diff --git a/snapraid.d b/snapraid.d index f3a6b707..255a8b6c 100644 --- a/snapraid.d +++ b/snapraid.d @@ -11,7 +11,7 @@ Synopsis : [-U, --force-uuid] [-D, --force-device] : [-v, --verbose] [-l, --log FILE] : [-s, --start BLKSTART] [-t, --count BLKCOUNT] - : sync|status|scrub|diff|dup|pool|check|fix|rehash + : sync|status|scrub|list|diff|dup|pool|check|fix|rehash :snapraid [-V, --version] [-h, --help] [-C, --gen-conf CONTENT] @@ -345,6 +345,12 @@ Commands Nothing is modified. + list + Lists all the files contained in the array at the time of the + last "sync" command. + + Nothing is modified. + diff Lists all the files modified from the last "sync" command that have to recompute their redundancy data. diff --git a/snapraid.txt b/snapraid.txt index 7a314901..351f675f 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -15,7 +15,7 @@ snapraid [-c, --conf CONFIG] [-U, --force-uuid] [-D, --force-device] [-v, --verbose] [-l, --log FILE] [-s, --start BLKSTART] [-t, --count BLKCOUNT] - sync|status|scrub|diff|dup|pool|check|fix|rehash + sync|status|scrub|list|diff|dup|pool|check|fix|rehash snapraid [-V, --version] [-h, --help] [-C, --gen-conf CONTENT] @@ -379,7 +379,15 @@ errors encoutered while scrubbing. Nothing is modified. -5.6 diff +5.6 list +-------- + +Lists all the files contained in the array at the time of the +last "sync" command. + +Nothing is modified. + +5.7 diff -------- Lists all the files modified from the last "sync" command that @@ -390,7 +398,7 @@ size and inode. Nothing is modified. -5.7 dup +5.8 dup ------- Lists all the duplicate files. Two files are assumed equal if their @@ -399,7 +407,7 @@ precomputed hashes are used. Nothing is modified. -5.8 pool +5.9 pool -------- Creates or updates in the "pooling" directory a virtual view of all @@ -414,8 +422,8 @@ view of the array. Any othe regular file is left in place. Nothing is modified outside the pool directory. -5.9 rehash ----------- +5.10 rehash +----------- Schedules a rehash of the whole array. diff --git a/state.c b/state.c index 1d178918..313bab8e 100644 --- a/state.c +++ b/state.c @@ -1646,11 +1646,11 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE state->loaded_blockmax = blockmax; if (state->opt.verbose) { - printf("\tfile %u\n", count_file); - printf("\tblock %u\n", count_block); - printf("\thardlink %u\n", count_hardlink); - printf("\tsymlink %u\n", count_symlink); - printf("\temptydir %u\n", count_dir); + printf("%8u files\n", count_file); + printf("%8u blocks\n", count_block); + printf("%8u hardlinks\n", count_hardlink); + printf("%8u symlinks\n", count_symlink); + printf("%8u empty dirs\n", count_dir); } } @@ -1961,11 +1961,11 @@ static void state_write_text(struct snapraid_state* state, STREAM* f) } if (state->opt.verbose) { - printf("\tfile %u\n", count_file); - printf("\tblock %u\n", count_block); - printf("\thardlink %u\n", count_hardlink); - printf("\tsymlink %u\n", count_symlink); - printf("\temptydir %u\n", count_dir); + printf("%8u files\n", count_file); + printf("%8u blocks\n", count_block); + printf("%8u hardlinks\n", count_hardlink); + printf("%8u symlinks\n", count_symlink); + printf("%8u empty dirs\n", count_dir); } } @@ -2706,11 +2706,11 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST state->loaded_blockmax = blockmax; if (state->opt.verbose) { - printf("\tfile %u\n", count_file); - printf("\tblock %u\n", count_block); - printf("\thardlink %u\n", count_hardlink); - printf("\tsymlink %u\n", count_symlink); - printf("\temptydir %u\n", count_dir); + printf("%8u files\n", count_file); + printf("%8u blocks\n", count_block); + printf("%8u hardlinks\n", count_hardlink); + printf("%8u symlinks\n", count_symlink); + printf("%8u empty dirs\n", count_dir); } } @@ -3089,11 +3089,11 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f) } if (state->opt.verbose) { - printf("\tfile %u\n", count_file); - printf("\tblock %u\n", count_block); - printf("\thardlink %u\n", count_hardlink); - printf("\tsymlink %u\n", count_symlink); - printf("\temptydir %u\n", count_dir); + printf("%8u files\n", count_file); + printf("%8u blocks\n", count_block); + printf("%8u hardlinks\n", count_hardlink); + printf("%8u symlinks\n", count_symlink); + printf("%8u empty dirs\n", count_dir); } } diff --git a/sync.c b/sync.c index 2ad5ce3d..14550a10 100644 --- a/sync.c +++ b/sync.c @@ -445,8 +445,10 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari state_progress_end(state, countpos, countmax, countsize); if (error || silent_error) { - printf("%u read/write errors\n", error); - printf("%u data errors\n", silent_error); + printf("\n"); + printf("%8u read/write errors\n", error); + printf("%8u data errors\n", silent_error); + printf("WARNING! There are errors!\n"); } else { /* print the result only if processed something */ if (countpos != 0)