lzip-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: tarlz: error archiving broken symbolic link


From: Jason Lenz
Subject: Re: tarlz: error archiving broken symbolic link
Date: Mon, 7 Mar 2022 19:52:04 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1

Hi again Antonio,

I was able to test the modification you suggested and unfortunately it did not solve the problem. I do have further details that I didn't think to mention initially which have a direct relation to the error.

The path that contains the broken symlinks is within a fuse filesystem. Specifically it is from a restic (https://restic.net) backup repository on a hard drive. I used the restic mount command described in the link below.

https://restic.readthedocs.io/en/stable/050_restore.html#restore-using-mount

My previous comments still hold true in that standard gnu tar is able to create the archive from the fuse system without problems and other standard utilities such as cp, ls etc. all seem to work without a hitch accessing the fuse system.

This time in addition I tried copying the files from the restic fuse system to my ext4 filesystem (cp -a fuse_path ext4_path) and then executed tarlz using that as the source instead. tarlz was able to create the archive containing the broken symlinks without any problems when using the ext4 source path. So the issue only occurs when trying to use tarlz with the fuse system as a source.

I also found one other interesting thing. When I do a long listing (ls -l path/to/files) on the fuse vs. ext4 files there is one difference I see:

Output from ls -l on fuse:
lrwxrwxrwx 1 lenzj users 0 Nov 11 10:59 broken_symlink_filename -> ..

Output from ls -l on ext4:
lrwxrwxrwx 1 lenzj users 120 Nov 11 10:59 broken_symlink_filename -> ..

So in other words, the fuse filesystem is showing the size of all the symlink files as zero vs. a size of something greater than zero on the ext4 system.

Again apologies that I didn't think to check or mention all of this the first time. This seems like something the restic development team probably needs to fix on their fuse system implementation, but admittedly I'm not an expert on how fuse systems work. I will reach out to them to see if indeed this is something they can/should fix.

I was trying to think of simple way to create a test folder so that you could replicate the error on your system, but I haven't come up with anything yet other than an installation of restic along with replicating the same type of backup / mount scenario I am using. I don't expect you to go to all that trouble. I'll try and dig more on my own and let you know what I find out.

In the meantime I can use the workaround to copy files from fuse to my ext4 system before using tarlz to archive them.

Thanks again!
Jason

On 3/7/22 10:40, Antonio Diaz Diaz wrote:
Hello Jason,

Jason Lenz wrote:
$ tarlz -cf test.tar.lz /path/to/files
...
tarlz: /path/to/files/broken-symlink: Error reading link

I guess there is some difference between your system and mine, because I can't reproduce the error (not even by writing the archive to test.tar.lz):

$ md dir
$ touch dir/a dir/b
$ ln -s foo dir/broken-symlink
$ ls -go dir
total 0
-rw-r--r-- 1 0 Mar  7 16:35 a
-rw-r--r-- 1 0 Mar  7 16:35 b
lrwxrwxrwx 1 3 Mar  7 16:36 broken-symlink -> foo
$ tarlz -c dir | tarlz -tv ; echo $?
drwxr-xr-x antonio/users        0 2022-03-07 16:36 dir
-rw-r--r-- antonio/users        0 2022-03-07 16:35 dir/a
-rw-r--r-- antonio/users        0 2022-03-07 16:35 dir/b
lrwxrwxrwx antonio/users        0 2022-03-07 16:36 dir/broken-symlink -> foo
0

When replacing tarlz with standard GNU tar version 1.34 and the exact
same command line, it would successfully create the archive containing
the broken symlink files.

Thanks for the hint. I think I may have found the cause of the problem. In line 443 of create.cc tarlz calls readlink passing the size of the buffer and expecting as return value the size of the contents of the symbolic link:

  len = sz = readlink( filename, (char *)header + linkname_o, linkname_l );

But according to POSIX[1]:

"If the number of bytes in the symbolic link is less than bufsize, the contents of the remainder of buf are unspecified."

and

"Upon successful completion, these functions shall return the count of bytes placed in the buffer."

[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html

So readlink may be returning more bytes than it should if the link is shorter than the buffer. One possible fix would be to change line 443 to ask just for the bytes required instead of passing the full size of the buffer:

  len = sz = readlink( filename, (char *)header + linkname_o, st.st_size );

I have tried this change and it works. Please, test the change and report back. If it also works for you, I'll release a corrected version.

P.S.: I really appreciate your efforts on lzip and associated utilities.

Thanks. :-)

Best regards,
Antonio.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]