From: Andre Noll Date: Wed, 15 Nov 2017 18:09:06 +0000 (+0100) Subject: Merge branch 'refs/heads/t/mountpoint' X-Git-Tag: v1.0.0~10 X-Git-Url: http://git.tuebingen.mpg.de/dss.git/log?a=commitdiff_plain;h=c9fd9f2239319b95c46e49b1b7040e1a898cdcf7;hp=50e03ce10c3bab1c43e1e68dca3b0471d63807d9;p=dss.git Merge branch 'refs/heads/t/mountpoint' 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. --- diff --git a/NEWS b/NEWS index fc80e8e..75fe3a2 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,9 @@ x.y.z (to be announced) - 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 diff --git a/dss.c b/dss.c index 6353fbe..bd9e577 100644 --- a/dss.c +++ b/dss.c @@ -1060,17 +1060,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(void) diff --git a/dss.suite b/dss.suite index 95dd30f..1e79870 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"), \