- ret = dss_exec(&rsync_pid, argv[0], argv, fds);
- if (ret < 0)
- return ret;
- snapshot_creation_status = SCS_RSYNC_RUNNING;
- return ret;
-}
-
-int handle_pre_create_hook_exit(int status)
-{
- int es, ret;
-
- if (!WIFEXITED(status)) {
- make_err_msg("pre-create-hook %d died involuntary",
- (int)pre_create_hook_pid);
- snapshot_creation_status = SCS_READY;
- compute_next_snapshot_time();
- ret = -E_INVOLUNTARY_EXIT;
- goto out;
- }
- es = WEXITSTATUS(status);
- if (es) {
- make_err_msg("pre-create-hook %d returned %d",
- (int)pre_create_hook_pid, es);
- snapshot_creation_status = SCS_READY;
- compute_next_snapshot_time();
- ret = -E_BAD_EXIT_CODE;
- goto out;
- }
- snapshot_creation_status = SCS_PRE_HOOK_SUCCESS;
- ret = 1;
-out:
- pre_create_hook_pid = 0;
- return ret;
-}
-
-int handle_sigchld()
-{
- pid_t pid;
- int status, ret = reap_child(&pid, &status);
-
- if (ret <= 0)
- return ret;
- if (pid == rsync_pid)
- return handle_rsync_exit(status);
- if (pid == rm_pid)
- return handle_rm_exit(status);
- if (pid == pre_create_hook_pid)
- return handle_pre_create_hook_exit(status);
- if (pid == post_create_hook_pid) {
- snapshot_creation_status = SCS_READY;
- compute_next_snapshot_time();
- return 1;
- }
- DSS_EMERG_LOG("BUG: unknown process %d died\n", (int)pid);
- exit(EXIT_FAILURE);
-}
-
-void handle_signal(void)
-{
- int sig, ret = next_signal();
-
- if (ret <= 0)
- goto out;
- sig = ret;
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- restart_rsync_process();
- kill_process(rsync_pid);
- kill_process(rm_pid);
- exit(EXIT_FAILURE);
- case SIGHUP:
- handle_sighup();
- ret = 1;
- break;
- case SIGCHLD:
- ret = handle_sigchld();
- break;
- }
-out:
- if (ret < 0)
- log_err_msg(ERROR, -ret);
-}
-
-int get_oldest(const char *dirname, void *private)
-{
- struct edge_snapshot_data *esd = private;
- struct snapshot s;
- int ret = is_snapshot(dirname, esd->now, &s);
-
- if (ret <= 0)
- return 1;
- if (s.creation_time > esd->snap.creation_time)
- return 1;
- free(esd->snap.name);
- esd->snap = s;
- return 1;
-}
-
-int remove_oldest_snapshot()
-{
- int ret;
- struct edge_snapshot_data esd = {
- .now = get_current_time(),
- .snap = {.creation_time = LLONG_MAX}
- };
- for_each_subdir(get_oldest, &esd);
- if (!esd.snap.name) /* no snapshot found */
- return 0;
- DSS_INFO_LOG("oldest snapshot: %s\n", esd.snap.name);
- ret = 0;
- if (esd.snap.creation_time == current_snapshot_creation_time)
- goto out; /* do not remove the snapshot currently being created */
- ret = remove_snapshot(&esd.snap);
-out:
- free(esd.snap.name);
- return ret;
-}
-
-/* TODO: Also consider number of inodes. */
-int disk_space_low(void)
-{
- struct disk_space ds;
- int ret = get_disk_space(".", &ds);
-