TAR und die Symlinks

Von Problemen mit TAR-Backups hört man zum Glück recht selten, heute schauen wir uns mal eines dieser Probleme an: Symlinks.

Wann man Symlinks nicht erhält

Schauen wir uns erstmal an um was es geht. So sieht etc/alternatives aus:

[root@s160 tmp]# ls -la /etc/alternatives/
insgesamt 68
drwxr-xr-x 2 root root 4096 2. Aug 06:22 .
drwxr-xr-x 125 root root 12288 2. Aug 06:25 ..
lrwxrwxrwx 1 root root 39 2. Aug 06:22 cifs-idmap-plugin -> /usr/lib64/cifs-utils/cifs_idmap_sss.so
lrwxrwxrwx 1 root root 25 2. Aug 06:22 ebtables -> /usr/sbin/ebtables-legacy
lrwxrwxrwx 1 root root 37 2. Aug 06:22 ifdown -> /etc/sysconfig/network-scripts/ifdown
lrwxrwxrwx 1 root root 35 2. Aug 06:22 ifup -> /etc/sysconfig/network-scripts/ifup
lrwxrwxrwx 1 root root 26 2. Aug 06:22 ip6tables -> /usr/sbin/ip6tables-legacy
lrwxrwxrwx 1 root root 34 2. Aug 06:22 ip6tables-restore -> /usr/sbin/ip6tables-legacy-restore
lrwxrwxrwx 1 root root 31 2. Aug 06:22 ip6tables-save -> /usr/sbin/ip6tables-legacy-save
lrwxrwxrwx 1 root root 25 2. Aug 06:22 iptables -> /usr/sbin/iptables-legacy
lrwxrwxrwx 1 root root 33 2. Aug 06:22 iptables-restore -> /usr/sbin/iptables-legacy-restore
lrwxrwxrwx 1 root root 30 2. Aug 06:22 iptables-save -> /usr/sbin/iptables-legacy-save
lrwxrwxrwx 1 root root 60 2. Aug 06:22 java -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64/bin/java
lrwxrwxrwx 1 root root 68 2. Aug 06:22 java.1.gz -> /usr/share/man/man1/java-java-11-openjdk-11.0.3.7-1.fc29.x86_64.1.gz
lrwxrwxrwx 1 root root 59 2. Aug 06:22 jjs -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64/bin/jjs
lrwxrwxrwx 1 root root 67 2. Aug 06:22 jjs.1.gz -> /usr/share/man/man1/jjs-java-11-openjdk-11.0.3.7-1.fc29.x86_64.1.gz
lrwxrwxrwx 1 root root 51 2. Aug 06:22 jre -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64
lrwxrwxrwx 1 root root 51 2. Aug 06:22 jre_11 -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64
lrwxrwxrwx 1 root root 50 2. Aug 06:22 jre_11_openjdk -> /usr/lib/jvm/jre-11-openjdk-11.0.3.7-1.fc29.x86_64
lrwxrwxrwx 1 root root 51 2. Aug 06:22 jre_openjdk -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64
lrwxrwxrwx 1 root root 63 2. Aug 06:22 keytool -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64/bin/keytool
lrwxrwxrwx 1 root root 71 2. Aug 06:22 keytool.1.gz -> /usr/share/man/man1/keytool-java-11-openjdk-11.0.3.7-1.fc29.x86_64.1.gz
lrwxrwxrwx 1 root root 34 2. Aug 06:22 libnssckbi.so.x86_64 -> /usr/lib64/pkcs11/p11-kit-trust.so
lrwxrwxrwx 1 root root 45 2. Aug 06:22 libwbclient.so.0.14-64 -> /usr/lib64/samba/wbclient/libwbclient.so.0.14
lrwxrwxrwx 1 root root 23 2. Aug 06:22 mta -> /usr/sbin/sendmail.exim
lrwxrwxrwx 1 root root 19 2. Aug 06:22 mta-mailq -> /usr/bin/mailq.exim
lrwxrwxrwx 1 root root 29 2. Aug 06:22 mta-mailqman -> /usr/share/man/man8/exim.8.gz
lrwxrwxrwx 1 root root 24 2. Aug 06:22 mta-newaliases -> /usr/bin/newaliases.exim
lrwxrwxrwx 1 root root 15 2. Aug 06:22 mta-pam -> /etc/pam.d/exim
lrwxrwxrwx 1 root root 19 2. Aug 06:22 mta-rmail -> /usr/bin/rmail.exim
lrwxrwxrwx 1 root root 19 2. Aug 06:22 mta-rsmtp -> /usr/bin/rsmtp.exim
lrwxrwxrwx 1 root root 18 2. Aug 06:22 mta-runq -> /usr/bin/runq.exim
lrwxrwxrwx 1 root root 22 2. Aug 06:22 mta-sendmail -> /usr/lib/sendmail.exim
lrwxrwxrwx 1 root root 63 2. Aug 06:22 pack200 -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64/bin/pack200
lrwxrwxrwx 1 root root 71 2. Aug 06:22 pack200.1.gz -> /usr/share/man/man1/pack200-java-11-openjdk-11.0.3.7-1.fc29.x86_64.1.gz
lrwxrwxrwx 1 root root 60 2. Aug 06:22 rmid -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64/bin/rmid
lrwxrwxrwx 1 root root 68 2. Aug 06:22 rmid.1.gz -> /usr/share/man/man1/rmid-java-11-openjdk-11.0.3.7-1.fc29.x86_64.1.gz
lrwxrwxrwx 1 root root 67 2. Aug 06:22 rmiregistry -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64/bin/rmiregistry
lrwxrwxrwx 1 root root 75 2. Aug 06:22 rmiregistry.1.gz -> /usr/share/man/man1/rmiregistry-java-11-openjdk-11.0.3.7-1.fc29.x86_64.1.gz
lrwxrwxrwx 1 root root 31 2. Aug 06:22 spf -> /usr/bin/spfquery.perl-Mail-SPF
lrwxrwxrwx 1 root root 27 2. Aug 06:22 spf-daemon -> /usr/bin/spfd.perl-Mail-SPF
lrwxrwxrwx 1 root root 47 2. Aug 06:22 spfquery-man-page -> /usr/share/man/man1/spfquery-perl-Mail-SPF.1.gz
lrwxrwxrwx 1 root root 65 2. Aug 06:22 unpack200 -> /usr/lib/jvm/java-11-openjdk-11.0.3.7-1.fc29.x86_64/bin/unpack200
lrwxrwxrwx 1 root root 73 2. Aug 06:22 unpack200.1.gz -> /usr/share/man/man1/unpack200-java-11-openjdk-11.0.3.7-1.fc29.x86_64.1.gz
lrwxrwxrwx 1 root root 15 2. Aug 06:22 whois -> /usr/bin/jwhois
lrwxrwxrwx 1 root root 37 2. Aug 06:22 whois-man -> /usr/share/man/man1/whois.jwhois.1.gz

