Provided by: manpages-ru-dev_4.27.0-1_all bug

НАИМЕНОВАНИЕ

       kcmp - сравнивает два процесса, определяя используют ли они общий ресурс ядра

БИБЛИОТЕКА

       Стандартная библиотека языка C (libc, -lc)

ОБЗОР

       #include <linux/kcmp.h>       /* определения констант KCMP_* */
       #include <sys/syscall.h>      /* определения констант SYS_* */
       #include <unistd.h>

       int syscall(SYS_kcmp, pid_t pid1, pid_t pid2, int type,
                   unsigned long idx1, unsigned long idx2);

       Note: glibc provides no wrapper for kcmp(), necessitating the use of syscall(2).

ОПИСАНИЕ

       Системный  вызов  kcmp()  может использоваться для проверки, используют ли два процесса pid1 и pid2 общий
       ресурс ядра, например виртуальную память, файловые дескрипторы и т.д.

       Право вызывать kcmp() определяется проверкой режима доступа ptrace  PTRACE_MODE_READ_REALCREDS  вместе  с
       pid1 и pid2; смотрите ptrace(2).

       В аргументе type указывается какой ресурс двух процессов нужно сравнивать. Допустимы следующие значения:

       KCMP_FILE
              Проверить,  что  файловый  дескриптор  idx1  в  процессе pid1 указывает на то же открытое файловое
              описание (смотрите open(2)) что и файловый дескриптор idx2 в  процессе  pid2.  Существование  двух
              файловых дескрипторов, ссылающихся на одно файловое описание, может возникнуть в результате вызова
              dup(2)  (и подобного) в fork(2), или передачи файловых дескрипторов через доменный сокет (смотрите
              unix(7)).

       KCMP_FILES
              Проверить, используют ли процессы общий одинаковый набор открытых файловых дескрипторов. Аргументы
              idx1 и idx2 игнорируются. Подробности смотрите в описании флага CLONE_FILES в clone(2).

       KCMP_FS
              Проверить, используют ли процессы общую одинаковую информацию о файловой системе (т. е. маску прав
              создания, рабочий каталог  и  корень  файловой  системы).  Аргументы  idx1  и  idx2  игнорируются.
              Подробности смотрите в описании флага CLONE_FS в clone(2).

       KCMP_IO
              Проверить, используют ли процессы общее контекст ввода-вывода. Аргументы idx1 и idx2 игнорируются.
              Подробности смотрите в описании флага CLONE_IO в clone(2).

       KCMP_SIGHAND
              Проверить, используют ли процессы общую одинаковую таблицу обработчиков сигналов. Аргументы idx1 и
              idx2 игнорируются. Подробности смотрите в описании флага CLONE_SIGHAND в clone(2).

       KCMP_SYSVSEM
              Проверить,  используют  ли  процессы  общий  одинаковый список отмены операций семафоров System V.
              Аргументы idx1 и  idx2  игнорируются.  Подробности  смотрите  в  описании  флага  CLONE_SYSVSEM  в
              clone(2).

       KCMP_VM
              Проверить, используют ли процессы общее адресное пространство. Аргументы idx1 и idx2 игнорируются.
              Подробности смотрите в описании флага CLONE_VM в clone(2).

       KCMP_EPOLL_TFD (начиная с Linux 4.13)
              Проверить,  есть ли файловый дескриптор idx1 процесса pid1 в экземпляре epoll(7), описанном в idx2
              у  процесса  pid2.  Аргумент  idx2  является  указателем  на  структуру,  которая  описывает  файл
              назначения. Формат структуры:

           struct kcmp_epoll_slot {
               __u32 efd;
               __u32 tfd;
               __u64 toff;
           };

       В  этой структуре поле efd содержит файловый дескриптор epoll, возвращаемый epoll_create(2), tfd содержит
       номер файлового дескриптора, а toff содержит смещение в  файле  назначения,  начиная  с  нуля.  Несколько
       разных  назначений  могут  быть  зарегистрированы  с  одним  номером  файлового  дескриптора, а установка
       определённого смещения помогает выбрать нужный.

       Заметим, что вызов kcmp() не защищён от ложных срабатываний (false positives), которые  могут  случаться,
       если  процессы в этот момент выполняются. То есть для получения достоверных результатов перед выполнением
       данного системного вызова нужно  послать процессам сигнал SIGSTOP (смотрите signal(7)).

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       При успешном выполнении kcmp() возвращает результат арифметического сложения указателей ядра (когда  ядро
       сравнивает ресурсы, оно использует их адреса памяти).

       Для  простоты  объяснения рассмотрим пример. Предположим, что v1 и v2 — адреса соответствующих ресурсов и
       возвращается значение:

              0      v1 равен v2; другими словами, два процесса используют ресурс совместно.

              1      v1 меньше v2.

              2      v1 больше v2.

              3      v1 не равен v2, но нужная информация недоступна.

       В случае ошибки возвращается -1, а errno устанавливается в значение ошибки.

       Значения вызова kcmp() специально выбраны так, чтобы их легко можно было упорядочить.  В  частности,  это
       удобно когда нужно сравнить большое количество файловых дескрипторов.

