Scroll to navigation

ioctl_ns(2) System Calls Manual ioctl_ns(2)

NUME

ioctl_ns - operații ioctl() pentru spațiile de nume Linux

DESCRIERE

Descoperirea relațiilor dintre spațiile de nume

Următoarele operații ioctl(2) sunt furnizate pentru a permite descoperirea relațiilor dintre spațiile de nume (a se vedea user_namespaces(7) și pid_namespaces(7)). Forma apelurilor este:


new_fd = ioctl(fd, request);

În fiecare caz, fd se referă la un fișier /proc/pid/ns/*. Ambele operații returnează un nou descriptor de fișier în caz de succes.

Returnează un descriptor de fișier care se referă la spațiul de nume al utilizatorului proprietar pentru spațiul de nume menționat de fd.
Returnează un descriptor de fișier care se referă la spațiul de nume părinte al spațiului de nume menționat de fd. Această operație este valabilă numai pentru spațiile de nume ierarhice (de exemplu, spațiile de nume PID și utilizator). Pentru spațiile de nume utilizator, NS_GET_PARENT este sinonim cu NS_GET_USERNS.

Noul descriptor de fișier returnat de aceste operații este deschis cu fanioanele O_RDONLY și O_CLOEXEC (close-on-exec; a se vedea fcntl(2)).

Aplicând fstat(2) descriptorului de fișier returnat, se obține o structură stat ale cărei câmpuri st_dev (dispozitiv rezident) și st_ino (număr de nod-i) identifică împreună spațiul de nume proprietar/părinte. Acest număr de nod-i poate fi comparat cu numărul de nod-i al unui alt fișier /proc/pid/ns/{pid,user} pentru a determina dacă acesta este spațiul de nume proprietar/părinte.

Oricare dintre aceste operații ioctl(2) poate eșua cu următoarele erori:

Spațiul de nume solicitat este în afara domeniului de aplicare al spațiului de nume al apelantului. Această eroare poate apărea dacă, de exemplu, spațiul de nume al utilizatorului proprietar este un strămoș al spațiului de nume al utilizatorului curent al apelantului. De asemenea, aceasta poate apărea în cazul încercărilor de a obține părintele spațiului de nume al utilizatorului inițial sau al PID.
Operația nu este acceptată de această versiune a nucleului.

În plus, operația NS_GET_PARENT poate eșua cu următoarea eroare:

fd se referă la un spațiu de nume neierarhic.

Consultați secțiunea EXEMPLE pentru un exemplu de utilizare a acestor operații.

Descoperirea tipului de spațiu de nume

Operația NS_GET_NSTYPE (disponibilă începând cu Linux 4.11) poate fi utilizată pentru a descoperi tipul de spațiu de nume la care se referă descriptorul de fișier fd:


nstype = ioctl(fd, NS_GET_NSTYPE);

fd refers to a /proc/pid/ns/* file.

Valoarea de returnare este una dintre valorile CLONE_NEW* care pot fi specificate la clone(2) sau unshare(2) pentru a crea un spațiu de nume.

Descoperirea proprietarului unui spațiu de nume de utilizator

Operația NS_GET_OWNER_UID (disponibilă începând cu Linux 4.11) poate fi utilizată pentru a descoperi ID-ul utilizatorului proprietar al unui spațiu de nume al utilizatorului (adică ID-ul utilizatorului efectiv al procesului care a creat spațiul de nume al utilizatorului). Forma apelului este:


uid_t uid;
ioctl(fd, NS_GET_OWNER_UID, &uid);

fd se referă la un fișier /proc/pid/ns/user.

ID-ul utilizatorului proprietar este returnat în uid_t indicat de al treilea argument.

Această operație poate eșua cu următoarea eroare:

fd nu se referă la un spațiu de nume al utilizatorului.

ERORI-IEȘIRE

Oricare dintre operațiile ioctl() de mai sus poate returna următoarele erori:

fd nu se referă la un fișier /proc/[pid]/ns/*.

STANDARDE

Spațiile de nume și operațiile descrise pe această pagină sunt specifice Linux.

EXEMPLE

Exemplul prezentat mai jos utilizează operațiile ioctl(2) descrise mai sus pentru a efectua o descoperire simplă a relațiilor dintre spațiile de nume. Următoarele sesiuni shell prezintă diverse exemple de utilizare a acestui program.

Încercarea de a obține părintele spațiului de nume al utilizatorului inițial eșuează, deoarece acesta nu are părinte:


$ ./ns_show /proc/self/ns/user p
Spațiul de nume părinte este în afara domeniului de aplicare al spațiului de nume

Creați un proces care rulează sleep(1) care rezidă în noile spații de nume utilizator și UTS și arătați că noul spațiu de nume UTS este asociat cu noul spațiu de nume utilizator:


$ unshare -Uu sleep 1000 &
[1] 23235
$ ./ns_show /proc/23235/ns/uts u
Dispozitivul/nodul-i al spațiului de nume al utilizatorului proprietar este: [0,3] / 4026532448
$ readlink /proc/23235/ns/user
utilizator:[4026532448]

Apoi arătați că părintele noului spațiu de nume al utilizatorului din exemplul precedent este spațiul de nume al utilizatorului inițial:


$ readlink /proc/self/ns/user
utilizator:[4026531837]
$ ./ns_show /proc/23235/ns/user p
Dispozitivul/nodul-i din spațiul de nume părinte este: [0,3] / 4026531837

Porniți un shell într-un nou spațiu de nume al utilizatorului și arătați că, din interiorul acestui shell, spațiul de nume al utilizatorului părinte nu poate fi descoperit. În mod similar, spațiul de nume UTS (care este asociat cu spațiul de nume al utilizatorului inițial) nu poate fi descoperit.


$ PS1="sh2$ " unshare -U bash
sh2$ ./ns_show /proc/self/ns/user p
Spațiul de nume părinte este în afara domeniului de aplicare al spațiului de nume
sh2$ ./ns_show /proc/self/ns/uts u
Spațiul de nume al utilizatorului proprietar este în afara domeniului dvs. de aplicare a spațiului de nume

Sursa programului

/* ns_show.c

Licențiat în conformitate cu Licența Publică Generală GNU v2 sau ulterioară. */ #include <errno.h> #include <fcntl.h> #include <linux/nsfs.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/sysmacros.h> #include <unistd.h> int main(int argc, char *argv[]) {
int fd, userns_fd, parent_fd;
struct stat sb;
if (argc < 2) {
fprintf(stderr, "Utilizare: %s /proc/[pid]/ns/[file] [p|u]\n",
argv[0]);
fprintf(stderr, "\nAfișează rezultatul uneia sau ambelor metode "
"NS_GET_USERNS (u) sau NS_GET_PARENT (p) pentru\n"
"fișierul /proc/[pid]/ns/[file] specificat. Dacă nu "
este specificat nici 'p', nici 'u',\n"
NS_GET_USERNS este valoarea implicită.\n");
exit(EXIT_FAILURE);
}
/* Obține un descriptor de fișier pentru fișierul 'ns'
specificat în argv[1]. */
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
/* Obține un descriptor de fișier pentru spațiul de nume al
utilizatorului proprietar și apoi obține și afișează numărul
de nod-i al spațiului de nume respectiv. */
if (argc < 3 || strchr(argv[2], 'u')) {
userns_fd = ioctl(fd, NS_GET_USERNS);
if (userns_fd == -1) {
if (errno == EPERM)
printf("Spațiul de nume al utilizatorului proprietar este în "
"afara domeniului dvs. de aplicare a spațiului de nume\n");
else
perror("ioctl-NS_GET_USERNS");
exit(EXIT_FAILURE);
}
if (fstat(userns_fd, &sb) == -1) {
perror("fstat-userns");
exit(EXIT_FAILURE);
}
printf("Dispozitivul/nodul-i al spațiului de nume al utilizatorului proprietar este: "
"[%x,%x] / %ju\n",
major(sb.st_dev),
minor(sb.st_dev),
(uintmax_t) sb.st_ino);
close(userns_fd);
}
/* Obține un descriptor de fișier pentru spațiul de nume părinte și apoi
obține și afișează numărul de nod-i al spațiului de nume respectiv. */
if (argc > 2 && strchr(argv[2], 'p')) {
parent_fd = ioctl(fd, NS_GET_PARENT);
if (parent_fd == -1) {
if (errno == EINVAL)
printf("Nu se poate obține spațiul de nume părinte al unui
"spațiu de nume neierarhizat\n");
else if (errno == EPERM)
printf("Spațiul de nume părinte este în afara domeniului
"de aplicare al spațiului de nume\n");
else
perror("ioctl-NS_GET_PARENT");
exit(EXIT_FAILURE);
}
if (fstat(parent_fd, &sb) == -1) {
perror("fstat-parentns");
exit(EXIT_FAILURE);
}
printf("Dispozitivul/nodul-i al spațiului de nume părinte este: [%x,%x] / %ju\n",
major(sb.st_dev),
minor(sb.st_dev),
(uintmax_t) sb.st_ino);
close(parent_fd);
}
exit(EXIT_SUCCESS); }

CONSULTAȚI ȘI

fstat(2), ioctl(2), proc(5), namespaces(7)

TRADUCERE

Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.

5 februarie 2023 Pagini de manual de Linux 6.03