Apakah mungkin untuk membuat operasi seek () pada pengembalian pipa bernama berhasil?

12

Apakah ada cara untuk membuatnya sehingga ketika program mencoba untuk melakukan seek()operasi pada pipa bernama itu akan kembali berhasil (tetapi bertindak seolah-olah pipa itu adalah file kosong) alih-alih 'Pencarian ilegal'?

Saya memiliki setiap log terakhir pada sistem saya yang tersimpan dalam database SQLite, saya tidak punya file di mana pun. Namun ada beberapa program yang mengalami masalah dengan ini. Ada 2 kasus khusus;

  • Suatu program ingin menulis ke file log yang syslog-ng telah buat sebagai pipa bernama dan sedang dibaca. Program ingin melakukan seek()karena suatu alasan dan kemudian gagal.
  • Suatu program (seperti denyhosts atau fail2ban) ingin membaca dari file log yang syslog-ng telah buat sebagai pipa bernama dan sedang menulis. Program ingin melakukan seek()itu dan gagal.

Idealnya saya hanya ingin ini berperilaku seolah-olah pipa bernama hanyalah file kosong. Saya tidak dapat melihat alasan mengapa suatu program menulis log perlu melakukan pencarian, itu hanya harus membuka file untuk ditambahkan dan mulai menulis. Saya dapat melihat mengapa program membaca ingin mencari, sehingga dapat melanjutkan dari posisi terakhir, dan jadi saya ingin berperilaku seolah-olah file itu kosong (seperti telah terpotong).

Jadi, apakah ada beberapa opsi yang dapat ditetapkan pada pipa bernama untuk membuat mereka berperilaku seperti ini? Jika tidak apakah ada mode yang dapat diatur ketika syslog-ng membuka pipa agar berperilaku seperti ini (saya terbuka untuk membuat perubahan kode)? Atau aku anak sungai?

Patrick
sumber

Jawaban:

10

Pipa Seekable telah diusulkan untuk kernel Linux, tetapi saya tidak mengetahui patch yang berfungsi untuk mengimplementasikannya.

Anda bisa menggunakan LD_PRELOADperpustakaan yang mengesampingkan lseekpanggilan pada file tertentu. Saya tidak tahu ada pembungkus di luar rak untuk keperluan ini. Shadowfs dapat membantu dalam menulis satu.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Saya akan mencoba rute LD_PRELOAD. Bukan solusi terbaik, tetapi harus bisa dilakukan.
Patrick
Btw, apakah memiliki pipa yang dapat dicari diperlukan untuk lebih sedikit agar dapat mengikuti pipa dengan cara yang sama seperti mengikuti file? Saya bertanya dalam konteks Follow a pipe using less? pertanyaan (Anda mungkin lebih suka menjawab di sana).
Piotr Dobrogost
@PiotrDobrogost Dalam konteks Fperintah dalam kurang, itu akan cukup untuk kurang menyegarkan layar jika tidak mendapatkan output apa pun untuk satu atau dua detik. Membuat pipa dapat dicari tidak akan membantu: perbedaan yang relevan ada Fpada akhir file, kemudian menunggu data muncul melewati akhir - tetapi untuk pipa, ujung file hanya datang ketika penulis menutup file.
Gilles 'SO- stop being evil'
1

Jika aplikasi itu memanggil mencari, maka itu baik rusak, atau tidak dimaksudkan untuk bekerja pada pipa. Jika yang pertama, maka itu perlu diperbaiki. Jika yang terakhir, maka ia mengharapkan upaya untuk benar-benar bekerja, jadi berbohong dan mengklaim itu berhasil ketika hampir tidak akan menyebabkan operasi yang salah.

Juga jika file log diganti dengan pipa bernama, maka hanya satu proses yang bisa membacanya dari satu waktu. Seharusnya soket.

psusi
sumber
2
Tidak dimaksudkan untuk bekerja pada pipa tidak berarti tidak bisa bekerja pada pipa. Bagaimana jika aplikasi hanya melakukan SEEK_END untuk sampai ke akhir file? Atau mungkin melakukan SEEK_CUR untuk menemukan lokasi saat ini. Tak satu pun dari ini akan menyebabkan masalah jika saya berbohong ke program tentang hasil pencarian. Satu-satunya tempat yang akan rusak adalah jika aplikasi mencoba untuk kembali dan menimpa data yang sudah ditulis yang seharusnya tidak dilakukan dengan file log. Dan ya, saya mengetahui batasan satu proses per pipa. Ini tidak akan menjadi masalah.
Patrick
1
Jika yang dilakukannya hanyalah mencari sampai akhir untuk menambahkan, maka itu hanya harus membuka file dalam mode tambahkan, sehingga jatuh ke dalam kategori rusak. Aplikasi tidak mencoba menemukan lokasi saat ini kecuali mereka harus dapat mencari di tempat lain, dan kemudian kembali ke lokasi saat ini, sehingga masuk ke dalam kategori "Anda akan memecahnya dengan gagal secara diam-diam". Sangat tidak mungkin suatu panggilan program mencari tetapi tidak benar - benar membutuhkannya untuk bekerja (dan jika itu benar, itu termasuk dalam kategori rusak).
psusi
1
Tidak benar. Banyak aplikasi mencari ke akhir file seandainya beberapa program lain telah menulis ke file sejak terakhir. Kalau tidak, menulis di mana saat ini di akan mengalahkan perubahan program lain. Dan jika membaca dari file, mungkin ingin menggunakan SEEK_CUR untuk mendapatkan lokasi saat ini sehingga ketika program mulai kembali, ia dapat melanjutkan di mana ia tinggalkan.
Patrick
1
@ Patrick, untuk yang pertama, jika menambahkan itu harus membuka kembali file dalam mode tambahkan. Dalam hal ini Anda berbicara tentang membaca, dalam hal ini, tidak masuk akal untuk melewatkan data baru yang belum dibaca (dan dengan diam-diam mengabaikan pencarian akan merusaknya). Adapun yang terakhir, jika sedang mencoba menggunakan mencari untuk kembali ke posisi yang sama setelah menutup dan membuka kembali file yang akan pecah pada pipa jika Anda diam-diam mengabaikan pencarian, karena ketika menutup pipa server mendapat SIGPIPE, yang mungkin membuatnya diatur ulang sehingga klien berikutnya yang membuka pipa dimulai dari awal.
psusi