Мысль интересная. Только часто удаляются файлы, которые никем не используются.
Недавно столкнулся с обратной проблемой: удалил ненужный длиннющий файл, а за него кто-то продолжал держаться (fuser и lsof не признались, кто именно) и место не освободилось. umount срабатывал только с ключом -l, что оказалось бесполезным. Место удалось освободить только перезагрузкой.
интересный вариант, но работает в очень редких случаях.
не рекламы ради, а здоровья для... попробуйте http://anyfs-tools.sourceforge.net/. наши - рулят!
у меня возникает время от времени такая проблема с лупфайлами
то есть размонтирую исошку и удаляю - так место не освобождается,
бывает что до перезагрузки, бывает что освобождается спустя некоторое время. проблема гарантированно не воспроизводится - думаю где-то унутре ядра есть рейс кондишн
>Представьте что вы весь день играли со звуковым файлом, и добились прекрасного звучания, потом решили что надо его переместить в другую папку и случайно удалил его. Обидно?
Обидно мне, досадно мне... да ладно...
В следующий раз осторожнее будем.
Я когда Линукс первый раз ставил, 6 гигов музыки грохнул за секунду, не успел даже испугаться %-)
> От случайного удаления гарантированнно помогают дополнительные хардлинки на файл.
Кстати да. А случайно нет такого софта под линукс, который бы перехватывал удаление (не только командой rm, а и через вызовы ядра), и вместо удаления кидал хардлинк в спец.каталог, который очищается по мере необходимости? Примерно то, что в оффтопике реализовано всякими execsoft undelete.
> в статье описано как восстановить случайно удаленный файл с помощью
> команды lsof.
Только одного не понял... как сикануть (lseek) файл на начало, прежде
чем так "восстанавливать"? Или это по каким-то причинам не требуется?
> Когда открывается файл (в т.ч. с помощью cp) без флажков вроде
> O_APPEND, он всегда позиционируется на начало.
ОК, просто не знал, что в /proc/pid/fd обычные символьные ссылки
на файлы. Думал, что там можно читать из дескрипторов самой проги,
и, соответственно, с той позиции, в которой она их оставила, а
там оказались просто ссылки...
>ОК, просто не знал, что в /proc/pid/fd обычные символьные ссылки
на файлы. Думал, что там можно читать из дескрипторов самой проги,
и, соответственно, с той позиции, в которой она их оставила, а
там оказались просто ссылки...
При открытии файла из userspace процессу выдается дескриптор (число). Числу в таблице дескрипторов в ядре соответствует struct file, в котором содержится offset. Под struct file живет struct dentry, которая является представлением VFS для записи в директории. Под struct dentry живет struct inode, которая является представлением VFS для конкретного файла. Для открытых жестких ссылок будет разный file, разный dentry, но одна inode. Для одного и того же открытого файла будет разный file, но одинаковая dentry и одинаковая inode. Получить один и тот же file из разных процессов/fd можно только путем fork или передачи структуры посредством специфичного Unix механизма, о котором можно почитать в cmsg(3).
> Получить один и тот же file из разных процессов/fd можно только путем
> fork или
Много чего можно получить только через fork() или... через /proc.
Например mm-контекст процесса можно (было раньше) заmmap()ить из
/proc/pid/mem. Я думал, с дескрипторами та же история. Ошибался.
>Много чего можно получить только через fork() или... через /proc.
>Например mm-контекст процесса можно (было раньше) заmmap()ить из
>/proc/pid/mem.
В Linux такую функциональность добавить очень нетривиально (хотя, разумеется, можно), особенно для private mappings, которые нужно тем или иным образом преобразовать в shared, чтобы между mm различных процессов области виртуальной памяти были синхронизированы. Текущая реализация procfs в Linux не позволяет делать mmap на /proc/pid/mem.
В некоторых продвинутых VM (в UVM, если не ошибаюсь) возможно совместное использование несколькими процессами одинаковых каталогов страниц, но в Linux наборы pgd/pte для каждого процесса - свои, а совместное использование памяти между процессами достигается за счет кэшей высокого уровня (для разделяемых отображений файлов - page cache соответствующего file mapping, для анонимной разделяемой памяти - page cache создаваемых на tmpfs ядром файлов).
>Рулят-то они рулят, но уж очень тормоза. Я как-то 300Гиг прошерстить пытался - так и не дождался окончания.
а терабайты не пробовал? надо же хотя бы пытаться соизмерять свои желания с возможностями. данная процедура, надеюсь, нужна очень редко и, только если других вариантов нет и тогда уже "время не имеет значения" (ц) пятый элемент.
опять же, можно в два прохода сделать, если я еще в теме.
> Кстати да. А случайно нет такого софта под линукс, который бы перехватывал
> удаление (не только командой rm, а и через вызовы ядра), и вместо удаления
> кидал хардлинк в спец.каталог,
Не совсем то, но слегка похоже:
http://www.netfort.gr.jp/~dancer/software/cowdancer.html.en
Работает через LD_PRELOAD, потому системные вызовы не перехватывает, а только
функци из glibc. И очисткой "по мере необходимости" (а это как?) не занимается.
> у меня возникает время от времени такая проблема с лупфайлами
> то есть размонтирую исошку и удаляю - так место не освобождается,
losetup -d /dev/loopN
должен помочь отцу русской демократии.
> В Linux такую функциональность добавить очень нетривиально
А удалить было тривиально? Она там была до недавнего времени.
Пользы от неё, правда, было не много скорее всего... (точнее
ей пользовались многие, но наверное только из лени или из-за
проблем с posix shm в старых glibc)
> особенно для private mappings, которые нужно тем или иным образом
> преобразовать в shared
Нафига? PTE расшарить и всё. Хотя не знаю, как именно там это
было сделано. Факт в том, что работало.
> Работает через LD_PRELOAD, потому системные вызовы не перехватывает
Системные вызовы через LD_PRELOAD отлично перехватываются.
По тому, что glibc их всех врапит. Если бы ни это, то как бы
работал, к примеру, aoss?
>А удалить было тривиально? Она там была до недавнего времени.
Посмотрел код 2.4.20, 2.6.3, 2.6.8, 2.6.18. Нигде даже намека на подобное нет. Есть mem_open, который ничего не делает, есть mem_read/mem_write/mem_lseek, которые реализуют функциональность read/write/lseek.
Не могли бы вы назвать версию ядра, где вы видели подобное?
>Нафига? PTE расшарить и всё.
Я же выше написал, что в Linux в настоящее время этот подход не используется. И реализовать его, хотя и теоретически возможно, но очень непросто (в настоящее время каталоги страниц для каждого процесса свои - за исключением kernel space, разумеется).
> как это? pid всегда видно, а этому процессу всегда можно сказать kill
Не всегда. Проверил: если файл повесить на /dev/loop, то он будет занят, но это никак не обнаружить, если не догадаться посмотреть на этот самый loop. У меня как раз iso'шка была, но я её точно отмонтировал. Возможно, что-то не то сделал и она осталась на loop'е; теперь уже не выяснить...
> Я же выше написал, что в Linux в настоящее время этот подход не
> используется.
А я написал, что использовался. И следовательно, реализуется не
так уж и сложно.
> P.S. Код, конечно, не ахти, но в тестовых целях должен пойти.
А при чём тут ptrace()? Достаточно было просто на /proc/self/mem
mmap() сделать... хотя какой смысл, и так ясно, что на данный
момент это не работает. Этим много кто пользовался.
>А я написал, что использовался. И следовательно, реализуется не так уж и сложно.
Думаю, что это была неработающая misfeature (к чему бы еще было удалять?). Впрочем, я скачаю ради прикола.
Как вариант - возможно, что vm был устроен принципиально иначе, чем в 2.4 и 2.6. Когда я вам писал про сложность добавления соответствующей функциональности в существующий код, разумеется, речь шла не про доисторические ядра, которые могли работать и на других принципах, а про 2.6 или хотя бы 2.4.
>А при чём тут ptrace()? Достаточно было просто на /proc/self/mem
>mmap() сделать... хотя какой смысл, и так ясно, что на данный
>момент это не работает. Этим много кто пользовался.
ptrace - чтобы, в частности, сработал read (а это нужно для наглядности). Чтобы read/mmap прошли в одинаковых условиях.
> Системные вызовы через LD_PRELOAD отлично перехватываются.
Аж ни разу. Можно статически слинковать бинарник. Можно сделать бинарник
SGID'ным. Можно в .interp указать свой interpreter, который не обращает
внимания на LD_PRELOAD.
> По тому, что glibc их всех врапит.
На glibc свет клином не сошелся.
> Если бы ни это, то как бы работал, к примеру, aoss?
Что такое aoss? [google выдает явно не относящиеся к делу ссылки].
Блин. 8-) Глюк с выводом strerror(errno), ведь оно может считаться в обратном порядке по отношению к read. В любом случае successful/failed выведется правильно.