Использование O_TMPFILE для очистки огромных страниц... или другие методы?
Моя программа использует огромные страницы. Для этого он открывает файлы следующим образом:
oflags = O_RDWR | O_CREAT | O_TRUNC;
fd = open(filename, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
куда filename
находится в файловой системе hugetlb. Это работает. Моя программа может тогда mmap()
созданные дескрипторы файлов. Но если моя программа будет убита, файлы останутся... и в огромной файловой системе страницы оставшиеся файлы будут заблокированы памятью, как показано следующей командой (876!= 1024):
cat /proc/meminfo | grep Huge
AnonHugePages: 741376 kB
HugePages_Total: 1024
HugePages_Free: 876
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Поэтому, поскольку моя программа не передает файл кому-либо еще, для меня имело смысл создавать временные файлы, используя флаг O_TMPFILE. Итак, я попробовал:
oflags = O_RDWR | O_TMPFILE;
fd = open(pathname, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
где pathname - точка пересечения hugetlbfs. Это терпит неудачу (по причине, которую я не могу объяснить) со следующей ошибкой:
open failed for /dev/hugepages: Operation not supported
Зачем? и более конкретно: как я могу гарантировать, что все огромные страницы, которые использует моя программа, будут освобождены?
Да: я мог поймать некоторые сигналы (например, SIGTERM
); но не все (SIGKILL
)
Да я мог unlink()
файл как можно скорее, используя первый подход, но что если SIGKILL
получено между open()
а также unlink()
,
Ядра вроде гарантий. Как и я. Какие надлежащие методы гарантируют 100% очистку независимо от того, когда и как завершается моя программа.
1 ответ
Похоже, O_TMPFILE еще не реализован для hugetlbfs; действительно, эта опция требует поддержки базовой файловой системы:
O_TMPFILE требует поддержки базовой файловой системой; только подмножество файловых систем Linux обеспечивают такую поддержку. В начальной реализации поддержка была предоставлена в файловых системах ex2, ext3, ext4, UDF, Minix и shmem. Поддержка XFS была добавлена в Linux 3.15.
Это подтверждается просмотром исходного кода ядра, в котором нет реализации inode_ops->tmpfile() в hugetlbfs.
Я считаю, что правильный ответ здесь - работать над этой реализацией...
Я заметил ваш комментарий по поводу опции unlink(), однако, возможно, следующий подход не такой рискованный:
- откройте файл (по имени) с помощью TRUNCATE (чтобы вы могли предположить, что его размер равен 0)
- снять связь
- mmap() это с вашим целевым размером
Если ваша программа будет убита в середине, худший вариант - оставить пустой файл.