Bagaimana program log dapat terus login ke file yang dihapus?


12

Dari Unix Power Tools, Edisi ke-3 : Alih-alih Menghapus File, kosongkan bagian ini:

Jika proses aktif membuka file (tidak jarang untuk file log), menghapus file dan membuat yang baru tidak akan memengaruhi program logging; pesan-pesan itu akan terus menuju ke file yang tidak lagi ditautkan . Mengosongkan file tidak merusak asosiasi, sehingga menghapus file tanpa mempengaruhi program logging.

( penekanan milikku )

Saya tidak mengerti mengapa suatu program akan terus login ke file yang dihapus. Apakah karena entri deskriptor file tidak dihapus dari tabel proses?

Jawaban:


11

Ketika Anda menghapus file, Anda benar-benar menghapus tautan ke file (ke inode). Jika seseorang sudah membuka file itu, mereka harus menjaga deskriptor file yang mereka miliki. File tetap di disk, mengambil ruang, dan dapat ditulis dan dibaca jika Anda memiliki akses ke sana.

The unlinkFungsi didefinisikan dengan perilaku ini dengan POSIX:

Ketika jumlah tautan file menjadi 0 dan tidak ada proses membuka file, ruang yang ditempati oleh file akan dibebaskan dan file tidak lagi dapat diakses. Jika satu atau lebih proses membuka file saat tautan terakhir dihapus, tautan tersebut akan dihapus sebelum tautan balik kembali () kembali, tetapi penghapusan konten file akan ditunda hingga semua referensi ke file ditutup .

Saran ini karena perilaku itu. Daemon akan membuka file, dan tidak akan melihat bahwa itu telah dihapus (kecuali jika dipantau secara khusus, yang tidak umum). Ini akan terus menulis dengan rapi ke deskriptor file yang ada: Anda akan tetap mengambil (lebih banyak) ruang pada disk, tetapi Anda tidak akan dapat melihat pesan apa pun yang ditulisnya, sehingga Anda benar-benar dalam keadaan terburuk. dari kedua dunia. Jika Anda memotong file ke panjang nol, maka ruang akan segera dibebaskan, dan pesan baru akan ditambahkan di ujung file yang baru di mana Anda dapat melihatnya.

Akhirnya, ketika daemon mengakhiri atau closefile , ruang akan dibebaskan. Tidak ada yang baru dapat membuka file dalam waktu yang berarti (selain melalui antarmuka reflektif spesifik sistem seperti Linux/proc/x/fd/... ). Juga dijamin bahwa:

Jika jumlah tautan file adalah 0, ketika semua deskriptor file yang terkait dengan file ditutup, ruang yang ditempati oleh file akan dibebaskan dan file tidak lagi dapat diakses.

Jadi Anda tidak kehilangan ruang disk Anda secara permanen, tetapi Anda tidak mendapatkan apa-apa dengan menghapus file dan Anda kehilangan akses ke pesan baru.


1
Apa yang akan terjadi jika pengguna (katakanlah root di sini) mencoba untuk memutuskan tautan /proc/x/fd/y? Apakah itu menyebabkan proses gagal menulis ke deskriptor file, atau apakah itu operasi ilegal?
nanofarad

