Gesaan dan Konteks Berkenaan
Satu perkhidmatan menggunakan /srv/releases/v1/app.conf. Ia mencipta /srv/live/pinned.conf sebagai pautan keras dan /srv/live/current.conf sebagai pautan simbolik relatif. Seorang pekerja (worker) membuka fail keluaran tersebut sebelum seorang pengendali menamakan semula dan kemudiannya membuang entri direktori.
Terangkan apa yang dirujuk oleh nama fail, pautan keras, pautan simbolik, nod-i (inode), dan deskriptor fail terbuka. Ramalkan hasil selepas setiap operasi. Kemudian pilih mekanisme yang betul untuk snapshot tidak boleh ubah (immutable), penuding keluaran boleh alih, dan rujukan merentas sistem fail. Jawapan ini menyasarkan sistem Linux dan fail biasa; snapshot khusus sistem fail dan pintasan Windows adalah di luar skop.
Perkara yang Dinilai oleh Penemu Duga
Isyarat pertama ialah model objek. Satu entri direktori mengikat satu nama kepada nod-i. Pautan keras ialah satu lagi entri direktori untuk nod-i yang sama; tiada satu pun nama merupakan "nama asal". Pautan simbolik ialah objek sistem fail berbeza yang muatan (payload) kandungannya merupakan laluan nama (pathname) yang dihuraikan apabila ia digunakan.
Isyarat kedua ialah penaakulan kitaran hayat. unlink membuang satu entri direktori, bukan semestinya objek fail tersebut. Nod-i dan data kekal wujud selagi pautan keras lain atau perihalan fail terbuka masih merujuknya. Pautan simbolik boleh terus wujud walaupun laluan yang disimpannya tidak lagi dapat dihuraikan.
Isyarat ketiga ialah meramalkan operasi dan bukannya menghafal jadual perbandingan. Menamakan semula satu pautan keras tidak mengubah rakan setaranya (peers). Menamakan semula symlink beroperasi pada symlink itu sendiri. Mengalihkan symlink atau sasarannya boleh mengubah maksud laluan relatif. Pautan keras merentas sistem fail gagal kerana identiti nod-i adalah setempat kepada satu sistem fail sahaja.
Isyarat terakhir ialah pertimbangan operasi: periksa identiti dan bilangan pautan, bezakan stat daripada lstat, lakukan penggantian atomik dalam sistem fail yang sama apabila diperlukan, dan elakkan perlumbaan semak-kemudian-buka (check-then-open races) pada laluan yang dikawal penyerang.
Soalan untuk Dijelaskan Sebelum Menjawab
- Adakah sumber dan nama pautan keras baharu berada pada sistem fail dilekapkan yang sama? Jika tidak,
linkgagal denganEXDEV; menyalin data atau menggunakan symlink menyelesaikan masalah yang berbeza. - Adakah pemanggil memerlukan objek yang stabil atau nama yang boleh dialihkan? Pautan keras menetapkan satu nod-i. Alias keluaran biasanya patut berupa symlink yang entri direktorinya boleh diganti.
- Adakah sasaran merupakan fail biasa atau direktori? Linux biasanya melarang pautan keras ke direktori, manakala symlink boleh menamakan kedua-duanya.
- Adakah symlink itu mutlak atau relatif? Sasaran relatif dihuraikan bermula dari direktori yang mengandungi symlink tersebut, bukan dari direktori kerja semasa proses.
- Adakah mana-mana proses sudah membuka fail tersebut? Menamakan semula atau menyahpaut laluan nama tidak mengalihkan deskriptor sedia ada; proses tersebut terus menggunakan objek yang telah dibuka.
- Adakah pertukaran tersebut mesti atomik untuk pembaca? Penggantian dengan
renameadalah atomik hanya dalam sistem fail dilekapkan yang sama. Pemindahan merentas sistem fail memerlukan protokol penerbitan yang berbeza. - Adakah komponen laluan dikawal oleh pengguna yang tidak dipercayai? Jika ya, operasi
lstatsebelumnya yang diikuti olehopenterdedah kepada perlumbaan. Operasi buka itu sendiri mesti menguatkuasakan dasar perayauan (traversal policy).
Rangka Kerja Jawapan 30 Saat
“Pautan keras ialah entri direktori kedua kepada nod-i yang sama, jadi kedua-dua nama berkongsi data dan metadata. Symlink mempunyai nod-i tersendiri dan menyimpan laluan, yang dihuraikan apabila diakses. Membuang satu nama pautan keras mengurangkan bilangan pautan; objek tersebut terus wujud melalui pautan keras lain dan deskriptor terbuka. Membuang atau menamakan semula sasaran boleh menyebabkan symlink tergantung (dangling).
Saya akan mengesahkannya dengan ls -li, stat, lstat atau readlink, dan deskriptor yang telah pun dibuka. Saya akan menggunakan pautan keras untuk menetapkan fail tepat dalam satu sistem fail, symlink untuk alias keluaran yang boleh diganti atau rujukan merentas sistem fail, dan symlink sementara berserta rename pada sistem fail yang sama untuk pertukaran alias secara atomik. Laluan tidak dipercayai memerlukan dasar buka atomik tanpa symlink atau di bawah direktori, bukan pemeriksaan berasingan.”
Panduan Terperinci Langkah demi Langkah
Langkah 1: Bina model nama-ke-objek
Bagi fail biasa, direktori menyimpan nama dan rujukan nod-i. Nod-i membawa jenis fail, pemilikan, mod, cap masa, saiz, pemetaan blok, dan bilangan pautan keras. Kandungan fail bukan milik satu “nama fail asal” yang istimewa.
Pautan keras menambah satu lagi entri direktori kepada nod-i tersebut. Mengubah bait atau mod melalui mana-mana nama boleh dilihat melalui nama yang satu lagi. Sebaliknya, symlink mempunyai nod-i tersendiri dan menyimpan rentetan seperti ../releases/v1/app.conf; carian laluan nama biasa mengikut rentetan tersebut ke nama lain.
Langkah 2: Jalankan eksperimen konkrit
Arahan berikut mewujudkan senario tersebut. Deskriptor fail shell sengaja dibiarkan terbuka:
mkdir -p /srv/releases/v1 /srv/live
printf 'version=1\n' > /srv/releases/v1/app.conf
ln /srv/releases/v1/app.conf /srv/live/pinned.conf
ln -s ../releases/v1/app.conf /srv/live/current.conf
exec 3< /srv/releases/v1/app.conf
ls -li /srv/releases/v1/app.conf /srv/live/pinned.conf
readlink /srv/live/current.conf
stat -L -c '%F %i %h' /srv/live/current.conf
stat -c '%F %i %h' /srv/live/current.conf
mv /srv/releases/v1/app.conf /srv/releases/v1/app.conf.moved
cat /srv/live/pinned.conf
cat /srv/live/current.conf
cat <&3
rm /srv/releases/v1/app.conf.moved /srv/live/pinned.conf
cat <&3
exec 3<&-Sebelum penamaan semula, laluan keluaran dan pinned.conf menunjukkan nod-i yang sama dan bilangan pautan keras sebanyak dua. readlink mencetak muatan symlink. stat biasa mengikut symlink ke sasaran, manakala pemeriksaan tanpa mengikut (non-following) dalam contoh melaporkan objek pautan simbolik itu sendiri.
Langkah 3: Ramalkan tingkah laku penamaan semula (rename)
mv dalam sistem fail ini menggunakan operasi penamaan semula untuk entri sumber. Nod-i tidak berpindah, jadi pinned.conf dan deskriptor 3 terus berfungsi. current.conf masih menyimpan ../releases/v1/app.conf; oleh sebab nama lama itu telah tiada, penyahrujukan (dereferencing) kini gagal. Menamakan semula symlink itu sendiri akan memindahkan objek pautan itu, bukan sasarannya, dan boleh mengubah maksud muatan relatif kerana penghuraian bermula dari direktori baharu yang mengandungi pautan tersebut.
Jika pelaksanaan perlu menukar current tanpa sela nama hilang (missing-name interval), cipta symlink sementara yang disediakan sepenuhnya dalam direktori yang sama dan gantikan current dengan rename. Pembaca yang membuka selepas penggantian akan menghuraikan entri direktori lama atau baharu. Proses yang telah membuka sasaran lama mengekalkan deskriptor lama mereka.
Langkah 4: Ramalkan penyahpautan (unlink) dan penebusgunaan (reclamation)
Membuang app.conf.moved menurunkan satu pautan keras. pinned.conf masih menamakan nod-i tersebut, jadi datanya kekal. Membuang pinned.conf menggugurkan entri direktori terakhir, tetapi deskriptor 3 masih memegang rujukan terbuka; cat <&3 terus membaca fail tersebut. Ruang storan hanya boleh ditebus guna selepas pautan keras terakhir dan rujukan terbuka terakhir tiada lagi.
Ini menjelaskan sebab pemadaman log aktif yang besar mungkin tidak membebaskan ruang, tetapi ia bukan sebab untuk memangkas (truncate) sebarang deskriptor secara sebarangan. Mula-mula kenal pasti proses pemilik dan kontrak putarannya, kemudian hantar isyarat atau mulakan semula proses itu dengan selamat jika perlu.
Langkah 5: Gunakan sempadan sistem fail dan direktori
Nombor nod-i adalah unik hanya dalam sistem failnya sendiri. Pautan keras tidak boleh menamakan nod-i tersebut dari sistem fail lain dan link mengembalikan EXDEV. Symlink boleh menyimpan laluan yang merentasi sempadan lekap kerana carian menghuraikan nama pada masa akses. Ia juga boleh menamakan direktori atau sasaran yang belum wujud.
Linux menghalang pautan keras biasa ke direktori bagi mengelakkan kitaran dan kekaburan perayauan. Symlink ke direktori dibenarkan, tetapi memindahkan symlink relatif boleh merosakkannya dan alat rekursif mungkin memilih dasar mengikut (follow policies) yang berbeza. Nyatakan dasar tersebut untuk alat sandaran, pemadaman, dan penggunaan.
Langkah 6: Pilih berdasarkan invarian
Gunakan pautan keras apabila invarian ialah “nama tambahan ini mesti memastikan nod-i tepat kekal boleh dicapai,” objek-objek tersebut berkongsi satu sistem fail, dan metadata yang dikongsi adalah bertujuan. Gunakan symlink apabila invarian ialah “huraikan alias ini kepada apa jua laluan yang sedang disimpannya,” terutamanya untuk direktori, penuding keluaran, atau nama merentas sistem fail. Gunakan salinan apabila bait, metadata, pengekalan, atau penempatan sistem fail yang bebas diperlukan.
Kedua-dua pautan bukanlah sandaran dengan sendirinya. Nama yang dipautkan secara keras berkongsi mutasi dan kerosakan. Symlink tidak mengandungi data sasaran. Sandaran memerlukan sempadan kegagalan dan pengekalan bebas serta ujian pemulihan.
Langkah 7: Sahkan identiti dan perayauan yang selamat
Bandingkan peranti dan nod-i, bukan nod-i sahaja, kerana nombor nod-i boleh berulang pada sistem fail yang berbeza. Periksa bilangan pautan keras dengan stat, periksa symlink itu sendiri dengan tingkah laku gaya lstat, cetak muatannya dengan readlink, dan uji urutan penamaan semula/penyahpautan yang tepat semasa deskriptor terbuka.
Bagi laluan yang tidak dipercayai, lstat(path) yang diikuti oleh open(path) membolehkan penyerang menukar komponen antara panggilan tersebut. Pada Linux, buka secara relatif kepada deskriptor direktori yang dipercayai dan gunakan sekatan penghuraian openat2 yang diperlukan, seperti melarang symlink atau pelepasan ke atas direktori. Keselamatan mesti dikuatkuasakan oleh carian yang mengembalikan deskriptor tersebut.
Contoh Jawapan Mantap
“Saya mulakan dengan entri direktori. app.conf dan pinned.conf ialah dua nama setara untuk satu nod-i, jadi ia berkongsi kandungan, kebenaran, pemilikan, dan cap masa. current.conf ialah nod-i symlink berasingan yang muatannya ialah ../releases/v1/app.conf. Laluan relatif bermula di /srv/live, tempat symlink itu berada.
Selepas menamakan semula laluan keluaran, pautan keras dan deskriptor yang telah dibuka masih merujuk kepada objek fail yang sama. Symlink menjadi tergantung kerana laluan nama yang disimpannya masih menamakan entri lama. Selepas membuang nama yang dipindahkan, pautan keras mengekalkan objek itu terus hidup. Selepas membuang pautan keras juga, deskriptor terbuka masih berfungsi; kernel hanya boleh menebus guna objek tersebut apabila deskriptor itu ditutup.
Saya akan menggunakan pautan keras untuk menetapkan artifak sistem fail sama yang tepat, symlink untuk alias current yang boleh dialihkan, dan salinan sebenar untuk pengekalan bebas. Saya akan mengemas kini current dengan mencipta symlink sementara dan menamakannya semula secara atomik dalam direktori yang sama. Saya akan membuktikan hasilnya dengan peranti/nod-i, bilangan pautan, readlink, akses pautan tergantung, dan ujian deskriptor terbuka. Jika laluan tidak dipercayai, saya akan menguatkuasakan peraturan tanpa symlink dan sempadan direktori semasa operasi buka itu sendiri.”
Kesilapan Biasa
- Memanggil pautan keras sebagai penuding kepada nama asal → semua pautan keras ialah entri direktori setara untuk satu nod-i → huraikan nama, identiti nod-i, dan bilangan pautan.
- Menyatakan pemadaman sentiasa memusnahkan fail serta-merta → nama lain atau rujukan terbuka mungkin masih kekal → jejaki kedua-dua bilangan pautan keras dan deskriptor terbuka.
- Menganggap symlink sebagai rujukan nod-i yang disimpan → ia menyimpan laluan nama yang kemudiannya boleh dihuraikan secara berbeza atau gagal → periksa muatan dan asas penghuraian.
- Membandingkan nombor nod-i tanpa identiti peranti → nombor nod-i hanya setempat pada sistem fail → bandingkan peranti bersama nod-i.
- Menggunakan pautan keras merentasi lekapan atau untuk direktori → Linux menolak kes tersebut → gunakan symlink atau salinan mengikut kebebasan yang diperlukan.
- Mengalihkan symlink relatif tanpa menilai semula → direktori yang mengandunginya mentakrifkan asas → kira semula atau jana semula sasaran selepas pemindahan.
- Memanggil mana-mana pautan sebagai sandaran → satu berkongsi objek dan satu lagi hanya menyimpan laluan → cipta salinan yang boleh dipulihkan secara bebas.
- Memeriksa laluan dan membukanya kemudian → penyerang boleh menukar symlink antara operasi → kuat kuasakan kekangan perayauan secara atomik semasa membuka.
Soalan dan Jawapan Susulan
Susulan 1: Adakah pautan keras mempunyai kebenaran atau pemilik berasingan?
Tidak. Kebenaran, pemilik, saiz, dan cap masa adalah milik nod-i yang dikongsi. Mengubahnya melalui satu pautan keras mengubah apa yang diperhatikan oleh setiap rakan setara. Nama entri direktori dan kebenaran direktori induknya adalah berasingan; menamakan semula atau menyahpaut nama ditadbir oleh direktori yang mengandunginya.
Susulan 2: Mengapa symlink relatif kadangkala rosak selepas dialihkan?
Muatannya ditafsirkan secara relatif kepada direktori yang mengandungi symlink tersebut. Mengalihkan pautan mengubah asas tersebut sambil mengekalkan rentetan yang disimpan. Symlink mutlak mengekalkan satu laluan nama tetapi mungkin salah di dalam bekas (container), chroot, lekapan alternatif, atau hos lain. Pilih selepas mentakrifkan keperluan pemindahan.
Susulan 3: Bolehkah rename menggantikan current secara atomik merentas sistem fail?
Tidak. rename Linux mengembalikan EXDEV merentas sistem fail yang dilekapkan. Terbitkan sasaran yang telah siap dalam sistem fail destinasi, cipta alias sementara di sana, kemudian namakan semula alias tersebut ke atas current dalam direktori yang sama. Tentukan pembersihan dan pemulihan untuk mana-mana fasa penyalinan terdahulu.
Susulan 4: Mengapa ruang cakera kekal digunakan selepas laluan nama terakhir dipadamkan?
Satu perihalan fail terbuka mungkin masih merujuk kepada nod-i tersebut. Cari deskriptor dan proses pemilik, kemudian gunakan prosedur putaran atau mula semula yang selamat bagi aplikasi. Ruang ditebus guna selepas nama terakhir dan rujukan terbuka terakhir hilang; membuang laluan nama sahaja hanya membuktikan nama itu telah tiada.
Susulan 5: Bagaimanakah perbezaan antara stat, lstat, dan readlink?
stat biasanya mengikut symlink terakhir dan melaporkan sasaran. lstat melaporkan objek symlink itu sendiri. readlink mengembalikan laluan nama yang disimpannya tanpa menghuraikannya. Gunakan ketiga-tiga konsep ini apabila membuktikan kedua-dua alias dan objek yang dicapainya pada masa ini.
Susulan 6: Bagaimanakah anda menghalang perlumbaan symlink dalam direktori muat naik?
Buka secara relatif kepada deskriptor direktori yang dipercayai dan pastikan carian menguatkuasakan bahawa ia kekal di bawah direktori tersebut dan tidak mengikut symlink yang dilarang. Kemudian sahkan deskriptor yang dikembalikan dengan operasi berasaskan deskriptor. Pemeriksaan laluan nama yang diikuti dengan pembukaan berasingan meninggalkan ruang untuk penggantian (replacement window).