GNU/Linux >> Belajar Linux >  >> Linux

Sistem file virtual di Linux:Mengapa kita membutuhkannya dan cara kerjanya

Apa itu sistem file? Menurut kontributor dan penulis Linux awal Robert Love, "Sistem file adalah penyimpanan data hierarkis yang mengikuti struktur tertentu." Namun, deskripsi ini berlaku sama baiknya untuk VFAT (Virtual File Allocation Table), Git, dan Cassandra (database NoSQL). Jadi apa yang membedakan sistem file?

Dasar-dasar sistem file

Kernel Linux mengharuskan entitas untuk menjadi sistem file, ia juga harus mengimplementasikan open() , baca() , dan tulis() metode pada objek persisten yang memiliki nama yang terkait dengannya. Dari sudut pandang pemrograman berorientasi objek, kernel memperlakukan sistem file generik sebagai antarmuka abstrak, dan tiga fungsi besar ini adalah "virtual", tanpa definisi default. Oleh karena itu, implementasi sistem file default kernel disebut sistem file virtual (VFS).

VFS mendasari pengamatan terkenal bahwa dalam sistem mirip Unix "semuanya adalah file." Pertimbangkan betapa anehnya demo kecil di atas yang menampilkan perangkat karakter /dev/console benar-benar bekerja. Gambar menunjukkan sesi Bash interaktif pada teletype virtual (tty). Mengirim string ke perangkat konsol virtual membuatnya muncul di layar virtual. VFS memiliki properti lain yang lebih aneh. Misalnya, mungkin untuk mencari di dalamnya.

Lebih banyak sumber daya Linux

  • Lembar contekan perintah Linux
  • Lembar contekan perintah Linux tingkat lanjut
  • Kursus online gratis:Ikhtisar Teknis RHEL
  • Lembar contekan jaringan Linux
  • Lembar contekan SELinux
  • Lembar contekan perintah umum Linux
  • Apa itu container Linux?
  • Artikel Linux terbaru kami

Sistem file yang sudah dikenal seperti ext4, NFS, dan /proc semuanya memberikan definisi dari tiga besar fungsi dalam struktur data bahasa C yang disebut file_operations. Selain itu, sistem file tertentu memperluas dan mengesampingkan fungsi VFS dengan cara berorientasi objek yang sudah dikenal. Seperti yang ditunjukkan oleh Robert Love, abstraksi VFS memungkinkan pengguna Linux dengan mudah menyalin file ke dan dari sistem operasi asing atau entitas abstrak seperti pipa tanpa mengkhawatirkan format data internal mereka. Atas nama ruang pengguna, melalui panggilan sistem, suatu proses dapat menyalin dari file ke dalam struktur data kernel dengan metode read() dari satu sistem file, kemudian menggunakan metode write() dari sistem file jenis lain untuk mengeluarkan data.

