PTY: 프로세스에게 터미널처럼 보이는 커널 객체

PTY exhaustion: 시스템이 프로세스에게 새 pseudo-terminal(가상 터미널)을 할당하려고 했지만 커널이 관리하는 PTY 리소스의 한도에 도달하여 더 이상 만들 수 없는 상태

구조

Terminal-like program
        │
        │ PTY master
        ▼
   ┌───────────┐
   │   Kernel  │
   └───────────┘
        ▲
        │ PTY slave
        │
   /dev/pts/N
        │
        ▼
      shell

일반적인 물리 터미널 대신, 소프트웨어가 터미널처럼 동작해야 할 때 PTY를 사용한다. 예를 들어 ssh, tmux, screen, 터미널 에뮬레이터, Docker의 -t, Kubernetes의 kubectl exec -it, IDE terminal 등이 이에 해당한다.

1. PTY가 정확히 무엇인가

PTY는 master/slave 쌍으로 이루어진 가상 터미널 장치다.

예를 들어 사용자가 SSH로 서버에 접속해서 shell을 띄우면 대략 다음과 같이 동작한다.

사용자 키보드
     │
     ▼
SSH client
     │ network
     ▼
sshd
     │
     ▼
PTY master  <──── kernel ────>  PTY slave
                              /dev/pts/4
                                  │
                                  ▼
                                bash

bash 입장에서는 /dev/pts/4가 실제 터미널처럼 보인다.

그래서 다음과 같은 터미널 기능이 가능해진다.

Ctrl+C
Ctrl+Z
job control
terminal resize
echo
canonical input
foreground/background process group

반대로 SSH에서 PTY를 할당하지 않으면 단순 pipe 기반 stdin/stdout처럼 동작할 수 있다.

~$ ssh host command 는 경우에 따라 PTY가 필요하지 않지만, ~$ ssh -t host는 명시적으로 PTY를 요청한다.

 

2. Linux에서 PTY는 어디에 존재하는가

현대 Linux에서는 보통 Unix98 PTY를 사용한다.

slave 측은 다음과 같이 보인다. /dev/pts/0 /dev/pts/1 ...

현재 터미널을 확인하려면 ~$ tty

PTY 관련 커널 상태는 다음에서 확인할 수 있다.

#현재 할당 되어 있는 PTY 개수
cat /proc/sys/kernel/pty/nr
#시스템 전체에서 허용되는 PTY 최대 개수
cat /proc/sys/kernel/pty/max

 

3. "PTY 고갈"이 실제로 무엇을 의미하는가

새로운 SSH connection이 들어오면서 sshd가 PTY를 달라고 커널에 요청한다. 이미 한계에 도달했을 경우 openpty() 또는 /dev/ptmx를 통한 PTY allocation이 실패한다.

다음과 같은 에러가 나올 수 있다.

openpty: No space left on device (디스크 공간 부족을 의미하는게 아니다)

 

4. 정상적인 PTY lifecycle

정상적으로는 다음처럼 동작한다.

1. process가 PTY 요청
2. kernel이 PTY master/slave pair 생성
3. /dev/pts/N 생성
4. shell/process가 slave 사용
5. 세션 종료
6. master/slave FD close
7. kernel이 PTY 회수

SSH 접속
   ↓
PTY 123 생성
   ↓
bash 실행
   ↓
사용자 logout
   ↓
FD close
   ↓
PTY 123 해제

 

5. PTY가 고갈되는 대표적인 원인

중요한 건 PTY 자체가 일반적으로 "영구적으로 leak"되는 게 아니라, PTY를 열어 둔 프로세스가 계속 살아 있기 때문에 회수되지 않는 경우가 많다는 점이다.

원인 1: SSH session 폭증

원인 2: orphaned 또는 오래 살아 있는 shell

원인 3: tmux/screen session 과다

원인 4: Container에서 TTY 대량 할당

원인 5: 테스트/자동화 코드의 PTY leak

 

6. PTY namespace/container와 관련한 주의점

