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-05-23
文件映射和 page cache:文件内容怎样变成页面
上一篇看了匿名页和 COW,它们处理的是没有文件 backing 的内存。文件 backing 是另一条主线:文件内容如何进入内核管理的页面池,又如何被 read() 复制到用户缓冲区或被 mmap() 映射进进程地址空间。这一切的共同枢纽是 page cache。 核心问题可以压成一句话: page cache 让文件 I/O 和虚拟内存共享同一批页面对象;read() 和 mmap() 只是进入 page cache 的两种路径。 问题从哪里来 教材常把文件 I/O 和虚拟内存分开讲。读文件用 read,写文件用 write,文件系统维护自己的“缓冲缓存”;进程内存用 mmap、malloc、fork,由 VM 子系统管理。两套体系,互不相干。 Linux 不是这样实现的。当前官方文档对 page cache 给出的定位非常直接: The page cache is the primary way that the user and the rest of the kernel interact with filesystems. 也就是说,绝大多数 read/wr...

2026-09-24
计算机网络 30:数据如何经过 Linux 主机,socket、协议栈、队列、软中断与网卡卸载
应用调用 sendall() 返回时,数据可能仍在本机发送队列中;抓包显示一个大于 MTU 的 TCP 对象时,线上也未必出现过同样大小的帧;监控里的网卡计数增长,则不一定只来自当前进程。三种观察都是真的,但它们观察的是 Linux 网络路径上的不同位置。 第 03 篇已经说明抓包点决定证据边界,第 19 篇区分了发送端、接收端与路径上的速度限制,第 29 篇讨论了应用怎样等待 socket 就绪。本篇把这些观察点放回一台 Linux 主机:应用通过 socket 提交或接收字节,内核协议栈维护连接和队列,设备收发路径可能经过 NAPI、软中断与卸载。每个观察点只能证明其附近发生了什么。 socket 是用户态与协议栈之间的接口 Linux socket(7) 把 socket 描述为用户进程与内核协议栈之间的统一接口。文件描述符只是应用持有的引用;TCP 连接状态、发送和接收缓冲、重传及拥塞控制由内核维护。一次系统调用返回,不等于整条端到端路径完成。 以一次 TCP 发送为例,可以分出四个不同事件: send() 或 sendall() 把字节交给本机内核,或者因错误而失败;...

2026-10-01
容器 03:PID 1 为什么改变信号与回收行为
在 PID namespace 中第一个子进程的 PID 是 1。这个数字不仅是用户界面的显示值:该进程承担接收孤儿进程、处理终止事件的职责。如果它结束,内核会终止此 PID namespace 中的其他进程。先掌握01 的 wait/信号和02 的 namespace 身份,否则容易把“应用没有退出”误判成运行时故障。 PID 号码与进程的两个视角 PID namespace 按层级组织。内侧看到的 PID 1 在外侧仍有宿主 PID,外侧能够观察内部进程,内部不能因此查看外侧所有进程。/proc 是一个挂载出来的进程信息视图;仅调用 unshare 而沿用旧 /proc 挂载,可能读到旧 namespace 的 PID,进而产生“shell 的 $$ 是 1,/proc/self/status 却有不同号码”的矛盾。应在私有挂载环境重新挂载 procfs,才用它检查当前 PID 视图;没有这个权限,明确标记观察限制,而不是补造一致的 PID 输出。 PID 1 对某些未安装处理函数的默认信号行为有特殊规则。它并不是“永远不会响应 TERM”:安装了 TERM han...

2026-10-01
容器 02:namespace 改变的是哪些资源视图
在一个终端里改了主机名,另一个终端为什么没变?关键不是 shell 的变量,而是两个进程引用的 UTS namespace 不同。沿01 的进程生命周期继续,把隔离看成“进程持有哪些内核对象”,而不是把容器想象成一台小型物理机。 比较视图,不比较字符串 clone 可让新进程进入新建的 namespace;unshare 使调用者与先前共享的指定 namespace 分离;setns 把调用者加入已有 namespace,但有具体的权限、类型和多线程前提。UTS 隔离 hostname 与 domainname,IPC 隔离相应的进程间通信对象;PID、mount、net 与 user 各有自己的资源集合。/proc/<pid>/ns/<type> 的链接目标包含可比对的 namespace inode。两个进程具有相同 UTS inode,表示指向同一 UTS namespace;两个进程恰好都输出 hostname=demo,却可能在不同 UTS 对象里。不能跨类型比较数字本身。 普通读者并不必在宿主得到所有 capability。unshare -U...
2026-05-24
NUMA:内存为什么有远近
上一篇讲了 swap 如何为匿名页提供外部 backing store。讨论中一直隐含一个假设:物理内存是一块均匀的资源,任何 CPU 访问任何物理页的代价相同。在 NUMA 架构下这个假设不成立。 这篇要回答的核心矛盾: NUMA 让"物理内存"不再是均匀资源;分配位置、CPU 位置和迁移策略共同决定访问成本。 问题从哪里来 在 UMA(Uniform Memory Access)系统中,所有 CPU 共享一条总线访问同一组内存控制器。每个 CPU 访问任何物理地址的延迟相同。早期单路和低端双路机器大多是这种架构。 当 CPU 数量增加,单一总线成为瓶颈。NUMA(Non-Uniform Memory Access)把系统拆成多个节点(node),每个节点包含若干 CPU 核心和一组本地内存。节点内部通过本地总线通信(快),节点之间通过互联(QPI、UPI、Infinity Fabric 等)通信(慢)。 1234567891011UMA: CPU0 CPU1 CPU2 CPU3 \ | | / shared bus ...
2026-05-23
页回收:kswapd 和 direct reclaim
上一篇讲了内核如何用 LRU 近似和 workingset 检测来判断"谁冷谁热"。判断完之后,实际把页面释放出来的工作由回收子系统完成。回收不是一个单点事件,而是围绕水位线、后台线程和分配路径形成的一套压力响应机制。 核心问题可以压成一句话: 回收是围绕水位线的分级压力响应,不是耗尽后的单点动作。 问题从哪里来 内存分配在 Linux 里几乎无处不在:用户态 malloc 背后的匿名页、page cache 的文件页、内核自己的 slab 对象。每次分配都从 buddy allocator 拿物理页。物理页是有限的。 如果等到完全分配不出页面再回收,分配方会被阻塞很长时间——回收可能涉及写脏页、等待 I/O、遍历反向映射。这种"等到没有了才动"的策略延迟不可控。 Linux 的做法是提前开始。内核设定一组水位线(watermark),在不同压力级别触发不同强度的回收。大部分情况下由后台线程 kswapd 在压力升起时提前回收;只有来不及时才在分配路径上直接回收(direct reclaim)。 水位线模型 每个 zone 有三条基本...
Announcement
人生只是,守株待兔






