Bagaimana findmnt dapat membuat daftar bind mounts?

11

Banyak orang terus mengatakan bahwa Linux tidak menyimpan informasi tentang bind mounts, jadi tidak ada cara untuk mendapatkan daftar mereka dan sumber mereka. Berikut ini beberapa contohnya:

  • dari salah satu komentar di sini :

    IIRC informasi ini tidak disimpan di mana pun: setelah mount --bind, dua salinan itu setara, tidak ada satu yang lebih "asli" dari yang lain. Lagipula tidak ada yang orisinal jika Anda sudah tidak terpasang /mnt.

  • dari jawaban di situs ini :

    Jadi satu-satunya cara untuk mengingat mount apa yang mengikat mount adalah log dari perintah mount yang tersisa /etc/mtab. Operasi bind mount ditunjukkan oleh opsi bind mount (yang menyebabkan tipe sistem file diabaikan). Tetapi mount tidak memiliki opsi untuk mendaftar hanya filesystem yang dipasang dengan sekumpulan set opsi tertentu.

  • dari laporan bug Debian :

    Ini disengaja. Kedua titik pemasangan sepenuhnya sama dalam semua hal sehingga kernel tidak menyimpan flag apa pun untuk membedakannya.

Di atas adalah omong kosong. Alat findmntini dapat membuat daftar jalur sumber bind mounts (dalam bentuk device[source-path]; Saya juga mencoba untuk mendapatkannya hanya mencantumkan jalur sumber dan bukan perangkat). Jika kernel Linux mempertahankan bind mount, maka informasi itu harus disimpan di suatu tempat , jika tidak, ia tidak akan tahu /homepasti terikat /users. Jadi di mana data ini? Apakah ini disimpan di beberapa wilayah yang tidak jelas dalam RAM? Apakah findmntmencari di /procsuatu tempat?

Melab
sumber
Versi apa findmntyang Anda jalankan dan opsi apa yang Anda berikan? Milik saya tidak mencetaknya seperti itu dan melihat kode sumber yang tampaknya menggunakan _PATH_PROC_MOUNTINFOyang tampaknya /proc/self/mountinfotidak memiliki informasi ini di dalamnya juga.
Bratchley
OK, saya kira /proc/self/mountinforelatif baru saja direstrukturisasi. Saya menggunakan mesin RHEL6 saya sebelumnya yang tidak memiliki info jalur tetapi mesin RHEL7 saya melakukan dan seperti yang disebutkan dalam tautan Anda Wheezy juga.
Bratchley
Itu bukan omong kosong: itu benar dengan kernel yang lebih tua, tetapi kernel yang lebih baru melacak informasi.
Gilles 'SO- stop being evil'
@Gilles Lalu bagaimana mungkin sebuah bind mount bertahan jika informasi bahwa satu direktori di-mount di tempat lain tidak dilacak?
Melab
@Elab Sebenarnya, bind mount lebih mudah untuk bertahan jika Anda tidak melacak bahwa itu adalah bind mount. Ketika /dev/Asudah terpasang di /Bdan Anda melakukannya mount --bind /B /C, kernel yang lebih tua hanya ingat /B → /dev/Adan /C → /dev/A, mereka tidak ingat hubungan antara /Bdan /C. Jadi unmount /Bsecara alami tidak berpengaruh /C. Kernel yang lebih baru ingat bahwa /Citu adalah ikatan /B, tetapi dengan cara yang tidak mencegah /Cdari melanjutkan bekerja jika /Btidak di-mount, saya tidak tahu persis bagaimana caranya.
Gilles 'SANGAT berhenti menjadi jahat'

Jawaban:

12

Anda sedikit salah paham; dua titik pemasangan sama dalam hal izin, bendera, dll karena ikatan secara efektif mengalihkan akses dari satu jalur ke jalur lainnya. Tetapi mereka masih berbeda .

Jika Anda melihat /proc/self/mountinfoAnda akan melihat tampilan kernel dari dunia mount untuk proses ini (ruang nama membuat segalanya lebih rumit; tidak hanya ada satu tampilan dari tabel mount).

man 5 procakan menjelaskan format file ini, tetapi Anda dapat melihat hierarki pohon dan di mana bind mount memiliki "induk". Ini adalah file yang findmntdiuraikan.

Stephen Harris
sumber
9

Linux tidak menyimpan informasi tentang mount mana yang merupakan mount mengikat . Itu menyimpan informasi tentang semua mount termasuk bind mounts .

Ini sangat mirip dengan tautan keras. Mount tautan ke sistem file seperti tautan nama file ke inode. Satu-satunya perbedaan adalah bahwa mounts juga memiliki flag per-mountpoint dan dapat merujuk ke subdirektori dari sistem file target alih-alih root sistem file.

Ketika Anda membuat tautan keras, sistem file tidak menyimpan nama file mana yang asli dan mana yang merupakan tautan keras. Keduanya hanya merujuk pada inode yang sama. Jika Anda membatalkan tautan file asli situasinya tidak dapat dibedakan dari apakah Anda secara langsung membuat file dengan nama file kedua.

Kembali ke bind mounts: Kernel menyimpan tabel yang berisi filesystem (diidentifikasi oleh major: pasangan nomor minor), mountpoint, path relatif ke root filesystem dan beberapa flag. Anda dapat mengakses daftar ini dengan melihat /proc/self/mountinfo. (Semakin rumit ketika ruang nama terlibat, seperti yang disebutkan @ stephen-harris). findmntparsing daftar ini.

Jika root Anda /dev/sda1dengan mayor: minor 8:1dan Anda jalankan mount --bind /a /b /proc/self/mountinfoakan berisi baris yang mirip dengan ini:

1 0 8:1 / / rw - ext4 /dev/sda1 rw,errors=remount-ro
2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro

Jika Anda /homeadalah /dev/sda2dengan utama: minor 8:2dan Anda menjalankan mount --bind /home /usersitu akan terlihat seperti ini:

1 0 8:1 / / rw - ext4 /dev/sda1 rw,errors=remount-ro
2 1 8:2 / /home rw - ext4 /dev/sda2 rw
3 1 8:2 / /users rw - ext4 /dev/sda2 rw

Kolom yang relevan untuk pertanyaan Anda adalah yang ketiga, keempat dan kelima. Ini adalah id filesystem (untuk filesystem nyata sama dengan device mayor: minor; untuk filesystem virtual seperti tmpfs [0: counter ]), path relatif ke root filesystem yang terikat ke mountpoint (biasanya / untuk normal mounts, bisa berupa apa saja untuk binding mounts) dan mountpoint.
Untuk makna kolom yang tersisa, lihat dokumentasi kernel Linux .

findmntmemanggil jalur sumber relatif ke root filesystem "FSROOT". Anda bisa menggunakannya findmnt -o TARGET,FSROOTuntuk mendapatkannya. Jika Anda menginginkan path sumber absolut, Anda mungkin perlu mem-parsing /proc/self/mountinfosendiri dan menggabungkan informasi tentang mount untuk sistem file yang sama.

Untuk informasi lebih lanjut, lihat jawaban saya untuk "Daftar hanya ikatan mount" .

cg909
sumber
Jika /proc/self/mountinfodapat berisi baris seperti 2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro, maka Linux pasti tidak menyimpan beberapa informasi tentang gunung mengikat.
Melab
Lihat contoh kedua saya. Itu membuat informasi yang filesystem sudah di-mount dan jalur mana yang relatif terhadap root filesystem yang dipasang . Jadi untuk mount --bind /home/melab /mntgaris yang dihasilkan mungkin terlihat seperti salah satu dari berikut tergantung pada dari /homedan /home/melabmerupakan mountpoint sebuah: 3 1 8:1 /home/melab /mnt rw - ext4 /dev/sda1 rw, 3 1 8:2 /melab /mnt rw - ext4 /dev/sda2 rw,3 1 8:3 / /mnt rw - ext4 /dev/sda3 rw
cg909
Memang benar bahwa sesuatu yang berbeda /di kolom keempat sering menunjukkan bind mount. Tetapi mungkin juga subvolume Btrfs.
cg909
Apakah /dev/sda3seharusnya dipasang di /home/melab?
Melab
Iya. Dalam contoh saya, saya menggunakan /dev/sda1as /, /dev/sda2as /homedan /dev/sda3as/home/melab
cg909