nodev, noexec, nosuid는 리눅스 시스템 보안 설정의 핵심.
discard : 이 옵션이 설정되어 있으면 블럭 해제 시 discard/TRIM 명령어를 수행하여 즉시 공간을 회수한다. SSD 장치와 sparse/thinly-privisioned LUN의 경우 유용하다.
discard와 fstrim.service
삼성전자 SSD PM883 펌웨어 이슈.
오류 메세지 내용의 failed command: SEND FPDMA QUEUED 는 대개 queued TRIM 사용시 발생하는 NCQ.
리눅스 * 삼성전자 SSD 펌웨어의 TRIM 이슈는 과거부터 꾸준히 제기. (https://www.reddit.com/r/buildapc/comments/3a58s0/dont_use_linux_on_samsung_ssds)..)
https://bugzilla.kernel.org/show_bug.cgi?id=203475
- 컨슈머용 SSD 내용이지만 Samsung SSD 8xx Series에서 랜덤하게 fault하는 이슈가 발생.
- 커널 파라미터 ncq를 비활성화거나 sata 3.0gbps 모드로 변경시 안정화 (단 해당 workaround적용시 심각한 SSD IOPS 저하 가능성)
linux에서 queued TRIM (Continuous TRIM) 활성 (queued TRIM을 지원하는 OS는 현재 리눅스 뿐)
- /etc/fstab 대상 디스크 마운트 포인트내 'discard' 옵션 추가 ( 해당 옵션은 block i/o discard 발생 시 TRIM 수행 )
우분투 20.04 에서 발생하지 않은 이유 ( 우분투 22.04 에서만 발생하고 있는 이유 )
- 21년경 우분투 cloudimage 루트(OS) 마운트포인트에 discard가 적용. (https://bugs.launchpad.net/ubuntu/+source/livecd-rootfs/+bug/1902103)
- 해당 노드는 PM883아닌 PM893으로 별도 모델의 SSD임을 확인했습니다
조치 방안
-(1) 최신 리눅스에서는 비정상적인 해당 디스크를 blacklist(현재는 차별 논란으로 인해 QUIRK라고 부릅니다)하여 NCQ TRIM을 실행하지 않음 ( linux >=6.2 )
커널 업그레이드
commit log: https://lore.kernel.org/all/20230220133603.029430013@linuxfoundation.org/
git: https://github.com/torvalds/linux/blob/eabcdba3ad4098460a376538df2ae36500223c1e/drivers/ata/libata-core.c#L4149
-(2)
/etc/fstab 디스크 마운트 포인트내 discard 옵션 제거 (재부팅 필요, TRIM은 i/o block해제 발생시 -> 1주일에 1회 동작으로 변경되므로 기존대비 i/o 성능 저하 발생 가능성 및 1주일 Periodic TRIM에 의해 스케쥴 시간 순간 일시적인 i/o 저하 체험가능)
discard 옵션은 파일 삭제 등의 블록 해제 작업 시 즉시 TRIM을 전송.
이 때 다른 I/O 명령어들과 함께 NCQ 큐에 TRIM 명령이 섞여 전송될 수 있어, 펌웨어 버그가 있는 SSD는 커널 패닉/파일시스템 손상과 같은 문제가 발생.
fstrim은 특정 시점에 스케쥴에 맞춰 비어있는 블록을 한꺼번에 TRIM.
이 때 시스템에서 동시에 수행되는 일반 I/O가 거의 없으면, TRIM 단독으로 전송되므로 NCQ와 충돌할 가능성이 훨씬 낮아짐.
대부분의 리눅스 배포판에서 fstrim.stimer는 비활성 시간대(일반적으로 일주일에 한 번, 일요일 새벽 12시경)에 수행되어 I/O 경합이 적은 시점에 작동.
# systemctl status fstrim.service
○ fstrim.service - Discard unused blocks on filesystems from /etc/fstab
Loaded: loaded (/usr/lib/systemd/system/fstrim.service; static)
Active: inactive (dead) since Mon 2025-04-14 01:00:32 KST; 12h ago
TriggeredBy: ● fstrim.timer
Docs: man:fstrim(8)
Process: 2210715 ExecStart=/sbin/fstrim --listed-in /etc/fstab:/proc/self/mountinfo --verbose --quiet-unsupported (code=exited, status=0/SUCCESS)
Main PID: 2210715 (code=exited, status=0/SUCCESS)
CPU: 99ms
# cat /usr/lib/systemd/system/fstrim.service
[Unit]
Description=Discard unused blocks on filesystems from /etc/fstab
Documentation=man:fstrim(8)
ConditionVirtualization=!container
[Service]
Type=oneshot
ExecStart=/sbin/fstrim --listed-in /etc/fstab:/proc/self/mountinfo --verbose --quiet-unsupported
PrivateDevices=no
PrivateNetwork=yes
PrivateUsers=no
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
MemoryDenyWriteExecute=yes
SystemCallFilter=@default @file-system @basic-io @system-service
# systemctl status fstrim.timer
● fstrim.timer - Discard unused filesystem blocks once a week
Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; preset: enabled)
Active: active (waiting) since Mon 2024-11-04 11:23:44 KST; 5 months 8 days ago
Trigger: Mon 2025-04-21 01:19:11 KST; 6 days left
Triggers: ● fstrim.service
Docs: man:fstrim
# cat /usr/lib/systemd/system/fstrim.timer
[Unit]
Description=Discard unused filesystem blocks once a week
Documentation=man:fstrim
ConditionVirtualization=!container
ConditionPathExists=!/etc/initrd-release
[Timer]
OnCalendar=weekly
AccuracySec=1h
Persistent=true
RandomizedDelaySec=100min
[Install]
WantedBy=timers.target
# systemctl list-timers fstrim.timer
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2025-04-21 01:19:11 KST 6 days Mon 2025-04-14 01:00:32 KST 12h ago fstrim.timer fstrim.service
discard와 fstrim의 가장 큰 차이는 모아서 한번에 처리하느냐, 스케줄에 맞춰 한번에 처리하느냐의 차이.
discard의 경우 공간이 확보될 때마다 TRIM을 수행하기 때문에 대량의 공간이 확보되는 경우 I/O 성능 저하를 경험할 수 있음.
fstrim의 경우 기본적으로 사용량이 가장 적을 법한 시간(일요일 00:00~01:00 즈음)에 TRIM을 수행하긴 하지만,
이 역시 fstrim이 수행되는 시점에 I/O 성능 저하를 경험할 수 있는건 동일하긴 함.
단, 실시간 블록 회수가 중요한 케이스를 제외하고는 I/O 성능이나 안정성 측면에서 fstrim이 더 우위에 있는 것 같음.