Skip to content
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

Restore of a existing symlink(with same content) fails #2578

Closed
eigood opened this issue Feb 13, 2020 · 10 comments · Fixed by #3780
Closed

Restore of a existing symlink(with same content) fails #2578

eigood opened this issue Feb 13, 2020 · 10 comments · Fixed by #3780
Labels
category: restore help: minor complexity less complex issue, good for beginners that want a little challenge yet not too complicated help: wanted type: bug

Comments

@eigood
Copy link

eigood commented Feb 13, 2020

Output of restic version

restic 0.9.6 compiled with go1.13.4 on linux/amd64
restic/restic latest 66a76c4e92a6 2 months ago 30.7MB

How did you run restic exactly?

First time, not existing:

docker run --rm -ti -e RESTIC_PASSWORD -e RESTIC_REPOSITORY -v restic-cache:/root/.cache/restic -v /srv/docker/restic:/srv/restic -v /srv/docker/clients/$site_id:/srv/app/$site_id:ro -v /srv/docker/clients/$site_id/restores/39e1d807:/srv/app/$site_id/restores/39e1d807:rw restic/restic restore --host $site_id --target /srv/app/$site_id/restores/39e1d807 39e1d807 --include /old/usr/share/zoneinfo/right/Turkey
repository 22780ffb opened successfully, password is correct
restoring <Snapshot 39e1d807 of [/srv/app/$site_id] at 2020-02-13 19:42:52 +0000 UTC by root@$site_id> to /srv/app/$site_id/restores/39e1d807

  • exit 0

Second time, immediately following, exists:

docker run --rm -ti -e RESTIC_PASSWORD -e RESTIC_REPOSITORY -v restic-cache:/root/.cache/restic -v /srv/docker/restic:/srv/restic -v /srv/docker/clients/$site_id:/srv/app/$site_id:ro -v /srv/docker/clients/$site_id/restores/39e1d807:/srv/app/$site_id/restores/39e1d807:rw restic/restic restore --host $site_id --target /srv/app/$site_id/restores/39e1d807 39e1d807 --include /old/usr/share/zoneinfo/right/Turkey
repository 22780ffb opened successfully, password is correct
restoring <Snapshot 39e1d807 of [/srv/app/$site_id] at 2020-02-13 19:42:52 +0000 UTC by root@$site_id> to /srv/app/$site_id/restores/39e1d807
ignoring error for /old/usr/share/zoneinfo/right/Turkey: Symlink: symlink Asia/Istanbul /srv/app/$site_id/restores/39e1d807/old/usr/share/zoneinfo/right/Turkey: file exists
There were 1 errors

What backend/server/service did you use to store the repository?

Local volume-mounted repo, via docker.

Expected behavior

All other content files in the repo were restored during the second call, but any symlinks that already existed have errors printed, even if their targets are the same. And, even if they were different, it shouldn't error, unless --verify exists(or some such).

No such error/warning was printed on the already existing regular files, so why does it do so on symlinks?

Actual behavior

Steps to reproduce the behavior

Backup a symlink, restore it twice.

Do you have any idea what may have caused this?

Do you have an idea how to solve the issue?

Did restic help you today? Did it make you happy in any way?

@rawtaz rawtaz added the state: need triaging need categorizing, labeling, next-step decision label Feb 13, 2020
@eigood
Copy link
Author

eigood commented Feb 13, 2020

As a followup, during the full restore to a separate folder, the first time, it was completely 100% empty. All files from the snapshot were written. The second time I ran the exact same command, the very same content files were fully 100% written again, but I got this symlink error. Since the content of each file was the same, it really shouldn't display these problems.

I have not verified that if I change the snapshot id(which might then have a slightly different set of content files) that I would get messages about normal files vs. symlinks. I just don't expect repeated runs of the same restore command to produce any kind of file already exists type warning.

@eigood
Copy link
Author

eigood commented Feb 13, 2020

restic/node.go, CreateFileAt always opens a file(CREATE|TRUNC), always replaces that file with the content, then closes it. That flow replaces the file with whatever was in the snapshot. But what if the file type on disk changes from what is in the snapshot? Or if the type is the same, should it be replaced as well?

The same problem seems to occur via device creation(which eventually calls mknod()).

@sseago
Copy link

sseago commented Mar 26, 2020

Also, if the symlink has changed (i.e. if I do a restore to the same target of a different (newer) snapshot, the error is the same, but this time since the symlink isn't created, the resulting filesystem has the wrong contents. If Restic could determine whether the symlink is the same as before and if it is, suppress the error, and if it is not, delete the symlink and recreate the new one, that would be ideal. If that's not possible, being able to distinguish between an actual error case (restic couldn't restore the symlink but what's there is different) from an OK situation (symlink unchanged, no need to update it) would be helpful.

@piotrcki
Copy link

Here is a script to reproduce the issue, coming from #3368 .

#!/bin/bash
set -e
set -x

TMP=$(mktemp -d restic-link-demo-XXXXXX)
cd "${TMP}"
mkdir dir1
echo A > dir1/file1
echo B > dir1/file2
ln -s file2 dir1/symlink-to-file2
echo 'pa$$' > restic-pass

restic init    -v -p restic-pass -r restic-repo
restic backup  -v -p restic-pass -r restic-repo dir1

rm -r dir1

restic restore -v -p restic-pass -r restic-repo -t . latest # This works
set +e
restic restore -v -p restic-pass -r restic-repo -t . latest # This FAILS
set -e

cd -
rm -rf "${TMP}"

@MichaelEischer MichaelEischer added category: restore help: minor complexity less complex issue, good for beginners that want a little challenge yet not too complicated help: wanted and removed state: need triaging need categorizing, labeling, next-step decision labels May 14, 2021
@MichaelEischer
Copy link
Member

restic could also just remove an old symlink if the path no longer matches.

@ghost
Copy link

ghost commented May 31, 2021

I observed an inherent problem with this situation.

When the error appear for symlink, the restore is stopped for next paths to restore.

restic -r s3:REPO_URL restore latest --target / --path "/" \
  --include /path/a \
  --include /path/b \
  --include /path/c \
  --host HOSTNAME

So if there are symlinks in path b, the restore process is exited before looking for path c restoring.

@MichaelEischer
Copy link
Member

@ldubut I'm not sure I understand the problem in your example. Doesn't restore just report the symlink error and then continue with restoring files? And which restic version are you using?

@ghost
Copy link

ghost commented Jun 7, 2021

@ldubut I'm not sure I understand the problem in your example. Doesn't restore just report the symlink error and then continue with restoring files? And which restic version are you using?

Hello, I'm using restic 0.12.0.

In my example, restic doesn't restore folders after the one where appears symlink errors.

restic -r s3:REPO_URL restore latest --target / --path "/" \
  --include /path/a \
  --include /path/b \
  --include /path/c \
  --host HOSTNAME

Here, if symlink error appears in folder b, the folder c isn't restored.
In this case, I need to run another restore command only for folder c.

So If I perform my restore like this:

restic -r s3:REPO_URL restore latest --target / --path "/" --include /path/a --host HOSTNAME
restic -r s3:REPO_URL restore latest --target / --path "/" --include /path/b --host HOSTNAME
restic -r s3:REPO_URL restore latest --target / --path "/" --include /path/c --host HOSTNAME

Symlink errors was returned, but I'm sure all datas are restored

@MichaelEischer
Copy link
Member

@ldubut Which log output does restic return in that case exactly?

@ghost
Copy link

ghost commented Jun 14, 2021

@ldubut Which log output does restic return in that case exactly?

HI,

stdout are similar as the author:

......
ignoring error for /etc/httpd/logs: Symlink: symlink ../../var/log/httpd /etc/httpd/logs: file exists
ignoring error for /etc/httpd/modules: Symlink: symlink ../../usr/lib64/httpd/modules /etc/httpd/modules: file exists
ignoring error for /etc/httpd/run: Symlink: symlink /run/httpd /etc/httpd/run: file exists
Fatal: There were 34 errors

But I think I had a bad observation, my files are finally restored.
Just content in /root are not restored, the problem maybe elsewhere.
So my issue seems invalid, sorry for my wrong return.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: restore help: minor complexity less complex issue, good for beginners that want a little challenge yet not too complicated help: wanted type: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants