LINUX.ORG.RU

Блокировка удаления открытого файла


0

0

Столкнулся с одной такой вот проблемой: когда я открываю /создаю файл через open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); То почему-то я могу его удалять через консольные команды типа rm А вот как сделать так, чтобы файл нельзя было удалить до тех пор пока я его не закрою? Вообще файл используется для последующего отображения в память через mmap и постепенного изменения некоторых данных в нем. При этом если файл удалить, то маппинг нормально работает и не выдает ошибок. В конце работы даже munmap и close без ошибок выполняются и при этом данные которые изменялись уже никуда не записываются



Последнее исправление: slesh (всего исправлений: 2)

Имхо без хаков так не сделать. По rm удаляется только ссылка на файл, а сам файл существует, пока открыт хотя бы один дескриптор или существует хотя бы одна ссылка. Хотя может и есть какой-нибудь ядрёный модуль или патч (или можно самому написать), который не даёт удалять ссылки, пока есть открытые дескрипторы.

kranky ★★★★★
()

Насколько мне помнится, файл на самом деле не удаляется, пока открывшая его программа этот файл не закроет.

DJAnto
()
Ответ на: комментарий от DJAnto

В том-то, и дело что файл удаляется. т.е.
rm /tmp/test.txt
echo test>/tmp/test.txt
файл удаляется, затем создается с уже новыми данными. А надо чтобы вообще ничего нельзя было сделать с файлами.
P.S. файловая система Ext4

slesh
() автор топика
Ответ на: комментарий от kss

Ну а смысл что он не удаляется? Если на деле его уже не как нельзя использовать. т.е. после закрытия программы, попытка повторного открытия проваливается. А необходимо чтобы данные были сохранены, и при дальнейшем запуске программы она их могла использовать. т.е. надо чтобы файл мог быть удален только в том, случае если программа которая с ним работает была бы не запущена

slesh
() автор топика

Зачем это нужно? Если пользователь хочет сделать rm, то ему виднее.

anonymous
()
Ответ на: комментарий от slesh

>А необходимо чтобы данные были сохранены, и при дальнейшем запуске программы она их могла использовать.

Ну можно перед закрытием программы проверять, существует ли ещё этот файл. Если нет, то просто пересоздать его и сохранить данные в него.

kss ★★★★★
()
Ответ на: комментарий от anonymous

Пользователи всегда чего то хотят и постоянно вводят то, что не надо и то о чем их не просили.
Ну если по обычному никак нельзя заблокировать файл, то придется по старинке: пригрозить пользователю сломать пальцы или удалит файл во время работы программы.

slesh
() автор топика

unlink удаляет ссылку, а сам индесный дексриптор удаляеться. Когда вы делаете unmap & close, вот тогда драйвер и дескриптор удаляет из файловой системы.

Как вариант, можно после open попробовать поменять права доступа к файлу. Но во-первых, это не атомарно, т.е. существует вероятность, что кто-то удалит файл после open(2) и до fchmod(2), и во-вторых, в домашней папке пользователя удалить файл можно даже если chmod a-rwx filename.

nanoo_linux
()
Ответ на: комментарий от kss

В том-то и дело, что за счет того, что юзается маппинг, то данные периодически автоматически сохраняются в файл. т.е. выходит такая хитрая защита от сбоя. Важные рабочие переменные таким образом сохраняются в файле. И если вдруг по различным причинам программа вырубиться, комп повиснет, свет вырубится, etc. То при следующем старте программы выполнение действий продолжится с последней позиции, если конечно юзверь не удалит файл во время работы.

slesh
() автор топика
Ответ на: комментарий от slesh

>Ну а смысл что он не удаляется? т.е. надо чтобы файл мог быть удален только в том, случае если программа которая с ним работает была бы не запущена

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

Я, признаться, впервые вижу человека, который считает такое поведение неправильным. Зачем тебе держать файл всё время открытым? При запуске открыл - прочитал, перед завершением программы открыл/создал - сохранил, и никаких проблем.

kranky ★★★★★
()
Ответ на: комментарий от kranky

7 лет программирования под Win дают о себе знать, по этому как-то не привычно такое видеть. Тут главное дело - не потерять все данные при сбое. По этому такой метод не подходит.

slesh
() автор топика
Ответ на: комментарий от slesh

>Тут главное дело - не потерять все данные при сбое

Ну тут не Win, так что количество сбоев несравнимо меньше. Но если уж очень надо, то можно как во всяких текстовых редакторах: сохранять резервную копию например каждую минуту. И в скрытый файл, чтобы никто случайно не удалил.

kranky ★★★★★
()

man файдовые блокировки (mandatory lock)

По-умолчанию, все файловые операции в unix — неблокирующие, поэтому можно читать и удалять файл, открытый на запись. Делается это для того, чтобы былиотеки и исполняемые файлы можно было обновлять без остановки системы. Если Вам нужно другое поведение — ставьте блокировку.

annoynimous ★★★★★
()
Ответ на: комментарий от kranky

Я уже понял что тут не Win. Да и в винде сбоев не так много, больше сбоев когда кое-кто ногами/швабрами провода выдергивает)). Так что лучше всего смериться с тем что файл могут удалить во время работы. Linux вроде такая гибкая система, а простейших вещей нет.

slesh
() автор топика
Ответ на: комментарий от slesh

> Так что лучше всего смериться с тем что файл могут удалить во время работы. Linux вроде такая гибкая система, а простейших вещей нет.

