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

Re: tar ate my symlinks



Brian Victor <bhv1@psu.edu> writes:
> 
> >Can you tell if the tarball actually has the symlinks in it but the
> >restore messed up, or if the files are stored incorrectly and restored
> >correctly?
> 
> I don't know; is there any way to tell that in a compressed (or even a
> decompressed) tarball?

Sure, use:

        tar tvfj linuxbackup.tar.bz2 | less

and you'll get an "ls -l"-style directory listing.

The symlinks should have an "lrwxrwxrwx" mode, and you should be able
to see their values.


I believe you've been bitten by a queer bit of "tar" behaviour.

Some time ago, there was a security bug where "tar" could be tricked
into following a symlink it had just created and then overwrite files
outside the directory where the restore was supposedly contained.  To
fix this problem, "tar" was patched to use a regular file placeholder
for possibly troublesome symlinks.  When "tar" completes, it's
supposed to go back and change those placeholder files back into
symlinks, but if "tar" crashes (or is stopped) before the restore
completes, the symlinks will be left as (zero-length) regular files.

Perhaps you interrupted the restore, or perhaps it crashed while
trying to restore "/proc" or something.  Then, "tar" wouldn't have had
a chance to go back and fix all the placeholders.

I would suggest reattempting the restore without extracting "/proc".
"tar"'s exclude mechanism is singularly stupid, so:

        tar -jxv --exclude=proc

will exclude *all* files and directories named "proc", not just the
top-level one.  However, you can do:

        ssh '...' | tar -jt | egrep -v '^proc' >FILES_TO_RESTORE
        ssh '...' | tar -jxv --files-from=FILES_TO_RESTORE

to avoid restoring the problematic "/proc" directory while still
restoring any "proc" files and directories hiding elsewhere.

If you still end up with screwed up symlinks no matter what you do,
all is not lost.  On the 192.168.2.10 machine, run the following
command:

        tar -jtvf linuxbackup.tar.bz2 | egrep '^l' | \
           perl -lane 'print "ln -snf $F[7] $F[5]" if (@F == 8 && $F[6] eq "->")' \
           > FIX_MY_SYMLINKS

That'll create a shell script capable of recreating all the broken
symlinks (except those where the symlink filename or value contained
whitespace---hopefully you don't have any of those that matter).
After you've double-checked that the commands in FIX_MY_SYMLINKS
aren't total nonsense, then on the broken machine, run:

        cd /
        ssh 192.168.2.10 cat FIX_MY_SYMLINKS | sh

and your symlinks should be restored.

Hope that helps.

-- 
Kevin Buhr <buhr@telus.net>



Reply to: