Linux hypervisor
Created|Updated|基础设施
|Word Count:125|Reading Time:1mins|Post Views:
hypervisor 可以被认为等于 virtual hardware。他们的出现,可以有效减少硬件服务器数量。
常见的 hypervisor 分成两类:
- 直接运行在硬件上的,基于内核的虚拟机。 OS as hypervisor。典型例子是 KVM。KVM 是被集成到 Linux 内核之中的完整虚拟化解决方案。
- 运行于另一个操作系统之上。典型的例子是 QEMU 和 WINE。
hypervisor的实现,总是要映射一些磁盘设备和网络设备的。
Author: magicliang
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles

2026-10-01
容器 35:性能差异来自隔离层还是实验条件
“容器性能损耗多少”缺少测量对象和实验条件。应用计算、内存申请、文件系统 copy-up、网络封装都在不同路径上。34只评估启动,不把 steady-state 性能一起平均。本篇先设定可以证伪的对照,再决定哪些数字能归因于容器边界。 把某个程序在宿主上执行十次、在容器里执行十次,得到两列数字后相除,并不能得出“容器比宿主慢 X%”:运行方式可能顺带改变了 CPU 配额、可用核心、进程 UID、文件路径、网络路由与镜像依赖。先用一种不碰磁盘、也不调用网络的短时计算任务建立最小对照;再单独讨论内存、OverlayFS 与网络。每次只改变一个前提,才能知道数字是哪个路径造成的。本篇没有专用 Docker/双 VM,数字一律留空,不用外部基准报告代替自己的实验。 逐项只改变一个条件 同一内核、架构、节点、二进制和输入,先在普通进程跑 bounded_load 的有界计算/内存路径,再在专用容器内跑同样命令;分别记录用户态时间、CPU/内存控制器、可运行 CPU 集与真实的 cgroup 限制。文件系统实验区分宿主相同盘的普通写入、容器可写层首次写入与同一镜像的重复写入;网络实验区分 l...
2026-05-23
页表:CPU 能读懂的翻译结构
上一篇把地址空间组织成一组 VMA,回答了“这个地址原则上是否属于进程,应该按什么规则处理”。这一篇切到另一层结构:页表。VMA 是内核策略的元数据,页表是 CPU 的 MMU 实际查询的硬件数据结构。两层一致时访问能继续,不一致时进入缺页异常。 核心问题可以压成一句话: VMA 决定一个地址原则上是否合法,页表决定一个虚拟页此刻能否被 CPU 翻译。 问题从哪里来 很多教材把页表画成“虚拟页号到物理页号的一张大表”。这张表足够回答“地址能不能翻译”,但解释不了几件实际发生的事。 一次 mmap 成功后,VMA 已经登记,可是第一次访问还会触发缺页异常,进程并没有出错。一段映射可能在 maps 里看得到、长期不被访问、/proc/<pid>/pagemap 报 present=0,进程也没有出错。一个共享文件页可以同时被多个进程访问,每个进程的页表里都有一份 PTE,但物理页只有一份。一个匿名页可能此刻在内存里、PTE present;过一会儿被 swap 出去,PTE 变成 swap 类型;再被访问时通过缺页恢复,PTE 又重新指向 PFN。 把这些现象统一起...
2026-05-23
缺页异常:一次访问如何进入内核
上一篇区分了 VMA 与页表:VMA 是地址区间策略,页表是 CPU 当前可消费的翻译记录。当 VMA 合法、PTE 却不满足这次访问时,硬件会把异常抛回内核,由内核的缺页处理路径接管。这一篇把这条路径走一遍。 核心问题可以压成一句话: page fault 不是错误的同义词,它是 Linux VM 延迟兑现承诺的主要入口。 问题从哪里来 “缺页异常”这个翻译容易引误解。它在英文里是 page fault,词义中性,本意只是“缺一次翻译”。大量正常程序每秒会产生上百次甚至数千次 page fault,进程跑得很好,没有任何错误。 mmap 完成后第一次访问、fork 后子进程写共享只读页、读一个尚未在 page cache 的文件、被回收过的匿名页再次访问、栈在合法范围内增长,都会触发 page fault。这些 fault 走完之后,程序继续执行下一条指令,用户态察觉不到任何异常。 只有少数情况会让 page fault 变成可见错误:访问完全不属于任何 VMA 的地址、对只读 VMA 写入、对不可执行区段取指令、内核回收阶段无法找到合适页面来满足需求。这些情况要么导致信...