Definisi fungsi yang termasuk dalam tipe dasar VFS itu sendiri ditemukan di file fs/*.c di sumber kernel, sedangkan subdirektori fs/ berisi sistem file tertentu. Kernel juga berisi entitas mirip sistem file seperti cgroups, /dev, dan tmpfs, yang diperlukan di awal proses boot dan oleh karena itu didefinisikan dalam subdirektori init/ kernel. Perhatikan bahwa cgroups, /dev, dan tmpfs tidak memanggil fungsi tiga besar file_operations, tetapi langsung membaca dari dan menulis ke memori.

Diagram di bawah ini secara kasar menggambarkan bagaimana ruang pengguna mengakses berbagai jenis sistem file yang biasa dipasang pada sistem Linux. Tidak ditampilkan konstruksi seperti pipa, dmesg, dan jam POSIX yang juga mengimplementasikan struct file_operations dan yang aksesnya melewati lapisan VFS.

Keberadaan VFS mendorong penggunaan kembali kode, karena metode dasar yang terkait dengan sistem file tidak perlu diimplementasikan kembali oleh setiap jenis sistem file. Penggunaan kembali kode adalah praktik terbaik rekayasa perangkat lunak yang diterima secara luas! Sayangnya, jika kode yang digunakan kembali menimbulkan bug serius, maka semua implementasi yang mewarisi metode umum akan mengalaminya.

/tmp:Tip sederhana

Cara mudah untuk mengetahui VFS apa yang ada pada sistem adalah dengan mengetikkan mount | grep -v sd | grep -v :/ , yang akan mencantumkan semua sistem file terpasang yang tidak ada di disk dan bukan NFS di sebagian besar komputer. Salah satu mount VFS yang terdaftar pasti akan menjadi /tmp, kan?

Mengapa menyimpan /tmp di penyimpanan tidak disarankan? Karena file di /tmp bersifat sementara(!), dan perangkat penyimpanan lebih lambat dari memori, tempat tmpfs dibuat. Lebih lanjut, perangkat fisik lebih mudah aus karena sering menulis daripada memori. Terakhir, file di /tmp mungkin berisi informasi sensitif, jadi menghilangkannya setiap kali reboot adalah sebuah fitur.

Sayangnya, skrip instalasi untuk beberapa distro Linux masih membuat /tmp pada perangkat penyimpanan secara default. Jangan putus asa jika hal ini terjadi pada sistem Anda. Ikuti instruksi sederhana di Arch Wiki yang selalu bagus untuk memperbaiki masalah, ingatlah bahwa memori yang dialokasikan untuk tmpfs tidak tersedia untuk tujuan lain. Dengan kata lain, sistem dengan tmpfs raksasa dengan file besar di dalamnya dapat kehabisan memori dan crash. Tip lain:saat mengedit file /etc/fstab, pastikan untuk mengakhirinya dengan baris baru, karena sistem Anda tidak akan bisa boot jika tidak. (Tebak bagaimana saya tahu.)

/proc dan /sys

Selain /tmp, VFS yang paling dikenal oleh sebagian besar pengguna Linux adalah /proc dan /sys. (/ dev bergantung pada memori bersama dan tidak memiliki file_operations). Mengapa dua rasa? Mari kita lihat lebih detail.

Procfs menawarkan snapshot ke keadaan instan kernel dan proses yang dikontrolnya untuk ruang pengguna. Di /proc, kernel menerbitkan informasi tentang fasilitas yang disediakannya, seperti interupsi, memori virtual, dan penjadwal. Selain itu, /proc/sys adalah tempat pengaturan yang dapat dikonfigurasi melalui perintah sysctl dapat diakses oleh ruang pengguna. Status dan statistik pada masing-masing proses dilaporkan dalam direktori /proc/.

Perilaku file /proc menggambarkan betapa berbedanya VFS pada sistem file pada disk. Di satu sisi, /proc/meminfo berisi informasi yang disajikan oleh perintah gratis . Di sisi lain, itu juga kosong! Bagaimana ini bisa terjadi? Situasi ini mengingatkan kita pada artikel terkenal yang ditulis oleh fisikawan Cornell University N. David Mermin pada tahun 1985 berjudul "Apakah bulan ada ketika tidak ada yang melihat? Realitas dan teori kuantum." Yang benar adalah bahwa kernel mengumpulkan statistik tentang memori ketika sebuah proses meminta mereka dari /proc, dan sebenarnya ada adalah tidak ada dalam file di /proc ketika tidak ada yang melihat. Seperti yang dikatakan Mermin, "Adalah doktrin kuantum mendasar bahwa pengukuran tidak, secara umum, mengungkapkan nilai yang sudah ada sebelumnya dari properti yang diukur." (Jawaban atas pertanyaan tentang bulan dibiarkan sebagai latihan.)

Kekosongan procfs yang tampak masuk akal, karena informasi yang tersedia di sana bersifat dinamis. Situasi dengan sysfs berbeda. Mari kita bandingkan berapa banyak file dengan ukuran setidaknya satu byte yang ada di /proc versus /sys.

Procfs memiliki satu, yaitu konfigurasi kernel yang diekspor, yang merupakan pengecualian karena hanya perlu dibuat sekali per boot. Di sisi lain, /sys memiliki banyak file yang lebih besar, yang sebagian besar terdiri dari satu halaman memori. Biasanya, file sysfs berisi tepat satu angka atau string, berbeda dengan tabel informasi yang dihasilkan dengan membaca file seperti /proc/meminfo.

Tujuan dari sysfs adalah untuk mengekspos properti yang dapat dibaca dan ditulis dari apa yang disebut kernel "kobjects" ke ruang pengguna. Satu-satunya tujuan kobject adalah penghitungan referensi:ketika referensi terakhir ke kobject dihapus, sistem akan mengklaim kembali sumber daya yang terkait dengannya. Namun, /sys merupakan sebagian besar dari "ABI stabil untuk userspace" kernel yang terkenal yang tidak seorang pun, dalam keadaan apa pun, dapat "dihancurkan". Itu tidak berarti file dalam sysfs statis, yang akan bertentangan dengan penghitungan referensi objek volatil.

ABI kernel yang stabil malah membatasi apa yang bisa muncul di /sys, bukan apa yang sebenarnya ada pada saat tertentu. Mencantumkan izin pada file di sysfs memberikan gambaran tentang bagaimana parameter perangkat, modul, sistem file, dll. yang dapat dikonfigurasi dan dapat disetel dapat diatur atau dibaca. Logika memaksa kesimpulan bahwa procfs juga merupakan bagian dari ABI kernel yang stabil, meskipun dokumentasi kernel tidak menyatakan secara eksplisit.

Mengintip VFS dengan alat eBPF dan bcc

Cara termudah untuk mempelajari bagaimana kernel mengelola file sysfs adalah dengan melihatnya beraksi, dan cara termudah untuk menonton di ARM64 atau x86_64 adalah dengan menggunakan eBPF. eBPF (Extended Berkeley Packet Filter) terdiri dari mesin virtual yang berjalan di dalam kernel yang dapat diminta oleh pengguna istimewa dari baris perintah. Sumber kernel memberi tahu pembaca apa yang dapat kernel> melakukan; menjalankan alat eBPF pada sistem yang di-boot menunjukkan apa yang sebenarnya lakukan .

Untungnya, memulai dengan eBPF cukup mudah melalui alat bcc, yang tersedia sebagai paket dari distro Linux utama dan telah banyak didokumentasikan oleh Brendan Gregg. Alat bcc adalah skrip Python dengan potongan kecil C yang disematkan, yang berarti siapa pun yang merasa nyaman dengan salah satu bahasa dapat dengan mudah memodifikasinya. Pada hitungan ini, ada 80 skrip Python di bcc/tools, sehingga sangat mungkin bahwa administrator sistem atau pengembang akan menemukan yang sudah ada yang relevan dengan kebutuhannya.

Untuk mendapatkan gambaran yang sangat kasar tentang pekerjaan apa yang dilakukan VFS pada sistem yang sedang berjalan, coba vfscount atau vfsstat sederhana, yang menunjukkan bahwa lusinan panggilan ke vfs_open() dan teman-temannya terjadi setiap detik.

Untuk contoh yang tidak terlalu sepele, mari kita lihat apa yang terjadi di sysfs ketika stik USB dimasukkan ke sistem yang sedang berjalan.

Dalam contoh sederhana pertama di atas, skrip alat bcc trace.py mencetak pesan setiap kali perintah sysfs_create_files() dijalankan. Kami melihat bahwa sysfs_create_files() dimulai oleh utas kworker sebagai respons terhadap penyisipan stik USB, tetapi file apa yang dibuat? Contoh kedua menggambarkan kekuatan penuh eBPF. Di sini, trace.py sedang mencetak kernel backtrace (opsi -K) ditambah nama file yang dibuat oleh sysfs_create_files(). Cuplikan di dalam tanda kutip tunggal adalah beberapa kode sumber C, termasuk format string yang mudah dikenali, bahwa skrip Python yang disediakan menginduksi compiler just-in-time LLVM untuk dikompilasi dan dijalankan di dalam mesin virtual dalam kernel. Tanda tangan fungsi sysfs_create_files() lengkap harus direproduksi dalam perintah kedua sehingga string format dapat merujuk ke salah satu parameter. Membuat kesalahan dalam cuplikan C ini menghasilkan kesalahan C-compiler yang dapat dikenali. Misalnya, jika -saya parameter dihilangkan, hasilnya adalah "Gagal mengkompilasi teks BPF." Pengembang yang fasih dengan C atau Python akan menemukan alat bcc mudah untuk diperluas dan dimodifikasi.

Ketika USB stick dimasukkan, kernel backtrace muncul yang menunjukkan bahwa PID 7711 adalah thread kworker yang membuat file bernama "events" di sysfs. Permintaan yang sesuai dengan sysfs_remove_files() menunjukkan bahwa penghapusan stik USB menghasilkan penghapusan file peristiwa, sesuai dengan gagasan penghitungan referensi. Menonton sysfs_create_link() dengan eBPF selama penyisipan stik USB (tidak ditampilkan) mengungkapkan bahwa tidak kurang dari 48 tautan simbolik dibuat.

Apa tujuan dari file acara? Menggunakan cscope untuk menemukan fungsi __device_add_disk() mengungkapkan bahwa ia memanggil disk_add_events(), dan "media_change" atau "eject_request" dapat ditulis ke file peristiwa. Di sini, lapisan blok kernel menginformasikan ruang pengguna tentang kemunculan dan hilangnya "disk". Pertimbangkan seberapa cepat informatif metode penyelidikan cara kerja penyisipan stik USB ini dibandingkan dengan mencoba mencari tahu prosesnya hanya dari sumbernya.

Sistem file root read-only memungkinkan perangkat yang disematkan

Pastinya, tidak ada yang mematikan server atau sistem desktop dengan mencabut steker listrik. Mengapa? Karena sistem file yang dipasang pada perangkat penyimpanan fisik mungkin memiliki penulisan yang tertunda, dan struktur data yang merekam statusnya mungkin tidak sinkron dengan apa yang tertulis di penyimpanan. Ketika itu terjadi, pemilik sistem harus menunggu pada boot berikutnya untuk menjalankan alat pemulihan sistem file fsck dan, dalam kasus terburuk, akan benar-benar kehilangan data.

Namun, penggemar akan mendengar bahwa banyak IoT dan perangkat yang disematkan seperti router, termostat, dan mobil sekarang menjalankan Linux. Banyak dari perangkat ini hampir seluruhnya tidak memiliki antarmuka pengguna, dan tidak ada cara untuk "membatalkan boot" mereka dengan bersih. Pertimbangkan untuk menyalakan mobil dengan baterai mati di mana daya ke unit kepala yang menjalankan Linux naik dan turun berulang kali. Bagaimana bisa sistem melakukan booting tanpa fsck yang lama ketika mesin akhirnya mulai bekerja? Jawabannya adalah bahwa perangkat yang disematkan mengandalkan sistem file root read-only (singkatnya ro-rootfs).

Sebuah ro-rootfs menawarkan banyak keuntungan yang kurang jelas dari incorruptibility. Salah satunya adalah bahwa malware tidak dapat menulis ke /usr atau /lib jika tidak ada proses Linux yang dapat menulis di sana. Yang lainnya adalah bahwa sistem file yang sebagian besar tidak dapat diubah sangat penting untuk dukungan lapangan dari perangkat jarak jauh, karena personel pendukung memiliki sistem lokal yang secara nominal identik dengan yang ada di lapangan. Mungkin keuntungan yang paling penting (tetapi juga paling halus) adalah bahwa ro-rootfs memaksa pengembang untuk memutuskan selama fase desain proyek objek sistem mana yang tidak dapat diubah. Berurusan dengan ro-rootfs mungkin sering tidak nyaman atau bahkan menyakitkan, seperti variabel const dalam bahasa pemrograman sering, tetapi manfaatnya dengan mudah membayar biaya tambahan.

Membuat rootfs hanya-baca memang memerlukan upaya tambahan untuk pengembang tertanam, dan di situlah VFS masuk. Linux membutuhkan file di /var agar dapat ditulis, dan sebagai tambahan, banyak aplikasi populer yang dijalankan sistem tertanam akan mencoba membuat konfigurasi dot-file di $HOME. Salah satu solusi untuk file konfigurasi di direktori home biasanya adalah dengan membuat dan membangunnya ke dalam rootfs. Untuk /var, satu pendekatan adalah memasangnya pada partisi terpisah yang dapat ditulisi sementara / sendiri dipasang sebagai hanya-baca. Menggunakan mount bind atau overlay adalah alternatif populer lainnya.

Mengikat dan melapisi dudukan dan penggunaannya oleh kontainer

Menjalankan man mount adalah tempat terbaik untuk belajar tentang pengikatan dan pemasangan overlay, yang memberi pengembang dan administrator sistem yang disematkan kekuatan untuk membuat sistem file di satu lokasi jalur dan kemudian menyediakannya ke aplikasi di lokasi kedua. Untuk sistem yang disematkan, implikasinya adalah mungkin untuk menyimpan file di /var pada perangkat flash yang tidak dapat ditulis tetapi overlay- atau mengikat-mount jalur di tmpfs ke jalur /var saat boot sehingga aplikasi dapat mencoret-coret di sana ke jantung mereka. sukacita. Pada penyalaan berikutnya, perubahan di /var akan hilang. Mount overlay menyediakan penyatuan antara tmpfs dan sistem file yang mendasarinya dan memungkinkan modifikasi nyata ke file yang ada di ro-rootfs, sementara bind mount dapat membuat direktori tmpfs kosong baru muncul sebagai dapat ditulis di jalur ro-rootfs. Sementara overlayf adalah tipe sistem file yang tepat, pengikatan mount diimplementasikan oleh fasilitas namespace VFS.

Berdasarkan deskripsi overlay dan bind mount, tidak ada yang akan terkejut bahwa container Linux banyak menggunakannya. Mari kita lihat apa yang terjadi saat kita menggunakan systemd-nspawn untuk memulai container dengan menjalankan alat mountsnoop bcc:

Dan mari kita lihat apa yang terjadi:

Di sini, systemd-nspawn menyediakan file yang dipilih di procfs dan sysfs host ke wadah di jalur di rootfs-nya. Selain flag MS_BIND yang menyetel pengikatan, beberapa flag lain yang dipanggil oleh panggilan sistem "mount" menentukan hubungan antara perubahan dalam namespace host dan dalam container. Misalnya, bind-mount dapat menyebarkan perubahan di /proc dan /sys ke container, atau menyembunyikannya, bergantung pada pemanggilannya.

Ringkasan

Memahami internal Linux tampaknya merupakan tugas yang mustahil, karena kernel itu sendiri berisi sejumlah besar kode, mengesampingkan aplikasi ruang pengguna Linux dan antarmuka panggilan sistem di pustaka C seperti glibc. Salah satu cara untuk membuat kemajuan adalah dengan membaca kode sumber dari satu subsistem kernel dengan penekanan pada pemahaman panggilan sistem dan header yang menghadap ruang pengguna ditambah antarmuka internal kernel utama, dicontohkan di sini oleh tabel file_operations. Operasi file adalah apa yang membuat "semuanya adalah file" benar-benar berfungsi, jadi menanganinya sangat memuaskan. File sumber kernel C di direktori fs/ tingkat atas merupakan implementasi dari sistem file virtual, yang merupakan lapisan shim yang memungkinkan interoperabilitas yang luas dan relatif mudah dari sistem file populer dan perangkat penyimpanan. Bind dan overlay mount melalui ruang nama Linux adalah keajaiban VFS yang memungkinkan container dan sistem file root read-only. Dikombinasikan dengan studi kode sumber, fasilitas kernel eBPF dan antarmuka bcc-nya membuat pemeriksaan kernel menjadi lebih sederhana daripada sebelumnya.

Terima kasih banyak kepada Akkana Peck dan Michael Eager atas komentar dan koreksinya.

Alison Chaiken akan mempresentasikan sistem file Virtual:mengapa kita membutuhkannya dan bagaimana mereka bekerja di Pameran Linux California Selatan tahunan (SCaLE 17x) ke-17 pada 7-10 Maret di Pasadena, California.


Linux
  1. Cara Bekerja Dengan Pengguna Dan Grup Di Linux

  2. Bagaimana Mengubah Ukuran Partisi Dan Sistem File Pada Mereka?

  3. Cara membuat dan memasang sistem file di Linux

  1. Bagaimana Linux menyelamatkan komputer yang lambat (dan planet ini)

  2. Cara Mengakses Sistem File Linux di Windows 10 dan WSL 2

  3. Cara menginstal TBB dari sumber di Linux dan membuatnya berfungsi

  1. Memahami jalur file dan cara menggunakannya di Linux

  2. Memahami sistem file Linux:ext4 dan seterusnya

  3. Cara Menyimpan Perintah Linux Dan Menggunakannya Sesuai Permintaan