ОШИБКИ

       EBADF  Значение type равно KCMP_FILE и fd1 или fd2 не являются открытыми файловыми дескрипторами.

       EFAULT Слот epoll, указанный в idx2, находится за пределами пользовательского адресного пространства.

       EINVAL Значение type неверно.

       ENOENT Файл назначения отсутствует в экземпляре epoll(7).

       EPERM  Недостаточно  прав  для  просмотра  ресурсов  процесса.  Для  проверки  процессов требуется мандат
              CAP_SYS_PTRACE, которого у вас нет. Также могут действовать другие  ограничения  ptrace,  например
              CONFIG_SECURITY_YAMA, которое при /proc/sys/kernel/yama/ptrace_scope равном 2, ограничивает kcmp()
              дочерними процессами; смотрите ptrace(2).

       ESRCH  Процесс pid1 или pid2 не существует.

СТАНДАРТЫ

       Linux.

ИСТОРИЯ

       Linux 3.5.

       Before   Linux   5.12,   this   system   call  is  available  only  if  the  kernel  is  configured  with
       CONFIG_CHECKPOINT_RESTORE, since the original purpose of the system call was for  the  checkpoint/restore
       in  user  space  (CRIU) feature.  (The alternative to this system call would have been to expose suitable
       process information via the proc(5)  filesystem; this was deemed to be unsuitable for security  reasons.)
       Since Linux 5.12, this system call is also available if the kernel is configured with CONFIG_KCMP.

ПРИМЕЧАНИЯ

       Дополнительную информацию об общих ресурсах смотрите в clone(2).

ПРИМЕРЫ

       Данная  программа использует kcmp() про проверки того, что пара файловых дескрипторов указывает на одно и
       тоже открытое файловое описание. Программа тестирует различные  случаи  для  пар  файловых  дескрипторов,
       описанных в выводе программы. Пример работы программы:

           $ ./a.out
           Parent PID is 1144
           Parent opened file on FD 3

           PID of child of fork() is 1145
                Compare duplicate FDs from different processes:
                     kcmp(1145, 1144, KCMP_FILE, 3, 3) ==> same
           Child opened file on FD 4
                Compare FDs from distinct open()s in same process:
                     kcmp(1145, 1145, KCMP_FILE, 3, 4) ==> different
           Child duplicated FD 3 to create FD 5
                Compare duplicated FDs in same process:
                     kcmp(1145, 1145, KCMP_FILE, 3, 5) ==> same

   Исходный код программы

       #define _GNU_SOURCE
       #include <err.h>
       #include <fcntl.h>
       #include <linux/kcmp.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/syscall.h>
       #include <sys/types.h>
       #include <sys/wait.h>
       #include <unistd.h>

       static int
       kcmp(pid_t pid1, pid_t pid2, int type,
            unsigned long idx1, unsigned long idx2)
       {
           return syscall(SYS_kcmp, pid1, pid2, type, idx1, idx2);
       }

       static void
       test_kcmp(char *msg, pid_t pid1, pid_t pid2, int fd_a, int fd_b)
       {
           printf("\t%s\n", msg);
           printf("\t\tkcmp(%jd, %jd, KCMP_FILE, %d, %d) ==> %s\n",
                  (intmax_t) pid1, (intmax_t) pid2, fd_a, fd_b,
                  (kcmp(pid1, pid2, KCMP_FILE, fd_a, fd_b) == 0) ?
                               "same" : "different");
       }

       int
       main(void)
       {
           int                fd1, fd2, fd3;
           static const char  pathname[] = "/tmp/kcmp.test";

           fd1 = open(pathname, O_CREAT | O_RDWR, 0600);
           if (fd1 == -1)
               err(EXIT_FAILURE, "open");

           printf("Parent PID is %jd\n", (intmax_t) getpid());
           printf("Parent opened file on FD %d\n\n", fd1);

           switch (fork()) {
           case -1:
               err(EXIT_FAILURE, "fork");

           case 0:
               printf("PID of child of fork() is %jd\n", (intmax_t) getpid());

               test_kcmp("Compare duplicate FDs from different processes:",
                         getpid(), getppid(), fd1, fd1);

               fd2 = open(pathname, O_CREAT | O_RDWR, 0600);
               if (fd2 == -1)
                   err(EXIT_FAILURE, "open");
               printf("Child opened file on FD %d\n", fd2);

               test_kcmp("Compare FDs from distinct open()s in same process:",
                         getpid(), getpid(), fd1, fd2);

               fd3 = dup(fd1);
               if (fd3 == -1)
                   err(EXIT_FAILURE, "dup");
               printf("Child duplicated FD %d to create FD %d\n", fd1, fd3);

               test_kcmp("Compare duplicated FDs in same process:",
                         getpid(), getpid(), fd1, fd3);
               break;

           default:
               wait(NULL);
           }

           exit(EXIT_SUCCESS);
       }

СМОТРИТЕ ТАКЖЕ

       clone(2), unshare(2)

ПЕРЕВОД

       Русский  перевод этой страницы руководства разработал(и) Alex Nik <rage.iz.me@gmail.com>, Azamat Hackimov
       <azamat.hackimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com>  и  Kirill
       Rekhov <krekhov.dev@gmail.com>

       Этот  перевод является свободной программной документацией; он распространяется на условиях общедоступной
       лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html  версии  3  или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если  вы  обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом
       разработчику(ам)  по  его(их)  адресу(ам)  электронной  почты  или  по   адресу   списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                  15 июня 2024 г.                                         kcmp(2)