Ich habe ein Skript, dass Hardlinks von Dateien erzeugt, die der Benutzer wählen kann. Die Dateien befinden sich auf einem per nfs eingebundenem Verzeichnis. Es ist denkbar, dass der Benutzer versehentlich Dateien von seinem Rechner wählt, die sich dann natürlich nicht hardlinken lassen. Ich würde daher vorher gerne prüfen, ob Datei und Verzeichnis in dem der Link entstehen soll auch wirklich auf demselben Datenträger sind. Ich habe das ursprüngliche Skript etwas erweitert und in ruby geschrieben. Der stat-Aufruf ist in ruby in der Klasse File::Stat gekapselt. Die Methode dev dieser Klasse gibt mir die device Nummer. Reicht es, diese device Nummern für die Datei und das Verzeichnis auf Gleichheit zu prüfen, das heißt, ist es garantiert, dass verschiedene Dateisysteme hier verschiedene Nummern haben? Oder gibt es bessere Ideen, wie ich sicherstellen kann, dass ln nicht fehlschlägt?
Fesstellen ob Datei und Verzeichnis auf demselben Dateisystem sind
|
Anmeldungsdatum: Beiträge: 1011 |
|
||
|
Anmeldungsdatum: Beiträge: 6532 |
Also ich mache das bisher auch so wenn ich Dateien verschieben will. Denn auf dem gleichen Dateisystem kann man das mit rename() machen, was deutlich schneller geht. Ich benutze dafür die entsprechende C-Funktion. Geht aber auch in der Shell stat --print="%D\n" <Dateiname> 802 $ Wie das genau codiert ist, kann ich ohne mein dickes Buch jetzt aber nicht sagen. p.s. Ob das so auch übers Netzwerk geht, weiß ich nicht. Mit Sockets habe ich noch nicht experimentiert. |
||
|
Projektleitung
Anmeldungsdatum: Beiträge: 13242 |
Nein, ich denke, das sollte tun. Ich habe das mal eben überprüft mit meinem BTRFS-Volume, das zwei Subvolumes hat, die unter / und /home gemountet sind:
Man sieht, obwohl es ja sogar nur ein Volume darunter ist, wir das vermutlich durch Linux VFS auf zwei Device-Ids gemappt. Allerdings: der ln kann ja auch aus anderen Gründen scheitern. Man könnte also auch die Strategie verfolgen es einfach zu tun und die Fehlermeldung anzuzeigen, die ggf. hochkommt (wenn die denn sinnvoll ist). |
||
|
Anmeldungsdatum: Beiträge: 6532 |
In meinem dicken Buch ist die Rede von Major und Minor ID Nummer, aber wie die aufgeteilt sind, konnte ich aus dem Text jetzt nicht direkt ablesen. Jedenfalls ist da keine Tabelle. Aber dazu mal drei weitere Beispiele: $ stat --print="%D\n" /etc/fstab 801 $ Das ist die erste Partition auf dem selben PC wie im obigen Beispiel. Ein weiteres Beispiel von einem USB-Stick (aus der Grabbelkiste, frei zur weiteren Verwendung). $ stat --print="%D\n" '/media/manfred/Lubuntu 16.04.3 LTS i386/md5sum.txt' 821 manfred@samurai:~$ Was ich jetzt aber nicht ganz verstehe ist folgendes Beispiel: $ stat --print="%D\n" extern/data/ab0308.jpg 37 $ Das ist eine Datei, die auf einem NAS liegt und im home Verzeichnis unter ~/extern eingebunden ist., aber auch eine deutlich andere ID hat. |
||
|
Anmeldungsdatum: Beiträge: 17630 |
Das halte ich für ein Gerücht. Ein mv auf dem gleichen Dateisystem ändert nur den Eintrag in der Tabelle des Dateisystems, aber verschiebt, also liest und schreibt kein einziges Bytes der Daten in der Datei. Eine 1,6 GB-Datei wird in weniger als 1/100tel Sekunde verschoben auf einer klassischen Festplatte. |
||
|
Anmeldungsdatum: Beiträge: 6532 |
Wieso das denn?
Das sag ich doch. Ein Rename auf dem gleichen Dateisystem ist auch nichts weiter als eine Änderung am Inhalt der Dateien, die die betroffenen Verzeichnisse repräsentieren. Funktioniert aber nur innerhalb eines Dateisystems (Verzeichnisses?). Ein Verzeichnis ist ja auch nur eine Datei. Und wenn die Aktion sich innerhalb einer Partition abspielt, werden nur Einträge von einer Datei in eine andere ausgeführt (wenn es die selbe Partition ist). Wenn das nicht richtig wäre, wäre ich schon vor einigen Jahren böse auf die Nase gefallen. |
||
|
(Themenstarter)
Anmeldungsdatum: Beiträge: 1011 |
Es ist jedenfalls das was ich brauche, dass eingebundene Verzeichnisse unterscheidbar sind. Ich war etwas irritiert, dass das so kleine Zahlen sind. Da ich nicht weiß, wie sich die bestimmen, wären da ja zufällige Kollisionen eher denkbar, im Gegensatz zu den länglichen UUIDs. Eine Fehlerbehandlung, wenn ln fehlschlägt empfiehlt sich natürlich in jedem Fall, aber ich ziehe es vor zwischen zwei Arten von Fehlern zu unterscheiden. Fehler durch den Benutzer, soll dieser korrigieren können. Dazu muss ich ihm aber eine sinnvolle Fehlermeldung anzeigen, die er versteht. Beispielsweise prüfe ich auch, ob versehentlich eine Verzeichnis ausgewählt wurde, damit ich eine hilfreiche Fehlermeldung der Art "Sie haben Verzeichnis foobar ausgewählt. Ein Hardlink für ein Verzeichnis ist nicht möglich." ausgeben kann. Wenn ich einfach einen generellen Fehler der Art "ln hat nicht funktioniert" für alle Fehler ausgebe, besteht die Gefahr, dass ich jedesmal hinlaufen und es selbst erklären muss. Danke an alle Kommentatoren. |
||
|
Projektleitung
Anmeldungsdatum: Beiträge: 13242 |
|||
|
Anmeldungsdatum: Beiträge: 6532 |
Nur damit keine Missverständnisse auftreten, du kannst damit keine Verzeichnisse unterscheiden, nur die Dateisysteme auf dem die Ziele liegen.
Besonders viele Geräte hat man ja selten. Mein Buch beschreibt das nicht weiter, erwähnt aber das bis Kernel 2.4 für Major (Type) und Minor ID nur jeweils 8 Bit reserviert wurden. |
||
|
Projektleitung
Anmeldungsdatum: Beiträge: 13242 |
|||
|
Anmeldungsdatum: Beiträge: 17630 |
|||
|
(Themenstarter)
Anmeldungsdatum: Beiträge: 1011 |
|||
|
Anmeldungsdatum: Beiträge: 6532 |
In "The Linux Programming Interface" Chap. 14.2 p.254 steht:
...
Ich denke das reicht. Ich habe nochmal ein Experiment gemacht, und eine der Beispieldateien auf dem NAS abgefragt, wobei ich das NAS diesmal über Caja eingebunden hatte: manfred@samurai:~$ stat -c %D /run/user/1000/gvfs/smb-share\:server\=lager1.local\,share\=homes/manfred/data/ab0308.jpg 31 Interessant ist, das diesmal eine andere ID kommt. Ob das jetzt an gvfs liegt oder daran dass es sich um ein Raid System handelt, kann ich nicht sagen. |
||
|
Projektleitung
Anmeldungsdatum: Beiträge: 13242 |
Gib doch mal die gesamten Befehle und Ausgaben aus. Ansonsten ist unklar, was Du mit "anderer ID" meinst. |
||
|
Anmeldungsdatum: Beiträge: 6532 |
Da fehlt doch nur der Prompt in der letzten Zeile. Was ich gemacht habe: Ich habe in Caja über Orte das NAS gesucht, mich eingelogt und fertig. Danach habe ich mir mit mc den Pfad herausgesucht und genau diesen im Terminal eingegeben. Ich werde das morgen noch einmal wiederholen, um zu sehen ob die ID gleich bleibt. Was kann ich denn noch testen? |