]> git.tuebingen.mpg.de Git - dss.git/blobdiff - dss.c
Introduce --no-resume.
[dss.git] / dss.c
diff --git a/dss.c b/dss.c
index 04fe30c4bb7798ae8a049b9eb46638b278ea3927..eae8b3ed0f2ea112a54c3d6356329c9f6e768441 100644 (file)
--- a/dss.c
+++ b/dss.c
@@ -734,7 +734,6 @@ static int handle_rsync_exit(int status)
        free(name_of_reference_snapshot);
        name_of_reference_snapshot = NULL;
 out:
-       create_pid = 0;
        create_process_stopped = 0;
        return ret;
 }
@@ -766,7 +765,6 @@ static int handle_pre_create_hook_exit(int status)
        snapshot_creation_status = HS_PRE_SUCCESS;
        ret = 1;
 out:
-       create_pid = 0;
        return ret;
 }
 
@@ -792,6 +790,7 @@ static int handle_sigchld(void)
                                snapshot_creation_status);
                        return -E_BUG;
                }
+               create_pid = 0;
        }
        if (pid == remove_pid) {
                ret = handle_remove_exit(status);
@@ -818,9 +817,13 @@ static int check_config(void)
        return 1;
 }
 
+/*
+ * Returns < 0 on errors, 0 if no config file is given and > 0 if the config
+ * file was read successfully.
+ */
 static int parse_config_file(int override)
 {
-       int ret;
+       int ret, config_file_exists;
        char *config_file;
        struct stat statbuf;
        char *old_logfile_arg = NULL;
@@ -839,13 +842,13 @@ static int parse_config_file(int override)
                old_daemon_given = conf.daemon_given;
        }
 
-       ret = stat(config_file, &statbuf);
-       if (ret && conf.config_file_given) {
+       config_file_exists = !stat(config_file, &statbuf);
+       if (!config_file_exists && conf.config_file_given) {
                ret = -ERRNO_TO_DSS_ERROR(errno);
                DSS_ERROR_LOG("failed to stat config file %s\n", config_file);
                goto out;
        }
-       if (!ret) {
+       if (config_file_exists) {
                struct cmdline_parser_params params = {
                        .override = override,
                        .initialize = 0,
@@ -884,7 +887,7 @@ static int parse_config_file(int override)
                log_welcome(conf.loglevel_arg);
        }
        DSS_DEBUG_LOG("loglevel: %d\n", conf.loglevel_arg);
-//     cmdline_parser_dump(logfile? logfile : stdout, &conf);
+       ret = config_file_exists;
 out:
        free(config_file);
        if (ret < 0)
@@ -898,14 +901,24 @@ static int change_to_dest_dir(void)
        return dss_chdir(conf.dest_dir_arg);
 }
 
+static void dump_dss_config(const char *msg)
+{
+       if (conf.loglevel_arg > INFO)
+               return;
+       DSS_INFO_LOG("%s\n", msg);
+       cmdline_parser_dump(logfile? logfile : stderr, &conf);
+}
+
 static int handle_sighup(void)
 {
        int ret;
 
-       DSS_NOTICE_LOG("SIGHUP\n");
+       DSS_NOTICE_LOG("SIGHUP, re-reading config\n");
+       dump_dss_config("current config");
        ret = parse_config_file(1);
        if (ret < 0)
                return ret;
+       dump_dss_config("new config");
        invalidate_next_snapshot_time();
        return change_to_dest_dir();
 }
@@ -953,6 +966,32 @@ static int use_rsync_locally(char *logname)
        return 1;
 }
 
+static int rename_resume_snap(int64_t creation_time)
+{
+       struct snapshot_list sl = {.num_snapshots = 0};
+       struct snapshot *s;
+       char *new_name = incomplete_name(creation_time);
+       int ret;
+
+       ret = 0;
+       if (conf.no_resume_given)
+               goto out;
+       dss_get_snapshot_list(&sl);
+       s = get_newest_snapshot(&sl);
+       if (!s)
+               goto out;
+       if ((s->flags & SS_COMPLETE) != 0) /* complete */
+               goto out;
+       DSS_INFO_LOG("resuming: reusing %s as destination dir\n", s->name);
+       ret = dss_rename(s->name, new_name);
+out:
+       if (ret >= 0)
+               DSS_NOTICE_LOG("creating new snapshot %s\n", new_name);
+       free(new_name);
+       free_snapshot_list(&sl);
+       return ret;
+}
+
 static void create_rsync_argv(char ***argv, int64_t *num)
 {
        char *logname;
@@ -1005,11 +1044,10 @@ static void free_rsync_argv(char **argv)
 static int create_snapshot(char **argv)
 {
        int ret, fds[3] = {0, 0, 0};
-       char *name;
 
-       name = incomplete_name(current_snapshot_creation_time);
-       DSS_NOTICE_LOG("creating new snapshot %s\n", name);
-       free(name);
+       ret = rename_resume_snap(current_snapshot_creation_time);
+       if (ret < 0)
+               return ret;
        ret = dss_exec(&create_pid, argv[0], argv, fds);
        if (ret < 0)
                return ret;
@@ -1294,8 +1332,23 @@ int main(int argc, char **argv)
        ret = parse_config_file(0);
        if (ret < 0)
                goto out;
+       if (ret == 0) { /* no config file given */
+               /*
+                * Parse the command line options again, but this time check
+                * that all required options are given.
+                */
+               params = (struct cmdline_parser_params) {
+                       .override = 1,
+                       .initialize = 1,
+                       .check_required = 1,
+                       .check_ambiguity = 1,
+                       .print_errors = 1
+               };
+               cmdline_parser_ext(argc, argv, &conf, &params); /* aborts on errors */
+       }
        if (conf.daemon_given)
                daemon_init();
+       dump_dss_config("dss configuration");
        ret = change_to_dest_dir();
        if (ret < 0)
                goto out;