kcmp(2) - wariua/manpages-ko GitHub Wiki

NAME

kcmp - 두 ν”„λ‘œμ„ΈμŠ€ λΉ„κ΅ν•΄μ„œ 컀널 μžμ› 곡유 μ—¬λΆ€ μ•Œμ•„λ‚΄κΈ°

SYNOPSIS

#include <linux/kcmp.h>

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

주의: 이 μ‹œμŠ€ν…œ ν˜ΈμΆœμ— λŒ€ν•œ glibc λž˜νΌκ°€ μ—†λ‹€. NOTES μ°Έκ³ .

DESCRIPTION

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) μ°Έκ³ ) ν”„λ‘œμ„ΈμŠ€λ₯Ό μ •μ§€μ‹œμΌœμ•Ό ν•œλ‹€.

RETURN VALUE

kcmp() 성곡 호좜의 λ°˜ν™˜ 값은 컀널 ν¬μΈν„°λ“€μ˜ μ‚°μˆ  비ꡐ 결과이닀. (μ»€λ„μ—μ„œ μžμ›μ„ 비ꡐ할 λ•Œ μžμ›μ˜ λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό μ‚¬μš©ν•œλ‹€.)

κ°€μž₯ μ‰¬μš΄ μ„€λͺ… 방법은 예λ₯Ό λ“œλŠ” 것이닀. v1κ³Ό v2κ°€ μ λ‹Ήν•œ μžμ› μ£Όμ†ŒλΌκ³  ν•  λ•Œ λ°˜ν™˜ 값은 λ‹€μŒ 쀑 ν•˜λ‚˜μ΄λ‹€.

0
v1이 v2와 κ°™λ‹€. λ‹€μ‹œ 말해 두 ν”„λ‘œμ„ΈμŠ€κ°€ μžμ›μ„ κ³΅μœ ν•œλ‹€.
1
v1이 v2보닀 μž‘λ‹€.
2
v1이 v2보닀 크닀.
3
v1이 v2와 κ°™μ§€ μ•Šλ˜, μˆœμ„œμ— λŒ€ν•œ 정보가 μ—†λ‹€.

였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•˜λ©° errnoλ₯Ό 적절히 μ„€μ •ν•œλ‹€.

kcmp()λŠ” 정렬에 μ ν•©ν•œ 값을 λ°˜ν™˜ν•˜λ„λ‘ μ„€κ³„λ˜μ—ˆλ‹€. λ§Žμ€ 수의 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 비ꡐ해야 ν•  λ•Œ 이 점이 특히 νŽΈλ¦¬ν•˜λ‹€.

ERRORS

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) μΈμŠ€ν„΄μŠ€μ— λŒ€μƒ 파일이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€.

VERSIONS

λ¦¬λˆ…μŠ€ 3.5μ—μ„œ kcmp() μ‹œμŠ€ν…œ 호좜이 처음 λ“±μž₯ν–ˆλ‹€.

CONFORMING TO

kcmp()λŠ” λ¦¬λˆ…μŠ€ μ „μš©μ΄λ―€λ‘œ 이식성이 μžˆμ–΄μ•Ό ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ—μ„œλŠ” μ‚¬μš©ν•˜μ§€ 말아야 ν•œλ‹€.

NOTES

glibcμ—μ„œ 이 μ‹œμŠ€ν…œ 호좜의 래퍼λ₯Ό μ œκ³΅ν•˜μ§€ μ•ŠλŠ”λ‹€. syscall(2)을 μ΄μš©ν•΄ ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€.

컀널을 CONFIG_CHECKPOINT_RESTORE둜 κ΅¬μ„±ν•œ κ²½μš°μ—λ§Œ 이 μ‹œμŠ€ν…œ 호좜이 μ‚¬μš© κ°€λŠ₯ν•˜λ‹€. 이 μ‹œμŠ€ν…œ 호좜의 μ£Ό μ‚¬μš©μ²˜λŠ” μ‚¬μš©μž 곡간 체크포인트/볡원(CRIU) κΈ°λŠ₯이닀. 이 μ‹œμŠ€ν…œ 호좜의 λŒ€μ•ˆμœΌλ‘œλŠ” proc(5) 파일 μ‹œμŠ€ν…œμ„ 톡해 μ μ ˆν•œ ν”„λ‘œμ„ΈμŠ€ 정보λ₯Ό λ…ΈμΆœν•˜λŠ” 것이 μžˆμ„ 텐데, λ³΄μ•ˆμ  이유둜 μ μ ˆν•˜μ§€ μ•Šλ‹€κ³  λ³΄μ•˜λ‹€.

이 νŽ˜μ΄μ§€μ—μ„œ μ–ΈκΈ‰ν•˜λŠ” 곡유 μžμ›λ“€μ— λŒ€ν•œ λ°°κ²½ μ •λ³΄λŠ” clone(2)을 보라.

EXAMPLE

μ•„λž˜ ν”„λ‘œκ·Έλž¨μ€ 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);
}

SEE ALSO

clone(2), unshare(2)


2019-03-06

⚠️ **GitHub.com Fallback** ⚠️