Linux container 환경에서는 /dev/pts가 별도의 devpts mount로 보일 수 있다.

그래서 컨테이너 안에서 보이는 /dev/pts 상태와 host 전체 커널의 PTY 상태를 구분해서 봐야 한다.

Linux kernel이 PTY를 관리하는 방식에는 전역 limit뿐 아니라 devpts namespace와 관련된 설정도 있어, container 환경에서는 host에서 확인하는 것이 더 정확한 경우가 많다.

특히 비교적 현대적인 kernel에서는:

cat /proc/sys/kernel/pty/max
cat /proc/sys/kernel/pty/reserve
cat /proc/sys/kernel/pty/nr

같은 항목이 존재할 수 있다.

pty.reserve는 특정 상황에서 initial mount namespace에 PTY 여유분을 예약하기 위한 개념이다.

'Linux(Ubuntu) > 서버 원격접속' 카테고리의 다른 글

XRDP Linux to Linux  (0) 2026.04.06
tailscale 명령어  (0) 2026.04.03
CSP Bastion Service 모음  (0) 2026.03.14
Apache Guacamole  (0) 2026.03.14
Azure Bastion  (0) 2026.03.14

Problem Case: 기존에 사용하던 방식인 curl을 이용한 docker 설치는 APT/DEB 방식임. 단, 동일 환경에서 apt, snap방식으로 docker가 모두 설치된 상태에서 snap docker와 Nvidia Toolkit간의 호환 문제가 발생하였음.

APT Docker 설정: /etc/docker/daemon.json

Snap Docker 설정: /var/snap/docker/current/config/daemon.json

APT Docker 재시작: systemctl restart docker

Snap Docker 재시작: snap restart docker.dockerd

발견된 서버의 APT/DEB Docker 버전은 29.1.3, snap docker 버전은 29.3.1 버전이었음

