From 31b7424d5b47509ed22667ca2ee31a5590664606 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 16 Oct 2017 17:19:08 +0200 Subject: [PATCH] New option: --mountpoint. 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 | 29 ++++++++++++++++++++++++----- dss.suite | 12 ++++++++++++ err.h | 1 + 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/dss.c b/dss.c index 3e626ab..3d234ff 100644 --- 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) diff --git a/dss.suite b/dss.suite index e69cc28..1e62acf 100644 --- 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 3d4e136..e747bf3 100644 --- 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"), \ -- 2.39.5