Еще раз, Вам сказали, что такие средства есть. Осильте их, пожалуйста и не распространяйте заведомо ложную информацию

annoynimous ★★★★★
()
Ответ на: комментарий от slesh

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

А если удалит – то он ССЗБ, в чем проблема-то?

anonymous
()

Прекратите лезть со своей BDSMной идеологией в мой уютненький линукс. Если пользователь решил сделать rm, ему действительно виднее и не надо городить дурацкие грабли, которые знающий человек при желании всё равно обойдёт за несколько минут, а заодно знатно обматерит того, кто их придумал. Если не хочешь чтобы файл мозолил пользователю, сделай его скрытым или положи его в /var/tmp/program_name или в ~/.config/program_name/ или в какую-нибудь другую подходящую по стандарту FHS директорию. И в мане не забудь описать, что это за файл и зачем он нужен, чтобы потом у пользователя глаза на лоб не лезли от размера ~/.config.

anonymous
()
Ответ на: комментарий от annoynimous

Ставить блокировку? Ну тогда она будет распространяться на все файлы данной ФС, а как то не охото для каждого компа это изменять. От fchmod толку мало. Потому что файл всё равно можно удалить, потому как владелец один и тот же.

slesh
() автор топика
Ответ на: комментарий от annoynimous

> от него спасает chattr +i

Который можно только от рута сделать. И от sudo chattr -i && sudo rm -f он таки не спасет :-)

anonymous
()

Вообще изначально задумка не очень красивая, ибо AFAIK есть ФС, которые 'теряют' все открытые файлы в случае неожиданного отключения питания. Ты ведь не станешь говорить пользователям, какую ФС им использовать?

kranky ★★★★★
()
Ответ на: комментарий от anonymous

Ладно, тему можно закрыть. Всё равно ни до чего путного не дойдем, как написал anonymous - пользователь у нас всегда прав и всегда знает что делает. Так что все косяки будут с его стороны)

slesh
() автор топика
Ответ на: комментарий от kranky

Ладно, подходим тогда с другой стороны: Данных порядка 16 метров. И ты предлагаешь через определенный интервал записывать их на винт? Так система сама бы решала какие участки и когда надо было бы скидывать на винт, а тут придется полностью всё данные записывать. Вообще прога собирается использоваться только для ФС ext3/4

slesh
() автор топика
Ответ на: комментарий от slesh

>Данных порядка 16 метров. И ты предлагаешь через определенный интервал записывать их на винт?

Именно.

Так система сама бы решала какие участки и когда надо было бы скидывать на винт, а тут придется полностью всё данные записывать


Сохраняй diff'ы =)

kranky ★★★★★
()
Ответ на: комментарий от anonymous

> Который можно только от рута сделать. И от sudo chattr -i && sudo rm -f он таки не спасет :-)

Если прога — демон, она может себе и такое позволить. А если не демон, то постановка задачи с затыканием дырки соской в корне неверна. Не могу найти ни одного use case (кроме вирусни), когда пользователь не мог бы удалять файл без ведома проги.

annoynimous ★★★★★
()
Ответ на: комментарий от annoynimous

> А если не демон, то постановка задачи с затыканием дырки соской в корне неверна.

Да и если демон, то тоже, вобщем-то.

anonymous
()
Ответ на: комментарий от slesh

> лучше всего смериться с тем что файл могут удалить во время работы

Если я решил удалить файл - это мое право, кто ты такой, дабы запрещать мне?

simple_best_world_web_master
()

Допустим, ты таки как-то решишь проблему с удалением файла во время работы программы. Но если пользователь захочет удалить файл, то что ему помешает завершить программу и таки удалить его?

ИМХО, проблему защиты данных от пользователя можно решить лишеним пользователя прав на удаление/редактирование файла с данными. Можно сделать демона, который будет выполняться под другим пользователем. Этот демон будет писать в файл, прав на изменение этого файла пользователю-удаляльщику не давать. Пользователю-удаляльщику написать клиент, который будет работать с демоном.

anonymous
()

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

true_admin ★★★★★
()
Ответ на: комментарий от Nastishka

Очевидно никакую нельзя. Но можно подойти творчески, и сделать проверку: если удаляемая ссылка не является последней, то удалять можно, а если последняя - то нельзя.

kranky ★★★★★
()
Ответ на: комментарий от kranky

А если удаляемый файл является символьной ссылкой? :-)

Nastishka ★★★★★
()

в общем небольшой ликбез.

В линукс файл - это грубо говоря индексный дескриптор на разделе с файловой системой (грубо говоря inode с которого начитается файл). А в директории прописаны связки между именами и этими дескрипторами (т.е. файлами). После того, как ты открыл файл по имени, ты уже работаешь с индексным дескриптором, т.е. с файлом и тебе не важно, существует ли в директории связка между именем и этим фалом. Далее, если ты стираешь эту связку, то удаляется имя из директории и уменьшается количество ссылок на файл. Если при закрытии файла количество ссылок 0, то файл удаляется физически драйвером файловой системы с диска.

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

Короче, ты можешь создать ссылку (hardlink) на файл, с которым работаешь на той-же файловой (и при этом позаботиться, чтобы ее не так просто было удалить) и перед закрытием проверять, что нужное тебе имя файла еще существует. Если нет, копировать созданный хардлинк в нужное имя.

Решение это кривое, в нем есть куча race conditions, и скорее всего твою задачу можно решить как-то по другому, без защит файла от удаления.

Liosha_Syrnikov
()

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

legolegs ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.