Canonical은 Docker Snap 29.2.0부터 호스트에 DEB 패키지로 설치된 Nvidia Container Toolkit이 있으면 Nvidia GPU container가 시작되지 않을 수 있다고 명시되어 있음. 이에 대한 해결책으로 Toolkit을 제거하거나 nvidia.runtime-hook 드라이버를 지정하도록 안내되어 있음(https://github.com/canonical/docker-snap#nvidia-container-toolkit-compatibility)

그 결과 본 서버의 DCGM container 시작 과정에서 /usr/bin/nvidia-cuda-mps-control 파일을 처리하지 못했음.

snap은 격리된 환경에서 실행되기 때문에 호스트의 Nvidia Toolkit 파일을 일반 Docker와 동일한 방식으로 참조하지 못했고 container가 Created 상태에서 시작되지 않았음.

 


참고사항

get.docker.com 설치

바이너리: /usr/bin/docker

설정: /etc/docker/daemon.json

데이터: /var/lib/docker

서비스: systemctl restart docker

 

snap install docker

바이너리: /snap/bin/docker

설정: /var/snap/docker/current/config/daemon.json

데이터: /var/snap/docker/common/var-lib-docker

서비스: snap restart docker.dockerd

'Linux(Ubuntu) > Monitoring' 카테고리의 다른 글

Local Monitoring Dashboard(on CLI terminal)  (0) 2026.03.06
journalctl 사용 모음  (0) 2026.02.12
Grafana 설정  (0) 2026.01.17
DCGM-exporter(6): Worker Node 추가  (0) 2026.01.17
DCGM-exporter(5): Prometheus, Grafana  (0) 2026.01.17

(Ubuntu) Linux 환경에서 용량을 확인하기위해 주로 df(disk free), du(disk usage) 이렇게 2가지 명령어를 여러 인자와 조합하여 사용한다. 본 게시글은 터미널 환경에서 더 쉽게 볼 수 있는 도구인 ncdu에 대해 소개한다.

sudo apt install ncdu # Ubuntu/Debian
sudo yum install ncdu # CentOS/RHEL

또는 경우에 따라 rpm, dnf 사용

 

이후 터미널에 바로 ncdu를 입력하면 로딩과 함께 용량 사용을 분석하고 가시화된 방식으로 용량 확인이 가능하다. 방향키로 움직이며 용량 확인을 편하게 할 수 있다.

종료: q or ctrl+c

'Linux(Ubuntu) > 기타' 카테고리의 다른 글

AMD Server Freeze BIOS Setting  (0) 2026.05.19
Kernel Panic Reboot  (0) 2026.04.29
Kernel Panic  (0) 2026.04.29
NMI  (0) 2026.04.29
RCU stall  (0) 2026.04.29

별도의 서비스를 운영하지 않는데 특정 서버가 자꾸 뻗는다.

MB: X370 Gaming Pro Carbon(MS-7A32)

CPU: AMD Ryzen 7 1800X 8-core processor

*1세대 Ryzen/X370 계열의 idle 전원 상태 안정성 문제가 여러 차례 제기된 이력이 있다.

진행 설정

#BIOS 설정 변경
Power Supply Idle Control = Auto -> Typical Current Idle
Global C-state Control = Auto -> Disabled

 

Power Supply Idle Control: CPU가 아주 낮은 전류 상태로 들어가는 방식을 조절

Global C-state Control: CPU의 유휴 절전 상태 사용 여부를 조절

Global C-state Control을 끄면 안정성은 좋아지지만 유휴 전력 증가, 전력 효율 저하 등 단점이 존재한다.

 

'Linux(Ubuntu) > 기타' 카테고리의 다른 글

Ubuntu 용량 확인: ncdu  (0) 2026.05.27
Kernel Panic Reboot  (0) 2026.04.29
Kernel Panic  (0) 2026.04.29
NMI  (0) 2026.04.29
RCU stall  (0) 2026.04.29

/goal 명령어 활성화 방법

codex cli 사용환경임을 가정함

본인 환경에서 codex를 설치한 위치를 찾고 내부에 있는 config.toml 파일을 수정하면 됨.

#local terminal로 별도 변경 없이 설치했을 때의 경로 기준
cd ./.codex

#내부에 config.toml 파일 존재 확인
ls

#편집(nano/vim)
sudo nano config.toml

아래에 다음 문구를 추가
[features]
goals=true

이후 codex를 새로 열어서 /goal 을 타이핑하면 추가된 것을 확인할 수 있음.

사용법은 /goal ~~~ 이렇게 하면 실행 시 goal 이 진행되는동안 계속 돌아감(우측 하단에 보라색 마킹 생김)

요구사항을 특정 조건, 특정 시간 이렇게 줘도 됨

'Agents > Codex' 카테고리의 다른 글

Codex CLI Ubuntu 설치  (0) 2026.04.06
Codex CLI Windows 설치(WSL X)  (0) 2026.04.02

1. 커널 패닉(Kernel Panic) 상태의 오해

커널 패닉이 발생했다고 해서 CPU의 전원이 즉시 꺼지는 것은 아님. 커널은 치명적인 오류를 감지하면 다음과 같은 단계를 밟음.

  1. 현재 실행 중인 모든 프로세스를 중단시킴.
  2. 화면에 에러 메시지(Panic log)를 출력함.
  3. 무한 루프(Infinite Loop)에 빠져 대기함.

이때 시스템은 멈춘 것처럼 보이지만, CPU는 여전히 전원을 공급받으며 '대기 루프'를 돌고 있는 상태.

2. 자동 재부팅의 원리: 하드웨어와 소프트웨어의 협업

① 하드웨어 와치독(Watchdog Timer)

컴퓨터 메인보드에는 Watchdog이라는 하드웨어 타이머가 있다. 이 장치는 카운트다운(예: 60초 → 0초)을 계속 수행한다.

  • 정상 상태: OS가 주기적으로 이 타이머를 "리셋" 한다. (이를 '개 밥 주기(Kicking the dog)'라고 부름.)
  • 패닉 상태: OS가 멈추면 리셋을 못 함. 타이머가 0에 도달하면, 하드웨어는 "시스템이 죽었구나!" 라고 판단하고 물리적인 리셋 신호를 보낸다.

② 커널 예외 처리 루틴 (Software)

사용자가 설정한 kernel.panic = 10은 커널 내부의 특정 변수 값을 바꾸는 것이다.

  1. 커널 패닉이 발생하면 커널은 하던 일을 멈추고 panic() 함수를 실행한다.
  2. 이 함수 안에는 if (panic_timeout > 0) 이라는 조건문이 있다.
  3. 만약 이 값이 10이라면, 커널은 시스템을 즉시 멈추는 대신 10초 동안 대기(Delay)하는 루프를 돈다.
  4. 10초가 지나면 커널은 키보드 컨트롤러나 전원 관리 칩(ACPI)에 "Reboot" 명령(정션 박스에 신호를 보내는 것과 유사)을 강제로 날린다.

 

3. 왜 이렇게 설정하는 것이 로그 기록에 유리한가?

시스템이 멈춘 상태로 영원히 두면, 메모리에 남아 있는 마지막 로그들이 디스크로 내려가지 못할 확률이 크다. 하지만 재부팅 명령이 내려지는 과정에서 커널은 다음과 같은 시도를 할 수 있다.

  • Emergency Sync: 커널은 재부팅 직전에 메모리 버퍼에 있는 데이터를 디스크로 밀어 넣으려는(Flush) 마지막 시도를 한다.
  • Kdump (커널 덤프): 설정에 따라 패닉 직전의 메모리 전체 상태를 파일로 저장하기도 한다.

 

4. 운영체제적 관점 요약

구분 일반적인 멈춤 (Freeze) 커널 패닉 (Panic)
상태 인터럽트 처리가 아예 안 됨 커널이 스스로 오류를 인지함
로그 기록 거의 불가능 패닉 직전까지 기록 가능
재부팅 하드웨어 와치독만 가능 kernel.panic 설정으로 자동 제어 가능

즉, kernel.panic=10 설정은 커널이 멈추더라도 10초 뒤에는 강제로라도 다시 시작하도록 미리 설정해두는 것.

실제 설정 예시

#커널 파라미터 임시 적용 (테스트용)
sudo sysctl -w kernel.panic=10

#영구 적용을 위해 파일 수정
echo "kernel.panic=10" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

 

Helped by Gemini 3 Pro

'Linux(Ubuntu) > 기타' 카테고리의 다른 글

Ubuntu 용량 확인: ncdu  (0) 2026.05.27
AMD Server Freeze BIOS Setting  (0) 2026.05.19
Kernel Panic  (0) 2026.04.29
NMI  (0) 2026.04.29
RCU stall  (0) 2026.04.29

kernel panic은 kernel이 이 상태로 계속 실행되면 더 위험하다고 판단하고 정상 운영을 포기하는 상태. 사용자 공간의 exception이나 process crash 와는 다름

process crash 과정

  1. user process fault
  2. kernel이 signal 전달
  3. 해당 process만 종료
  4. OS는 계속 동작

kernel panic 과정

  1. kernel 내부 불일치 또는 치명적 진행성 문제
  2. kernel이 panic( ) 호출
  3. 정상 스케줄링 중단
  4. 로그/덤프 출력 시도
  5. 설정에 따라 reboot or halt

panic이후 재부팅은 systemd가 하는게 아님. 이 단계에서는 user space가 이미 믿을 수 없는 상태이거나 멈췄을 수 있음. 따라서 재부팅 경로는 kernel 내부에서 진행.

  1. panic( )
  2. panic_timeout 확인
  3. emergency_restart( )
  4. machine_emergency_restart( )
  5. arch/x86 reboot path
  6. ACPI / keyboard controller / triple fault / EFI reset등 가능한 reset method
  7. HW reset

참고) 정상 reboot

  1. systemd reboot
  2. systemd가 service 종료
  3. file system sync/unmount
  4. kernel reboot syscall
  5. HW reset

