Implement --checksum.
authorAndre Noll <maan@tuebingen.mpg.de>
Mon, 17 Apr 2017 17:06:37 +0000 (19:06 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Thu, 13 Jul 2017 20:54:03 +0000 (22:54 +0200)
It is considered good practice to run rsync with --checksum from time
to time. This patch implements the feature via the new --checksum
option.

The probabilistic approach was chosen so that dss does not need to
remember which snapshots were created with --checksum.

dss.c
dss.suite

diff --git a/dss.c b/dss.c
index 5e2ef46f71251c6a157f2f9df02900c8e534a3a9..3e626ab0113b1890277da115ea6c735dbdb690d7 100644 (file)
--- a/dss.c
+++ b/dss.c
@@ -1347,6 +1347,7 @@ static void create_rsync_argv(char ***argv, int64_t *num)
        char *logname;
        int i = 0, j, N = OPT_GIVEN(DSS, RSYNC_OPTION);
        struct snapshot_list sl;
        char *logname;
        int i = 0, j, N = OPT_GIVEN(DSS, RSYNC_OPTION);
        struct snapshot_list sl;
+       static bool seeded;
 
        dss_get_snapshot_list(&sl);
        assert(!name_of_reference_snapshot);
 
        dss_get_snapshot_list(&sl);
        assert(!name_of_reference_snapshot);
@@ -1357,6 +1358,14 @@ static void create_rsync_argv(char ***argv, int64_t *num)
        (*argv)[i++] = dss_strdup("rsync");
        (*argv)[i++] = dss_strdup("-a");
        (*argv)[i++] = dss_strdup("--delete");
        (*argv)[i++] = dss_strdup("rsync");
        (*argv)[i++] = dss_strdup("-a");
        (*argv)[i++] = dss_strdup("--delete");
+       if (!seeded) {
+               srandom((unsigned)time(NULL)); /* no need to be fancy here */
+               seeded = true;
+       }
+       if (1000 * (random() / (RAND_MAX + 1.0)) < OPT_UINT32_VAL(DSS, CHECKSUM)) {
+               DSS_NOTICE_LOG(("adding --checksum to rsync options\n"));
+               (*argv)[i++] = dss_strdup("--checksum");
+       }
        for (j = 0; j < N; j++)
                (*argv)[i++] = dss_strdup(lls_string_val(j,
                        OPT_RESULT(DSS, RSYNC_OPTION)));
        for (j = 0; j < N; j++)
                (*argv)[i++] = dss_strdup(lls_string_val(j,
                        OPT_RESULT(DSS, RSYNC_OPTION)));
index e7473cb6d2f4ab619c753262664ff5c377ed21c6..e69cc28630c8a39359cba3aead33ab3b847011a8 100644 (file)
--- a/dss.suite
+++ b/dss.suite
@@ -109,6 +109,29 @@ caption = Subcommands
                        Set this if the user that runs dss is different from the user on the
                        remote host.
                [/help]
                        Set this if the user that runs dss is different from the user on the
                        remote host.
                [/help]
+       [option checksum]
+               summary = run rsync with --checksum occasionally
+               typestr = permille
+               arg_info = required_arg
+               arg_type = uint32
+               default_val = 0
+               [help]
+                       If a file on the backup becomes corrupt in a way that file size
+                       and modification time still match the original file, rsync will not
+                       consider the file for transfer ("quick check"). Hence the corruption
+                       stays on the backup until the file is modified on the source.
+                       The --checksum option of rsync disables the quick check and compares
+                       the contents of each file, fixing such corruptions. Since computing
+                       the checksums adds a significant slowdown due to a lot of disk I/O,
+                       the option is not enabled by default.
+
+                       The argument to the --checksum option of dss is a number between 0
+                       and 1000, inclusively, which determines the probability of adding
+                       --checksum to the rsync options each time a snapshot is created. The
+                       default value zero means to never add the option. The value 100 will
+                       create every tenth snapshot (on average) using checksums, and the
+                       value 1000 will always pass --checksum to rsync.
+               [/help]
        [option rsync-option]
                short_opt = O
                summary = further rsync options
        [option rsync-option]
                short_opt = O
                summary = further rsync options