Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

11105
637
415734


[리눅스커널] 프로세스: current 매크로란 4. 프로세스(Process) 관리

지금까지 살펴봤듯이 프로세스 속성 정보를 관리하는 struct task_struct 타입의 태스크 디스크립터는 커널에서 가장 중요하게 관리하는 자료구조입니다. 여기에는 그럴 만한 이유가 있는데, 커널은 태스크 디스크립터에 접근해 프로세스 정보를 수시로 접근하고 저장하며, 태스크 디스크립터에 들어 있는 속성 정보로 함수의 실행 흐름이 바뀌기 때문입니다.
   
그렇다 보니 간단하면서도 시스템에 부하를 주지 않는 형태로 태스크 디스크립터의 주소에 접근하는 매크로 코드가 필요하다는 요구가 불거졌고, 커널에서는 이런 요구사항을 만족하는 매크로를 제공하기에 이르렀습니다. 이를 current 매크로라고 합니다. 

그럼 current 매크로는 무엇일까요? current 매크로에 접근하는 이유와 관련 자료 구조에 대해 다음과 같이 설명할 수 있습니다.

 current 매크로는 현재 구동 중인 프로세스의 태스크 디스크립터 주소를 알려줍니다.
 current 매크로를 통해 직접 태스크 디스크립터 필드에 접근할 수 있습니다.

* 유튜브 강의 동영상도 있으니 같이 들으시면 좋습니다. 




#프로세스

프로세스 소개 
프로세스 확인하기  
프로세스는 어떻게 생성할까?  
유저 레벨 프로세스 실행 실습  
커널 스레드  
커널 내부 프로세스의 생성 과정   
프로세스의 종료 과정 분석  
태스크 디스크립터(task_struct 구조체)  
스레드 정보: thread_info 구조체  
프로세스의 태스크 디스크립터에 접근하는 매크로 함수  
프로세스 디버깅  
   * glibc의 fork() 함수를 gdb로 디버깅하기  


"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)

# Reference: For more information on 'Linux Kernel';

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2


Thanks,
Austin Kim


repository:  
http://rousalome.egloos.com/10025058




핑백

덧글

  • 영악한 얼음여왕 2019/08/21 00:26 # 답글

    안녕하세요 질문 하나만 해도될까요? 제가 현재 커널에서 realpath를 구현중입니다...ㅠㅠ
    char *realpath(char *buffer, char resolv[256]) 함수입니다.

    매개변수값은 이렇게 되어있습니다.

    buffer는 __user *filename을 복사한 상대경로값입니다.
    resolv[256]는 buffer를 절대경로로 변환한 값입니다.

    함수가 진행이 되면서 buffer의 왼쪽부터 폴더 하나하나를 따라가면서 resolv에 차곡차곡 쌓아가게됩니다.

    그렇게해서 완성된 절대경로를 return resolve; 하여 함수를 종료하게 됩니다.

    그러나 symbolic link, hard link같은 경우에는 링크가 가리키는 절대 경로명을 찾아주고싶습니다.

    그래서
    __old_kernel_stat sb; 을 선언해 준 후

    lstat(resolv, &sb) 해준 다음,
    if S_ISLNK(sb.st_mode) 링크폴더라면
    readlink() 함수로 링크가 가리키는 폴더의 절대경로를 받아 다시 함수를 작동하게 하고싶습니다.

    예를들면 /etc를 카리키는 심볼릭 링크를 test로 생성후 vim /test/tmp 명령어를 실행합니다. 그러면 openat 시스템 콜을 통해 do_sys_open함수의 char __user* filename 변수로 파일값을 전달받고 이 변수를 buffer배열에 copy 합니다. char *path; 선언 후
    path = realpath(buffer, resolv); 함수를 실행합니다.

    그러면 realpath에서 '/'단위로 토큰을 만들어 따라가서 resolv에 쌓아가기 시작합니다. 그러다 resolv 가 "/test" 상태가 되었을 때 lstat를 통해 "/test"가 심볼릭 링크라는 것을 알아낸 후 readlink()함수를 통해 "/test"를 "/etc"로 변환해준 후 다시 토큰을 쌓아 최종적으로 resolv는 "/etc/tmp"를 최종적으로 가졌으면 합니다.

    그러나 커널 내에서는 lstat와 readlink를 사용하지를 못하네요...

    혹시 좋은 방법 있을까요..?

    [ 현재 fs/stat.c 에서 lstat함수를 k_lstat로, readlink함수를 k_readlink로 복사하여 적용을 시도했으나 커널패닉이 계속 나네요..
    __user 를 지워도 보고 copy_to_user를 memcpy로 카피하여 값을 가져오려고도 시도해봤지만 성공을 하지는 못했습니다..
    현재는 lstat와 readlink함수 그대로 복원시켜두었습니다..
    도와주실수 있나요.. ? :( ]
  • JohnLee 2023/01/20 15:34 # 삭제 답글

    1회차 책을 읽다 질문이 있어 댓글을 답니다.
    4.10.1절 중에
    #define get_current() (current_thread_info()->task)
    #define current get_current()
    에서 왜 굳이 한줄로 사용할 수 있는 매크로를 두 줄로 정의하는 건가요? 앞에서도 몇몇 코드에서도 이런 의문이 들었는데 이 절에서 티나게 두 코드가 붙어있어 이렇게 달려왔습니다.

    #define current (current_thread_info()->task)
    처럼 한 줄이면 코드 수도 줄어들고 좋을텐데 말입니다.
  • AustinKim 2023/01/21 13:01 #

    주신 질문에 대해 아래와 같이 새롭게 글을 포스팅했습니다.

    http://rousalome.egloos.com/10238490

    혹시 추가로 궁금하신 점이 있으면 위 포스팅에 댓글을 남겨주시면 됩니다.
    감사합니다.
댓글 입력 영역