In dem Verzeichnis schreiben Pakete Symlinks zu Programmen rein, die es im System doppelt gibt. Z.B.: OpenJDK mit Java 8 und Java 11 . Das Paket, welches zuletzt installiert oder aktualisiert wird, nagelt dort die Symlinks über. (Anm. so bin ich überhaupt erst zum Thema gekommen 😉 ).

Wenn man jetzt die Symlinks vor der „Katastrophe“ wieder haben will, entpackt man sein Systembackup. Weil /etc weit vorne im Archiv steht und so ein Backup auch schon mal 80-100 GB haben kann, bricht man i.d.R. ab, wenn tar -xvzf archiv.tgz etc/alternatives keine Ausgaben mehr macht, weil der Verzeichnispfad dann „durch“ ist. So spart man sich viiiieeel Zeit, oder auch nicht 🙂

Weil, wenn man dann in das Verzeichnis schaut sieht man das hier:

[root@s160 tmp]# ls -ls etc/alternatives/
insgesamt 0
0 ---------- 1 root root 0  2. Aug 09:30 cifs-idmap-plugin
0 ---------- 1 root root 0  2. Aug 09:30 ebtables
0 ---------- 1 root root 0  2. Aug 09:30 ifdown
0 ---------- 1 root root 0  2. Aug 09:30 ifup
0 ---------- 1 root root 0  2. Aug 09:30 ip6tables
0 ---------- 1 root root 0  2. Aug 09:30 ip6tables-restore
0 ---------- 1 root root 0  2. Aug 09:30 ip6tables-save
0 ---------- 1 root root 0  2. Aug 09:30 iptables
0 ---------- 1 root root 0  2. Aug 09:30 iptables-restore
0 ---------- 1 root root 0  2. Aug 09:30 iptables-save
0 ---------- 1 root root 0  2. Aug 09:30 java
0 ---------- 1 root root 0  2. Aug 09:30 ld
0 ---------- 1 root root 0  2. Aug 09:30 libnssckbi.so.x86_64
0 ---------- 1 root root 0  2. Aug 09:30 libwbclient.so.0.14-64
0 ---------- 1 root root 0  2. Aug 09:30 mta
0 ---------- 1 root root 0  2. Aug 09:30 mta-mailq
0 ---------- 1 root root 0  2. Aug 09:30 mta-mailqman
0 ---------- 1 root root 0  2. Aug 09:30 mta-newaliases
0 ---------- 1 root root 0  2. Aug 09:30 mta-pam
0 ---------- 1 root root 0  2. Aug 09:30 mta-rmail
0 ---------- 1 root root 0  2. Aug 09:30 mta-rsmtp
0 ---------- 1 root root 0  2. Aug 09:30 mta-runq
0 ---------- 1 root root 0  2. Aug 09:30 mta-sendmail
0 ---------- 1 root root 0  2. Aug 09:30 spf
0 ---------- 1 root root 0  2. Aug 09:30 spf-daemon
0 ---------- 1 root root 0  2. Aug 09:30 spfquery-man-page
0 ---------- 1 root root 0  2. Aug 09:30 whois
0 ---------- 1 root root 0  2. Aug 09:30 whois-man

Das schockt, oder? Keine Symlinks mehr, nur noch leere Files mit 0 Byte Größe.

Was tun????

Vielleicht Man-Page lesen? Viel Spaß beim Suchen, keine Chance 🙂 Da findet sich nur dies:

-h, –dereference
Follow symlinks; archive and dump the files they point to.

Das macht TAR eh von alleine, … sagt man.  Probierts aus, ob Ihr -h im Extract drin habt oder nicht, spielt keine Rolle. Die Ursache liegt in einem kleinen Erwartungsproblem: Man erwartet, daß sobald eine Datei aus dem Archiv extrahiert wurde, diese im Filesystem auch mit allen Infos wie UID/GID, Filerechten vorhanden ist.

Da tickt tar aber leider etwas merkwürdig. Es macht das erst, wenn das Backup komplett durchlaufen wurde.

Lösung

Die Lösung lautet: Durchlaufen lassen!

Danach stimmt alles wieder, so wie man das erwarten würde. Machmal sind Lösung auch trivial. Das es im Einzelfall dann 100GB per Netzwerk sind, ist dann halt so, wenn man alles in ein Backupfile schreibt.