'Linux(Ubuntu) > 기타' 카테고리의 다른 글

AMD Server Freeze BIOS Setting  (0) 2026.05.19
Kernel Panic Reboot  (0) 2026.04.29
NMI  (0) 2026.04.29
RCU stall  (0) 2026.04.29
RCU  (0) 2026.04.29

NMI: Non-Maskable Interrupt

일반 인터럽트보다 더 강한 성격의 인터럽트. Linux는 hard lockup이나 stall이 의심되면 다른 CPU에 NMI를 쏴서 지금 어디에서 멈췄는지 backtrace를 찍어보라고 요청함. 그런데 NMIs are not reaching exc_nmi( )가 나온다는 건, 해당 CPU들이 NMI 핸들러 진입조차 못했거나 적어도 kernel이 기대한 방식으로 응답하지 않았다는 뜻. CA 관점에서는 다음 계층 중 하나가 심하게 꼬였을 가능성을 의미함.

  • CPU core가 특정 상태에서 빠져나오지 못함
  • local APIC / interrupt delivery 문제
  • timer interupt 처리 문제
  • kernel이 interrupt-disabled 구간에서 장시간 stuck
  • 드라이버가 kernel 모드에서 CPU를 오래 붙잡음
  • 펌웨어 / 전원관리 / C-state 계층 문제

