X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=dss.c;h=c996d47313c4673010e87f6042c9009901224b69;hb=9be379abc03581531410b22e6164e9d54be3c034;hp=c5f636c2ed8b86ad5170c164d3f6e2d4d08d862c;hpb=67f36528afce8e7dd5016283eb3da5a99be4778d;p=dss.git diff --git a/dss.c b/dss.c index c5f636c..c996d47 100644 --- a/dss.c +++ b/dss.c @@ -161,7 +161,6 @@ static int64_t compute_next_snapshot_time(void) struct snapshot *s = NULL; struct snapshot_list sl; - current_snapshot_creation_time = 0; dss_get_snapshot_list(&sl); FOR_EACH_SNAPSHOT(s, i, &sl) { if (!(s->flags & SS_COMPLETE)) @@ -197,7 +196,6 @@ static int next_snapshot_is_due(void) { int64_t now = get_current_time(); - assert(snapshot_creation_status == HS_READY); if (!next_snapshot_time_is_valid()) next_snapshot_time = compute_next_snapshot_time(); if (next_snapshot_time <= now) { @@ -216,10 +214,6 @@ static int pre_create_hook(void) assert(snapshot_creation_status == HS_READY); /* make sure that the next snapshot time will be recomputed */ invalidate_next_snapshot_time(); - if (!conf.pre_create_hook_given) { - snapshot_creation_status = HS_PRE_SUCCESS; - return 0; - } DSS_DEBUG_LOG("executing %s\n", conf.pre_create_hook_arg); ret = dss_exec_cmdline_pid(&create_pid, conf.pre_create_hook_arg, fds); @@ -245,15 +239,10 @@ static int pre_remove_hook(struct snapshot *s, const char *why) *snapshot_currently_being_removed = *s; snapshot_currently_being_removed->name = dss_strdup(s->name); - if (!conf.pre_remove_hook_given) { - snapshot_removal_status = HS_PRE_SUCCESS; - return 0; - } cmd = make_message("%s %s/%s", conf.pre_remove_hook_arg, conf.dest_dir_arg, s->name); DSS_DEBUG_LOG("executing %s\n", cmd); - ret = dss_exec_cmdline_pid(&remove_pid, - conf.pre_remove_hook_arg, fds); + ret = dss_exec_cmdline_pid(&remove_pid, cmd, fds); free(cmd); if (ret < 0) return ret; @@ -505,10 +494,6 @@ static int post_create_hook(void) int ret, fds[3] = {0, 0, 0}; char *cmd; - if (!conf.post_create_hook_given) { - snapshot_creation_status = HS_READY; - return 0; - } cmd = make_message("%s %s/%s", conf.post_create_hook_arg, conf.dest_dir_arg, path_to_last_complete_snapshot); DSS_NOTICE_LOG("executing %s\n", cmd); @@ -528,10 +513,6 @@ static int post_remove_hook(void) assert(s); - if (!conf.post_remove_hook_given) { - snapshot_removal_status = HS_READY; - return 0; - } cmd = make_message("%s %s/%s", conf.post_remove_hook_arg, conf.dest_dir_arg, s->name); DSS_NOTICE_LOG("executing %s\n", cmd); @@ -555,6 +536,7 @@ static void stop_create_process(void) { if (!create_pid || create_process_stopped) return; + DSS_INFO_LOG("suspending create process %d\n", (int)create_pid); kill(SIGSTOP, create_pid); create_process_stopped = 1; } @@ -563,6 +545,7 @@ static void restart_create_process(void) { if (!create_pid || !create_process_stopped) return; + DSS_INFO_LOG("resuming create process %d\n", (int)create_pid); kill (SIGCONT, create_pid); create_process_stopped = 0; } @@ -639,10 +622,7 @@ static int handle_rm_exit(int status) snapshot_removal_status = HS_READY; return -E_BAD_EXIT_CODE; } - if (conf.post_remove_hook_given) - snapshot_removal_status = HS_SUCCESS; - else - snapshot_removal_status = HS_READY; + snapshot_removal_status = HS_SUCCESS; return 1; } @@ -734,7 +714,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 +745,6 @@ static int handle_pre_create_hook_exit(int status) snapshot_creation_status = HS_PRE_SUCCESS; ret = 1; out: - create_pid = 0; return ret; } @@ -781,17 +759,22 @@ static int handle_sigchld(void) if (pid == create_pid) { switch (snapshot_creation_status) { case HS_PRE_RUNNING: - return handle_pre_create_hook_exit(status); + ret = handle_pre_create_hook_exit(status); + break; case HS_RUNNING: - return handle_rsync_exit(status); + ret = handle_rsync_exit(status); + break; case HS_POST_RUNNING: snapshot_creation_status = HS_READY; - return 1; + ret = 1; + break; default: DSS_EMERG_LOG("BUG: create can't die in status %d\n", snapshot_creation_status); return -E_BUG; } + create_pid = 0; + return ret; } if (pid == remove_pid) { ret = handle_remove_exit(status); @@ -967,6 +950,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; @@ -1019,11 +1028,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; @@ -1051,7 +1059,6 @@ static int select_loop(void) } FD_ZERO(&rfds); FD_SET(signal_pipe, &rfds); - DSS_DEBUG_LOG("tvp: %p, tv_sec : %lu\n", tvp, (long unsigned) tv.tv_sec); ret = dss_select(signal_pipe + 1, &rfds, NULL, tvp); if (ret < 0) goto out; @@ -1095,10 +1102,14 @@ static int select_loop(void) case HS_POST_RUNNING: continue; case HS_PRE_SUCCESS: - free_rsync_argv(rsync_argv); - create_rsync_argv(&rsync_argv, ¤t_snapshot_creation_time); + if (!name_of_reference_snapshot) { + free_rsync_argv(rsync_argv); + create_rsync_argv(&rsync_argv, ¤t_snapshot_creation_time); + } /* fall through */ case HS_NEEDS_RESTART: + if (!next_snapshot_is_due()) + continue; ret = create_snapshot(rsync_argv); if (ret < 0) goto out; @@ -1120,8 +1131,6 @@ static void exit_hook(int exit_code) char *argv[] = {conf.exit_hook_arg, dss_strerror(-exit_code), NULL}; pid_t pid; - if (!conf.exit_hook_given) - return; DSS_NOTICE_LOG("executing %s %s\n", argv[0], argv[1]); dss_exec(&pid, conf.exit_hook_arg, argv, fds); }