이번 주 LWN.net 위클리 에디션(9월 24일자) 주요 내용이다. 9월 말 나올 Git 2.56은 조용한 릴리스지만 그 다음 릴리스가 SHA-256 기본 전환과 reftable, Rust 필수화를 한꺼번에 들고 오는 3.0이 될 가능성이 커졌다. 커널 쪽에서는 GCC의 Rust 프런트엔드 gccrs가 3년 걸린 이름 해석 재작성을 끝내고 core 크레이트 컴파일 직전까지 왔고, Jens Axboe는 io_uring의 “블로킹하지 않는다” 보장을 지키려고 스레드 두 개의 신원을 통째로 맞바꾸는 RFC를 올렸다. 여기에 Linux Test Project로 NetBSD의 compat_linux를 검증한 GSoC 결과와, 20년째 제자리인 데스크톱 UX를 오픈소스가 먼저 흔들어보자는 Akademy 발표까지 다룬다.
- Looking forward to Git 2.56 — and 3.0 — 2.56의 새 기능과 SHA-256·reftable·Rust를 묶은 3.0 로드맵
- Compiling the kernel with gccrs — 이름 해석 재작성을 마친 gccrs가 커널 Rust 코드를 컴파일하기까지 남은 일
- Thread-identity switcheroo for io_uring — 블로킹 직전에 제출 스레드와 워커 스레드의 신원을 교환하는 RFC
- Testing compat_linux on NetBSD with the Linux Test Project — 리눅스 테스트 스위트로 NetBSD의 리눅스 바이너리 실행 계층을 검증한 결과
- Ideas on modernizing the open-source desktop — WIMP 모델 이후를 오픈소스가 먼저 실험해야 한다는 Scott Jenson의 제안
- 짧은 소식: WordPress 미인증 RCE, Radicle 프로토콜 취약점 2건, 커널 7.3-rc4, GNOME 51, systemd v262, Systemtap 5.6
Git 2.56과 그 다음에 올 3.0
9월 말 예정된 Git 2.56은 머지 커밋을 제외하고 700여 개 커밋이 들어간 릴리스지만, 대부분 사용자의 Git 사용 방식을 바꾸지는 않는다. 눈에 띄는 것은 아직 실험 단계인 git history 툴박스에 추가된 drop 서브커맨드다.
$ git history drop <commit-id>
지정한 커밋을 현재 브랜치 히스토리에서 빼고 그 뒤 커밋들을 재생(replay)한다. 다만 히스토리에 머지 커밋이 있으면 아직 동작을 거부하므로, 대부분의 실제 저장소에서는 쓸 수 없다.
| 변경 | 내용 |
|---|---|
git status | 추적 브랜치보다 뒤처진 브랜치에 git pull을 제안. 단, fetch하지 않은 원격 추적 브랜치보다 뒤처져 있으면 여전히 “up to date”라고 표시한다 |
git refs | create, delete, update, rename 서브커맨드 추가 — 이름 그대로 동작한다 |
git branch --delete-merged | 원격 추적 브랜치에 머지된 로컬 브랜치 삭제 |
git branch -d | bisect에 사용 중인 브랜치면 설명과 함께 실패 |
git add --resolved | 충돌이 해결된 파일만 스테이징 |
| 설정 파일 락 | 실패 시 재시도 — 여러 명령이 동시에 설정을 고칠 때의 짜증 해소 |
Corbet의 평가는 “견실한 릴리스지만, 의미 있는 작업 상당수를 미래로 미뤄둔 프로젝트의 징후가 보인다”는 것이다. 그래서 관심은 다음 릴리스로 넘어간다. 9월 초 Git 메인테이너 Junio Hamano는 다음 릴리스를 그동안 준비해 온 3.0으로 낼지, 아니면 2.x를 한 번 더 낼지 커뮤니티에 물었다.
3.0이 미뤄져 온 이유는 호환성 파괴가 한꺼번에 몰려 있기 때문이다.
| 변경 | 내용 | 상태 |
|---|---|---|
| SHA-256 기본값 | 객체 ID 해시를 SHA-1에서 SHA-256으로. 2.42(2023)부터 비실험 지원 | GitLab·Forgejo 지원, GitHub 미지원 |
| reftable | 레퍼런스를 .git/refs/ 파일 대신 바이너리 파일로 저장. 2.45에서 도입 | libgit2도 지원 추가 완료 |
| 소문자 객체 ID만 허용 | f00f00과 F00F00이 같은 ID로 취급되던 모호함 제거 | 3.0 전 추가 희망 |
| Rust 필수화 | Rust 컴파일러가 없는 플랫폼은 업그레이드 불가 | 3.0에서 전환 예정 |
reftable이 필요한 이유는 규모다. Android 저장소에는 레퍼런스가 80만 개를 넘는데, 이 정도면 ref 조회나 특정 커밋을 가리키는 ref 존재 확인이 비싼 연산이 된다. Git 사용자에게는 성능 외에 보이는 변화가 없지만, Git 저장소를 직접 읽는 다른 소프트웨어에는 문제가 될 수 있다. 우려 대상으로 지목된 libgit2는 Patrick Steinhardt가 reftable 지원을 추가했고 SHA-256은 8월에 기본 활성화했다고 밝혀 블로커에서 빠졌다.
남은 변수는 GitHub다. GitHub와 호환되지 않는 저장소를 만드는 Git을 릴리스하는 것은 부담스러운 선택이다. 다만 GitHub 직원이자 SHA-256 전환의 핵심 개발자인 brian m. carlson은 Hamano의 질문에 이 주제에 관한 소식이 곧 나올 것이라고 답하며, 다음 릴리스를 3.0으로 하는 편이 최선일 수 있다고 했다. 그는 남은 우려들이 릴리스를 붙잡을 이유는 아니라고 정리했다.
SHA-256(그리고 로컬 저장소를 다루는 소프트웨어라면 reftable)에 이미 상당히 앞서 있지 않은 쪽은 고려할 가치가 없다고 본다. 예를 들어 JGit과 Gitoxide는 최소 1년 전에 SHA-256이 Git 3.0에 온다고 통보받았다. (내가 통보했으니 안다.)
마찬가지로 아직 Rust를 지원하지 않는 플랫폼에 Rust 지원을 진지하게 추진하는 사람은 없는 것으로 아는데, 그것도 블로커가 되어서는 안 된다고 생각한다.
Hamano는 “이건 인기투표도 아니고 민주주의도 아니다”라며 결정을 보류했다. 그 사이 기사에는 업데이트가 붙었다. Kernel Recipes에서 Steinhardt가 합의된 릴리스 계획을 설명했는데, 2026년 12월 릴리스는 3.0 전환이 온다는 신호로 2.98로 명명하고, 2027년 4월에 장기지원(LTS) 릴리스인 2.99를 낸 뒤 같은 시점에 3.0을 함께 릴리스해 이후 모든 릴리스의 기반으로 삼는다는 것이다. SHA-1을 쓰고 reftable이 없는 저장소는 계속 완전히 지원된다.
gccrs로 커널을 컴파일하기까지
Pierre-Emmanuel Patry와 Arthur Cohen이 RustConf 2026에서 GCC의 Rust 프런트엔드 gccrs 현황을 발표했고, Patry는 다음 주 Kangrejos에서 커널 쪽 청중을 상대로 후속 발표를 했다. Cohen은 발표 제목 “Compiling the Linux kernel with gccrs”가 거짓말이라고 먼저 밝혔다. gccrs는 아직 커널을 컴파일하지 못한다. Patry의 표현으로는 현재 목표가 “커널을 잘못 컴파일하는 것”이다. 테스트하고 검증할 수 있는 바이너리를 내놓는 지점까지 가야 뭔가를 “컴파일한다”고 말할 수 있고, Rust 코드를 불평 없이 받아들이는 시점과 실제로 동작하는 커널이 나오는 시점 사이에는 거의 확실히 간격이 있다.
rustc가 이미 있는데 별도 구현이 필요한 이유는 GCC 쪽 생태계다. GCC는 rustc보다 많은 백엔드 아키텍처를 지원하고, 기존 프로젝트들이 의존하는 커스텀 컴파일러 플러그인을 지원한다. 커널에 Rust 코드가 들어온 지금, GCC만으로 커널 전체를 빌드할 수 있으면 좋다는 것이다.
목표는 커널에 있는 Rust 코드를 컴파일하는 것이고, 그 코드는 서로 의존하는 여러 크레이트로 나뉘어 있다.
| 크레이트 | 역할 | 난점 |
|---|---|---|
core | Rust 언어 기능이 동작하기 위한 최소한. for 루프가 쓰는 Iterator 트레이트가 여기 있다 | 약 85,000줄, 저수준 연산이 몰려 있어 “정말 복잡하다” |
alloc | 메모리 할당 | arbitrary self types 등을 쓰지만 커널 버전은 표준 라이브러리 버전보다 단순 |
stdarch | 아키텍처별 연산 | — |
pin_init | 이동 불가 구조체 생성 | — |
| 표준 라이브러리 | 커널은 링크하지 않지만, 절차적 매크로(procedural macro)가 링크할 수 있음 | 커널 크레이트 2개가 절차적 매크로를 사용해 결국 필요 |
처음에는 작은 Rust 코드 조각을 따로 컴파일해보는 방식이었는데 한계에 닿았고, 지금은 core를 먼저 되게 한 뒤 의존 그래프를 따라 alloc 쪽으로 올라가는 전략이다. 문제는 core에서 나오는 버그가 앞선 버그 뒤에 가려져 작업을 병렬화하기 어렵다는 점이다. 그래서 alloc에 필요한 부분만 담은 mock core를 만들어 병렬로 진행할 수 있게 했다.
Kangrejos에서 Miguel Ojeda는 표준 라이브러리가 준비될 때까지 임시로 rustc가 컴파일한 절차적 매크로를 쓸 수 있는지 물었다. Patry는 이론적으로는 가능할 것 같다면서도, 절차적 매크로와 그것이 생성하는 코드 사이에 이상한 비호환성을 들여와 생태계를 흔드는 것을 경계했다. Ojeda는 커널에서 표준 라이브러리를 쓰는 곳이 syn 크레이트 경유와 교체 가능해 보이는 BTreeSet 한 곳뿐이라고 확인해줬지만, Gary Guo는 절차적 매크로가 암묵적으로 쓰는 할당(allocation) 지원의 복잡도를 간과하고 있다고 지적했다. “할당이 되면 B-트리는 아마 공짜로 따라올 것”이라는 얘기다.
지난 3년간 두 사람이 매달린 작업은 이름 해석(name resolution)이다. 교과서식 컴파일러처럼 단순하게 만든 초기 구현이 근본적으로 잘못됐다는 게 드러났기 때문이다. Rust에는 네임스페이스가 여러 개(함수와 상수, 타입, 레이블, 라이프타임) 있고 해석이 그 사이를 넘나들어야 하며, 이름이 정의 전에 쓰일 수도 있다. 게다가 이름은 매크로가 정의할 수도 있고 그 매크로 자체가 이름 해석에 의존하므로, 이름 해석과 매크로 확장을 모든 이름이 발견될 때까지 반복하는 고정점(fix-point) 방식으로 번갈아 돌려야 한다. Cohen은 상사에게 3주면 된다고 했는데 거의 3년이 걸려 RustConf 직전에 끝났다.
고정점 반복은 같은 호출을 여러 번 하게 되므로 성능 문제로 이어졌다. 캐시를 넣기 전과 후의 차이가 크다.
| 컴파일러 | core 컴파일 시간 |
|---|---|
| gccrs (캐시 전) | 약 42분 |
| gccrs (호출 캐시 추가) | 약 3분 |
| rustc | 약 30초 |
“rustc만큼 빠르지는 않지만 작업할 수 있을 만큼은 빠르다”는 평가다. 인라인 어셈블리와 lang items도 대체로 동작하고, 이제는 개별 버그 하나하나가 core 컴파일을 막는 마지막 버그일 수 있는 단계다. 남은 알려진 문제로는 크레이트 메타데이터 직렬화 형식이 아직 추상 구문 트리(AST) 덤프라는 임시 해법이어서 크로스 크레이트 링킹을 제대로 하려면 정리해야 한다는 점, 그리고 Drop 트레이트 처리가 일반적인 경우만 지원하고 비선형 제어 흐름·부분 이동(partial move)·제네릭·임시값에서는 걸려 넘어진다는 점이 있다.
크레이트가 다 컴파일되면 다음 단계는 안정화된 최신 Rust를 따라잡는 일이다. gccrs는 그동안 움직이는 목표를 쫓지 않으려고 rustc 1.49와 그에 맞는 옛 커널 버전을 기준으로 삼아왔다. 언어 자체가 바뀐 기능 중 처리해야 할 것으로는 trait upcasting, 새 use<...> 문법, 트레이트의 return-position impl Trait 세 가지가 꼽혔다. 여기에 커널이 C-Rust 바인딩 생성에 쓰는 실험 기능 cfi_encoding이 있는데, GCC의 제어 흐름 완전성(CFI) 코드를 손봐야 해서 까다롭다. 관련 패치 시리즈는 2025년에 올라온 뒤 아직 머지되지 않았다.
io_uring의 스레드 신원 맞바꾸기
io_uring은 비동기 실행이 핵심이고, 애플리케이션은 명시적으로 요청하지 않는 한 블로킹하지 않는다는 보장을 믿고 쓴다. 문제는 커널의 많은 경로가 애초에 비동기 실행을 염두에 두고 설계되지 않았다는 점이다. fdatasync(), statx(), 일부 openat() 경로(O_NONBLOCK 플래그와 무관하게) 등이 그렇다.
현재 커널은 블로킹할 가능성이 있는 연산을 모두 별도 워커 스레드로 넘긴다. 제출 스레드는 계속 진행할 수 있고 워커는 필요하면 블로킹한다. 대신 대기 중인 워커를 깨우고 컨텍스트 스위치를 해야 하므로 공짜가 아니다. 실제로 블로킹한다면 이 비용이 묻히지만, 많은 경우 연산은 블로킹 없이 끝난다. 그러면 일어나지도 않은 블로킹을 피하려고 낸 비용이 요청 처리 비용의 상당 부분을 차지한다. 성능 때문에 io_uring을 쓰는 사람들에게는 아픈 지점이다.
Jens Axboe가 올린 RFC는 반대 방향을 택한다. 일단 제출 스레드에서 연산을 진행하고, 정말 블로킹하는 경우만 따로 처리하는 것이다. 블로킹을 감지하려면 스케줄러가 필요하다. task_struct의 flags에 PF_IO_HANDOFF 플래그를 새로 두고, 이 플래그가 켜진 스레드가 어떤 이유로든 블로킹하려 하면 스케줄러가 io_uring_task_sleeping()을 호출한다. 스케줄러에 후킹하면 커널 어디서 블로킹이 일어나도 io_uring이 알 수 있고, 해당 코드 경로를 일일이 고칠 필요가 없다.
알았다고 해서 되돌릴 수는 없다. 블로킹은 커널 거의 어디서나 일어날 수 있어서, 블로킹 지점까지 한 일을 되감고 워커 스레드에서 재시작하는 것은 현실적인 선택이 아니다. 그래서 Axboe의 해법은 “스레드 신원 핸드오프(thread identity handoff)”다.
| 스레드 | 교환 후 하는 일 |
|---|---|
| 워커 스레드 | 스레드 ID, 시그널 처리 설정 등 모든 면에서 원래 제출 스레드처럼 보이게 만든 뒤, 제출 링 처리를 이어가다 유저 공간으로 복귀한다 |
| 원래 제출 스레드 | 워커 스레드의 신원을 받아 평소처럼 블로킹하고, 깨어나면 연산을 끝까지 수행한 뒤 워커 풀로 돌아간다 |
io_uring_enter()에서 반환되는 스레드는 호출한 스레드와 task_struct가 다르지만 나머지는 (바라건대) 똑같아 보인다. 결과적으로 블로킹 가능한 연산을 제출 스레드에서 실행하고, 실제로 블로킹하지 않으면 거기서 전부 끝낼 수 있다. 워커를 끌어오는 비용은 정말 블로킹할 때만 낸다.
간단해 보이지만 지뢰가 많다. 두 스레드가 task_struct를 교환하기 전에 커널의 다른 어떤 곳도 그 구조체를 참조하고 있지 않음을 확실히 해야 한다. 그렇지 않으면 언젠가 잘못된 task_struct 참조로 무언가를 하게 되고, 이는 커널 CVE 흐름을 따라가려 애쓰는 사람들의 부담을 줄이는 데 전혀 도움이 되지 않는 결과다. 그래서 핸드오프를 막는 조건 목록이 thread_handoff_allowed()와 thread_handoff_compatible()에 길게 들어 있다.
ptrace()로 추적당하는 중(추적자가task_struct참조를 쥐고 있음), 또는 반대로 다른 태스크를 추적하는 중- perf 이벤트 사용, 커널에서 futex 소유권이 추적되는 경우
- 실시간 스케줄러로 실행 중, core scheduling 쿠키 보유,
vfork()수행 중 - 섀도 스택 사용 — Peter Zijlstra가 이 조건 때문에 대부분의 실제 시스템에서 기능을 못 쓰게 된다고 지적했고, Axboe는 섀도 스택도 신원과 함께 옮길 수 있을 것으로 본다
이 판정이 시리즈에서 가장 무섭고 깨지기 쉬운 부분이다. task_struct는 커널 전역에서 접근 가능하므로 참조가 생길 모든 가능성을 커버했는지 알기 어렵고, io_uring을 전혀 생각하지 않는 개발자가 앞으로 새 참조를 추가할 걱정은 그 다음 문제다.
대가는 크다. 커버 레터의 벤치마크에서 tmpfs 위 fsync() 테스트는 거의 700% 개선을 보였다. 다른 개선은 더 작고, 항상 블로킹하는 테스트 일부는 역행했다. 역행이 가장 심한 쪽은 큐 깊이가 깊을 때다. 각 연산을 즉시 워커 스레드로 밀면 병렬 처리가 되는데, 제출 스레드에서 블로킹 지점까지 순차로 처리하면 그 작업이 직렬화되기 때문이다. Axboe는 해결 아이디어가 있다면서도, 이런 연산을 하는 애플리케이션은 애초에 큐 깊이가 깊지 않은 편이라 추진할 가치가 있는지 모르겠다고 했다.
Axboe 본인도 조만간 머지할 생각은 없고, 접근 자체가 성립할 가능성이 있는지 가리는 데 관심이 있다. Gabriel Krisman Bertazi의 평이 분위기를 요약한다. “정말 멋지고, 아주 위험한 것 같다.”
LTP로 NetBSD의 compat_linux 테스트하기
NetBSD는 커널 수준 기능 compat_linux로 리눅스 바이너리를 오래 지원해왔지만 테스트 커버리지가 부족했다. GSoC 참가자 Henrique Brito는 Linux Test Project(LTP) 테스트 스위트를 NetBSD에서 빌드·실행할 수 있게 하는 작업을 택했고, 멘토 Stephen Borrill이 EuroBSDCon 2026에서 결과를 발표했다.
Borrill은 NetBSD 기반 씬 클라이언트와 서버를 만드는 회사를 운영한다. 씬 클라이언트 다수가 Citrix의 ICA 애플리케이션으로 가상 데스크톱에 접속해야 하는데 NetBSD 네이티브 버전이 없어 리눅스 버전을 compat_linux로 돌린다. 그런데 새 ICA 클라이언트가 ENOSYS로 실패했고, 이 일로 compat_linux에 관심을 갖게 됐다.
발표 제목에 처음 들어 있던 “리눅스 에뮬레이션”이라는 표현은 정확하지 않다는 게 Borrill의 설명이다. compat_linux가 켜지면 NetBSD는 리눅스 코드를 “성능 영향이 사실상 없는” 상태로 네이티브 실행한다. “우리가 하는 일은 시스템 콜이나 파일 접근 방식 같은 것들이 리눅스처럼 보이게 하는 작은 심(shim)뿐이다.”
| 항목 | 내용 |
|---|---|
| 시스템 콜 매핑 | 아키텍처별 /sys/compat/linux/arch/<ARCH>/syscalls.master에 정의 |
| 공유 라이브러리 | /emul/linux(32비트는 /emul/linux32) 섀도 루트에서 먼저 찾고 없으면 폴백 |
| 기본 활성화 | GENERIC 커널에는 빠져 있고 모듈로 제공 — 보안 때문에 “전부 모듈로 옮겼다” |
| 아키텍처 | x86·Arm의 32/64비트. FreeBSD·SunOS·Ultrix 바이너리 지원도 함께 있음 |
NetBSD에는 Kyua라는 자체 테스트 프레임워크가 있지만 compat_linux 커버리지가 넓지 않다. 그래서 NetBSD 테스트 스위트를 확장하는 대신 LTP를 NetBSD에서 빌드해 쓰는 쪽을 택했다. 시스템 콜 쪽만 봐도 376개 테스트 묶음에 약 1,300개 테스트가 있다. 크로스 컴파일 대신 compat_linux 아래에서 리눅스용 GCC로 빌드하는 방식을 골라, pkgsrc의 SUSE 15.5 호환 패키지를 쓰고 GCC 12용 리눅스 호환 패키지를 만들어 pkgsrc에 올렸다.
처음 실행했을 때 통과율은 높았지만 스킵이 너무 많았다. 원인은 버전이었다. NetBSD 10.1의 compat_linux는 자신을 2013년에 나온 Linux 3.11로 알리는데, SUSE 15.5 패키지는 5.14.21을 기대한다. 설정에서 커널 버전만 바꿀 수도 있었지만, 더 나은 해법으로 6.3.10을 알리는 NetBSD 11을 쓰기로 했다. 당시 미출시였지만 RC4가 있었고, 올해 GSoC 코딩 시작 두 달 뒤인 7월 30일에 정식 릴리스됐다.
Brito는 LTP 실행을 관리하는 compat_linux_test_project 스크립트를 만들었다. NetBSD가 지원하지 않는 Btrfs·XFS 대신 ext2/ext3/ext4/tmpfs로 테스트를 제한하고, compat_linux에는 커널이 없어 존재하지 않는 .config를 적절히 공급해 LTP가 미지원 서브시스템을 스킵하게 하며, 멈추거나 커널 패닉을 내는 것으로 알려진 테스트를 건너뛴다. 전체 실행은 약 25분이 걸리고, 특정 시스템 콜만 골라 돌릴 수도 있다.
$ compat_linux_test_project -s readv, writev, open, close
재실행 결과를 이전 결과나 프로젝트가 정의한 기본 베이스라인과 비교하는 옵션도 있어, 자기 장비의 결과가 알려진 상태와 어떻게 다른지 바로 볼 수 있다. 참고로 패키지를 정적 링크로 빌드해보니 동적 링크 시 약 80MB였던 것이 약 5.1GB가 됐다. Borrill은 “펍에서 빌드를 돌렸는데 마지막에 패키지를 tarball로 만드는 동안 한 파인트를 주문해서 다 마실 시간이 있었다”며 사실상 쓸 수 없다고 했다.
실패 유형은 다양했고, 그중 몇 가지가 흥미롭다.
| 사례 | 내용 | 대응 방향 |
|---|---|---|
lseek() | SEEK_DATA·SEEK_HOLE 미구현으로 테스트가 조기 종료, 이후 테스트가 실패로 집계되지 않았음 | 구현 필요 |
open() | O_TMPFILE·O_PATH 미지원으로 파일 열기 테스트 다수 실패 | NetBSD 커널에 구현해 compat_linux가 물려받게 하는 쪽 |
writev() | iovcnt = 0일 때 BSD는 POSIX대로 EINVAL, 리눅스는 0을 반환 | “버그 호환”을 위해 compat_linux에 2~3줄로 처리 |
setsockopt()·shmat() | LTP가 NetBSD에는 없는 리눅스 버그를 확인하는 테스트 | 무시할지 버그 호환으로 갈지 미정 |
copy_file_range() | 이전 GSoC에서 추가된 콜. off_in/off_out이 NULL이 아니면 커널 패닉 | 수정 완료, NetBSD에 커밋됨 |
| 네임스페이스 계열 | NetBSD는 리눅스 네임스페이스 관련 시스템 콜을 전혀 지원하지 않음 | “GSoC 프로젝트 범위 밖” |
다음 단계는 아키텍처 확장, 특히 Arm이다. 그러려면 pkgsrc의 SUSE 호환 패키지가 추가 아키텍처를 지원해야 하는데, Borrill은 아직 시간을 내지 못했고 집에 돌아가면 “라즈베리파이를 띄워서 해보겠다”고 했다. Brito는 자주 쓰이는 핵심 시스템 콜의 테스트 결과를 스프레드시트로 정리해뒀고, 어떤 콜이 왜 실패하는지까지 파악해둔 덕에 이제 “집어들 수 있는 작업 목록”이 생겼다. futex() 지원이 나아졌는지 묻는 질문에 Borrill은 아니라고 답했고, 리눅스 버전별 동작 차이를 compat_linux가 구분해 지원하는지는 모른다고 했다.
오픈소스 데스크톱을 현대화하자는 제안
Apple과 Google 등에서 오래 UI/UX를 해온 Scott Jenson이 KDE 연례 개발자 콘퍼런스 Akademy 2026에서 오픈소스 프로젝트들이 더 많이 실험해서 수십 년 묵은 “창, 아이콘, 메뉴, 포인터”(WIMP) 모델을 넘어서자고 설득했다. 그는 2005년 Google에 합류했을 때는 “우리는 악하지 않았고 옳은 일을 하려 했다”며 문화가 급격히 바뀐 뒤 회사를 떠났고, 지금은 Mastodon과 Home Assistant 일을 하며 “오픈소스에 좋은 UX 디자인을 조금 더 밀어넣으려” 한다고 소개했다.
그가 든 구체적 사례 하나가 창 간 드래그다. 맥에서는 마우스 버튼을 누를 때(mouse down) 항목이 선택되지만 창은 버튼을 뗄 때(mouse up) 올라온다. 그래서 배경 창의 파일을 다른 창으로 끌어다 놓기 쉽다. 리눅스 대부분은 mouse down 즉시 창을 올려서 이 동작을 방해한다. 2년 전 Mastodon에 이 얘기를 썼더니 어떤 KDE 개발자가 좋은 생각이라며 몇 시간 뒤에 구현했다. 발표 중 “그게 누구였는지 모르겠다”고 하자 객석에서 “천만에요”라는 목소리가 나왔다. 그는 이것이 오픈소스가 멋진 지점이라고 했다.
정작 하려던 말은 데스크톱 UX가 20년째 거의 변하지 않았다는 것이다. 1980~90년대에는 새 아이디어가 많았고 “그 다음엔 안정화됐고 별로 바뀐 게 없다”. 리눅스 UX는 Windows와 맥에서 가져온 것이 많고, 리눅스 커뮤니티는 “대체로” UX 연구와 테스트, “솔직히 말해 실수까지” 마이크로소프트와 애플에 맡겨왔다. GNOME의 사용자 연구나 KDE의 휴먼 인터페이스 가이드라인(HIG) 같은 예외는 있지만 상시적으로 리눅스 데스크톱 전체의 UX 연구를 하거나 그것에 돈을 대는 곳은 없다.
문제는 뒤를 따라갈 대상이 사라졌다는 점이다. 애플은 iPhone과 iPad에 집중하면서 데스크톱 UX와 하드웨어를 오래 방치했고, 다시 맥으로 눈을 돌린 뒤 내놓은 Liquid Glass 같은 것은 사용자에게 인기가 없었으며 추가되는 기능은 “기본적으로 iPhone에, 자기 생태계에 더 묶어두는” 성격이라고 봤다. 마이크로소프트는 OneDrive 강요, Windows Recall, “광고 범벅” 같은 “실수를 연달아” 하고 있다. “리눅스 커뮤니티 전체가 애플과 마이크로소프트가 위험을 다 감수해주기를 기다려왔는데, 그들은 더 이상 위험을 감수하지 않는다.”
그는 데스크톱 혁신이 멈췄다고 말할 때 돌아오는 반박을 세 가지로 정리했다.
| 반박 | 그의 답 |
|---|---|
| “모바일이 이겼다, 데스크톱은 낡았다” | 소비자 시장과 소셜 미디어는 가져갔지만 “생산성은 못 가져갔다”. 키보드와 큰 화면을 가진 데스크톱은 “조용히 훌륭하다” |
| “WIMP 모델로 할 수 있는 건 다 했다” | 동의하지 않음 — 할 일이 더 남아 있다 |
| “내 환경 건드리지 마라” | 이해한다. 전부 바꾸고 싶은 게 아니라 “새로운 것들로 부드럽게 성장”하고 싶다 |
UX를 “픽셀”로만 이해하는 것도 그가 지적하는 지점이다. 그는 UX를 스타일(여백·아이콘·색), 구조(앱 안에서 사용자가 이동하는 내비게이션 모델), 전략(대상 사용자와 우선순위 — “UX 디자이너가 팀 시간을 아껴주는 가장 빠른 방법은 ‘아니오’라고 말하도록 돕는 것”), 그리고 그가 “stuff”라고 부른 하부 기술의 제약이라는 층으로 나눴다. DOS용으로 만들면 “좋은 매킨토시 앱을 쓰지 않게 된다. 기술이 할 수 있는 것을 규정한다”는 것이다. 40년간 쌓인 데스크톱의 “역사적 잔재”도 여기 들어간다. 초기 매킨토시 화면은 높이가 342픽셀이었고 창이 많이 겹쳤는데, 그 뒤로 우리는 “창은 겹쳐야 한다고 그냥 가정했다”. 거대한 화면을 쓰는 지금은 기존 창 관리 모델이 잘 맞지 않고, 그래서 사람들이 타일링 창 관리자를 쓰는 이유를 이해한다고 했다.
Xerox PARC에서 첫 WIMP 인터페이스 설계를 이끈 Alan Kay의 “관점은 IQ 80점만큼의 가치가 있다”는 말을 빌려, 현재를 보고 과거를 잊지 말고 질문을 제대로 세우라는 세 단계를 제시했다. 과거 사례로는 2003년에 시연됐다가 2006년에 접힌 프로젝트와, EU 자금으로 진행된 시맨틱 데스크톱 연구 프로젝트 NEPOMUK을 들었다. NEPOMUK은 KDE 4에 들어가 “데스크톱과 웹, 다른 기기의 정보를 하나의 일관된 인터페이스로 결합”하려 했지만, 나중에 제거되고 기능 범위를 줄인 파일 인덱싱·검색 프레임워크 Baloo로 대체됐다. 그는 사람들이 이런 실패를 아이디어가 틀렸다는 증거로 받아들이는 것을 우려했다. “당시의 하드웨어와 시스템이 비전을 받쳐주지 못했다고 본다. 이 프로젝트들을 다시 생각할 때가 됐다.”
그래서 그가 던진 질문은 “오직 큰 모니터만을 위해 설계한다면 어떻게 될까”, “데스크톱이 시간에 걸친 사용자의 의도를 어떻게 포착할 수 있을까”였고, 거기서 나온 프로토타입 셋을 시연했다.
- 와이드스크린 우선 데스크톱 — 화면 중앙은 작업에 좋고 양옆은 “주변시에는 좋지만 작업에는 나쁘다”. 중앙 창에 초점을 두고 나머지는 Exposé 같은 타일링으로 배치해, 가상 데스크톱보다 나은 다수 창 관리 모델을 노린다. 음악 플레이어 창을 화면 끝 “stash 영역”으로 끌면 재생 버튼만 남은 위젯으로 변한다. 지금의 Wayland로도 가능할 것으로 봤다
- Obsidian Canvas를 참고한 클립보드 — 웹 브라우저나 다른 소스에서 이미지·텍스트·파일을 끌어다 문서별로 모아두고, 닫았다 다음 날 다시 와도 그대로 남아 있게 한다. 로컬 AI가 “호텔이 여러 개 모였네, 정리해드릴게요” 식으로 정리할 수도 있다
- 프라이버시를 지키는 데이터 수집 — 브라우저가 보여주는 방문 기록은 “별로 유용하지 않다”며, AI 없이 “단순한 수학만으로” 페이지 체류 시간 같은 주의 신호를 모아 어디에 시간을 썼는지 이야기로 보여준다
질문 시간에 나온 것은 Windows Recall이 겪은 프라이버시 문제를 어떻게 막겠냐는 것이었다. Jenson은 “흥미로운 정보”가 아니라 텔레메트리 데이터를 모으는 것이어서 공격자에게 매력이 크게 떨어진다고 답했다. 다만 문제를 가볍게 볼 생각은 없고, 먼저 프로토타입으로 아이디어가 좋은지 확인한 뒤 암호화나 보호 방법을 찾겠다고 했다. Recall의 가장 큰 문제는 “얼마나 멍청하게 보호했는지”였고 다른 사람들은 훨씬 잘할 수 있다고 본다는 것이다.
짧은 소식
- WordPress 미인증 RCE — 페이지 템플릿을 결정하는
get_page_template()함수에서 제한적인 조건 아래 미인증 공격자가 원격 코드를 실행할 수 있는 치명적 취약점이 발견됐다. 최신 브랜치 업데이트와 함께 4.7까지 백포트가 제공된다. WordPress 포크인 ClassicPress도 영향을 받지만 아직 보안 업데이트가 없다. - Radicle 네트워크 프로토콜 취약점 2건 — P2P 코드 협업 프로젝트 Radicle이 노드 간 프로토콜의 치명적 취약점 두 건을 공개했다. 프로토콜이 “기대된 기밀성을 제공하지 않아” 두 노드 사이 네트워크를 관찰할 수 있는 누구나 교환 데이터를 읽을 수 있고, 피어 인증이 깨져 Node ID를 위장해 권한 없는 비공개 저장소를 읽을 수 있다. 두 결함을 함께 쓰면 경로상 공격자가 양쪽 Node ID를 보고 그중 하나를 써서 저장소 전체를 가져올 수 있으며, 어떤 설정이나 허용 목록으로도 막히지 않는다. 보안 업데이트 전에 공개됐고, 하위 호환을 깨는 대규모 업데이트가 준비 중이다.
- 커널 7.3-rc4 — 9월 20일 릴리스. 리누스 토발즈는 “이제 다들 알지 않나, ‘크다, 어쩌고저쩌고'”라고 했다. 이번 릴리스는 개발자 2,720명이 올린 머지 제외 체인지셋 17,056건으로, 그중 649명이 첫 커널 기여자다. 9월 21일에는 7.2.7, 6.18.53, 6.12.111 안정 업데이트가 나왔다.
- GNOME 51 — 성능 개선 다수, Maps의 오프라인 데이터와 개선된 대중교통 정보, 파일 미리보기 인터페이스 개편이 포함됐다.
- systemd v262 — 작은 컨테이너용 단일 정적 링크 바이너리 빌드, Linux 6.17에 들어온 커널 coredump 소켓 프로토콜 지원, OpenSSL 4 지원이 추가됐다.
- Systemtap 5.6 —
--bpf런타임용 BPF LSM 훅과 XDP 패킷 처리 프로브, BTF 기반kernel.tracepoint프로브, 문장 단위 실행 추적, 새@enumname()연산자, dyninst 하드웨어 워치포인트, Linux 7.2 런타임/탭셋 호환 작업이 들어갔다. - Igalia 25주년 — 오픈소스 컨설팅 기업 Igalia가 업스트림 작업 25년을 기념하는 글을 냈다. WebKit, 모바일 브라우저 렌더링, 커널(CPU·GPU 스케줄링), 3D 그래픽 드라이버, Orca 스크린 리더, GStreamer 등 목록이 길다. 노동자 소유 협동조합인 이 회사는 “이건 자선이 아니다”라며, 고객이 받는 것은 영원히 들고 다녀야 할 패치가 아니라 업스트림에 들어가 계약이 끝난 뒤에도 동작하는 코드라고 설명했다.
이번 주 개발 인용문에서는 Tomas Vondra의 조언이 실용적이다. 패치에 설계 문제를 고치는 변경이 하나 더 필요한데 10분이면 되고 거의 기계적인 일이라서, 피드백을 빨리 받으려고 그 변경 없이 먼저 올리는 경우를 생각해보자는 것이다. 그러면 리뷰어 일부는 이미 하려던 그 변경을 지적하고(유용하지 않은 피드백이다), 다른 리뷰어들은 직접 고쳐버려서 리뷰어마다 10분씩 낭비된다. “다른 사람의 시간을 아낄 수 있다면 그렇게 하라. 당신에게는 10분이지만 여러 명이면 금방 쌓여서 ‘커뮤니티 시간’ 한 시간이 될 수 있다.”
행사는 프라하로 몰린다. 10월 2~4일 GNU Tools Cauldron, 3~4일 Linux Days, 5~7일 Linux Plumbers Conference, 6일 Yocto Project Developer Day와 Real-time Linux User Forum, 7~9일 Open Source Summit Europe과 Embedded Linux Conference Europe, 8일 Linux Security Summit Europe, 10~11일 GStreamer Conference, 13~15일 OpenSSL Conference가 이어진다. 그 앞으로는 9월 28~30일 토론토 X.Org Developers Conference, 30일~10월 1일 베를린 All Systems Go!가 있다. CFP 마감은 Open vSwitch and OVN 2026 Fall Conference가 9월 28일, OpenFest 2026과 Ubuntu Summit 26.10이 10월 1일, OpenALT가 10월 4일, OLF Conference가 10월 9일이다.
이번 주 핵심 요약
- Git 3.0은 SHA-256 기본값, reftable, Rust 필수화를 한 릴리스에 묶는다. 일정은 2026년 12월 2.98 → 2027년 4월 2.99(LTS)와 3.0 동시 릴리스로 정리됐으니, 당장 깨지는 일은 없지만 Git 저장소를 직접 파싱하는 사내 도구가 있다면 SHA-256과 reftable을 읽을 수 있는지 지금부터 확인해둘 것. GitHub의 SHA-256 지원 여부가 실질적인 전환 시점을 결정한다.
- gccrs는 “3주”로 예상한 이름 해석 재작성에 3년을 썼다. 캐시 하나로
core컴파일이 42분에서 3분이 된 것처럼 아직 성능 여유가 많이 남아 있고, rustc 1.49 기준이라 최신 Rust를 따라잡는 일도 남았다. GCC만으로 커널을 빌드하고 싶거나 rustc가 지원하지 않는 아키텍처를 쓴다면 의미 있는 진척이지만, 실제로 쓸 수 있게 되기까지는 아직 시간이 필요하다. - io_uring 신원 핸드오프는 tmpfs
fsync()에서 700% 개선을 보이지만, 핸드오프가 금지되는 조건 목록(ptrace, perf, 실시간 스케줄러, 섀도 스택 등)이 실제 배포 환경을 대부분 걸러낸다. 섀도 스택 문제가 해결되지 않으면 효과를 볼 수 있는 시스템이 많지 않다. 큐 깊이가 깊은 워크로드에서는 역행하므로, 기대할 대상은 짧은 메타데이터 연산을 얕은 큐로 쏟는 쪽이다. compat_linux사례에서 가져갈 것은 “스펙대로 맞는 동작”이 호환성 문제가 된다는 점이다.writev(iovcnt=0)에서 NetBSD는 POSIX대로EINVAL을 돌려주는데 리눅스는0을 준다. 리눅스 바이너리를 다른 커널에서 돌리려면 결국 리눅스의 실제 동작에 맞춰야 한다. 반대로 리눅스에만 의존하는 코드를 쓸 때도 스펙이 아니라 구현 동작에 기대고 있는지 생각해볼 만하다.- Jenson의 지적 중 실제로 쓸 수 있는 것은 “창 간 드래그” 같은 작은 상호작용 차이가 체감을 크게 바꾼다는 관찰이다. mouse down에 창을 올리느냐 mouse up에 올리느냐 같은 결정이 데이터 이동의 난이도를 가른다. 프로토타입 쪽은 아직 아이디어 단계이고, 특히 체류 시간 수집은 Recall 사례처럼 보호 설계가 먼저 나와야 평가할 수 있다.