rsync zwischen MacOS (HFS+) und Linux (ext3) – und defekte Dateinamen

Bei umfangreicheren rsync-Läufen hier im lokalen Netz (ging um ca. 4 TB die von einem Ubuntu Server mit ext3 auf einen Mac mit HFS+ gehen sollten) stellten sich 2 Probleme heraus, die beim Sync zwischen Linux Maschinen nicht auftraten:

  • Ein großer Teil der Daten (und zwar alle mit Leerzeichen oder Umlauten im Dateinamen) wurde bei jedem rsync Aufruf neu übertragen, obwohl die Dateien sich nicht geändert hatten.
  • Umlaute waren z.T. defekt.

Eine längere Herleitung spare ich mir hier mal – statt dessen nur das Ergebnis der Recherchen, da das ggf. noch für jemanden nützlich sein könnte:

Das Problem entstand durch unterschiedliche Charsets auf beiden Maschinen:

Something else that can trip up rsync is a filesystem changeing the filename behind the scenes. This can happen when a filesystem changes an all-uppercase name into lowercase, or when it decomposes UTF-8 behind your back.

An example of the latter can occur with HFS+ on Mac OS X: if you copy a directory with a file that has a UTF-8 character sequence in it, say a 2-byte umlaut-u (303274), the file will get that character stored by the filesystem using 3 bytes (165314210), and rsync will not know that these differing filenames are the same file (it will, in fact, remove a prior copy of the file if –delete is enabled, and then recreate it).

You can avoid a charset problem by passing an appropriate –iconv option to rsync that tells it what character-set the source files are, and what character-set the destination files get stored in. For instance, the above Mac OS X problem would be dealt with by using –iconv=UTF-8,UTF8-MAC (UTF8-MAC is a pseudo-charset recognized by Mac OS X iconv in which all characters are decomposed).

(Die Erklärung stammt aus der rsync FAQ.)

Dem geneigten Mac-User fällt aber leider schnell auf, dass das mitgelieferte rsync den Parameter --iconv leider nicht versteht. Hier empfiehlt sich das Updaten z.B. über Macports – dazu hatte ich hier gerade schon ein paar Zeilen geschrieben.

Lange Rede, kurzer Sinn – nach dem rsync Update und der Angabe der Parameter schaut das bisher sehr gut aus. Folgender Kommandozeilenaufruf wird dabei verwendet:

rsync -a --modify-window=1 --stats --progress --exclude "*.frk"' --delete --iconv=UTF8-MAC,UTF8 root@SERVERNAME:/pfad/zum/Quell-Verzeichnis/ /pfad/zum/Ziel-Verzeichnis/

Kurznotiz: Darwinports, Fink und Macports

Nachdem Stefan in seinem Blog kurz und eindringlich von Darwinports abriet und Fink mich vor einiger Zeit schon nicht begeistert hatte, habe ich heute mal Macports eine Chance gegeben.

Kurzfazit:

  • Installation über einen Mac Installer (!), entsprechend problemlos und schnell
  • Installation von Paketen sehr einfach, automatische Auflösung von Abhängigkeiten klappt gut
  • binnen 15 min. gewechselt vom unerträglich schlechten RSYNC auf dem Mac zu einer aktuellen Version (rsync  version 3.0.7  protocol version 30)

Tipp der Redaktion, sozusagen 😉

rsync über FTP mit fuse

Es ist schon spät, daher eine eher Staccato-artige Zusammenfassung in der Hoffnung, dass das noch für andere hilfreich sein könnte:

Problem:

Man will Daten von Server A (unter Linux, voller Zugriff) auf oder von Server B (nur FTP, kein anderer Zugriff) kopieren bzw. mit diesem Server abgleichen (Konkreter Anwendungsfall: Man will verschiedene WordPress Installationen nebst Plugins automatisiert von einem zentralen Server updaten).

Normalerweise nähme man rsync – hätte man weiter reichenden Zugriff auf Server B als eben FTP:

Lösung:

Die benötigten Pakete installieren mit dem $Installer-Deiner-Wahl, hier z.B. mit apt:

apt-get install curlftpfs

Abhängigkeiten sollten dann (wenn man etwas taugliches nutzt) automatisch aufgelöst werden, das Paket curlftpfs hängt natürlich vom fuse ab. Falls das nicht automatisch passieren sollte, bitte manuell nachhelfen:

apt-get install fuse-utils libfuse2

Dann ein Verzeichnis anlegen, in das wir später das „FTP Laufwerk“ mounten wollen, z.B.

mkdir /home/www/mount/servername

Nun das FTP Share mounten:

curlftpfs USERNAME:PASSWORD@SERVER-ADRESSE /home/www/mount/servername/

Und vóila: Der FTP Server sollte nun über das lokale Dateisystem verfügbar sein und somit plötzlich auch für rsync.

Bei der rsync Anwendung sind aber ein paar Sachen zu beachten, da ansonsten stets Fehler auftreten (Dateien können nicht geschrieben werden etc.).

Man will z.B. die sonst sehr gern genommene Option „-a“ oder, mein Klassiker, „-avz“ nicht nutzen. Mit dieser Option wird u.a. versucht, den Eigentümer oder die Gruppe einer Datei zu setzen. Dies schlägt auf dem FTP Server im Zweifelsfalle fehl, wodurch der Vorgang nicht komplett abgeschlossen werden kann. Ferner versucht rsync stets, das TMP-Verzeichnis innerhalb der tranferierten Daten abzulegen – was wiederum zu Problemen führt.

All diese Probleme kann man wie folgt umschiffen:

rsync -rltv --temp-dir=/tmp/ --stats --progress /home/www/wordpress-update/ /home/www/mount/servername

Mein aktueller Anwendungsfall war ja das Updaten von WordPress Installationen – hierbei will man einige Dateien auf keinen Fall überschreiben (die Konfigurationsdatei, die XML-Sitemap des Google-Sitemaps-Plugins und die .htaccess). Da die Anzahl der auszuschließenden Dateien recht gering ist, kann man das noch prima mittels --exclude machen:

rsync -rltv --temp-dir=/tmp/ --stats --progress --exclude=wp-config.php --exclude=robots.txt --exclude=sitemap* --exclude=.htaccess --exclude=wp-content /home/www/wordpress/ /home/www/mount/servername

Weiteres und eine auführlichere Beschreibung vielleicht schon morgen, jetzt muss ich erstmal schlafen 😉

Danke für die Anregungen/Ideen an: blog.simlau.net, lieber-linux.de, stackoverflow.com, debiantutorials.net und commandlinefu.com.