kcmp(2) - wariua/manpages-ko GitHub Wiki
kcmp - λ νλ‘μΈμ€ λΉκ΅ν΄μ 컀λ μμ 곡μ μ¬λΆ μμλ΄κΈ°
#include <linux/kcmp.h>
int kcmp(pid_t pid1, pid_t pid2, int type,
unsigned long idx1, unsigned long idx2);
μ£Όμ: μ΄ μμ€ν νΈμΆμ λν glibc λνΌκ° μλ€. NOTES μ°Έκ³ .
kcmp()
μμ€ν
νΈμΆμ μ΄μ©ν΄ pid1
κ³Ό pid2
λ‘ λνλΈ λ νλ‘μΈμ€κ° κ°μ λ©λͺ¨λ¦¬λ νμΌ λμ€ν¬λ¦½ν° λ±μ 컀λ μμμ 곡μ νλμ§ νμΈν μ μλ€.
kcmp()
μ΄μ© κΆνμ pid1
κ³Ό pid2
λͺ¨λμ λν ptrace μ κ·Ό λͺ¨λ PTRACE_MODE_READ_REALCREDS
κ²μ¬μ λ°λΌ κ²°μ λλ€. ptrace(2) μ°Έκ³ .
type
μΈμλ λ νλ‘μΈμ€μμ μ΄λ€ μμμ λΉκ΅ν μ§ λνλΈλ€. λ€μ κ°λ€ μ€ νλμ΄λ€.
KCMP_FILE
-
νλ‘μΈμ€
pid1
λ΄μ νμΌ λμ€ν¬λ¦½ν°idx1
μ΄ νλ‘μΈμ€pid2
λ΄μ νμΌ λμ€ν¬λ¦½ν°idx2
μ κ°μ μ΄λ¦° νμΌ κΈ°μ νλͺ©(open(2) μ°Έκ³ )μ κ°λ¦¬ν€λμ§ νμΈνλ€. dup(2) (λ° μ μ¬ ν¨μ), fork(2), λλ©μΈ μμΌμ ν΅ν νμΌ λμ€ν¬λ¦½ν° μ λ¬(unix(7) μ°Έκ³ )μ κ²°κ³Όλ‘ κ°μ μ΄λ¦° νμΌ κΈ°μ νλͺ©μ κ°λ¦¬ν€λ λ κ°μ νμΌ λμ€ν¬λ¦½ν°κ° μ‘΄μ¬ν μ μλ€. KCMP_FILES
-
νλ‘μΈμ€λ€μ΄ λμΌν μ΄λ¦° νμΌ λμ€ν¬λ¦½ν° μ§ν©μ 곡μ νλμ§ νμΈνλ€.
idx1
λ°idx2
μΈμλ 무μνλ€. clone(2)μCLONE_FILES
νλκ·Έ λ Όμ μ°Έκ³ . KCMP_FS
-
νλ‘μΈμ€λ€μ΄ κ°μ νμΌ μμ€ν
μ 보(μ¦ νμΌ λͺ¨λ μμ± λ§μ€ν¬, μμ
λλ ν°λ¦¬, νμΌ μμ€ν
루νΈ)λ₯Ό 곡μ νλμ§ νμΈνλ€.
idx1
λ°idx2
μΈμλ 무μνλ€. clone(2)μCLONE_FS
νλκ·Έ λ Όμ μ°Έκ³ . KCMP_IO
-
νλ‘μΈμ€λ€μ΄ I/O λ¬Έλ§₯μ 곡μ νλμ§ νμΈνλ€.
idx1
λ°idx2
μΈμλ 무μνλ€. clone(2)μCLONE_IO
νλκ·Έ λ Όμ μ°Έκ³ . KCMP_SIGHAND
-
νλ‘μΈμ€λ€μ΄ λμΌν μκ·Έλ μ²λ¦¬ λ°©μ ν
μ΄λΈμ 곡μ νλμ§ νμΈνλ€.
idx1
λ°idx2
μΈμλ 무μνλ€. clone(2)μCLONE_SIGHAND
νλκ·Έ λ Όμ μ°Έκ³ . KCMP_SYSVSEM
-
νλ‘μΈμ€λ€μ΄ λμΌν μμ€ν
V μΈλ§ν¬μ΄ μμ
μ·¨μ λͺ©λ‘μ 곡μ νλμ§ νμΈνλ€.
idx1
λ°idx2
μΈμλ 무μνλ€. clone(2)μCLONE_SYSVSEM
νλκ·Έ λ Όμ μ°Έκ³ . KCMP_VM
-
νλ‘μΈμ€λ€μ΄ λμΌν μ£Όμ 곡κ°μ 곡μ νλμ§ νμΈνλ€.
idx1
λ°idx2
μΈμλ 무μνλ€. clone(2)μCLONE_VM
νλκ·Έ λ Όμ μ°Έκ³ . KCMP_EPOLL_TFD
-
νλ‘μΈμ€
pid1
μ νμΌ λμ€ν¬λ¦½ν°idx1
μ΄ νλ‘μΈμ€pid2
μidx2
κ° κΈ°μ νλ epoll(7) μΈμ€ν΄μ€ λ΄μ μλμ§ νμΈνλ€.idx2
μΈμλ λμ νμΌμ κΈ°μ νλ ꡬ쑰체μ λν ν¬μΈν°μ΄λ€. κ·Έ ꡬ쑰체λ λ€μ ννμ΄λ€.struct kcmp_epoll_slot { __u32 efd; __u32 tfd; __u64 toff; };
μ΄ κ΅¬μ‘°μ²΄μμ
efd
λ epoll_create(2)κ° λ°νν epoll νμΌ λμ€ν¬λ¦½ν°μ΄κ³ ,tfd
λ λμ νμΌ λμ€ν¬λ¦½ν° λ²νΈμ΄κ³ ,toff
λ 0λΆν° μΈλ λμ νμΌ μ€νμ μ΄λ€. κ°μ νμΌ λμ€ν¬λ¦½ν° λ²νΈλ‘ μλ‘ λ€λ₯Έ μ¬λ¬ λμμ λ±λ‘ν μ μκΈ° λλ¬Έμ μ€νμ μ§μ μ΄ κ°κ°μ μ‘°μ¬νλ λ° λμμ΄ λλ€.
μ°Έκ³ λ‘ kcmp()
λ νλ‘μΈμ€λ€μ΄ νμ¬ λμ μ€μΈ κ²½μ° λ°μν μ μλ κ±°μ§ μμ±μ λν λλΉκ° λμ΄ μμ§ μλ€. μ μλ―Έν κ²°κ³Όλ₯Ό μ»μΌλ €λ©΄ μ΄ μμ€ν
νΈμΆλ‘ μ‘°μ¬νκΈ°μ μμ 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
κ° μ΄λ¦° νμΌ λμ€ν¬λ¦½ν°κ° μλλ€. EINVAL
-
type
μ΄ μ ν¨νμ§ μλ€. EPERM
- νλ‘μΈμ€ μμμ μ‘°μ¬ν κΆνμ΄ λΆμ‘±νλ€. μμ νκ³ μμ§ μμ νλ‘μΈμ€λ₯Ό μ‘°μ¬νλ €λ©΄
CAP_SYS_PTRACE
μλ₯μ΄ νμνλ€. κ·Έλ¦¬κ³ λ€λ₯Έ ptrace μ μ½μ΄ μ μ©λ μλ μλ€. κ°λ ΉCONFIG_SECURITY_YAMA
μμλ/proc/sys/kernel/yama/ptrace_scope
κ° 2μΌ λkcmp()
λ₯Ό μμ νλ‘μΈμ€λ€λ‘ μ ννλ€. ptrace(2) μ°Έκ³ . ESRCH
- νλ‘μΈμ€
pid1
μ΄λpid2
κ° μ‘΄μ¬νμ§ μλλ€. EFAULT
-
idx2
κ° κ°λ¦¬ν€λ epoll μ¬λ‘―μ΄ μ¬μ©μμ μ£Όμ κ³΅κ° λ°μ μλ€. ENOENT
- epoll(7) μΈμ€ν΄μ€μ λμ νμΌμ΄ μ‘΄μ¬νμ§ μλλ€.
리λ
μ€ 3.5μμ kcmp()
μμ€ν
νΈμΆμ΄ μ²μ λ±μ₯νλ€.
kcmp()
λ 리λ
μ€ μ μ©μ΄λ―λ‘ μ΄μμ±μ΄ μμ΄μΌ νλ νλ‘κ·Έλ¨μμλ μ¬μ©νμ§ λ§μμΌ νλ€.
glibcμμ μ΄ μμ€ν νΈμΆμ λνΌλ₯Ό μ 곡νμ§ μλλ€. syscall(2)μ μ΄μ©ν΄ νΈμΆν΄μΌ νλ€.
컀λμ CONFIG_CHECKPOINT_RESTORE
λ‘ κ΅¬μ±ν κ²½μ°μλ§ μ΄ μμ€ν
νΈμΆμ΄ μ¬μ© κ°λ₯νλ€. μ΄ μμ€ν
νΈμΆμ μ£Ό μ¬μ©μ²λ μ¬μ©μ κ³΅κ° μ²΄ν¬ν¬μΈνΈ/볡μ(CRIU) κΈ°λ₯μ΄λ€. μ΄ μμ€ν
νΈμΆμ λμμΌλ‘λ proc(5) νμΌ μμ€ν
μ ν΅ν΄ μ μ ν νλ‘μΈμ€ μ 보λ₯Ό λ
ΈμΆνλ κ²μ΄ μμ ν
λ°, 보μμ μ΄μ λ‘ μ μ νμ§ μλ€κ³ 보μλ€.
μ΄ νμ΄μ§μμ μΈκΈνλ 곡μ μμλ€μ λν λ°°κ²½ μ 보λ 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
#include _GNU_SOURCE
#include <sys/syscall.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/kcmp.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
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, id_t pid1, pid_t pid2, int fd_a, int fd_b)
{
printf("\t%s\n", msg);
printf("\t\tkcmp(%ld, %ld, KCMP_FILE, %d, %d) ==> %s\n",
(long) pid1, (long) pid2, fd_a, fd_b,
(kcmp(pid1, pid2, KCMP_FILE, fd_a, fd_b) == 0) ?
"same" : "different");
}
int
main(int argc, char *argv[])
{
int fd1, fd2, fd3;
char pathname[] = "/tmp/kcmp.text";
fd1 = open(pathname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd1 == -1)
errExit("open");
printf("Parent PID is %ld\n", (long) getpid());
printf("Parent opened file on FD %d\n\n", fd1);
switch (fork()) {
case -1:
errExit("fork");
case 0:
printf("PID of child of fork() is %ld\n", (long) getpid());
test_kcmp("Compare duplicate FDs from different processes:",
getpid(), getppid(), fd1, fd1);
fd2 = open(pathname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd2 == -1)
errExit("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)
errExit("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);
}
2019-03-06