@hexafraction /proc/*/fd/*adalah symlink ke file nyata, jadi menghapusnya tidak akan menghapus file. Saya sarankan Anda untuk bereksperimen :) (bukan pada sistem produksi tentu saja!)
Ruslan

1
@MichaelHomer Mungkin Anda bisa mengklarifikasi dalam jawaban Anda bahwa sekali file tidak terhubung, proses yang memiliki deskriptor file menunjuk ke sana dapat menghubungkannya lagi, di jalur yang sama atau tidak. Ini terkadang bermanfaat.
lgeorget

@hexafraction Nah, ini hanya representasi (dalam ruang sistem file) dari proses negara dan objek. Jika Anda menghapus representasi tersebut di ruang sistem file, tidak ada yang seharusnya terjadi pada proses aktual - kecuali jika itu (atau proses lain) bergantung pada representasi yang ada di sana. Tidak yakin Anda bisa menggunakannya rmdi dalam /procatau /systanpa diberitahu oleh sistem.
David Tonhofer

@ lgeorget Bagaimana itu bisa dicapai?
Michael

8

Persis.

File adalah tri-partite.

  • Konten, yaitu, array byte yang datar, ditulis di suatu tempat pada disk atau dibuat saat itu juga.
  • The Indeks simpul , atau inode untuk jangka pendek, yang merupakan struktur data dihuni dan digunakan oleh kernel. Ini berisi semua metadata (ukuran, izin, dll.) Tentang file, dan juga penunjuk ke lokasi konten file.
  • Satu atau lebih entri direktori , yang merupakan lokasi, dimanipulasi sebagai jalur seperti /home/user/personal_file, yang bertindak sebagai pegangan di mana Anda dapat menggunakan file, memodifikasi kontennya, mengubah metadata-nya, dll.

Saat Anda membuka file, Anda memberikan path ke sistem operasi dan mengembalikan Anda menangani langsung ke inode. Dengan pegangan ini, disebut deskriptor file, Anda dapat memanipulasi file seperti yang Anda inginkan (atau setidaknya, sebagaimana diizinkan oleh OS).

Anda tidak pernah dapat menghapus secara langsung sebuah inode, Anda harus memberikan jalur ke OS untuk meminta penghapusan. Jadi, ketika Anda ingin menghapus file, Anda hanya menghapus entri direktori. Jika file memiliki entri direktori lain, itu akan terus dapat diakses, dan bahkan jika tidak, inode-nya tidak akan dihapus sementara masih ada file deskriptor yang menunjuk ke sana. @ MichaelHomer menjawab lebih teknis dan lebih rinci tentang topik khusus ini.


4

2 jawaban lainnya menjelaskan masalah ini dengan baik - file tidak bisa "dihapus" sampai semua direktori terhubung dan semua deskriptor file terbuka untuknya hilang.

Untuk menghindari ini, itu kebiasaan yang baik untuk digunakan

> /var/log/bigfile

dari pada

rm -f /var/log/bigfile

karena itu hanya mengatur ulang konten ke 0 byte alih-alih menghapusnya, dan Anda masih dapat melihat apa yang ditulis untuknya.

Jika Anda menghapus file, dan berada di linux di mana Anda memiliki sistem file / proc / fd, Anda masih dapat menggunakan

> /proc/12345/fd/3

untuk nol konten file (dengan anggapan 12345 adalah id proses Anda dan 3 adalah nomor fd file besar). Ini bisa menjadi penyelamat jika disk Anda berjalan penuh dan Anda tidak dapat membunuh proses yang menulis file log Anda karena suatu alasan.


> /var/log/bigfilemenghapus data yang ada dalam file tetapi tidak menghentikan program dari menulis di sana. Ada beberapa keadaan di mana itu adalah hal yang benar. Saya akan mengatakan itu kebiasaan buruk untuk masuk. Jika Anda ingin menghapus file, gunakan rm. Jika Anda ingin menghentikan program yang sedang menulis di sana, bunuh atau matikan program itu, sebelum atau setelah dihapus.
Gilles 'SANGAT berhenti menjadi jahat'

1
@ Giles, topik ini tentang fakta bahwa menghapus tidak akan membantu jika suatu program masih membuka file. Dan jika disk Anda penuh karena beberapa program bertingkah dan syslogdmengisi /var/log/messages, > /var/log/messagesadalah pilihan yang jauh lebih baik daripada membunuh syslogd. Tentu saja, itu seharusnya tidak menghentikan Anda dari menganalisis apa masalahnya di tempat pertama.
Guntram Blohm mendukung Monica
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.