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.