.\" -*- coding: UTF-8 -*- .\" Copyright (C) 2014 Michael Kerrisk .\" and Copyright (C) 2014 David Herrmann .\" .\" SPDX-License-Identifier: GPL-2.0-or-later .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH memfd_create 2 "3 мая 2023 г." "Linux man\-pages 6.05.01" .SH ИМЯ memfd_create \- создаёт анонимный файл .SH LIBRARY Standard C library (\fIlibc\fP, \fI\-lc\fP) .SH СИНТАКСИС .nf \fB#define _GNU_SOURCE\fP /* Смотрите feature_test_macros(7) */ \fB#include \fP .PP \fBint memfd_create(const char *\fP\fIname\fP\fB, unsigned int \fP\fIflags\fP\fB);\fP .fi .SH ОПИСАНИЕ .\" David Herrmann: .\" memfd uses VM_NORESERVE so each page is accounted on first access. .\" This means, the overcommit-limits (see __vm_enough_memory()) and the .\" memory-cgroup limits (mem_cgroup_try_charge()) are applied. Note that .\" those are accounted on "current" and "current->mm", that is, the .\" process doing the first page access. Вызов \fBmemfd_create\fP() создаёт анонимный файл и возвращает ссылающийся на него файловый дескриптор. Анонимный файл ведёт себя как обычный файл и может быть изменён, обрезан, отображён в память и т.д. Однако в отличие от обычного файла он располагается в ОЗУ и не имеет энергонезависимого хранилища. Как только все ссылки на файл удаляются, он автоматически исчезает. Анонимные файлы располагаются в анонимной памяти. Поэтому у файлов, создаваемых \fBmemfd_create\fP(), такая же семантика как и областей анонимной памяти, выделяемой с помощью \fBmmap\fP(2) с флагом \fBMAP_ANONYMOUS\fP. .PP Первоначально, размер файла равен 0. После этого вызова нужно задать размер файла с помощью \fBftruncate\fP(2) (или заполнить файл с помощью \fBwrite\fP(2) или подобными). .PP Имя, указанное в \fIname\fP, используется в качестве имени файла и будет показываться как цель соответствующей символьной ссылки в каталоге. \fI/proc/self/fd/\fP. Отображаемое имя всегда начинается с \fImemfd:\fP и служит только для отладки. Имена не влияют на поведение файлового дескриптора и поэтому несколько файлов могут иметь одно имя без каких\-либо последствий. .PP Для изменения поведения \fBmemfd_create\fP() можно использовать следующие значения \fIflags\fP (через OR): .TP \fBMFD_CLOEXEC\fP Устанавливает флаг close\-on\-exec (\fBFD_CLOEXEC\fP) для нового открытого файлового дескриптора. Смотрите описание флага \fBO_CLOEXEC\fP в \fBopen\fP(2) для того, чтобы узнать как это может пригодиться. .TP \fBMFD_ALLOW_SEALING\fP .\" FIXME Why is the MFD_ALLOW_SEALING behavior not simply the default? .\" Is it worth adding some text explaining this? Разрешает операции опечатывания (sealing) файла. Описание операций \fBF_ADD_SEALS\fP и \fBF_GET_SEALS\fP смотрите в \fBfcntl\fP(2), а также в ЗАМЕЧАНИЯ ниже. Первоначально набор печатей пуст. Если этот флаг не установлен, то начальным набором печатей будет \fBF_SEAL_SEAL\fP, означающий запрещение установки печатей на файл. .TP \fBMFD_HUGETLB\fP (начиная с Linux 4.14) .\" commit 749df87bd7bee5a79cef073f5d032ddb2b211de8 .\" commit 47b9012ecdc747f6936395265e677d41e11a31ff В файловой системе hugetlbfs, использующей огромные страницы, будет создан анонимный файл. В файле исходного кода Linux \fIDocumentation/admin\-guide/mm/hugetlbpage.rst\fP дана подробная информация о hugetlbfs. Одновременное указание \fBMFD_HUGETLB\fP и \fBMFD_ALLOW_SEALING\fP в \fIflags\fP поддерживается начиная с Linux 4.16. .TP \fBMFD_HUGE_2MB\fP, \fBMFD_HUGE_1GB\fP, \fB...\fP Используется как дополнение к \fBMFD_HUGETLB\fP для выбора размера страницы hugetlb (соответственно, 2\ МБ, 1\ ГБ, …) в системах, которые поддерживают различные размеры страниц hugetlb. Определения размеров огромных страниц включены в заголовочный файл \fI.\fP .IP Дополнительную информацию о кодировании размеров огромных страниц, отсутствующих в заголовочном файле, смотрите в описании сходных по имени констант в \fBmmap\fP(2). .PP Неиспользуемые биты в \fIflags\fP должны быть равны 0. .PP В качестве возвращаемого значения \fBmemfd_create\fP() возвращает новый файловый дескриптор, который можно использовать для обращения к файлу. Данный файловый дескриптор открыт на чтение и запись (\fBO_RDWR\fP) и в файловом дескрипторе установлен флаг \fBO_LARGEFILE\fP. .PP При вызове \fBfork\fP(2) и \fBexecve\fP(2) с файловым дескриптором, созданным \fBmemfd_create\fP(), применяется обычная семантика. Копия файлового дескриптора наследуется потомком, созданным \fBfork\fP(2), указывает на тот же файл. Файловый дескриптор сохраняется при после \fBexecve\fP(2), если не установлен флаг close\-on\-exec. .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" При успешном выполнении \fBmemfd_create\fP() возвращает новый файловый дескриптор. При ошибке возвращается \-1, и \fIerrno\fP устанавливается в соответствующее значение. .SH ОШИБКИ .TP \fBEFAULT\fP Некорректный адрес в \fIname\fP. .TP \fBEINVAL\fP В \fIflags\fP указаны неизвестные биты. .TP \fBEINVAL\fP .\" NAME_MAX - strlen("memfd:") Значение \fIname\fP было слишком длинным (ограничено 249 байтами, не считая конечный байт null). .TP \fBEINVAL\fP В \fIflags\fP указаны \fBMFD_HUGETLB\fP и \fBMFD_ALLOW_SEALING\fP одновременно. .TP \fBEMFILE\fP Было достигнуто ограничение по количеству открытых файловых дескрипторов на процесс. .TP \fBENFILE\fP Достигнуто максимальное количество открытых файлов в системе. .TP \fBENOMEM\fP Недостаточно памяти для создания нового анонимного файла. .TP \fBEPERM\fP The \fBMFD_HUGETLB\fP flag was specified, but the caller was not privileged (did not have the \fBCAP_IPC_LOCK\fP capability) and is not a member of the \fIsysctl_hugetlb_shm_group\fP group; see the description of \fI/proc/sys/vm/sysctl_hugetlb_shm_group\fP in \fBproc\fP(5). .SH СТАНДАРТЫ Linux. .SH ИСТОРИЯ Linux 3.17, glibc 2.27. .SH ЗАМЕЧАНИЯ .\" See also http://lwn.net/Articles/593918/ .\" and http://lwn.net/Articles/594919/ and http://lwn.net/Articles/591108/ Системный вызов \fBmemfd_create\fP() предоставляет простую альтернативу ручному монтированию файловой системы \fBtmpfs\fP(5), созданию и открытию файла в этой файловой системе. Основным предназначением \fBmemfd_create\fP() является создание файлов и соответствующих файловых дескрипторов, которые используются с программным интерфейсом опечатывания файлов, предоставляемым \fBfcntl\fP(2). .PP Системный вызов \fBmemfd_create\fP() также используется и без опечатывания файла (вот почему опечатывание файлов отключено, если этого не запросить явно с помощью флага \fBMFD_ALLOW_SEALING\fP). В частности, он может использоваться как альтернатива созданию файлов в \fItmp\fP или использованию \fBopen\fP(2) с \fBO_TMPFILE\fP в случаях, когда не требуется реальная ссылка на конечный файл в файловой системе. .SS "Опечатывание файла (file sealing)" Ели файл не опечатан, то процессы, которые связываются через общую память, должны или доверять друг другу, или учитывать возможность того, что недоверенная сторона может работать с общей памятью проблемным способом. Например, недоверенная сторона может изменить содержимое общей памяти в любое время или уменьшить область общей памяти. Первая возможность делает локальный процесс уязвимым к состязательности условий «момент проверки — момент использования» (обычно решается копированием данных из области общей памяти перед проверкой и использованием). Последняя возможность делает локальный процесс уязвимым к сигналам \fBSIGBUS\fP, которые возникают при попытке получить доступ к теперь несуществующему расположению в области общей памяти (решается использованием обработчика сигнала \fBSIGBUS\fP). .PP Взаимодействие с недоверенными сторонами приводит к усложнению кода для работы с общей памятью. Опечатывание памяти позволяет устранить эту сложность, позволяя процессу безопасно работать, зная что его партнёр не может изменить общую память нежелательным способом. .PP В примере использования механизма опечатывания происходит следующее: .IP (1) 5 Первый процесс создаёт файл \fBtmpfs\fP(5) с помощью \fBmemfd_create\fP(). Вызов возвращает файловый дескриптор, используемый далее. .IP (2) Первый процесс задаёт размер файла, созданного ранее, с помощью \fBftruncate\fP(2), отображает его с помощью \fBmmap\fP(2) и заполняется общую память нужными данными. .IP (3) The first process uses the \fBfcntl\fP(2) \fBF_ADD_SEALS\fP operation to place one or more seals on the file, in order to restrict further modifications on the file. (If placing the seal \fBF_SEAL_WRITE\fP, then it will be necessary to first unmap the shared writable mapping created in the previous step. Otherwise, behavior similar to \fBF_SEAL_WRITE\fP can be achieved by using \fBF_SEAL_FUTURE_WRITE\fP, which will prevent future writes via \fBmmap\fP(2) and \fBwrite\fP(2) from succeeding while keeping existing shared writable mappings). .IP (4) Второй процесс получает файловый дескриптор файла \fBtmpfs\fP(5) и отображает его. Варианты того, как это можно сделать: .RS .IP \[bu] 3 Процесс, вызвавший \fBmemfd_create\fP(), может переслать полученный файловый дескриптор второму процессу через доменный сокет UNIX (смотрите \fBunix\fP(7) и \fBcmsg\fP(3)). Второй процесс затем отображает файл с помощью \fBmmap\fP(2). .IP \[bu] Второй процесс создаётся с помощью \fBfork\fP(2) и, таким образом, наследует файловый дескриптор и отображение (заметим, что в этом случае и следующем образуется природное доверие между двумя процессами, так как они работают с правами одного пользовательского идентификатора. Поэтому опечатывание файла здесь не нужно). .IP \[bu] The second process opens the file \fI/proc/\fPpid\fI/fd/\fPfd, where \fI\fP is the PID of the first process (the one that called \fBmemfd_create\fP()), and \fI\fP is the number of the file descriptor returned by the call to \fBmemfd_create\fP() in that process. The second process then maps the file using \fBmmap\fP(2). .RE .IP (5) Второй процесс использует \fBfcntl\fP(2) с операцией \fBF_GET_SEALS\fP для получения битовой маски печатей, которые были применены к файлу. Данная маска проверяется, чтобы определить какие ограничения наложены на изменения файла. Если требуется, то второй процесс может наложить дополнительные печати, что ещё ограничить действия (возможно до тех пор, пока не будет наложена печать \fBF_SEAL_SEAL\fP). .SH ПРИМЕРЫ Далее показано два примера программы, в которых продемонстрировано использование \fBmemfd_create\fP() и программный интерфейс опечатывания файла. .PP Первая программа, \fIt_memfd_create.c\fP, создаёт файл \fBtmpfs\fP(5) с помощью \fBmemfd_create\fP(), изменяет его размер, отображает в память и, возможно, накладывает несколько печатей на файл. Программа принимает не более трёх аргументов командной строки, два первых обязательные. Первым аргументом задаётся имя файла, во втором — размер файла, а в необязательном третьем — строка символов, задающих устанавливаемые печати на файл. .PP Вторая программа, \fIt_get_seals.c\fP, может использоваться для открытия существующего файла, созданного \fBmemfd_create\fP(), и проверки набора печатей, применённых к файлу. .PP Следующий пример сеанса показывает как использовать программу. Сначала создаётся файл \fBtmpfs\fP(5) и накладываются печати: .PP .in +4n .EX $ \fB./t_memfd_create my_memfd_file 4096 sw &\fP [1] 11775 PID: 11775; fd: 3; /proc/11775/fd/3 .EE .in .PP После этого программа \fIt_memfd_create\fP продолжает выполняться в фоновом режиме. Из другой программы можно получить дескриптор файла, созданный \fBmemfd_create\fP(), открыв файл \fI/proc/\fPpid\fI/fd\fP, который соответствует файловому дескриптору, открытому \fBmemfd_create\fP(). Используя это имя, можно просмотреть содержимое символьной ссылки \fI/proc/\fPpid\fI/fd\fP и использовать программу \fIt_get_seals\fP для просмотра печатей, которые установлены на файл: .PP .in +4n .EX $ \fBreadlink /proc/11775/fd/3\fP /memfd:my_memfd_file (удалён) $ \fB./t_get_seals /proc/11775/fd/3\fP Наложенные печати: WRITE SHRINK .EE .in .SS "Исходный код программы: t_memfd_create.c" .\" SRC BEGIN (t_memfd_create.c) \& .EX #define _GNU_SOURCE #include #include #include #include #include #include #include #include \& int main(int argc, char *argv[]) { int fd; char *name, *seals_arg; ssize_t len; unsigned int seals; \& if (argc < 3) { fprintf(stderr, "%s name size [seals]\en", argv[0]); fprintf(stderr, "\et\[aq]seals\[aq] can contain any of the " "following characters:\en"); fprintf(stderr, "\et\etg \- F_SEAL_GROW\en"); fprintf(stderr, "\et\ets \- F_SEAL_SHRINK\en"); fprintf(stderr, "\et\etw \- F_SEAL_WRITE\en"); fprintf(stderr, "\et\etW \- F_SEAL_FUTURE_WRITE\en"); fprintf(stderr, "\et\etS \- F_SEAL_SEAL\en"); exit(EXIT_FAILURE); } \& name = argv[1]; len = atoi(argv[2]); seals_arg = argv[3]; \& /* Create an anonymous file in tmpfs; allow seals to be placed on the file. */ \& fd = memfd_create(name, MFD_ALLOW_SEALING); if (fd == \-1) err(EXIT_FAILURE, "memfd_create"); \& /* Size the file as specified on the command line. */ \& if (ftruncate(fd, len) == \-1) err(EXIT_FAILURE, "truncate"); \& printf("PID: %jd; fd: %d; /proc/%jd/fd/%d\en", (intmax_t) getpid(), fd, (intmax_t) getpid(), fd); \& /* Code to map the file and populate the mapping with data omitted. */ \& /* If a \[aq]seals\[aq] command\-line argument was supplied, set some seals on the file. */ \& if (seals_arg != NULL) { seals = 0; \& if (strchr(seals_arg, \[aq]g\[aq]) != NULL) seals |= F_SEAL_GROW; if (strchr(seals_arg, \[aq]s\[aq]) != NULL) seals |= F_SEAL_SHRINK; if (strchr(seals_arg, \[aq]w\[aq]) != NULL) seals |= F_SEAL_WRITE; if (strchr(seals_arg, \[aq]W\[aq]) != NULL) seals |= F_SEAL_FUTURE_WRITE; if (strchr(seals_arg, \[aq]S\[aq]) != NULL) seals |= F_SEAL_SEAL; \& if (fcntl(fd, F_ADD_SEALS, seals) == \-1) err(EXIT_FAILURE, "fcntl"); } \& /* Keep running, so that the file created by memfd_create() continues to exist. */ \& pause(); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SS "Исходный код программы: t_get_seals.c" .\" SRC BEGIN (t_get_seals.c) \& .EX #define _GNU_SOURCE #include #include #include #include \& int main(int argc, char *argv[]) { int fd; unsigned int seals; \& if (argc != 2) { fprintf(stderr, "%s /proc/PID/fd/FD\en", argv[0]); exit(EXIT_FAILURE); } \& fd = open(argv[1], O_RDWR); if (fd == \-1) err(EXIT_FAILURE, "open"); \& seals = fcntl(fd, F_GET_SEALS); if (seals == \-1) err(EXIT_FAILURE, "fcntl"); \& printf("Existing seals:"); if (seals & F_SEAL_SEAL) printf(" SEAL"); if (seals & F_SEAL_GROW) printf(" GROW"); if (seals & F_SEAL_WRITE) printf(" WRITE"); if (seals & F_SEAL_FUTURE_WRITE) printf(" FUTURE_WRITE"); if (seals & F_SEAL_SHRINK) printf(" SHRINK"); printf("\en"); \& /* Code to map the file and access the contents of the resulting mapping omitted. */ \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "СМ. ТАКЖЕ" \fBfcntl\fP(2), \fBftruncate\fP(2), \fBmemfd_secret\fP(2), \fBmmap\fP(2), \fBshmget\fP(2), \fBshm_open\fP(3) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства был сделан aereiae , Alexey , Azamat Hackimov , Dmitriy S. Seregin , Dmitry Bolkhovskikh , ITriskTI , Max Is , Yuri Kozlov , Иван Павлов и Малянов Евгений Викторович . .PP Этот перевод является бесплатной документацией; прочитайте .UR https://www.gnu.org/licenses/gpl-3.0.html Стандартную общественную лицензию GNU версии 3 .UE или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. .PP Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на .MT man-pages-ru-talks@lists.sourceforge.net .ME .