From da08ca4497c69c8170cef415bfd3bf87feb0282a Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Fri, 13 Jun 2014 18:23:24 +0200 Subject: [PATCH] Makes a backup copy of the content file. Before overwriting the existing content file, rename it adding the .backup extension, but only if such content file was read and validated. --- HISTORY | 3 +++ TODO | 7 ------- cmdline/elem.c | 10 ++++++++++ cmdline/state.c | 23 +++++++++++++++++++++++ cmdline/state.h | 1 + snapraid.1 | 7 ++++--- snapraid.d | 7 ++++--- snapraid.txt | 7 ++++--- 8 files changed, 49 insertions(+), 16 deletions(-) diff --git a/HISTORY b/HISTORY index b68a8dc8..d4287845 100644 --- a/HISTORY +++ b/HISTORY @@ -5,6 +5,9 @@ SnapRAID HISTORY ================= * The -N, --force-nocopy option now also works if you used previously "sync" commands without it. + * When saving the content file keep a copy of the previos one adding + the ".backup" extension. + * Auto exclude the lock file. 6.2 2014/5 ========== diff --git a/TODO b/TODO index a9e7f6ec..afafea4a 100644 --- a/TODO +++ b/TODO @@ -5,13 +5,6 @@ This is the list of TODO items for SnapRAID. - Next -* Keep backup copies of the content file. -Like snapraid.content.1, snapraid.content.2, snapraid.content.3 and so on. -Note that the rotation should happen only one time for each sync, -and not for intermediate sync write. - -* Auto exclude lock files. - * Measures the time waited in blocking syscall for each disk, and prints stats of the disk speeds when the command finish, or when it's running. diff --git a/cmdline/elem.c b/cmdline/elem.c index 42f1f5de..e272435a 100644 --- a/cmdline/elem.c +++ b/cmdline/elem.c @@ -298,6 +298,16 @@ int filter_content(tommy_list* contentlist, const char* path) pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); if (pathcmp(tmp, path) == 0) return -1; + + /* exclude also the ".backup" copy */ + pathprint(tmp, sizeof(tmp), "%s.backup", content->content); + if (pathcmp(tmp, path) == 0) + return -1; + + /* exclude also the ".lock" file */ + pathprint(tmp, sizeof(tmp), "%s.lock", content->content); + if (pathcmp(tmp, path) == 0) + return -1; } return 0; diff --git a/cmdline/state.c b/cmdline/state.c index 41e7b9d4..f1ff89c6 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -4008,6 +4008,9 @@ void state_read(struct snapraid_state* state) state_map(state); state_content_check(state, path); + + /* mark that we read the content file, and it passed all the checks */ + state->checked_read = 1; } void state_write(struct snapraid_state* state) @@ -4087,6 +4090,24 @@ void state_write(struct snapraid_state* state) while (i) { struct snapraid_content* content = i->data; char tmp[PATH_MAX]; + char backup[PATH_MAX]; + + /* if the content file was checked reading it, it's a good candidate */ + /* to be renamed as backup copy */ + if (state->checked_read) { + pathprint(backup, sizeof(backup), "%s.backup", content->content); + if (rename(content->content, backup) != 0) { + /* ignore the error for not existing */ + if (errno != ENOENT) { + /* LCOV_EXCL_START */ + fprintf(stderr, "Error renaming the content file '%s' to '%s' in rename(). %s.\n", content->content, backup, strerror(errno)); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + } + } + + /* now renames the just written copy with the correct name */ pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); if (rename(tmp, content->content) != 0) { /* LCOV_EXCL_START */ @@ -4094,10 +4115,12 @@ void state_write(struct snapraid_state* state) exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } + i = i->next; } state->need_write = 0; /* no write needed anymore */ + state->checked_read = 0; /* what we wrote is not checked in read */ } void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tommy_list* filterlist_disk, int filter_missing, int filter_error) diff --git a/cmdline/state.h b/cmdline/state.h index 853e8ea7..8de6f8a0 100644 --- a/cmdline/state.h +++ b/cmdline/state.h @@ -91,6 +91,7 @@ struct snapraid_state { int filter_hidden; /**< Filter out hidden files. */ uint64_t autosave; /**< Autosave after the specified amount of data. 0 to disable. */ int need_write; /**< If the state is changed. */ + int checked_read; /**< If the state was read and checked. */ uint32_t block_size; /**< Block size in bytes. */ unsigned raid_mode; /**< Raid mode to use. RAID_MODE_DEFAULT or RAID_MODE_ALTERNATE. */ char parity_path[LEV_MAX][PATH_MAX]; /**< Path of the parity file. One for each parity. */ diff --git a/snapraid.1 b/snapraid.1 index 216c37d7..94459f15 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -1389,10 +1389,11 @@ SnapRAID stores the list and checksums of your files in the content file. It\'s a binary file, listing all the files present in your disk array, with all the checksums to verify their integrity. .PP -You do not need to understand its format to use SnapRAID. -.PP This file is read and written by the \[dq]sync\[dq] and \[dq]scrub\[dq] commands, and -only read by \[dq]fix\[dq], \[dq]check\[dq] and \[dq]status\[dq]. +read by \[dq]fix\[dq], \[dq]check\[dq] and \[dq]status\[dq]. +.PP +When saving a new copy, the previous one is renamed adding the \[dq].backup\[dq] +extension. .SH PARITY SnapRAID stores the parity information of your array in the parity files. diff --git a/snapraid.d b/snapraid.d index ff2f504e..a6edfa5e 100644 --- a/snapraid.d +++ b/snapraid.d @@ -1007,10 +1007,11 @@ Content It's a binary file, listing all the files present in your disk array, with all the checksums to verify their integrity. - You do not need to understand its format to use SnapRAID. - This file is read and written by the "sync" and "scrub" commands, and - only read by "fix", "check" and "status". + read by "fix", "check" and "status". + + When saving a new copy, the previous one is renamed adding the ".backup" + extension. Parity SnapRAID stores the parity information of your array in the parity diff --git a/snapraid.txt b/snapraid.txt index bf8e923e..69264b8e 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -1090,10 +1090,11 @@ SnapRAID stores the list and checksums of your files in the content file. It's a binary file, listing all the files present in your disk array, with all the checksums to verify their integrity. -You do not need to understand its format to use SnapRAID. - This file is read and written by the "sync" and "scrub" commands, and -only read by "fix", "check" and "status". +read by "fix", "check" and "status". + +When saving a new copy, the previous one is renamed adding the ".backup" +extension. 11 PARITY