Linux - Как mkstemp64 создает скрытый файл и как его увидеть в файловой системе

Предыстория:

В CentOS 7 x86_64. Я использую applydeltarpm, и мне не хватило места на диске при создании нового RPM из дельты. Я наблюдал, как использование дискового пространства / увеличилось во время процесса применения до 100%, но не смог найти рабочий/временный файл на томе с помощью ls -l /tmp или find /tmp -mmin -1 -type f.

Я изменил исходный код applydeltarpm, чтобы использовать /var/tmp вместо /tmp, и пересобрал RPM. Теперь apply работает с модифицированным applydeltarpm, потому что /var/tmp занимает намного больше места на диске. Но я все еще не могу найти временный файл, созданный с помощью mkstemp64.

Вопрос:

Временный файл, созданный mkstemp64, кажется «несуществующим», но все еще существует как файловый дескриптор для создателя и занимает значительное место на диске, когда applydeltarpm создает большой RPM (1 час для применения на медленном диске). В документации mkstemp64 говорится, что создается фактический файл. И исходный код показывает, что имя файла шаблона — /tmp/deltarpmpageXXXXXX. Но файла с таким именем шаблона не существует.

Как можно создать этот временный файл в системе, чтобы его нельзя было найти в обычном списке каталогов ls или find. И как мне найти такие "несуществующие" файлы в системе?

(Мне любопытно, потому что я также слежу за безопасностью системы)

Ссылки:

https://github.com/rpm-software-management/deltarpm/blob/master/applydeltarpm.c

  # line 198

  if (pagefd < 0)
    {
      char tmpname[80];
      sprintf(tmpname, "/tmp/deltarpmpageXXXXXX");
#ifdef DELTARPM_64BIT
      pagefd = mkstemp64(tmpname);
#else
      pagefd = mkstemp(tmpname);
#endif
      if (pagefd < 0)
        {
          fprintf(stderr, "could not create page area\n");
          exit(1);
        }
      unlink(tmpname);
    }

https://www.mkssoftware.com/docs/man3/mkstemp.3.asp

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

Функция mkstemp() похожа на mktemp() тем, что создает уникальное имя файла на основе шаблона; однако mkstemp() фактически создает файл и возвращает его файловый дескриптор. Имя созданного файла хранится в шаблоне.

Функция mkstemp64() идентична функции mkstemp(), за исключением того, что файл открывается с установленным флагом O_LARGEFILE.


person Russell E Glaue    schedule 18.08.2017    source источник
comment
Он unlinks файл сразу после создания.   -  person melpomene    schedule 18.08.2017


Ответы (1)


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

unlink() не удаляет файл, а только удаляет ссылку на файл из файловой системы. Каждая ссылка на файл в файловой системе увеличивает количество ссылок на файл на единицу (может быть несколько ссылок на один и тот же файл). Также каждый процесс, который вызывает open() или mmap() для открытия файла, увеличивает количество файлов, пока не закроет дескриптор - тогда количество ссылок уменьшается. Файл существует до тех пор, пока на него есть хотя бы одна ссылка. Когда количество ссылок достигает нуля, файл фактически удаляется.

mkstemp() также вызывает open() за кулисами, чтобы открыть временный файл и вернуть его дескриптор.

Чтобы увидеть файлы, которые открыты, но больше не существуют в файловой системе, вы можете использовать lsof и найдите строки, где после имени файла стоит "(удалено)".

lsof | grep '(deleted)'

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

person Erki Aring    schedule 18.08.2017
comment
Спасибо. Я нашел этот вопрос о стеке, который помогает мне находить и отслеживать несвязанные файлы в /proc, что больше похоже на то, что я искал: unix.stackexchange.com/questions/68523/ - person Russell E Glaue; 19.08.2017