기록 84편을 계약 에이전트로 다시 썼다. 기존 71편(kss 25 · virt 46)과, 계약에만 있고 안 쓰여 있던 새 글감 13편이다. 원장 84개를 열어 단계마다 스킬 영수증과 관문 종료 코드를 적었고 verify-pipeline-run.py 가 error 0 으로 닫는다. SSOT 결함 둘을 고쳤다. - kss 의 `약 58일` 이 반입 중 `약 59일` 로 바뀌어 있었다. 원 증거 파일이 「남은 일수: 88일 … 실제 갱신까지 약 58일」로 산수를 직접 적는다. D-4a 쪽 `약 59일` 은 강제 갱신 뒤(`VALID: 89 days`)라 맞는 값이라 그대로 뒀다. - virt §198 의 `11.6GB` 는 §178 의 원 측정 `Mem: 11648`(MiB)과 어긋나는데 원 가이드의 표기 그대로라 고치지 않고 쓰이는 자리에 대조를 적었다. 기록의 수치 오류 셋을 고쳤다 — CASE 요약의 「게스트 셋에 8240MB」(5120+3120 은 둘이다), k3s 편이 같은 것을 여섯·일곱·여덟로 세던 것, no-docker 편의 「셋을 더 든다」(§281 의 표는 네 행이고 디스크 행이 빠져 있었다). 계약을 셋 고쳤다. - kss 의 sourceRepository 리비전이 cdac9b8 이었는데 그 커밋에는 docs/guides/** 28개가 아예 없다. 9465582b 로 바꾸고, 반입한 바이트가 어느 커밋과도 같지 않다는 것을 측정값과 함께 적었다 — 반입은 커밋이 아니라 그 시점의 작업 트리에서 떠 온 것이다(kss 297/306 · virt 12/14 가 작업 트리와 같고, 200 커밋을 거슬러 전수 대조했을 때 가장 가까운 커밋도 28개가 어긋났다). - virt 계약이 「2026-09-11 재배분」이라고 적는데 SSOT 는 재배분 날짜를 적지 않고 재배분 뒤 값은 이미 2026-09-10 측정에 찍혀 있다. - kss 후보 대장이 지나친 절 아홉에 처분을 적었다(warn 9 → 0). 새 글감은 0건이고 넷은 앵커가 h3 슬러그의 접두가 아니라 중간 토막이라 검사기가 못 본 것이었다. style_profile.mjs 의 결함 둘을 고쳤다 — frontmatter 가 문장으로 세어져 (실측 398자짜리 「문장」 하나) 평균 길이를 기준 안으로 밀어 올리고 있었고, engPerSent 의 분자는 목록을 포함한 글에서, 분모는 목록을 걷어낸 글에서 세고 있었다(Question 기록에서 11.94 → 3.86). verify-pipeline.py 전 항목 PASS · error 0 · unittest 334건 OK. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.6 KiB
id, kind, slug, title, topic, topicName, project, status, studio, sourceRevision, source
| id | kind | slug | title | topic | topicName | project | status | studio | sourceRevision | source | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 274c5636-33f6-4c19-a54b-d2a96af31289 | REFERENCE | confirm-the-disk-backend-on-the-host | Guest 안에서 본 disk 로 backend 를 단정하지 않는다 | storage-virtualization | 스토리지 가상화 | virtualization | 초안 | https://hyeonworks.com/studio/documents/274c5636-33f6-4c19-a54b-d2a96af31289/edit | no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다 |
|
Guest 안에서 본 disk 로 backend 를 단정하지 않는다
백엔드는 게스트가 디스크로 쓰는 그 장치를 호스트 쪽에서 실제로 대 주는 것을 말한다. 게스트에 로그인해 lsblk 를 돌리면 /dev/vda 와 그 파티션이 나오고, 거기까지는 물리 머신과 같은 화면이다. 개념 문서는 그 이름이 호스트의 실제 SSD 를 뜻하지 않으며 아래에 qcow2 파일과 RAW 파일과 호스트 블록 장치 셋이 올 수 있다고 적었다. 이 기준은 용량과 성능과 영속성을 판단하기 전에 호스트 쪽에서 무엇에 붙어 있는지를 먼저 확정하게 한다.
관계
- /dev/vda 뒤에 있는 것 — qcow2 · RAW · Host block device 이 기준이 가르라고 하는 세 갈래를 그 글이 설명한다.
- Guest 의 write() 가 virtqueue 에 실리기까지 — VFS · Filesystem · Page Cache · Block Layer · virtio-blk 게스트가 본 그 디스크 이름이 어디에서 나왔는지를 그 글이 설명한다.
- 이 호스트의 /dev/vda 는 어떤 backend 에 붙어 있는가 이 기준의 첫 확인을 이 환경에서 실제로 돌리는 물음이다.
- 이 disk image 는 qcow2 인가 RAW 인가, 그리고 Guest 가 보는 크기와 Host 가 실제로 쓰는 크기는 얼마나 다른가 백엔드가 파일로 확정됐을 때 형식과 크기를 읽는 물음이다.
- disk image 는 최종적으로 어느 Host block device 위에 있는가 그 파일이 놓인 파일시스템과 블록 장치까지 잇는 물음이다.
- 지연 원인을 CPU 로 읽기 전에 storage 계층을 따로 잰다 그 기준의 호스트 쪽 관측은 여기서 확정한 백엔드를 전제한다.
목적
게스트 안의 이름을 호스트의 저장 구조로 읽으면 그 위에서 하는 판단이 모두 어긋난다. 개념 문서는 게스트 리눅스가 /dev/vda 를 하나의 블록 장치로 인식하지만 그것이 호스트의 실제 SSD 를 뜻하지는 않는다고 적었다. 같은 대상을 호스트 관점에서 보면 파일 하나이고 게스트 관점에서 보면 디스크이며, 둘 다 맞다.
무엇 위에서 재고 있는지가 정해지지 않으면 용량 판독과 성능 판독이 서로 다른 대상을 가리킨다. 게스트가 100 GB 를 본다는 사실과 호스트가 그만큼 쓰고 있다는 사실은 다른 이야기이고, 형식이 무엇인지에 따라 확인할 항목도 달라진다.
개념 문서가 실제 서버에서 확인하라고 적어 둔 물음 가운데 넷이 이 확정 위에서 돌아간다. 백엔드가 무엇인지, 형식이 무엇인지, 크기가 얼마나 벌어져 있는지, 그 아래가 어느 장치인지다. 넷마다 같은 절차를 되풀이해 적지 않고 한 편으로 두었으므로 각 물음이 여기를 가리킨다.
규칙
1. 게스트의 장치 이름을 호스트의 저장 장치로 옮겨 읽지 않는다
물리 머신에서는 /dev/sda 나 /dev/nvme0n1 이 보이고 virtio-blk 를 쓰는 가상 머신에서는 /dev/vda 나 /dev/vdb 가 보인다. 이름이 그렇게 갈릴 뿐 게스트 쪽 화면은 두 경우 모두 블록 장치 하나와 그 파티션으로 보인다. 게스트에서 얻은 이름은 게스트가 인식한 것까지 말해 주고 그 아래 구조는 말해 주지 않는다.
2. Target 과 Source 를 이어 붙인 뒤에 판독을 시작한다
게스트에서 lsblk 로 보이는 블록 장치와 파티션을 적고, 호스트에서 virsh domblklist <VM_NAME> 로 Target 과 Source 를 적는다. 개념 문서가 든 예시에서는 Target vda 에 Source /var/lib/libvirt/images/vm1.qcow2 가 붙어 있었다. 이 대응이 있어야 게스트의 /dev/vda 에서 virtio-blk 와 QEMU 를 지나 그 파일까지 이어진다. 그 경로는 개념 문서가 예시로 붙여 둔 이름이다. 두 명령을 이 호스트에서 돌린 출력은 아직 없다.
3. Source 가 파일인지 호스트 블록 장치인지 확정한다
개념 문서는 백엔드가 반드시 파일일 필요는 없다고 적고 게스트의 /dev/vda 아래에 호스트의 /dev/nvme0n1p3 이 오는 구성을 들었다. 파일이면 qemu-img info 에 그 경로를 주어 형식을 읽고, 호스트 블록 장치면 qcow2 쪽 확인 항목은 애초에 걸리지 않는다.
두 명령이 필요로 하는 것도 다르다. qemu-img info 는 이미지 파일만 만지는 도구라 가상 머신이 꺼져 있어도 돌고 도메인이 아예 없어도 돈다. Target 과 Source 를 잇는 virsh domblklist 는 도메인이 있어야 하므로, 이미지 파일만 손에 있는 상태에서 확정되는 것은 형식까지다.
4. 용량은 virtual size 와 실제 할당을 갈라 읽는다
qcow2 는 가상 디스크 크기와 실제 호스트 할당량이 다를 수 있다. 개념 문서가 든 그림은 게스트가 보는 공간 100 GB 에 호스트 실제 할당 3GB 였다. 게스트가 데이터를 기록하면서 실제 할당량이 1GB 에서 10GB 로, 다시 40GB 로 늘 수 있다는 예도 함께 보였다. qemu-img info 를 볼 때 virtual size 와 실제 allocation 을 구분해서 봐야 한다.
5. 파일이면 그 파일이 놓인 호스트 파일시스템과 블록 장치까지 적는다
백엔드가 qcow2 파일이면 QEMU 는 결국 호스트 리눅스에 파일 입출력을 요청한다. 그 요청은 Host Filesystem 과 Host Block Layer 와 NVMe Driver 를 지나 Physical NVMe 로 내려간다. 게스트의 스토리지 스택 아래에 호스트의 스토리지 스택이 한 번 더 있으므로, 어느 파일시스템과 어느 블록 장치 위에 있는지를 lsblk 로 함께 적는다.
적을 파일이 하나가 아닐 수 있다. qemu-img info 출력에 backing file 줄이 있으면 그 파일은 오버레이이고, 자기가 들고 있지 않은 클러스터를 읽을 때마다 바닥 파일을 읽는다. 바닥까지 같은 항목으로 적어야 그 게스트가 실제로 읽는 파일이 모두 덮인다.
적용 조건
- 가상 머신의 디스크 성능이나 용량이나 영속성을 판단하기 전
- 게스트 안에서 잰 스토리지 수치를 해석하기 전
- 저장 공간 계획을 세우거나 이미지를 옮기기 전
- 가상 머신 여러 대가 같은 물리 장치를 쓰는지 확인할 때
예외
- 백엔드가 호스트 블록 장치면 qcow2 쪽 확인은 걸리지 않는다. 가상 크기와 실제 할당량의 차이도, 매핑과 메타데이터 처리도 그 구성에는 없다.
- 백엔드를 확정해도 성능은 예측되지 않는다. 개념 문서는 RAW 는 무조건 빠르고 qcow2 는 무조건 느리다는 식으로 일반화하지 말라고 못박고, 실제 성능은 캐시 모드, 스토리지 백엔드, 부하 패턴, 큐 깊이, 스냅숏 체인, 그 아래 파일시스템, 물리 장치에 영향을 받는다고 적었다. 이 기준은 무엇 위에서 재고 있는지까지만 확정한다.
- 이 절차를 처음부터 끝까지 돌린 출력은 이 저장소에 없다. 네 번째 규칙의 qemu-img info 는 바닥 이미지 하나에만 돌렸고, virsh domblklist 와 게스트 lsblk 의 출력은 아직 없다. 나머지는 개념 문서가 서술한 확인 순서이고 이 호스트에서 나온 값이 아니다.
예시
- 게스트에서 보이는 것 : /dev/vda 와 그 파티션
- 호스트에서 이어 붙일 것 : Target 과 Source 의 대응
- Source 의 세 갈래 : qcow2 파일 · RAW 파일 · 호스트 블록 장치
- 용량 : virtual size 와 실제 allocation 을 따로 적는다
- 파일이면 더 볼 것 : 그 파일이 올라간 파일시스템과 블록 장치
- 이 호스트에서 돌린 qemu-img info : o — 바닥 이미지 하나뿐이다
- 이 호스트에서 돌린 virsh domblklist : x