refactor: 문서 개선 중
@@ -10,23 +10,23 @@
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **Boundary: Guest Userspace** (boundary): 게스트 사용자 공간. 저장장치를 직접 다루지 않는다. Evidence: L5807–L5809.
|
||||
- **Boundary: Guest Kernel** (boundary): 게스트 커널 공간. VM Boundary 위쪽 계층이 전부 여기 있다. Evidence: L5815–L5833.
|
||||
- **PostgreSQL / Keycloak** (service): 파일 연산을 요청하는 게스트 프로세스. Evidence: L5807–L5809, L5885–L5885, L5811–L5813.
|
||||
- **VFS** (service): 열린 파일이 어느 filesystem 구현에 속하는지 보고 연산을 넘기는 공통 계층. Evidence: L5815–L5817, L5905–L5905.
|
||||
- **ext4 / XFS** (service): 파일과 디렉터리를 block 공간에 배치하는 게스트 filesystem. Evidence: L5819–L5819.
|
||||
- **Guest Page Cache** (store): 게스트 RAM 에 있는 cache. write() 가 성공해도 데이터는 아직 여기까지만 확정된다. Evidence: L5821–L5821.
|
||||
- **Guest Block Layer** (service): 파일 세계의 요청을 block device 세계의 요청으로 바꾸는 계층. Evidence: L5825–L5825.
|
||||
- **/dev/vda** (device): 게스트 Linux 가 하나의 block device 로 인식하는 이름. Evidence: L5829–L5829, L5879–L5879.
|
||||
- **virtio-blk Frontend** (service): 그 가상 block device 를 제어하는 게스트 커널 driver. Evidence: L5831–L5831, L5789–L5789.
|
||||
- **virtqueue** (queue): 요청이 실리는 자리. 바로 아래가 VM Boundary 다. Evidence: L5833–L5835.
|
||||
- **Boundary: Guest Userspace** (boundary): 게스트 사용자 공간. 저장장치를 직접 다루지 않는다. Evidence: L5820–L5822.
|
||||
- **Boundary: Guest Kernel** (boundary): 게스트 커널 공간. VM Boundary 위쪽 계층이 전부 여기 있다. Evidence: L5828–L5846.
|
||||
- **PostgreSQL / Keycloak** (service): 파일 연산을 요청하는 게스트 프로세스. Evidence: L5820–L5822, L5898–L5898, L5824–L5826.
|
||||
- **VFS** (service): 열린 파일이 어느 filesystem 구현에 속하는지 보고 연산을 넘기는 공통 계층. Evidence: L5828–L5830, L5918–L5918.
|
||||
- **ext4 / XFS** (service): 파일과 디렉터리를 block 공간에 배치하는 게스트 filesystem. Evidence: L5832–L5832.
|
||||
- **Guest Page Cache** (store): 게스트 RAM 에 있는 cache. write() 가 성공해도 데이터는 아직 여기까지만 확정된다. Evidence: L5834–L5834.
|
||||
- **Guest Block Layer** (service): 파일 세계의 요청을 block device 세계의 요청으로 바꾸는 계층. Evidence: L5838–L5838.
|
||||
- **/dev/vda** (device): 게스트 Linux 가 하나의 block device 로 인식하는 이름. Evidence: L5842–L5842, L5892–L5892.
|
||||
- **virtio-blk Frontend** (service): 그 가상 block device 를 제어하는 게스트 커널 driver. Evidence: L5844–L5844, L5802–L5802.
|
||||
- **virtqueue** (queue): 요청이 실리는 자리. 바로 아래가 VM Boundary 다. Evidence: L5846–L5848.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **PostgreSQL / Keycloak → VFS:** data. Evidence: L5811–L5813, L5890–L5890.
|
||||
- **VFS → ext4 / XFS:** data. Evidence: L5817–L5819.
|
||||
- **ext4 / XFS → Guest Page Cache:** data. Evidence: L5819–L5821.
|
||||
- **Guest Page Cache → Guest Block Layer:** writeback. Evidence: L5823–L5825.
|
||||
- **Guest Block Layer → /dev/vda:** WRITE / FLUSH. Evidence: L5827–L5829.
|
||||
- **/dev/vda → virtio-blk Frontend:** data. Evidence: L5829–L5831.
|
||||
- **virtio-blk Frontend → virtqueue:** Virtio block request. Evidence: L5831–L5833.
|
||||
- **PostgreSQL / Keycloak → VFS:** data. Evidence: L5824–L5826, L5903–L5903.
|
||||
- **VFS → ext4 / XFS:** data. Evidence: L5830–L5832.
|
||||
- **ext4 / XFS → Guest Page Cache:** data. Evidence: L5832–L5834.
|
||||
- **Guest Page Cache → Guest Block Layer:** writeback. Evidence: L5836–L5838.
|
||||
- **Guest Block Layer → /dev/vda:** WRITE / FLUSH. Evidence: L5840–L5842.
|
||||
- **/dev/vda → virtio-blk Frontend:** data. Evidence: L5842–L5844.
|
||||
- **virtio-blk Frontend → virtqueue:** Virtio block request. Evidence: L5844–L5846.
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=TB, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
subgraph cluster_0 {
|
||||
label="Guest Userspace";
|
||||
style="rounded,dashed";
|
||||
color="#66788a";
|
||||
n0 [label="PostgreSQL / Keycloak", shape=box, style="rounded,filled"];
|
||||
}
|
||||
subgraph cluster_1 {
|
||||
label="Guest Kernel";
|
||||
style="rounded,dashed";
|
||||
color="#66788a";
|
||||
n1 [label="VFS", shape=box, style="rounded,filled"];
|
||||
n2 [label="ext4 / XFS", shape=box, style="rounded,filled"];
|
||||
n3 [label="Guest Page Cache", shape=box, style="rounded,filled"];
|
||||
n4 [label="Guest Block Layer", shape=box, style="rounded,filled"];
|
||||
n5 [label="/dev/vda", shape=box, style="rounded,filled"];
|
||||
n6 [label="virtio-blk Frontend", shape=box, style="rounded,filled"];
|
||||
n7 [label="virtqueue", shape=oval, style="rounded,filled"];
|
||||
}
|
||||
n0 -> n1 [label="", style=solid];
|
||||
n1 -> n2 [label="", style=solid];
|
||||
n2 -> n3 [label="", style=solid];
|
||||
n3 -> n4 [label="writeback", style=solid];
|
||||
n4 -> n5 [label="WRITE / FLUSH", style=solid];
|
||||
n5 -> n6 [label="", style=solid];
|
||||
n6 -> n7 [label="Virtio block request", style=solid];
|
||||
}
|
||||
@@ -1,73 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="guest-block-io-to-virtqueue" name="게스트의 write() 가 virtqueue 에 실리기까지">
|
||||
<mxGraphModel dx="680" dy="1360" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1360" math="0" shadow="0">
|
||||
<mxGraphModel dx="680" dy="2501" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="2501" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="g_guest-userspace" value="Guest Userspace" style="swimlane;html=1;rounded=1;startSize=30;horizontal=1;dashed=1;strokeWidth=1.5;fillColor=#f7f9fb;strokeColor=#66788a;fontStyle=1;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="40.0" y="35.0" width="241.0" height="160.0" as="geometry"/>
|
||||
<mxGeometry x="35.0" y="99.0" width="241.0" height="160.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="g_guest-kernel" value="Guest Kernel" style="swimlane;html=1;rounded=1;startSize=30;horizontal=1;dashed=1;strokeWidth=1.5;fillColor=#f7f9fb;strokeColor=#66788a;fontStyle=1;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="47.0" y="219.0" width="227.0" height="1096.0" as="geometry"/>
|
||||
<mxGeometry x="47.0" y="440.0" width="227.0" height="2016.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_app" value="PostgreSQL / Keycloak<br/>read / write<br/>fsync / sync" tooltip="파일 연산을 요청하는 게스트 프로세스. | Evidence: L5807-L5809, L5885-L5885, L5811-L5813" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="81.0" width="181.0" height="88.0" as="geometry"/>
|
||||
<mxCell id="n_app" value="PostgreSQL / Keycloak<br/>read / write<br/>fsync / sync" tooltip="파일 연산을 요청하는 게스트 프로세스. | Evidence: L5820-L5822, L5898-L5898, L5824-L5826" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="65.0" y="145.0" width="181.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_vfs" value="VFS" tooltip="열린 파일이 어느 filesystem 구현에 속하는지 보고 연산을 넘기는 공통 계층. | Evidence: L5815-L5817, L5905-L5905" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="85.5" y="265.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_vfs" value="VFS" tooltip="열린 파일이 어느 filesystem 구현에 속하는지 보고 연산을 넘기는 공통 계층. | Evidence: L5828-L5830, L5918-L5918" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="77.0" y="486.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_fs" value="ext4 / XFS" tooltip="파일과 디렉터리를 block 공간에 배치하는 게스트 filesystem. | Evidence: L5819-L5819" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="85.5" y="425.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_fs" value="ext4 / XFS" tooltip="파일과 디렉터리를 block 공간에 배치하는 게스트 filesystem. | Evidence: L5832-L5832" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="77.0" y="796.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_page-cache" value="Guest Page Cache" tooltip="게스트 RAM 에 있는 cache. write() 가 성공해도 데이터는 아직 여기까지만 확정된다. | Evidence: L5821-L5821" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="85.5" y="585.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_page-cache" value="Guest Page Cache" tooltip="게스트 RAM 에 있는 cache. write() 가 성공해도 데이터는 아직 여기까지만 확정된다. | Evidence: L5834-L5834" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="77.0" y="1106.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_block-layer" value="Guest Block Layer" tooltip="파일 세계의 요청을 block device 세계의 요청으로 바꾸는 계층. | Evidence: L5825-L5825" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="84.0" y="745.0" width="153.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_block-layer" value="Guest Block Layer" tooltip="파일 세계의 요청을 block device 세계의 요청으로 바꾸는 계층. | Evidence: L5838-L5838" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="77.0" y="1416.0" width="153.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_vda" value="/dev/vda" tooltip="게스트 Linux 가 하나의 block device 로 인식하는 이름. | Evidence: L5829-L5829, L5879-L5879" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="85.5" y="905.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_vda" value="/dev/vda" tooltip="게스트 Linux 가 하나의 block device 로 인식하는 이름. | Evidence: L5842-L5842, L5892-L5892" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="77.0" y="1729.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_virtio-blk" value="virtio-blk Frontend" tooltip="그 가상 block device 를 제어하는 게스트 커널 driver. | Evidence: L5831-L5831, L5789-L5789" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="77.0" y="1065.0" width="167.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_virtio-blk" value="virtio-blk Frontend" tooltip="그 가상 block device 를 제어하는 게스트 커널 driver. | Evidence: L5844-L5844, L5802-L5802" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="77.0" y="2039.0" width="167.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_virtqueue" value="virtqueue" tooltip="요청이 실리는 자리. 바로 아래가 VM Boundary 다. | Evidence: L5833-L5835" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="85.5" y="1225.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_virtqueue" value="virtqueue" tooltip="요청이 실리는 자리. 바로 아래가 VM Boundary 다. | Evidence: L5846-L5848" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="77.0" y="2366.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_app-to-vfs" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_app" target="n_vfs">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="184.5" y="217.0" as="offset"/>
|
||||
<mxPoint x="153.8" y="331.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_vfs-to-fs" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_vfs" target="n_fs">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="184.5" y="377.0" as="offset"/>
|
||||
<mxPoint x="176.0" y="673.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_fs-to-page-cache" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_fs" target="n_page-cache">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="184.5" y="537.0" as="offset"/>
|
||||
<mxPoint x="176.0" y="983.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_page-cache-to-block-layer" value="writeback" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_page-cache" target="n_block-layer">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="184.5" y="697.0" as="offset"/>
|
||||
<mxPoint x="152.8" y="1265.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_block-layer-to-vda" value="WRITE / FLUSH" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_block-layer" target="n_vda">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="184.5" y="857.0" as="offset"/>
|
||||
<mxPoint x="152.8" y="1576.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_vda-to-virtio-blk" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_vda" target="n_virtio-blk">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="184.5" y="1017.0" as="offset"/>
|
||||
<mxPoint x="156.2" y="1888.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_virtio-blk-to-virtqueue" value="Virtio block request" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtio-blk" target="n_virtqueue">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="184.5" y="1177.0" as="offset"/>
|
||||
<mxPoint x="156.2" y="2206.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
{
|
||||
"id": "group-guest-userspace",
|
||||
"type": "rectangle",
|
||||
"x": 40.0,
|
||||
"y": 35.0,
|
||||
"x": 35.0,
|
||||
"y": 99.0,
|
||||
"width": 241.0,
|
||||
"height": 160.0,
|
||||
"angle": 0,
|
||||
@@ -36,8 +36,8 @@
|
||||
{
|
||||
"id": "group-label-guest-userspace",
|
||||
"type": "text",
|
||||
"x": 56.0,
|
||||
"y": 41.0,
|
||||
"x": 51.0,
|
||||
"y": 105.0,
|
||||
"width": 135,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -76,9 +76,9 @@
|
||||
"id": "group-guest-kernel",
|
||||
"type": "rectangle",
|
||||
"x": 47.0,
|
||||
"y": 219.0,
|
||||
"y": 440.0,
|
||||
"width": 227.0,
|
||||
"height": 1096.0,
|
||||
"height": 2016.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#f8f9fa",
|
||||
@@ -106,7 +106,7 @@
|
||||
"id": "group-label-guest-kernel",
|
||||
"type": "text",
|
||||
"x": 63.0,
|
||||
"y": 225.0,
|
||||
"y": 446.0,
|
||||
"width": 108,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -144,10 +144,10 @@
|
||||
{
|
||||
"id": "edge-app-to-vfs",
|
||||
"type": "arrow",
|
||||
"x": 160.5,
|
||||
"y": 169.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 152.0,
|
||||
"y": 233.0,
|
||||
"width": 3.5,
|
||||
"height": 253.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -170,20 +170,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
3.5,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
3.5,
|
||||
126.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
126.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
253.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -204,10 +204,10 @@
|
||||
{
|
||||
"id": "edge-vfs-to-fs",
|
||||
"type": "arrow",
|
||||
"x": 160.5,
|
||||
"y": 329.0,
|
||||
"x": 152.0,
|
||||
"y": 550.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"height": 246.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -235,15 +235,15 @@
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
246.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -264,10 +264,10 @@
|
||||
{
|
||||
"id": "edge-fs-to-page-cache",
|
||||
"type": "arrow",
|
||||
"x": 160.5,
|
||||
"y": 489.0,
|
||||
"x": 152.0,
|
||||
"y": 860.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"height": 246.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -295,15 +295,15 @@
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
246.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -324,10 +324,10 @@
|
||||
{
|
||||
"id": "edge-page-cache-to-block-layer",
|
||||
"type": "arrow",
|
||||
"x": 160.5,
|
||||
"y": 649.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 152.0,
|
||||
"y": 1170.0,
|
||||
"width": 1.5,
|
||||
"height": 246.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -355,15 +355,15 @@
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
1.5,
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
1.5,
|
||||
246.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -384,8 +384,8 @@
|
||||
{
|
||||
"id": "edge-label-page-cache-to-block-layer",
|
||||
"type": "text",
|
||||
"x": 139.5,
|
||||
"y": 685.0,
|
||||
"x": 107.75,
|
||||
"y": 1253.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -423,10 +423,10 @@
|
||||
{
|
||||
"id": "edge-block-layer-to-vda",
|
||||
"type": "arrow",
|
||||
"x": 160.5,
|
||||
"y": 809.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 152.0,
|
||||
"y": 1480.0,
|
||||
"width": 1.5,
|
||||
"height": 249.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -449,20 +449,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
1.5,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
1.5,
|
||||
124.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
124.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
249.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -483,8 +483,8 @@
|
||||
{
|
||||
"id": "edge-label-block-layer-to-vda",
|
||||
"type": "text",
|
||||
"x": 132.5,
|
||||
"y": 845.0,
|
||||
"x": 100.75,
|
||||
"y": 1564.5,
|
||||
"width": 104,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -522,10 +522,10 @@
|
||||
{
|
||||
"id": "edge-vda-to-virtio-blk",
|
||||
"type": "arrow",
|
||||
"x": 160.5,
|
||||
"y": 969.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 152.0,
|
||||
"y": 1793.0,
|
||||
"width": 8.5,
|
||||
"height": 246.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -553,15 +553,15 @@
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
8.5,
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
8.5,
|
||||
246.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -582,10 +582,10 @@
|
||||
{
|
||||
"id": "edge-virtio-blk-to-virtqueue",
|
||||
"type": "arrow",
|
||||
"x": 160.5,
|
||||
"y": 1129.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 152.0,
|
||||
"y": 2103.0,
|
||||
"width": 8.5,
|
||||
"height": 263.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -608,20 +608,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
8.5,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
8.5,
|
||||
131.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
131.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
263.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -642,8 +642,8 @@
|
||||
{
|
||||
"id": "edge-label-virtio-blk-to-virtqueue",
|
||||
"type": "text",
|
||||
"x": 104.5,
|
||||
"y": 1165.0,
|
||||
"x": 76.25,
|
||||
"y": 2194.5,
|
||||
"width": 160,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -681,8 +681,8 @@
|
||||
{
|
||||
"id": "node-app",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 81.0,
|
||||
"x": 65.0,
|
||||
"y": 145.0,
|
||||
"width": 181.0,
|
||||
"height": 88.0,
|
||||
"angle": 0,
|
||||
@@ -711,8 +711,8 @@
|
||||
{
|
||||
"id": "node-label-app",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 91.0,
|
||||
"x": 75.0,
|
||||
"y": 155.0,
|
||||
"width": 161.0,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
@@ -750,8 +750,8 @@
|
||||
{
|
||||
"id": "node-vfs",
|
||||
"type": "rectangle",
|
||||
"x": 85.5,
|
||||
"y": 265.0,
|
||||
"x": 77.0,
|
||||
"y": 486.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -780,8 +780,8 @@
|
||||
{
|
||||
"id": "node-label-vfs",
|
||||
"type": "text",
|
||||
"x": 95.5,
|
||||
"y": 275.0,
|
||||
"x": 87.0,
|
||||
"y": 496.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -819,8 +819,8 @@
|
||||
{
|
||||
"id": "node-fs",
|
||||
"type": "rectangle",
|
||||
"x": 85.5,
|
||||
"y": 425.0,
|
||||
"x": 77.0,
|
||||
"y": 796.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -849,8 +849,8 @@
|
||||
{
|
||||
"id": "node-label-fs",
|
||||
"type": "text",
|
||||
"x": 95.5,
|
||||
"y": 435.0,
|
||||
"x": 87.0,
|
||||
"y": 806.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -888,8 +888,8 @@
|
||||
{
|
||||
"id": "node-page-cache",
|
||||
"type": "rectangle",
|
||||
"x": 85.5,
|
||||
"y": 585.0,
|
||||
"x": 77.0,
|
||||
"y": 1106.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -918,8 +918,8 @@
|
||||
{
|
||||
"id": "node-label-page-cache",
|
||||
"type": "text",
|
||||
"x": 95.5,
|
||||
"y": 595.0,
|
||||
"x": 87.0,
|
||||
"y": 1116.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -957,8 +957,8 @@
|
||||
{
|
||||
"id": "node-block-layer",
|
||||
"type": "rectangle",
|
||||
"x": 84.0,
|
||||
"y": 745.0,
|
||||
"x": 77.0,
|
||||
"y": 1416.0,
|
||||
"width": 153.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -987,8 +987,8 @@
|
||||
{
|
||||
"id": "node-label-block-layer",
|
||||
"type": "text",
|
||||
"x": 94.0,
|
||||
"y": 755.0,
|
||||
"x": 87.0,
|
||||
"y": 1426.0,
|
||||
"width": 133.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -1026,8 +1026,8 @@
|
||||
{
|
||||
"id": "node-vda",
|
||||
"type": "rectangle",
|
||||
"x": 85.5,
|
||||
"y": 905.0,
|
||||
"x": 77.0,
|
||||
"y": 1729.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1056,8 +1056,8 @@
|
||||
{
|
||||
"id": "node-label-vda",
|
||||
"type": "text",
|
||||
"x": 95.5,
|
||||
"y": 915.0,
|
||||
"x": 87.0,
|
||||
"y": 1739.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -1096,7 +1096,7 @@
|
||||
"id": "node-virtio-blk",
|
||||
"type": "rectangle",
|
||||
"x": 77.0,
|
||||
"y": 1065.0,
|
||||
"y": 2039.0,
|
||||
"width": 167.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1126,7 +1126,7 @@
|
||||
"id": "node-label-virtio-blk",
|
||||
"type": "text",
|
||||
"x": 87.0,
|
||||
"y": 1075.0,
|
||||
"y": 2049.0,
|
||||
"width": 147.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -1164,8 +1164,8 @@
|
||||
{
|
||||
"id": "node-virtqueue",
|
||||
"type": "rectangle",
|
||||
"x": 85.5,
|
||||
"y": 1225.0,
|
||||
"x": 77.0,
|
||||
"y": 2366.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1194,8 +1194,8 @@
|
||||
{
|
||||
"id": "node-label-virtqueue",
|
||||
"type": "text",
|
||||
"x": 95.5,
|
||||
"y": 1235.0,
|
||||
"x": 87.0,
|
||||
"y": 2376.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
|
||||
@@ -2,30 +2,41 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "guest-block-io-to-virtqueue",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "f41eedadcb8a6841cf981bea9e0a9e50a3df836df3cad528b4245a8d42e83915",
|
||||
"spec_sha256": "3c2c2a9e053d25d2277226299d48db325ea1d1af836f6bacf4c23ea3672c38f4",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "128. 전체 구조",
|
||||
"line": 5804
|
||||
"line": 5817
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"guest-block-io-to-virtqueue.svg",
|
||||
"guest-block-io-to-virtqueue.drawio",
|
||||
"guest-block-io-to-virtqueue.mmd",
|
||||
"guest-block-io-to-virtqueue.d2",
|
||||
"guest-block-io-to-virtqueue.dot",
|
||||
"guest-block-io-to-virtqueue.drawio",
|
||||
"guest-block-io-to-virtqueue.excalidraw",
|
||||
"guest-block-io-to-virtqueue.alt.md"
|
||||
],
|
||||
"lint_issue_count": 5,
|
||||
"lint_issue_count": 6,
|
||||
"assumption_count": 0,
|
||||
"assumptions_allowed": false,
|
||||
"composition_profile": "component-flow",
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "bdb3a2b7f3434ecf75e7dceca28611002766e42aabd96a9c8f521c29049466d9",
|
||||
"output_sha256": {
|
||||
"guest-block-io-to-virtqueue.svg": "5b7be8f61cc3a04b3b490184f7fe4b1cb2b6f62e48fb6d1dd116b4a8253fdc4a",
|
||||
"guest-block-io-to-virtqueue.mmd": "cf6e5a7a029e614d0e0f1f295663f9f733e9fbeeee002b16c545129257f7565d",
|
||||
"guest-block-io-to-virtqueue.d2": "92c96a0b016a4b2b8f3d03ca528574f3c75156588ff66610c47bd7b938181740",
|
||||
"guest-block-io-to-virtqueue.dot": "3f3605120200df313b5476cb4a3b2121aa5b8b3c05052e9e822403b5275f7077",
|
||||
"guest-block-io-to-virtqueue.drawio": "c649f476bed58b768777cbac3d773a5a3ba3d7cfa95a9bb3e598defb670c94b9",
|
||||
"guest-block-io-to-virtqueue.excalidraw": "84f0416128f3a3ac1ceca2a0a2e3cb5b0ebbb74bf522c47ae2c0b558c2fe24c8",
|
||||
"guest-block-io-to-virtqueue.alt.md": "0d45d2ce74a7e2245e046f950fa0bbdd4e037bdb095444e95f14e762d8f4bc53"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="1360" viewBox="0 0 680 1360" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="2501" viewBox="0 0 680 2501" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">게스트의 write() 가 virtqueue 에 실리기까지</title>
|
||||
<desc id="diagram-description">위에서 아래로 읽는다. 맨 위 Guest Userspace 구역에 PostgreSQL / Keycloak 이 있고 write() 가 게스트 커널로 내려간다. Guest Kernel 구역 안에서 VFS 가 먼저 받고, ext4 / XFS 가 파일을 block 공간에 배치하고, Guest Page Cache 가 그 내용을 dirty page 로 받아 두었다가 writeback 으로 Guest Block Layer 에 내려보낸다. Guest Block Layer 는 그것을 WRITE 나 FLUSH 요청으로 바꿔 /dev/vda 에 걸고, virtio-blk Frontend 가 그 요청을 virtqueue 에 게시한다. virtqueue 아래의 VM Boundary 부터는 QEMU 와 호스트 계층이라 이 그림에서 잘랐다. 완료가 같은 virtqueue 로 되돌아오는 역방향은 SSOT 의 다른 절이 대는 사실이라 이 그림에 넣지 않았고 본문 문단이 맡는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"guest-block-io-to-virtqueue","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"128. 전체 구조","line":5804}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"guest-block-io-to-virtqueue","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"128. 전체 구조","line":5817}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -49,59 +49,59 @@
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="680" height="1360" />
|
||||
<rect class="group-box" x="40.0" y="35.0" width="241.0" height="160.0" rx="8" />
|
||||
<rect class="group-label-bg" x="54.0" y="25.0" width="127.0" height="22" />
|
||||
<text class="group-label" x="64.0" y="40.0">Guest Userspace</text>
|
||||
<rect class="group-box" x="47.0" y="219.0" width="227.0" height="1096.0" rx="8" />
|
||||
<rect class="group-label-bg" x="61.0" y="209.0" width="106.0" height="22" />
|
||||
<text class="group-label" x="71.0" y="224.0">Guest Kernel</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="160.5,169.0 160.5,217.0 160.5,217.0 160.5,265.0" data-evidence="5811-5813,5890-5890" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="160.5,329.0 160.5,377.0 160.5,377.0 160.5,425.0" data-evidence="5817-5819" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="160.5,489.0 160.5,537.0 160.5,537.0 160.5,585.0" data-evidence="5819-5821" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="160.5,649.0 160.5,697.0 160.5,697.0 160.5,745.0" data-evidence="5823-5825" />
|
||||
<rect class="edge-label-bg" x="145.3" y="683.0" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="184.5" y="698.0">writeback</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="160.5,809.0 160.5,857.0 160.5,857.0 160.5,905.0" data-evidence="5827-5829" />
|
||||
<rect class="edge-label-bg" x="131.9" y="843.0" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="184.5" y="858.0">WRITE / FLUSH</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="160.5,969.0 160.5,1017.0 160.5,1017.0 160.5,1065.0" data-evidence="5829-5831" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="160.5,1129.0 160.5,1177.0 160.5,1177.0 160.5,1225.0" data-evidence="5831-5833" />
|
||||
<rect class="edge-label-bg" x="108.5" y="1163.0" width="152.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="184.5" y="1178.0">Virtio block request</text>
|
||||
<rect class="canvas" width="680" height="2501" />
|
||||
<rect class="group-box" x="35.0" y="99.0" width="241.0" height="160.0" rx="8" />
|
||||
<rect class="group-label-bg" x="49.0" y="89.0" width="127.0" height="22" />
|
||||
<text class="group-label" x="59.0" y="104.0">Guest Userspace</text>
|
||||
<rect class="group-box" x="47.0" y="440.0" width="227.0" height="2016.0" rx="8" />
|
||||
<rect class="group-label-bg" x="61.0" y="430.0" width="106.0" height="22" />
|
||||
<text class="group-label" x="71.0" y="445.0">Guest Kernel</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="155.5,233.0 155.5,359.5 152.0,359.5 152.0,486.0" data-evidence="5824-5826,5903-5903" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="152.0,550.0 152.0,673.0 152.0,673.0 152.0,796.0" data-evidence="5830-5832" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="152.0,860.0 152.0,983.0 152.0,983.0 152.0,1106.0" data-evidence="5832-5834" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="152.0,1170.0 152.0,1293.0 153.5,1293.0 153.5,1416.0" data-evidence="5836-5838" />
|
||||
<rect class="edge-label-bg" x="113.6" y="1251.0" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="152.8" y="1266.0">writeback</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="153.5,1480.0 153.5,1604.5 152.0,1604.5 152.0,1729.0" data-evidence="5840-5842" />
|
||||
<rect class="edge-label-bg" x="100.2" y="1562.5" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="152.8" y="1577.5">WRITE / FLUSH</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="152.0,1793.0 152.0,1916.0 160.5,1916.0 160.5,2039.0" data-evidence="5842-5844" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="160.5,2103.0 160.5,2234.5 152.0,2234.5 152.0,2366.0" data-evidence="5844-5846" />
|
||||
<rect class="edge-label-bg" x="80.2" y="2192.5" width="152.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="156.2" y="2207.5">Virtio block request</text>
|
||||
<g id="node-app">
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="5807-5809,5885-5885,5811-5813" x="70.0" y="81.0" width="181.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="108.0">PostgreSQL / Keycloak</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="129.0" x2="237.0" y2="129.0" />
|
||||
<text class="node-detail" x="86.0" y="146.0">read / write</text>
|
||||
<text class="node-detail" x="86.0" y="162.0">fsync / sync</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="5820-5822,5898-5898,5824-5826" x="65.0" y="145.0" width="181.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="155.5" y="172.0">PostgreSQL / Keycloak</text>
|
||||
<line class="node-detail-divider" x1="79.0" y1="193.0" x2="232.0" y2="193.0" />
|
||||
<text class="node-detail" x="81.0" y="210.0">read / write</text>
|
||||
<text class="node-detail" x="81.0" y="226.0">fsync / sync</text>
|
||||
</g>
|
||||
<g id="node-vfs">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5815-5817,5905-5905" x="85.5" y="265.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="295.0">VFS</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5828-5830,5918-5918" x="77.0" y="486.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="152.0" y="516.0">VFS</text>
|
||||
</g>
|
||||
<g id="node-fs">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5819-5819" x="85.5" y="425.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="455.0">ext4 / XFS</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5832-5832" x="77.0" y="796.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="152.0" y="826.0">ext4 / XFS</text>
|
||||
</g>
|
||||
<g id="node-page-cache">
|
||||
<rect class="node-shape kind-store emphasis-normal role-store" data-evidence="5821-5821" x="85.5" y="585.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="615.0">Guest Page Cache</text>
|
||||
<rect class="node-shape kind-store emphasis-normal role-store" data-evidence="5834-5834" x="77.0" y="1106.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="152.0" y="1136.0">Guest Page Cache</text>
|
||||
</g>
|
||||
<g id="node-block-layer">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5825-5825" x="84.0" y="745.0" width="153.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="775.0">Guest Block Layer</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5838-5838" x="77.0" y="1416.0" width="153.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="153.5" y="1446.0">Guest Block Layer</text>
|
||||
</g>
|
||||
<g id="node-vda">
|
||||
<rect class="node-shape kind-device emphasis-normal role-service" data-evidence="5829-5829,5879-5879" x="85.5" y="905.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="935.0">/dev/vda</text>
|
||||
<rect class="node-shape kind-device emphasis-normal role-service" data-evidence="5842-5842,5892-5892" x="77.0" y="1729.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="152.0" y="1759.0">/dev/vda</text>
|
||||
</g>
|
||||
<g id="node-virtio-blk">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5831-5831,5789-5789" x="77.0" y="1065.0" width="167.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="1095.0">virtio-blk Frontend</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5844-5844,5802-5802" x="77.0" y="2039.0" width="167.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="2069.0">virtio-blk Frontend</text>
|
||||
</g>
|
||||
<g id="node-virtqueue">
|
||||
<rect class="node-shape kind-queue emphasis-primary role-queue" data-evidence="5833-5835" x="85.5" y="1225.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="1255.0">virtqueue</text>
|
||||
<rect class="node-shape kind-queue emphasis-primary role-queue" data-evidence="5846-5848" x="77.0" y="2366.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="152.0" y="2396.0">virtqueue</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
@@ -10,21 +10,21 @@ Guest 구역 안에서 Keycloak · PostgreSQL 의 GVA 가 Guest TLB 와 Guest Pa
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **Boundary: Guest** (boundary): VM Boundary 안쪽. Guest Userspace 와 Guest Kernel 이 여기 있고 GVA 가 GPA 가 되는 첫 번째 변환이 여기서 끝난다. Evidence: L4034–L4053.
|
||||
- **Boundary: Host RAM** (boundary): 변환이 끝난 주소가 닿는 실제 서버 메모리. Evidence: L4069–L4079.
|
||||
- **Keycloak · PostgreSQL** (actor): Guest 안에서 메모리를 읽는 프로세스. 여기서 GVA 가 출발한다. Evidence: L4034–L4038.
|
||||
- **Guest TLB** (component): 최근 변환 결과를 담아 두는 CPU 안의 캐시. Evidence: L4043–L4045.
|
||||
- **Guest Page Table** (component): GVA 를 GPA 로 바꾸는 첫 번째 변환 표. Evidence: L4048–L4053.
|
||||
- **EPT** (component): VM Boundary 바깥에서 GPA 를 HPA 로 바꾸는 두 번째 변환 표. KVM 과 CPU 가 맡는다. Evidence: L4055–L4067.
|
||||
- **Host Physical Memory** (store): HPA 가 가리키는 실제 서버 메모리. Evidence: L4069–L4072.
|
||||
- **NUMA Node 0** (store): physical page 가 놓일 수 있는 한쪽 NUMA node. Evidence: L4073–L4075.
|
||||
- **NUMA Node 1** (store): physical page 가 놓일 수 있는 다른 쪽 NUMA node. Evidence: L4073–L4075.
|
||||
- **Boundary: Guest** (boundary): VM Boundary 안쪽. Guest Userspace 와 Guest Kernel 이 여기 있고 GVA 가 GPA 가 되는 첫 번째 변환이 여기서 끝난다. Evidence: L4047–L4066.
|
||||
- **Boundary: Host RAM** (boundary): 변환이 끝난 주소가 닿는 실제 서버 메모리. Evidence: L4082–L4092.
|
||||
- **Keycloak · PostgreSQL** (actor): Guest 안에서 메모리를 읽는 프로세스. 여기서 GVA 가 출발한다. Evidence: L4047–L4051.
|
||||
- **Guest TLB** (component): 최근 변환 결과를 담아 두는 CPU 안의 캐시. Evidence: L4056–L4058.
|
||||
- **Guest Page Table** (component): GVA 를 GPA 로 바꾸는 첫 번째 변환 표. Evidence: L4061–L4066.
|
||||
- **EPT** (component): VM Boundary 바깥에서 GPA 를 HPA 로 바꾸는 두 번째 변환 표. KVM 과 CPU 가 맡는다. Evidence: L4068–L4080.
|
||||
- **Host Physical Memory** (store): HPA 가 가리키는 실제 서버 메모리. Evidence: L4082–L4085.
|
||||
- **NUMA Node 0** (store): physical page 가 놓일 수 있는 한쪽 NUMA node. Evidence: L4086–L4088.
|
||||
- **NUMA Node 1** (store): physical page 가 놓일 수 있는 다른 쪽 NUMA node. Evidence: L4086–L4088.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **EPT → Host Physical Memory:** HPA. Evidence: L4062–L4071.
|
||||
- **Host Physical Memory → NUMA Node 0:** Physical Page. Evidence: L4071–L4075.
|
||||
- **Host Physical Memory → NUMA Node 1:** Physical Page. Evidence: L4071–L4075.
|
||||
- **Guest Page Table → EPT:** VM Boundary. Evidence: L4053–L4062.
|
||||
- **Keycloak · PostgreSQL → Guest TLB:** GVA. Evidence: L4036–L4043.
|
||||
- **Guest TLB → Guest Page Table:** TLB Miss. Evidence: L4043–L4048.
|
||||
- **EPT → Host Physical Memory:** HPA. Evidence: L4075–L4084.
|
||||
- **Host Physical Memory → NUMA Node 0:** Physical Page. Evidence: L4084–L4088.
|
||||
- **Host Physical Memory → NUMA Node 1:** Physical Page. Evidence: L4084–L4088.
|
||||
- **Guest Page Table → EPT:** VM Boundary. Evidence: L4066–L4075.
|
||||
- **Keycloak · PostgreSQL → Guest TLB:** GVA. Evidence: L4049–L4056.
|
||||
- **Guest TLB → Guest Page Table:** TLB Miss. Evidence: L4056–L4061.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Guest 의 메모리 접근 한 번은 이름이 두 번 바뀌며 네 계층을 지난다
|
||||
# Question: Guest 프로세스가 읽은 주소는 어느 계층을 차례로 지나 어떤 물리 메모리에 닿는가
|
||||
direction: down
|
||||
direction: right
|
||||
g0: "Guest" {
|
||||
n0: "Keycloak · PostgreSQL" {
|
||||
shape: person
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
subgraph cluster_0 {
|
||||
label="Guest";
|
||||
style="rounded,dashed";
|
||||
color="#66788a";
|
||||
n0 [label="Keycloak · PostgreSQL", shape=box, style="rounded,dashed,filled"];
|
||||
n1 [label="Guest TLB", shape=box, style="rounded,filled"];
|
||||
n2 [label="Guest Page Table", shape=box, style="rounded,filled"];
|
||||
}
|
||||
subgraph cluster_1 {
|
||||
label="Host RAM";
|
||||
style="rounded,dashed";
|
||||
color="#66788a";
|
||||
n4 [label="Host Physical Memory", shape=box, style="rounded,filled"];
|
||||
n5 [label="NUMA Node 0", shape=box, style="rounded,filled"];
|
||||
n6 [label="NUMA Node 1", shape=box, style="rounded,filled"];
|
||||
}
|
||||
n3 [label="EPT", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="GVA", style=solid];
|
||||
n1 -> n2 [label="TLB Miss", style=solid];
|
||||
n2 -> n3 [label="VM Boundary", style=solid];
|
||||
n3 -> n4 [label="HPA", style=solid];
|
||||
n4 -> n5 [label="Physical Page", style=solid];
|
||||
n4 -> n6 [label="Physical Page", style=solid];
|
||||
}
|
||||
@@ -1,65 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="guest-memory-address-translation-path" name="Guest 의 메모리 접근 한 번은 이름이 두 번 바뀌며 네 계층을 지난다">
|
||||
<mxGraphModel dx="680" dy="1078" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<mxGraphModel dx="1900" dy="352" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1900" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="g_guest" value="Guest" style="swimlane;html=1;rounded=1;startSize=30;horizontal=1;dashed=1;strokeWidth=1.5;fillColor=#f7f9fb;strokeColor=#66788a;fontStyle=1;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="129.5" y="35.0" width="241.0" height="494.0" as="geometry"/>
|
||||
<mxGeometry x="40.0" y="91.0" width="861.0" height="160.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="g_host-ram" value="Host RAM" style="swimlane;html=1;rounded=1;startSize=30;horizontal=1;dashed=1;strokeWidth=1.5;fillColor=#f7f9fb;strokeColor=#66788a;fontStyle=1;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="40.0" y="737.0" width="420.0" height="296.0" as="geometry"/>
|
||||
<mxGeometry x="1311.0" y="35.0" width="544.0" height="272.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_guest-process" value="Keycloak · PostgreSQL<br/>Guest Userspace" tooltip="Guest 안에서 메모리를 읽는 프로세스. 여기서 GVA 가 출발한다. | Evidence: L4034-L4038" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="159.5" y="81.0" width="181.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_guest-process" value="Keycloak · PostgreSQL<br/>Guest Userspace" tooltip="Guest 안에서 메모리를 읽는 프로세스. 여기서 GVA 가 출발한다. | Evidence: L4047-L4051" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="145.5" width="181.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_guest-tlb" value="Guest TLB<br/>Guest Kernel" tooltip="최근 변환 결과를 담아 두는 CPU 안의 캐시. | Evidence: L4043-L4045" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="175.0" y="248.0" width="150.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_guest-tlb" value="Guest TLB<br/>Guest Kernel" tooltip="최근 변환 결과를 담아 두는 CPU 안의 캐시. | Evidence: L4056-L4058" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="411.0" y="145.5" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_guest-page-table" value="Guest Page Table<br/>Guest Kernel<br/>GVA → GPA" tooltip="GVA 를 GPA 로 바꾸는 첫 번째 변환 표. | Evidence: L4048-L4053" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="175.0" y="415.0" width="150.0" height="88.0" as="geometry"/>
|
||||
<mxCell id="n_guest-page-table" value="Guest Page Table<br/>Guest Kernel<br/>GVA → GPA" tooltip="GVA 를 GPA 로 바꾸는 첫 번째 변환 표. | Evidence: L4061-L4066" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="721.0" y="137.0" width="150.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_ept" value="EPT<br/>KVM / CPU<br/>GPA → HPA" tooltip="VM Boundary 바깥에서 GPA 를 HPA 로 바꾸는 두 번째 변환 표. KVM 과 CPU 가 맡는다. | Evidence: L4055-L4067" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="175.0" y="599.0" width="150.0" height="88.0" as="geometry"/>
|
||||
<mxCell id="n_ept" value="EPT<br/>KVM / CPU<br/>GPA → HPA" tooltip="VM Boundary 바깥에서 GPA 를 HPA 로 바꾸는 두 번째 변환 표. KVM 과 CPU 가 맡는다. | Evidence: L4068-L4080" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="1031.0" y="137.0" width="150.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_host-physical-memory" value="Host Physical Memory" tooltip="HPA 가 가리키는 실제 서버 메모리. | Evidence: L4069-L4072" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="163.0" y="783.0" width="174.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_host-physical-memory" value="Host Physical Memory" tooltip="HPA 가 가리키는 실제 서버 메모리. | Evidence: L4082-L4085" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1341.0" y="149.0" width="174.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_numa-node-0" value="NUMA Node 0" tooltip="physical page 가 놓일 수 있는 한쪽 NUMA node. | Evidence: L4073-L4075" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="943.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_numa-node-0" value="NUMA Node 0" tooltip="physical page 가 놓일 수 있는 한쪽 NUMA node. | Evidence: L4086-L4088" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1675.0" y="81.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_numa-node-1" value="NUMA Node 1" tooltip="physical page 가 놓일 수 있는 다른 쪽 NUMA node. | Evidence: L4073-L4075" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="280.0" y="943.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_numa-node-1" value="NUMA Node 1" tooltip="physical page 가 놓일 수 있는 다른 쪽 NUMA node. | Evidence: L4086-L4088" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1675.0" y="217.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_ept-to-host-memory" value="HPA" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_ept" target="n_host-physical-memory">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="274.0" y="735.0" as="offset"/>
|
||||
<mxPoint x="1261.0" y="153.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_host-memory-to-node-0" value="Physical Page" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-physical-memory" target="n_numa-node-0">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="193.0" y="867.0" as="offset"/>
|
||||
<mxPoint x="1619.0" y="142.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_host-memory-to-node-1" value="Physical Page" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-physical-memory" target="n_numa-node-1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="307.0" y="867.0" as="offset"/>
|
||||
<mxPoint x="1619.0" y="219.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_page-table-to-ept" value="VM Boundary" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-page-table" target="n_ept">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="274.0" y="551.0" as="offset"/>
|
||||
<mxPoint x="951.0" y="153.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_process-to-tlb" value="GVA" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-process" target="n_guest-tlb">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="274.0" y="200.0" as="offset"/>
|
||||
<mxPoint x="331.0" y="153.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_tlb-to-page-table" value="TLB Miss" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-tlb" target="n_guest-page-table">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="274.0" y="367.0" as="offset"/>
|
||||
<mxPoint x="641.0" y="153.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
{
|
||||
"id": "group-guest",
|
||||
"type": "rectangle",
|
||||
"x": 129.5,
|
||||
"y": 35.0,
|
||||
"width": 241.0,
|
||||
"height": 494.0,
|
||||
"x": 40.0,
|
||||
"y": 91.0,
|
||||
"width": 861.0,
|
||||
"height": 160.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#f8f9fa",
|
||||
@@ -36,8 +36,8 @@
|
||||
{
|
||||
"id": "group-label-guest",
|
||||
"type": "text",
|
||||
"x": 145.5,
|
||||
"y": 41.0,
|
||||
"x": 56.0,
|
||||
"y": 97.0,
|
||||
"width": 100,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -75,10 +75,10 @@
|
||||
{
|
||||
"id": "group-host-ram",
|
||||
"type": "rectangle",
|
||||
"x": 40.0,
|
||||
"y": 737.0,
|
||||
"width": 420.0,
|
||||
"height": 296.0,
|
||||
"x": 1311.0,
|
||||
"y": 35.0,
|
||||
"width": 544.0,
|
||||
"height": 272.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#f8f9fa",
|
||||
@@ -105,8 +105,8 @@
|
||||
{
|
||||
"id": "group-label-host-ram",
|
||||
"type": "text",
|
||||
"x": 56.0,
|
||||
"y": 743.0,
|
||||
"x": 1327.0,
|
||||
"y": 41.0,
|
||||
"width": 100,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -144,10 +144,10 @@
|
||||
{
|
||||
"id": "edge-ept-to-host-memory",
|
||||
"type": "arrow",
|
||||
"x": 250.0,
|
||||
"y": 687.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 1181.0,
|
||||
"y": 181.0,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -174,16 +174,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -204,8 +204,8 @@
|
||||
{
|
||||
"id": "edge-label-ept-to-host-memory",
|
||||
"type": "text",
|
||||
"x": 229.0,
|
||||
"y": 723.0,
|
||||
"x": 1216.0,
|
||||
"y": 141.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -243,10 +243,10 @@
|
||||
{
|
||||
"id": "edge-host-memory-to-node-0",
|
||||
"type": "arrow",
|
||||
"x": 145.0,
|
||||
"y": 847.0,
|
||||
"width": 96.0,
|
||||
"height": 96.0,
|
||||
"x": 1515.0,
|
||||
"y": 113.0,
|
||||
"width": 160.0,
|
||||
"height": 59.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -269,20 +269,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
96.0,
|
||||
0.0,
|
||||
59.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
59.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
96.0,
|
||||
48.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -303,8 +303,8 @@
|
||||
{
|
||||
"id": "edge-label-host-memory-to-node-0",
|
||||
"type": "text",
|
||||
"x": 141.0,
|
||||
"y": 855.0,
|
||||
"x": 1567.0,
|
||||
"y": 130.5,
|
||||
"width": 104,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -342,10 +342,10 @@
|
||||
{
|
||||
"id": "edge-host-memory-to-node-1",
|
||||
"type": "arrow",
|
||||
"x": 259.0,
|
||||
"y": 847.0,
|
||||
"width": 96.0,
|
||||
"height": 96.0,
|
||||
"x": 1515.0,
|
||||
"y": 190.0,
|
||||
"width": 160.0,
|
||||
"height": 59.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -372,16 +372,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
96.0,
|
||||
48.0
|
||||
80.0,
|
||||
59.0
|
||||
],
|
||||
[
|
||||
96.0,
|
||||
96.0
|
||||
160.0,
|
||||
59.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -402,8 +402,8 @@
|
||||
{
|
||||
"id": "edge-label-host-memory-to-node-1",
|
||||
"type": "text",
|
||||
"x": 255.0,
|
||||
"y": 855.0,
|
||||
"x": 1567.0,
|
||||
"y": 207.5,
|
||||
"width": 104,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -441,10 +441,10 @@
|
||||
{
|
||||
"id": "edge-page-table-to-ept",
|
||||
"type": "arrow",
|
||||
"x": 250.0,
|
||||
"y": 503.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 871.0,
|
||||
"y": 181.0,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -471,16 +471,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -501,8 +501,8 @@
|
||||
{
|
||||
"id": "edge-label-page-table-to-ept",
|
||||
"type": "text",
|
||||
"x": 229.0,
|
||||
"y": 539.0,
|
||||
"x": 906.0,
|
||||
"y": 141.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -540,10 +540,10 @@
|
||||
{
|
||||
"id": "edge-process-to-tlb",
|
||||
"type": "arrow",
|
||||
"x": 250.0,
|
||||
"y": 152.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 251.0,
|
||||
"y": 181.0,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -570,16 +570,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -600,8 +600,8 @@
|
||||
{
|
||||
"id": "edge-label-process-to-tlb",
|
||||
"type": "text",
|
||||
"x": 229.0,
|
||||
"y": 188.0,
|
||||
"x": 286.0,
|
||||
"y": 141.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -639,10 +639,10 @@
|
||||
{
|
||||
"id": "edge-tlb-to-page-table",
|
||||
"type": "arrow",
|
||||
"x": 250.0,
|
||||
"y": 319.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 561.0,
|
||||
"y": 181.0,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -669,16 +669,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -699,8 +699,8 @@
|
||||
{
|
||||
"id": "edge-label-tlb-to-page-table",
|
||||
"type": "text",
|
||||
"x": 229.0,
|
||||
"y": 355.0,
|
||||
"x": 596.0,
|
||||
"y": 141.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -738,8 +738,8 @@
|
||||
{
|
||||
"id": "node-guest-process",
|
||||
"type": "rectangle",
|
||||
"x": 159.5,
|
||||
"y": 81.0,
|
||||
"x": 70.0,
|
||||
"y": 145.5,
|
||||
"width": 181.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -768,8 +768,8 @@
|
||||
{
|
||||
"id": "node-label-guest-process",
|
||||
"type": "text",
|
||||
"x": 169.5,
|
||||
"y": 91.0,
|
||||
"x": 80.0,
|
||||
"y": 155.5,
|
||||
"width": 161.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -807,8 +807,8 @@
|
||||
{
|
||||
"id": "node-guest-tlb",
|
||||
"type": "rectangle",
|
||||
"x": 175.0,
|
||||
"y": 248.0,
|
||||
"x": 411.0,
|
||||
"y": 145.5,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -837,8 +837,8 @@
|
||||
{
|
||||
"id": "node-label-guest-tlb",
|
||||
"type": "text",
|
||||
"x": 185.0,
|
||||
"y": 258.0,
|
||||
"x": 421.0,
|
||||
"y": 155.5,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -876,8 +876,8 @@
|
||||
{
|
||||
"id": "node-guest-page-table",
|
||||
"type": "rectangle",
|
||||
"x": 175.0,
|
||||
"y": 415.0,
|
||||
"x": 721.0,
|
||||
"y": 137.0,
|
||||
"width": 150.0,
|
||||
"height": 88.0,
|
||||
"angle": 0,
|
||||
@@ -906,8 +906,8 @@
|
||||
{
|
||||
"id": "node-label-guest-page-table",
|
||||
"type": "text",
|
||||
"x": 185.0,
|
||||
"y": 425.0,
|
||||
"x": 731.0,
|
||||
"y": 147.0,
|
||||
"width": 130.0,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
@@ -945,8 +945,8 @@
|
||||
{
|
||||
"id": "node-ept",
|
||||
"type": "rectangle",
|
||||
"x": 175.0,
|
||||
"y": 599.0,
|
||||
"x": 1031.0,
|
||||
"y": 137.0,
|
||||
"width": 150.0,
|
||||
"height": 88.0,
|
||||
"angle": 0,
|
||||
@@ -975,8 +975,8 @@
|
||||
{
|
||||
"id": "node-label-ept",
|
||||
"type": "text",
|
||||
"x": 185.0,
|
||||
"y": 609.0,
|
||||
"x": 1041.0,
|
||||
"y": 147.0,
|
||||
"width": 130.0,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
@@ -1014,8 +1014,8 @@
|
||||
{
|
||||
"id": "node-host-physical-memory",
|
||||
"type": "rectangle",
|
||||
"x": 163.0,
|
||||
"y": 783.0,
|
||||
"x": 1341.0,
|
||||
"y": 149.0,
|
||||
"width": 174.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1044,8 +1044,8 @@
|
||||
{
|
||||
"id": "node-label-host-physical-memory",
|
||||
"type": "text",
|
||||
"x": 173.0,
|
||||
"y": 793.0,
|
||||
"x": 1351.0,
|
||||
"y": 159.0,
|
||||
"width": 154.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -1083,8 +1083,8 @@
|
||||
{
|
||||
"id": "node-numa-node-0",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 943.0,
|
||||
"x": 1675.0,
|
||||
"y": 81.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1113,8 +1113,8 @@
|
||||
{
|
||||
"id": "node-label-numa-node-0",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 953.0,
|
||||
"x": 1685.0,
|
||||
"y": 91.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -1152,8 +1152,8 @@
|
||||
{
|
||||
"id": "node-numa-node-1",
|
||||
"type": "rectangle",
|
||||
"x": 280.0,
|
||||
"y": 943.0,
|
||||
"x": 1675.0,
|
||||
"y": 217.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1182,8 +1182,8 @@
|
||||
{
|
||||
"id": "node-label-numa-node-1",
|
||||
"type": "text",
|
||||
"x": 290.0,
|
||||
"y": 953.0,
|
||||
"x": 1685.0,
|
||||
"y": 227.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
|
||||
@@ -2,30 +2,41 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "guest-memory-address-translation-path",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "9db86cb8c5f81b1c5886877e1efd3ae4d4174d839fb29cffd5f8ae102508f2f3",
|
||||
"spec_sha256": "e30f27d5ec8b8a67d37f29129f6d6988f5713e779480a2be0ae5417d8d3c143b",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "87. 최종 기준 그림",
|
||||
"line": 4029
|
||||
"line": 4042
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"guest-memory-address-translation-path.svg",
|
||||
"guest-memory-address-translation-path.drawio",
|
||||
"guest-memory-address-translation-path.mmd",
|
||||
"guest-memory-address-translation-path.d2",
|
||||
"guest-memory-address-translation-path.dot",
|
||||
"guest-memory-address-translation-path.drawio",
|
||||
"guest-memory-address-translation-path.excalidraw",
|
||||
"guest-memory-address-translation-path.alt.md"
|
||||
],
|
||||
"lint_issue_count": 0,
|
||||
"lint_issue_count": 2,
|
||||
"assumption_count": 0,
|
||||
"assumptions_allowed": false,
|
||||
"composition_profile": "component-flow",
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "f61398e1b5a1282f1904e0674b0bc1ecf6eccea307053bd176c40eff3580d445",
|
||||
"output_sha256": {
|
||||
"guest-memory-address-translation-path.svg": "713f7a4c829230fb80d915946f08f7af1b190336ad8b27222885f8e010099c35",
|
||||
"guest-memory-address-translation-path.mmd": "84e22ae6bfaf94daaf62c61270b00aba3160c87a6084b9033a77adac7e3efc90",
|
||||
"guest-memory-address-translation-path.d2": "060efab06f41aa65df54cb1f19ad2fb0a9e05c4fadfb896cfc6cac5a260571e2",
|
||||
"guest-memory-address-translation-path.dot": "e3e795e40a234ff708981b04c15d4924eaa8cd71779b81c24633b52bfecd9ba0",
|
||||
"guest-memory-address-translation-path.drawio": "584d77a986cf771141d4246570b52f4590a79e840831ad2924585494ecd2f5b6",
|
||||
"guest-memory-address-translation-path.excalidraw": "dcc857856e9a2cf2abde5812668c1987710f8655230a4a8e8299ffa74298a6ff",
|
||||
"guest-memory-address-translation-path.alt.md": "ea2406106c239086672848f73b69658275fff87d34399e9837f570173c0d7a26"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%% Guest 의 메모리 접근 한 번은 이름이 두 번 바뀌며 네 계층을 지난다
|
||||
%% question: Guest 프로세스가 읽은 주소는 어느 계층을 차례로 지나 어떤 물리 메모리에 닿는가
|
||||
flowchart TB
|
||||
flowchart LR
|
||||
subgraph g_guest["Guest"]
|
||||
n0(["Keycloak · PostgreSQL"])
|
||||
n1["Guest TLB"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="1078" viewBox="0 0 680 1078" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1900" height="352" viewBox="0 0 1900 352" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">Guest 의 메모리 접근 한 번은 이름이 두 번 바뀌며 네 계층을 지난다</title>
|
||||
<desc id="diagram-description">위에서 아래로 읽는다. 맨 위 Guest 구역 안에 Keycloak · PostgreSQL 이 있고 그 접근은 GVA 로 Guest TLB 에 들어간다. TLB 에 변환이 없으면 TLB Miss 로 Guest Page Table 을 조회하고 거기서 GVA 가 GPA 가 된다. 그 GPA 는 VM Boundary 를 넘어 Guest 구역 밖의 EPT 로 가고 EPT 가 GPA 를 HPA 로 바꾼다. HPA 는 Host RAM 구역의 Host Physical Memory 에 닿고, 그 physical page 는 맨 아래에서 NUMA Node 0 또는 NUMA Node 1 가운데 한쪽에 놓인다. 상자 안 작은 글씨는 그 단계가 어느 계층인지와 무엇을 무엇으로 바꾸는지를 적은 것이다. 어느 단계에서 접근이 완료되지 못할 때 무엇이 일어나는지와 QEMU 가 이 경로를 어떻게 준비하는지는 본문의 문단과 표가 맡는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"guest-memory-address-translation-path","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"87. 최종 기준 그림","line":4029}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"guest-memory-address-translation-path","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"87. 최종 기준 그림","line":4042}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -49,67 +49,67 @@
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="680" height="1078" />
|
||||
<rect class="group-box" x="129.5" y="35.0" width="241.0" height="494.0" rx="8" />
|
||||
<rect class="group-label-bg" x="143.5" y="25.0" width="90.0" height="22" />
|
||||
<text class="group-label" x="153.5" y="40.0">Guest</text>
|
||||
<rect class="group-box" x="40.0" y="737.0" width="420.0" height="296.0" rx="8" />
|
||||
<rect class="group-label-bg" x="54.0" y="727.0" width="90.0" height="22" />
|
||||
<text class="group-label" x="64.0" y="742.0">Host RAM</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="250.0,687.0 250.0,735.0 250.0,735.0 250.0,783.0" data-evidence="4062-4071" />
|
||||
<rect class="edge-label-bg" x="252.0" y="721.0" width="44.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="274.0" y="736.0">HPA</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="241.0,847.0 241.0,895.0 145.0,895.0 145.0,943.0" data-evidence="4071-4075" />
|
||||
<rect class="edge-label-bg" x="140.4" y="853.0" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="193.0" y="868.0">Physical Page</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="259.0,847.0 259.0,895.0 355.0,895.0 355.0,943.0" data-evidence="4071-4075" />
|
||||
<rect class="edge-label-bg" x="254.4" y="853.0" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="307.0" y="868.0">Physical Page</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="250.0,503.0 250.0,551.0 250.0,551.0 250.0,599.0" data-evidence="4053-4062" />
|
||||
<rect class="edge-label-bg" x="228.2" y="537.0" width="91.7" height="22" rx="3" />
|
||||
<text class="edge-label" x="274.0" y="552.0">VM Boundary</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="250.0,152.0 250.0,200.0 250.0,200.0 250.0,248.0" data-evidence="4036-4043" />
|
||||
<rect class="edge-label-bg" x="252.0" y="186.0" width="44.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="274.0" y="201.0">GVA</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="250.0,319.0 250.0,367.0 250.0,367.0 250.0,415.0" data-evidence="4043-4048" />
|
||||
<rect class="edge-label-bg" x="238.2" y="353.0" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="274.0" y="368.0">TLB Miss</text>
|
||||
<rect class="canvas" width="1900" height="352" />
|
||||
<rect class="group-box" x="40.0" y="91.0" width="861.0" height="160.0" rx="8" />
|
||||
<rect class="group-label-bg" x="54.0" y="81.0" width="90.0" height="22" />
|
||||
<text class="group-label" x="64.0" y="96.0">Guest</text>
|
||||
<rect class="group-box" x="1311.0" y="35.0" width="544.0" height="272.0" rx="8" />
|
||||
<rect class="group-label-bg" x="1325.0" y="25.0" width="90.0" height="22" />
|
||||
<text class="group-label" x="1335.0" y="40.0">Host RAM</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="1181.0,181.0 1261.0,181.0 1261.0,181.0 1341.0,181.0" data-evidence="4075-4084" />
|
||||
<rect class="edge-label-bg" x="1239.0" y="139.0" width="44.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="1261.0" y="154.0">HPA</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="1515.0,172.0 1595.0,172.0 1595.0,113.0 1675.0,113.0" data-evidence="4084-4088" />
|
||||
<rect class="edge-label-bg" x="1566.5" y="128.5" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="1619.0" y="143.5">Physical Page</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="1515.0,190.0 1595.0,190.0 1595.0,249.0 1675.0,249.0" data-evidence="4084-4088" />
|
||||
<rect class="edge-label-bg" x="1566.5" y="205.5" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="1619.0" y="220.5">Physical Page</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="871.0,181.0 951.0,181.0 951.0,181.0 1031.0,181.0" data-evidence="4066-4075" />
|
||||
<rect class="edge-label-bg" x="905.1" y="139.0" width="91.7" height="22" rx="3" />
|
||||
<text class="edge-label" x="951.0" y="154.0">VM Boundary</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="251.0,181.0 331.0,181.0 331.0,181.0 411.0,181.0" data-evidence="4049-4056" />
|
||||
<rect class="edge-label-bg" x="309.0" y="139.0" width="44.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="331.0" y="154.0">GVA</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="561.0,181.0 641.0,181.0 641.0,181.0 721.0,181.0" data-evidence="4056-4061" />
|
||||
<rect class="edge-label-bg" x="605.2" y="139.0" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="641.0" y="154.0">TLB Miss</text>
|
||||
<g id="node-guest-process">
|
||||
<rect class="node-shape kind-actor emphasis-normal role-source" data-evidence="4034-4038" x="159.5" y="81.0" width="181.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="250.0" y="108.0">Keycloak · PostgreSQL</text>
|
||||
<line class="node-detail-divider" x1="173.5" y1="129.0" x2="326.5" y2="129.0" />
|
||||
<text class="node-detail" x="175.5" y="146.0">Guest Userspace</text>
|
||||
<rect class="node-shape kind-actor emphasis-normal role-source" data-evidence="4047-4051" x="70.0" y="145.5" width="181.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="172.5">Keycloak · PostgreSQL</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="193.5" x2="237.0" y2="193.5" />
|
||||
<text class="node-detail" x="86.0" y="210.5">Guest Userspace</text>
|
||||
</g>
|
||||
<g id="node-guest-tlb">
|
||||
<rect class="node-shape kind-component emphasis-normal role-store" data-evidence="4043-4045" x="175.0" y="248.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="250.0" y="275.0">Guest TLB</text>
|
||||
<line class="node-detail-divider" x1="189.0" y1="296.0" x2="311.0" y2="296.0" />
|
||||
<text class="node-detail" x="191.0" y="313.0">Guest Kernel</text>
|
||||
<rect class="node-shape kind-component emphasis-normal role-store" data-evidence="4056-4058" x="411.0" y="145.5" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="486.0" y="172.5">Guest TLB</text>
|
||||
<line class="node-detail-divider" x1="425.0" y1="193.5" x2="547.0" y2="193.5" />
|
||||
<text class="node-detail" x="427.0" y="210.5">Guest Kernel</text>
|
||||
</g>
|
||||
<g id="node-guest-page-table">
|
||||
<rect class="node-shape kind-component emphasis-normal role-service" data-evidence="4048-4053" x="175.0" y="415.0" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="250.0" y="442.0">Guest Page Table</text>
|
||||
<line class="node-detail-divider" x1="189.0" y1="463.0" x2="311.0" y2="463.0" />
|
||||
<text class="node-detail" x="191.0" y="480.0">Guest Kernel</text>
|
||||
<text class="node-detail" x="191.0" y="496.0">GVA → GPA</text>
|
||||
<rect class="node-shape kind-component emphasis-normal role-service" data-evidence="4061-4066" x="721.0" y="137.0" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="796.0" y="164.0">Guest Page Table</text>
|
||||
<line class="node-detail-divider" x1="735.0" y1="185.0" x2="857.0" y2="185.0" />
|
||||
<text class="node-detail" x="737.0" y="202.0">Guest Kernel</text>
|
||||
<text class="node-detail" x="737.0" y="218.0">GVA → GPA</text>
|
||||
</g>
|
||||
<g id="node-ept">
|
||||
<rect class="node-shape kind-component emphasis-primary role-service" data-evidence="4055-4067" x="175.0" y="599.0" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="250.0" y="626.0">EPT</text>
|
||||
<line class="node-detail-divider" x1="189.0" y1="647.0" x2="311.0" y2="647.0" />
|
||||
<text class="node-detail" x="191.0" y="664.0">KVM / CPU</text>
|
||||
<text class="node-detail" x="191.0" y="680.0">GPA → HPA</text>
|
||||
<rect class="node-shape kind-component emphasis-primary role-service" data-evidence="4068-4080" x="1031.0" y="137.0" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="1106.0" y="164.0">EPT</text>
|
||||
<line class="node-detail-divider" x1="1045.0" y1="185.0" x2="1167.0" y2="185.0" />
|
||||
<text class="node-detail" x="1047.0" y="202.0">KVM / CPU</text>
|
||||
<text class="node-detail" x="1047.0" y="218.0">GPA → HPA</text>
|
||||
</g>
|
||||
<g id="node-host-physical-memory">
|
||||
<rect class="node-shape kind-store emphasis-normal role-store" data-evidence="4069-4072" x="163.0" y="783.0" width="174.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="250.0" y="813.0">Host Physical Memory</text>
|
||||
<rect class="node-shape kind-store emphasis-normal role-store" data-evidence="4082-4085" x="1341.0" y="149.0" width="174.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="1428.0" y="179.0">Host Physical Memory</text>
|
||||
</g>
|
||||
<g id="node-numa-node-0">
|
||||
<rect class="node-shape kind-store emphasis-normal role-sink" data-evidence="4073-4075" x="70.0" y="943.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="973.0">NUMA Node 0</text>
|
||||
<rect class="node-shape kind-store emphasis-normal role-sink" data-evidence="4086-4088" x="1675.0" y="81.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="1750.0" y="111.0">NUMA Node 0</text>
|
||||
</g>
|
||||
<g id="node-numa-node-1">
|
||||
<rect class="node-shape kind-store emphasis-normal role-sink" data-evidence="4073-4075" x="280.0" y="943.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="355.0" y="973.0">NUMA Node 1</text>
|
||||
<rect class="node-shape kind-store emphasis-normal role-sink" data-evidence="4086-4088" x="1675.0" y="217.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="1750.0" y="247.0">NUMA Node 1</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,27 @@
|
||||
# Host memory pressure가 storage와 OOM으로 갈라지는 경로
|
||||
|
||||
## Alternative text
|
||||
|
||||
Host memory pressure가 reclaim에서 clean page 재읽기, anonymous page의 Host swap과 storage contention, 메모리 확보 실패에 따른 Host OOM으로 갈라지는 흐름도. QEMU가 OOM victim이 될 때 VM 전체가 중단될 수 있다는 결과는 본문에서 설명한다.
|
||||
|
||||
## Long description
|
||||
|
||||
왼쪽에서 Host memory pressure가 reclaim으로 들어간다. reclaim 이후 clean file-backed page는 버렸다가 필요할 때 storage에서 다시 읽는 경로, anonymous page는 Host swap I/O를 통해 physical storage와 경쟁하는 경로, 필요한 메모리를 확보하지 못하면 Host OOM으로 가는 경로로 갈린다. storage contention이 application latency로 이어지는 결과와 Host OOM이 QEMU를 victim으로 고를 때 VM 전체가 중단될 수 있다는 결과는 본문에서 이어 설명한다.
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **Host memory pressure** (resource): 실제 Host RAM 수요가 available physical memory에 접근한 상태. Evidence: L2818–L2831.
|
||||
- **Reclaim** (component): Linux가 회수 가능한 page/cache를 처리하는 첫 대응. Evidence: L2818–L2831.
|
||||
- **clean file-backed page** (data): 원본이 storage에 있어 RAM에서 제거하고 나중에 다시 읽을 수 있다. Evidence: L2834–L2848.
|
||||
- **Host swap I/O** (storage): anonymous page의 backing이 필요할 때 host swap I/O가 생길 수 있다. Evidence: L2850–L2852, L2856–L2886.
|
||||
- **Storage contention** (storage): 여러 I/O가 한 physical device에 몰려 contention을 만든다. Evidence: L2938–L2965.
|
||||
- **Host OOM** (result): reclaim 등으로도 필요한 memory 확보에 실패했을 때 Host kernel에서 발생할 수 있다. Evidence: L3213–L3231, L3249–L3265.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **clean file-backed page → Storage contention:** reread. Evidence: L2834–L2848.
|
||||
- **Host memory pressure → Reclaim:** pressure. Evidence: L2818–L2831.
|
||||
- **Reclaim → clean file-backed page:** file-backed. Evidence: L2834–L2848.
|
||||
- **Reclaim → Host OOM:** 확보 실패. Evidence: L3213–L3231.
|
||||
- **Reclaim → Host swap I/O:** anonymous. Evidence: L2850–L2852.
|
||||
- **Host swap I/O → Storage contention:** swap. Evidence: L2871–L2886, L2940–L2946.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Host memory pressure가 storage와 OOM으로 갈라지는 경로
|
||||
# Question: Host memory pressure가 생겼을 때 reclaim 이후 어떤 경로가 swap I/O와 storage contention으로 이어지고, 확보 실패는 어디서 OOM으로 이어지는가
|
||||
direction: right
|
||||
n0: "Host memory pressure" {
|
||||
shape: rectangle
|
||||
}
|
||||
n1: "Reclaim" {
|
||||
shape: rectangle
|
||||
}
|
||||
n2: "clean file-backed page" {
|
||||
shape: rectangle
|
||||
}
|
||||
n3: "Host swap I/O" {
|
||||
shape: cylinder
|
||||
}
|
||||
n4: "Storage contention" {
|
||||
shape: cylinder
|
||||
}
|
||||
n5: "Host OOM" {
|
||||
shape: rectangle
|
||||
}
|
||||
n0 -> n1: "pressure"
|
||||
n1 -> n2: "file-backed"
|
||||
n2 -> n4: "reread"
|
||||
n1 -> n3: "anonymous"
|
||||
n3 -> n4: "swap"
|
||||
n1 -> n5: "확보 실패"
|
||||
@@ -0,0 +1,17 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="Host memory pressure", shape=box, style="rounded,filled"];
|
||||
n1 [label="Reclaim", shape=box, style="rounded,filled"];
|
||||
n2 [label="clean file-backed page", shape=box, style="rounded,filled"];
|
||||
n3 [label="Host swap I/O", shape=cylinder, style="rounded,filled"];
|
||||
n4 [label="Storage contention", shape=cylinder, style="rounded,filled"];
|
||||
n5 [label="Host OOM", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="pressure", style=solid];
|
||||
n1 -> n2 [label="file-backed", style=solid];
|
||||
n2 -> n4 [label="reread", style=solid];
|
||||
n1 -> n3 [label="anonymous", style=solid];
|
||||
n3 -> n4 [label="swap", style=solid];
|
||||
n1 -> n5 [label="확보 실패", style=solid];
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="memory-pressure-reclaim-swap-oom" name="Host memory pressure가 storage와 OOM으로 갈라지는 경로">
|
||||
<mxGraphModel dx="1313" dy="455" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1313" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_pressure" value="Host memory pressure" tooltip="실제 Host RAM 수요가 available physical memory에 접근한 상태. | Evidence: L2818-L2831" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=document;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="180.0" width="220.0" height="110.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_reclaim" value="Reclaim" tooltip="Linux가 회수 가능한 page/cache를 처리하는 첫 대응. | Evidence: L2818-L2831" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="450.0" y="203.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_clean-page" value="clean file-backed page<br/>discard · reread" tooltip="원본이 storage에 있어 RAM에서 제거하고 나중에 다시 읽을 수 있다. | Evidence: L2834-L2848" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="760.0" y="60.0" width="188.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_host-oom" value="Host OOM" tooltip="reclaim 등으로도 필요한 memory 확보에 실패했을 때 Host kernel에서 발생할 수 있다. | Evidence: L3213-L3231, L3249-L3265" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="779.0" y="203.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_host-swap" value="Host swap I/O<br/>anonymous page" tooltip="anonymous page의 backing이 필요할 때 host swap I/O가 생길 수 있다. | Evidence: L2850-L2852, L2856-L2886" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="779.0" y="339.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_storage" value="Storage contention<br/>Host swap<br/>DB I/O<br/>writeback" tooltip="여러 I/O가 한 physical device에 몰려 contention을 만든다. | Evidence: L2938-L2965" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="1108.0" y="182.5" width="160.0" height="105.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_clean-storage" value="reread" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_clean-page" target="n_storage">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="1052.0" y="160.8" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_pressure-reclaim" value="pressure" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_pressure" target="n_reclaim">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="370.0" y="207.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_reclaim-clean" value="file-backed" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_reclaim" target="n_clean-page">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="704.0" y="156.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_reclaim-oom" value="확보 실패" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_reclaim" target="n_host-oom">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="689.5" y="207.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_reclaim-swap" value="anonymous" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_reclaim" target="n_host-swap">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="713.5" y="313.8" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_swap-storage" value="swap" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-swap" target="n_storage">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="1042.5" y="309.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "memory-pressure-reclaim-swap-oom",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "5861e49daf088f0cd326d7fd970908676dca01d984c0f7a0feb1350ad820999b",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "제2부 — 메모리 가상화",
|
||||
"line": 1670
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"memory-pressure-reclaim-swap-oom.svg",
|
||||
"memory-pressure-reclaim-swap-oom.mmd",
|
||||
"memory-pressure-reclaim-swap-oom.d2",
|
||||
"memory-pressure-reclaim-swap-oom.dot",
|
||||
"memory-pressure-reclaim-swap-oom.drawio",
|
||||
"memory-pressure-reclaim-swap-oom.excalidraw",
|
||||
"memory-pressure-reclaim-swap-oom.alt.md"
|
||||
],
|
||||
"lint_issue_count": 0,
|
||||
"assumption_count": 0,
|
||||
"assumptions_allowed": false,
|
||||
"composition_profile": "component-flow",
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "ba06d73804fd520863c0cde6749d9b0d64f690e2fc38846e4d798982248feeca",
|
||||
"output_sha256": {
|
||||
"memory-pressure-reclaim-swap-oom.svg": "efcd3add0e205f71dcc42a8b9195dbfedc4db250a45f468f3708522f99f859fd",
|
||||
"memory-pressure-reclaim-swap-oom.mmd": "b2963febc42ddaf0067c1d4e154470cd87c062b6604dd55e8ef3ea2a396d8c40",
|
||||
"memory-pressure-reclaim-swap-oom.d2": "a00a8d24f0bf8967f3248026846562ea03492cdbd9ac89a09f9242864a58d6c2",
|
||||
"memory-pressure-reclaim-swap-oom.dot": "c3d5a50508ffb776c4ad6540535308c80a24dcd61800fba7b661fe4cf9520cac",
|
||||
"memory-pressure-reclaim-swap-oom.drawio": "9e56388949d8012cf7638667f94ac64178eb90a0d552c4b86cf0fbdb7681180c",
|
||||
"memory-pressure-reclaim-swap-oom.excalidraw": "77f8e646292609d6da44308fed8398e9cc1706c1d8379f3a204278f9a4211ece",
|
||||
"memory-pressure-reclaim-swap-oom.alt.md": "88d0c06a087ca774e9ec4e45c0d2c98207b4cf65935272e3fd497c8aef3033f4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
%% Host memory pressure가 storage와 OOM으로 갈라지는 경로
|
||||
%% question: Host memory pressure가 생겼을 때 reclaim 이후 어떤 경로가 swap I/O와 storage contention으로 이어지고, 확보 실패는 어디서 OOM으로 이어지는가
|
||||
flowchart LR
|
||||
n0["Host memory pressure"]
|
||||
n1["Reclaim"]
|
||||
n2["clean file-backed page"]
|
||||
n3[("Host swap I/O")]
|
||||
n4[("Storage contention")]
|
||||
n5["Host OOM"]
|
||||
n0 -->|"pressure"| n1
|
||||
n1 -->|"file-backed"| n2
|
||||
n2 -->|"reread"| n4
|
||||
n1 -->|"anonymous"| n3
|
||||
n3 -->|"swap"| n4
|
||||
n1 -->|"확보 실패"| n5
|
||||
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1313" height="455" viewBox="0 0 1313 455" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">Host memory pressure가 storage와 OOM으로 갈라지는 경로</title>
|
||||
<desc id="diagram-description">왼쪽에서 Host memory pressure가 reclaim으로 들어간다. reclaim 이후 clean file-backed page는 버렸다가 필요할 때 storage에서 다시 읽는 경로, anonymous page는 Host swap I/O를 통해 physical storage와 경쟁하는 경로, 필요한 메모리를 확보하지 못하면 Host OOM으로 가는 경로로 갈린다. storage contention이 application latency로 이어지는 결과와 Host OOM이 QEMU를 victim으로 고를 때 VM 전체가 중단될 수 있다는 결과는 본문에서 이어 설명한다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"memory-pressure-reclaim-swap-oom","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"제2부 — 메모리 가상화","line":1670}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
</marker>
|
||||
<style>
|
||||
:root { color-scheme: light; }
|
||||
text { font-family: Inter, Pretendard, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #111827; }
|
||||
.canvas { fill: #ffffff; }
|
||||
.group-box { fill: #ffffff; stroke: #9ca3af; stroke-width: 1.4; stroke-dasharray: 7 5; }
|
||||
.group-label-bg { fill: #ffffff; }
|
||||
.group-label { font-size: 13px; font-weight: 650; fill: #374151; }
|
||||
.edge { fill: none; stroke: #374151; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; marker-end: url(#arrow); }
|
||||
.edge.style-dashed, .edge.semantic-dashed, .edge.assumption { stroke-dasharray: 7 5; }
|
||||
.edge.style-dotted { stroke-dasharray: 2 5; }
|
||||
.edge.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.edge.emphasis-muted { stroke: #9ca3af; }
|
||||
.edge.emphasis-warning, .edge.kind-failure, .edge.kind-error { stroke: #dc2626; stroke-width: 2.2; }
|
||||
.edge-label-bg { fill: #ffffff; }
|
||||
.edge-label { font-size: 12px; font-weight: 560; text-anchor: middle; }
|
||||
.node-shape { fill: #ffffff; stroke: #4b5563; stroke-width: 1.7; }
|
||||
.node-shape.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.node-shape.emphasis-muted { stroke: #9ca3af; fill: #f9fafb; }
|
||||
.node-shape.emphasis-warning { stroke: #d97706; stroke-width: 2; fill: #fffdf5; }
|
||||
.node-shape.kind-database, .node-shape.kind-datastore, .node-shape.kind-storage { fill: #f8fafc; }
|
||||
.node-shape.kind-queue, .node-shape.kind-event, .node-shape.kind-topic { fill: #fafafa; }
|
||||
.node-shape.assumption { stroke-dasharray: 4 4; }
|
||||
.storage-bottom, .controller-divider { fill: none; stroke: #4b5563; stroke-width: 1.4; }
|
||||
.controller-led { fill: #4b5563; }
|
||||
.actor-symbol { fill: none; stroke: #4b5563; stroke-width: 1.8; stroke-linecap: round; }
|
||||
.actor-symbol.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.node-label { font-size: 14px; font-weight: 650; text-anchor: middle; }
|
||||
.node-role { font-size: 10px; letter-spacing: 0.04em; text-anchor: middle; fill: #6b7280; }
|
||||
.node-detail-divider { stroke: #d1d5db; stroke-width: 1; }
|
||||
.node-detail { font-size: 11px; fill: #374151; }
|
||||
.assumption-badge { font-size: 9px; font-weight: 700; fill: #92400e; }
|
||||
.failure-mark { stroke: #dc2626; stroke-width: 4; stroke-linecap: round; }
|
||||
.lifeline { stroke: #9ca3af; stroke-width: 1.2; stroke-dasharray: 5 5; }
|
||||
.timeline-axis { stroke: #374151; stroke-width: 1.8; marker-end: url(#arrow); }
|
||||
.timeline-stem { stroke: #6b7280; stroke-width: 1.3; }
|
||||
.timeline-marker { fill: #ffffff; stroke: #374151; stroke-width: 1.7; }
|
||||
.timeline-marker.primary { fill: #2563eb; stroke: #2563eb; }
|
||||
.timeline-marker.warning { fill: #dc2626; stroke: #dc2626; }
|
||||
.timeline-label { font-size: 13px; font-weight: 650; text-anchor: middle; }
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="1313" height="455" />
|
||||
<polyline class="edge kind-data style-dashed emphasis-normal" points="948.0,95.5 1028.0,95.5 1028.0,226.0 1108.0,226.0" data-evidence="2834-2848" />
|
||||
<rect class="edge-label-bg" x="1022.9" y="146.8" width="58.2" height="22" rx="3" />
|
||||
<text class="edge-label" x="1052.0" y="161.8">reread</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="290.0,235.0 370.0,235.0 370.0,235.0 450.0,235.0" data-evidence="2818-2831" />
|
||||
<rect class="edge-label-bg" x="334.2" y="193.0" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="370.0" y="208.0">pressure</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="600.0,217.0 680.0,217.0 680.0,95.5 760.0,95.5" data-evidence="2834-2848" />
|
||||
<rect class="edge-label-bg" x="658.1" y="142.2" width="91.7" height="22" rx="3" />
|
||||
<text class="edge-label" x="704.0" y="157.2">file-backed</text>
|
||||
<polyline class="edge kind-control style-dashed emphasis-normal" points="600.0,235.0 689.5,235.0 689.5,235.0 779.0,235.0" data-evidence="3213-3231" />
|
||||
<rect class="edge-label-bg" x="663.8" y="193.0" width="51.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="689.5" y="208.0">확보 실패</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="600.0,253.0 689.5,253.0 689.5,374.5 779.0,374.5" data-evidence="2850-2852" />
|
||||
<rect class="edge-label-bg" x="674.4" y="299.8" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="713.5" y="314.8">anonymous</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="929.0,374.5 1018.5,374.5 1018.5,244.0 1108.0,244.0" data-evidence="2871-2886,2940-2946" />
|
||||
<rect class="edge-label-bg" x="1020.1" y="295.2" width="44.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="1042.5" y="310.2">swap</text>
|
||||
<g id="node-pressure">
|
||||
<path class="node-shape kind-resource emphasis-normal role-source" data-evidence="2818-2831" d="M 70.0 180.0 H 259.2 L 290.0 210.8 V 290.0 H 70.0 Z M 259.2 180.0 V 210.8 H 290.0" />
|
||||
<text class="node-label" x="180.0" y="233.0">Host memory pressure</text>
|
||||
</g>
|
||||
<g id="node-reclaim">
|
||||
<rect class="node-shape kind-component emphasis-primary role-service" data-evidence="2818-2831" x="450.0" y="203.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="525.0" y="233.0">Reclaim</text>
|
||||
</g>
|
||||
<g id="node-clean-page">
|
||||
<rect class="node-shape kind-data emphasis-normal role-service" data-evidence="2834-2848" x="760.0" y="60.0" width="188.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="854.0" y="87.0">clean file-backed page</text>
|
||||
<line class="node-detail-divider" x1="774.0" y1="108.0" x2="934.0" y2="108.0" />
|
||||
<text class="node-detail" x="776.0" y="125.0">discard · reread</text>
|
||||
</g>
|
||||
<g id="node-host-oom">
|
||||
<rect class="node-shape kind-result emphasis-normal role-service" data-evidence="3213-3231,3249-3265" x="779.0" y="203.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="854.0" y="233.0">Host OOM</text>
|
||||
</g>
|
||||
<g id="node-host-swap">
|
||||
<rect class="node-shape kind-storage emphasis-normal role-store" data-evidence="2850-2852,2856-2886" x="779.0" y="350.8" width="150.0" height="47.3" /><ellipse class="node-shape kind-storage emphasis-normal role-store" cx="854.0" cy="350.8" rx="75.0" ry="11.8" /><path class="storage-bottom" d="M 779.0 398.2 A 75.0 11.8 0 0 0 929.0 398.2" />
|
||||
<text class="node-label" x="854.0" y="366.0">Host swap I/O</text>
|
||||
<line class="node-detail-divider" x1="793.0" y1="387.0" x2="915.0" y2="387.0" />
|
||||
<text class="node-detail" x="795.0" y="404.0">anonymous page</text>
|
||||
</g>
|
||||
<g id="node-storage">
|
||||
<rect class="node-shape kind-storage emphasis-normal role-store" data-evidence="2938-2965" x="1108.0" y="195.5" width="160.0" height="79.0" /><ellipse class="node-shape kind-storage emphasis-normal role-store" cx="1188.0" cy="195.5" rx="80.0" ry="13.0" /><path class="storage-bottom" d="M 1108.0 274.5 A 80.0 13.0 0 0 0 1268.0 274.5" />
|
||||
<text class="node-label" x="1188.0" y="209.5">Storage contention</text>
|
||||
<line class="node-detail-divider" x1="1122.0" y1="230.5" x2="1254.0" y2="230.5" />
|
||||
<text class="node-detail" x="1124.0" y="247.5">Host swap</text>
|
||||
<text class="node-detail" x="1124.0" y="263.5">DB I/O</text>
|
||||
<text class="node-detail" x="1124.0" y="279.5">writeback</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
@@ -0,0 +1,26 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
subgraph cluster_0 {
|
||||
label="forward · priority filter - 10";
|
||||
style="rounded,dashed";
|
||||
color="#66788a";
|
||||
n1 [label="ct state new accept", shape=box, style="rounded,filled"];
|
||||
}
|
||||
subgraph cluster_1 {
|
||||
label="ip libvirt_network · guest_input";
|
||||
style="rounded,dashed";
|
||||
color="#66788a";
|
||||
n2 [label="inserted accept", shape=box, style="rounded,filled"];
|
||||
n3 [label="reject", shape=box, style="rounded,filled"];
|
||||
}
|
||||
n0 [label="inbound packet", shape=box, style="rounded,filled"];
|
||||
n4 [label="edge nginx", shape=box, style="rounded,filled"];
|
||||
n5 [label="connection refused", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="forward hook", style=solid];
|
||||
n1 -> n2 [label="after insert", style=solid];
|
||||
n1 -> n3 [label="before insert", style=solid];
|
||||
n2 -> n4 [label="accept", style=solid];
|
||||
n3 -> n5 [label="reject", style=solid];
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "nftables-forward-hook-chain-order",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "7c412e3a6278b75551ce56f35693dd236d0b3bf0962c2788a87703123f009f9f",
|
||||
"spec_sha256": "a035a69d70e850cb32cb89258e9912fdcd4533a8d312be789b040a12b51b1225",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "60d902c7aed218ba637b48603a3bd0e6b193fea59c9de97ffdb8e05d5087aedd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "180. nftables 는 앞 체인의 `accept` 로 뒤 체인의 `reject` 를 막지 못한다",
|
||||
@@ -14,9 +14,10 @@
|
||||
},
|
||||
"outputs": [
|
||||
"nftables-forward-hook-chain-order.svg",
|
||||
"nftables-forward-hook-chain-order.drawio",
|
||||
"nftables-forward-hook-chain-order.mmd",
|
||||
"nftables-forward-hook-chain-order.d2",
|
||||
"nftables-forward-hook-chain-order.dot",
|
||||
"nftables-forward-hook-chain-order.drawio",
|
||||
"nftables-forward-hook-chain-order.excalidraw",
|
||||
"nftables-forward-hook-chain-order.alt.md"
|
||||
],
|
||||
@@ -27,5 +28,15 @@
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "6ced898c845eb65e6dccc403fcadfbf82d3805f7fe089c75241132621201298e",
|
||||
"output_sha256": {
|
||||
"nftables-forward-hook-chain-order.svg": "f5cf1414171d34677a6e2e430b4269a8687a5968f50488f2257ddc3d3be808db",
|
||||
"nftables-forward-hook-chain-order.mmd": "a523ee8885b46bc40937b8992f9ebf65d273eaf378f980af1026bbf2cda84e83",
|
||||
"nftables-forward-hook-chain-order.d2": "117662bdc7955bb01ceb6a36136ee2d5d6da727301b5c0f2c24c75fc71454c87",
|
||||
"nftables-forward-hook-chain-order.dot": "e71e3d8dc4a0e7417e4ef8514b79ec52099609c50bf895d31888e3ed4add8166",
|
||||
"nftables-forward-hook-chain-order.drawio": "9a60b8116a117e18d83eb6ba78048f3400578dd62adb3247aa88f3d5bffb0e98",
|
||||
"nftables-forward-hook-chain-order.excalidraw": "efa24031fb83393e57aeebd824f3e839c97c5b55f61ae1922c6933a4f1e709b7",
|
||||
"nftables-forward-hook-chain-order.alt.md": "aa81f31c4403feadabb90846086ab5f29b821fd82712fcb275d8e8c0b92e17b2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1298" height="434" viewBox="0 0 1298 434" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">같은 forward 훅에 붙은 base 체인 둘이 우선순위 순으로 이어서 평가되고, 앞 체인의 accept 는 뒤 체인의 reject 를 막지 못한다</title>
|
||||
<desc id="diagram-description">왼쪽에서 오른쪽으로 읽는다. 왼쪽 끝이 밖에서 친 curl 이 만든 inbound packet 이고 forward 훅으로 들어간다. 첫 점선 상자가 DNAT 파일에 둔 base 체인이다. priority filter - 10 이라 먼저 돌고, 그 안의 ct state new accept 가 이 packet 을 통과시킨다. 다음 점선 상자가 libvirt 가 만든 ip libvirt_network 테이블의 guest_input 체인이다. 앞 체인의 accept 는 평가를 끝내지 않으므로 같은 packet 이 이 체인으로 이어진다. 그 안의 상자 둘은 같은 체인의 맨 앞과 맨 끝이다. 구멍을 넣기 전에는 맨 앞이 비어 있어 packet 이 ct state established,related accept 에 걸리지 못한 채 체인 끝 reject 에 닿았고 connection refused 로 끝났다. 그 reject 규칙의 카운터가 4 패킷 240 바이트다. insert 로 구멍을 넣으면 그 규칙이 맨 앞에 서서 같은 packet 을 먼저 받아 192.168.122.10 의 엣지 nginx 로 보낸다. 실선이 구멍을 넣은 뒤의 경로이고 점선이 넣기 전의 경로다. 이 그림은 그 규칙이 libvirt 네트워크를 다시 세우면 사라진다는 것은 말하지 않는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"nftables-forward-hook-chain-order","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"60d902c7aed218ba637b48603a3bd0e6b193fea59c9de97ffdb8e05d5087aedd","anchor":{"kind":"heading","value":"180. nftables 는 앞 체인의 `accept` 로 뒤 체인의 `reject` 를 막지 못한다","line":7805}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"nftables-forward-hook-chain-order","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"180. nftables 는 앞 체인의 `accept` 로 뒤 체인의 `reject` 를 막지 못한다","line":7805}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
|
||||
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
@@ -10,16 +10,16 @@ QEMU vCPU Thread, VM1 Memory Backing, Node 0 CPU, Node 0 RAM, Node 1 RAM 다섯
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **QEMU vCPU Thread** (process): Guest vCPU 가 Host 에서 갖는 실체. Host scheduler 가 이것을 logical CPU 에 올린다. Evidence: L3315–L3324.
|
||||
- **VM1 Memory Backing** (memory): 그 가상 머신의 Host physical backing page 가 놓이는 자리. Evidence: L3327–L3327, L3352–L3354, L3381–L3382.
|
||||
- **Node 0 CPU** (compute): vCPU thread 가 실행되는 logical CPU. NUMA Node 0 에 속한다. Evidence: L3322–L3330.
|
||||
- **Node 0 RAM** (memory): Node 0 CPU 와 같은 node 의 RAM. Evidence: L3288–L3296, L3373–L3382.
|
||||
- **Node 1 RAM** (memory): 다른 node 의 RAM. Node 0 CPU 가 읽으면 interconnect 를 건넌다. Evidence: L3299–L3306, L3334–L3334.
|
||||
- **QEMU vCPU Thread** (process): Guest vCPU 가 Host 에서 갖는 실체. Host scheduler 가 이것을 logical CPU 에 올린다. Evidence: L3328–L3337.
|
||||
- **VM1 Memory Backing** (memory): 그 가상 머신의 Host physical backing page 가 놓이는 자리. Evidence: L3340–L3340, L3365–L3367, L3394–L3395.
|
||||
- **Node 0 CPU** (compute): vCPU thread 가 실행되는 logical CPU. NUMA Node 0 에 속한다. Evidence: L3335–L3343.
|
||||
- **Node 0 RAM** (memory): Node 0 CPU 와 같은 node 의 RAM. Evidence: L3301–L3309, L3386–L3395.
|
||||
- **Node 1 RAM** (memory): 다른 node 의 RAM. Node 0 CPU 가 읽으면 interconnect 를 건넌다. Evidence: L3312–L3319, L3347–L3347.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **QEMU vCPU Thread → Node 0 CPU:** vCPU Pinning. Evidence: L3322–L3324, L3347–L3350.
|
||||
- **VM1 Memory Backing → Node 1 RAM:** Memory Placement. Evidence: L3327–L3327, L3352–L3354.
|
||||
- **Node 0 CPU → Node 1 RAM:** Remote Access. Evidence: L3329–L3339, L3356–L3357.
|
||||
- **VM1 Memory Backing → Node 0 RAM:** Memory Binding. Evidence: L3361–L3366, L3381–L3382.
|
||||
- **Node 0 CPU → Node 0 RAM:** Local Access. Evidence: L3288–L3296, L3373–L3382.
|
||||
- **QEMU vCPU Thread → Node 0 CPU:** vCPU Pinning. Evidence: L3335–L3337, L3360–L3363.
|
||||
- **VM1 Memory Backing → Node 1 RAM:** Memory Placement. Evidence: L3340–L3340, L3365–L3367.
|
||||
- **Node 0 CPU → Node 1 RAM:** Remote Access. Evidence: L3342–L3352, L3369–L3370.
|
||||
- **VM1 Memory Backing → Node 0 RAM:** Memory Binding. Evidence: L3374–L3379, L3394–L3395.
|
||||
- **Node 0 CPU → Node 0 RAM:** Local Access. Evidence: L3301–L3309, L3386–L3395.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="QEMU vCPU Thread", shape=box, style="rounded,filled"];
|
||||
n1 [label="VM1 Memory Backing", shape=box, style="rounded,filled"];
|
||||
n2 [label="Node 0 CPU", shape=box, style="rounded,filled"];
|
||||
n3 [label="Node 0 RAM", shape=box, style="rounded,filled"];
|
||||
n4 [label="Node 1 RAM", shape=box, style="rounded,filled"];
|
||||
n0 -> n2 [label="vCPU Pinning", style=solid];
|
||||
n1 -> n4 [label="Memory Placement", style=solid];
|
||||
n2 -> n4 [label="Remote Access", style=solid];
|
||||
n1 -> n3 [label="Memory Binding", style=solid];
|
||||
n2 -> n3 [label="Local Access", style=solid];
|
||||
}
|
||||
@@ -5,19 +5,19 @@
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_qemu-vcpu-thread" value="QEMU vCPU Thread<br/>Guest vCPU" tooltip="Guest vCPU 가 Host 에서 갖는 실체. Host scheduler 가 이것을 logical CPU 에 올린다. | Evidence: L3315-L3324" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxCell id="n_qemu-vcpu-thread" value="QEMU vCPU Thread<br/>Guest vCPU" tooltip="Guest vCPU 가 Host 에서 갖는 실체. Host scheduler 가 이것을 logical CPU 에 올린다. | Evidence: L3328-L3337" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="45.0" y="35.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_vm-memory-backing" value="VM1 Memory Backing<br/>VM1 RAM" tooltip="그 가상 머신의 Host physical backing page 가 놓이는 자리. | Evidence: L3327-L3327, L3352-L3354, L3381-L3382" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_vm-memory-backing" value="VM1 Memory Backing<br/>VM1 RAM" tooltip="그 가상 머신의 Host physical backing page 가 놓이는 자리. | Evidence: L3340-L3340, L3365-L3367, L3394-L3395" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="255.0" y="35.0" width="160.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_node0-cpu" value="Node 0 CPU<br/>Host Logical CPU" tooltip="vCPU thread 가 실행되는 logical CPU. NUMA Node 0 에 속한다. | Evidence: L3322-L3330" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxCell id="n_node0-cpu" value="Node 0 CPU<br/>Host Logical CPU" tooltip="vCPU thread 가 실행되는 logical CPU. NUMA Node 0 에 속한다. | Evidence: L3335-L3343" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="465.0" y="35.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_node0-ram" value="Node 0 RAM<br/>Local Memory" tooltip="Node 0 CPU 와 같은 node 의 RAM. | Evidence: L3288-L3296, L3373-L3382" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_node0-ram" value="Node 0 RAM<br/>Local Memory" tooltip="Node 0 CPU 와 같은 node 의 RAM. | Evidence: L3301-L3309, L3386-L3395" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="675.0" y="35.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_node1-ram" value="Node 1 RAM<br/>Remote Memory" tooltip="다른 node 의 RAM. Node 0 CPU 가 읽으면 interconnect 를 건넌다. | Evidence: L3299-L3306, L3334-L3334" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_node1-ram" value="Node 1 RAM<br/>Remote Memory" tooltip="다른 node 의 RAM. Node 0 CPU 가 읽으면 interconnect 를 건넌다. | Evidence: L3312-L3319, L3347-L3347" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="885.0" y="35.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_vcpu-pinning" value="vCPU Pinning" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu-vcpu-thread" target="n_node0-cpu">
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "numa-vcpu-and-memory-placement",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "afeb9cbc8d7063a1945cabb916eadab7d248a252fce57e433355e6c679090bd5",
|
||||
"spec_sha256": "49d394cecc2f97b5dd1c569cc040275a11abb76b563dda8edde59f497d21c7d9",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "75. vCPU와 NUMA의 연결",
|
||||
"line": 3313
|
||||
"line": 3326
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"numa-vcpu-and-memory-placement.svg",
|
||||
"numa-vcpu-and-memory-placement.drawio",
|
||||
"numa-vcpu-and-memory-placement.mmd",
|
||||
"numa-vcpu-and-memory-placement.d2",
|
||||
"numa-vcpu-and-memory-placement.dot",
|
||||
"numa-vcpu-and-memory-placement.drawio",
|
||||
"numa-vcpu-and-memory-placement.excalidraw",
|
||||
"numa-vcpu-and-memory-placement.alt.md"
|
||||
],
|
||||
@@ -27,5 +28,15 @@
|
||||
"reference_ids": [
|
||||
"payment-approval-sequence"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "1db7bff99e8493c392fb04c43ee74f13b4bcf0c0d2685f036bcdd74bbd6c00c4",
|
||||
"output_sha256": {
|
||||
"numa-vcpu-and-memory-placement.svg": "3720f7bf05faaf6e542fd41cb08d62afad368a2aa55ee6d960a1372b0d766da2",
|
||||
"numa-vcpu-and-memory-placement.mmd": "5b1860bb9a59f0f7848a7789e8ccd0c8471b5560113bbf44c09a9d1672494bc0",
|
||||
"numa-vcpu-and-memory-placement.d2": "a061122778afc79df6d07608d99ca98f625e73411a8dceeba163cd2315a3b215",
|
||||
"numa-vcpu-and-memory-placement.dot": "63025126420fadbf9ddf5686ff7e07aab5ec7cd226349d812d36fb47046f2e0f",
|
||||
"numa-vcpu-and-memory-placement.drawio": "24c0328f9bba296c4bdeed687a72d80789d893d3c4d803567d10611f84057059",
|
||||
"numa-vcpu-and-memory-placement.excalidraw": "c8115da91d5a884bb8d256b01477ec548ece6db09fc1c3ac58a609d9ab9b0834",
|
||||
"numa-vcpu-and-memory-placement.alt.md": "a8db12c5add65f655d32a0f5bb00b01c6c873503ca57b52ff4814f215dd8afdb"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1080" height="480" viewBox="0 0 1080 480" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">vCPU 를 Node 0 에 묶어도 backing 이 Node 1 에 있으면 접근은 remote 로 남는다</title>
|
||||
<desc id="diagram-description">참여자는 왼쪽부터 QEMU vCPU Thread, VM1 Memory Backing, Node 0 CPU, Node 0 RAM, Node 1 RAM 다섯이다. 메시지는 위에서 아래로 읽는다. 1번에서 vCPU thread 가 Node 0 CPU 에 pinning 되고, 2번에서 VM1 의 memory backing 이 Node 1 에 놓인다. 그 배치에서 3번의 memory 접근은 Node 1 RAM 으로 가고 이것이 remote access 다. Node 0 과 Node 1 사이에는 interconnect 가 있어 이 접근만 그 구간을 건넌다. 4번과 5번은 그 뒤에 일어나는 다른 사건이 아니라 배치를 고친 구성이다. memory placement 와 binding 까지 Node 0 으로 맞추면 같은 접근이 Node 0 RAM 으로 가고 local access 가 된다. 접근 비용이 실제로 얼마나 차이 나는지, 이 Host 가 몇 개의 node 를 가졌는지는 그림이 말하지 않는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"numa-vcpu-and-memory-placement","profile":"sequence"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"75. vCPU와 NUMA의 연결","line":3313}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"numa-vcpu-and-memory-placement","profile":"sequence"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"75. vCPU와 NUMA의 연결","line":3326}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -50,44 +50,44 @@
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="1080" height="480" />
|
||||
<rect class="node-shape kind-process emphasis-primary role-participant" data-evidence="3315-3324" x="45.0" y="35.0" width="150.0" height="71.0" rx="7" />
|
||||
<rect class="node-shape kind-process emphasis-primary role-participant" data-evidence="3328-3337" x="45.0" y="35.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="120.0" y="62.0">QEMU vCPU Thread</text>
|
||||
<line class="node-detail-divider" x1="59.0" y1="83.0" x2="181.0" y2="83.0" />
|
||||
<text class="node-detail" x="61.0" y="100.0">Guest vCPU</text>
|
||||
<line class="lifeline" x1="120.0" y1="106.0" x2="120.0" y2="450.0" />
|
||||
<rect class="node-shape kind-memory emphasis-normal role-participant" data-evidence="3327-3327,3352-3354,3381-3382" x="255.0" y="35.0" width="160.0" height="71.0" rx="7" />
|
||||
<rect class="node-shape kind-memory emphasis-normal role-participant" data-evidence="3340-3340,3365-3367,3394-3395" x="255.0" y="35.0" width="160.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="335.0" y="62.0">VM1 Memory Backing</text>
|
||||
<line class="node-detail-divider" x1="269.0" y1="83.0" x2="401.0" y2="83.0" />
|
||||
<text class="node-detail" x="271.0" y="100.0">VM1 RAM</text>
|
||||
<line class="lifeline" x1="335.0" y1="106.0" x2="335.0" y2="450.0" />
|
||||
<rect class="node-shape kind-compute emphasis-primary role-participant" data-evidence="3322-3330" x="465.0" y="35.0" width="150.0" height="71.0" rx="7" />
|
||||
<rect class="node-shape kind-compute emphasis-primary role-participant" data-evidence="3335-3343" x="465.0" y="35.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="540.0" y="62.0">Node 0 CPU</text>
|
||||
<line class="node-detail-divider" x1="479.0" y1="83.0" x2="601.0" y2="83.0" />
|
||||
<text class="node-detail" x="481.0" y="100.0">Host Logical CPU</text>
|
||||
<line class="lifeline" x1="540.0" y1="106.0" x2="540.0" y2="450.0" />
|
||||
<rect class="node-shape kind-memory emphasis-normal role-participant" data-evidence="3288-3296,3373-3382" x="675.0" y="35.0" width="150.0" height="71.0" rx="7" />
|
||||
<rect class="node-shape kind-memory emphasis-normal role-participant" data-evidence="3301-3309,3386-3395" x="675.0" y="35.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="750.0" y="62.0">Node 0 RAM</text>
|
||||
<line class="node-detail-divider" x1="689.0" y1="83.0" x2="811.0" y2="83.0" />
|
||||
<text class="node-detail" x="691.0" y="100.0">Local Memory</text>
|
||||
<line class="lifeline" x1="750.0" y1="106.0" x2="750.0" y2="450.0" />
|
||||
<rect class="node-shape kind-memory emphasis-normal role-participant" data-evidence="3299-3306,3334-3334" x="885.0" y="35.0" width="150.0" height="71.0" rx="7" />
|
||||
<rect class="node-shape kind-memory emphasis-normal role-participant" data-evidence="3312-3319,3347-3347" x="885.0" y="35.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="960.0" y="62.0">Node 1 RAM</text>
|
||||
<line class="node-detail-divider" x1="899.0" y1="83.0" x2="1021.0" y2="83.0" />
|
||||
<text class="node-detail" x="901.0" y="100.0">Remote Memory</text>
|
||||
<line class="lifeline" x1="960.0" y1="106.0" x2="960.0" y2="450.0" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="120.0,140.0 540.0,140.0" data-evidence="3322-3324,3347-3350" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="120.0,140.0 540.0,140.0" data-evidence="3335-3337,3360-3363" />
|
||||
<rect class="edge-label-bg" x="270.8" y="114.0" width="118.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="330.0" y="129.0">1. vCPU Pinning</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="335.0,202.0 960.0,202.0" data-evidence="3327-3327,3352-3354" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="335.0,202.0 960.0,202.0" data-evidence="3340-3340,3365-3367" />
|
||||
<rect class="edge-label-bg" x="574.9" y="176.0" width="145.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="647.5" y="191.0">2. Memory Placement</text>
|
||||
<polyline class="edge kind-read style-dashed emphasis-normal" points="540.0,264.0 960.0,264.0" data-evidence="3329-3339,3356-3357" />
|
||||
<polyline class="edge kind-read style-dashed emphasis-normal" points="540.0,264.0 960.0,264.0" data-evidence="3342-3352,3369-3370" />
|
||||
<rect class="edge-label-bg" x="687.4" y="238.0" width="125.2" height="22" rx="3" />
|
||||
<text class="edge-label" x="750.0" y="253.0">3. Remote Access</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="335.0,326.0 750.0,326.0" data-evidence="3361-3366,3381-3382" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="335.0,326.0 750.0,326.0" data-evidence="3374-3379,3394-3395" />
|
||||
<rect class="edge-label-bg" x="476.6" y="300.0" width="131.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="542.5" y="315.0">4. Memory Binding</text>
|
||||
<polyline class="edge kind-read style-solid emphasis-normal" points="540.0,388.0 750.0,388.0" data-evidence="3288-3296,3373-3382" />
|
||||
<polyline class="edge kind-read style-solid emphasis-normal" points="540.0,388.0 750.0,388.0" data-evidence="3301-3309,3386-3395" />
|
||||
<rect class="edge-label-bg" x="585.8" y="362.0" width="118.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="645.0" y="377.0">5. Local Access</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
@@ -10,34 +10,34 @@
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **virsh** (cli): VM/network 관리 CLI. packet datapath 에는 직접 참여하지 않는다. Evidence: L5662–L5662, L5687–L5689.
|
||||
- **libvirt** (service): VM lifecycle 과 NIC/network configuration 을 관리한다. Evidence: L5663–L5663, L5691–L5691.
|
||||
- **QEMU** (process): 실제로 실행되는 프로세스. 이 안에 virtio-net device model 이 있다. Evidence: L5666–L5666, L5693–L5693.
|
||||
- **virtio-net Device Model** (service): control/setup path 가 닿는 자리. 장치를 만들고 backend 를 연결한다. Evidence: L5666–L5666, L5695–L5700.
|
||||
- **Physical NIC** (hardware): 밖에서 온 packet 이 처음 닿는 하드웨어. Evidence: L5706–L5708.
|
||||
- **Physical NIC Driver** (driver): 그 하드웨어를 제어하는 Host kernel driver. Evidence: L5674–L5674, L5710–L5710.
|
||||
- **virsh** (cli): VM/network 관리 CLI. packet datapath 에는 직접 참여하지 않는다. Evidence: L5675–L5675, L5700–L5702.
|
||||
- **libvirt** (service): VM lifecycle 과 NIC/network configuration 을 관리한다. Evidence: L5676–L5676, L5704–L5704.
|
||||
- **QEMU** (process): 실제로 실행되는 프로세스. 이 안에 virtio-net device model 이 있다. Evidence: L5679–L5679, L5706–L5706.
|
||||
- **virtio-net Device Model** (service): control/setup path 가 닿는 자리. 장치를 만들고 backend 를 연결한다. Evidence: L5679–L5679, L5708–L5713.
|
||||
- **Physical NIC** (hardware): 밖에서 온 packet 이 처음 닿는 하드웨어. Evidence: L5719–L5721.
|
||||
- **Physical NIC Driver** (driver): 그 하드웨어를 제어하는 Host kernel driver. Evidence: L5687–L5687, L5723–L5723.
|
||||
- **Linux Bridge /
|
||||
Routing / NAT** (network): L2 software switch 와 L3 routing, 주소 변환이 놓이는 자리. Evidence: L5672–L5673, L5712–L5712.
|
||||
- **TAP** (network): VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점. Evidence: L5671–L5671, L5714–L5714.
|
||||
- **vhost-net** (kernel): 반복되는 packet datapath 를 Host kernel 에서 처리하는 backend. Evidence: L5669–L5669, L5716–L5716.
|
||||
- **QEMU virtio backend** (process): vhost-net 을 쓰지 않을 때 datapath backend 를 맡는 쪽. Evidence: L5668–L5668, L5742–L5742.
|
||||
- **virtqueue** (queue): Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 공유 큐. Evidence: L5667–L5667, L5718–L5718.
|
||||
- **Guest** (service): packet 이 올라가 애플리케이션 socket 에 닿는 쪽. Evidence: L5664–L5665, L5720–L5726.
|
||||
Routing / NAT** (network): L2 software switch 와 L3 routing, 주소 변환이 놓이는 자리. Evidence: L5685–L5686, L5725–L5725.
|
||||
- **TAP** (network): VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점. Evidence: L5684–L5684, L5727–L5727.
|
||||
- **vhost-net** (kernel): 반복되는 packet datapath 를 Host kernel 에서 처리하는 backend. Evidence: L5682–L5682, L5729–L5729.
|
||||
- **QEMU virtio backend** (process): vhost-net 을 쓰지 않을 때 datapath backend 를 맡는 쪽. Evidence: L5681–L5681, L5755–L5755.
|
||||
- **virtqueue** (queue): Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 공유 큐. Evidence: L5680–L5680, L5731–L5731.
|
||||
- **Guest** (service): packet 이 올라가 애플리케이션 socket 에 닿는 쪽. Evidence: L5677–L5678, L5733–L5739.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **Linux Bridge /
|
||||
Routing / NAT → TAP:** Ethernet Frame. Evidence: L5671–L5671, L5712–L5714.
|
||||
Routing / NAT → TAP:** Ethernet Frame. Evidence: L5684–L5684, L5725–L5727.
|
||||
- **Physical NIC Driver → Linux Bridge /
|
||||
Routing / NAT:** L2 forwarding. Evidence: L5672–L5672, L5710–L5712.
|
||||
- **libvirt → QEMU:** NIC/network configuration. Evidence: L5663–L5663, L5691–L5693.
|
||||
- **Physical NIC → Physical NIC Driver:** Ethernet Frame. Evidence: L5671–L5671, L5708–L5710.
|
||||
- **QEMU virtio backend → virtqueue:** Data Path. Evidence: L5729–L5729, L5742–L5744.
|
||||
- **QEMU → virtio-net Device Model:** QEMU process. Evidence: L5666–L5666, L5693–L5695.
|
||||
- **virtio-net Device Model → QEMU virtio backend:** control. Evidence: L5668–L5668, L5700–L5700.
|
||||
- **virtio-net Device Model → vhost-net:** vhost-net backend 설정. Evidence: L5700–L5700, L5716–L5716.
|
||||
- **TAP → QEMU virtio backend:** data. Evidence: L5729–L5729, L5740–L5742.
|
||||
- **TAP → vhost-net:** vhost-net 사용. Evidence: L5703–L5703, L5714–L5716.
|
||||
- **vhost-net → virtqueue:** Data Path. Evidence: L5703–L5703, L5716–L5718.
|
||||
- **virsh → libvirt:** Control / Setup. Evidence: L5662–L5663, L5684–L5691.
|
||||
- **virtqueue → Guest:** virtio-net Frontend Driver. Evidence: L5664–L5664, L5718–L5726.
|
||||
Routing / NAT:** L2 forwarding. Evidence: L5685–L5685, L5723–L5725.
|
||||
- **libvirt → QEMU:** NIC config. Evidence: L5676–L5676, L5704–L5706.
|
||||
- **Physical NIC → Physical NIC Driver:** Ethernet Frame. Evidence: L5684–L5684, L5721–L5723.
|
||||
- **QEMU virtio backend → virtqueue:** Data Path. Evidence: L5742–L5742, L5755–L5757.
|
||||
- **QEMU → virtio-net Device Model:** QEMU process. Evidence: L5679–L5679, L5706–L5708.
|
||||
- **virtio-net Device Model → QEMU virtio backend:** control. Evidence: L5681–L5681, L5713–L5713.
|
||||
- **virtio-net Device Model → vhost-net:** vhost-net backend 설정. Evidence: L5713–L5713, L5729–L5729.
|
||||
- **TAP → QEMU virtio backend:** data. Evidence: L5742–L5742, L5753–L5755.
|
||||
- **TAP → vhost-net:** vhost-net 사용. Evidence: L5716–L5716, L5727–L5729.
|
||||
- **vhost-net → virtqueue:** Data Path. Evidence: L5716–L5716, L5729–L5731.
|
||||
- **virsh → libvirt:** Control / Setup. Evidence: L5675–L5676, L5697–L5704.
|
||||
- **virtqueue → Guest:** frontend. Evidence: L5677–L5677, L5731–L5739.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다
|
||||
# Question: 설정하는 경로와 packet 이 흐르는 경로는 어디에서 갈라지고, 그 두 갈래 가운데 어느 쪽이 QEMU 사용자 공간을 지나는가
|
||||
direction: down
|
||||
direction: right
|
||||
n0: "virsh" {
|
||||
shape: rectangle
|
||||
}
|
||||
@@ -38,7 +38,7 @@ n11: "Guest" {
|
||||
shape: rectangle
|
||||
}
|
||||
n0 -> n1: "Control / Setup"
|
||||
n1 -> n2: "NIC/network configuration"
|
||||
n1 -> n2: "NIC config"
|
||||
n2 -> n3: "QEMU process"
|
||||
n4 -> n5: "Ethernet Frame"
|
||||
n5 -> n6: "L2 forwarding"
|
||||
@@ -49,4 +49,4 @@ n7 -> n8: "vhost-net 사용"
|
||||
n7 -> n9
|
||||
n8 -> n10: "Data Path"
|
||||
n9 -> n10: "Data Path"
|
||||
n10 -> n11: "virtio-net Frontend Driver"
|
||||
n10 -> n11: "frontend"
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="virsh", shape=box, style="rounded,filled"];
|
||||
n1 [label="libvirt", shape=box, style="rounded,filled"];
|
||||
n2 [label="QEMU", shape=box, style="rounded,filled"];
|
||||
n3 [label="virtio-net Device Model", shape=box, style="rounded,filled"];
|
||||
n4 [label="Physical NIC", shape=box, style="rounded,filled"];
|
||||
n5 [label="Physical NIC Driver", shape=box, style="rounded,filled"];
|
||||
n6 [label="Linux Bridge /\nRouting / NAT", shape=box, style="rounded,filled"];
|
||||
n7 [label="TAP", shape=box, style="rounded,filled"];
|
||||
n8 [label="vhost-net", shape=box, style="rounded,filled"];
|
||||
n9 [label="QEMU virtio backend", shape=box, style="rounded,filled"];
|
||||
n10 [label="virtqueue", shape=oval, style="rounded,filled"];
|
||||
n11 [label="Guest", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="Control / Setup", style=solid];
|
||||
n1 -> n2 [label="NIC config", style=solid];
|
||||
n2 -> n3 [label="QEMU process", style=solid];
|
||||
n4 -> n5 [label="Ethernet Frame", style=solid];
|
||||
n5 -> n6 [label="L2 forwarding", style=solid];
|
||||
n6 -> n7 [label="Ethernet Frame", style=solid];
|
||||
n3 -> n8 [label="vhost-net backend 설정", style=solid];
|
||||
n3 -> n9 [label="", style=solid];
|
||||
n7 -> n8 [label="vhost-net 사용", style=solid];
|
||||
n7 -> n9 [label="", style=solid];
|
||||
n8 -> n10 [label="Data Path", style=solid];
|
||||
n9 -> n10 [label="Data Path", style=solid];
|
||||
n10 -> n11 [label="frontend", style=solid];
|
||||
}
|
||||
@@ -1,110 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="packet-control-and-data-paths" name="control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다">
|
||||
<mxGraphModel dx="680" dy="1296" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1296" math="0" shadow="0">
|
||||
<mxGraphModel dx="2249" dy="390" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2249" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_virsh" value="virsh<br/>User" tooltip="VM/network 관리 CLI. packet datapath 에는 직접 참여하지 않는다. | Evidence: L5662-L5662, L5687-L5689" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="90.5" y="60.0" width="150.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_virsh" value="virsh<br/>User" tooltip="VM/network 관리 CLI. packet datapath 에는 직접 참여하지 않는다. | Evidence: L5675-L5675, L5700-L5702" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="99.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_physical-nic" value="Physical NIC" tooltip="밖에서 온 packet 이 처음 닿는 하드웨어. | Evidence: L5706-L5708" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="300.5" y="63.5" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_physical-nic" value="Physical NIC" tooltip="밖에서 온 packet 이 처음 닿는 하드웨어. | Evidence: L5719-L5721" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="242.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_libvirt" value="libvirt" tooltip="VM lifecycle 과 NIC/network configuration 을 관리한다. | Evidence: L5663-L5663, L5691-L5691" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="82.0" y="227.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_libvirt" value="libvirt" tooltip="VM lifecycle 과 NIC/network configuration 을 관리한다. | Evidence: L5676-L5676, L5704-L5704" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="388.5" y="102.5" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_physical-nic-driver" value="Physical NIC Driver" tooltip="그 하드웨어를 제어하는 Host kernel driver. | Evidence: L5674-L5674, L5710-L5710" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="292.0" y="227.0" width="167.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_physical-nic-driver" value="Physical NIC Driver" tooltip="그 하드웨어를 제어하는 Host kernel driver. | Evidence: L5687-L5687, L5723-L5723" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="380.0" y="238.5" width="167.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_qemu" value="QEMU<br/>Host Userspace" tooltip="실제로 실행되는 프로세스. 이 안에 virtio-net device model 이 있다. | Evidence: L5666-L5666, L5693-L5693" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="90.5" y="388.5" width="150.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_qemu" value="QEMU<br/>Host Userspace" tooltip="실제로 실행되는 프로세스. 이 안에 virtio-net device model 이 있다. | Evidence: L5679-L5679, L5706-L5706" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="707.0" y="94.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_linux-bridge" value="Linux Bridge /
|
||||
Routing / NAT" tooltip="L2 software switch 와 L3 routing, 주소 변환이 놓이는 자리. | Evidence: L5672-L5673, L5712-L5712" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="300.5" y="387.0" width="150.0" height="74.0" as="geometry"/>
|
||||
Routing / NAT" tooltip="L2 software switch 와 L3 routing, 주소 변환이 놓이는 자리. | Evidence: L5685-L5686, L5725-L5725" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="707.0" y="237.0" width="150.0" height="74.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_virtio-net-device-model" value="virtio-net Device Model<br/>virtual NIC 생성<br/>feature negotiation<br/>virtqueue 설정<br/>vhost-net backend 설정" tooltip="control/setup path 가 닿는 자리. 장치를 만들고 backend 를 연결한다. | Evidence: L5666-L5666, L5695-L5700" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="557.0" width="174.0" height="142.0" as="geometry"/>
|
||||
<mxCell id="n_virtio-net-device-model" value="virtio-net Device Model<br/>virtual NIC 생성<br/>feature negotiation<br/>virtqueue 설정<br/>vhost-net backend 설정" tooltip="control/setup path 가 닿는 자리. 장치를 만들고 backend 를 연결한다. | Evidence: L5679-L5679, L5708-L5713" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="1017.0" y="60.0" width="174.0" height="142.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_tap" value="TAP<br/>Host-side interface" tooltip="VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점. | Evidence: L5671-L5671, L5714-L5714" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="304.0" y="592.5" width="167.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_tap" value="TAP<br/>Host-side interface" tooltip="VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점. | Evidence: L5684-L5684, L5727-L5727" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1020.5" y="274.0" width="167.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_qemu-virtio-backend" value="QEMU virtio backend<br/>QEMU Userspace" tooltip="vhost-net 을 쓰지 않을 때 datapath backend 를 맡는 쪽. | Evidence: L5668-L5668, L5742-L5742" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="82.0" y="795.0" width="167.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_qemu-virtio-backend" value="QEMU virtio backend<br/>QEMU Userspace" tooltip="vhost-net 을 쓰지 않을 때 datapath backend 를 맡는 쪽. | Evidence: L5681-L5681, L5755-L5755" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1351.0" y="95.5" width="167.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_vhost-net" value="vhost-net<br/>Host Kernel" tooltip="반복되는 packet datapath 를 Host kernel 에서 처리하는 backend. | Evidence: L5669-L5669, L5716-L5716" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="309.0" y="795.0" width="150.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_vhost-net" value="vhost-net<br/>Host Kernel" tooltip="반복되는 packet datapath 를 Host kernel 에서 처리하는 backend. | Evidence: L5682-L5682, L5729-L5729" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1359.5" y="238.5" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_virtqueue" value="virtqueue<br/>shared queue" tooltip="Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 공유 큐. | Evidence: L5667-L5667, L5718-L5718" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="195.5" y="962.0" width="150.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_virtqueue" value="virtqueue<br/>shared queue" tooltip="Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 공유 큐. | Evidence: L5680-L5680, L5731-L5731" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1678.0" y="167.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_guest" value="Guest<br/>virtio-net Frontend Driver<br/>Guest TCP/IP Stack<br/>Socket<br/>Keycloak" tooltip="packet 이 올라가 애플리케이션 socket 에 닿는 쪽. | Evidence: L5664-L5665, L5720-L5726" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="162.5" y="1129.0" width="216.0" height="122.0" as="geometry"/>
|
||||
<mxCell id="n_guest" value="Guest<br/>virtio-net Frontend Driver<br/>Guest TCP/IP Stack<br/>Socket<br/>Keycloak" tooltip="packet 이 올라가 애플리케이션 socket 에 닿는 쪽. | Evidence: L5677-L5678, L5733-L5739" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1988.0" y="141.5" width="216.0" height="122.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_bridge-to-tap" value="Ethernet Frame" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_linux-bridge" target="n_tap">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="381.5" y="498.8" as="offset"/>
|
||||
<mxPoint x="962.8" y="291.8" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_driver-to-bridge" value="L2 forwarding" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_physical-nic-driver" target="n_linux-bridge">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="399.5" y="339.0" as="offset"/>
|
||||
<mxPoint x="651.0" y="272.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_libvirt-to-qemu" value="NIC/network configuration" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_libvirt" target="n_qemu">
|
||||
<mxCell id="e_libvirt-to-qemu" value="NIC config" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_libvirt" target="n_qemu">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="161.2" y="311.8" as="offset"/>
|
||||
<mxPoint x="646.8" y="132.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_nic-to-driver" value="Ethernet Frame" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_physical-nic" target="n_physical-nic-driver">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="399.5" y="177.2" as="offset"/>
|
||||
<mxPoint x="324.0" y="272.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_qemu-backend-to-virtqueue" value="Data Path" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu-virtio-backend" target="n_virtqueue">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="213.5" y="886.0" as="offset"/>
|
||||
<mxPoint x="1622.0" y="162.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_qemu-to-device-model" value="QEMU process" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu" target="n_virtio-net-device-model">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="161.2" y="480.2" as="offset"/>
|
||||
<mxPoint x="961.0" y="130.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_setup-qemu-backend" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtio-net-device-model" target="n_qemu-virtio-backend">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="152.2" y="719.0" as="offset"/>
|
||||
<mxPoint x="1271.0" y="94.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_setup-vhost-backend" value="vhost-net backend 설정" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtio-net-device-model" target="n_vhost-net">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="270.5" y="719.0" as="offset"/>
|
||||
<mxPoint x="1299.2" y="202.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_tap-to-qemu-backend" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_tap" target="n_qemu-virtio-backend">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="276.5" y="701.2" as="offset"/>
|
||||
<mxPoint x="1293.2" y="220.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_tap-to-vhost" value="vhost-net 사용" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_tap" target="n_vhost-net">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="394.8" y="701.2" as="offset"/>
|
||||
<mxPoint x="1297.5" y="300.8" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_vhost-to-virtqueue" value="Data Path" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_vhost-net" target="n_virtqueue">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="331.8" y="886.0" as="offset"/>
|
||||
<mxPoint x="1617.8" y="242.8" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_virsh-to-libvirt" value="Control / Setup" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virsh" target="n_libvirt">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="161.2" y="151.0" as="offset"/>
|
||||
<mxPoint x="304.2" y="106.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_virtqueue-to-guest" value="virtio-net Frontend Driver" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtqueue" target="n_guest">
|
||||
<mxCell id="e_virtqueue-to-guest" value="frontend" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtqueue" target="n_guest">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="294.5" y="1081.0" as="offset"/>
|
||||
<mxPoint x="1908.0" y="174.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
{
|
||||
"id": "edge-bridge-to-tap",
|
||||
"type": "arrow",
|
||||
"x": 375.5,
|
||||
"y": 461.0,
|
||||
"width": 12.0,
|
||||
"height": 131.5,
|
||||
"x": 857.0,
|
||||
"y": 274.0,
|
||||
"width": 163.5,
|
||||
"height": 35.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -36,16 +36,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
65.75
|
||||
81.75,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
12.0,
|
||||
65.75
|
||||
81.75,
|
||||
35.5
|
||||
],
|
||||
[
|
||||
12.0,
|
||||
131.5
|
||||
163.5,
|
||||
35.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -66,8 +66,8 @@
|
||||
{
|
||||
"id": "edge-label-bridge-to-tap",
|
||||
"type": "text",
|
||||
"x": 325.5,
|
||||
"y": 486.75,
|
||||
"x": 906.75,
|
||||
"y": 279.75,
|
||||
"width": 112,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -105,10 +105,10 @@
|
||||
{
|
||||
"id": "edge-driver-to-bridge",
|
||||
"type": "arrow",
|
||||
"x": 375.5,
|
||||
"y": 291.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 547.0,
|
||||
"y": 270.5,
|
||||
"width": 160.0,
|
||||
"height": 3.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -135,16 +135,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
3.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
160.0,
|
||||
3.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -165,8 +165,8 @@
|
||||
{
|
||||
"id": "edge-label-driver-to-bridge",
|
||||
"type": "text",
|
||||
"x": 347.5,
|
||||
"y": 327.0,
|
||||
"x": 599.0,
|
||||
"y": 260.25,
|
||||
"width": 104,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -204,10 +204,10 @@
|
||||
{
|
||||
"id": "edge-libvirt-to-qemu",
|
||||
"type": "arrow",
|
||||
"x": 157.0,
|
||||
"y": 291.0,
|
||||
"width": 8.5,
|
||||
"height": 97.5,
|
||||
"x": 538.5,
|
||||
"y": 129.5,
|
||||
"width": 168.5,
|
||||
"height": 5.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -231,19 +231,19 @@
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
5.0
|
||||
],
|
||||
[
|
||||
84.25,
|
||||
5.0
|
||||
],
|
||||
[
|
||||
84.25,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.75
|
||||
],
|
||||
[
|
||||
8.5,
|
||||
48.75
|
||||
],
|
||||
[
|
||||
8.5,
|
||||
97.5
|
||||
168.5,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -264,9 +264,9 @@
|
||||
{
|
||||
"id": "edge-label-libvirt-to-qemu",
|
||||
"type": "text",
|
||||
"x": 61.25,
|
||||
"y": 299.75,
|
||||
"width": 200,
|
||||
"x": 601.75,
|
||||
"y": 120.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
@@ -292,21 +292,21 @@
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "NIC/network configuration",
|
||||
"text": "NIC config",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "NIC/network configuration",
|
||||
"originalText": "NIC config",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-nic-to-driver",
|
||||
"type": "arrow",
|
||||
"x": 375.5,
|
||||
"y": 127.5,
|
||||
"width": 0.0,
|
||||
"height": 99.5,
|
||||
"x": 220.0,
|
||||
"y": 270.5,
|
||||
"width": 160.0,
|
||||
"height": 3.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -330,19 +330,19 @@
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
3.5
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
3.5
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
49.75
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
49.75
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
99.5
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -363,8 +363,8 @@
|
||||
{
|
||||
"id": "edge-label-nic-to-driver",
|
||||
"type": "text",
|
||||
"x": 343.5,
|
||||
"y": 165.25,
|
||||
"x": 268.0,
|
||||
"y": 260.25,
|
||||
"width": 112,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -402,10 +402,10 @@
|
||||
{
|
||||
"id": "edge-qemu-backend-to-virtqueue",
|
||||
"type": "arrow",
|
||||
"x": 165.5,
|
||||
"y": 866.0,
|
||||
"width": 96.0,
|
||||
"height": 96.0,
|
||||
"x": 1518.0,
|
||||
"y": 131.0,
|
||||
"width": 160.0,
|
||||
"height": 62.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -432,16 +432,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
96.0,
|
||||
48.0
|
||||
80.0,
|
||||
62.5
|
||||
],
|
||||
[
|
||||
96.0,
|
||||
96.0
|
||||
160.0,
|
||||
62.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -462,8 +462,8 @@
|
||||
{
|
||||
"id": "edge-label-qemu-backend-to-virtqueue",
|
||||
"type": "text",
|
||||
"x": 168.5,
|
||||
"y": 874.0,
|
||||
"x": 1577.0,
|
||||
"y": 150.25,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -501,10 +501,10 @@
|
||||
{
|
||||
"id": "edge-qemu-to-device-model",
|
||||
"type": "arrow",
|
||||
"x": 157.0,
|
||||
"y": 459.5,
|
||||
"width": 8.5,
|
||||
"height": 97.5,
|
||||
"x": 857.0,
|
||||
"y": 129.5,
|
||||
"width": 160.0,
|
||||
"height": 1.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -527,20 +527,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
8.5,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
8.5,
|
||||
48.75
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.75
|
||||
80.0,
|
||||
1.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
97.5
|
||||
160.0,
|
||||
1.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -561,8 +561,8 @@
|
||||
{
|
||||
"id": "edge-label-qemu-to-device-model",
|
||||
"type": "text",
|
||||
"x": 113.25,
|
||||
"y": 468.25,
|
||||
"x": 913.0,
|
||||
"y": 118.25,
|
||||
"width": 96,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -600,10 +600,10 @@
|
||||
{
|
||||
"id": "edge-setup-qemu-backend",
|
||||
"type": "arrow",
|
||||
"x": 148.0,
|
||||
"y": 699.0,
|
||||
"width": 8.5,
|
||||
"height": 96.0,
|
||||
"x": 1191.0,
|
||||
"y": 122.0,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -630,16 +630,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
8.5,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
8.5,
|
||||
96.0
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -660,10 +660,10 @@
|
||||
{
|
||||
"id": "edge-setup-vhost-backend",
|
||||
"type": "arrow",
|
||||
"x": 166.0,
|
||||
"y": 699.0,
|
||||
"width": 209.0,
|
||||
"height": 96.0,
|
||||
"x": 1191.0,
|
||||
"y": 140.0,
|
||||
"width": 168.5,
|
||||
"height": 125.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -690,16 +690,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
84.25,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
209.0,
|
||||
48.0
|
||||
84.25,
|
||||
125.0
|
||||
],
|
||||
[
|
||||
209.0,
|
||||
96.0
|
||||
168.5,
|
||||
125.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -720,8 +720,8 @@
|
||||
{
|
||||
"id": "edge-label-setup-vhost-backend",
|
||||
"type": "text",
|
||||
"x": 190.5,
|
||||
"y": 707.0,
|
||||
"x": 1219.25,
|
||||
"y": 190.5,
|
||||
"width": 160,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -759,10 +759,10 @@
|
||||
{
|
||||
"id": "edge-tap-to-qemu-backend",
|
||||
"type": "arrow",
|
||||
"x": 174.5,
|
||||
"y": 663.5,
|
||||
"width": 204.0,
|
||||
"height": 131.5,
|
||||
"x": 1187.5,
|
||||
"y": 140.0,
|
||||
"width": 163.5,
|
||||
"height": 160.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -785,20 +785,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
204.0,
|
||||
0.0,
|
||||
160.5
|
||||
],
|
||||
[
|
||||
81.75,
|
||||
160.5
|
||||
],
|
||||
[
|
||||
81.75,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
204.0,
|
||||
65.75
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
65.75
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
131.5
|
||||
163.5,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -819,10 +819,10 @@
|
||||
{
|
||||
"id": "edge-tap-to-vhost",
|
||||
"type": "arrow",
|
||||
"x": 393.0,
|
||||
"y": 663.5,
|
||||
"width": 3.5,
|
||||
"height": 131.5,
|
||||
"x": 1187.5,
|
||||
"y": 283.0,
|
||||
"width": 172.0,
|
||||
"height": 35.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -845,20 +845,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
3.5,
|
||||
0.0,
|
||||
35.5
|
||||
],
|
||||
[
|
||||
86.0,
|
||||
35.5
|
||||
],
|
||||
[
|
||||
86.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
3.5,
|
||||
65.75
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
65.75
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
131.5
|
||||
172.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -879,8 +879,8 @@
|
||||
{
|
||||
"id": "edge-label-tap-to-vhost",
|
||||
"type": "text",
|
||||
"x": 346.75,
|
||||
"y": 689.25,
|
||||
"x": 1249.5,
|
||||
"y": 288.75,
|
||||
"width": 96,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -918,10 +918,10 @@
|
||||
{
|
||||
"id": "edge-vhost-to-virtqueue",
|
||||
"type": "arrow",
|
||||
"x": 279.5,
|
||||
"y": 866.0,
|
||||
"width": 104.5,
|
||||
"height": 96.0,
|
||||
"x": 1509.5,
|
||||
"y": 211.5,
|
||||
"width": 168.5,
|
||||
"height": 62.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -944,20 +944,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
104.5,
|
||||
0.0,
|
||||
62.5
|
||||
],
|
||||
[
|
||||
84.25,
|
||||
62.5
|
||||
],
|
||||
[
|
||||
84.25,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
104.5,
|
||||
48.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
168.5,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -978,8 +978,8 @@
|
||||
{
|
||||
"id": "edge-label-vhost-to-virtqueue",
|
||||
"type": "text",
|
||||
"x": 286.75,
|
||||
"y": 874.0,
|
||||
"x": 1572.75,
|
||||
"y": 230.75,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -1017,10 +1017,10 @@
|
||||
{
|
||||
"id": "edge-virsh-to-libvirt",
|
||||
"type": "arrow",
|
||||
"x": 157.0,
|
||||
"y": 131.0,
|
||||
"width": 8.5,
|
||||
"height": 96.0,
|
||||
"x": 220.0,
|
||||
"y": 134.5,
|
||||
"width": 168.5,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -1043,20 +1043,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
8.5,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
8.5,
|
||||
48.0
|
||||
84.25,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
84.25,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
168.5,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -1077,8 +1077,8 @@
|
||||
{
|
||||
"id": "edge-label-virsh-to-libvirt",
|
||||
"type": "text",
|
||||
"x": 101.25,
|
||||
"y": 139.0,
|
||||
"x": 244.25,
|
||||
"y": 94.5,
|
||||
"width": 120,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -1116,10 +1116,10 @@
|
||||
{
|
||||
"id": "edge-virtqueue-to-guest",
|
||||
"type": "arrow",
|
||||
"x": 270.5,
|
||||
"y": 1033.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 1828.0,
|
||||
"y": 202.5,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -1146,16 +1146,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -1176,9 +1176,9 @@
|
||||
{
|
||||
"id": "edge-label-virtqueue-to-guest",
|
||||
"type": "text",
|
||||
"x": 190.5,
|
||||
"y": 1069.0,
|
||||
"width": 208,
|
||||
"x": 1863.0,
|
||||
"y": 162.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
@@ -1204,19 +1204,19 @@
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "virtio-net Frontend Driver",
|
||||
"text": "frontend",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "virtio-net Frontend Driver",
|
||||
"originalText": "frontend",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-virsh",
|
||||
"type": "rectangle",
|
||||
"x": 90.5,
|
||||
"y": 60.0,
|
||||
"x": 70.0,
|
||||
"y": 99.0,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -1245,8 +1245,8 @@
|
||||
{
|
||||
"id": "node-label-virsh",
|
||||
"type": "text",
|
||||
"x": 100.5,
|
||||
"y": 70.0,
|
||||
"x": 80.0,
|
||||
"y": 109.0,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -1284,8 +1284,8 @@
|
||||
{
|
||||
"id": "node-physical-nic",
|
||||
"type": "rectangle",
|
||||
"x": 300.5,
|
||||
"y": 63.5,
|
||||
"x": 70.0,
|
||||
"y": 242.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1314,8 +1314,8 @@
|
||||
{
|
||||
"id": "node-label-physical-nic",
|
||||
"type": "text",
|
||||
"x": 310.5,
|
||||
"y": 73.5,
|
||||
"x": 80.0,
|
||||
"y": 252.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -1353,8 +1353,8 @@
|
||||
{
|
||||
"id": "node-libvirt",
|
||||
"type": "rectangle",
|
||||
"x": 82.0,
|
||||
"y": 227.0,
|
||||
"x": 388.5,
|
||||
"y": 102.5,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1383,8 +1383,8 @@
|
||||
{
|
||||
"id": "node-label-libvirt",
|
||||
"type": "text",
|
||||
"x": 92.0,
|
||||
"y": 237.0,
|
||||
"x": 398.5,
|
||||
"y": 112.5,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -1422,8 +1422,8 @@
|
||||
{
|
||||
"id": "node-physical-nic-driver",
|
||||
"type": "rectangle",
|
||||
"x": 292.0,
|
||||
"y": 227.0,
|
||||
"x": 380.0,
|
||||
"y": 238.5,
|
||||
"width": 167.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -1452,8 +1452,8 @@
|
||||
{
|
||||
"id": "node-label-physical-nic-driver",
|
||||
"type": "text",
|
||||
"x": 302.0,
|
||||
"y": 237.0,
|
||||
"x": 390.0,
|
||||
"y": 248.5,
|
||||
"width": 147.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -1491,8 +1491,8 @@
|
||||
{
|
||||
"id": "node-qemu",
|
||||
"type": "rectangle",
|
||||
"x": 90.5,
|
||||
"y": 388.5,
|
||||
"x": 707.0,
|
||||
"y": 94.0,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -1521,8 +1521,8 @@
|
||||
{
|
||||
"id": "node-label-qemu",
|
||||
"type": "text",
|
||||
"x": 100.5,
|
||||
"y": 398.5,
|
||||
"x": 717.0,
|
||||
"y": 104.0,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -1560,8 +1560,8 @@
|
||||
{
|
||||
"id": "node-linux-bridge",
|
||||
"type": "rectangle",
|
||||
"x": 300.5,
|
||||
"y": 387.0,
|
||||
"x": 707.0,
|
||||
"y": 237.0,
|
||||
"width": 150.0,
|
||||
"height": 74.0,
|
||||
"angle": 0,
|
||||
@@ -1590,8 +1590,8 @@
|
||||
{
|
||||
"id": "node-label-linux-bridge",
|
||||
"type": "text",
|
||||
"x": 310.5,
|
||||
"y": 397.0,
|
||||
"x": 717.0,
|
||||
"y": 247.0,
|
||||
"width": 130.0,
|
||||
"height": 54.0,
|
||||
"angle": 0,
|
||||
@@ -1629,8 +1629,8 @@
|
||||
{
|
||||
"id": "node-virtio-net-device-model",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 557.0,
|
||||
"x": 1017.0,
|
||||
"y": 60.0,
|
||||
"width": 174.0,
|
||||
"height": 142.0,
|
||||
"angle": 0,
|
||||
@@ -1659,8 +1659,8 @@
|
||||
{
|
||||
"id": "node-label-virtio-net-device-model",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 567.0,
|
||||
"x": 1027.0,
|
||||
"y": 70.0,
|
||||
"width": 154.0,
|
||||
"height": 122.0,
|
||||
"angle": 0,
|
||||
@@ -1698,8 +1698,8 @@
|
||||
{
|
||||
"id": "node-tap",
|
||||
"type": "rectangle",
|
||||
"x": 304.0,
|
||||
"y": 592.5,
|
||||
"x": 1020.5,
|
||||
"y": 274.0,
|
||||
"width": 167.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -1728,8 +1728,8 @@
|
||||
{
|
||||
"id": "node-label-tap",
|
||||
"type": "text",
|
||||
"x": 314.0,
|
||||
"y": 602.5,
|
||||
"x": 1030.5,
|
||||
"y": 284.0,
|
||||
"width": 147.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -1767,8 +1767,8 @@
|
||||
{
|
||||
"id": "node-qemu-virtio-backend",
|
||||
"type": "rectangle",
|
||||
"x": 82.0,
|
||||
"y": 795.0,
|
||||
"x": 1351.0,
|
||||
"y": 95.5,
|
||||
"width": 167.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -1797,8 +1797,8 @@
|
||||
{
|
||||
"id": "node-label-qemu-virtio-backend",
|
||||
"type": "text",
|
||||
"x": 92.0,
|
||||
"y": 805.0,
|
||||
"x": 1361.0,
|
||||
"y": 105.5,
|
||||
"width": 147.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -1836,8 +1836,8 @@
|
||||
{
|
||||
"id": "node-vhost-net",
|
||||
"type": "rectangle",
|
||||
"x": 309.0,
|
||||
"y": 795.0,
|
||||
"x": 1359.5,
|
||||
"y": 238.5,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -1866,8 +1866,8 @@
|
||||
{
|
||||
"id": "node-label-vhost-net",
|
||||
"type": "text",
|
||||
"x": 319.0,
|
||||
"y": 805.0,
|
||||
"x": 1369.5,
|
||||
"y": 248.5,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -1905,8 +1905,8 @@
|
||||
{
|
||||
"id": "node-virtqueue",
|
||||
"type": "rectangle",
|
||||
"x": 195.5,
|
||||
"y": 962.0,
|
||||
"x": 1678.0,
|
||||
"y": 167.0,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -1935,8 +1935,8 @@
|
||||
{
|
||||
"id": "node-label-virtqueue",
|
||||
"type": "text",
|
||||
"x": 205.5,
|
||||
"y": 972.0,
|
||||
"x": 1688.0,
|
||||
"y": 177.0,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -1974,8 +1974,8 @@
|
||||
{
|
||||
"id": "node-guest",
|
||||
"type": "rectangle",
|
||||
"x": 162.5,
|
||||
"y": 1129.0,
|
||||
"x": 1988.0,
|
||||
"y": 141.5,
|
||||
"width": 216.0,
|
||||
"height": 122.0,
|
||||
"angle": 0,
|
||||
@@ -2004,8 +2004,8 @@
|
||||
{
|
||||
"id": "node-label-guest",
|
||||
"type": "text",
|
||||
"x": 172.5,
|
||||
"y": 1139.0,
|
||||
"x": 1998.0,
|
||||
"y": 151.5,
|
||||
"width": 196.0,
|
||||
"height": 102.0,
|
||||
"angle": 0,
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "packet-control-and-data-paths",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "fa2d5e22352fa6cf975665cd431a236deaa4ae88ea0eb8461bb1b3c8b0b03dc6",
|
||||
"spec_sha256": "5ad8e6e91ced885c14673ed8b75153b054376278d256fa39f26aba1df9ed947b",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "125. 최종 기준 구조",
|
||||
"line": 5682
|
||||
"line": 5695
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"packet-control-and-data-paths.svg",
|
||||
"packet-control-and-data-paths.drawio",
|
||||
"packet-control-and-data-paths.mmd",
|
||||
"packet-control-and-data-paths.d2",
|
||||
"packet-control-and-data-paths.dot",
|
||||
"packet-control-and-data-paths.drawio",
|
||||
"packet-control-and-data-paths.excalidraw",
|
||||
"packet-control-and-data-paths.alt.md"
|
||||
],
|
||||
@@ -27,5 +28,15 @@
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "cf22eb6977c1e3e1d493881d30604c345489c58bce67e8b76e854f4117ba2788",
|
||||
"output_sha256": {
|
||||
"packet-control-and-data-paths.svg": "82845b88520456296032041122e937ae087fb0521dfcdd510d589f1cbe12eb70",
|
||||
"packet-control-and-data-paths.mmd": "53a570ae187c9f35848eab3df4401d73ebd5be465a05067fb231ff36358a68ed",
|
||||
"packet-control-and-data-paths.d2": "316908b56f29c6b508d133c8c5b6baa9dfe6aa5348540f8877fd798480a21039",
|
||||
"packet-control-and-data-paths.dot": "32fbc68beb83b176eef7e12b966cb8eb6e589881dc6d6a4aeb77434a0c0bc396",
|
||||
"packet-control-and-data-paths.drawio": "ee81cf96da5e4d6b70c8dc35ad0f77c043d493157e9be49608e7ccf5b6aba2a7",
|
||||
"packet-control-and-data-paths.excalidraw": "dec21227b4a33abfdcb8087f417933dd3f00c3ead46890d505bfb05a8b847c3b",
|
||||
"packet-control-and-data-paths.alt.md": "c21d6531f69bc6e02826e1306d327920108cf6b010ac94588011a92387f16125"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%% control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다
|
||||
%% question: 설정하는 경로와 packet 이 흐르는 경로는 어디에서 갈라지고, 그 두 갈래 가운데 어느 쪽이 QEMU 사용자 공간을 지나는가
|
||||
flowchart TB
|
||||
flowchart LR
|
||||
n0["virsh"]
|
||||
n1["libvirt"]
|
||||
n2["QEMU"]
|
||||
@@ -14,7 +14,7 @@ flowchart TB
|
||||
n10(["virtqueue"])
|
||||
n11["Guest"]
|
||||
n0 -->|"Control / Setup"| n1
|
||||
n1 -->|"NIC/network configuration"| n2
|
||||
n1 -->|"NIC config"| n2
|
||||
n2 -->|"QEMU process"| n3
|
||||
n4 -->|"Ethernet Frame"| n5
|
||||
n5 -->|"L2 forwarding"| n6
|
||||
@@ -25,4 +25,4 @@ flowchart TB
|
||||
n7 --> n9
|
||||
n8 -->|"Data Path"| n10
|
||||
n9 -->|"Data Path"| n10
|
||||
n10 -->|"virtio-net Frontend Driver"| n11
|
||||
n10 -->|"frontend"| n11
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="1296" viewBox="0 0 680 1296" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="2249" height="390" viewBox="0 0 2249 390" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다</title>
|
||||
<desc id="diagram-description">왼쪽에서 오른쪽으로 읽는다. 위쪽 줄이 control/setup path 다. virsh 에서 libvirt 와 QEMU 를 지나 virtio-net Device Model 에 닿고, 그 device model 이 virtual NIC 생성과 feature negotiation, virtqueue 설정, vhost-net backend 설정을 맡는다. 아래쪽 줄이 data path 다. Physical NIC 에서 Physical NIC Driver 와 Linux Bridge, TAP 까지 온다. 두 줄은 네 번째 열 다음에서 만난다. device model 은 점선으로 backend 둘을 설정하고, TAP 은 실선으로 그 둘 가운데 실제로 쓰는 쪽에 packet 을 넘긴다. vhost-net 을 쓰면 packet 은 Host Kernel 안에서 처리돼 QEMU 사용자 공간을 지나지 않고, QEMU virtio backend 를 쓰면 같은 packet 이 QEMU 사용자 공간을 지난다. 어느 쪽이든 virtqueue 에서 만나 Guest 로 올라간다. 이 Host 가 둘 중 어느 backend 를 쓰고 있는지는 그림이 말하지 않는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"packet-control-and-data-paths","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"125. 최종 기준 구조","line":5682}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"packet-control-and-data-paths","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"125. 최종 기준 구조","line":5695}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -49,112 +49,112 @@
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="680" height="1296" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="375.5,461.0 375.5,526.8 387.5,526.8 387.5,592.5" data-evidence="5671-5671,5712-5714" />
|
||||
<rect class="edge-label-bg" x="325.6" y="484.8" width="111.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="381.5" y="499.8">Ethernet Frame</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="375.5,291.0 375.5,339.0 375.5,339.0 375.5,387.0" data-evidence="5672-5672,5710-5712" />
|
||||
<rect class="edge-label-bg" x="346.9" y="325.0" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="399.5" y="340.0">L2 forwarding</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="157.0,291.0 157.0,339.8 165.5,339.8 165.5,388.5" data-evidence="5663-5663,5691-5693" />
|
||||
<rect class="edge-label-bg" x="68.5" y="297.8" width="185.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="161.2" y="312.8">NIC/network configuration</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="375.5,127.5 375.5,177.2 375.5,177.2 375.5,227.0" data-evidence="5671-5671,5708-5710" />
|
||||
<rect class="edge-label-bg" x="343.6" y="163.2" width="111.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="399.5" y="178.2">Ethernet Frame</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="165.5,866.0 165.5,914.0 261.5,914.0 261.5,962.0" data-evidence="5729-5729,5742-5744" />
|
||||
<rect class="edge-label-bg" x="174.3" y="872.0" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="213.5" y="887.0">Data Path</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="165.5,459.5 165.5,508.2 157.0,508.2 157.0,557.0" data-evidence="5666-5666,5693-5695" />
|
||||
<rect class="edge-label-bg" x="112.0" y="466.2" width="98.4" height="22" rx="3" />
|
||||
<text class="edge-label" x="161.2" y="481.2">QEMU process</text>
|
||||
<polyline class="edge kind-control style-dashed emphasis-normal" points="148.0,699.0 148.0,747.0 156.5,747.0 156.5,795.0" data-evidence="5668-5668,5700-5700" />
|
||||
<polyline class="edge kind-control style-dashed emphasis-normal" points="166.0,699.0 166.0,747.0 375.0,747.0 375.0,795.0" data-evidence="5700-5700,5716-5716" />
|
||||
<rect class="edge-label-bg" x="194.5" y="705.0" width="152.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="270.5" y="720.0">vhost-net backend 설정</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="378.5,663.5 378.5,729.2 174.5,729.2 174.5,795.0" data-evidence="5729-5729,5740-5742" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="396.5,663.5 396.5,729.2 393.0,729.2 393.0,795.0" data-evidence="5703-5703,5714-5716" />
|
||||
<rect class="edge-label-bg" x="345.6" y="687.2" width="98.4" height="22" rx="3" />
|
||||
<text class="edge-label" x="394.8" y="702.2">vhost-net 사용</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="384.0,866.0 384.0,914.0 279.5,914.0 279.5,962.0" data-evidence="5703-5703,5716-5718" />
|
||||
<rect class="edge-label-bg" x="292.6" y="872.0" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="331.8" y="887.0">Data Path</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="165.5,131.0 165.5,179.0 157.0,179.0 157.0,227.0" data-evidence="5662-5663,5684-5691" />
|
||||
<rect class="edge-label-bg" x="102.0" y="137.0" width="118.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="161.2" y="152.0">Control / Setup</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="270.5,1033.0 270.5,1081.0 270.5,1081.0 270.5,1129.0" data-evidence="5664-5664,5718-5726" />
|
||||
<rect class="edge-label-bg" x="198.4" y="1067.0" width="192.2" height="22" rx="3" />
|
||||
<text class="edge-label" x="294.5" y="1082.0">virtio-net Frontend Driver</text>
|
||||
<rect class="canvas" width="2249" height="390" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="857.0,274.0 938.8,274.0 938.8,309.5 1020.5,309.5" data-evidence="5684-5684,5725-5727" />
|
||||
<rect class="edge-label-bg" x="906.9" y="277.8" width="111.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="962.8" y="292.8">Ethernet Frame</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="547.0,270.5 627.0,270.5 627.0,274.0 707.0,274.0" data-evidence="5685-5685,5723-5725" />
|
||||
<rect class="edge-label-bg" x="598.5" y="258.2" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="651.0" y="273.2">L2 forwarding</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="538.5,134.5 622.8,134.5 622.8,129.5 707.0,129.5" data-evidence="5676-5676,5704-5706" />
|
||||
<rect class="edge-label-bg" x="604.2" y="118.0" width="85.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="646.8" y="133.0">NIC config</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="220.0,274.0 300.0,274.0 300.0,270.5 380.0,270.5" data-evidence="5684-5684,5721-5723" />
|
||||
<rect class="edge-label-bg" x="268.1" y="258.2" width="111.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="324.0" y="273.2">Ethernet Frame</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="1518.0,131.0 1598.0,131.0 1598.0,193.5 1678.0,193.5" data-evidence="5742-5742,5755-5757" />
|
||||
<rect class="edge-label-bg" x="1582.8" y="148.2" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="1622.0" y="163.2">Data Path</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="857.0,129.5 937.0,129.5 937.0,131.0 1017.0,131.0" data-evidence="5679-5679,5706-5708" />
|
||||
<rect class="edge-label-bg" x="911.8" y="116.2" width="98.4" height="22" rx="3" />
|
||||
<text class="edge-label" x="961.0" y="131.2">QEMU process</text>
|
||||
<polyline class="edge kind-control style-dashed emphasis-normal" points="1191.0,122.0 1271.0,122.0 1271.0,122.0 1351.0,122.0" data-evidence="5681-5681,5713-5713" />
|
||||
<polyline class="edge kind-control style-dashed emphasis-normal" points="1191.0,140.0 1275.2,140.0 1275.2,265.0 1359.5,265.0" data-evidence="5713-5713,5729-5729" />
|
||||
<rect class="edge-label-bg" x="1223.2" y="188.5" width="152.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="1299.2" y="203.5">vhost-net backend 설정</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="1187.5,300.5 1269.2,300.5 1269.2,140.0 1351.0,140.0" data-evidence="5742-5742,5753-5755" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="1187.5,318.5 1273.5,318.5 1273.5,283.0 1359.5,283.0" data-evidence="5716-5716,5727-5729" />
|
||||
<rect class="edge-label-bg" x="1248.3" y="286.8" width="98.4" height="22" rx="3" />
|
||||
<text class="edge-label" x="1297.5" y="301.8">vhost-net 사용</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="1509.5,274.0 1593.8,274.0 1593.8,211.5 1678.0,211.5" data-evidence="5716-5716,5729-5731" />
|
||||
<rect class="edge-label-bg" x="1578.6" y="228.8" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="1617.8" y="243.8">Data Path</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="220.0,134.5 304.2,134.5 304.2,134.5 388.5,134.5" data-evidence="5675-5676,5697-5704" />
|
||||
<rect class="edge-label-bg" x="245.0" y="92.5" width="118.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="304.2" y="107.5">Control / Setup</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="1828.0,202.5 1908.0,202.5 1908.0,202.5 1988.0,202.5" data-evidence="5677-5677,5731-5739" />
|
||||
<rect class="edge-label-bg" x="1872.2" y="160.5" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="1908.0" y="175.5">frontend</text>
|
||||
<g id="node-virsh">
|
||||
<rect class="node-shape kind-cli emphasis-normal role-actor" data-evidence="5662-5662,5687-5689" x="90.5" y="60.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="165.5" y="87.0">virsh</text>
|
||||
<line class="node-detail-divider" x1="104.5" y1="108.0" x2="226.5" y2="108.0" />
|
||||
<text class="node-detail" x="106.5" y="125.0">User</text>
|
||||
<rect class="node-shape kind-cli emphasis-normal role-actor" data-evidence="5675-5675,5700-5702" x="70.0" y="99.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="126.0">virsh</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="147.0" x2="206.0" y2="147.0" />
|
||||
<text class="node-detail" x="86.0" y="164.0">User</text>
|
||||
</g>
|
||||
<g id="node-physical-nic">
|
||||
<rect class="node-shape kind-hardware emphasis-normal role-source" data-evidence="5706-5708" x="300.5" y="63.5" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="375.5" y="93.5">Physical NIC</text>
|
||||
<rect class="node-shape kind-hardware emphasis-normal role-source" data-evidence="5719-5721" x="70.0" y="242.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="272.0">Physical NIC</text>
|
||||
</g>
|
||||
<g id="node-libvirt">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5663-5663,5691-5691" x="82.0" y="227.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="157.0" y="257.0">libvirt</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5676-5676,5704-5704" x="388.5" y="102.5" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="463.5" y="132.5">libvirt</text>
|
||||
</g>
|
||||
<g id="node-physical-nic-driver">
|
||||
<rect class="node-shape kind-driver emphasis-normal role-service" data-evidence="5674-5674,5710-5710" x="292.0" y="227.0" width="167.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="375.5" y="257.0">Physical NIC Driver</text>
|
||||
<rect class="node-shape kind-driver emphasis-normal role-service" data-evidence="5687-5687,5723-5723" x="380.0" y="238.5" width="167.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="463.5" y="268.5">Physical NIC Driver</text>
|
||||
</g>
|
||||
<g id="node-qemu">
|
||||
<rect class="node-shape kind-process emphasis-normal role-service" data-evidence="5666-5666,5693-5693" x="90.5" y="388.5" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="165.5" y="415.5">QEMU</text>
|
||||
<line class="node-detail-divider" x1="104.5" y1="436.5" x2="226.5" y2="436.5" />
|
||||
<text class="node-detail" x="106.5" y="453.5">Host Userspace</text>
|
||||
<rect class="node-shape kind-process emphasis-normal role-service" data-evidence="5679-5679,5706-5706" x="707.0" y="94.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="782.0" y="121.0">QEMU</text>
|
||||
<line class="node-detail-divider" x1="721.0" y1="142.0" x2="843.0" y2="142.0" />
|
||||
<text class="node-detail" x="723.0" y="159.0">Host Userspace</text>
|
||||
</g>
|
||||
<g id="node-linux-bridge">
|
||||
<rect class="node-shape kind-network emphasis-normal role-service" data-evidence="5672-5673,5712-5712" x="300.5" y="387.0" width="150.0" height="74.0" rx="7" />
|
||||
<text class="node-label" x="375.5" y="414.0">Linux Bridge /</text>
|
||||
<text class="node-label" x="375.5" y="432.0">Routing / NAT</text>
|
||||
<rect class="node-shape kind-network emphasis-normal role-service" data-evidence="5685-5686,5725-5725" x="707.0" y="237.0" width="150.0" height="74.0" rx="7" />
|
||||
<text class="node-label" x="782.0" y="264.0">Linux Bridge /</text>
|
||||
<text class="node-label" x="782.0" y="282.0">Routing / NAT</text>
|
||||
</g>
|
||||
<g id="node-virtio-net-device-model">
|
||||
<rect class="node-shape kind-service emphasis-primary role-service" data-evidence="5666-5666,5695-5700" x="70.0" y="557.0" width="174.0" height="142.0" rx="7" />
|
||||
<text class="node-label" x="157.0" y="585.0">virtio-net Device</text>
|
||||
<text class="node-label" x="157.0" y="603.0">Model</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="624.0" x2="230.0" y2="624.0" />
|
||||
<text class="node-detail" x="86.0" y="641.0">virtual NIC 생성</text>
|
||||
<text class="node-detail" x="86.0" y="657.0">feature negotiation</text>
|
||||
<text class="node-detail" x="86.0" y="673.0">virtqueue 설정</text>
|
||||
<text class="node-detail" x="86.0" y="689.0">vhost-net backend 설정</text>
|
||||
<rect class="node-shape kind-service emphasis-primary role-service" data-evidence="5679-5679,5708-5713" x="1017.0" y="60.0" width="174.0" height="142.0" rx="7" />
|
||||
<text class="node-label" x="1104.0" y="88.0">virtio-net Device</text>
|
||||
<text class="node-label" x="1104.0" y="106.0">Model</text>
|
||||
<line class="node-detail-divider" x1="1031.0" y1="127.0" x2="1177.0" y2="127.0" />
|
||||
<text class="node-detail" x="1033.0" y="144.0">virtual NIC 생성</text>
|
||||
<text class="node-detail" x="1033.0" y="160.0">feature negotiation</text>
|
||||
<text class="node-detail" x="1033.0" y="176.0">virtqueue 설정</text>
|
||||
<text class="node-detail" x="1033.0" y="192.0">vhost-net backend 설정</text>
|
||||
</g>
|
||||
<g id="node-tap">
|
||||
<rect class="node-shape kind-network emphasis-normal role-service" data-evidence="5671-5671,5714-5714" x="304.0" y="592.5" width="167.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="387.5" y="619.5">TAP</text>
|
||||
<line class="node-detail-divider" x1="318.0" y1="640.5" x2="457.0" y2="640.5" />
|
||||
<text class="node-detail" x="320.0" y="657.5">Host-side interface</text>
|
||||
<rect class="node-shape kind-network emphasis-normal role-service" data-evidence="5684-5684,5727-5727" x="1020.5" y="274.0" width="167.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="1104.0" y="301.0">TAP</text>
|
||||
<line class="node-detail-divider" x1="1034.5" y1="322.0" x2="1173.5" y2="322.0" />
|
||||
<text class="node-detail" x="1036.5" y="339.0">Host-side interface</text>
|
||||
</g>
|
||||
<g id="node-qemu-virtio-backend">
|
||||
<rect class="node-shape kind-process emphasis-normal role-service" data-evidence="5668-5668,5742-5742" x="82.0" y="795.0" width="167.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="165.5" y="822.0">QEMU virtio backend</text>
|
||||
<line class="node-detail-divider" x1="96.0" y1="843.0" x2="235.0" y2="843.0" />
|
||||
<text class="node-detail" x="98.0" y="860.0">QEMU Userspace</text>
|
||||
<rect class="node-shape kind-process emphasis-normal role-service" data-evidence="5681-5681,5755-5755" x="1351.0" y="95.5" width="167.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="1434.5" y="122.5">QEMU virtio backend</text>
|
||||
<line class="node-detail-divider" x1="1365.0" y1="143.5" x2="1504.0" y2="143.5" />
|
||||
<text class="node-detail" x="1367.0" y="160.5">QEMU Userspace</text>
|
||||
</g>
|
||||
<g id="node-vhost-net">
|
||||
<rect class="node-shape kind-kernel emphasis-normal role-service" data-evidence="5669-5669,5716-5716" x="309.0" y="795.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="384.0" y="822.0">vhost-net</text>
|
||||
<line class="node-detail-divider" x1="323.0" y1="843.0" x2="445.0" y2="843.0" />
|
||||
<text class="node-detail" x="325.0" y="860.0">Host Kernel</text>
|
||||
<rect class="node-shape kind-kernel emphasis-normal role-service" data-evidence="5682-5682,5729-5729" x="1359.5" y="238.5" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="1434.5" y="265.5">vhost-net</text>
|
||||
<line class="node-detail-divider" x1="1373.5" y1="286.5" x2="1495.5" y2="286.5" />
|
||||
<text class="node-detail" x="1375.5" y="303.5">Host Kernel</text>
|
||||
</g>
|
||||
<g id="node-virtqueue">
|
||||
<rect class="node-shape kind-queue emphasis-normal role-queue" data-evidence="5667-5667,5718-5718" x="195.5" y="962.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="270.5" y="989.0">virtqueue</text>
|
||||
<line class="node-detail-divider" x1="209.5" y1="1010.0" x2="331.5" y2="1010.0" />
|
||||
<text class="node-detail" x="211.5" y="1027.0">shared queue</text>
|
||||
<rect class="node-shape kind-queue emphasis-normal role-queue" data-evidence="5680-5680,5731-5731" x="1678.0" y="167.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="1753.0" y="194.0">virtqueue</text>
|
||||
<line class="node-detail-divider" x1="1692.0" y1="215.0" x2="1814.0" y2="215.0" />
|
||||
<text class="node-detail" x="1694.0" y="232.0">shared queue</text>
|
||||
</g>
|
||||
<g id="node-guest">
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="5664-5665,5720-5726" x="162.5" y="1129.0" width="216.0" height="122.0" rx="7" />
|
||||
<text class="node-label" x="270.5" y="1156.0">Guest</text>
|
||||
<line class="node-detail-divider" x1="176.5" y1="1177.0" x2="364.5" y2="1177.0" />
|
||||
<text class="node-detail" x="178.5" y="1194.0">virtio-net Frontend Driver</text>
|
||||
<text class="node-detail" x="178.5" y="1210.0">Guest TCP/IP Stack</text>
|
||||
<text class="node-detail" x="178.5" y="1226.0">Socket</text>
|
||||
<text class="node-detail" x="178.5" y="1242.0">Keycloak</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="5677-5678,5733-5739" x="1988.0" y="141.5" width="216.0" height="122.0" rx="7" />
|
||||
<text class="node-label" x="2096.0" y="168.5">Guest</text>
|
||||
<line class="node-detail-divider" x1="2002.0" y1="189.5" x2="2190.0" y2="189.5" />
|
||||
<text class="node-detail" x="2004.0" y="206.5">virtio-net Frontend Driver</text>
|
||||
<text class="node-detail" x="2004.0" y="222.5">Guest TCP/IP Stack</text>
|
||||
<text class="node-detail" x="2004.0" y="238.5">Socket</text>
|
||||
<text class="node-detail" x="2004.0" y="254.5">Keycloak</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -10,16 +10,16 @@ Guest Page Table 과 EPT, QEMU 의 Guest RAM Backing 에서 각각 fault 가 갈
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **Guest Page Table** (component): 첫 번째 translation 단계. 여기서 접근을 완료할 수 없으면 Guest Page Fault 가 난다. Evidence: L2443–L2445, L2484–L2485.
|
||||
- **Guest Kernel** (service): Guest Page Fault 를 받는 계층. Evidence: L2487–L2487, L2493–L2494.
|
||||
- **EPT** (component): 두 번째 translation 단계. Guest translation 이 성공한 뒤 여기서 막히면 EPT Violation 이 난다. Evidence: L2465–L2469, L2484–L2485.
|
||||
- **KVM** (service): EPT Violation 을 VM Exit 뒤에 받는 계층. Evidence: L2471–L2473, L2487–L2487.
|
||||
- **QEMU · Guest RAM Backing** (store): Host 의 일반 userspace 메모리로 관리되는 자리. demand allocation 이나 reclaim, swap 때문에 여기서 fault 가 난다. Evidence: L2504–L2504, L2514–L2519.
|
||||
- **Host Kernel** (service): Host Page Fault 를 받아 필요한 Host page 를 처리하는 계층. Evidence: L2521–L2525.
|
||||
- **Guest Page Table** (component): 첫 번째 translation 단계. 여기서 접근을 완료할 수 없으면 Guest Page Fault 가 난다. Evidence: L2456–L2458, L2497–L2498.
|
||||
- **Guest Kernel** (service): Guest Page Fault 를 받는 계층. Evidence: L2500–L2500, L2506–L2507.
|
||||
- **EPT** (component): 두 번째 translation 단계. Guest translation 이 성공한 뒤 여기서 막히면 EPT Violation 이 난다. Evidence: L2478–L2482, L2497–L2498.
|
||||
- **KVM** (service): EPT Violation 을 VM Exit 뒤에 받는 계층. Evidence: L2484–L2486, L2500–L2500.
|
||||
- **QEMU · Guest RAM Backing** (store): Host 의 일반 userspace 메모리로 관리되는 자리. demand allocation 이나 reclaim, swap 때문에 여기서 fault 가 난다. Evidence: L2517–L2517, L2527–L2532.
|
||||
- **Host Kernel** (service): Host Page Fault 를 받아 필요한 Host page 를 처리하는 계층. Evidence: L2534–L2538.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **EPT → KVM:** EPT Violation · VM Exit. Evidence: L2467–L2473, L2487–L2487.
|
||||
- **Guest Page Table → Guest Kernel:** Guest Page Fault. Evidence: L2484–L2487, L2493–L2494.
|
||||
- **QEMU · Guest RAM Backing → Host Kernel:** Host Page Fault. Evidence: L2517–L2525.
|
||||
- **Guest Page Table → EPT:** GPA. Evidence: L2461–L2467.
|
||||
- **EPT → KVM:** EPT Violation · VM Exit. Evidence: L2480–L2486, L2500–L2500.
|
||||
- **Guest Page Table → Guest Kernel:** Guest #PF. Evidence: L2497–L2500, L2506–L2507.
|
||||
- **QEMU · Guest RAM Backing → Host Kernel:** Host #PF. Evidence: L2530–L2538.
|
||||
- **Guest Page Table → EPT:** GPA. Evidence: L2474–L2480.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 세 fault 는 변환 사슬의 서로 다른 단계에서 갈라져 나가 서로 다른 계층이 받는다
|
||||
# Question: Guest Page Fault · EPT Violation · Host Page Fault 는 각각 어느 단계에서 갈라지고 누가 받는가
|
||||
direction: down
|
||||
direction: right
|
||||
n0: "Guest Page Table" {
|
||||
shape: rectangle
|
||||
}
|
||||
@@ -19,7 +19,7 @@ n4: "QEMU · Guest RAM Backing" {
|
||||
n5: "Host Kernel" {
|
||||
shape: rectangle
|
||||
}
|
||||
n0 -> n1: "Guest Page Fault" { style.stroke-dash: 4 }
|
||||
n0 -> n1: "Guest #PF" { style.stroke-dash: 4 }
|
||||
n0 -> n2: "GPA"
|
||||
n2 -> n3: "EPT Violation · VM Exit" { style.stroke-dash: 4 }
|
||||
n4 -> n5: "Host Page Fault" { style.stroke-dash: 4 }
|
||||
n4 -> n5: "Host #PF" { style.stroke-dash: 4 }
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="Guest Page Table", shape=box, style="rounded,filled"];
|
||||
n1 [label="Guest Kernel", shape=box, style="rounded,filled"];
|
||||
n2 [label="EPT", shape=box, style="rounded,filled"];
|
||||
n3 [label="KVM", shape=box, style="rounded,filled"];
|
||||
n4 [label="QEMU · Guest RAM Backing", shape=box, style="rounded,filled"];
|
||||
n5 [label="Host Kernel", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="Guest #PF", style=dashed];
|
||||
n0 -> n2 [label="GPA", style=solid];
|
||||
n2 -> n3 [label="EPT Violation · VM Exit", style=dashed];
|
||||
n4 -> n5 [label="Host #PF", style=dashed];
|
||||
}
|
||||
@@ -1,46 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="page-fault-layers-in-a-vm" name="세 fault 는 변환 사슬의 서로 다른 단계에서 갈라져 나가 서로 다른 계층이 받는다">
|
||||
<mxGraphModel dx="685" dy="523" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<mxGraphModel dx="902" dy="448" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="902" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_guest-page-table" value="Guest Page Table<br/>GVA → GPA" tooltip="첫 번째 translation 단계. 여기서 접근을 완료할 수 없으면 Guest Page Fault 가 난다. | Evidence: L2443-L2445, L2484-L2485" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="166.5" y="70.0" width="150.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_guest-page-table" value="Guest Page Table<br/>GVA → GPA" tooltip="첫 번째 translation 단계. 여기서 접근을 완료할 수 없으면 Guest Page Fault 가 난다. | Evidence: L2456-L2458, L2497-L2498" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="78.5" y="114.5" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_qemu-backing" value="QEMU · Guest RAM Backing<br/>Host Virtual Memory" tooltip="Host 의 일반 userspace 메모리로 관리되는 자리. demand allocation 이나 reclaim, swap 때문에 여기서 fault 가 난다. | Evidence: L2504-L2504, L2514-L2519" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="376.5" y="60.0" width="167.0" height="91.0" as="geometry"/>
|
||||
<mxCell id="n_qemu-backing" value="QEMU · Guest RAM Backing<br/>Host Virtual Memory" tooltip="Host 의 일반 userspace 메모리로 관리되는 자리. demand allocation 이나 reclaim, swap 때문에 여기서 fault 가 난다. | Evidence: L2517-L2517, L2527-L2532" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="257.5" width="167.0" height="91.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_ept" value="EPT<br/>GPA → HPA" tooltip="두 번째 translation 단계. Guest translation 이 성공한 뒤 여기서 막히면 EPT Violation 이 난다. | Evidence: L2465-L2469, L2484-L2485" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="247.0" width="150.0" height="71.0" as="geometry"/>
|
||||
<mxCell id="n_ept" value="EPT<br/>GPA → HPA" tooltip="두 번째 translation 단계. Guest translation 이 성공한 뒤 여기서 막히면 EPT Violation 이 난다. | Evidence: L2478-L2482, L2497-L2498" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="397.0" y="60.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_guest-kernel" value="Guest Kernel" tooltip="Guest Page Fault 를 받는 계층. | Evidence: L2487-L2487, L2493-L2494" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="280.0" y="250.5" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_guest-kernel" value="Guest Kernel" tooltip="Guest Page Fault 를 받는 계층. | Evidence: L2500-L2500, L2506-L2507" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="397.0" y="203.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_host-kernel" value="Host Kernel" tooltip="Host Page Fault 를 받아 필요한 Host page 를 처리하는 계층. | Evidence: L2521-L2525" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="490.0" y="250.5" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_host-kernel" value="Host Kernel" tooltip="Host Page Fault 를 받아 필요한 Host page 를 처리하는 계층. | Evidence: L2534-L2538" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="397.0" y="339.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_kvm" value="KVM" tooltip="EPT Violation 을 VM Exit 뒤에 받는 계층. | Evidence: L2471-L2473, L2487-L2487" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="280.0" y="414.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_kvm" value="KVM" tooltip="EPT Violation 을 VM Exit 뒤에 받는 계층. | Evidence: L2484-L2486, L2500-L2500" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="707.0" y="199.5" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_ept-violation-branch" value="EPT Violation · VM Exit" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;dashed=1;" edge="1" parent="1" source="n_ept" target="n_kvm">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="250.0" y="338.0" as="offset"/>
|
||||
<mxPoint x="651.0" y="163.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_guest-fault-branch" value="Guest Page Fault" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;dashed=1;" edge="1" parent="1" source="n_guest-page-table" target="n_guest-kernel">
|
||||
<mxCell id="e_guest-fault-branch" value="Guest #PF" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;dashed=1;" edge="1" parent="1" source="n_guest-page-table" target="n_guest-kernel">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="302.8" y="167.8" as="offset"/>
|
||||
<mxPoint x="336.8" y="197.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_host-fault-branch" value="Host Page Fault" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;dashed=1;" edge="1" parent="1" source="n_qemu-backing" target="n_host-kernel">
|
||||
<mxCell id="e_host-fault-branch" value="Host #PF" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;dashed=1;" edge="1" parent="1" source="n_qemu-backing" target="n_host-kernel">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="512.5" y="172.8" as="offset"/>
|
||||
<mxPoint x="341.0" y="337.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_translation-continues" value="GPA" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-page-table" target="n_ept">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="188.8" y="166.0" as="offset"/>
|
||||
<mxPoint x="336.8" y="118.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
{
|
||||
"id": "edge-ept-violation-branch",
|
||||
"type": "arrow",
|
||||
"x": 145.0,
|
||||
"y": 318.0,
|
||||
"width": 210.0,
|
||||
"height": 96.0,
|
||||
"x": 547.0,
|
||||
"y": 95.5,
|
||||
"width": 160.0,
|
||||
"height": 136.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -36,16 +36,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
210.0,
|
||||
48.0
|
||||
80.0,
|
||||
136.0
|
||||
],
|
||||
[
|
||||
210.0,
|
||||
96.0
|
||||
160.0,
|
||||
136.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -66,8 +66,8 @@
|
||||
{
|
||||
"id": "edge-label-ept-violation-branch",
|
||||
"type": "text",
|
||||
"x": 158.0,
|
||||
"y": 326.0,
|
||||
"x": 559.0,
|
||||
"y": 151.5,
|
||||
"width": 184,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -105,10 +105,10 @@
|
||||
{
|
||||
"id": "edge-guest-fault-branch",
|
||||
"type": "arrow",
|
||||
"x": 250.5,
|
||||
"y": 141.0,
|
||||
"width": 104.5,
|
||||
"height": 109.5,
|
||||
"x": 228.5,
|
||||
"y": 159.0,
|
||||
"width": 168.5,
|
||||
"height": 76.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -135,16 +135,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
54.75
|
||||
84.25,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
104.5,
|
||||
54.75
|
||||
84.25,
|
||||
76.0
|
||||
],
|
||||
[
|
||||
104.5,
|
||||
109.5
|
||||
168.5,
|
||||
76.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -165,9 +165,9 @@
|
||||
{
|
||||
"id": "edge-label-guest-fault-branch",
|
||||
"type": "text",
|
||||
"x": 238.75,
|
||||
"y": 155.75,
|
||||
"width": 128,
|
||||
"x": 291.75,
|
||||
"y": 185.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
@@ -193,21 +193,21 @@
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "Guest Page Fault",
|
||||
"text": "Guest #PF",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Guest Page Fault",
|
||||
"originalText": "Guest #PF",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-host-fault-branch",
|
||||
"type": "arrow",
|
||||
"x": 460.0,
|
||||
"y": 151.0,
|
||||
"width": 105.0,
|
||||
"height": 99.5,
|
||||
"x": 237.0,
|
||||
"y": 303.0,
|
||||
"width": 160.0,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -234,16 +234,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
49.75
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
105.0,
|
||||
49.75
|
||||
80.0,
|
||||
68.0
|
||||
],
|
||||
[
|
||||
105.0,
|
||||
99.5
|
||||
160.0,
|
||||
68.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -264,9 +264,9 @@
|
||||
{
|
||||
"id": "edge-label-host-fault-branch",
|
||||
"type": "text",
|
||||
"x": 452.5,
|
||||
"y": 160.75,
|
||||
"width": 120,
|
||||
"x": 296.0,
|
||||
"y": 325.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
@@ -292,21 +292,21 @@
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "Host Page Fault",
|
||||
"text": "Host #PF",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Host Page Fault",
|
||||
"originalText": "Host #PF",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-translation-continues",
|
||||
"type": "arrow",
|
||||
"x": 145.0,
|
||||
"y": 141.0,
|
||||
"width": 87.5,
|
||||
"height": 106.0,
|
||||
"x": 228.5,
|
||||
"y": 95.5,
|
||||
"width": 168.5,
|
||||
"height": 45.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -329,20 +329,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
87.5,
|
||||
0.0,
|
||||
45.5
|
||||
],
|
||||
[
|
||||
84.25,
|
||||
45.5
|
||||
],
|
||||
[
|
||||
84.25,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
87.5,
|
||||
53.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
53.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
106.0
|
||||
168.5,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -363,8 +363,8 @@
|
||||
{
|
||||
"id": "edge-label-translation-continues",
|
||||
"type": "text",
|
||||
"x": 143.75,
|
||||
"y": 154.0,
|
||||
"x": 291.75,
|
||||
"y": 106.25,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -402,8 +402,8 @@
|
||||
{
|
||||
"id": "node-guest-page-table",
|
||||
"type": "rectangle",
|
||||
"x": 166.5,
|
||||
"y": 70.0,
|
||||
"x": 78.5,
|
||||
"y": 114.5,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -432,8 +432,8 @@
|
||||
{
|
||||
"id": "node-label-guest-page-table",
|
||||
"type": "text",
|
||||
"x": 176.5,
|
||||
"y": 80.0,
|
||||
"x": 88.5,
|
||||
"y": 124.5,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -471,8 +471,8 @@
|
||||
{
|
||||
"id": "node-qemu-backing",
|
||||
"type": "rectangle",
|
||||
"x": 376.5,
|
||||
"y": 60.0,
|
||||
"x": 70.0,
|
||||
"y": 257.5,
|
||||
"width": 167.0,
|
||||
"height": 91.0,
|
||||
"angle": 0,
|
||||
@@ -501,8 +501,8 @@
|
||||
{
|
||||
"id": "node-label-qemu-backing",
|
||||
"type": "text",
|
||||
"x": 386.5,
|
||||
"y": 70.0,
|
||||
"x": 80.0,
|
||||
"y": 267.5,
|
||||
"width": 147.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -540,8 +540,8 @@
|
||||
{
|
||||
"id": "node-ept",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 247.0,
|
||||
"x": 397.0,
|
||||
"y": 60.0,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
@@ -570,8 +570,8 @@
|
||||
{
|
||||
"id": "node-label-ept",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 257.0,
|
||||
"x": 407.0,
|
||||
"y": 70.0,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
@@ -609,8 +609,8 @@
|
||||
{
|
||||
"id": "node-guest-kernel",
|
||||
"type": "rectangle",
|
||||
"x": 280.0,
|
||||
"y": 250.5,
|
||||
"x": 397.0,
|
||||
"y": 203.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -639,8 +639,8 @@
|
||||
{
|
||||
"id": "node-label-guest-kernel",
|
||||
"type": "text",
|
||||
"x": 290.0,
|
||||
"y": 260.5,
|
||||
"x": 407.0,
|
||||
"y": 213.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -678,8 +678,8 @@
|
||||
{
|
||||
"id": "node-host-kernel",
|
||||
"type": "rectangle",
|
||||
"x": 490.0,
|
||||
"y": 250.5,
|
||||
"x": 397.0,
|
||||
"y": 339.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -708,8 +708,8 @@
|
||||
{
|
||||
"id": "node-label-host-kernel",
|
||||
"type": "text",
|
||||
"x": 500.0,
|
||||
"y": 260.5,
|
||||
"x": 407.0,
|
||||
"y": 349.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -747,8 +747,8 @@
|
||||
{
|
||||
"id": "node-kvm",
|
||||
"type": "rectangle",
|
||||
"x": 280.0,
|
||||
"y": 414.0,
|
||||
"x": 707.0,
|
||||
"y": 199.5,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -777,8 +777,8 @@
|
||||
{
|
||||
"id": "node-label-kvm",
|
||||
"type": "text",
|
||||
"x": 290.0,
|
||||
"y": 424.0,
|
||||
"x": 717.0,
|
||||
"y": 209.5,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "page-fault-layers-in-a-vm",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "1db9b8029b08c8d4c61b3f01119f121b394b7d0efb9818cb63793d65b858d667",
|
||||
"spec_sha256": "25421b9911ae384dcdb8d986608e8b727aea1345c48d19210e608b4d9ebbd026",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "48. Guest Page Fault와 EPT Violation 비교",
|
||||
"line": 2480
|
||||
"line": 2493
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"page-fault-layers-in-a-vm.svg",
|
||||
"page-fault-layers-in-a-vm.drawio",
|
||||
"page-fault-layers-in-a-vm.mmd",
|
||||
"page-fault-layers-in-a-vm.d2",
|
||||
"page-fault-layers-in-a-vm.dot",
|
||||
"page-fault-layers-in-a-vm.drawio",
|
||||
"page-fault-layers-in-a-vm.excalidraw",
|
||||
"page-fault-layers-in-a-vm.alt.md"
|
||||
],
|
||||
@@ -27,5 +28,15 @@
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "403c7a8d1ab23e8e8a21ff940845a1a99bbf97b95535c2598ce37b4ddfb34851",
|
||||
"output_sha256": {
|
||||
"page-fault-layers-in-a-vm.svg": "ddd294b5abeceb1ad8a7df1e8b14568ca5b4ac4f6aa94267e99b281fc2c0305e",
|
||||
"page-fault-layers-in-a-vm.mmd": "613bc7653e5896cd279d8a4a0cf497f08abd800433b42722f223a80dbfd4b8d4",
|
||||
"page-fault-layers-in-a-vm.d2": "5ea7f0d37257545af1b8f7930e5a3cc28559d2b7dee034f7bc39d848faa3f36e",
|
||||
"page-fault-layers-in-a-vm.dot": "75410f40e76c82baf0f1d4e52453e7714c4b5cee25efb75c476db31afef78f90",
|
||||
"page-fault-layers-in-a-vm.drawio": "70e07a8e69ad81634599b05cf24cd7b083f819799c1084c5e48a6c225ad29702",
|
||||
"page-fault-layers-in-a-vm.excalidraw": "a817ec26ba3159c9dff9276556375f72846b65a34c2098ea6fe05eeaf20657c9",
|
||||
"page-fault-layers-in-a-vm.alt.md": "4d703b128f2c6fdf3b17393433e349330b6c392cf1b056a240e349a850a2527e"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
%% 세 fault 는 변환 사슬의 서로 다른 단계에서 갈라져 나가 서로 다른 계층이 받는다
|
||||
%% question: Guest Page Fault · EPT Violation · Host Page Fault 는 각각 어느 단계에서 갈라지고 누가 받는가
|
||||
flowchart TB
|
||||
flowchart LR
|
||||
n0["Guest Page Table"]
|
||||
n1["Guest Kernel"]
|
||||
n2["EPT"]
|
||||
n3["KVM"]
|
||||
n4["QEMU · Guest RAM Backing"]
|
||||
n5["Host Kernel"]
|
||||
n0 -.->|"Guest Page Fault"| n1
|
||||
n0 -.->|"Guest #PF"| n1
|
||||
n0 -->|"GPA"| n2
|
||||
n2 -.->|"EPT Violation · VM Exit"| n3
|
||||
n4 -.->|"Host Page Fault"| n5
|
||||
n4 -.->|"Host #PF"| n5
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="685" height="523" viewBox="0 0 685 523" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="902" height="448" viewBox="0 0 902 448" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">세 fault 는 변환 사슬의 서로 다른 단계에서 갈라져 나가 서로 다른 계층이 받는다</title>
|
||||
<desc id="diagram-description">위에서 아래로 읽는다. 맨 위 왼쪽에 Guest Page Table 이 있고 거기서 갈래가 둘이다. 하나는 Guest Page Fault 로 Guest Kernel 에 빠지고, 다른 하나는 GPA 를 들고 아래 EPT 로 내려간다. EPT 에서도 갈래가 나뉘어 EPT Violation 은 VM Exit 을 거쳐 KVM 으로 간다. 맨 위 오른쪽에는 QEMU 의 Guest RAM Backing 이 따로 있고 그쪽 갈래인 Host Page Fault 는 Host Kernel 로 간다. 받는 자리의 이름이 그대로 계층 이름이다 — Guest Kernel · KVM · Host Kernel. QEMU 갈래가 EPT 갈래와 선으로 이어져 있지 않은 것은 근거 문서가 둘을 잇는 문장을 두지 않았기 때문이다. 다섯 원인이 무엇인지와 두 사건을 항목별로 견주는 것은 본문의 표가 맡는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"page-fault-layers-in-a-vm","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"48. Guest Page Fault와 EPT Violation 비교","line":2480}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"page-fault-layers-in-a-vm","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"48. Guest Page Fault와 EPT Violation 비교","line":2493}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -49,48 +49,48 @@
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="685" height="523" />
|
||||
<polyline class="edge kind-event style-solid emphasis-normal semantic-dashed" points="145.0,318.0 145.0,366.0 355.0,366.0 355.0,414.0" data-evidence="2467-2473,2487-2487" />
|
||||
<rect class="edge-label-bg" x="163.9" y="324.0" width="172.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="250.0" y="339.0">EPT Violation · VM Exit</text>
|
||||
<polyline class="edge kind-event style-solid emphasis-normal semantic-dashed" points="250.5,141.0 250.5,195.8 355.0,195.8 355.0,250.5" data-evidence="2484-2487,2493-2494" />
|
||||
<rect class="edge-label-bg" x="240.2" y="153.8" width="125.2" height="22" rx="3" />
|
||||
<text class="edge-label" x="302.8" y="168.8">Guest Page Fault</text>
|
||||
<polyline class="edge kind-event style-solid emphasis-normal semantic-dashed" points="460.0,151.0 460.0,200.8 565.0,200.8 565.0,250.5" data-evidence="2517-2525" />
|
||||
<rect class="edge-label-bg" x="453.2" y="158.8" width="118.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="512.5" y="173.8">Host Page Fault</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="232.5,141.0 232.5,194.0 145.0,194.0 145.0,247.0" data-evidence="2461-2467" />
|
||||
<rect class="edge-label-bg" x="166.8" y="152.0" width="44.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="188.8" y="167.0">GPA</text>
|
||||
<rect class="canvas" width="902" height="448" />
|
||||
<polyline class="edge kind-event style-solid emphasis-normal semantic-dashed" points="547.0,95.5 627.0,95.5 627.0,231.5 707.0,231.5" data-evidence="2480-2486,2500-2500" />
|
||||
<rect class="edge-label-bg" x="565.0" y="149.5" width="172.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="651.0" y="164.5">EPT Violation · VM Exit</text>
|
||||
<polyline class="edge kind-event style-solid emphasis-normal semantic-dashed" points="228.5,159.0 312.8,159.0 312.8,235.0 397.0,235.0" data-evidence="2497-2500,2506-2507" />
|
||||
<rect class="edge-label-bg" x="297.6" y="183.0" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="336.8" y="198.0">Guest #PF</text>
|
||||
<polyline class="edge kind-event style-solid emphasis-normal semantic-dashed" points="237.0,303.0 317.0,303.0 317.0,371.0 397.0,371.0" data-evidence="2530-2538" />
|
||||
<rect class="edge-label-bg" x="305.2" y="323.0" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="341.0" y="338.0">Host #PF</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="228.5,141.0 312.8,141.0 312.8,95.5 397.0,95.5" data-evidence="2474-2480" />
|
||||
<rect class="edge-label-bg" x="314.8" y="104.2" width="44.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="336.8" y="119.2">GPA</text>
|
||||
<g id="node-guest-page-table">
|
||||
<rect class="node-shape kind-component emphasis-normal role-source" data-evidence="2443-2445,2484-2485" x="166.5" y="70.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="241.5" y="97.0">Guest Page Table</text>
|
||||
<line class="node-detail-divider" x1="180.5" y1="118.0" x2="302.5" y2="118.0" />
|
||||
<text class="node-detail" x="182.5" y="135.0">GVA → GPA</text>
|
||||
<rect class="node-shape kind-component emphasis-normal role-source" data-evidence="2456-2458,2497-2498" x="78.5" y="114.5" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="153.5" y="141.5">Guest Page Table</text>
|
||||
<line class="node-detail-divider" x1="92.5" y1="162.5" x2="214.5" y2="162.5" />
|
||||
<text class="node-detail" x="94.5" y="179.5">GVA → GPA</text>
|
||||
</g>
|
||||
<g id="node-qemu-backing">
|
||||
<rect class="node-shape kind-store emphasis-normal role-source" data-evidence="2504-2504,2514-2519" x="376.5" y="60.0" width="167.0" height="91.0" rx="7" />
|
||||
<text class="node-label" x="460.0" y="87.0">QEMU · Guest RAM</text>
|
||||
<text class="node-label" x="460.0" y="105.0">Backing</text>
|
||||
<line class="node-detail-divider" x1="390.5" y1="126.0" x2="529.5" y2="126.0" />
|
||||
<text class="node-detail" x="392.5" y="143.0">Host Virtual Memory</text>
|
||||
<rect class="node-shape kind-store emphasis-normal role-source" data-evidence="2517-2517,2527-2532" x="70.0" y="257.5" width="167.0" height="91.0" rx="7" />
|
||||
<text class="node-label" x="153.5" y="284.5">QEMU · Guest RAM</text>
|
||||
<text class="node-label" x="153.5" y="302.5">Backing</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="323.5" x2="223.0" y2="323.5" />
|
||||
<text class="node-detail" x="86.0" y="340.5">Host Virtual Memory</text>
|
||||
</g>
|
||||
<g id="node-ept">
|
||||
<rect class="node-shape kind-component emphasis-primary role-service" data-evidence="2465-2469,2484-2485" x="70.0" y="247.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="274.0">EPT</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="295.0" x2="206.0" y2="295.0" />
|
||||
<text class="node-detail" x="86.0" y="312.0">GPA → HPA</text>
|
||||
<rect class="node-shape kind-component emphasis-primary role-service" data-evidence="2478-2482,2497-2498" x="397.0" y="60.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="472.0" y="87.0">EPT</text>
|
||||
<line class="node-detail-divider" x1="411.0" y1="108.0" x2="533.0" y2="108.0" />
|
||||
<text class="node-detail" x="413.0" y="125.0">GPA → HPA</text>
|
||||
</g>
|
||||
<g id="node-guest-kernel">
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="2487-2487,2493-2494" x="280.0" y="250.5" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="355.0" y="280.5">Guest Kernel</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="2500-2500,2506-2507" x="397.0" y="203.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="472.0" y="233.0">Guest Kernel</text>
|
||||
</g>
|
||||
<g id="node-host-kernel">
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="2521-2525" x="490.0" y="250.5" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="565.0" y="280.5">Host Kernel</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="2534-2538" x="397.0" y="339.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="472.0" y="369.0">Host Kernel</text>
|
||||
</g>
|
||||
<g id="node-kvm">
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="2471-2473,2487-2487" x="280.0" y="414.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="355.0" y="444.0">KVM</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="2484-2486,2500-2500" x="707.0" y="199.5" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="782.0" y="229.5">KVM</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
@@ -0,0 +1,26 @@
|
||||
# qcow2 L1·L2 매핑과 backing fallback
|
||||
|
||||
## Alternative text
|
||||
|
||||
게스트 오프셋이 L1과 L2 표를 지나 현재 qcow2 데이터 클러스터로 가거나, L2 항목이 0일 때 backing file 또는 zero-fill로 갈라지는 qcow2 매핑도.
|
||||
|
||||
## Long description
|
||||
|
||||
게스트가 읽으려는 위치는 L1 표와 L2 표를 통해 파일 안 데이터 클러스터 오프셋으로 변환된다. 매핑된 값이 있으면 현재 qcow2의 데이터 클러스터를 읽는다. 값이 0이고 backing file이 있으면 base.qcow2의 같은 가상 위치를 읽고, backing file이 없으면 0으로 채운 64KB를 반환한다. backing file 경로는 qcow2 헤더의 문자열이므로 오버레이만 옮기면 부팅할 수 없다는 제한도 그림 끝에 반영한다.
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **Guest offset** (data): 게스트가 읽으려는 가상 디스크 위치. Evidence: L14317–L14325.
|
||||
- **L1 table** (component): 필요한 L2 표가 있는 클러스터 위치를 찾는다. Evidence: L14312–L14337.
|
||||
- **L2 entry** (component): 현재 qcow2 데이터 클러스터 오프셋을 가지거나 0일 수 있다. Evidence: L14320–L14347.
|
||||
- **현재 qcow2 data cluster** (store): L2 값이 있을 때 같은 qcow2 파일 안에서 읽는 데이터 클러스터. Evidence: L14267–L14272, L14343–L14345.
|
||||
- **base.qcow2** (store): L2 항목이 0이고 backing file이 있을 때 같은 가상 위치를 읽는 바닥 파일. Evidence: L14343–L14354.
|
||||
- **zero-filled 64KB** (result): L2 항목이 0이고 backing file도 없을 때 만들어 반환하는 0 데이터. Evidence: L14343–L14347.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **L1 table → L2 entry:** L2 cluster. Evidence: L14320–L14337.
|
||||
- **L2 entry → base.qcow2:** 0 + backing. Evidence: L14343–L14350.
|
||||
- **L2 entry → 현재 qcow2 data cluster:** mapped. Evidence: L14343–L14345.
|
||||
- **L2 entry → zero-filled 64KB:** 0 + no backing. Evidence: L14343–L14347.
|
||||
- **Guest offset → L1 table:** 상위 비트. Evidence: L14317–L14324.
|
||||
@@ -0,0 +1,26 @@
|
||||
# qcow2 L1·L2 매핑과 backing fallback
|
||||
# Question: 게스트 오프셋은 qcow2 파일의 데이터 클러스터로 어떻게 매핑되고, L2 항목이 0일 때 왜 backing file이나 zero-fill로 갈리는가
|
||||
direction: right
|
||||
n0: "Guest offset" {
|
||||
shape: rectangle
|
||||
}
|
||||
n1: "L1 table" {
|
||||
shape: rectangle
|
||||
}
|
||||
n2: "L2 entry" {
|
||||
shape: rectangle
|
||||
}
|
||||
n3: "현재 qcow2 data cluster" {
|
||||
shape: rectangle
|
||||
}
|
||||
n4: "base.qcow2" {
|
||||
shape: rectangle
|
||||
}
|
||||
n5: "zero-filled 64KB" {
|
||||
shape: rectangle
|
||||
}
|
||||
n0 -> n1: "상위 비트"
|
||||
n1 -> n2: "L2 cluster"
|
||||
n2 -> n3: "mapped"
|
||||
n2 -> n4: "0 + backing"
|
||||
n2 -> n5: "0 + no backing"
|
||||
@@ -0,0 +1,16 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="Guest offset", shape=box, style="rounded,filled"];
|
||||
n1 [label="L1 table", shape=box, style="rounded,filled"];
|
||||
n2 [label="L2 entry", shape=box, style="rounded,filled"];
|
||||
n3 [label="현재 qcow2 data cluster", shape=box, style="rounded,filled"];
|
||||
n4 [label="base.qcow2", shape=box, style="rounded,filled"];
|
||||
n5 [label="zero-filled 64KB", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="상위 비트", style=solid];
|
||||
n1 -> n2 [label="L2 cluster", style=solid];
|
||||
n2 -> n3 [label="mapped", style=solid];
|
||||
n2 -> n4 [label="0 + backing", style=solid];
|
||||
n2 -> n5 [label="0 + no backing", style=solid];
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="qcow2-mapping-clusters" name="qcow2 L1·L2 매핑과 backing fallback">
|
||||
<mxGraphModel dx="1257" dy="448" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1257" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_guest-offset" value="Guest offset<br/>virtual disk position" tooltip="게스트가 읽으려는 가상 디스크 위치. | Evidence: L14317-L14325" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="196.0" width="181.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_l1" value="L1 table<br/>상위 비트" tooltip="필요한 L2 표가 있는 클러스터 위치를 찾는다. | Evidence: L14312-L14337" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="411.0" y="196.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_l2" value="L2 entry<br/>중간 13비트" tooltip="현재 qcow2 데이터 클러스터 오프셋을 가지거나 0일 수 있다. | Evidence: L14320-L14347" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="721.0" y="196.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_backing" value="base.qcow2<br/>backing file" tooltip="L2 항목이 0이고 backing file이 있을 때 같은 가상 위치를 읽는 바닥 파일. | Evidence: L14343-L14354" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="1046.5" y="60.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_local-cluster" value="현재 qcow2 data cluster" tooltip="L2 값이 있을 때 같은 qcow2 파일 안에서 읽는 데이터 클러스터. | Evidence: L14267-L14272, L14343-L14345" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="1031.0" y="203.0" width="181.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_zero-fill" value="zero-filled 64KB" tooltip="L2 항목이 0이고 backing file도 없을 때 만들어 반환하는 0 데이터. | Evidence: L14343-L14347" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1046.5" y="339.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_l1-l2" value="L2 cluster" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_l1" target="n_l2">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="641.0" y="203.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_l2-backing" value="0 + backing" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_l2" target="n_backing">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="982.8" y="154.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_l2-local" value="mapped" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_l2" target="n_local-cluster">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="975.0" y="233.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_l2-zero" value="0 + no backing" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_l2" target="n_zero-fill">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="982.8" y="310.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_offset-l1" value="상위 비트" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-offset" target="n_l1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="331.0" y="203.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -0,0 +1,922 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "techviz-harness",
|
||||
"elements": [
|
||||
{
|
||||
"id": "edge-l1-l2",
|
||||
"type": "arrow",
|
||||
"x": 561.0,
|
||||
"y": 231.5,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 586743950,
|
||||
"version": 1,
|
||||
"versionNonce": 1823449811,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-l1",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-l2",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-l1-l2",
|
||||
"type": "text",
|
||||
"x": 596.0,
|
||||
"y": 191.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1344248471,
|
||||
"version": 1,
|
||||
"versionNonce": 1292323506,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "L2 cluster",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "L2 cluster",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-l2-backing",
|
||||
"type": "arrow",
|
||||
"x": 871.0,
|
||||
"y": 95.5,
|
||||
"width": 175.5,
|
||||
"height": 118.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 1567107232,
|
||||
"version": 1,
|
||||
"versionNonce": 1394231586,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
118.0
|
||||
],
|
||||
[
|
||||
87.75,
|
||||
118.0
|
||||
],
|
||||
[
|
||||
87.75,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
175.5,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-l2",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-backing",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-l2-backing",
|
||||
"type": "text",
|
||||
"x": 937.75,
|
||||
"y": 142.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 751142759,
|
||||
"version": 1,
|
||||
"versionNonce": 1636292120,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "0 + backing",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "0 + backing",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-l2-local",
|
||||
"type": "arrow",
|
||||
"x": 871.0,
|
||||
"y": 231.5,
|
||||
"width": 160.0,
|
||||
"height": 3.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 205827981,
|
||||
"version": 1,
|
||||
"versionNonce": 1468667393,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
3.5
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
3.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-l2",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-local-cluster",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-l2-local",
|
||||
"type": "text",
|
||||
"x": 930.0,
|
||||
"y": 221.25,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1218557231,
|
||||
"version": 1,
|
||||
"versionNonce": 919123626,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "mapped",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "mapped",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-l2-zero",
|
||||
"type": "arrow",
|
||||
"x": 871.0,
|
||||
"y": 249.5,
|
||||
"width": 175.5,
|
||||
"height": 121.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 1572116611,
|
||||
"version": 1,
|
||||
"versionNonce": 650463629,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
87.75,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
87.75,
|
||||
121.5
|
||||
],
|
||||
[
|
||||
175.5,
|
||||
121.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-l2",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-zero-fill",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-l2-zero",
|
||||
"type": "text",
|
||||
"x": 926.75,
|
||||
"y": 298.25,
|
||||
"width": 112,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1455255978,
|
||||
"version": 1,
|
||||
"versionNonce": 35062350,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "0 + no backing",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "0 + no backing",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-offset-l1",
|
||||
"type": "arrow",
|
||||
"x": 251.0,
|
||||
"y": 231.5,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 1376738291,
|
||||
"version": 1,
|
||||
"versionNonce": 1345642548,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-guest-offset",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-l1",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-offset-l1",
|
||||
"type": "text",
|
||||
"x": 286.0,
|
||||
"y": 191.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1804422112,
|
||||
"version": 1,
|
||||
"versionNonce": 797123369,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "상위 비트",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "상위 비트",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-guest-offset",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 196.0,
|
||||
"width": 181.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1190817156,
|
||||
"version": 1,
|
||||
"versionNonce": 139318315,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-guest-offset",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 206.0,
|
||||
"width": 161.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 83110366,
|
||||
"version": 1,
|
||||
"versionNonce": 49655676,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "Guest offset\nvirtual disk position",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Guest offset\nvirtual disk position",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-l1",
|
||||
"type": "rectangle",
|
||||
"x": 411.0,
|
||||
"y": 196.0,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1774178777,
|
||||
"version": 1,
|
||||
"versionNonce": 229505492,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-l1",
|
||||
"type": "text",
|
||||
"x": 421.0,
|
||||
"y": 206.0,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 15495054,
|
||||
"version": 1,
|
||||
"versionNonce": 244208457,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "L1 table\n상위 비트",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "L1 table\n상위 비트",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-l2",
|
||||
"type": "rectangle",
|
||||
"x": 721.0,
|
||||
"y": 196.0,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 207729084,
|
||||
"version": 1,
|
||||
"versionNonce": 618174549,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-l2",
|
||||
"type": "text",
|
||||
"x": 731.0,
|
||||
"y": 206.0,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 248933745,
|
||||
"version": 1,
|
||||
"versionNonce": 1248263086,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "L2 entry\n중간 13비트",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "L2 entry\n중간 13비트",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-backing",
|
||||
"type": "rectangle",
|
||||
"x": 1046.5,
|
||||
"y": 60.0,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 241530005,
|
||||
"version": 1,
|
||||
"versionNonce": 110043311,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-backing",
|
||||
"type": "text",
|
||||
"x": 1056.5,
|
||||
"y": 70.0,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1088329617,
|
||||
"version": 1,
|
||||
"versionNonce": 1471763197,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "base.qcow2\nbacking file",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "base.qcow2\nbacking file",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-local-cluster",
|
||||
"type": "rectangle",
|
||||
"x": 1031.0,
|
||||
"y": 203.0,
|
||||
"width": 181.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1087803653,
|
||||
"version": 1,
|
||||
"versionNonce": 174713902,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-local-cluster",
|
||||
"type": "text",
|
||||
"x": 1041.0,
|
||||
"y": 213.0,
|
||||
"width": 161.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1290752056,
|
||||
"version": 1,
|
||||
"versionNonce": 635359524,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "현재 qcow2 data cluster",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "현재 qcow2 data cluster",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-zero-fill",
|
||||
"type": "rectangle",
|
||||
"x": 1046.5,
|
||||
"y": 339.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1358300415,
|
||||
"version": 1,
|
||||
"versionNonce": 304765438,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-zero-fill",
|
||||
"type": "text",
|
||||
"x": 1056.5,
|
||||
"y": 349.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 720572336,
|
||||
"version": 1,
|
||||
"versionNonce": 603273159,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "zero-filled 64KB",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "zero-filled 64KB",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": 10,
|
||||
"viewBackgroundColor": "#ffffff",
|
||||
"currentItemFontFamily": 5
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "qcow2-mapping-clusters",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "7f8a8cdf4d78168e56ca829ead8d8e574479d11d431891d3d9e5fce5b40635a4",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "231. qcow2 파일 내부는 어떻게 생겼나 — 매핑표가 전부다",
|
||||
"line": 14221
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"qcow2-mapping-clusters.svg",
|
||||
"qcow2-mapping-clusters.mmd",
|
||||
"qcow2-mapping-clusters.d2",
|
||||
"qcow2-mapping-clusters.dot",
|
||||
"qcow2-mapping-clusters.drawio",
|
||||
"qcow2-mapping-clusters.excalidraw",
|
||||
"qcow2-mapping-clusters.alt.md"
|
||||
],
|
||||
"lint_issue_count": 0,
|
||||
"assumption_count": 0,
|
||||
"assumptions_allowed": false,
|
||||
"composition_profile": "component-flow",
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "12590f917b1fa302a293b29584e40de224f9b280f479110128cde4878b89cd65",
|
||||
"output_sha256": {
|
||||
"qcow2-mapping-clusters.svg": "9668c9c2e9a6e67d290833f4c055607744c6b8448c89fdb5c2e374a1832e3324",
|
||||
"qcow2-mapping-clusters.mmd": "614782850ad8082f2d2b8b6eadd5969d3a71e6fb77fb08173b87420a1b1b16a3",
|
||||
"qcow2-mapping-clusters.d2": "5508d5d8d5496f41b537ae94d98ceb4f42d685ae8d0b0ae895827ce8b52949a1",
|
||||
"qcow2-mapping-clusters.dot": "e5423cf82ef26c98d391e7f5553959332ebe4808c28ac4e74a93450c04c4a656",
|
||||
"qcow2-mapping-clusters.drawio": "bfcea347243b06067ec55e63f582e2d07213a1c76ddbbc7df907a5c5feb67506",
|
||||
"qcow2-mapping-clusters.excalidraw": "8fa0e7c79497e1e13223ebc2601c57872c5dcb58cb2bf7e2bd8008b5ef3d1c98",
|
||||
"qcow2-mapping-clusters.alt.md": "f72433e1f4f80441e41bd668dd67818e5837a14e2a3b0a1b703fa2e14c3bfda6"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
%% qcow2 L1·L2 매핑과 backing fallback
|
||||
%% question: 게스트 오프셋은 qcow2 파일의 데이터 클러스터로 어떻게 매핑되고, L2 항목이 0일 때 왜 backing file이나 zero-fill로 갈리는가
|
||||
flowchart LR
|
||||
n0["Guest offset"]
|
||||
n1["L1 table"]
|
||||
n2["L2 entry"]
|
||||
n3["현재 qcow2 data cluster"]
|
||||
n4["base.qcow2"]
|
||||
n5["zero-filled 64KB"]
|
||||
n0 -->|"상위 비트"| n1
|
||||
n1 -->|"L2 cluster"| n2
|
||||
n2 -->|"mapped"| n3
|
||||
n2 -->|"0 + backing"| n4
|
||||
n2 -->|"0 + no backing"| n5
|
||||
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1257" height="448" viewBox="0 0 1257 448" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">qcow2 L1·L2 매핑과 backing fallback</title>
|
||||
<desc id="diagram-description">게스트가 읽으려는 위치는 L1 표와 L2 표를 통해 파일 안 데이터 클러스터 오프셋으로 변환된다. 매핑된 값이 있으면 현재 qcow2의 데이터 클러스터를 읽는다. 값이 0이고 backing file이 있으면 base.qcow2의 같은 가상 위치를 읽고, backing file이 없으면 0으로 채운 64KB를 반환한다. backing file 경로는 qcow2 헤더의 문자열이므로 오버레이만 옮기면 부팅할 수 없다는 제한도 그림 끝에 반영한다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"qcow2-mapping-clusters","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"231. qcow2 파일 내부는 어떻게 생겼나 — 매핑표가 전부다","line":14221}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
</marker>
|
||||
<style>
|
||||
:root { color-scheme: light; }
|
||||
text { font-family: Inter, Pretendard, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #111827; }
|
||||
.canvas { fill: #ffffff; }
|
||||
.group-box { fill: #ffffff; stroke: #9ca3af; stroke-width: 1.4; stroke-dasharray: 7 5; }
|
||||
.group-label-bg { fill: #ffffff; }
|
||||
.group-label { font-size: 13px; font-weight: 650; fill: #374151; }
|
||||
.edge { fill: none; stroke: #374151; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; marker-end: url(#arrow); }
|
||||
.edge.style-dashed, .edge.semantic-dashed, .edge.assumption { stroke-dasharray: 7 5; }
|
||||
.edge.style-dotted { stroke-dasharray: 2 5; }
|
||||
.edge.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.edge.emphasis-muted { stroke: #9ca3af; }
|
||||
.edge.emphasis-warning, .edge.kind-failure, .edge.kind-error { stroke: #dc2626; stroke-width: 2.2; }
|
||||
.edge-label-bg { fill: #ffffff; }
|
||||
.edge-label { font-size: 12px; font-weight: 560; text-anchor: middle; }
|
||||
.node-shape { fill: #ffffff; stroke: #4b5563; stroke-width: 1.7; }
|
||||
.node-shape.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.node-shape.emphasis-muted { stroke: #9ca3af; fill: #f9fafb; }
|
||||
.node-shape.emphasis-warning { stroke: #d97706; stroke-width: 2; fill: #fffdf5; }
|
||||
.node-shape.kind-database, .node-shape.kind-datastore, .node-shape.kind-storage { fill: #f8fafc; }
|
||||
.node-shape.kind-queue, .node-shape.kind-event, .node-shape.kind-topic { fill: #fafafa; }
|
||||
.node-shape.assumption { stroke-dasharray: 4 4; }
|
||||
.storage-bottom, .controller-divider { fill: none; stroke: #4b5563; stroke-width: 1.4; }
|
||||
.controller-led { fill: #4b5563; }
|
||||
.actor-symbol { fill: none; stroke: #4b5563; stroke-width: 1.8; stroke-linecap: round; }
|
||||
.actor-symbol.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.node-label { font-size: 14px; font-weight: 650; text-anchor: middle; }
|
||||
.node-role { font-size: 10px; letter-spacing: 0.04em; text-anchor: middle; fill: #6b7280; }
|
||||
.node-detail-divider { stroke: #d1d5db; stroke-width: 1; }
|
||||
.node-detail { font-size: 11px; fill: #374151; }
|
||||
.assumption-badge { font-size: 9px; font-weight: 700; fill: #92400e; }
|
||||
.failure-mark { stroke: #dc2626; stroke-width: 4; stroke-linecap: round; }
|
||||
.lifeline { stroke: #9ca3af; stroke-width: 1.2; stroke-dasharray: 5 5; }
|
||||
.timeline-axis { stroke: #374151; stroke-width: 1.8; marker-end: url(#arrow); }
|
||||
.timeline-stem { stroke: #6b7280; stroke-width: 1.3; }
|
||||
.timeline-marker { fill: #ffffff; stroke: #374151; stroke-width: 1.7; }
|
||||
.timeline-marker.primary { fill: #2563eb; stroke: #2563eb; }
|
||||
.timeline-marker.warning { fill: #dc2626; stroke: #dc2626; }
|
||||
.timeline-label { font-size: 13px; font-weight: 650; text-anchor: middle; }
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="1257" height="448" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="561.0,231.5 641.0,231.5 641.0,231.5 721.0,231.5" data-evidence="14320-14337" />
|
||||
<rect class="edge-label-bg" x="598.5" y="189.5" width="85.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="641.0" y="204.5">L2 cluster</text>
|
||||
<polyline class="edge kind-data style-dashed emphasis-normal" points="871.0,213.5 958.8,213.5 958.8,95.5 1046.5,95.5" data-evidence="14343-14350" />
|
||||
<rect class="edge-label-bg" x="936.9" y="140.5" width="91.7" height="22" rx="3" />
|
||||
<text class="edge-label" x="982.8" y="155.5">0 + backing</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="871.0,231.5 951.0,231.5 951.0,235.0 1031.0,235.0" data-evidence="14343-14345" />
|
||||
<rect class="edge-label-bg" x="945.9" y="219.2" width="58.2" height="22" rx="3" />
|
||||
<text class="edge-label" x="975.0" y="234.2">mapped</text>
|
||||
<polyline class="edge kind-result style-dashed emphasis-normal" points="871.0,249.5 958.8,249.5 958.8,371.0 1046.5,371.0" data-evidence="14343-14347" />
|
||||
<rect class="edge-label-bg" x="926.9" y="296.2" width="111.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="982.8" y="311.2">0 + no backing</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="251.0,231.5 331.0,231.5 331.0,231.5 411.0,231.5" data-evidence="14317-14324" />
|
||||
<rect class="edge-label-bg" x="305.2" y="189.5" width="51.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="331.0" y="204.5">상위 비트</text>
|
||||
<g id="node-guest-offset">
|
||||
<rect class="node-shape kind-data emphasis-normal role-source" data-evidence="14317-14325" x="70.0" y="196.0" width="181.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="160.5" y="223.0">Guest offset</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="244.0" x2="237.0" y2="244.0" />
|
||||
<text class="node-detail" x="86.0" y="261.0">virtual disk position</text>
|
||||
</g>
|
||||
<g id="node-l1">
|
||||
<rect class="node-shape kind-component emphasis-normal role-service" data-evidence="14312-14337" x="411.0" y="196.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="486.0" y="223.0">L1 table</text>
|
||||
<line class="node-detail-divider" x1="425.0" y1="244.0" x2="547.0" y2="244.0" />
|
||||
<text class="node-detail" x="427.0" y="261.0">상위 비트</text>
|
||||
</g>
|
||||
<g id="node-l2">
|
||||
<rect class="node-shape kind-component emphasis-primary role-service" data-evidence="14320-14347" x="721.0" y="196.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="796.0" y="223.0">L2 entry</text>
|
||||
<line class="node-detail-divider" x1="735.0" y1="244.0" x2="857.0" y2="244.0" />
|
||||
<text class="node-detail" x="737.0" y="261.0">중간 13비트</text>
|
||||
</g>
|
||||
<g id="node-backing">
|
||||
<rect class="node-shape kind-store emphasis-normal role-store" data-evidence="14343-14354" x="1046.5" y="71.8" width="150.0" height="47.3" /><ellipse class="node-shape kind-store emphasis-normal role-store" cx="1121.5" cy="71.8" rx="75.0" ry="11.8" /><path class="storage-bottom" d="M 1046.5 119.2 A 75.0 11.8 0 0 0 1196.5 119.2" />
|
||||
<text class="node-label" x="1121.5" y="87.0">base.qcow2</text>
|
||||
<line class="node-detail-divider" x1="1060.5" y1="108.0" x2="1182.5" y2="108.0" />
|
||||
<text class="node-detail" x="1062.5" y="125.0">backing file</text>
|
||||
</g>
|
||||
<g id="node-local-cluster">
|
||||
<rect class="node-shape kind-store emphasis-normal role-store" data-evidence="14267-14272,14343-14345" x="1031.0" y="213.7" width="181.0" height="42.7" /><ellipse class="node-shape kind-store emphasis-normal role-store" cx="1121.5" cy="213.7" rx="90.5" ry="10.7" /><path class="storage-bottom" d="M 1031.0 256.3 A 90.5 10.7 0 0 0 1212.0 256.3" />
|
||||
<text class="node-label" x="1121.5" y="233.0">현재 qcow2 data cluster</text>
|
||||
</g>
|
||||
<g id="node-zero-fill">
|
||||
<rect class="node-shape kind-result emphasis-normal role-sink" data-evidence="14343-14347" x="1046.5" y="339.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="1121.5" y="369.0">zero-filled 64KB</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.4 KiB |
@@ -0,0 +1,26 @@
|
||||
# virtqueue 뒤 QEMU block backend의 세 형태
|
||||
|
||||
## Alternative text
|
||||
|
||||
Guest의 /dev/vda가 virtio-blk와 virtqueue를 지나 QEMU block backend에 도착한 뒤 qcow2 파일, RAW 파일, Host block device 세 갈래로 나뉘는 구조도. 그 아래 Host block stack은 별도 Concept이 맡아 이 그림에서는 다시 합치지 않는다.
|
||||
|
||||
## Long description
|
||||
|
||||
왼쪽에서 Guest /dev/vda 요청이 virtio-blk와 virtqueue를 지나 VM boundary를 넘는다. QEMU block backend에서 qcow2 file, RAW file, Host block device 세 갈래로 나뉜다. qcow2와 RAW 노드에는 Host filesystem을 경유한다는 차이를, Host block device에는 파일 backend가 아니라는 차이를 적었다. 세 경로 아래의 Host block stack은 별도 Concept이 맡으므로 이 그림에서는 다시 합치지 않는다.
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **/dev/vda** (storage): Guest가 보는 virtual disk. Evidence: L6355–L6363.
|
||||
- **virtio-blk · virtqueue** (component): Guest /dev/vda 요청을 virtio-blk가 받아 virtqueue에 싣는 경로를 한 노드로 묶었다. Evidence: L6355–L6364.
|
||||
- **QEMU block backend** (service): Guest virtual I/O를 실제 Host backend에 연결한다. Evidence: L6367–L6387.
|
||||
- **qcow2 file** (storage): sparse/COW 기능을 가진 file backend. Evidence: L6419–L6460, L6512–L6547.
|
||||
- **RAW file** (storage): 상대적으로 단순한 offset 대응을 쓰는 file backend. Evidence: L6512–L6547.
|
||||
- **Host block device** (storage): QEMU가 Host block device를 직접 backend로 사용할 수 있는 형태. Evidence: L6551–L6575.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **QEMU block backend → Host block device:** block-device backend. Evidence: L6551–L6575.
|
||||
- **QEMU block backend → qcow2 file:** qcow2 backend. Evidence: L6369–L6379, L6419–L6460.
|
||||
- **QEMU block backend → RAW file:** RAW backend. Evidence: L6512–L6547.
|
||||
- **/dev/vda → virtio-blk · virtqueue:** block I/O. Evidence: L6355–L6363.
|
||||
- **virtio-blk · virtqueue → QEMU block backend:** VM boundary. Evidence: L6362–L6374.
|
||||
@@ -0,0 +1,26 @@
|
||||
# virtqueue 뒤 QEMU block backend의 세 형태
|
||||
# Question: Guest /dev/vda 요청이 VM boundary를 넘은 뒤 QEMU에서 qcow2, RAW, Host block device 중 어느 backend로 이어지는가
|
||||
direction: right
|
||||
n0: "/dev/vda" {
|
||||
shape: cylinder
|
||||
}
|
||||
n1: "virtio-blk · virtqueue" {
|
||||
shape: rectangle
|
||||
}
|
||||
n2: "QEMU block backend" {
|
||||
shape: rectangle
|
||||
}
|
||||
n3: "qcow2 file" {
|
||||
shape: cylinder
|
||||
}
|
||||
n4: "RAW file" {
|
||||
shape: cylinder
|
||||
}
|
||||
n5: "Host block device" {
|
||||
shape: cylinder
|
||||
}
|
||||
n0 -> n1: "block I/O"
|
||||
n1 -> n2: "VM boundary"
|
||||
n2 -> n3: "qcow2 backend"
|
||||
n2 -> n4: "RAW backend"
|
||||
n2 -> n5: "block-device backend"
|
||||
@@ -0,0 +1,16 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="/dev/vda", shape=cylinder, style="rounded,filled"];
|
||||
n1 [label="virtio-blk · virtqueue", shape=box, style="rounded,filled"];
|
||||
n2 [label="QEMU block backend", shape=box, style="rounded,filled"];
|
||||
n3 [label="qcow2 file", shape=cylinder, style="rounded,filled"];
|
||||
n4 [label="RAW file", shape=cylinder, style="rounded,filled"];
|
||||
n5 [label="Host block device", shape=cylinder, style="rounded,filled"];
|
||||
n0 -> n1 [label="block I/O", style=solid];
|
||||
n1 -> n2 [label="VM boundary", style=solid];
|
||||
n2 -> n3 [label="qcow2 backend", style=solid];
|
||||
n2 -> n4 [label="RAW backend", style=solid];
|
||||
n2 -> n5 [label="block-device backend", style=solid];
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="qemu-block-backend-forms" name="virtqueue 뒤 QEMU block backend의 세 형태">
|
||||
<mxGraphModel dx="1253" dy="564" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1253" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_vda" value="/dev/vda" tooltip="Guest가 보는 virtual disk. | Evidence: L6355-L6363" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="257.5" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_virtio-queue" value="virtio-blk · virtqueue<br/>Guest<br/>VM boundary 직전" tooltip="Guest /dev/vda 요청을 virtio-blk가 받아 virtqueue에 싣는 경로를 한 노드로 묶었다. | Evidence: L6355-L6364" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="380.0" y="245.5" width="188.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_backend" value="QEMU block backend" tooltip="Guest virtual I/O를 실제 Host backend에 연결한다. | Evidence: L6367-L6387" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="728.0" y="257.5" width="160.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_block-device" value="Host block device<br/>/dev/...<br/>file 없음<br/>→ Host block stack" tooltip="QEMU가 Host block device를 직접 backend로 사용할 수 있는 형태. | Evidence: L6551-L6575" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="1048.0" y="60.0" width="160.0" height="105.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_qcow2" value="qcow2 file<br/>file backend<br/>mapping · metadata<br/>→ Host filesystem" tooltip="sparse/COW 기능을 가진 file backend. | Evidence: L6419-L6460, L6512-L6547" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="1048.0" y="237.0" width="160.0" height="105.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_raw" value="RAW file<br/>file backend<br/>offset 대응<br/>→ Host filesystem" tooltip="상대적으로 단순한 offset 대응을 쓰는 file backend. | Evidence: L6512-L6547" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="1051.5" y="414.0" width="153.0" height="105.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_backend-block" value="block-device backend" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_backend" target="n_block-device">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="992.0" y="192.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_backend-qcow2" value="qcow2 backend" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_backend" target="n_qcow2">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="968.0" y="261.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_backend-raw" value="RAW backend" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_backend" target="n_raw">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="993.8" y="387.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_vda-virtio" value="block I/O" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_vda" target="n_virtio-queue">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="300.0" y="261.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_vq-backend" value="VM boundary" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtio-queue" target="n_backend">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="648.0" y="261.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -0,0 +1,922 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "techviz-harness",
|
||||
"elements": [
|
||||
{
|
||||
"id": "edge-backend-block",
|
||||
"type": "arrow",
|
||||
"x": 888.0,
|
||||
"y": 112.5,
|
||||
"width": 160.0,
|
||||
"height": 159.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 1753917267,
|
||||
"version": 1,
|
||||
"versionNonce": 7070954,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
159.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
159.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-backend",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-block-device",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-backend-block",
|
||||
"type": "text",
|
||||
"x": 912.0,
|
||||
"y": 180.0,
|
||||
"width": 160,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 948380865,
|
||||
"version": 1,
|
||||
"versionNonce": 1886842897,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "block-device backend",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "block-device backend",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-backend-qcow2",
|
||||
"type": "arrow",
|
||||
"x": 888.0,
|
||||
"y": 289.5,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 1037898307,
|
||||
"version": 1,
|
||||
"versionNonce": 605207362,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-backend",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-qcow2",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-backend-qcow2",
|
||||
"type": "text",
|
||||
"x": 916.0,
|
||||
"y": 249.5,
|
||||
"width": 104,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 801300859,
|
||||
"version": 1,
|
||||
"versionNonce": 607900389,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "qcow2 backend",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "qcow2 backend",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-backend-raw",
|
||||
"type": "arrow",
|
||||
"x": 888.0,
|
||||
"y": 307.5,
|
||||
"width": 163.5,
|
||||
"height": 159.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 845643799,
|
||||
"version": 1,
|
||||
"versionNonce": 622700656,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
81.75,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
81.75,
|
||||
159.0
|
||||
],
|
||||
[
|
||||
163.5,
|
||||
159.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-backend",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-raw",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-backend-raw",
|
||||
"type": "text",
|
||||
"x": 948.75,
|
||||
"y": 375.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 694437893,
|
||||
"version": 1,
|
||||
"versionNonce": 1459806024,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "RAW backend",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "RAW backend",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-vda-virtio",
|
||||
"type": "arrow",
|
||||
"x": 220.0,
|
||||
"y": 289.5,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 1903638622,
|
||||
"version": 1,
|
||||
"versionNonce": 339021053,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-vda",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-virtio-queue",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-vda-virtio",
|
||||
"type": "text",
|
||||
"x": 255.0,
|
||||
"y": 249.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 124979975,
|
||||
"version": 1,
|
||||
"versionNonce": 1180572335,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "block I/O",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "block I/O",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-vq-backend",
|
||||
"type": "arrow",
|
||||
"x": 568.0,
|
||||
"y": 289.5,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 1649285052,
|
||||
"version": 1,
|
||||
"versionNonce": 359088642,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-virtio-queue",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-backend",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-vq-backend",
|
||||
"type": "text",
|
||||
"x": 603.0,
|
||||
"y": 249.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1715374896,
|
||||
"version": 1,
|
||||
"versionNonce": 804862916,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "VM boundary",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "VM boundary",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-vda",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 257.5,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#e7f5ff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 656251698,
|
||||
"version": 1,
|
||||
"versionNonce": 1124580118,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-vda",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 267.5,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1507714488,
|
||||
"version": 1,
|
||||
"versionNonce": 673939059,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "/dev/vda",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "/dev/vda",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-virtio-queue",
|
||||
"type": "rectangle",
|
||||
"x": 380.0,
|
||||
"y": 245.5,
|
||||
"width": 188.0,
|
||||
"height": 88.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1377893440,
|
||||
"version": 1,
|
||||
"versionNonce": 287173562,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-virtio-queue",
|
||||
"type": "text",
|
||||
"x": 390.0,
|
||||
"y": 255.5,
|
||||
"width": 168.0,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 931218772,
|
||||
"version": 1,
|
||||
"versionNonce": 1603301814,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "virtio-blk · virtqueue\nGuest\nVM boundary 직전",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "virtio-blk · virtqueue\nGuest\nVM boundary 직전",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-backend",
|
||||
"type": "rectangle",
|
||||
"x": 728.0,
|
||||
"y": 257.5,
|
||||
"width": 160.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 430450037,
|
||||
"version": 1,
|
||||
"versionNonce": 288855291,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-backend",
|
||||
"type": "text",
|
||||
"x": 738.0,
|
||||
"y": 267.5,
|
||||
"width": 140.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 349920174,
|
||||
"version": 1,
|
||||
"versionNonce": 257387561,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "QEMU block backend",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "QEMU block backend",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-block-device",
|
||||
"type": "rectangle",
|
||||
"x": 1048.0,
|
||||
"y": 60.0,
|
||||
"width": 160.0,
|
||||
"height": 105.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#e7f5ff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1046702581,
|
||||
"version": 1,
|
||||
"versionNonce": 1391342654,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-block-device",
|
||||
"type": "text",
|
||||
"x": 1058.0,
|
||||
"y": 70.0,
|
||||
"width": 140.0,
|
||||
"height": 85.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1997913124,
|
||||
"version": 1,
|
||||
"versionNonce": 1061639791,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "Host block device\n/dev/...\nfile 없음\n→ Host block stack",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Host block device\n/dev/...\nfile 없음\n→ Host block stack",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-qcow2",
|
||||
"type": "rectangle",
|
||||
"x": 1048.0,
|
||||
"y": 237.0,
|
||||
"width": 160.0,
|
||||
"height": 105.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#e7f5ff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1108590116,
|
||||
"version": 1,
|
||||
"versionNonce": 663628861,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-qcow2",
|
||||
"type": "text",
|
||||
"x": 1058.0,
|
||||
"y": 247.0,
|
||||
"width": 140.0,
|
||||
"height": 85.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1782912670,
|
||||
"version": 1,
|
||||
"versionNonce": 427333534,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "qcow2 file\nfile backend\nmapping · metadata\n→ Host filesystem",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "qcow2 file\nfile backend\nmapping · metadata\n→ Host filesystem",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-raw",
|
||||
"type": "rectangle",
|
||||
"x": 1051.5,
|
||||
"y": 414.0,
|
||||
"width": 153.0,
|
||||
"height": 105.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#e7f5ff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1800492809,
|
||||
"version": 1,
|
||||
"versionNonce": 641737384,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-raw",
|
||||
"type": "text",
|
||||
"x": 1061.5,
|
||||
"y": 424.0,
|
||||
"width": 133.0,
|
||||
"height": 85.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 401005464,
|
||||
"version": 1,
|
||||
"versionNonce": 131485356,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "RAW file\nfile backend\noffset 대응\n→ Host filesystem",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "RAW file\nfile backend\noffset 대응\n→ Host filesystem",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": 10,
|
||||
"viewBackgroundColor": "#ffffff",
|
||||
"currentItemFontFamily": 5
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "qemu-block-backend-forms",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "f93efd7e7cc5bcf159ec1c0741a18e6f394ccb5aa7b257edf2d9a5339c4d0315",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "제4부 — 스토리지 가상화",
|
||||
"line": 5791
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"qemu-block-backend-forms.svg",
|
||||
"qemu-block-backend-forms.mmd",
|
||||
"qemu-block-backend-forms.d2",
|
||||
"qemu-block-backend-forms.dot",
|
||||
"qemu-block-backend-forms.drawio",
|
||||
"qemu-block-backend-forms.excalidraw",
|
||||
"qemu-block-backend-forms.alt.md"
|
||||
],
|
||||
"lint_issue_count": 0,
|
||||
"assumption_count": 0,
|
||||
"assumptions_allowed": false,
|
||||
"composition_profile": "component-flow",
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "85100cd6fde358fcc1408453c9208a1bbee5e58219856b92ff9346b3116623e3",
|
||||
"output_sha256": {
|
||||
"qemu-block-backend-forms.svg": "c493b2209e6af06b96bbc3affa53990a477ec71cd355f2cf8e84f2fba4beaedf",
|
||||
"qemu-block-backend-forms.mmd": "638f59435935b3df10da5209b13de0a6286d2835267c54d2039d8bc64c66ced3",
|
||||
"qemu-block-backend-forms.d2": "fa95e164401780c28227177a17d0d4ab48edb86c1c7dc74b2d92c25d4a4d280e",
|
||||
"qemu-block-backend-forms.dot": "f4ec55f023a6738a43a18bae7c40921ea9ba14390c224add8a9f2b133d3e7e32",
|
||||
"qemu-block-backend-forms.drawio": "f7d53a7f56be239541dd5edfef2cbc88834e886cb9a8aebdb260d6f6a39b6d2b",
|
||||
"qemu-block-backend-forms.excalidraw": "195dcaa2379574889102dd39a3af19aec39ed5b61b5173a953143ed13ffddadd",
|
||||
"qemu-block-backend-forms.alt.md": "ee90a0c129da2dd608e199df0a267d783af6bb0dd34dff1d5967a075dc42d2d5"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
%% virtqueue 뒤 QEMU block backend의 세 형태
|
||||
%% question: Guest /dev/vda 요청이 VM boundary를 넘은 뒤 QEMU에서 qcow2, RAW, Host block device 중 어느 backend로 이어지는가
|
||||
flowchart LR
|
||||
n0[("/dev/vda")]
|
||||
n1["virtio-blk · virtqueue"]
|
||||
n2["QEMU block backend"]
|
||||
n3[("qcow2 file")]
|
||||
n4[("RAW file")]
|
||||
n5[("Host block device")]
|
||||
n0 -->|"block I/O"| n1
|
||||
n1 -->|"VM boundary"| n2
|
||||
n2 -->|"qcow2 backend"| n3
|
||||
n2 -->|"RAW backend"| n4
|
||||
n2 -->|"block-device backend"| n5
|
||||
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1253" height="564" viewBox="0 0 1253 564" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">virtqueue 뒤 QEMU block backend의 세 형태</title>
|
||||
<desc id="diagram-description">왼쪽에서 Guest /dev/vda 요청이 virtio-blk와 virtqueue를 지나 VM boundary를 넘는다. QEMU block backend에서 qcow2 file, RAW file, Host block device 세 갈래로 나뉜다. qcow2와 RAW 노드에는 Host filesystem을 경유한다는 차이를, Host block device에는 파일 backend가 아니라는 차이를 적었다. 세 경로 아래의 Host block stack은 별도 Concept이 맡으므로 이 그림에서는 다시 합치지 않는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"qemu-block-backend-forms","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"제4부 — 스토리지 가상화","line":5791}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
</marker>
|
||||
<style>
|
||||
:root { color-scheme: light; }
|
||||
text { font-family: Inter, Pretendard, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #111827; }
|
||||
.canvas { fill: #ffffff; }
|
||||
.group-box { fill: #ffffff; stroke: #9ca3af; stroke-width: 1.4; stroke-dasharray: 7 5; }
|
||||
.group-label-bg { fill: #ffffff; }
|
||||
.group-label { font-size: 13px; font-weight: 650; fill: #374151; }
|
||||
.edge { fill: none; stroke: #374151; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; marker-end: url(#arrow); }
|
||||
.edge.style-dashed, .edge.semantic-dashed, .edge.assumption { stroke-dasharray: 7 5; }
|
||||
.edge.style-dotted { stroke-dasharray: 2 5; }
|
||||
.edge.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.edge.emphasis-muted { stroke: #9ca3af; }
|
||||
.edge.emphasis-warning, .edge.kind-failure, .edge.kind-error { stroke: #dc2626; stroke-width: 2.2; }
|
||||
.edge-label-bg { fill: #ffffff; }
|
||||
.edge-label { font-size: 12px; font-weight: 560; text-anchor: middle; }
|
||||
.node-shape { fill: #ffffff; stroke: #4b5563; stroke-width: 1.7; }
|
||||
.node-shape.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.node-shape.emphasis-muted { stroke: #9ca3af; fill: #f9fafb; }
|
||||
.node-shape.emphasis-warning { stroke: #d97706; stroke-width: 2; fill: #fffdf5; }
|
||||
.node-shape.kind-database, .node-shape.kind-datastore, .node-shape.kind-storage { fill: #f8fafc; }
|
||||
.node-shape.kind-queue, .node-shape.kind-event, .node-shape.kind-topic { fill: #fafafa; }
|
||||
.node-shape.assumption { stroke-dasharray: 4 4; }
|
||||
.storage-bottom, .controller-divider { fill: none; stroke: #4b5563; stroke-width: 1.4; }
|
||||
.controller-led { fill: #4b5563; }
|
||||
.actor-symbol { fill: none; stroke: #4b5563; stroke-width: 1.8; stroke-linecap: round; }
|
||||
.actor-symbol.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.node-label { font-size: 14px; font-weight: 650; text-anchor: middle; }
|
||||
.node-role { font-size: 10px; letter-spacing: 0.04em; text-anchor: middle; fill: #6b7280; }
|
||||
.node-detail-divider { stroke: #d1d5db; stroke-width: 1; }
|
||||
.node-detail { font-size: 11px; fill: #374151; }
|
||||
.assumption-badge { font-size: 9px; font-weight: 700; fill: #92400e; }
|
||||
.failure-mark { stroke: #dc2626; stroke-width: 4; stroke-linecap: round; }
|
||||
.lifeline { stroke: #9ca3af; stroke-width: 1.2; stroke-dasharray: 5 5; }
|
||||
.timeline-axis { stroke: #374151; stroke-width: 1.8; marker-end: url(#arrow); }
|
||||
.timeline-stem { stroke: #6b7280; stroke-width: 1.3; }
|
||||
.timeline-marker { fill: #ffffff; stroke: #374151; stroke-width: 1.7; }
|
||||
.timeline-marker.primary { fill: #2563eb; stroke: #2563eb; }
|
||||
.timeline-marker.warning { fill: #dc2626; stroke: #dc2626; }
|
||||
.timeline-label { font-size: 13px; font-weight: 650; text-anchor: middle; }
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="1253" height="564" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="888.0,271.5 968.0,271.5 968.0,112.5 1048.0,112.5" data-evidence="6551-6575" />
|
||||
<rect class="edge-label-bg" x="916.0" y="178.0" width="152.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="992.0" y="193.0">block-device backend</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="888.0,289.5 968.0,289.5 968.0,289.5 1048.0,289.5" data-evidence="6369-6379,6419-6460" />
|
||||
<rect class="edge-label-bg" x="915.5" y="247.5" width="105.1" height="22" rx="3" />
|
||||
<text class="edge-label" x="968.0" y="262.5">qcow2 backend</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="888.0,307.5 969.8,307.5 969.8,466.5 1051.5,466.5" data-evidence="6512-6547" />
|
||||
<rect class="edge-label-bg" x="947.9" y="373.0" width="91.7" height="22" rx="3" />
|
||||
<text class="edge-label" x="993.8" y="388.0">RAW backend</text>
|
||||
<polyline class="edge kind-request style-solid emphasis-normal" points="220.0,289.5 300.0,289.5 300.0,289.5 380.0,289.5" data-evidence="6355-6363" />
|
||||
<rect class="edge-label-bg" x="260.9" y="247.5" width="78.3" height="22" rx="3" />
|
||||
<text class="edge-label" x="300.0" y="262.5">block I/O</text>
|
||||
<polyline class="edge kind-request style-solid emphasis-normal" points="568.0,289.5 648.0,289.5 648.0,289.5 728.0,289.5" data-evidence="6362-6374" />
|
||||
<rect class="edge-label-bg" x="602.1" y="247.5" width="91.7" height="22" rx="3" />
|
||||
<text class="edge-label" x="648.0" y="262.5">VM boundary</text>
|
||||
<g id="node-vda">
|
||||
<rect class="node-shape kind-storage emphasis-normal role-source" data-evidence="6355-6363" x="70.0" y="268.2" width="150.0" height="42.7" /><ellipse class="node-shape kind-storage emphasis-normal role-source" cx="145.0" cy="268.2" rx="75.0" ry="10.7" /><path class="storage-bottom" d="M 70.0 310.8 A 75.0 10.7 0 0 0 220.0 310.8" />
|
||||
<text class="node-label" x="145.0" y="287.5">/dev/vda</text>
|
||||
</g>
|
||||
<g id="node-virtio-queue">
|
||||
<rect class="node-shape kind-component emphasis-normal role-service" data-evidence="6355-6364" x="380.0" y="245.5" width="188.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="474.0" y="272.5">virtio-blk · virtqueue</text>
|
||||
<line class="node-detail-divider" x1="394.0" y1="293.5" x2="554.0" y2="293.5" />
|
||||
<text class="node-detail" x="396.0" y="310.5">Guest</text>
|
||||
<text class="node-detail" x="396.0" y="326.5">VM boundary 직전</text>
|
||||
</g>
|
||||
<g id="node-backend">
|
||||
<rect class="node-shape kind-service emphasis-primary role-service" data-evidence="6367-6387" x="728.0" y="257.5" width="160.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="808.0" y="287.5">QEMU block backend</text>
|
||||
</g>
|
||||
<g id="node-block-device">
|
||||
<rect class="node-shape kind-storage emphasis-normal role-service" data-evidence="6551-6575" x="1048.0" y="73.0" width="160.0" height="79.0" /><ellipse class="node-shape kind-storage emphasis-normal role-service" cx="1128.0" cy="73.0" rx="80.0" ry="13.0" /><path class="storage-bottom" d="M 1048.0 152.0 A 80.0 13.0 0 0 0 1208.0 152.0" />
|
||||
<text class="node-label" x="1128.0" y="87.0">Host block device</text>
|
||||
<line class="node-detail-divider" x1="1062.0" y1="108.0" x2="1194.0" y2="108.0" />
|
||||
<text class="node-detail" x="1064.0" y="125.0">/dev/...</text>
|
||||
<text class="node-detail" x="1064.0" y="141.0">file 없음</text>
|
||||
<text class="node-detail" x="1064.0" y="157.0">→ Host block stack</text>
|
||||
</g>
|
||||
<g id="node-qcow2">
|
||||
<rect class="node-shape kind-storage emphasis-normal role-service" data-evidence="6419-6460,6512-6547" x="1048.0" y="250.0" width="160.0" height="79.0" /><ellipse class="node-shape kind-storage emphasis-normal role-service" cx="1128.0" cy="250.0" rx="80.0" ry="13.0" /><path class="storage-bottom" d="M 1048.0 329.0 A 80.0 13.0 0 0 0 1208.0 329.0" />
|
||||
<text class="node-label" x="1128.0" y="264.0">qcow2 file</text>
|
||||
<line class="node-detail-divider" x1="1062.0" y1="285.0" x2="1194.0" y2="285.0" />
|
||||
<text class="node-detail" x="1064.0" y="302.0">file backend</text>
|
||||
<text class="node-detail" x="1064.0" y="318.0">mapping · metadata</text>
|
||||
<text class="node-detail" x="1064.0" y="334.0">→ Host filesystem</text>
|
||||
</g>
|
||||
<g id="node-raw">
|
||||
<rect class="node-shape kind-storage emphasis-normal role-service" data-evidence="6512-6547" x="1051.5" y="427.0" width="153.0" height="79.0" /><ellipse class="node-shape kind-storage emphasis-normal role-service" cx="1128.0" cy="427.0" rx="76.5" ry="13.0" /><path class="storage-bottom" d="M 1051.5 506.0 A 76.5 13.0 0 0 0 1204.5 506.0" />
|
||||
<text class="node-label" x="1128.0" y="441.0">RAW file</text>
|
||||
<line class="node-detail-divider" x1="1065.5" y1="462.0" x2="1190.5" y2="462.0" />
|
||||
<text class="node-detail" x="1067.5" y="479.0">file backend</text>
|
||||
<text class="node-detail" x="1067.5" y="495.0">offset 대응</text>
|
||||
<text class="node-detail" x="1067.5" y="511.0">→ Host filesystem</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.2 KiB |
@@ -0,0 +1,27 @@
|
||||
# L7 두 홉과 진입점 이중화 재귀
|
||||
|
||||
## Alternative text
|
||||
|
||||
브라우저에서 edge nginx와 Traefik을 거쳐 Pod로 가는 두 L7 홉과, edge nginx를 두 대로 늘릴 때 앞단 selector가 새 단일 장애점이 되는 재귀를 함께 보여 주는 흐름도.
|
||||
|
||||
## Long description
|
||||
|
||||
왼쪽의 정상 경로는 브라우저가 TLS를 edge nginx에서 종료하고 고정 노드 IP로 전달한 뒤, Traefik이 동적으로 Pod를 고르는 흐름이다. 아래쪽 이중화 경로는 nginx-1과 nginx-2 앞에 selector를 두면 어느 nginx로 갈지 정할 수 있지만 selector 자체가 새 SPOF가 되어 같은 질문이 반복된다는 점을 보여 준다. VRRP·DNS·BGP·클라우드 LB 같은 재귀 종료 방식의 상세 비교는 본문 표에 남기고 그림에는 넣지 않는다.
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **Browser** (actor): 외부 요청의 시작점. Evidence: L15860–L15864.
|
||||
- **edge nginx** (service): 클러스터 밖 진입점. TLS와 인증서, forwarded header, 어느 노드로 보낼지를 맡는다. Evidence: L15860–L15882.
|
||||
- **Traefik** (service): 클러스터 안에서 Service/Ingress 상태를 따라 어느 Pod로 보낼지 정한다. Evidence: L15872–L15882.
|
||||
- **Pod** (runtime): Traefik이 선택한 실제 워크로드. Evidence: L15860–L15864.
|
||||
- **앞단 selector** (service): nginx를 여러 머신으로 이중화했을 때 어느 nginx로 갈지 정하는 새 앞단. Evidence: L15941–L15945.
|
||||
- **nginx-1 · nginx-2** (service): 진짜 이중화를 위해 머신을 늘린 edge nginx 쌍. Evidence: L15934–L15944.
|
||||
- **selector가 새 SPOF** (result): selector를 하나 더 두면 같은 단일 장애점 질문이 한 단계 앞으로 이동한다. Evidence: L15941–L15952.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **Browser → edge nginx:** HTTPS. Evidence: L15860–L15864.
|
||||
- **edge nginx → Traefik:** 노드 선택 · HTTP. Evidence: L15872–L15882.
|
||||
- **앞단 selector → nginx-1 · nginx-2:** nginx 선택. Evidence: L15941–L15945.
|
||||
- **앞단 selector → selector가 새 SPOF:** 단일 selector. Evidence: L15941–L15952.
|
||||
- **Traefik → Pod:** Ingress routing. Evidence: L15860–L15882.
|
||||
@@ -0,0 +1,29 @@
|
||||
# L7 두 홉과 진입점 이중화 재귀
|
||||
# Question: 요청은 왜 nginx와 Traefik이라는 두 L7 홉을 지나며, nginx를 두 대로 늘리면 왜 다시 selector가 필요한가
|
||||
direction: right
|
||||
n0: "Browser" {
|
||||
shape: person
|
||||
}
|
||||
n1: "edge nginx" {
|
||||
shape: rectangle
|
||||
}
|
||||
n2: "Traefik" {
|
||||
shape: rectangle
|
||||
}
|
||||
n3: "Pod" {
|
||||
shape: rectangle
|
||||
}
|
||||
n4: "앞단 selector" {
|
||||
shape: rectangle
|
||||
}
|
||||
n5: "nginx-1 · nginx-2" {
|
||||
shape: rectangle
|
||||
}
|
||||
n6: "selector가 새 SPOF" {
|
||||
shape: rectangle
|
||||
}
|
||||
n0 -> n1: "HTTPS"
|
||||
n1 -> n2: "노드 선택 · HTTP"
|
||||
n2 -> n3: "Ingress routing"
|
||||
n4 -> n5: "nginx 선택"
|
||||
n4 -> n6: "단일 selector"
|
||||
@@ -0,0 +1,17 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="Browser", shape=box, style="rounded,dashed,filled"];
|
||||
n1 [label="edge nginx", shape=box, style="rounded,filled"];
|
||||
n2 [label="Traefik", shape=box, style="rounded,filled"];
|
||||
n3 [label="Pod", shape=box, style="rounded,filled"];
|
||||
n4 [label="앞단 selector", shape=box, style="rounded,filled"];
|
||||
n5 [label="nginx-1 · nginx-2", shape=box, style="rounded,filled"];
|
||||
n6 [label="selector가 새 SPOF", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="HTTPS", style=solid];
|
||||
n1 -> n2 [label="노드 선택 · HTTP", style=solid];
|
||||
n2 -> n3 [label="Ingress routing", style=solid];
|
||||
n4 -> n5 [label="nginx 선택", style=solid];
|
||||
n4 -> n6 [label="단일 selector", style=solid];
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="two-l7-hops-entry-recursion" name="L7 두 홉과 진입점 이중화 재귀">
|
||||
<mxGraphModel dx="1198" dy="489" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1198" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_browser" value="Browser" tooltip="외부 요청의 시작점. | Evidence: L15860-L15864" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;dashed=1;fillColor=#f5f7fa;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="138.5" width="150.0" height="84.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_selector" value="앞단 selector<br/>edge redundancy" tooltip="nginx를 여러 머신으로 이중화했을 때 어느 nginx로 갈지 정하는 새 앞단. | Evidence: L15941-L15945" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="294.5" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_edge-nginx" value="edge nginx<br/>L7<br/>TLS 종료<br/>고정 노드 선택" tooltip="클러스터 밖 진입점. TLS와 인증서, forwarded header, 어느 노드로 보낼지를 맡는다. | Evidence: L15860-L15882" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="381.5" y="60.0" width="150.0" height="105.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_new-spof" value="selector가 새 SPOF" tooltip="selector를 하나 더 두면 같은 단일 장애점 질문이 한 단계 앞으로 이동한다. | Evidence: L15941-L15952" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="381.5" y="237.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_nginx-pair" value="nginx-1 · nginx-2<br/>서로 다른 머신" tooltip="진짜 이중화를 위해 머신을 늘린 edge nginx 쌍. | Evidence: L15934-L15944" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="380.0" y="373.0" width="153.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_traefik" value="Traefik<br/>L7<br/>Ingress<br/>동적 Pod 선택" tooltip="클러스터 안에서 Service/Ingress 상태를 따라 어느 Pod로 보낼지 정한다. | Evidence: L15872-L15882" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="693.0" y="199.5" width="150.0" height="105.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_pod" value="Pod" tooltip="Traefik이 선택한 실제 워크로드. | Evidence: L15860-L15864" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1003.0" y="220.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_browser-edge" value="HTTPS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_browser" target="n_edge-nginx">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="324.8" y="146.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_edge-traefik" value="노드 선택 · HTTP" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_edge-nginx" target="n_traefik">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="636.2" y="182.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_selector-pair" value="nginx 선택" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_selector" target="n_nginx-pair">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="324.0" y="373.8" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_selector-spof" value="단일 selector" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_selector" target="n_new-spof">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="324.8" y="295.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_traefik-pod" value="Ingress routing" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_traefik" target="n_pod">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="923.0" y="224.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -0,0 +1,991 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "techviz-harness",
|
||||
"elements": [
|
||||
{
|
||||
"id": "edge-browser-edge",
|
||||
"type": "arrow",
|
||||
"x": 220.0,
|
||||
"y": 112.5,
|
||||
"width": 161.5,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 186905999,
|
||||
"version": 1,
|
||||
"versionNonce": 1820419618,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
68.0
|
||||
],
|
||||
[
|
||||
80.75,
|
||||
68.0
|
||||
],
|
||||
[
|
||||
80.75,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
161.5,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-browser",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-edge-nginx",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-browser-edge",
|
||||
"type": "text",
|
||||
"x": 279.75,
|
||||
"y": 134.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1526221385,
|
||||
"version": 1,
|
||||
"versionNonce": 1972303568,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "HTTPS",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "HTTPS",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-edge-traefik",
|
||||
"type": "arrow",
|
||||
"x": 531.5,
|
||||
"y": 112.5,
|
||||
"width": 161.5,
|
||||
"height": 139.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 554407219,
|
||||
"version": 1,
|
||||
"versionNonce": 216820257,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.75,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.75,
|
||||
139.5
|
||||
],
|
||||
[
|
||||
161.5,
|
||||
139.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-edge-nginx",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-traefik",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-edge-traefik",
|
||||
"type": "text",
|
||||
"x": 588.25,
|
||||
"y": 170.25,
|
||||
"width": 96,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1588681295,
|
||||
"version": 1,
|
||||
"versionNonce": 1551632150,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "노드 선택 · HTTP",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "노드 선택 · HTTP",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-selector-pair",
|
||||
"type": "arrow",
|
||||
"x": 220.0,
|
||||
"y": 339.0,
|
||||
"width": 160.0,
|
||||
"height": 69.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 2620936,
|
||||
"version": 1,
|
||||
"versionNonce": 157891078,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
69.5
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
69.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-selector",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-nginx-pair",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-selector-pair",
|
||||
"type": "text",
|
||||
"x": 279.0,
|
||||
"y": 361.75,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 960601273,
|
||||
"version": 1,
|
||||
"versionNonce": 86143142,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "nginx 선택",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "nginx 선택",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-selector-spof",
|
||||
"type": "arrow",
|
||||
"x": 220.0,
|
||||
"y": 269.0,
|
||||
"width": 161.5,
|
||||
"height": 52.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 356089597,
|
||||
"version": 1,
|
||||
"versionNonce": 433321811,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
52.0
|
||||
],
|
||||
[
|
||||
80.75,
|
||||
52.0
|
||||
],
|
||||
[
|
||||
80.75,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
161.5,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-selector",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-new-spof",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-selector-spof",
|
||||
"type": "text",
|
||||
"x": 279.75,
|
||||
"y": 283.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 423024263,
|
||||
"version": 1,
|
||||
"versionNonce": 617422139,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "단일 selector",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "단일 selector",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "edge-traefik-pod",
|
||||
"type": "arrow",
|
||||
"x": 843.0,
|
||||
"y": 252.0,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": null,
|
||||
"seed": 1096728329,
|
||||
"version": 1,
|
||||
"versionNonce": 1723994398,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "node-traefik",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "node-pod",
|
||||
"focus": 0,
|
||||
"gap": 4
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": true
|
||||
},
|
||||
{
|
||||
"id": "edge-label-traefik-pod",
|
||||
"type": "text",
|
||||
"x": 863.0,
|
||||
"y": 212.0,
|
||||
"width": 120,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1933132434,
|
||||
"version": 1,
|
||||
"versionNonce": 670041335,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 13,
|
||||
"fontFamily": 5,
|
||||
"text": "Ingress routing",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Ingress routing",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-browser",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 138.5,
|
||||
"width": 150.0,
|
||||
"height": 84.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1549664096,
|
||||
"version": 1,
|
||||
"versionNonce": 397227867,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-browser",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 148.5,
|
||||
"width": 130.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 225442297,
|
||||
"version": 1,
|
||||
"versionNonce": 1441680053,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "Browser",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Browser",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-selector",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 294.5,
|
||||
"width": 150.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1184769825,
|
||||
"version": 1,
|
||||
"versionNonce": 1029245291,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-selector",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 304.5,
|
||||
"width": 130.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 288604214,
|
||||
"version": 1,
|
||||
"versionNonce": 460695876,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "앞단 selector\nedge redundancy",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "앞단 selector\nedge redundancy",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-edge-nginx",
|
||||
"type": "rectangle",
|
||||
"x": 381.5,
|
||||
"y": 60.0,
|
||||
"width": 150.0,
|
||||
"height": 105.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 248904590,
|
||||
"version": 1,
|
||||
"versionNonce": 1382229884,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-edge-nginx",
|
||||
"type": "text",
|
||||
"x": 391.5,
|
||||
"y": 70.0,
|
||||
"width": 130.0,
|
||||
"height": 85.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1452529323,
|
||||
"version": 1,
|
||||
"versionNonce": 150210873,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "edge nginx\nL7\nTLS 종료\n고정 노드 선택",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "edge nginx\nL7\nTLS 종료\n고정 노드 선택",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-new-spof",
|
||||
"type": "rectangle",
|
||||
"x": 381.5,
|
||||
"y": 237.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 202855345,
|
||||
"version": 1,
|
||||
"versionNonce": 974263866,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-new-spof",
|
||||
"type": "text",
|
||||
"x": 391.5,
|
||||
"y": 247.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1946517495,
|
||||
"version": 1,
|
||||
"versionNonce": 1945847116,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "selector가 새 SPOF",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "selector가 새 SPOF",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-nginx-pair",
|
||||
"type": "rectangle",
|
||||
"x": 380.0,
|
||||
"y": 373.0,
|
||||
"width": 153.0,
|
||||
"height": 71.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1402329794,
|
||||
"version": 1,
|
||||
"versionNonce": 1572853951,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-nginx-pair",
|
||||
"type": "text",
|
||||
"x": 390.0,
|
||||
"y": 383.0,
|
||||
"width": 133.0,
|
||||
"height": 51.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1201103364,
|
||||
"version": 1,
|
||||
"versionNonce": 1167919269,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "nginx-1 · nginx-2\n서로 다른 머신",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "nginx-1 · nginx-2\n서로 다른 머신",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-traefik",
|
||||
"type": "rectangle",
|
||||
"x": 693.0,
|
||||
"y": 199.5,
|
||||
"width": 150.0,
|
||||
"height": 105.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1004362376,
|
||||
"version": 1,
|
||||
"versionNonce": 1434039951,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-traefik",
|
||||
"type": "text",
|
||||
"x": 703.0,
|
||||
"y": 209.5,
|
||||
"width": 130.0,
|
||||
"height": 85.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1067358536,
|
||||
"version": 1,
|
||||
"versionNonce": 1366351535,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "Traefik\nL7\nIngress\n동적 Pod 선택",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Traefik\nL7\nIngress\n동적 Pod 선택",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "node-pod",
|
||||
"type": "rectangle",
|
||||
"x": 1003.0,
|
||||
"y": 220.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 339878091,
|
||||
"version": 1,
|
||||
"versionNonce": 723591255,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "node-label-pod",
|
||||
"type": "text",
|
||||
"x": 1013.0,
|
||||
"y": 230.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": null,
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 1089876355,
|
||||
"version": 1,
|
||||
"versionNonce": 1055792127,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 0,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 15,
|
||||
"fontFamily": 5,
|
||||
"text": "Pod",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Pod",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": 10,
|
||||
"viewBackgroundColor": "#ffffff",
|
||||
"currentItemFontFamily": 5
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "two-l7-hops-entry-recursion",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "552c4dddd1e282894d019a6969c02211c756842dfc2c9678f3aef4d5a4179b51",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "261. 진입점 자체가 죽으면 — 로드밸런서의 재귀 문제",
|
||||
"line": 15796
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"two-l7-hops-entry-recursion.svg",
|
||||
"two-l7-hops-entry-recursion.mmd",
|
||||
"two-l7-hops-entry-recursion.d2",
|
||||
"two-l7-hops-entry-recursion.dot",
|
||||
"two-l7-hops-entry-recursion.drawio",
|
||||
"two-l7-hops-entry-recursion.excalidraw",
|
||||
"two-l7-hops-entry-recursion.alt.md"
|
||||
],
|
||||
"lint_issue_count": 0,
|
||||
"assumption_count": 0,
|
||||
"assumptions_allowed": false,
|
||||
"composition_profile": "component-flow",
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "696b5eacdc38802d1a5292be1f7c55021bd3c613d0672b69fbb1321ccd356170",
|
||||
"output_sha256": {
|
||||
"two-l7-hops-entry-recursion.svg": "e9f30d5041e9c29252b8fd92fd8ba6c2304cc7502db29709cbfa11a36c419b2f",
|
||||
"two-l7-hops-entry-recursion.mmd": "89b13720136391d5ccce8ef1e0fbbece0c31e6b2251fb8e78a79cedd16f4d5cd",
|
||||
"two-l7-hops-entry-recursion.d2": "89612014c64a9efdc5e5398f2e4d945ce834b157627395b22d746c75c31203e2",
|
||||
"two-l7-hops-entry-recursion.dot": "df604779925b64355402019d985d4c2e34cb3a25630d9fb1a542ffed9a6f3f65",
|
||||
"two-l7-hops-entry-recursion.drawio": "c4cb00a19ad30bcf4c2284c1f6937e4d5059546982b7f3c98422963262e0697c",
|
||||
"two-l7-hops-entry-recursion.excalidraw": "1620c8848c78a0d47e6538dbe117208fd63625fe23782d0f800030230c335bf3",
|
||||
"two-l7-hops-entry-recursion.alt.md": "8f0ad5d24a038648568192a7b461f1acbe6be87407de91fbfa82253c3b9c3829"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
%% L7 두 홉과 진입점 이중화 재귀
|
||||
%% question: 요청은 왜 nginx와 Traefik이라는 두 L7 홉을 지나며, nginx를 두 대로 늘리면 왜 다시 selector가 필요한가
|
||||
flowchart LR
|
||||
n0(["Browser"])
|
||||
n1["edge nginx"]
|
||||
n2["Traefik"]
|
||||
n3["Pod"]
|
||||
n4["앞단 selector"]
|
||||
n5["nginx-1 · nginx-2"]
|
||||
n6["selector가 새 SPOF"]
|
||||
n0 -->|"HTTPS"| n1
|
||||
n1 -->|"노드 선택 · HTTP"| n2
|
||||
n2 -->|"Ingress routing"| n3
|
||||
n4 -->|"nginx 선택"| n5
|
||||
n4 -->|"단일 selector"| n6
|
||||
classDef external stroke-dasharray: 6 4
|
||||
class n0 external
|
||||
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1198" height="489" viewBox="0 0 1198 489" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">L7 두 홉과 진입점 이중화 재귀</title>
|
||||
<desc id="diagram-description">왼쪽의 정상 경로는 브라우저가 TLS를 edge nginx에서 종료하고 고정 노드 IP로 전달한 뒤, Traefik이 동적으로 Pod를 고르는 흐름이다. 아래쪽 이중화 경로는 nginx-1과 nginx-2 앞에 selector를 두면 어느 nginx로 갈지 정할 수 있지만 selector 자체가 새 SPOF가 되어 같은 질문이 반복된다는 점을 보여 준다. VRRP·DNS·BGP·클라우드 LB 같은 재귀 종료 방식의 상세 비교는 본문 표에 남기고 그림에는 넣지 않는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"two-l7-hops-entry-recursion","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"261. 진입점 자체가 죽으면 — 로드밸런서의 재귀 문제","line":15796}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
</marker>
|
||||
<style>
|
||||
:root { color-scheme: light; }
|
||||
text { font-family: Inter, Pretendard, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #111827; }
|
||||
.canvas { fill: #ffffff; }
|
||||
.group-box { fill: #ffffff; stroke: #9ca3af; stroke-width: 1.4; stroke-dasharray: 7 5; }
|
||||
.group-label-bg { fill: #ffffff; }
|
||||
.group-label { font-size: 13px; font-weight: 650; fill: #374151; }
|
||||
.edge { fill: none; stroke: #374151; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; marker-end: url(#arrow); }
|
||||
.edge.style-dashed, .edge.semantic-dashed, .edge.assumption { stroke-dasharray: 7 5; }
|
||||
.edge.style-dotted { stroke-dasharray: 2 5; }
|
||||
.edge.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.edge.emphasis-muted { stroke: #9ca3af; }
|
||||
.edge.emphasis-warning, .edge.kind-failure, .edge.kind-error { stroke: #dc2626; stroke-width: 2.2; }
|
||||
.edge-label-bg { fill: #ffffff; }
|
||||
.edge-label { font-size: 12px; font-weight: 560; text-anchor: middle; }
|
||||
.node-shape { fill: #ffffff; stroke: #4b5563; stroke-width: 1.7; }
|
||||
.node-shape.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.node-shape.emphasis-muted { stroke: #9ca3af; fill: #f9fafb; }
|
||||
.node-shape.emphasis-warning { stroke: #d97706; stroke-width: 2; fill: #fffdf5; }
|
||||
.node-shape.kind-database, .node-shape.kind-datastore, .node-shape.kind-storage { fill: #f8fafc; }
|
||||
.node-shape.kind-queue, .node-shape.kind-event, .node-shape.kind-topic { fill: #fafafa; }
|
||||
.node-shape.assumption { stroke-dasharray: 4 4; }
|
||||
.storage-bottom, .controller-divider { fill: none; stroke: #4b5563; stroke-width: 1.4; }
|
||||
.controller-led { fill: #4b5563; }
|
||||
.actor-symbol { fill: none; stroke: #4b5563; stroke-width: 1.8; stroke-linecap: round; }
|
||||
.actor-symbol.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
|
||||
.node-label { font-size: 14px; font-weight: 650; text-anchor: middle; }
|
||||
.node-role { font-size: 10px; letter-spacing: 0.04em; text-anchor: middle; fill: #6b7280; }
|
||||
.node-detail-divider { stroke: #d1d5db; stroke-width: 1; }
|
||||
.node-detail { font-size: 11px; fill: #374151; }
|
||||
.assumption-badge { font-size: 9px; font-weight: 700; fill: #92400e; }
|
||||
.failure-mark { stroke: #dc2626; stroke-width: 4; stroke-linecap: round; }
|
||||
.lifeline { stroke: #9ca3af; stroke-width: 1.2; stroke-dasharray: 5 5; }
|
||||
.timeline-axis { stroke: #374151; stroke-width: 1.8; marker-end: url(#arrow); }
|
||||
.timeline-stem { stroke: #6b7280; stroke-width: 1.3; }
|
||||
.timeline-marker { fill: #ffffff; stroke: #374151; stroke-width: 1.7; }
|
||||
.timeline-marker.primary { fill: #2563eb; stroke: #2563eb; }
|
||||
.timeline-marker.warning { fill: #dc2626; stroke: #dc2626; }
|
||||
.timeline-label { font-size: 13px; font-weight: 650; text-anchor: middle; }
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="1198" height="489" />
|
||||
<polyline class="edge kind-request style-solid emphasis-normal" points="220.0,180.5 300.8,180.5 300.8,112.5 381.5,112.5" data-evidence="15860-15864" />
|
||||
<rect class="edge-label-bg" x="299.0" y="132.5" width="51.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="324.8" y="147.5">HTTPS</text>
|
||||
<polyline class="edge kind-request style-solid emphasis-normal" points="531.5,112.5 612.2,112.5 612.2,252.0 693.0,252.0" data-evidence="15872-15882" />
|
||||
<rect class="edge-label-bg" x="587.0" y="168.2" width="98.4" height="22" rx="3" />
|
||||
<text class="edge-label" x="636.2" y="183.2">노드 선택 · HTTP</text>
|
||||
<polyline class="edge kind-request style-dashed emphasis-normal" points="220.0,339.0 300.0,339.0 300.0,408.5 380.0,408.5" data-evidence="15941-15945" />
|
||||
<rect class="edge-label-bg" x="288.2" y="359.8" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="324.0" y="374.8">nginx 선택</text>
|
||||
<polyline class="edge kind-result style-dashed emphasis-normal" points="220.0,321.0 300.8,321.0 300.8,269.0 381.5,269.0" data-evidence="15941-15952" />
|
||||
<rect class="edge-label-bg" x="278.9" y="281.0" width="91.7" height="22" rx="3" />
|
||||
<text class="edge-label" x="324.8" y="296.0">단일 selector</text>
|
||||
<polyline class="edge kind-request style-solid emphasis-normal" points="843.0,252.0 923.0,252.0 923.0,252.0 1003.0,252.0" data-evidence="15860-15882" />
|
||||
<rect class="edge-label-bg" x="863.8" y="210.0" width="118.5" height="22" rx="3" />
|
||||
<text class="edge-label" x="923.0" y="225.0">Ingress routing</text>
|
||||
<g id="node-browser">
|
||||
<g class="actor-symbol emphasis-normal" data-evidence="15860-15864"><circle cx="145.0" cy="158.5" r="11.0" /><line x1="145.0" y1="174.5" x2="145.0" y2="193.5" /><line x1="127.0" y1="184.5" x2="163.0" y2="184.5" /><line x1="145.0" y1="193.5" x2="130.0" y2="210.5" /><line x1="145.0" y1="193.5" x2="160.0" y2="210.5" /></g>
|
||||
<text class="node-label" x="145.0" y="215.5">Browser</text>
|
||||
</g>
|
||||
<g id="node-selector">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="15941-15945" x="70.0" y="294.5" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="321.5">앞단 selector</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="342.5" x2="206.0" y2="342.5" />
|
||||
<text class="node-detail" x="86.0" y="359.5">edge redundancy</text>
|
||||
</g>
|
||||
<g id="node-edge-nginx">
|
||||
<rect class="node-shape kind-service emphasis-primary role-service" data-evidence="15860-15882" x="381.5" y="60.0" width="150.0" height="105.0" rx="7" />
|
||||
<text class="node-label" x="456.5" y="87.0">edge nginx</text>
|
||||
<line class="node-detail-divider" x1="395.5" y1="108.0" x2="517.5" y2="108.0" />
|
||||
<text class="node-detail" x="397.5" y="125.0">L7</text>
|
||||
<text class="node-detail" x="397.5" y="141.0">TLS 종료</text>
|
||||
<text class="node-detail" x="397.5" y="157.0">고정 노드 선택</text>
|
||||
</g>
|
||||
<g id="node-new-spof">
|
||||
<rect class="node-shape kind-result emphasis-normal role-sink" data-evidence="15941-15952" x="381.5" y="237.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="456.5" y="267.0">selector가 새 SPOF</text>
|
||||
</g>
|
||||
<g id="node-nginx-pair">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="15934-15944" x="380.0" y="373.0" width="153.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="456.5" y="400.0">nginx-1 · nginx-2</text>
|
||||
<line class="node-detail-divider" x1="394.0" y1="421.0" x2="519.0" y2="421.0" />
|
||||
<text class="node-detail" x="396.0" y="438.0">서로 다른 머신</text>
|
||||
</g>
|
||||
<g id="node-traefik">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="15872-15882" x="693.0" y="199.5" width="150.0" height="105.0" rx="7" />
|
||||
<text class="node-label" x="768.0" y="226.5">Traefik</text>
|
||||
<line class="node-detail-divider" x1="707.0" y1="247.5" x2="829.0" y2="247.5" />
|
||||
<text class="node-detail" x="709.0" y="264.5">L7</text>
|
||||
<text class="node-detail" x="709.0" y="280.5">Ingress</text>
|
||||
<text class="node-detail" x="709.0" y="296.5">동적 Pod 선택</text>
|
||||
</g>
|
||||
<g id="node-pod">
|
||||
<rect class="node-shape kind-runtime emphasis-normal role-sink" data-evidence="15860-15864" x="1003.0" y="220.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="1078.0" y="250.0">Pod</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
@@ -10,24 +10,24 @@ virtio-balloon Driver, virtqueue, QEMU virtio-balloon Device, Host Memory Manage
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **virtio-balloon Driver** (driver): Guest kernel 쪽 balloon driver. target 을 받아 Guest page 를 확보한다. Evidence: L3013–L3015, L3046–L3046.
|
||||
- **virtqueue** (queue): Guest 와 QEMU 가 balloon 요청을 주고받는 공유 큐. VM Boundary 바로 안쪽이다. Evidence: L3017–L3017.
|
||||
- **virtio-balloon Driver** (driver): Guest kernel 쪽 balloon driver. target 을 받아 Guest page 를 확보한다. Evidence: L3026–L3028, L3059–L3059.
|
||||
- **virtqueue** (queue): Guest 와 QEMU 가 balloon 요청을 주고받는 공유 큐. VM Boundary 바로 안쪽이다. Evidence: L3030–L3030.
|
||||
- **QEMU virtio-balloon
|
||||
Device** (service): Host 쪽 balloon device. 경계를 넘어온 내용을 Host memory management 로 넘긴다. Evidence: L3022–L3022, L3037–L3041.
|
||||
Device** (service): Host 쪽 balloon device. 경계를 넘어온 내용을 Host memory management 로 넘긴다. Evidence: L3035–L3035, L3050–L3054.
|
||||
- **Host Memory
|
||||
Management** (service): balloon target 을 정하는 쪽이자 회수 기회가 생기는 자리. Evidence: L3025–L3025, L3034–L3037.
|
||||
Management** (service): balloon target 을 정하는 쪽이자 회수 기회가 생기는 자리. Evidence: L3038–L3038, L3047–L3050.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **Host Memory
|
||||
Management → QEMU virtio-balloon
|
||||
Device:** Balloon target 조정. Evidence: L3034–L3041.
|
||||
Device:** Balloon target 조정. Evidence: L3047–L3054.
|
||||
- **QEMU virtio-balloon
|
||||
Device → virtqueue:** VM Boundary. Evidence: L3017–L3022, L3041–L3046.
|
||||
- **virtqueue → virtio-balloon Driver:** Balloon target. Evidence: L3013–L3017, L3043–L3046.
|
||||
- **virtio-balloon Driver → virtqueue:** Guest pages 확보. Evidence: L3046–L3050.
|
||||
Device → virtqueue:** VM Boundary. Evidence: L3030–L3035, L3054–L3059.
|
||||
- **virtqueue → virtio-balloon Driver:** Balloon target. Evidence: L3026–L3030, L3056–L3059.
|
||||
- **virtio-balloon Driver → virtqueue:** Guest pages 확보. Evidence: L3059–L3063.
|
||||
- **virtqueue → QEMU virtio-balloon
|
||||
Device:** VM Boundary. Evidence: L3017–L3025.
|
||||
Device:** VM Boundary. Evidence: L3030–L3038.
|
||||
- **QEMU virtio-balloon
|
||||
Device → Host Memory
|
||||
Management:** 회수 가능 backing. Evidence: L3022–L3028, L3077–L3079.
|
||||
Management:** 회수 가능 backing. Evidence: L3035–L3041, L3090–L3092.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="virtio-balloon Driver", shape=box, style="rounded,filled"];
|
||||
n1 [label="virtqueue", shape=oval, style="rounded,filled"];
|
||||
n2 [label="QEMU virtio-balloon\nDevice", shape=box, style="rounded,filled"];
|
||||
n3 [label="Host Memory\nManagement", shape=box, style="rounded,filled"];
|
||||
n3 -> n2 [label="Balloon target 조정", style=solid];
|
||||
n2 -> n1 [label="VM Boundary", style=solid];
|
||||
n1 -> n0 [label="Balloon target", style=solid];
|
||||
n0 -> n1 [label="Guest pages 확보", style=solid];
|
||||
n1 -> n2 [label="VM Boundary", style=solid];
|
||||
n2 -> n3 [label="회수 가능 backing", style=solid];
|
||||
}
|
||||
@@ -5,18 +5,18 @@
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_balloon-driver" value="virtio-balloon Driver<br/>Guest Kernel" tooltip="Guest kernel 쪽 balloon driver. target 을 받아 Guest page 를 확보한다. | Evidence: L3013-L3015, L3046-L3046" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxCell id="n_balloon-driver" value="virtio-balloon Driver<br/>Guest Kernel" tooltip="Guest kernel 쪽 balloon driver. target 을 받아 Guest page 를 확보한다. | Evidence: L3026-L3028, L3059-L3059" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="45.0" y="35.0" width="181.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_virtqueue" value="virtqueue" tooltip="Guest 와 QEMU 가 balloon 요청을 주고받는 공유 큐. VM Boundary 바로 안쪽이다. | Evidence: L3017-L3017" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_virtqueue" value="virtqueue" tooltip="Guest 와 QEMU 가 balloon 요청을 주고받는 공유 큐. VM Boundary 바로 안쪽이다. | Evidence: L3030-L3030" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="255.0" y="35.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_qemu-balloon-device" value="QEMU virtio-balloon
|
||||
Device" tooltip="Host 쪽 balloon device. 경계를 넘어온 내용을 Host memory management 로 넘긴다. | Evidence: L3022-L3022, L3037-L3041" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
Device" tooltip="Host 쪽 balloon device. 경계를 넘어온 내용을 Host memory management 로 넘긴다. | Evidence: L3035-L3035, L3050-L3054" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="465.0" y="35.0" width="167.0" height="74.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_host-memory-management" value="Host Memory
|
||||
Management" tooltip="balloon target 을 정하는 쪽이자 회수 기회가 생기는 자리. | Evidence: L3025-L3025, L3034-L3037" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
Management" tooltip="balloon target 을 정하는 쪽이자 회수 기회가 생기는 자리. | Evidence: L3038-L3038, L3047-L3050" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="675.0" y="35.0" width="150.0" height="74.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_target-adjust" value="Balloon target 조정" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-memory-management" target="n_qemu-balloon-device">
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "virtio-balloon-inflate-deflate",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "1a53fd7e3e5cf5b553be00d6c12f47f8493d302f9a79f660d29e1d85490e61de",
|
||||
"spec_sha256": "4656ebc5df3dec37c88ef57a973289ffff3ac2d8035c85c09ffc1819d68ab855",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "65. virtio-balloon 구조",
|
||||
"line": 3008
|
||||
"line": 3021
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"virtio-balloon-inflate-deflate.svg",
|
||||
"virtio-balloon-inflate-deflate.drawio",
|
||||
"virtio-balloon-inflate-deflate.mmd",
|
||||
"virtio-balloon-inflate-deflate.d2",
|
||||
"virtio-balloon-inflate-deflate.dot",
|
||||
"virtio-balloon-inflate-deflate.drawio",
|
||||
"virtio-balloon-inflate-deflate.excalidraw",
|
||||
"virtio-balloon-inflate-deflate.alt.md"
|
||||
],
|
||||
@@ -27,5 +28,15 @@
|
||||
"reference_ids": [
|
||||
"payment-approval-sequence"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "3eb87c2e0da87b76563f6611dca1821ffe17b18debb16ede52863436ff74a534",
|
||||
"output_sha256": {
|
||||
"virtio-balloon-inflate-deflate.svg": "4722f6147d70def8734f300b7ffdaba8acb341448182ed9666be74136104c7ee",
|
||||
"virtio-balloon-inflate-deflate.mmd": "a756eba8251ca111a406ff5af80c3e45f537df7f5b03e7536e25e2d14498a945",
|
||||
"virtio-balloon-inflate-deflate.d2": "4ef3dab8288b8823688910eb416fe922d258a0736d0e4074c1f6931c052df9ed",
|
||||
"virtio-balloon-inflate-deflate.dot": "5ab4b8d1b4fc02972b5dd270496ed95d98918b34ef8476c4b4bf95b5131eb201",
|
||||
"virtio-balloon-inflate-deflate.drawio": "20abf47a8865a3569aa1caa56dd7de168c2af3d0052e228381f27087dc60ad83",
|
||||
"virtio-balloon-inflate-deflate.excalidraw": "0613fa8301e2a5d7eb080f706e6841d828445b4ce7baf23e9b845a7856a90abb",
|
||||
"virtio-balloon-inflate-deflate.alt.md": "4358baa3745beb79671dc64ed9cf31f445815ab6256d7c65e3924ceb1a0dbc82"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="870" height="542" viewBox="0 0 870 542" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">balloon target 은 VM Boundary 를 건너 driver 에 닿고 확보한 page 는 같은 경계를 되건너 온다</title>
|
||||
<desc id="diagram-description">참여자는 왼쪽부터 Guest kernel 의 virtio-balloon Driver, virtqueue, QEMU virtio-balloon Device, Host Memory Management 네 개다. 메시지는 위에서 아래로 읽는다. 1번은 Host Memory Management 가 QEMU 쪽 device 에 balloon target 조정을 보내는 것이고, 2번에서 그 요청이 virtqueue 로 내려가면서 VM Boundary 를 넘고, 3번에서 Guest kernel 의 driver 에 balloon target 이 닿는다. 여기서 방향이 바뀐다. 4번에서 driver 가 확보한 Guest page 를 virtqueue 에 올리고, 5번에서 그것이 다시 VM Boundary 를 넘어 QEMU 쪽 device 로 가고, 6번에서 device 가 Host Memory Management 에 회수 가능 backing 으로 넘긴다. target 을 올릴 때와 내릴 때 Guest 가 쓸 수 있는 memory 가 어느 쪽으로 움직이는지는 본문의 표가 맡는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"virtio-balloon-inflate-deflate","profile":"sequence"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"65. virtio-balloon 구조","line":3008}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"virtio-balloon-inflate-deflate","profile":"sequence"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"65. virtio-balloon 구조","line":3021}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -50,38 +50,38 @@
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="870" height="542" />
|
||||
<rect class="node-shape kind-driver emphasis-primary role-participant" data-evidence="3013-3015,3046-3046" x="45.0" y="35.0" width="181.0" height="71.0" rx="7" />
|
||||
<rect class="node-shape kind-driver emphasis-primary role-participant" data-evidence="3026-3028,3059-3059" x="45.0" y="35.0" width="181.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="135.5" y="62.0">virtio-balloon Driver</text>
|
||||
<line class="node-detail-divider" x1="59.0" y1="83.0" x2="212.0" y2="83.0" />
|
||||
<text class="node-detail" x="61.0" y="100.0">Guest Kernel</text>
|
||||
<line class="lifeline" x1="135.5" y1="106.0" x2="135.5" y2="512.0" />
|
||||
<rect class="node-shape kind-queue emphasis-normal role-participant" data-evidence="3017-3017" x="255.0" y="35.0" width="150.0" height="64.0" rx="7" />
|
||||
<rect class="node-shape kind-queue emphasis-normal role-participant" data-evidence="3030-3030" x="255.0" y="35.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="330.0" y="65.0">virtqueue</text>
|
||||
<line class="lifeline" x1="330.0" y1="99.0" x2="330.0" y2="512.0" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-participant" data-evidence="3022-3022,3037-3041" x="465.0" y="35.0" width="167.0" height="74.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-participant" data-evidence="3035-3035,3050-3054" x="465.0" y="35.0" width="167.0" height="74.0" rx="7" />
|
||||
<text class="node-label" x="548.5" y="62.0">QEMU virtio-balloon</text>
|
||||
<text class="node-label" x="548.5" y="80.0">Device</text>
|
||||
<line class="lifeline" x1="548.5" y1="109.0" x2="548.5" y2="512.0" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-participant" data-evidence="3025-3025,3034-3037" x="675.0" y="35.0" width="150.0" height="74.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-participant" data-evidence="3038-3038,3047-3050" x="675.0" y="35.0" width="150.0" height="74.0" rx="7" />
|
||||
<text class="node-label" x="750.0" y="62.0">Host Memory</text>
|
||||
<text class="node-label" x="750.0" y="80.0">Management</text>
|
||||
<line class="lifeline" x1="750.0" y1="109.0" x2="750.0" y2="512.0" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="750.0,140.0 548.5,140.0" data-evidence="3034-3041" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="750.0,140.0 548.5,140.0" data-evidence="3047-3054" />
|
||||
<rect class="edge-label-bg" x="573.2" y="114.0" width="152.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="649.2" y="129.0">1. Balloon target 조정</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="548.5,202.0 330.0,202.0" data-evidence="3017-3022,3041-3046" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="548.5,202.0 330.0,202.0" data-evidence="3030-3035,3054-3059" />
|
||||
<rect class="edge-label-bg" x="383.4" y="176.0" width="111.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="439.2" y="191.0">2. VM Boundary</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="330.0,264.0 135.5,264.0" data-evidence="3013-3017,3043-3046" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="330.0,264.0 135.5,264.0" data-evidence="3026-3030,3056-3059" />
|
||||
<rect class="edge-label-bg" x="166.8" y="238.0" width="131.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="232.8" y="253.0">3. Balloon target</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="135.5,326.0 330.0,326.0" data-evidence="3046-3050" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="135.5,326.0 330.0,326.0" data-evidence="3059-3063" />
|
||||
<rect class="edge-label-bg" x="166.8" y="300.0" width="131.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="232.8" y="315.0">4. Guest pages 확보</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="330.0,388.0 548.5,388.0" data-evidence="3017-3025" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="330.0,388.0 548.5,388.0" data-evidence="3030-3038" />
|
||||
<rect class="edge-label-bg" x="383.4" y="362.0" width="111.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="439.2" y="377.0">5. VM Boundary</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="548.5,450.0 750.0,450.0" data-evidence="3022-3028,3077-3079" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="548.5,450.0 750.0,450.0" data-evidence="3035-3041,3090-3092" />
|
||||
<rect class="edge-label-bg" x="586.6" y="424.0" width="125.2" height="22" rx="3" />
|
||||
<text class="edge-label" x="649.2" y="439.0">6. 회수 가능 backing</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
@@ -10,16 +10,16 @@ Guest 에서 VM Exit 으로 KVM 에 닿은 뒤 커널 처리와 QEMU 처리 두
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **Guest** (service): VM Exit 이 나기 직전까지 실행 중이던 Guest. Evidence: L498–L501.
|
||||
- **KVM** (service): VM Exit 을 받아 Exit Reason 을 확인하고 갈래를 고르는 자리. Evidence: L495–L495, L502–L504.
|
||||
- **KVM 커널 처리** (service): 커널 안에서 끝낼 수 있는 Exit 을 처리하는 갈래. QEMU 까지 올라가지 않는다. Evidence: L508–L510, L531–L531.
|
||||
- **QEMU** (service): userspace 처리가 필요한 Exit 에서만 개입하는 갈래. Evidence: L510–L516, L533–L533.
|
||||
- **Guest 실행 재개** (service): 두 갈래가 다시 만나는 자리. VM Exit 은 VM 종료가 아니라 여기로 돌아온다. Evidence: L521–L524, L529–L529.
|
||||
- **Guest** (service): VM Exit 이 나기 직전까지 실행 중이던 Guest. Evidence: L511–L514.
|
||||
- **KVM** (service): VM Exit 을 받아 Exit Reason 을 확인하고 갈래를 고르는 자리. Evidence: L508–L508, L515–L517.
|
||||
- **KVM 커널 처리** (service): 커널 안에서 끝낼 수 있는 Exit 을 처리하는 갈래. QEMU 까지 올라가지 않는다. Evidence: L521–L523, L544–L544.
|
||||
- **QEMU** (service): userspace 처리가 필요한 Exit 에서만 개입하는 갈래. Evidence: L523–L529, L546–L546.
|
||||
- **Guest 실행 재개** (service): 두 갈래가 다시 만나는 자리. VM Exit 은 VM 종료가 아니라 여기로 돌아온다. Evidence: L534–L537, L542–L542.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **Guest → KVM:** VM Exit. Evidence: L495–L495, L498–L502.
|
||||
- **KVM → KVM 커널 처리:** 커널 처리 가능. Evidence: L504–L510, L531–L531.
|
||||
- **KVM 커널 처리 → Guest 실행 재개:** VM Entry. Evidence: L518–L524, L531–L531.
|
||||
- **KVM → QEMU:** KVM_RUN return. Evidence: L508–L512, L533–L533.
|
||||
- **QEMU → Guest 실행 재개:** VM Entry. Evidence: L514–L524, L533–L533.
|
||||
- **Guest → KVM:** VM Exit. Evidence: L508–L508, L511–L515.
|
||||
- **KVM → KVM 커널 처리:** 커널 처리 가능. Evidence: L517–L523, L544–L544.
|
||||
- **KVM 커널 처리 → Guest 실행 재개:** VM Entry. Evidence: L531–L537, L544–L544.
|
||||
- **KVM → QEMU:** KVM_RUN return. Evidence: L521–L525, L546–L546.
|
||||
- **QEMU → Guest 실행 재개:** VM Entry. Evidence: L527–L537, L546–L546.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="Guest", shape=box, style="rounded,filled"];
|
||||
n1 [label="KVM", shape=box, style="rounded,filled"];
|
||||
n2 [label="KVM 커널 처리", shape=box, style="rounded,filled"];
|
||||
n3 [label="QEMU", shape=box, style="rounded,filled"];
|
||||
n4 [label="Guest 실행 재개", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="VM Exit", style=solid];
|
||||
n1 -> n2 [label="커널 처리 가능", style=solid];
|
||||
n1 -> n3 [label="KVM_RUN return", style=solid];
|
||||
n2 -> n4 [label="VM Entry", style=solid];
|
||||
n3 -> n4 [label="VM Entry", style=solid];
|
||||
}
|
||||
@@ -5,19 +5,19 @@
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_guest" value="Guest" tooltip="VM Exit 이 나기 직전까지 실행 중이던 Guest. | Evidence: L498-L501" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_guest" value="Guest" tooltip="VM Exit 이 나기 직전까지 실행 중이던 Guest. | Evidence: L511-L514" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="152.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_kvm" value="KVM<br/>Exit Reason" tooltip="VM Exit 을 받아 Exit Reason 을 확인하고 갈래를 고르는 자리. | Evidence: L495-L495, L502-L504" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxCell id="n_kvm" value="KVM<br/>Exit Reason" tooltip="VM Exit 을 받아 Exit Reason 을 확인하고 갈래를 고르는 자리. | Evidence: L508-L508, L515-L517" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="380.0" y="148.5" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_kvm-kernel-handling" value="KVM 커널 처리<br/>Kernel" tooltip="커널 안에서 끝낼 수 있는 Exit 을 처리하는 갈래. QEMU 까지 올라가지 않는다. | Evidence: L508-L510, L531-L531" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_kvm-kernel-handling" value="KVM 커널 처리<br/>Kernel" tooltip="커널 안에서 끝낼 수 있는 Exit 을 처리하는 갈래. QEMU 까지 올라가지 않는다. | Evidence: L521-L523, L544-L544" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="690.0" y="60.0" width="150.0" height="71.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_qemu" value="QEMU<br/>Userspace<br/>device emulation<br/>KVM_RUN 재호출" tooltip="userspace 처리가 필요한 Exit 에서만 개입하는 갈래. | Evidence: L510-L516, L533-L533" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_qemu" value="QEMU<br/>Userspace<br/>device emulation<br/>KVM_RUN 재호출" tooltip="userspace 처리가 필요한 Exit 에서만 개입하는 갈래. | Evidence: L523-L529, L546-L546" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="690.0" y="203.0" width="150.0" height="105.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_guest-resume" value="Guest 실행 재개" tooltip="두 갈래가 다시 만나는 자리. VM Exit 은 VM 종료가 아니라 여기로 돌아온다. | Evidence: L521-L524, L529-L529" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_guest-resume" value="Guest 실행 재개" tooltip="두 갈래가 다시 만나는 자리. VM Exit 은 VM 종료가 아니라 여기로 돌아온다. | Evidence: L534-L537, L542-L542" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="1000.0" y="152.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_exit-to-kvm" value="VM Exit" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest" target="n_kvm">
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "vm-exit-handling-cycle",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "114180c059ff8c4be3e253da16d2d2f0e0fb44a2b87b03fcd2104f4e3fd6fa79",
|
||||
"spec_sha256": "252e1217d5faf4d4dcbf10ccc3820cbc954a7f43a9c4936d9a6773742ce7751d",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "9. VM Exit 이후 처리",
|
||||
"line": 493
|
||||
"line": 506
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"vm-exit-handling-cycle.svg",
|
||||
"vm-exit-handling-cycle.drawio",
|
||||
"vm-exit-handling-cycle.mmd",
|
||||
"vm-exit-handling-cycle.d2",
|
||||
"vm-exit-handling-cycle.dot",
|
||||
"vm-exit-handling-cycle.drawio",
|
||||
"vm-exit-handling-cycle.excalidraw",
|
||||
"vm-exit-handling-cycle.alt.md"
|
||||
],
|
||||
@@ -27,5 +28,15 @@
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "e19ad5e4f10b63dcc8873b89824d7325d4e7d00da148111debc3982dde326ee4",
|
||||
"output_sha256": {
|
||||
"vm-exit-handling-cycle.svg": "ee31021001ee6c5ca4a7b6d7aef68fc22f985ed0ef043d77e4f1e729c88879e1",
|
||||
"vm-exit-handling-cycle.mmd": "7ae0eea6854928cf6485483ed2f477293d8674f880e55400c1b49aed2267448e",
|
||||
"vm-exit-handling-cycle.d2": "ea19922bd0d4227c52959c504544cd38bb9fc812b6074610b304bf1275249c4f",
|
||||
"vm-exit-handling-cycle.dot": "66ab3013183f0a8cb835e485765cc3b338f80fc90854c4c00d03cd721768f470",
|
||||
"vm-exit-handling-cycle.drawio": "bcddde755cb94de69b7ff6b9a6c58abcfe83439b941136f34b181b18a65cc737",
|
||||
"vm-exit-handling-cycle.excalidraw": "e9f0e13cb801c4fa1872dfb102a377372940306569a97730ad9cdd6d4efcdbe8",
|
||||
"vm-exit-handling-cycle.alt.md": "a74241dbbba9e86b671f6cd6163d1a159de7815c66ad0bb01787d75568f4c5b3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1195" height="353" viewBox="0 0 1195 353" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">VM Exit 은 KVM 에서 끝나기도 하고 QEMU userspace 까지 가기도 한다</title>
|
||||
<desc id="diagram-description">왼쪽에서 오른쪽으로 읽는다. 왼쪽 끝에 Guest 가 있고 VM Exit 이 KVM 으로 제어권을 넘긴다. KVM 은 Exit Reason 을 확인해 두 갈래 중 하나를 고른다. 커널 안에서 처리할 수 있는 Exit 은 Kernel 쪽 KVM 커널 처리로 가고, userspace 처리가 필요한 Exit 만 KVM_RUN 이 반환되면서 Userspace 쪽 QEMU 로 간다. QEMU 는 필요한 장치 동작을 처리한 뒤 KVM_RUN 을 다시 호출한다. 두 갈래는 오른쪽 끝에서 다시 만나며 어느 쪽이든 VM Entry 를 지나 Guest 실행 재개로 돌아온다. 무엇이 Exit 을 부르는지와 Exit 이 잦을 때 무엇을 함께 보는지는 본문의 표와 문단이 맡는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"vm-exit-handling-cycle","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"9. VM Exit 이후 처리","line":493}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"vm-exit-handling-cycle","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"9. VM Exit 이후 처리","line":506}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -50,39 +50,39 @@
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="1195" height="353" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="220.0,184.0 300.0,184.0 300.0,184.0 380.0,184.0" data-evidence="495-495,498-502" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="220.0,184.0 300.0,184.0 300.0,184.0 380.0,184.0" data-evidence="508-508,511-515" />
|
||||
<rect class="edge-label-bg" x="267.6" y="142.0" width="64.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="300.0" y="157.0">VM Exit</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="530.0,175.0 610.0,175.0 610.0,95.5 690.0,95.5" data-evidence="504-510,531-531" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="530.0,175.0 610.0,175.0 610.0,95.5 690.0,95.5" data-evidence="517-523,544-544" />
|
||||
<rect class="edge-label-bg" x="598.2" y="121.2" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="634.0" y="136.2">커널 처리 가능</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="840.0,95.5 920.0,95.5 920.0,175.0 1000.0,175.0" data-evidence="518-524,531-531" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="840.0,95.5 920.0,95.5 920.0,175.0 1000.0,175.0" data-evidence="531-537,544-544" />
|
||||
<rect class="edge-label-bg" x="908.2" y="121.2" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="944.0" y="136.2">VM Entry</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="530.0,193.0 610.0,193.0 610.0,255.5 690.0,255.5" data-evidence="508-512,533-533" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="530.0,193.0 610.0,193.0 610.0,255.5 690.0,255.5" data-evidence="521-525,546-546" />
|
||||
<rect class="edge-label-bg" x="578.1" y="210.2" width="111.8" height="22" rx="3" />
|
||||
<text class="edge-label" x="634.0" y="225.2">KVM_RUN return</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="840.0,255.5 920.0,255.5 920.0,193.0 1000.0,193.0" data-evidence="514-524,533-533" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="840.0,255.5 920.0,255.5 920.0,193.0 1000.0,193.0" data-evidence="527-537,546-546" />
|
||||
<rect class="edge-label-bg" x="908.2" y="210.2" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="944.0" y="225.2">VM Entry</text>
|
||||
<g id="node-guest">
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="498-501" x="70.0" y="152.0" width="150.0" height="64.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="511-514" x="70.0" y="152.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="182.0">Guest</text>
|
||||
</g>
|
||||
<g id="node-kvm">
|
||||
<rect class="node-shape kind-service emphasis-primary role-service" data-evidence="495-495,502-504" x="380.0" y="148.5" width="150.0" height="71.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-primary role-service" data-evidence="508-508,515-517" x="380.0" y="148.5" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="455.0" y="175.5">KVM</text>
|
||||
<line class="node-detail-divider" x1="394.0" y1="196.5" x2="516.0" y2="196.5" />
|
||||
<text class="node-detail" x="396.0" y="213.5">Exit Reason</text>
|
||||
</g>
|
||||
<g id="node-kvm-kernel-handling">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="508-510,531-531" x="690.0" y="60.0" width="150.0" height="71.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="521-523,544-544" x="690.0" y="60.0" width="150.0" height="71.0" rx="7" />
|
||||
<text class="node-label" x="765.0" y="87.0">KVM 커널 처리</text>
|
||||
<line class="node-detail-divider" x1="704.0" y1="108.0" x2="826.0" y2="108.0" />
|
||||
<text class="node-detail" x="706.0" y="125.0">Kernel</text>
|
||||
</g>
|
||||
<g id="node-qemu">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="510-516,533-533" x="690.0" y="203.0" width="150.0" height="105.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="523-529,546-546" x="690.0" y="203.0" width="150.0" height="105.0" rx="7" />
|
||||
<text class="node-label" x="765.0" y="230.0">QEMU</text>
|
||||
<line class="node-detail-divider" x1="704.0" y1="251.0" x2="826.0" y2="251.0" />
|
||||
<text class="node-detail" x="706.0" y="268.0">Userspace</text>
|
||||
@@ -90,7 +90,7 @@
|
||||
<text class="node-detail" x="706.0" y="300.0">KVM_RUN 재호출</text>
|
||||
</g>
|
||||
<g id="node-guest-resume">
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="521-524,529-529" x="1000.0" y="152.0" width="150.0" height="64.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="534-537,542-542" x="1000.0" y="152.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="1075.0" y="182.0">Guest 실행 재개</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
@@ -10,17 +10,17 @@ VM1 QEMU, VM2 QEMU, Nginx, Host 기타 네 곳에서 나온 화살표가 하나
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **VM1 QEMU** (service): 가상 머신 하나의 QEMU 프로세스. 게스트의 I/O 가 여기서 호스트 파일 I/O 가 된다. Evidence: L7029–L7029, L7041–L7044.
|
||||
- **VM2 QEMU** (service): 다른 가상 머신의 QEMU 프로세스. Evidence: L7031–L7031, L7046–L7048.
|
||||
- **Nginx** (service): 호스트에서 직접 도는 프로세스. Evidence: L7033–L7033.
|
||||
- **Host 기타** (service): 그 밖의 호스트 프로세스. Evidence: L7035–L7038.
|
||||
- **Host Block Layer** (service): 어디서 왔는지 구분하지 않고 모두 Host block request 로 다루는 계층. queue 에서 관리해 device 로 내보낸다. Evidence: L7031–L7031, L7017–L7022, L7054–L7054, L7058–L7060.
|
||||
- **NVMe** (device): 네 갈래가 결국 함께 쓰는 하나의 물리 device. Evidence: L7031–L7031, L7019–L7019, L7066–L7069.
|
||||
- **VM1 QEMU** (service): 가상 머신 하나의 QEMU 프로세스. 게스트의 I/O 가 여기서 호스트 파일 I/O 가 된다. Evidence: L7042–L7042, L7054–L7057.
|
||||
- **VM2 QEMU** (service): 다른 가상 머신의 QEMU 프로세스. Evidence: L7044–L7044, L7059–L7061.
|
||||
- **Nginx** (service): 호스트에서 직접 도는 프로세스. Evidence: L7046–L7046.
|
||||
- **Host 기타** (service): 그 밖의 호스트 프로세스. Evidence: L7048–L7051.
|
||||
- **Host Block Layer** (service): 어디서 왔는지 구분하지 않고 모두 Host block request 로 다루는 계층. queue 에서 관리해 device 로 내보낸다. Evidence: L7044–L7044, L7030–L7035, L7067–L7067, L7071–L7073.
|
||||
- **NVMe** (device): 네 갈래가 결국 함께 쓰는 하나의 물리 device. Evidence: L7044–L7044, L7032–L7032, L7079–L7082.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **VM1 QEMU → Host Block Layer:** data. Evidence: L7029–L7031.
|
||||
- **VM2 QEMU → Host Block Layer:** data. Evidence: L7031–L7031.
|
||||
- **Nginx → Host Block Layer:** data. Evidence: L7031–L7033.
|
||||
- **Host 기타 → Host Block Layer:** data. Evidence: L7031–L7035.
|
||||
- **Host Block Layer → NVMe:** dispatch. Evidence: L7031–L7031, L7054–L7054.
|
||||
- **VM1 QEMU → Host Block Layer:** data. Evidence: L7042–L7044.
|
||||
- **VM2 QEMU → Host Block Layer:** data. Evidence: L7044–L7044.
|
||||
- **Nginx → Host Block Layer:** data. Evidence: L7044–L7046.
|
||||
- **Host 기타 → Host Block Layer:** data. Evidence: L7044–L7048.
|
||||
- **Host Block Layer → NVMe:** dispatch. Evidence: L7044–L7044, L7067–L7067.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 가상 머신 둘과 호스트 프로세스가 하나의 NVMe 로 모인다
|
||||
# Question: 서로 다른 곳에서 시작한 I/O 는 어디에서 하나로 모여 device 로 나가는가
|
||||
direction: down
|
||||
direction: right
|
||||
n0: "VM1 QEMU" {
|
||||
shape: rectangle
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="VM1 QEMU", shape=box, style="rounded,filled"];
|
||||
n1 [label="VM2 QEMU", shape=box, style="rounded,filled"];
|
||||
n2 [label="Nginx", shape=box, style="rounded,filled"];
|
||||
n3 [label="Host 기타", shape=box, style="rounded,filled"];
|
||||
n4 [label="Host Block Layer", shape=box, style="rounded,filled"];
|
||||
n5 [label="NVMe", shape=box, style="rounded,filled"];
|
||||
n0 -> n4 [label="", style=solid];
|
||||
n1 -> n4 [label="", style=solid];
|
||||
n2 -> n4 [label="", style=solid];
|
||||
n3 -> n4 [label="", style=solid];
|
||||
n4 -> n5 [label="dispatch", style=solid];
|
||||
}
|
||||
@@ -1,51 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="vms-sharing-one-nvme" name="가상 머신 둘과 호스트 프로세스가 하나의 NVMe 로 모인다">
|
||||
<mxGraphModel dx="895" dy="580" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="895" pageHeight="1169" math="0" shadow="0">
|
||||
<mxGraphModel dx="895" dy="642" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="895" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_vm1-qemu" value="VM1 QEMU<br/>WRITE X<br/>READ Y<br/>WRITE Z" tooltip="가상 머신 하나의 QEMU 프로세스. 게스트의 I/O 가 여기서 호스트 파일 I/O 가 된다. | Evidence: L7029-L7029, L7041-L7044" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_vm1-qemu" value="VM1 QEMU<br/>WRITE X<br/>READ Y<br/>WRITE Z" tooltip="가상 머신 하나의 QEMU 프로세스. 게스트의 I/O 가 여기서 호스트 파일 I/O 가 된다. | Evidence: L7042-L7042, L7054-L7057" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="60.0" width="150.0" height="105.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_vm2-qemu" value="VM2 QEMU<br/>READ A<br/>WRITE B" tooltip="다른 가상 머신의 QEMU 프로세스. | Evidence: L7031-L7031, L7046-L7048" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="280.0" y="68.5" width="150.0" height="88.0" as="geometry"/>
|
||||
<mxCell id="n_vm2-qemu" value="VM2 QEMU<br/>READ A<br/>WRITE B" tooltip="다른 가상 머신의 QEMU 프로세스. | Evidence: L7044-L7044, L7059-L7061" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="237.0" width="150.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_nginx" value="Nginx" tooltip="호스트에서 직접 도는 프로세스. | Evidence: L7033-L7033" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="490.0" y="80.5" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_nginx" value="Nginx" tooltip="호스트에서 직접 도는 프로세스. | Evidence: L7046-L7046" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="397.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_host-other" value="Host 기타" tooltip="그 밖의 호스트 프로세스. | Evidence: L7035-L7038" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="700.0" y="80.5" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_host-other" value="Host 기타" tooltip="그 밖의 호스트 프로세스. | Evidence: L7048-L7051" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="533.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_host-block-layer" value="Host Block Layer<br/>Host block request<br/>blk-mq" tooltip="어디서 왔는지 구분하지 않고 모두 Host block request 로 다루는 계층. queue 에서 관리해 device 로 내보낸다. | Evidence: L7031-L7031, L7017-L7022, L7054-L7054, L7058-L7060" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="380.0" y="261.0" width="160.0" height="88.0" as="geometry"/>
|
||||
<mxCell id="n_host-block-layer" value="Host Block Layer<br/>Host block request<br/>blk-mq" tooltip="어디서 왔는지 구분하지 않고 모두 Host block request 로 다루는 계층. queue 에서 관리해 device 로 내보낸다. | Evidence: L7044-L7044, L7030-L7035, L7067-L7067, L7071-L7073" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="380.0" y="284.5" width="160.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_nvme" value="NVMe" tooltip="네 갈래가 결국 함께 쓰는 하나의 물리 device. | Evidence: L7031-L7031, L7019-L7019, L7066-L7069" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="385.0" y="445.0" width="150.0" height="90.0" as="geometry"/>
|
||||
<mxCell id="n_nvme" value="NVMe" tooltip="네 갈래가 결국 함께 쓰는 하나의 물리 device. | Evidence: L7044-L7044, L7032-L7032, L7079-L7082" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=cylinder3;boundedLbl=1;backgroundOutline=1;fillColor=#eef6fb;" vertex="1" parent="1">
|
||||
<mxGeometry x="700.0" y="296.5" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_vm1-to-block-layer" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_vm1-qemu" target="n_host-block-layer">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="289.0" y="185.0" as="offset"/>
|
||||
<mxPoint x="324.0" y="207.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_vm2-to-block-layer" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_vm2-qemu" target="n_host-block-layer">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="403.0" y="180.8" as="offset"/>
|
||||
<mxPoint x="324.0" y="300.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_nginx-to-block-layer" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_nginx" target="n_host-block-layer">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="517.0" y="174.8" as="offset"/>
|
||||
<mxPoint x="324.0" y="383.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_host-other-to-block-layer" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-other" target="n_host-block-layer">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="631.0" y="174.8" as="offset"/>
|
||||
<mxPoint x="324.0" y="460.2" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_block-layer-to-nvme" value="dispatch" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-block-layer" target="n_nvme">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="484.0" y="397.0" as="offset"/>
|
||||
<mxPoint x="620.0" y="300.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
{
|
||||
"id": "edge-vm1-to-block-layer",
|
||||
"type": "arrow",
|
||||
"x": 145.0,
|
||||
"y": 165.0,
|
||||
"width": 288.0,
|
||||
"height": 96.0,
|
||||
"x": 220.0,
|
||||
"y": 112.5,
|
||||
"width": 160.0,
|
||||
"height": 189.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -36,16 +36,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
288.0,
|
||||
48.0
|
||||
80.0,
|
||||
189.0
|
||||
],
|
||||
[
|
||||
288.0,
|
||||
96.0
|
||||
160.0,
|
||||
189.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -66,10 +66,10 @@
|
||||
{
|
||||
"id": "edge-vm2-to-block-layer",
|
||||
"type": "arrow",
|
||||
"x": 355.0,
|
||||
"y": 156.5,
|
||||
"width": 96.0,
|
||||
"height": 104.5,
|
||||
"x": 220.0,
|
||||
"y": 281.0,
|
||||
"width": 160.0,
|
||||
"height": 38.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -96,16 +96,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
52.25
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
96.0,
|
||||
52.25
|
||||
80.0,
|
||||
38.5
|
||||
],
|
||||
[
|
||||
96.0,
|
||||
104.5
|
||||
160.0,
|
||||
38.5
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -126,10 +126,10 @@
|
||||
{
|
||||
"id": "edge-nginx-to-block-layer",
|
||||
"type": "arrow",
|
||||
"x": 469.0,
|
||||
"y": 144.5,
|
||||
"width": 96.0,
|
||||
"height": 116.5,
|
||||
"x": 220.0,
|
||||
"y": 337.5,
|
||||
"width": 160.0,
|
||||
"height": 91.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -152,20 +152,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
96.0,
|
||||
0.0,
|
||||
91.5
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
91.5
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
96.0,
|
||||
58.25
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
58.25
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
116.5
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -186,10 +186,10 @@
|
||||
{
|
||||
"id": "edge-host-other-to-block-layer",
|
||||
"type": "arrow",
|
||||
"x": 487.0,
|
||||
"y": 144.5,
|
||||
"width": 288.0,
|
||||
"height": 116.5,
|
||||
"x": 220.0,
|
||||
"y": 355.5,
|
||||
"width": 160.0,
|
||||
"height": 209.5,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -212,20 +212,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
288.0,
|
||||
0.0,
|
||||
209.5
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
209.5
|
||||
],
|
||||
[
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
288.0,
|
||||
58.25
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
58.25
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
116.5
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -246,10 +246,10 @@
|
||||
{
|
||||
"id": "edge-block-layer-to-nvme",
|
||||
"type": "arrow",
|
||||
"x": 460.0,
|
||||
"y": 349.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 540.0,
|
||||
"y": 328.5,
|
||||
"width": 160.0,
|
||||
"height": 0.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -276,16 +276,16 @@
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
80.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
160.0,
|
||||
0.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -306,8 +306,8 @@
|
||||
{
|
||||
"id": "edge-label-block-layer-to-nvme",
|
||||
"type": "text",
|
||||
"x": 439.0,
|
||||
"y": 385.0,
|
||||
"x": 575.0,
|
||||
"y": 288.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -414,8 +414,8 @@
|
||||
{
|
||||
"id": "node-vm2-qemu",
|
||||
"type": "rectangle",
|
||||
"x": 280.0,
|
||||
"y": 68.5,
|
||||
"x": 70.0,
|
||||
"y": 237.0,
|
||||
"width": 150.0,
|
||||
"height": 88.0,
|
||||
"angle": 0,
|
||||
@@ -444,8 +444,8 @@
|
||||
{
|
||||
"id": "node-label-vm2-qemu",
|
||||
"type": "text",
|
||||
"x": 290.0,
|
||||
"y": 78.5,
|
||||
"x": 80.0,
|
||||
"y": 247.0,
|
||||
"width": 130.0,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
@@ -483,8 +483,8 @@
|
||||
{
|
||||
"id": "node-nginx",
|
||||
"type": "rectangle",
|
||||
"x": 490.0,
|
||||
"y": 80.5,
|
||||
"x": 70.0,
|
||||
"y": 397.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -513,8 +513,8 @@
|
||||
{
|
||||
"id": "node-label-nginx",
|
||||
"type": "text",
|
||||
"x": 500.0,
|
||||
"y": 90.5,
|
||||
"x": 80.0,
|
||||
"y": 407.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -552,8 +552,8 @@
|
||||
{
|
||||
"id": "node-host-other",
|
||||
"type": "rectangle",
|
||||
"x": 700.0,
|
||||
"y": 80.5,
|
||||
"x": 70.0,
|
||||
"y": 533.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -582,8 +582,8 @@
|
||||
{
|
||||
"id": "node-label-host-other",
|
||||
"type": "text",
|
||||
"x": 710.0,
|
||||
"y": 90.5,
|
||||
"x": 80.0,
|
||||
"y": 543.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -622,7 +622,7 @@
|
||||
"id": "node-host-block-layer",
|
||||
"type": "rectangle",
|
||||
"x": 380.0,
|
||||
"y": 261.0,
|
||||
"y": 284.5,
|
||||
"width": 160.0,
|
||||
"height": 88.0,
|
||||
"angle": 0,
|
||||
@@ -652,7 +652,7 @@
|
||||
"id": "node-label-host-block-layer",
|
||||
"type": "text",
|
||||
"x": 390.0,
|
||||
"y": 271.0,
|
||||
"y": 294.5,
|
||||
"width": 140.0,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
@@ -690,10 +690,10 @@
|
||||
{
|
||||
"id": "node-nvme",
|
||||
"type": "rectangle",
|
||||
"x": 385.0,
|
||||
"y": 445.0,
|
||||
"x": 700.0,
|
||||
"y": 296.5,
|
||||
"width": 150.0,
|
||||
"height": 90.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "#ffffff",
|
||||
@@ -720,10 +720,10 @@
|
||||
{
|
||||
"id": "node-label-nvme",
|
||||
"type": "text",
|
||||
"x": 395.0,
|
||||
"y": 455.0,
|
||||
"x": 710.0,
|
||||
"y": 306.5,
|
||||
"width": 130.0,
|
||||
"height": 70.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
|
||||
@@ -2,30 +2,41 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "vms-sharing-one-nvme",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "43a75d5863edb3e1585ebf97e76f7bd9bf773c90836d4f8f91936eb8a557bd28",
|
||||
"spec_sha256": "6812a95ed58705ecd051637940be6fa063ab59e3e383ab7178eb02f65911df2b",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "159. 여러 VM이 하나의 NVMe를 공유하면",
|
||||
"line": 7026
|
||||
"line": 7039
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"vms-sharing-one-nvme.svg",
|
||||
"vms-sharing-one-nvme.drawio",
|
||||
"vms-sharing-one-nvme.mmd",
|
||||
"vms-sharing-one-nvme.d2",
|
||||
"vms-sharing-one-nvme.dot",
|
||||
"vms-sharing-one-nvme.drawio",
|
||||
"vms-sharing-one-nvme.excalidraw",
|
||||
"vms-sharing-one-nvme.alt.md"
|
||||
],
|
||||
"lint_issue_count": 5,
|
||||
"lint_issue_count": 6,
|
||||
"assumption_count": 0,
|
||||
"assumptions_allowed": false,
|
||||
"composition_profile": "component-flow",
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "097931ac2fcf015484bea63eb103ff71903eebf82ab1f0e75dbfcdf03e5f3b6c",
|
||||
"output_sha256": {
|
||||
"vms-sharing-one-nvme.svg": "e9e9d9d5ae1b52963b7c1f2da7ec26469e9aa2151359dbd155c7723f3d3e6f7e",
|
||||
"vms-sharing-one-nvme.mmd": "4a5feab7ba90b3abe5b789ae8b2e94a40bdc93550e3bdb8688aff6b25f4f129d",
|
||||
"vms-sharing-one-nvme.d2": "a60e12df711a410c4396d9b83910da472c74f96fc95f7f89e2ccbfbb6cc7a206",
|
||||
"vms-sharing-one-nvme.dot": "9e731563bc8008ab4429da8d153f42d1da54ed8f04a87fae3c0dd4794e9ef1ea",
|
||||
"vms-sharing-one-nvme.drawio": "51d7776fb874bcb205782d46167aef73698c59a12c6f578f6154e9112b27517c",
|
||||
"vms-sharing-one-nvme.excalidraw": "c6200d7585ab24fecaf0ed04dca372e93467b1383dbaec03f8c053d520f8d83a",
|
||||
"vms-sharing-one-nvme.alt.md": "e002e3dae78d86266d8ef4c9f572ba225386643c74221fb1cc0665267a9e374e"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%% 가상 머신 둘과 호스트 프로세스가 하나의 NVMe 로 모인다
|
||||
%% question: 서로 다른 곳에서 시작한 I/O 는 어디에서 하나로 모여 device 로 나가는가
|
||||
flowchart TB
|
||||
flowchart LR
|
||||
n0["VM1 QEMU"]
|
||||
n1["VM2 QEMU"]
|
||||
n2["Nginx"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="895" height="580" viewBox="0 0 895 580" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="895" height="642" viewBox="0 0 895 642" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">가상 머신 둘과 호스트 프로세스가 하나의 NVMe 로 모인다</title>
|
||||
<desc id="diagram-description">위쪽에 네 출발점이 나란히 있다. VM1 QEMU 는 WRITE X 와 READ Y, WRITE Z 를 내고 VM2 QEMU 는 READ A 와 WRITE B 를 내며, 그 옆에 호스트의 Nginx 와 다른 프로세스가 있다. 네 갈래가 모두 가운데의 Host Block Layer 하나로 모인다. Host Block Layer 는 그 I/O 가 가상 머신 안에서 시작했는지 호스트 프로세스에서 시작했는지를 본질적으로 구분해 처리하는 계층이 아니라 들어온 것을 모두 Host block request 로 다루고, 그 요청들을 queue 에서 관리해 맨 아래 NVMe 로 dispatch 한다. 여기서 생기는 경쟁이 Storage Contention 이고 CPU 실행 시간을 두고 벌어지는 CPU Contention 과는 다투는 자원이 다르다는 것은 본문 문단이 맡는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"vms-sharing-one-nvme","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"159. 여러 VM이 하나의 NVMe를 공유하면","line":7026}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"vms-sharing-one-nvme","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"159. 여러 VM이 하나의 NVMe를 공유하면","line":7039}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -49,16 +49,16 @@
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="895" height="580" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="145.0,165.0 145.0,213.0 433.0,213.0 433.0,261.0" data-evidence="7029-7031" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="355.0,156.5 355.0,208.8 451.0,208.8 451.0,261.0" data-evidence="7031-7031" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="565.0,144.5 565.0,202.8 469.0,202.8 469.0,261.0" data-evidence="7031-7033" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="775.0,144.5 775.0,202.8 487.0,202.8 487.0,261.0" data-evidence="7031-7035" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="460.0,349.0 460.0,397.0 460.0,397.0 460.0,445.0" data-evidence="7031-7031,7054-7054" />
|
||||
<rect class="edge-label-bg" x="448.2" y="383.0" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="484.0" y="398.0">dispatch</text>
|
||||
<rect class="canvas" width="895" height="642" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="220.0,112.5 300.0,112.5 300.0,301.5 380.0,301.5" data-evidence="7042-7044" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="220.0,281.0 300.0,281.0 300.0,319.5 380.0,319.5" data-evidence="7044-7044" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="220.0,429.0 300.0,429.0 300.0,337.5 380.0,337.5" data-evidence="7044-7046" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="220.0,565.0 300.0,565.0 300.0,355.5 380.0,355.5" data-evidence="7044-7048" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="540.0,328.5 620.0,328.5 620.0,328.5 700.0,328.5" data-evidence="7044-7044,7067-7067" />
|
||||
<rect class="edge-label-bg" x="584.2" y="286.5" width="71.6" height="22" rx="3" />
|
||||
<text class="edge-label" x="620.0" y="301.5">dispatch</text>
|
||||
<g id="node-vm1-qemu">
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="7029-7029,7041-7044" x="70.0" y="60.0" width="150.0" height="105.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="7042-7042,7054-7057" x="70.0" y="60.0" width="150.0" height="105.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="87.0">VM1 QEMU</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="108.0" x2="206.0" y2="108.0" />
|
||||
<text class="node-detail" x="86.0" y="125.0">WRITE X</text>
|
||||
@@ -66,29 +66,29 @@
|
||||
<text class="node-detail" x="86.0" y="157.0">WRITE Z</text>
|
||||
</g>
|
||||
<g id="node-vm2-qemu">
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="7031-7031,7046-7048" x="280.0" y="68.5" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="355.0" y="95.5">VM2 QEMU</text>
|
||||
<line class="node-detail-divider" x1="294.0" y1="116.5" x2="416.0" y2="116.5" />
|
||||
<text class="node-detail" x="296.0" y="133.5">READ A</text>
|
||||
<text class="node-detail" x="296.0" y="149.5">WRITE B</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="7044-7044,7059-7061" x="70.0" y="237.0" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="264.0">VM2 QEMU</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="285.0" x2="206.0" y2="285.0" />
|
||||
<text class="node-detail" x="86.0" y="302.0">READ A</text>
|
||||
<text class="node-detail" x="86.0" y="318.0">WRITE B</text>
|
||||
</g>
|
||||
<g id="node-nginx">
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="7033-7033" x="490.0" y="80.5" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="565.0" y="110.5">Nginx</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="7046-7046" x="70.0" y="397.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="427.0">Nginx</text>
|
||||
</g>
|
||||
<g id="node-host-other">
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="7035-7038" x="700.0" y="80.5" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="775.0" y="110.5">Host 기타</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="7048-7051" x="70.0" y="533.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="563.0">Host 기타</text>
|
||||
</g>
|
||||
<g id="node-host-block-layer">
|
||||
<rect class="node-shape kind-service emphasis-primary role-queue" data-evidence="7031-7031,7017-7022,7054-7054,7058-7060" x="380.0" y="261.0" width="160.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="460.0" y="288.0">Host Block Layer</text>
|
||||
<line class="node-detail-divider" x1="394.0" y1="309.0" x2="526.0" y2="309.0" />
|
||||
<text class="node-detail" x="396.0" y="326.0">Host block request</text>
|
||||
<text class="node-detail" x="396.0" y="342.0">blk-mq</text>
|
||||
<rect class="node-shape kind-service emphasis-primary role-queue" data-evidence="7044-7044,7030-7035,7067-7067,7071-7073" x="380.0" y="284.5" width="160.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="460.0" y="311.5">Host Block Layer</text>
|
||||
<line class="node-detail-divider" x1="394.0" y1="332.5" x2="526.0" y2="332.5" />
|
||||
<text class="node-detail" x="396.0" y="349.5">Host block request</text>
|
||||
<text class="node-detail" x="396.0" y="365.5">blk-mq</text>
|
||||
</g>
|
||||
<g id="node-nvme">
|
||||
<rect class="node-shape kind-device emphasis-normal role-sink" data-evidence="7031-7031,7019-7019,7066-7069" x="385.0" y="458.0" width="150.0" height="64.0" /><ellipse class="node-shape kind-device emphasis-normal role-sink" cx="460.0" cy="458.0" rx="75.0" ry="13.0" /><path class="storage-bottom" d="M 385.0 522.0 A 75.0 13.0 0 0 0 535.0 522.0" />
|
||||
<text class="node-label" x="460.0" y="488.0">NVMe</text>
|
||||
<rect class="node-shape kind-device emphasis-normal role-sink" data-evidence="7044-7044,7032-7032,7079-7082" x="700.0" y="307.2" width="150.0" height="42.7" /><ellipse class="node-shape kind-device emphasis-normal role-sink" cx="775.0" cy="307.2" rx="75.0" ry="10.7" /><path class="storage-bottom" d="M 700.0 349.8 A 75.0 10.7 0 0 0 850.0 349.8" />
|
||||
<text class="node-label" x="775.0" y="326.5">NVMe</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
@@ -10,19 +10,19 @@ PostgreSQL 의 fsync() 가 Guest Filesystem, Guest Block Layer, virtio-blk, QEMU
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **PostgreSQL** (service): 필요한 시점에 fsync() 를 불러 영속성 경계까지 반영을 요청하는 게스트 프로세스. Evidence: L6742–L6742, L6726–L6734.
|
||||
- **Guest Filesystem** (service): fsync() 요구를 처음 받는 게스트 파일시스템. Evidence: L6746–L6746.
|
||||
- **Guest Block Layer** (service): 요구를 FLUSH 등의 block 요청으로 바꾸는 계층. Evidence: L6749–L6751.
|
||||
- **virtio-blk** (service): 그 요청을 VM 경계 너머로 옮기는 게스트 driver. Evidence: L6753–L6753.
|
||||
- **QEMU / Backend** (service): 요청을 받아 호스트 쪽 파일 I/O 나 block I/O 로 잇는 자리. Evidence: L6756–L6756, L6686–L6686.
|
||||
- **Host Storage Stack** (service): 호스트 Page Cache 와 파일시스템, Block Layer 가 놓인 구간. Evidence: L6759–L6759, L6688–L6692.
|
||||
- **Physical Storage** (store): 요구가 여기까지 전달되어야 정전 이후 생존을 말할 수 있다. Evidence: L6762–L6765, L6729–L6729.
|
||||
- **PostgreSQL** (service): 필요한 시점에 fsync() 를 불러 영속성 경계까지 반영을 요청하는 게스트 프로세스. Evidence: L6755–L6755, L6739–L6747.
|
||||
- **Guest Filesystem** (service): fsync() 요구를 처음 받는 게스트 파일시스템. Evidence: L6759–L6759.
|
||||
- **Guest Block Layer** (service): 요구를 FLUSH 등의 block 요청으로 바꾸는 계층. Evidence: L6762–L6764.
|
||||
- **virtio-blk** (service): 그 요청을 VM 경계 너머로 옮기는 게스트 driver. Evidence: L6766–L6766.
|
||||
- **QEMU / Backend** (service): 요청을 받아 호스트 쪽 파일 I/O 나 block I/O 로 잇는 자리. Evidence: L6769–L6769, L6699–L6699.
|
||||
- **Host Storage Stack** (service): 호스트 Page Cache 와 파일시스템, Block Layer 가 놓인 구간. Evidence: L6772–L6772, L6701–L6705.
|
||||
- **Physical Storage** (store): 요구가 여기까지 전달되어야 정전 이후 생존을 말할 수 있다. Evidence: L6775–L6778, L6742–L6742.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **PostgreSQL → Guest Filesystem:** fsync(). Evidence: L6744–L6746.
|
||||
- **Guest Filesystem → Guest Block Layer:** control. Evidence: L6746–L6749.
|
||||
- **Guest Block Layer → virtio-blk:** FLUSH 등. Evidence: L6751–L6753.
|
||||
- **virtio-blk → QEMU / Backend:** control. Evidence: L6753–L6756.
|
||||
- **QEMU / Backend → Host Storage Stack:** control. Evidence: L6756–L6759.
|
||||
- **Host Storage Stack → Physical Storage:** control. Evidence: L6759–L6765.
|
||||
- **PostgreSQL → Guest Filesystem:** fsync(). Evidence: L6757–L6759.
|
||||
- **Guest Filesystem → Guest Block Layer:** control. Evidence: L6759–L6762.
|
||||
- **Guest Block Layer → virtio-blk:** FLUSH 등. Evidence: L6764–L6766.
|
||||
- **virtio-blk → QEMU / Backend:** control. Evidence: L6766–L6769.
|
||||
- **QEMU / Backend → Host Storage Stack:** control. Evidence: L6769–L6772.
|
||||
- **Host Storage Stack → Physical Storage:** control. Evidence: L6772–L6778.
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
digraph techviz {
|
||||
graph [rankdir=TB, splines=ortho, nodesep=0.55, ranksep=0.85];
|
||||
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
|
||||
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
|
||||
n0 [label="PostgreSQL", shape=box, style="rounded,filled"];
|
||||
n1 [label="Guest Filesystem", shape=box, style="rounded,filled"];
|
||||
n2 [label="Guest Block Layer", shape=box, style="rounded,filled"];
|
||||
n3 [label="virtio-blk", shape=box, style="rounded,filled"];
|
||||
n4 [label="QEMU / Backend", shape=box, style="rounded,filled"];
|
||||
n5 [label="Host Storage Stack", shape=box, style="rounded,filled"];
|
||||
n6 [label="Physical Storage", shape=box, style="rounded,filled"];
|
||||
n0 -> n1 [label="fsync()", style=solid];
|
||||
n1 -> n2 [label="", style=solid];
|
||||
n2 -> n3 [label="FLUSH 등", style=solid];
|
||||
n3 -> n4 [label="", style=solid];
|
||||
n4 -> n5 [label="", style=solid];
|
||||
n5 -> n6 [label="", style=solid];
|
||||
}
|
||||
@@ -1,59 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
|
||||
<diagram id="write-completion-boundaries" name="fsync() 의 요구가 물리 storage 까지 내려가는 사슬">
|
||||
<mxGraphModel dx="680" dy="1153" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<mxGraphModel dx="680" dy="2127" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="2127" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_postgresql" value="PostgreSQL<br/>write()<br/>fsync()" tooltip="필요한 시점에 fsync() 를 불러 영속성 경계까지 반영을 요청하는 게스트 프로세스. | Evidence: L6742-L6742, L6726-L6734" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="75.0" y="60.0" width="150.0" height="88.0" as="geometry"/>
|
||||
<mxCell id="n_postgresql" value="PostgreSQL<br/>write()<br/>fsync()" tooltip="필요한 시점에 fsync() 를 불러 영속성 경계까지 반영을 요청하는 게스트 프로세스. | Evidence: L6755-L6755, L6739-L6747" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="35.0" y="145.0" width="150.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_guest-filesystem" value="Guest Filesystem" tooltip="fsync() 요구를 처음 받는 게스트 파일시스템. | Evidence: L6746-L6746" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="75.0" y="244.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_guest-filesystem" value="Guest Filesystem" tooltip="fsync() 요구를 처음 받는 게스트 파일시스템. | Evidence: L6759-L6759" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="47.0" y="455.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_guest-block-layer" value="Guest Block Layer" tooltip="요구를 FLUSH 등의 block 요청으로 바꾸는 계층. | Evidence: L6749-L6751" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="73.5" y="404.0" width="153.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_guest-block-layer" value="Guest Block Layer" tooltip="요구를 FLUSH 등의 block 요청으로 바꾸는 계층. | Evidence: L6762-L6764" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="47.0" y="765.0" width="153.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_virtio-blk" value="virtio-blk" tooltip="그 요청을 VM 경계 너머로 옮기는 게스트 driver. | Evidence: L6753-L6753" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="75.0" y="564.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_virtio-blk" value="virtio-blk" tooltip="그 요청을 VM 경계 너머로 옮기는 게스트 driver. | Evidence: L6766-L6766" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="47.0" y="1078.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_qemu-backend" value="QEMU / Backend" tooltip="요청을 받아 호스트 쪽 파일 I/O 나 block I/O 로 잇는 자리. | Evidence: L6756-L6756, L6686-L6686" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="75.0" y="724.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_qemu-backend" value="QEMU / Backend" tooltip="요청을 받아 호스트 쪽 파일 I/O 나 block I/O 로 잇는 자리. | Evidence: L6769-L6769, L6699-L6699" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="47.0" y="1388.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_host-storage-stack" value="Host Storage Stack" tooltip="호스트 Page Cache 와 파일시스템, Block Layer 가 놓인 구간. | Evidence: L6759-L6759, L6688-L6692" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="884.0" width="160.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_host-storage-stack" value="Host Storage Stack" tooltip="호스트 Page Cache 와 파일시스템, Block Layer 가 놓인 구간. | Evidence: L6772-L6772, L6701-L6705" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="47.0" y="1698.0" width="160.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_physical-storage" value="Physical Storage" tooltip="요구가 여기까지 전달되어야 정전 이후 생존을 말할 수 있다. | Evidence: L6762-L6765, L6729-L6729" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="75.0" y="1044.0" width="150.0" height="64.0" as="geometry"/>
|
||||
<mxCell id="n_physical-storage" value="Physical Storage" tooltip="요구가 여기까지 전달되어야 정전 이후 생존을 말할 수 있다. | Evidence: L6775-L6778, L6742-L6742" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="47.0" y="2018.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_app-to-guest-fs" value="fsync()" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_postgresql" target="n_guest-filesystem">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="174.0" y="196.0" as="offset"/>
|
||||
<mxPoint x="116.0" y="316.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_guest-fs-to-block-layer" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-filesystem" target="n_guest-block-layer">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="174.0" y="356.0" as="offset"/>
|
||||
<mxPoint x="122.8" y="614.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_block-layer-to-virtio" value="FLUSH 등" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-block-layer" target="n_virtio-blk">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="174.0" y="516.0" as="offset"/>
|
||||
<mxPoint x="122.8" y="925.5" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_virtio-to-qemu" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtio-blk" target="n_qemu-backend">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="174.0" y="676.0" as="offset"/>
|
||||
<mxPoint x="146.0" y="1265.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_qemu-to-host-stack" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu-backend" target="n_host-storage-stack">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="174.0" y="836.0" as="offset"/>
|
||||
<mxPoint x="124.5" y="1547.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e_host-stack-to-physical" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-storage-stack" target="n_physical-storage">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="174.0" y="996.0" as="offset"/>
|
||||
<mxPoint x="124.5" y="1862.0" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
{
|
||||
"id": "edge-app-to-guest-fs",
|
||||
"type": "arrow",
|
||||
"x": 150.0,
|
||||
"y": 148.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 110.0,
|
||||
"y": 233.0,
|
||||
"width": 12.0,
|
||||
"height": 222.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -37,15 +37,15 @@
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
111.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
12.0,
|
||||
111.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
12.0,
|
||||
222.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -66,8 +66,8 @@
|
||||
{
|
||||
"id": "edge-label-app-to-guest-fs",
|
||||
"type": "text",
|
||||
"x": 129.0,
|
||||
"y": 184.0,
|
||||
"x": 71.0,
|
||||
"y": 304.0,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -105,10 +105,10 @@
|
||||
{
|
||||
"id": "edge-guest-fs-to-block-layer",
|
||||
"type": "arrow",
|
||||
"x": 150.0,
|
||||
"y": 308.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 122.0,
|
||||
"y": 519.0,
|
||||
"width": 1.5,
|
||||
"height": 246.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -136,15 +136,15 @@
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
1.5,
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
1.5,
|
||||
246.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -165,10 +165,10 @@
|
||||
{
|
||||
"id": "edge-block-layer-to-virtio",
|
||||
"type": "arrow",
|
||||
"x": 150.0,
|
||||
"y": 468.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 122.0,
|
||||
"y": 829.0,
|
||||
"width": 1.5,
|
||||
"height": 249.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -191,20 +191,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
1.5,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
1.5,
|
||||
124.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
124.5
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
249.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -225,8 +225,8 @@
|
||||
{
|
||||
"id": "edge-label-block-layer-to-virtio",
|
||||
"type": "text",
|
||||
"x": 129.0,
|
||||
"y": 504.0,
|
||||
"x": 77.75,
|
||||
"y": 913.5,
|
||||
"width": 90,
|
||||
"height": 24,
|
||||
"angle": 0,
|
||||
@@ -264,10 +264,10 @@
|
||||
{
|
||||
"id": "edge-virtio-to-qemu",
|
||||
"type": "arrow",
|
||||
"x": 150.0,
|
||||
"y": 628.0,
|
||||
"x": 122.0,
|
||||
"y": 1142.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"height": 246.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -295,15 +295,15 @@
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
246.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -324,10 +324,10 @@
|
||||
{
|
||||
"id": "edge-qemu-to-host-stack",
|
||||
"type": "arrow",
|
||||
"x": 150.0,
|
||||
"y": 788.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 122.0,
|
||||
"y": 1452.0,
|
||||
"width": 5.0,
|
||||
"height": 246.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -355,15 +355,15 @@
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
5.0,
|
||||
123.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
5.0,
|
||||
246.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -384,10 +384,10 @@
|
||||
{
|
||||
"id": "edge-host-stack-to-physical",
|
||||
"type": "arrow",
|
||||
"x": 150.0,
|
||||
"y": 948.0,
|
||||
"width": 0.0,
|
||||
"height": 96.0,
|
||||
"x": 122.0,
|
||||
"y": 1762.0,
|
||||
"width": 5.0,
|
||||
"height": 256.0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"backgroundColor": "transparent",
|
||||
@@ -410,20 +410,20 @@
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0.0,
|
||||
5.0,
|
||||
0.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
5.0,
|
||||
128.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
48.0
|
||||
128.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
96.0
|
||||
256.0
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
@@ -444,8 +444,8 @@
|
||||
{
|
||||
"id": "node-postgresql",
|
||||
"type": "rectangle",
|
||||
"x": 75.0,
|
||||
"y": 60.0,
|
||||
"x": 35.0,
|
||||
"y": 145.0,
|
||||
"width": 150.0,
|
||||
"height": 88.0,
|
||||
"angle": 0,
|
||||
@@ -474,8 +474,8 @@
|
||||
{
|
||||
"id": "node-label-postgresql",
|
||||
"type": "text",
|
||||
"x": 85.0,
|
||||
"y": 70.0,
|
||||
"x": 45.0,
|
||||
"y": 155.0,
|
||||
"width": 130.0,
|
||||
"height": 68.0,
|
||||
"angle": 0,
|
||||
@@ -513,8 +513,8 @@
|
||||
{
|
||||
"id": "node-guest-filesystem",
|
||||
"type": "rectangle",
|
||||
"x": 75.0,
|
||||
"y": 244.0,
|
||||
"x": 47.0,
|
||||
"y": 455.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -543,8 +543,8 @@
|
||||
{
|
||||
"id": "node-label-guest-filesystem",
|
||||
"type": "text",
|
||||
"x": 85.0,
|
||||
"y": 254.0,
|
||||
"x": 57.0,
|
||||
"y": 465.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -582,8 +582,8 @@
|
||||
{
|
||||
"id": "node-guest-block-layer",
|
||||
"type": "rectangle",
|
||||
"x": 73.5,
|
||||
"y": 404.0,
|
||||
"x": 47.0,
|
||||
"y": 765.0,
|
||||
"width": 153.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -612,8 +612,8 @@
|
||||
{
|
||||
"id": "node-label-guest-block-layer",
|
||||
"type": "text",
|
||||
"x": 83.5,
|
||||
"y": 414.0,
|
||||
"x": 57.0,
|
||||
"y": 775.0,
|
||||
"width": 133.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -651,8 +651,8 @@
|
||||
{
|
||||
"id": "node-virtio-blk",
|
||||
"type": "rectangle",
|
||||
"x": 75.0,
|
||||
"y": 564.0,
|
||||
"x": 47.0,
|
||||
"y": 1078.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -681,8 +681,8 @@
|
||||
{
|
||||
"id": "node-label-virtio-blk",
|
||||
"type": "text",
|
||||
"x": 85.0,
|
||||
"y": 574.0,
|
||||
"x": 57.0,
|
||||
"y": 1088.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -720,8 +720,8 @@
|
||||
{
|
||||
"id": "node-qemu-backend",
|
||||
"type": "rectangle",
|
||||
"x": 75.0,
|
||||
"y": 724.0,
|
||||
"x": 47.0,
|
||||
"y": 1388.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -750,8 +750,8 @@
|
||||
{
|
||||
"id": "node-label-qemu-backend",
|
||||
"type": "text",
|
||||
"x": 85.0,
|
||||
"y": 734.0,
|
||||
"x": 57.0,
|
||||
"y": 1398.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -789,8 +789,8 @@
|
||||
{
|
||||
"id": "node-host-storage-stack",
|
||||
"type": "rectangle",
|
||||
"x": 70.0,
|
||||
"y": 884.0,
|
||||
"x": 47.0,
|
||||
"y": 1698.0,
|
||||
"width": 160.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -819,8 +819,8 @@
|
||||
{
|
||||
"id": "node-label-host-storage-stack",
|
||||
"type": "text",
|
||||
"x": 80.0,
|
||||
"y": 894.0,
|
||||
"x": 57.0,
|
||||
"y": 1708.0,
|
||||
"width": 140.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
@@ -858,8 +858,8 @@
|
||||
{
|
||||
"id": "node-physical-storage",
|
||||
"type": "rectangle",
|
||||
"x": 75.0,
|
||||
"y": 1044.0,
|
||||
"x": 47.0,
|
||||
"y": 2018.0,
|
||||
"width": 150.0,
|
||||
"height": 64.0,
|
||||
"angle": 0,
|
||||
@@ -888,8 +888,8 @@
|
||||
{
|
||||
"id": "node-label-physical-storage",
|
||||
"type": "text",
|
||||
"x": 85.0,
|
||||
"y": 1054.0,
|
||||
"x": 57.0,
|
||||
"y": 2028.0,
|
||||
"width": 130.0,
|
||||
"height": 44.0,
|
||||
"angle": 0,
|
||||
|
||||
@@ -2,30 +2,41 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "write-completion-boundaries",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "c7838bc8393b43c94ed4628db350f0fb26e90fc0d566201e471d49d533963699",
|
||||
"spec_sha256": "8d44da349d9a7266196589b928fc15554c3e3b25fcf10e94f6f5f71a8cd8a39b",
|
||||
"source_context": {
|
||||
"document": "docs/virtualization/final/document.md",
|
||||
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
||||
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "150. `fsync()`가 필요한 이유",
|
||||
"line": 6723
|
||||
"line": 6736
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"write-completion-boundaries.svg",
|
||||
"write-completion-boundaries.drawio",
|
||||
"write-completion-boundaries.mmd",
|
||||
"write-completion-boundaries.d2",
|
||||
"write-completion-boundaries.dot",
|
||||
"write-completion-boundaries.drawio",
|
||||
"write-completion-boundaries.excalidraw",
|
||||
"write-completion-boundaries.alt.md"
|
||||
],
|
||||
"lint_issue_count": 4,
|
||||
"lint_issue_count": 5,
|
||||
"assumption_count": 0,
|
||||
"assumptions_allowed": false,
|
||||
"composition_profile": "component-flow",
|
||||
"reference_ids": [
|
||||
"payment-event-flow"
|
||||
],
|
||||
"diagram_only": true
|
||||
"diagram_only": true,
|
||||
"source_spec_file_sha256": "bb567101fd18f99abd2bcd62de04ee8b9d6ab54c20ffbf1ee681daab73219a72",
|
||||
"output_sha256": {
|
||||
"write-completion-boundaries.svg": "c78624a9b2ee8116f73a412d52ee4fe0dda725c90e7df83d726be3a5a36be3fd",
|
||||
"write-completion-boundaries.mmd": "e7642e0fc2a3b9946e471c5993218257b4aca33749521ede6ac80012c8f3981c",
|
||||
"write-completion-boundaries.d2": "ad2f18856ec2c98b1c9a72fa5e7a7db65c1732e480687b15b8ed0a54416b2d9c",
|
||||
"write-completion-boundaries.dot": "72373f45393d43098daec116f4373d8fe2e5473ae5bc5775c159447877c14075",
|
||||
"write-completion-boundaries.drawio": "cc592ec929c1e2883309acccafac5d8c9cf566cf78fb4ff86b4542feee810a74",
|
||||
"write-completion-boundaries.excalidraw": "c75a2368d625125477666b85b8305e348a06541ffe5aaf6653fddd8e217b8358",
|
||||
"write-completion-boundaries.alt.md": "c14e7bb4da2acaa2e39a584d363750cdf2f4ed79ed8d55bb0c4efe6c77aa230c"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="1153" viewBox="0 0 680 1153" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="2127" viewBox="0 0 680 2127" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">fsync() 의 요구가 물리 storage 까지 내려가는 사슬</title>
|
||||
<desc id="diagram-description">위에서 아래로 읽는다. 맨 위 PostgreSQL 이 fsync() 를 부르고 그 요구가 Guest Filesystem 으로 내려간다. Guest Block Layer 에서 FLUSH 등의 요청으로 바뀌고, virtio-blk 를 지나 VM 경계를 넘어 QEMU / Backend 로 간다. 거기서 Host Storage Stack 을 지나 맨 아래 Physical Storage 까지 그 의미가 전달되어야 완료가 성립한다. 여섯 번 손이 바뀌는 동안 한 곳이라도 그 의미를 지키지 않으면 게스트가 받은 완료 응답이 거짓이 된다. write() 완료와 writeback 완료, fsync/flush 완료, 전원 장애에도 안전한 durability 가 서로 다르다는 구분은 본문의 코드블록이 맡는다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"write-completion-boundaries","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd","anchor":{"kind":"heading","value":"150. `fsync()`가 필요한 이유","line":6723}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"write-completion-boundaries","profile":"component-flow"},"source_context":{"document":"docs/virtualization/final/document.md","document_sha256":"8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210","anchor":{"kind":"heading","value":"150. `fsync()`가 필요한 이유","line":6736}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -49,46 +49,46 @@
|
||||
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="680" height="1153" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,148.0 150.0,196.0 150.0,196.0 150.0,244.0" data-evidence="6744-6746" />
|
||||
<rect class="edge-label-bg" x="141.6" y="182.0" width="64.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="174.0" y="197.0">fsync()</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,308.0 150.0,356.0 150.0,356.0 150.0,404.0" data-evidence="6746-6749" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,468.0 150.0,516.0 150.0,516.0 150.0,564.0" data-evidence="6751-6753" />
|
||||
<rect class="edge-label-bg" x="141.6" y="502.0" width="64.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="174.0" y="517.0">FLUSH 등</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,628.0 150.0,676.0 150.0,676.0 150.0,724.0" data-evidence="6753-6756" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,788.0 150.0,836.0 150.0,836.0 150.0,884.0" data-evidence="6756-6759" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,948.0 150.0,996.0 150.0,996.0 150.0,1044.0" data-evidence="6759-6765" />
|
||||
<rect class="canvas" width="680" height="2127" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="110.0,233.0 110.0,344.0 122.0,344.0 122.0,455.0" data-evidence="6757-6759" />
|
||||
<rect class="edge-label-bg" x="83.5" y="302.0" width="64.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="116.0" y="317.0">fsync()</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="122.0,519.0 122.0,642.0 123.5,642.0 123.5,765.0" data-evidence="6759-6762" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="123.5,829.0 123.5,953.5 122.0,953.5 122.0,1078.0" data-evidence="6764-6766" />
|
||||
<rect class="edge-label-bg" x="90.3" y="911.5" width="64.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="122.8" y="926.5">FLUSH 등</text>
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="122.0,1142.0 122.0,1265.0 122.0,1265.0 122.0,1388.0" data-evidence="6766-6769" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="122.0,1452.0 122.0,1575.0 127.0,1575.0 127.0,1698.0" data-evidence="6769-6772" />
|
||||
<polyline class="edge kind-control style-solid emphasis-normal" points="127.0,1762.0 127.0,1890.0 122.0,1890.0 122.0,2018.0" data-evidence="6772-6778" />
|
||||
<g id="node-postgresql">
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="6742-6742,6726-6734" x="75.0" y="60.0" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="150.0" y="87.0">PostgreSQL</text>
|
||||
<line class="node-detail-divider" x1="89.0" y1="108.0" x2="211.0" y2="108.0" />
|
||||
<text class="node-detail" x="91.0" y="125.0">write()</text>
|
||||
<text class="node-detail" x="91.0" y="141.0">fsync()</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="6755-6755,6739-6747" x="35.0" y="145.0" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="110.0" y="172.0">PostgreSQL</text>
|
||||
<line class="node-detail-divider" x1="49.0" y1="193.0" x2="171.0" y2="193.0" />
|
||||
<text class="node-detail" x="51.0" y="210.0">write()</text>
|
||||
<text class="node-detail" x="51.0" y="226.0">fsync()</text>
|
||||
</g>
|
||||
<g id="node-guest-filesystem">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6746-6746" x="75.0" y="244.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="150.0" y="274.0">Guest Filesystem</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6759-6759" x="47.0" y="455.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="122.0" y="485.0">Guest Filesystem</text>
|
||||
</g>
|
||||
<g id="node-guest-block-layer">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6749-6751" x="73.5" y="404.0" width="153.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="150.0" y="434.0">Guest Block Layer</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6762-6764" x="47.0" y="765.0" width="153.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="123.5" y="795.0">Guest Block Layer</text>
|
||||
</g>
|
||||
<g id="node-virtio-blk">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6753-6753" x="75.0" y="564.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="150.0" y="594.0">virtio-blk</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6766-6766" x="47.0" y="1078.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="122.0" y="1108.0">virtio-blk</text>
|
||||
</g>
|
||||
<g id="node-qemu-backend">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6756-6756,6686-6686" x="75.0" y="724.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="150.0" y="754.0">QEMU / Backend</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6769-6769,6699-6699" x="47.0" y="1388.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="122.0" y="1418.0">QEMU / Backend</text>
|
||||
</g>
|
||||
<g id="node-host-storage-stack">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6759-6759,6688-6692" x="70.0" y="884.0" width="160.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="150.0" y="914.0">Host Storage Stack</text>
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6772-6772,6701-6705" x="47.0" y="1698.0" width="160.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="127.0" y="1728.0">Host Storage Stack</text>
|
||||
</g>
|
||||
<g id="node-physical-storage">
|
||||
<rect class="node-shape kind-store emphasis-primary role-sink" data-evidence="6762-6765,6729-6729" x="75.0" y="1044.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="150.0" y="1074.0">Physical Storage</text>
|
||||
<rect class="node-shape kind-store emphasis-primary role-sink" data-evidence="6775-6778,6742-6742" x="47.0" y="2018.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="122.0" y="2048.0">Physical Storage</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |