X-Git-Url: http://git.tuebingen.mpg.de/?p=dss.git;a=blobdiff_plain;f=dss.c;h=aec4109abab7dff1b970189a48a83caa253c2333;hp=b27bdf6604d14f44dfa34d402e1c22f6e37055ae;hb=8dd55d3a9f4165296d9f5a834870a832f232ca03;hpb=a6727ed6659f287eb2a4f68ac5fbf3178f40498f diff --git a/dss.c b/dss.c index b27bdf6..aec4109 100644 --- a/dss.c +++ b/dss.c @@ -380,8 +380,8 @@ static int post_create_hook(void) compute_next_snapshot_time(); return 0; } - cmd = make_message("%s %s", conf.post_create_hook_arg, - path_to_last_complete_snapshot); + 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); ret = dss_exec_cmdline_pid(&post_create_hook_pid, cmd, fds); free(cmd); @@ -498,6 +498,15 @@ static int handle_rsync_exit(int status) goto out; } es = WEXITSTATUS(status); + if (es == 13) { /* Errors with program diagnostics */ + DSS_WARNING_LOG("rsync process %d returned %d -- restarting\n", + (int)rsync_pid, es); + snapshot_creation_status = SCS_RSYNC_NEEDS_RESTART; + gettimeofday(&next_snapshot_time, NULL); + next_snapshot_time.tv_sec += 60; + ret = 1; + goto out; + } if (es != 0 && es != 23 && es != 24) { DSS_ERROR_LOG("rsync process %d returned %d\n", (int)rsync_pid, es); ret = -E_BAD_EXIT_CODE; @@ -686,6 +695,21 @@ out: return ret; } +/* + * We can not use rsync locally if the local user is different from the remote + * user or if the src dir is not on the local host (or both). + */ +static int use_rsync_locally(char *logname) +{ + char *h = conf.remote_host_arg; + + if (strcmp(h, "localhost") && strcmp(h, "127.0.0.1")) + return 0; + if (conf.remote_user_given && strcmp(conf.remote_user_arg, logname)) + return 0; + return 1; +} + static void create_rsync_argv(char ***argv, int64_t *num) { char *logname, *newest; @@ -709,7 +733,7 @@ static void create_rsync_argv(char ***argv, int64_t *num) } else DSS_INFO_LOG("no previous snapshot found\n"); logname = dss_logname(); - if (conf.remote_user_given && !strcmp(conf.remote_user_arg, logname)) + if (use_rsync_locally(logname)) (*argv)[i++] = dss_strdup(conf.source_dir_arg); else (*argv)[i++] = make_message("%s@%s:%s/", conf.remote_user_given? @@ -726,6 +750,9 @@ static void create_rsync_argv(char ***argv, int64_t *num) static void free_rsync_argv(char **argv) { int i; + + if (!argv) + return; for (i = 0; argv[i]; i++) free(argv[i]); free(argv); @@ -751,11 +778,11 @@ static int select_loop(void) int ret; /* check every 60 seconds for free disk space */ struct timeval tv; + char **rsync_argv = NULL; for (;;) { fd_set rfds; int low_disk_space; - char **rsync_argv; struct timeval now, *tvp; if (rm_pid) @@ -801,10 +828,15 @@ static int select_loop(void) continue; case SCS_PRE_HOOK_RUNNING: continue; + case SCS_RSYNC_NEEDS_RESTART: + ret = create_snapshot(rsync_argv); + if (ret < 0) + goto out; + continue; case SCS_PRE_HOOK_SUCCESS: + free_rsync_argv(rsync_argv); create_rsync_argv(&rsync_argv, ¤t_snapshot_creation_time); ret = create_snapshot(rsync_argv); - free_rsync_argv(rsync_argv); if (ret < 0) goto out; continue; @@ -826,16 +858,13 @@ out: static void exit_hook(int exit_code) { int fds[3] = {0, 0, 0}; - char *cmd; + char *argv[] = {conf.exit_hook_arg, dss_strerror(-exit_code), NULL}; pid_t pid; if (!conf.exit_hook_given) return; - cmd = make_message("%s %s", conf.exit_hook_arg, - dss_strerror(-exit_code)); - DSS_NOTICE_LOG("executing %s\n", cmd); - dss_exec_cmdline_pid(&pid, cmd, fds); - free(cmd); + DSS_NOTICE_LOG("executing %s %s\n", argv[0], argv[1]); + dss_exec(&pid, conf.exit_hook_arg, argv, fds); } static int com_run(void) @@ -952,8 +981,12 @@ static int com_ls(void) struct snapshot *s; dss_get_snapshot_list(&sl); - FOR_EACH_SNAPSHOT(s, i, &sl) - dss_msg("%u\t%s\n", s->interval, s->name); + FOR_EACH_SNAPSHOT(s, i, &sl) { + int64_t d = 0; + if (s->flags & SS_COMPLETE) + d = (s->completion_time - s->creation_time) / 60; + dss_msg("%u\t%s\t%3" PRId64 ":%02" PRId64 "\n", s->interval, s->name, d/60, d%60); + }; free_snapshot_list(&sl); return 1; }