libvirt/Domain 对象管理

让名称和 UUID 指向同一虚拟机对象

libvirt 为 Domain 对象维护 UUID 与名称两个哈希索引,两个入口指向同一个对象。

v10.10.0索引与查找核验 2026-10-08
相关概念

工程问题#

API 调用者可能拿名称,也可能拿 UUID 查询虚拟机;创建、重命名和删除还必须保持各入口一致。

实际实现#

virDomainObjList 的 objs 与 objsName 分别索引 UUID 字符串和名称。加入第二张表失败时回滚第一张,并由锁与引用计数管理生命周期。

处理流程#

  1. 格式化 UUID 并建立第一索引
  2. 建立名称索引并增加引用
  3. 按调用者提供的键查询
  4. 更新或删除时协调两张索引

源码片段#

固定版本 · 原文摘录
src/conf/virdomainobjlist.cv10.10.0 · L226–L244
查看原文件
226static int227virDomainObjListAddObjLocked(virDomainObjList *doms,228                             virDomainObj *vm)229{230    char uuidstr[VIR_UUID_STRING_BUFLEN];231232    virUUIDFormat(vm->def->uuid, uuidstr);233    if (virHashAddEntry(doms->objs, uuidstr, vm) < 0)234        return -1;235    virObjectRef(vm);236237    if (virHashAddEntry(doms->objsName, vm->def->name, vm) < 0) {238        virHashRemoveEntry(doms->objs, uuidstr);239        return -1;240    }241    virObjectRef(vm);242243    return 0;244}
virDomainObjListAddObjLocked

同一个 vm 先按 UUID 放入 objs,再按名称放入 objsName;第二次插入失败就删除第一项。两次 virObjectRef 对应两个索引持有的对象引用。函数名中的 Locked 表示调用者负责满足锁定约束。

收益与取舍#

工程分析

带来的收益

  • 常见点查找无需遍历全部虚拟机
  • 避免复制完整 Domain 对象

付出的代价

  • 工程分析:双索引多消耗键和表项内存
  • 跨索引更新需要一致性与回滚逻辑

可比较的选择

单索引加遍历维护简单,但第二种查询方式需要线性扫描。

版本与适用范围#

对应 libvirt v10.10.0 的 UUID 与名称查询;数字运行 ID 查询在此实现中不等同于第三张哈希索引。

参考来源#

源码、官方文档与原始论文
01
libvirt · virDomainObjListAddObjLocked / virDomainObjListFindByName

src/conf/virdomainobjlist.c · virDomainObjListAddObjLocked / virDomainObjListFindByName

源码v10.10.0

相关实现与比较#

4 个相关案例
QEMU·TCG 翻译块v9.2.0

QEMU TCG 用 QHT 保存 TranslationBlock 索引,帮助复用与当前客体执行状态一致的翻译结果。

附源码片段 · 缓存与复用
6 个匹配案例