리눅스 시스템 프로그래밍 들어가며

동그란개발자·2024년 10월 27일

✔️ 사내 리눅스 시스템/네트워크 프로그래밍 강의와 "Linux System Programming" 서적 1장을 참고해 전체적인 그림을 그릴 수 있도록 정리한 글입니다

왜 시스템 프로그래밍인가?

컴퓨터 시스템을 뜯어보면, 크게 유저 공간과 커널 공간으로 나눌 수 있습니다. 추상화된 형태로 시스템 콜을 활용하는, 쉽게 말해 유저 공간에서만 노는 애플리케이션 프로그래머가 시스템 프로그래밍을 알면 어떤 이점이 있을까? 의구심이 들 수 있겠네요.

그렇게 중요하다고 지겹게 듣는 운영체제, 컴퓨터 구조, 알고리즘 등등.. 다 유기적으로 연결되어 있어서 사실 시스템 레벨까지 이해하는 건 단순한 애플리케이션 구현을 넘어서 안정성 있는 소프트웨어를 설계할 수 있는 뼈와 근육이 되어줍니다.

리눅스 시스템 프로그래밍의 초석

  • 시스템 콜
  • C 라이브러리: glibc
  • C 컴파일러: gcc

✔️ 시스템 콜을 활용해 유저 공간에서 운영체제에 특정 자원이나 서비스를 요청할 수 있다.

✔️ C 컴파일러와 라이브러리에 의해 커널이 시스템 콜 호출을 처리한다. 우리는 그 내막을 알 필요없이, 시스템 콜을 호출하면 그만이다.

Linux 시스템 프로그래밍의 주요 개념

파일 및 파일시스템

✔️ 리눅스는 "Everything-is-a-File" 철학을 따라서, 모든 걸 파일로 추상화해서 다룬다.

✔️ 파일을 다루기 위해선 파일 시스템의 인덱스인 File Descriptor(FD)가 필요하다.

✔️ 하나의 파일은 메타 정보 + 데이터을 기본 틀로 가지고 있어, inode(메타 정보) + data block(데이터)으로 구성된다.

✔️ 크게 세가지로 분류될 수 있다

  1. 일반 파일
  2. 디렉토리와 링크
  3. 특수 파일

일반 파일

  • inode + 데이터블록 구성

디렉토리와 링크

  • inode + (특수한 형태의) 데이터블록 구성
  • 디렉토리의 데이터블록에 filename 저장, inode와 filename 매핑

특수 파일

  • inode로만 구성

  • 디바이스 파일, 네임드 파이프, 유닉스 도메인 소켓이 이에 해당된다

    	👉 디바이스 파일: 입출력 장치(예: 하드 드라이브, 프린터, 터미널 등)를 파일로 추상화, 리눅스에서는 /dev 디렉토리 아래에 위치
    	👉 네임드 파이프: 프로세스 간 통신(IPC) 방식 중 하나로, 두 개 이상의 프로세스가 데이터를 주고받을 수 있게 함
    	👉 유닉스 도메인 소켓: 동일한 시스템 내의 프로세스 간 통신(IPC)을 위한 소켓

파일 시스템이란?

✔️ 계층화된 파일 및 디렉토리 집합으로, 각 파일 시스템은 특정 네임스페이스에 "마운트"된다.

👉 마운트?(mount, unmount)
외부 장치의 파일 시스템을 특정 디렉터리(마운트 포인트)에 연결하여 OS가 접근 가능하게 만드는 과정

✔️ 데이터를 저장하기 위한 최소 단위 - 블럭

프로세스

프로세스란?

프로세스 vs. 프로그램

✔️ 프로세스는 "실행 중인 프로그램"으로, 파일 시스템 상에 있는 프로그램 파일을 커널로 가져와 가상 주소 공간을 만든다

가상 주소 공간, Virtual Address Space (VAS)

✔️ 프로세스 별 독립적으로 주어지는 가상 공간으로, 텍스트 섹션, 데이터 섹션, BSS 섹션으로 구분

스케쥴링

프로세스와 쓰레드

쓰레드는 흔히 프로세스 내에서 "최소한의 실행 단위"라고 하죠. 다만 이게 따로 구분되는 이유는요? 분명히 비슷한데.. 프로세스 내에서 실행되는 작업 단위가 왜 필요했을까요?

✔️ 쓰레드는 사실 프로세스와 함께 등장하지 않았다.
✔️ 실질적으로 큼직한 프로세스 한두개를 CPU에 스케쥴링 시킬 일이 많다. 프로세스 단위로 스케쥴링 시키기보다, 잘게 쪼개 스케쥴링 시키는 게 효율적이지 않을까?

Life Cycle

Child : fork() - exec() - exit()
Parent :            ..wait()..
  • 부모 프로세스가 wait 하지 않아 자식 프로세스가 회수되지 않으면, 좀비 프로세스가 된다

User, Group, Permission

🧐 유닉스/리눅스 환경에서 접근 제어가 필요한 이유는?

  1. 멀티 유저 환경
  2. 자료가 여러 유저에 의해 공유될 수 있는 환경
  3. 세부적인 접근 제어의 필요성 👉 Access Control List(ACL)

시스템 이해하기

✔️ 프로세스가 주체(Subject)가 되어, 객체(Object)로서 파일에게
✔️ 주체는 Key를 가지고, 객체는 Lock을 가진다
✔️ 해당 Key가 Lock과 맞으면 통과, 해당 권한 부여

  • uid(user id), gid(group id)는 프로세스가 가진 열쇠로서, 프로세스 테이블에 기록된다.
  • owner, group은 파일이 가진 자물쇠로서, inode에 기록된다.
  1. uid —> owner : 맞으면 owner라는 권한 부여
  2. gid —> group : 맞으면 group라는 권한 부여
  3. 그게 아니면, other 권한 부여
  • Permission bits로 권한 표기: Read/Write/Execute for owner, group, other(xxxxxxxxx)

Access Control List(ACL)

임의의 사용자/그룹에 대하여 추가적인 권한 설정을 설정하는 것이다.

예를 들어, 재무 팀장이 Owner(Read/Write 가능), 재무팀 그룹(Read), 그 외 접근 불가하지만 사장은 특별히 조회 가능한 경우가 있다.

Signal

✔️ 프로세스 입장에서 외부에서 느닷없이 날아온 짱돌과 같다.
✔️ 짱돌(시그널)이 날아와 전달됐을 때, 프로세스의 리액션은?

Generation (커널에서 발생)

  1. 예외 발생 (ex. 나누기 0, seg fault)
  2. 사용자 요청 (ex. kill 명령)

Delivery (프로세스의 반응)

  1. 맞는다 (디폴트 동작)
  2. 피한다, 무시한다
  3. 잡는다 (=signal handling)

0개의 댓글