]> git.tuebingen.mpg.de Git - dss.git/blobdiff - dss.c
Merge branch 'refs/heads/t/multiple-source-dirs'
[dss.git] / dss.c
diff --git a/dss.c b/dss.c
index 9390f48c9f8f16a810680b374050ae45ba6349b0..a219cfd37b4569fbc3aa67fb2d4443a950353197 100644 (file)
--- a/dss.c
+++ b/dss.c
@@ -81,7 +81,7 @@ static int64_t next_snapshot_time;
 static struct timeval next_removal_check;
 /** Creation time of the snapshot currently being created. */
 static int64_t current_snapshot_creation_time;
-/** The snapshot currently being removed. */
+/* Set by the pre-rm hook, cleared by handle_remove_exit(). */
 struct snapshot *snapshot_currently_being_removed;
 /** Needed by the post-create hook. */
 static char *path_to_last_complete_snapshot;
@@ -158,7 +158,7 @@ static void dump_dss_config(const char *msg)
        fprintf(log, "\n*** internal state ***\n\n");
        fprintf(log,
                "pid: %d\n"
-               "logile: %s\n"
+               "logfile: %s\n"
                "snapshot_currently_being_removed: %s\n"
                "path_to_last_complete_snapshot: %s\n"
                "reference_snapshot: %s\n"
@@ -574,9 +574,6 @@ static int is_reference_snapshot(struct snapshot *s)
        return strcmp(s->name, name_of_reference_snapshot)? 0 : 1;
 }
 
-/*
- * return: 0: no redundant snapshots, 1: rm process started, negative: error
- */
 static struct snapshot *find_redundant_snapshot(struct snapshot_list *sl)
 {
        int i, interval;
@@ -1301,9 +1298,7 @@ static int handle_signal(void)
        switch (sig) {
        case SIGINT:
        case SIGTERM:
-               kill_children();
-               ret = -E_SIGNAL;
-               break;
+               return -E_SIGNAL;
        case SIGHUP:
                ret = handle_sighup();
                break;
@@ -1388,7 +1383,7 @@ out:
 static void create_rsync_argv(char ***argv, int64_t *num)
 {
        char *logname;
-       int i = 0, j, N = OPT_GIVEN(DSS, RSYNC_OPTION);
+       int i = 0, j, N;
        struct snapshot_list sl;
        static bool seeded;
 
@@ -1397,7 +1392,13 @@ static void create_rsync_argv(char ***argv, int64_t *num)
        name_of_reference_snapshot = name_of_newest_complete_snapshot(&sl);
        free_snapshot_list(&sl);
 
-       *argv = dss_malloc((15 + N) * sizeof(char *));
+       /*
+        * We specify up to 6 arguments, one argument per given rsync option
+        * and one argument per given source dir. We also need space for the
+        * terminating NULL pointer.
+        */
+       N = OPT_GIVEN(DSS, RSYNC_OPTION) + OPT_GIVEN(DSS, SOURCE_DIR);
+       *argv = dss_malloc((7 + N) * sizeof(char *));
        (*argv)[i++] = dss_strdup("rsync");
        (*argv)[i++] = dss_strdup("-a");
        (*argv)[i++] = dss_strdup("--delete");
@@ -1409,7 +1410,7 @@ static void create_rsync_argv(char ***argv, int64_t *num)
                DSS_NOTICE_LOG(("adding --checksum to rsync options\n"));
                (*argv)[i++] = dss_strdup("--checksum");
        }
-       for (j = 0; j < N; j++)
+       for (j = 0; j < OPT_GIVEN(DSS, RSYNC_OPTION); j++)
                (*argv)[i++] = dss_strdup(lls_string_val(j,
                        OPT_RESULT(DSS, RSYNC_OPTION)));
        if (name_of_reference_snapshot) {
@@ -1419,14 +1420,34 @@ static void create_rsync_argv(char ***argv, int64_t *num)
        } else
                DSS_INFO_LOG(("no suitable reference snapshot found\n"));
        logname = dss_logname();
-       if (use_rsync_locally(logname))
-               (*argv)[i++] = dss_strdup(OPT_STRING_VAL(DSS, SOURCE_DIR));
-       else
-               (*argv)[i++] = make_message("%s@%s:%s/",
-                       OPT_GIVEN(DSS, REMOTE_USER)?
-                               OPT_STRING_VAL(DSS, REMOTE_USER) : logname,
-                       OPT_STRING_VAL(DSS, REMOTE_HOST),
-                       OPT_STRING_VAL(DSS, SOURCE_DIR));
+       if (use_rsync_locally(logname)) {
+               for (j = 0; j < OPT_GIVEN(DSS, SOURCE_DIR); j++)
+                       (*argv)[i++] = dss_strdup(lls_string_val(j,
+                               OPT_RESULT(DSS, SOURCE_DIR)));
+       } else {
+               /*
+                * dss-1.0 and earlier did not support multiple source
+                * directories.  These versions appended a slash to the end of
+                * the source directory to make sure that only the contents of
+                * the single source directory, but not the directory itself,
+                * are copied to the destination. For multiple source
+                * directories, however, this is not a good idea because the
+                * source directories may well contain identical file names,
+                * which would then be copied to the same location on the
+                * destination, overwriting each other. Moreover, we want the
+                * directory on the destination match the source. To preserve
+                * the old behaviour, we thus have to special-case N=1.
+                */
+               for (j = 0; j < OPT_GIVEN(DSS, SOURCE_DIR); j++) {
+                       (*argv)[i++] = make_message("%s@%s:%s%s",
+                               OPT_GIVEN(DSS, REMOTE_USER)?
+                                       OPT_STRING_VAL(DSS, REMOTE_USER) : logname,
+                               OPT_STRING_VAL(DSS, REMOTE_HOST),
+                               lls_string_val(j, OPT_RESULT(DSS, SOURCE_DIR)),
+                               N == 1? "/" : ""
+                       );
+               }
+       }
        free(logname);
        *num = get_current_time();
        (*argv)[i++] = incomplete_name(*num);
@@ -1780,7 +1801,7 @@ static void handle_version_and_help(void)
        else if (OPT_GIVEN(DSS, HELP))
                txt = lls_short_help(CMD_PTR(DSS));
        else if (OPT_GIVEN(DSS, VERSION))
-               txt = dss_strdup(VERSION_STRING);
+               txt = make_message("%s\n", VERSION_STRING);
        else
                return;
        printf("%s", txt);