X-Git-Url: http://git.tuebingen.mpg.de/?p=dss.git;a=blobdiff_plain;f=dss.c;h=c6c48f51889fc1c5c7e7a1e44c550a262886f8a7;hp=d0dab0dc3f688254163d9d138069a48dd77ccd5b;hb=04a4e5db8eeb1744d668353366bf5e98491550d5;hpb=3025388040c1521121255e5ae7ceabdcb1b1e421 diff --git a/dss.c b/dss.c index d0dab0d..c6c48f5 100644 --- a/dss.c +++ b/dss.c @@ -63,6 +63,8 @@ static struct lls_parse_result *cmdline_lpr, *lpr; /** Parsed subcommand options. */ static struct lls_parse_result *cmdline_sublpr, *sublpr; +/* The executing subcommand (NULL at startup). */ +static const struct lls_command *subcmd; /** Wether daemon_init() was called. */ static bool daemonized; /** Non-NULL if we log to a file. */ @@ -242,16 +244,19 @@ __printf_1_2 void dss_log(const char* fmt,...) if (loglevel < lpr_ll) return; outfd = logfile? logfile : stderr; - time(&t1); - tm = localtime(&t1); - strftime(str, sizeof(str), "%b %d %H:%M:%S", tm); - fprintf(outfd, "%s ", str); - if (lpr_ll <= INFO) - fprintf(outfd, "%i: ", loglevel); + if (subcmd == CMD_PTR(RUN)) { + time(&t1); + tm = localtime(&t1); + strftime(str, sizeof(str), "%b %d %H:%M:%S", tm); + fprintf(outfd, "%s ", str); + if (lpr_ll <= INFO) + fprintf(outfd, "%i: ", loglevel); + } + if (subcmd == CMD_PTR(RUN)) #ifdef DSS_NO_FUNC_NAMES - fprintf(outfd, "%s:%d: ", location_file, location_line); + fprintf(outfd, "%s:%d: ", location_file, location_line); #else - fprintf(outfd, "%s: ", location_func); + fprintf(outfd, "%s: ", location_func); #endif va_start(argp, fmt); vfprintf(outfd, fmt, argp); @@ -1055,12 +1060,18 @@ static int handle_sigchld(void) static int change_to_dest_dir(void) { + int ret; const char *dd = OPT_STRING_VAL(DSS, DEST_DIR); + DSS_INFO_LOG(("changing cwd to %s\n", dd)); - return dss_chdir(dd); + if (chdir(dd) >= 0) + return 1; + ret = -ERRNO_TO_DSS_ERROR(errno); + DSS_ERROR_LOG(("could not change cwd to %s\n", dd)); + return ret; } -static int check_config(const struct lls_command *cmd) +static int check_config(void) { int ret; uint32_t unit_interval = OPT_UINT32_VAL(DSS, UNIT_INTERVAL); @@ -1076,13 +1087,13 @@ static int check_config(const struct lls_command *cmd) DSS_ERROR_LOG(("bad number of intervals: %i\n", num_intervals)); return -E_INVALID_NUMBER; } - if (cmd == CMD_PTR(RUN) || cmd == CMD_PTR(CREATE)) + if (subcmd == CMD_PTR(RUN) || subcmd == CMD_PTR(CREATE)) if (!OPT_GIVEN(DSS, SOURCE_DIR)) { DSS_ERROR_LOG(("--source-dir required\n")); return -E_SYNTAX; } - if (cmd == CMD_PTR(RUN) || cmd == CMD_PTR(CREATE) - || cmd == CMD_PTR(LS) || cmd == CMD_PTR(PRUNE)) { + if (subcmd == CMD_PTR(RUN) || subcmd == CMD_PTR(CREATE) + || subcmd == CMD_PTR(LS) || subcmd == CMD_PTR(PRUNE)) { if (!OPT_GIVEN(DSS, DEST_DIR)) { DSS_ERROR_LOG(("--dest-dir required\n")); return -E_SYNTAX; @@ -1220,7 +1231,7 @@ static int handle_sighup(void) ret = parse_config_file(true /* SIGHUP */, CMD_PTR(RUN)); if (ret < 0) return ret; - ret = check_config(CMD_PTR(RUN)); + ret = check_config(); if (ret < 0) return ret; close_log(logfile); @@ -1341,6 +1352,7 @@ static void create_rsync_argv(char ***argv, int64_t *num) char *logname; int i = 0, j, N = OPT_GIVEN(DSS, RSYNC_OPTION); struct snapshot_list sl; + static bool seeded; dss_get_snapshot_list(&sl); assert(!name_of_reference_snapshot); @@ -1351,6 +1363,14 @@ static void create_rsync_argv(char ***argv, int64_t *num) (*argv)[i++] = dss_strdup("rsync"); (*argv)[i++] = dss_strdup("-a"); (*argv)[i++] = dss_strdup("--delete"); + if (!seeded) { + srandom((unsigned)time(NULL)); /* no need to be fancy here */ + seeded = true; + } + if (1000 * (random() / (RAND_MAX + 1.0)) < OPT_UINT32_VAL(DSS, CHECKSUM)) { + DSS_NOTICE_LOG(("adding --checksum to rsync options\n")); + (*argv)[i++] = dss_strdup("--checksum"); + } for (j = 0; j < N; j++) (*argv)[i++] = dss_strdup(lls_string_val(j, OPT_RESULT(DSS, RSYNC_OPTION))); @@ -1510,14 +1530,23 @@ static void lock_dss_or_die(void) static int com_run(void) { - int ret; + int ret, fd = -1; + char *config_file; + pid_t pid; if (OPT_GIVEN(DSS, DRY_RUN)) { DSS_ERROR_LOG(("dry run not supported by this command\n")); return -E_SYNTAX; } + config_file = get_config_file_name(); + ret = get_dss_pid(config_file, &pid); + free(config_file); + if (ret >= 0) { + DSS_ERROR_LOG(("pid %d\n", (int)pid)); + return -E_ALREADY_RUNNING; + } if (OPT_GIVEN(RUN, DAEMON)) { - daemon_init(); + fd = daemon_init(); daemonized = true; logfile = open_log(OPT_STRING_VAL(RUN, LOGFILE)); } @@ -1526,6 +1555,16 @@ static int com_run(void) ret = install_sighandler(SIGHUP); if (ret < 0) return ret; + if (fd >= 0) { + ret = write(fd, "\0", 1); + if (ret != 1) { + DSS_ERROR_LOG(("write to daemon pipe returned %d\n", + ret)); + if (ret < 0) + return -ERRNO_TO_DSS_ERROR(errno); + return -E_BUG; + } + } ret = select_loop(); if (ret >= 0) /* impossible */ ret = -E_BUG; @@ -1711,18 +1750,17 @@ static void show_subcommand_summary(void) int main(int argc, char **argv) { int ret; - const struct lls_command *cmd = CMD_PTR(DSS); char *errctx = NULL; unsigned num_inputs; - const struct dss_user_data *ud = NULL; + const struct dss_user_data *ud; - ret = lls_parse(argc, argv, cmd, &cmdline_lpr, &errctx); + ret = lls_parse(argc, argv, CMD_PTR(DSS), &cmdline_lpr, &errctx); if (ret < 0) { ret = lopsub_error(ret, &errctx); goto out; } lpr = cmdline_lpr; - ret = parse_config_file(false /* no SIGHUP */, cmd); + ret = parse_config_file(false /* no SIGHUP */, CMD_PTR(DSS)); if (ret < 0) goto out; handle_version_and_help(); @@ -1734,24 +1772,24 @@ int main(int argc, char **argv) ret = lopsub_error(ret, &errctx); goto out; } - cmd = lls_cmd(ret, dss_suite); - ret = lls_parse(num_inputs, argv + argc - num_inputs, cmd, + subcmd = lls_cmd(ret, dss_suite); + ret = lls_parse(num_inputs, argv + argc - num_inputs, subcmd, &cmdline_sublpr, &errctx); if (ret < 0) { ret = lopsub_error(ret, &errctx); goto out; } sublpr = cmdline_sublpr; - ret = parse_config_file(false /* no SIGHUP */, cmd); + ret = parse_config_file(false /* no SIGHUP */, subcmd); if (ret < 0) goto out; - ret = check_config(cmd); + ret = check_config(); if (ret < 0) goto out; ret = setup_signal_handling(); if (ret < 0) goto out; - ud = lls_user_data(cmd); + ud = lls_user_data(subcmd); ret = ud->handler(); signal_shutdown(); out: @@ -1764,8 +1802,8 @@ out: lls_free_parse_result(lpr, CMD_PTR(DSS)); if (lpr != cmdline_lpr) lls_free_parse_result(cmdline_lpr, CMD_PTR(DSS)); - lls_free_parse_result(sublpr, cmd); + lls_free_parse_result(sublpr, subcmd); if (sublpr != cmdline_sublpr) - lls_free_parse_result(cmdline_sublpr, cmd); + lls_free_parse_result(cmdline_sublpr, subcmd); exit(ret >= 0? EXIT_SUCCESS : EXIT_FAILURE); }