]> git.tue.mpg.de Git - dss.git/commitdiff
New option: --mountpoint.
authorAndre Noll <maan@tuebingen.mpg.de>
Mon, 16 Oct 2017 15:19:08 +0000 (17:19 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sat, 21 Oct 2017 11:06:45 +0000 (13:06 +0200)
The new option applies to run, create, ls and prune. The feature
could be implemented as a pre-create hook, but since it is so common,
it makes sense to add it to dss proper.

As for the implementation we simply check that "." and ".." are on
different devices (or are identical).

dss.c
dss.suite
err.h

diff --git a/dss.c b/dss.c
index 3e626ab0113b1890277da115ea6c735dbdb690d7..3d234ffb68851ddbb7996df59a8bdd31eb97c529 100644 (file)
--- a/dss.c
+++ b/dss.c
@@ -1053,17 +1053,36 @@ 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)
index e69cc28630c8a39359cba3aead33ab3b847011a8..1e62acf7587e5934619521a35dc2cd3107d22c55 100644 (file)
--- a/dss.suite
+++ b/dss.suite
@@ -79,6 +79,18 @@ caption = Subcommands
 
                        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
diff --git a/err.h b/err.h
index 3d4e136f208473fb2de31cb645a868f33995bbaa..e747bf3c1e1c079afe0188da066d9c4ac572d222 100644 (file)
--- a/err.h
+++ b/err.h
@@ -48,6 +48,7 @@ static inline char *dss_strerror(int num)
        DSS_ERROR(INVALID_NUMBER, "invalid number"), \
        DSS_ERROR(STRFTIME, "strftime() failed"), \
        DSS_ERROR(LOCALTIME, "localtime() failed"), \
+       DSS_ERROR(MOUNTPOINT, "destination directory is no mountpoint"), \
        DSS_ERROR(NULL_OPEN, "can not open /dev/null"), \
        DSS_ERROR(DUP_PIPE, "exec error: can not create pipe"), \
        DSS_ERROR(INVOLUNTARY_EXIT, "unexpected termination cause"), \