이 경우 사용자 프로그램 하나가 죽은게 아니라 kernel/CPU 진행성 자체가 깨짐에 가까움.

참고 용어

1) soft lockup watchdog:

-CPU가 너무 오래 커널 스케쥴링 지점을 지나지 않으면 감지

2) hard lockup watchdog:

-NMI 기반으로 CPU가 아예 인터럽트에도 반응하지 않는지 감지

3) hung task detector:

-특정 task가 D state 등에서 너무 오래 block되면 감지

4) RCU stall detector:

RCU grace period가 너무 오래 끝나지 않으면 감지

'Linux(Ubuntu) > 기타' 카테고리의 다른 글

Kernel Panic Reboot  (0) 2026.04.29
Kernel Panic  (0) 2026.04.29
RCU stall  (0) 2026.04.29
RCU  (0) 2026.04.29
UFW BLOCK log 제거  (0) 2026.02.05

default pipeline

  1. CPU stop/RCU 진행 불능 발생
  2. RCU stall detector가 감지
  3. RCU stall log 출력
  4. no panic, no reboot
  5. 상태 회복 안 되면 freeze로 남음

bypass pipeline

    1. RCU stall log 출력 이후
    2. 설정 확인: panic_on_rcu_stall=1
    3. kernel이 RCU stall을 panic으로 승격
    4. panic( ) 호출
    5. kernel.panic=30 확인, 30s 대기
    6. kernel이 emergency_restart( ) 계열 호출
    7. 하드웨어 reset 경로로 재부팅, 서비스 재시작

기본 설정, 즉 panic_on_rcu_stall=0일 때 흐름은 대략 다음과 같음

1. 어떤 CPU가 멈추거나 커널 내부 진행이 막힘

예를 들어 CPU가 커널 모드에서 빠져나오지 못하거나, 타이머 인터럽트/스케줄링/softirq 처리가 밀리거나, 특정 드라이버가 CPU를 오래 붙잡음.


  2. RCU grace period가 끝나지 않음

RCU는 “모든 CPU가 안전 지점을 한 번씩 지났는가?”를 기다림. 그런데 어떤 CPU가 stuck 상태면 RCU는 오래된 자료구조를 안전하게 해제할 수 없음.


  3. RCU stall detector가 타임아웃을 감지

일정 시간 동안 RCU grace period가 진행되지 않으면 커널이 로그를 찍음

rcu: INFO: rcu_preempt detected stalls on CPUs/tasks
rcu_preempt kthread timer wakeup didn't happen
rcu_preempt kthread starved


  4. 커널이 문제 CPU들에 NMI backtrace를 요청
     커널은 멈춘 CPU가 어디서 stuck됐는지 보기 위해 NMI를 보냄.