2026-10-01
容器 01:父进程退出,工作是否已经结束
“主进程退出了”既不能证明它启动的子进程已完成,也不能证明系统已经回收了全部进程状态。将这句话拆成 fork、exec、文件描述符、信号与 wait,才能解释容器里最常见的退出和日志问题。先阅读00:观测对象与实验基线;这一篇只使用普通进程建立可复核的生命周期,不假定容器运行时已经可用。 四个独立动作 fork() 创建子进程:父子最初有独立 PID,子进程继承打开的文件描述符,但调用返回后谁先执行取决于调度,不能把日志先后当程序依赖。execve() 用新程序替换当前进程映像,不会因为替换而分配新的 PID。默认打开的 FD 随之保留;设置 FD_CLOEXEC 才要求 exec 时关闭相应描述符。容器标准输出常作为由运行时提供的 FD 传入应用,因此新程序是否继承它是能否观察日志的关键。别把“关闭路径名对应的文件”和“关闭 FD”混为一谈:先前打开的 FD 指向已打开文件对象,删除路径也未必让引用立刻失效。 子进程结束时留下退出状态,父进程通过 waitpid() 读取并回收;WIFEXITED 与 WEXITSTATUS 用于正常退出,WIFSIGNALED 用于信号终止。...

2026-10-01
容器 07:内存超限与 I/O 变慢不是一种失败
06已经区分 CPU 带宽与相对竞争。内存、进程数量和块设备 I/O 也通过不同控制器暴露各自的失败证据;把“容器慢/死了”统一解释为 OOM,会错过问题所在。 内存约束不是单个数字 cgroup v2 中 memory.current 提供当前使用量,memory.max 为硬上限,memory.high 引导回收与节流;memory.events 的 high、max、oom、oom_kill 记录不同事件。超过 memory.high 不意味着立即杀进程;达到 memory.max 也不能不看回收成败就声称发生了 OOM kill。计数器是累积的,需比较实验前后,记录关联进程和层级。先在专用 VM 给单一小组设置有界内存与申请上限,绝不在共享宿主引发全局压力;每轮记录进程退出状态、memory.events、memory.current 和 dmesg 是否有权限取得相应事件。 pids.max 限制组内任务数量,达到时新的 fork 可以失败,并非旧进程自动被终止。io.max 规定特定设备的 BPS/IOPS 上限,需要先确认设备号、后端以及页缓存是否掩盖了真实块 I/...
2025-05-17
Unix/Linux 系统的常见目录
一级目录 目录路径 缩写解释 / 全称 用途描述 常见子目录/示例 / Root 根目录,所有其他目录的起点 无 /bin Binaries 基础命令的二进制文件(所有用户必需) ls, cp, mv, cat /boot Boot 系统启动文件(内核、引导加载程序) vmlinuz-*(内核文件)、grub/(GRUB配置)、initramfs /dev Devices 设备文件(物理/虚拟设备接口) sda(磁盘)、tty(终端)、null(空设备)、random(随机数生成器) /etc Etcetera 系统级配置文件(全局配置) passwd(用户账户)、fstab(挂载表)、apt/(APT包管理器配置)、ssh/ /home Home 用户主目录(个人文件和数据) /home/alice(用户 Alice 的目录) /lib Libraries 基础共享库和内核模块(支持 /bin 和 /sbin) libc.so(C标准库)、modules/(内核模块) /media Media 可移动设备挂载点(自动挂载) usb/(U...
Announcement
人生只是,守株待兔






