Можно ли сделать успешными операции поиска () для именованного канала?

12

Есть ли способ сделать так, чтобы когда программы пытались выполнить seek()операции с именованным каналом, он возвращался успешно (но действовал так, как если бы канал был пустым файлом) вместо «Незаконного поиска»?

У меня есть все последние записи в моей системе, хранящиеся в базе данных SQLite, у меня нигде нет файлов. Однако есть несколько программ, которые имеют проблемы с этим. Есть 2 конкретных случая;

  • Программа хочет записать в файл журнала, который syslog-ng создал как именованный канал и который читает. Программа хочет выполнить seek()по какой-то причине, а затем не удается.
  • Программа (например, denyhosts или fail2ban) хочет читать из файла журнала, который syslog-ng создал как именованный канал и в который пишет. Программа хочет выполнить seek()на нем и терпит неудачу.

В идеале мне бы хотелось, чтобы эти запросы вели себя так, как будто именованный канал был просто пустым файлом. Я не вижу никакой причины, по которой программе, пишущей журнал, в любом случае нужно будет выполнять поиск, просто нужно открыть файл для добавления и начать запись. Я могу понять, почему чтение программы хотело бы искать, чтобы оно могло возобновить свою последнюю позицию, и поэтому я бы хотел, чтобы он вел себя так, как если бы файл был пуст (как будто он был усечен).

Так есть ли какая-либо опция, которая может быть установлена ​​для именованных каналов, чтобы заставить их вести себя таким образом? Если нет, то есть ли режим, который можно установить, когда syslog-ng открывает канал, чтобы он так себя вел (я открыт для внесения изменений в код)? Или я до ручья?

Патрик
источник

Ответы:

10

Для ядра Linux были предложены доступные для поиска каналы, но я не знаю, как работает исправление для их реализации.

Вы можете использовать LD_PRELOADбиблиотеку ed, которая переопределяет lseekвызов для определенных файлов. Я не знаю ни одной готовой упаковки для этой цели. Shadowfs может помочь в написании одного.

Жиль "ТАК - перестань быть злым"
источник
1
Я попробую маршрут LD_PRELOAD. Не самое лучшее решение, но должно быть выполнимым.
Патрик
Кстати, будет ли иметь доступную трубу для того, чтобы меньше могло следовать по трубе так же, как она может следовать за файлом? Я спрашиваю в контексте Следуй трубе, используя меньше? вопрос (вы можете предпочесть ответить там).
Петр Доброгост
@PiotrDobrogost В контексте Fкоманды less было бы достаточно, чтобы меньше обновляло экран, если он не получает никакого вывода в течение секунды или около того. Создание каналов для поиска не помогло бы: существующее различие заключается в том, что он Fидет в конец файла, а затем ожидает появления данных после конца, но для канала конец файла наступает только тогда, когда записывающее устройство закрывает файл.
Жиль "ТАК - перестань быть злым"
1

Если приложение вызывает поиск, оно либо не работает, либо не предназначено для работы с каналами. Если первое, то это нужно исправить. Если последнее, то оно ожидает, что стремление действительно сработает, поэтому ложь и утверждение, что это сработало, когда это не сработало, почти наверняка приведет к некорректной работе.

Также, если файл журнала заменяется именованным каналом, тогда только один процесс может читать из него одновременно. Это должно быть гнездо вместо.

psusi
источник
2
Не предназначен для работы на трубах не означает, что не может работать на трубах. Что если приложение просто выполняет SEEK_END, чтобы добраться до конца файла? Или, может быть, он делает SEEK_CUR, чтобы найти текущее местоположение. Ни один из них не вызвал бы никаких проблем, если бы я солгал программе о результатах поиска. Единственное место, которое может сломаться, - это если приложение пытается вернуться назад и перезаписать уже записанные данные, чего не следует делать с файлами журналов. И да, я знаю об ограничении одного процесса на трубу. Это не будет проблемой.
Патрик
1
Если все, что он делает, это пытается завершить добавление до конца, тогда он должен просто открыть файл в режиме добавления, чтобы он попал в категорию неработающих. Приложения не пытаются найти текущее местоположение, если им не нужно искать в другом месте, а затем возвращаться к текущему местоположению, поэтому оно попадает в категорию «вы сломаете его, молча провалившись». Маловероятно, что программа вызывает поиск, но на самом деле она не нужна для работы (и если она это делает, она попадает в категорию неисправностей).
psusi
1
Не правда. Многие приложения ищут конец файла в случае, если какая-либо другая программа записала в файл с момента его последнего выполнения. В противном случае запись в том месте, где он находится в данный момент, приведет к срыву изменений другой программы. И если он читает из файла, он может захотеть использовать SEEK_CUR, чтобы получить его текущее местоположение, чтобы при запуске программы он мог возобновить работу с того места, где остановился.
Патрик
1
@ Патрик, для первого, если он добавляется, он должен открыть файл в режиме добавления. В этом случае вы говорите о чтении, и в этом случае не имеет смысла пропускать новые данные, которые они еще не прочитали (и молчаливое игнорирование поиска может нарушить это). Что касается последнего, если он пытается использовать поиск, чтобы вернуться в ту же позицию после закрытия и повторного открытия файла, который будет разорван на канале, если вы молча проигнорируете запрос, так как, когда он закрывает канал, сервер получает SIGPIPE, который по-видимому, он сбрасывается, поэтому следующий клиент, открывающий канал, запускается в начале.
psusi