Sending NMI from CPU 3 to CPUs ...


  5. CPU가 NMI에도 응답하지 않으면 더 심각한 로그가 찍힘

nmi_backtrace_stall_check: CPU 9: NMIs are not reaching exc_nmi()


  6. 기본 설정에서는 panic으로 가지 않음

kernel.panic_on_rcu_stall = 0

      이 값이 0이면 RCU stall은 “치명적 경고”로 로그만 남기고, panic()을 호출하지 않음.


  7. kernel.panic=30도 발동하지 않음(사용자가 별도 설정했을 경우)

kernel.panic=30: panic이 이미 발생했을 때 30초 후 재부팅하는 설정.

그런데 기본 RCU stall 경로에서는 panic이 발생하지 않으므로 이 설정까지 도달하지 않음.


  8. 커널은 계속 살아보려고 시도함

RCU stall 메시지를 반복 출력하거나, watchdog/hung task 메시지가 추가로 나올 수 있음. 일부 CPU나 일부 task는 여전히 돌 수도 있음.

9. 하지만 실제 시스템은 사실상 freeze 상태가 될 수 있음

특히 여러 CPU가 NMI에도 응답하지 않는 상태면 user space도 제대로 진행되지 않음. SSH, GUI, systemd, journald, Docker 같은 것들이 멈추거나 응답하지 않을 수 있음.

10. 자동 재부팅 없이 그대로 방치됨

panic이 아니므로 emergency reboot 경로로 가지 않음. 결국 사람이 전원 버튼, reset 버튼, IPMI, 스마트플러그 같은 외부 수단으로 재부팅해야 함.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Linux(Ubuntu) > 기타' 카테고리의 다른 글

Kernel Panic  (0) 2026.04.29
NMI  (0) 2026.04.29
RCU  (0) 2026.04.29
UFW BLOCK log 제거  (0) 2026.02.05
Ubuntu Linux Log Setting  (0) 2026.02.02

Read-Copy-Update의 약자. kernel 내부에서 매우 자주 사용하는 동기화 방식. 락을 무겁게 잡지 않고도 읽는 쪽은 빠르게 지나가고, 쓰는 쪽은 안전한 시점까지 기다렸다가 오래된 데이터를 제거하는 구조.

ex) kernel 안에 다음과 같은 공유 자료구조가 있다고 생각하면 됨.

reader CPUs: 현재 자료구조를 lock 없이 빠르게 읽음

writer CPUs: new version 만들고 pointer 교체

writer CPUs: 예전 version을 바로 free 하지 않고 기다림

왜 기다리냐면 어떤 CPU가 아직 예전 pointer를 보고 있을 수 있기 때문. 그래서 RCU는 모든 CPU가 최소 한 번은 안전한 지점, 즉 quiescent state를 지났는가?를 추적함. 이 안전한 지점을 지나면 예전 데이터를 더이상 참조하는 CPU가 없다고 판단하고 free 할 수 있음.

다만 문제는 어떤 CPU가 kernel 안에서 너무 오래 멈추거나, interrupt/scheduling/timer가 제대로 안 돌면 RCU가 모든 CPU가 안전 지점을 지났다는 확인을 못함. 그러면 RCU grace period가 끝나지 않게됨. 이 상태가 오래 지속되면 kernel은 다음과 같이 판단함.

rcu: INFO: rcu_preempt detected stalls on CPUs/tasks
rcu_preempt kthread timer wakeup didn't happen
rcu_preempt kthread starved
Possible timer handling issue

 

'Linux(Ubuntu) > 기타' 카테고리의 다른 글

NMI  (0) 2026.04.29
RCU stall  (0) 2026.04.29
UFW BLOCK log 제거  (0) 2026.02.05
Ubuntu Linux Log Setting  (0) 2026.02.02
계정 접근 권한 rwx 관리  (0) 2026.01.15

+ Recent posts