New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option to follow symbolic links #3863
base: master
Are you sure you want to change the base?
Conversation
A new flag --follow-symlinks was added to the backup command (default off). When enabled, restic will dereference any symbolic link encountered to its destination file or folder instead. This allows the destination of symbolic links to be backed up as if they were standard files or folders. In order to prevent infinite loops or backup of unwanted symlinks, use the --exclude options.
To be honest, I'm not at all convinced by that approach. It is all to easy to create infinite loops. Users shouldn't have to somehow determining beforehand which symlinks could lead to endless loops. But I also don't have time at the moment to think about what an alternative could look like. |
Maybe this is naive, but here's a simple technique that will use a little memory if you use '--follow-symlinks'. That might be the price you have to pay for the feature. I'm assuming that restic backups run in a single process, and you don't need to consider clusters of restic processes performing backups in parallel.
|
@kerryland , Here is what I've found so far.
The basis of my patch is to use os.Stat() instead of os.Lstat() -- and then Restic works. Do you know of any other way to find the destination path? I'm not keen on launching a shell command to find out. (fyi: my previous patch involved options for patterns which identify Symbolic links to descend into) By the way, command: @MichaelEischer , |
Launching a shell command from within the archiver is completely out of question.
On Unix we could also use Inodes to detect duplicates. But that won't work on windows. If we included the symlink targets in the backup then we somehow have to recognize whether we've already visited a certain folder. The suggestion from kerryland would do that, but depends on being able to determine the symlink location. I haven't given the matter much thought though, as I currently don't have time to come up with a concept on how to better handle symlinks without making a total mess out of things. |
Well. That's about it from me. For those who follow, I provided two solutions:
@MichaelEischer If you come up with another solution, let me know and I will try to code it up. For now, I'm at a stand-still. |
I've never used GO before, which is why I've been conspicuously silent, but if these GO functions really don't work on Windows then surely that's a major GO bug that needs to be reported and fixed? Anyway, I just had a quick play on Windows with 1.19.3 and didn't see any problem. Is it a bug specific to 1.18.1? Can't we upgrade? Here's the awful code I just wrote/scavenged.
I created a directory "realdir", then a symlink "softlink", and a hardlink to the "realdir" directory. The output looks like this:
|
@MichaelEischer @cccapon getting the target of a junction (reparse point) on Windows is not fun. It's possible with the winapi https://stackoverflow.com/questions/46383428/get-the-immediate-target-path-from-symlink-reparse-point but I don't know if that's implemented in Go somewhere. |
I've done detection based on a regex that catches cloud file errors (reparse points) in my restic wrapper. |
@deajan I'd be interested to hear more. How are you using regex in this context? |
@cccapon I'm wrapping restic in a Python script, the interesting part being the following:
If interested, I've built a whole restic wrapper, including YAML config file, and a nice GUI that allows backup/restore operations as well as GUI config for MSWindows and Linux. Sorry if I kindof hijacked the thread, but the above solution is my current workaround for reparse points in windows environment. |
@cccapon I think you guys are conflating symbolic links with junctions. Also, https://go-review.googlesource.com/c/go/+/460595 might be of interest. Let's start by adding support for symbolic links, and follow up with a separate issue for junctions. |
For those who follow, I did find a way around this problem with the current restic.exe (v 0.16.0). In your backup script, change directories (cd in BAT, Push-Location in PowerShell) to the root directory of the symbolic link, then launch restic and backup the '.' (dot) current directory. When restic's starting point is already inside the mount point (junction) it runs fine. restic just can't cross the devision between one file system and the next. |
A new flag '--follow-symlinks' was added to the backup command (default off). When enabled, restic will dereference any symbolic link encountered to its destination file or folder instead. This allows the destination of symbolic links to be backed up as if they were standard files or folders.
In order to prevent infinite loops or backup of unwanted symlinks, use the --exclude options as well.
What does this PR change? What problem does it solve?
Symbolic links are used for a variety of purposes in the Windows file system and sometimes it is necessary to archive the linked contents.
Under Windows, restic does not currently back up folders linked to by symbolic links.
This change causes restic to dereference symbolic links during backup and examine the underlying file or folder instead. The default processing of restic does not change and unless this option is used, symbolic links will still be ignored.
Was the change previously discussed in an issue or on the forum?
Issues:
#542
#1078
#1215
#2211
#2564
#2699
#2708
#3674
#3594
#3848
Forum:
4582
1508
Checklist
changelog/unreleased/
that describes the changes for our users (see template).gofmt
on the code in all commits.