]> git.tuebingen.mpg.de Git - dss.git/commitdiff
Merge branch 'refs/heads/t/mountpoint'
authorAndre Noll <maan@tuebingen.mpg.de>
Wed, 15 Nov 2017 18:09:06 +0000 (19:09 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Wed, 15 Nov 2017 18:09:53 +0000 (19:09 +0100)
A new main option which aborts dss if the destination file system is
not mounted.

Cooking for two weeks.

* refs/heads/t/mountpoint:
  New option: --mountpoint.

1  2 
NEWS
dss.c
dss.suite

diff --combined NEWS
index fc80e8e6535045fc321b2e9be932b8f224177337,755cad21834cc7b6d150746e6555544d706802c6..75fe3a2bd5eda8353f9bb4f42b9e62fcbf6e5ff7
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -7,13 -7,10 +7,16 @@@ x.y.z (to be announced
   - The --no-resume option has been removed.
  
   - The gengetopt option parser has been replaced by the
 - [lopsub](http://people.tuebingen.mpg.de/~maan/lopsub) library. Hence
 + [lopsub](http://people.tuebingen.mpg.de/maan/lopsub) library. Hence
   lopsub must be installed to compile this package. Also help2man is
   no longer required since lopsub has built-in roff support.
  
 + - New subcommand "configtest" to check the command line options and
 + the configuration file for syntactic correctness.
 +
++ - New option: --mountpoint. If this option is given, dss aborts if
++ no file system is mounted on the destination directory.
++
   - "make install" will install the executable and the man page.
  
   - In run mode, dss no longer exits successfully if another instance
   - CFLAGS, CPPFLAGS and LDFLAGS can now be used to override the flags
   of the build system.
  
 + - For all subcommands other than "run", timestamps and function names
 + are omitted from the log output.
 +
 + - The dss logo is now created with ImageMagick rather than dia.
 +
  ------------------
  0.1.7 (2017-04-17)
  ------------------
diff --combined dss.c
index 6353fbe79df9b7b38f92d6e6c6fba1fa80399f5b,3d234ffb68851ddbb7996df59a8bdd31eb97c529..bd9e577e3f6a6df2b94c6f48dddb9ffdeff96d39
--- 1/dss.c
--- 2/dss.c
+++ b/dss.c
@@@ -63,8 -63,6 +63,8 @@@ static struct lls_parse_result *cmdline
  
  /** 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. */
@@@ -244,19 -242,16 +244,19 @@@ __printf_1_2 void dss_log(const char* f
        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);
@@@ -300,7 -295,6 +300,7 @@@ static int send_signal(int sig
                dss_msg("%d\n", (int)pid);
                return 0;
        }
 +      DSS_NOTICE_LOG(("sending signal %d to pid %d\n", sig, (int)pid));
        ret = kill(pid, sig);
        if (ret < 0)
                return -ERRNO_TO_DSS_ERROR(errno);
@@@ -521,7 -515,7 +521,7 @@@ static struct snapshot *find_orphaned_s
        struct snapshot *s;
        int i;
  
 -      DSS_DEBUG_LOG(("looking for orphaned snapshots\n"));
 +      DSS_DEBUG_LOG(("looking for old incomplete snapshots\n"));
        FOR_EACH_SNAPSHOT(s, i, sl) {
                if (snapshot_is_being_created(s))
                        continue;
@@@ -735,7 -729,6 +735,7 @@@ static int try_to_free_disk_space(void
        if (!low_disk_space)
                goto out;
        DSS_WARNING_LOG(("disk space low and nothing obvious to remove\n"));
 +      why = "oldest";
        victim = find_oldest_removable_snapshot(&sl);
        if (victim)
                goto remove;
@@@ -1060,20 -1053,39 +1060,39 @@@ static int handle_sigchld(void
        return -E_BUG;
  }
  
+ /* also checks if . is a mountpoint, if --mountpoint was given */
  static int change_to_dest_dir(void)
  {
        int ret;
        const char *dd = OPT_STRING_VAL(DSS, DEST_DIR);
+       struct stat dot, dotdot;
  
        DSS_INFO_LOG(("changing cwd to %s\n", 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;
+       if (chdir(dd) < 0) {
+               ret = -ERRNO_TO_DSS_ERROR(errno);
+               DSS_ERROR_LOG(("could not change cwd to %s\n", dd));
+               return ret;
+       }
+       if (!OPT_GIVEN(DSS, MOUNTPOINT))
+               return 0;
+       if (stat(".", &dot) < 0) {
+               ret = -ERRNO_TO_DSS_ERROR(errno);
+               DSS_ERROR_LOG(("could not stat .\n"));
+               return ret;
+       }
+       if (stat("..", &dotdot) < 0) {
+               ret = -ERRNO_TO_DSS_ERROR(errno);
+               DSS_ERROR_LOG(("could not stat ..\n"));
+               return ret;
+       }
+       if (dot.st_dev == dotdot.st_dev && dot.st_ino != dotdot.st_ino) {
+               DSS_ERROR_LOG(("mountpoint check failed for %s\n", dd));
+               return -E_MOUNTPOINT;
+       }
+       return 1;
  }
  
 -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);
                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;
@@@ -1233,7 -1245,7 +1252,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);
@@@ -1703,13 -1715,6 +1722,13 @@@ static int com_ls(void
  }
  EXPORT_CMD_HANDLER(ls);
  
 +static int com_configtest(void)
 +{
 +      printf("Syntax Ok\n");
 +      return 0;
 +}
 +EXPORT_CMD_HANDLER(configtest);
 +
  static int setup_signal_handling(void)
  {
        int ret;
@@@ -1751,7 -1756,7 +1770,7 @@@ static void show_subcommand_summary(voi
        for (i = 1; (cmd = lls_cmd(i, dss_suite)); i++) {
                const char *name = lls_command_name(cmd);
                const char *purpose = lls_purpose(cmd);
 -              printf("%-10s%s\n", name, purpose);
 +              printf("%-11s%s\n", name, purpose);
        }
        exit(EXIT_SUCCESS);
  }
  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();
                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:
        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);
  }
diff --combined dss.suite
index 95dd30ff9dc7ea5963957aad8e809a57d0277c52,1e62acf7587e5934619521a35dc2cd3107d22c55..1e798702676106238c180879889957d7913c2056
+++ b/dss.suite
@@@ -34,7 -34,7 +34,7 @@@ caption = Subcommand
                        However, there is one exception to this rule: The run subcommand
                        re-reads the configuration file when it receives the HUP signal. In
                        this case the options in the config file override any options that
 -                      were previously given at the command line. This allows to change the
 +                      were previously given at the command line. This allows changing the
                        configuration of a running dss process by sending SIGHUP.
                [/help]
        [option loglevel]
  
                        This option is mandatory for all subcommands except kill.
                [/help]
+       [option mountpoint]
+               summary = abort if destination directory is not a mountpoint
+               [help]
+                       This option checks whether a file system is mounted on the directory
+                       specified as the argument to --dest-dir. Operation proceeds only
+                       if this is the case. Otherwise dss exits unsuccessfully without
+                       performing any action. Use this option to prevent snapshot creation
+                       if the snapshot file system is not mounted.
+                       This option is silently ignored for subcommands which do not depend
+                       on the destination directory.
+               [/help]
        [option Rsync-options]
                summary = Controlling how rsync is run
                flag ignored
                typestr = percent
                default_val = 2
                [help]
 -                      This is like --min-free-mb but allows to specify the amount of
 -                      free disk space as a percentage. It is not recommended to set both
 +                      This is like --min-free-mb but the amount of free disk space
 +                      is specified as a percentage. It is not recommended to set both
                        --min-free-mb and --min-free-percent to zero as this will cause your
                        file system to fill up quickly.
                [/help]
  
                        Sending SIGHUP causes the running dss process to reload its config file.
                [/help]
 +[subcommand configtest]
 +      purpose = run a configuration file syntax test
 +      [description]
 +              This command checks the command line options and the configuration
 +              file for syntactic correctness. It either reports "Syntax Ok" and
 +              exits successfully or prints information about the first syntax error
 +              detected and terminates with exit code 1.
 +      [/description]
  
  [section copyright]
        Written by Andre Noll