.\" -*- coding: UTF-8 -*- .\" Copyright (c) 2017 by Michael Kerrisk .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH ioctl_ns 2 "2 мая 2024 г." "Linux man\-pages 6.8" .SH ИМЯ ioctl_ns \- операции ioctl() для пространств имён Linux .SH ОПИСАНИЕ .\" ============================================================ .\" .SS "Определение отношений между пространствами имён" Следующие операции \fBioctl\fP(2) позволяют определить порядок отношений между пространствами имён (смотрите \fBuser_namespaces\fP(7) и \fBpid_namespaces\fP(7)). Форма вызовов: .P .in +4n .EX new_fd = ioctl(fd, op); .EE .in .P Здесь в каждом случае \fIfd\fP ссылается на файл \fI/proc/\fPpid\fI/ns/*\fP. При успешном выполнении обе операции возвращают новый файловый дескриптор. .TP \fBNS_GET_USERNS\fP (начиная с Linux 4.9) .\" commit bcac25a58bfc6bd79191ac5d7afb49bea96da8c9 .\" commit 6786741dbf99e44fb0c0ed85a37582b8a26f1c3b Возвращает файловый дескриптор, ссылающийся на пространство имён пользователя, которое владеет пространством имён, на которое ссылается \fIfd\fP. .TP \fBNS_GET_PARENT\fP (начиная с Linux 4.9) .\" commit a7306ed8d94af729ecef8b6e37506a1c6fc14788 Возвращает файловый дескриптор, который ссылается на родительское пространство имён для пространства имён, на которое ссылается \fIfd\fP. Эта операция допускается только, для иерархических пространств имён (т. е., PID и пространства имён пользователя). Для пространств имён пользователя \fBNS_GET_PARENT\fP является синонимом \fBNS_GET_USERNS\fP. .P Новый файловый дескриптор, возвращаемый этими операциями, открывается с флагами \fBO_RDONLY\fP и \fBO_CLOEXEC\fP (close\-on\-exec; смотрите \fBfcntl\fP(2)). .P Применив \fBfstat\fP(2) к возвращаемому файловому дескриптору, можно получить структуру \fIstat\fP, в которой поля \fIst_dev\fP (подлежащее устройство) и \fIst_ino\fP (номер иноды) вместе отождествляют владельческое/родительское пространство имён. Этот номер иноды можно сравнить с номером иноды другого файла \fI/proc/\fPpid\fI/ns\fP/{\fIpid\fP,\fIuser\fP}, чтобы определить то же ли это владельческое/родительское пространство имён. .P Эти операции \fBioctl\fP(2) могут завершаться со следующими ошибками: .TP \fBEPERM\fP Запрошенное пространство имён лежит вне области пространств имён вызывающего. Эта ошибка может случиться, если, например, владельческое пространство имён является предком текущего пространства имён пользователя вызывающего. Также она может возникнуть при попытке получить родителя первоначального пространства имён пользователя или PID. .TP \fBENOTTY\fP Операция не поддерживается в этой версии ядра. .P Также, операция \fBNS_GET_PARENT\fP может завершиться со следующей ошибкой: .TP \fBEINVAL\fP Значение \fIfd\fP ссылается на не иерархическое пространство имён. .P .\" ============================================================ .\" Использование этих операций смотрите в разделе ПРИМЕРЫ. .SS "Определение типа пространства имён" .\" commit e5ff5ce6e20ee22511398bb31fb912466cf82a36 Операция \fBNS_GET_NSTYPE\fP (доступна, начиная с Linux 4.11) позволяет определять тип пространства имён, на которое ссылается файловый дескриптор \fIfd\fP: .P .in +4n .EX nstype = ioctl(fd, NS_GET_NSTYPE); .EE .in .P Значение \fIfd\fP ссылается на файл \fI/proc/\fPpid\fI/ns/*\fP. .P .\" ============================================================ .\" Возвращаемым значением является одно из \fBCLONE_NEW*\fP, которое может указываться \fBclone\fP(2) или \fBunshare\fP(2) для создания пространства имён. .SS "Определение владельца пространства имён пользователя" .\" commit 015bb305b8ebe8d601a238ab70ebdc394c7a19ba Операция \fBNS_GET_OWNER_UID\fP (доступна, начиная с Linux 4.11) позволяет определять пользовательский ID владельца пространства имён пользователя (т. е., эффективный пользовательский ID процесса, который создал пространство имён пользователя). Формат вызова: .P .in +4n .EX uid_t uid; ioctl(fd, NS_GET_OWNER_UID, &uid); .EE .in .P Значение \fIfd\fP ссылается на файл \fI/proc/\fPpid\fI/ns/user\fP. .P Возвращаемый пользовательский ID владельца находится в третьем аргументе с типом \fIuid_t\fP. .P Данная операция может завершиться со следующей ошибкой: .TP \fBEINVAL\fP Значение \fIfd\fP не ссылается на пространство имён пользователя. .SH ОШИБКИ Любая из этих операций \fBioctl\fP() может завершаться со следующими ошибками: .TP \fBENOTTY\fP \fIfd\fP does not refer to a \fI/proc/\fPpid\fI/ns/\fP* file. .SH СТАНДАРТЫ Linux. .SH ПРИМЕРЫ В примере, показанном ниже, используются описанные выше операции \fBioctl\fP(2), с помощью которых определяются отношения между пространствами имён. Далее показаны сценарии запуска этой программы. .P Попытка определить родителя изначального пространства имён пользователя завершается ошибкой, так как родителя нет: .P .in +4n .EX $ \fB./ns_show /proc/self/ns/user p\fP Родительское пространство имён находится вне области вашего пространства имён .EE .in .P Создаётся процесс, выполняющий \fBsleep\fP(1), который располагается в новом пространстве имён пользователя и UTS, и показывается, что новое пространство имён UTS связано с новым пространством имён пользователя: .P .in +4n .EX $ \fBunshare \-Uu sleep 1000 &\fP [1] 23235 $ \fB./ns_show /proc/23235/ns/uts u\fP Устройство/инода, владеющая пространством имён пользователя: [0,3] / 4026532448 $ \fBreadlink /proc/23235/ns/user\fP user:[4026532448] .EE .in .P Теперь покажем, что родителем нового пространства имён пользователя из предыдущего примера является начальное пространство имён пользователя: .P .in +4n .EX $ \fBreadlink /proc/self/ns/user\fP user:[4026531837] $ \fB./ns_show /proc/23235/ns/user p\fP Устройство/инода родительского пространства имён: [0,3] / 4026531837 .EE .in .P Запустим оболочку в новом пространстве имён пользователя и покажем, что внутри оболочки родительское пространство имён пользователя невозможно определить. Также невозможно определить пространство имён UTS (которое связано с изначальным пространством имён пользователя). .P .in +4n .EX $ \fBPS1="sh2$ " unshare \-U bash\fP sh2$ \fB./ns_show /proc/self/ns/user p\fP Родительское пространство имён находится вне области вашего пространства имён sh2$ \fB./ns_show /proc/self/ns/uts u\fP Владеющее пространство имён пользователя находится вне области вашего пространства имён .EE .in .SS "Исходный код программы" .\" SRC BEGIN (ns_show.c) \& .EX /* ns_show.c \& Licensed under the GNU General Public License v2 or later. */ #include #include #include #include #include #include #include #include #include #include #include \& int main(int argc, char *argv[]) { int fd, userns_fd, parent_fd; struct stat sb; \& if (argc < 2) { fprintf(stderr, "Usage: %s /proc/[pid]/ns/[file] [p|u]\en", argv[0]); fprintf(stderr, "\enDisplay the result of one or both " "of NS_GET_USERNS (u) or NS_GET_PARENT (p)\en" "for the specified /proc/[pid]/ns/[file]. If neither " "\[aq]p\[aq] nor \[aq]u\[aq] is specified,\en" "NS_GET_USERNS is the default.\en"); exit(EXIT_FAILURE); } \& /* Obtain a file descriptor for the \[aq]ns\[aq] file specified in argv[1]. */ \& fd = open(argv[1], O_RDONLY); if (fd == \-1) { perror("open"); exit(EXIT_FAILURE); } \& /* Obtain a file descriptor for the owning user namespace and then obtain and display the inode number of that namespace. */ \& if (argc < 3 || strchr(argv[2], \[aq]u\[aq])) { userns_fd = ioctl(fd, NS_GET_USERNS); \& if (userns_fd == \-1) { if (errno == EPERM) printf("The owning user namespace is outside " "your namespace scope\en"); else perror("ioctl\-NS_GET_USERNS"); exit(EXIT_FAILURE); } \& if (fstat(userns_fd, &sb) == \-1) { perror("fstat\-userns"); exit(EXIT_FAILURE); } printf("Device/Inode of owning user namespace is: " "[%x,%x] / %ju\en", major(sb.st_dev), minor(sb.st_dev), (uintmax_t) sb.st_ino); \& close(userns_fd); } \& /* Obtain a file descriptor for the parent namespace and then obtain and display the inode number of that namespace. */ \& if (argc > 2 && strchr(argv[2], \[aq]p\[aq])) { parent_fd = ioctl(fd, NS_GET_PARENT); \& if (parent_fd == \-1) { if (errno == EINVAL) printf("Can\[aq] get parent namespace of a " "nonhierarchical namespace\en"); else if (errno == EPERM) printf("The parent namespace is outside " "your namespace scope\en"); else perror("ioctl\-NS_GET_PARENT"); exit(EXIT_FAILURE); } \& if (fstat(parent_fd, &sb) == \-1) { perror("fstat\-parentns"); exit(EXIT_FAILURE); } printf("Device/Inode of parent namespace is: [%x,%x] / %ju\en", major(sb.st_dev), minor(sb.st_dev), (uintmax_t) sb.st_ino); \& close(parent_fd); } \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "СМОТРИТЕ ТАКЖЕ" \fBfstat\fP(2), \fBioctl\fP(2), \fBproc\fP(5), \fBnamespaces\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства разработал Azamat Hackimov , Dmitriy S. Seregin , Yuri Kozlov и Иван Павлов . .PP Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, .UR https://www.gnu.org/licenses/gpl-3.0.html .UE версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ. .PP Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику по его адресу электронной почты или по адресу .MT списка рассылки русских переводчиков .ME .