Wenn ich eine Datei auf einem BTRFS-Subvolume starte, erhalte ich die Hauptgerätenummer 0
. Gibt es eine zuverlässige Möglichkeit, den Einhängepunkt dieses Geräts zu finden, ohne im Voraus zu wissen, dass es sich um ein BTRFS-Subvolume handelt?
zB möchte ich dies in Python tun können:
>>> st = os.stat('a file')
>>> os.major(st.st_dev)
0
>>> os.minor(st.st_dev)
38
>>> os.path.exists('/sys/dev/block/0:38')
False
>>> magic_method_that_gets_mount_point(0, 38)
'/home'
>>> magic_method_that_gets_mount_point(8, 1)
'/boot'
(in meinem Fall ist sda1
( /sys/dev/block/8:1
) auf gemountet /boot
und /home
ist ein BTRFS-Untervolume von sda2
).
Bearbeiten
Ich müsste dies tun können, ohne den Pfad der Datei zu kennen. Oben habe ich os.stat
als Beispiel verwendet, aber die Informationen werden tatsächlich aus einem ioctl
Aufruf eines Loop-Geräts abgerufen, das Folgendes zurückgibt:
struct loop_info64 {
uint64_t lo_device;
uint64_t lo_inode;
uint64_t lo_rdevice;
uint64_t lo_offset;
uint64_t lo_sizelimit;
uint32_t lo_number;
uint32_t lo_encrypt_type;
uint32_t lo_encrypt_key_size;
uint32_t lo_flags;
uint8_t lo_file_name[64];
uint8_t lo_crypt_name[64];
uint8_t lo_encrypt_key[32];
uint64_t lo_init[2];
};
Das Feld ist vorhanden, lo_file_name
hat jedoch eine maximale Länge von 63 Zeichen und kann daher nicht zuverlässig geöffnet werden. Ich weiß auch von /sys/block/loopX/loop/backing_file
, dies ist jedoch nur unter Linux >= 2.6.37 verfügbar und mein Code muss unter CentOS 6 (2.6.32) ausgeführt werden.
Bearbeitung #2
Mein ultimatives Ziel hier ist es, die Sicherungsdatei für ein Loop-Gerät zuverlässig finden zu können. Sogar util-linux tut dies nicht auf Kerneln < 2.6.37, z. B.
> dd if=/dev/urandom bs=4096 count=256 of=/root/a_really_really_really_really_really_really_really_long_file_name.img
256+0 records in
256+0 records out
1048576 bytes (1.0 MB) copied, 0.137397 s, 7.6 MB/s
> LD=`losetup -f --show /root/a_really_really_really_really_really_really_really_long_file_name.img`
> losetup $LD
/dev/loop1: [fd00]:922372 (/root/a_really_really_really_really_really_really_really_long_*)
Beachten Sie, dass der Dateiname abgeschnitten ist. Dies liegt daran, dass Util-Linux die loop_info64
Struktur verwendet, bei der das Feld auf 63 Zeichen begrenzt ist lo_file_name
.
Was ich zuverlässig bekomme, ist die Geräte-ID und die Inode-Nummer der Sicherungsdatei. Hier stoße ich auf ein Problem, da die Sicherungsdatei auf einem Btrfs-Subvolume gespeichert ist.
Antwort1
Ich habe mir den Quellcode der GNU Core-Utils angesehen, insbesondere den df
Befehl.
Es durchläuft die Hierarchie rekursiv, bis sich die Geräte-IDs ändern. Der Punkt, an dem sich die IDs ändern, ist der Einhängepunkt.
Ich habe gerade versucht, den Einhängepunkt des Dateisystems zu finden, in dem ~/home/me/a-dir/another-dir
es sich befindet. Folgendes habe ich getan:
stat . #noting device IDs
while id not changes and root not hit
do
cd ..
stat .
done
if root not hit
then
cd -
fi
(Dieser Code ist Pseudo-Bash, alle Bedingungen und Schleifen wurden manuell erstellt. Er dient nur dazu, das Konzept zu beweisen. Die Programmierung und Übersetzung in Python überlasse ich als Übung dem Leser.)