HAM API完全指南:掌握ubturbo_ham_register等关键接口的使用方法 HAM API完全指南掌握ubturbo_ham_register等关键接口的使用方法【免费下载链接】hamBased on the remote memory access capability and high bandwidth of the UB, deterministic duration virtual machine live migration is achieved, addressing planned downtime issues and ensuring system high availability.项目地址: https://gitcode.com/openeuler/ham前往项目官网免费下载https://ar.openeuler.org/ar/想要实现确定性时长的虚拟机热迁移吗openEuler社区的HAM项目为您提供了完美的解决方案本文将为您详细介绍HAM API的完整使用方法帮助您快速掌握ubturbo_ham_register等关键接口实现系统高可用性的迁移服务。HAMHigh-Availability Migration是基于灵衢总线的远端内存访问能力与大带宽实现确定性时长虚拟机热迁移的关键组件。通过本文的简单教程您将学会如何使用HAM API来解决计划内停机问题确保您的系统始终保持高可用状态。 HAM项目简介与架构HAM是一个高可用性热迁移服务它利用灵衢内存池化能力将目的端虚拟机内存上线到源端操作系统并通过内核migrate_pages接口迁移内存。在迁移过程中通过灵衢总线的远端内存访问能力保活虚拟机实现零数据副本的迁移彻底去除迭代清脏依赖。从上图可以看到HAM架构设计简洁高效主要由以下几个核心模块组成HAM库(libham.so) - 提供迁移API接口迁移任务管理- 协调迁移过程内存精准迁移- 确保数据一致性错误处理机制- 保障迁移可靠性 快速安装与部署在开始使用HAM API之前您需要先完成HAM的安装。以下是简单的安装步骤安装依赖组件确保已安装obmm、ubturbo、ubs-engine等基础组件安装libvirt和QEMU执行以下命令安装必要的虚拟化工具yum install -y libvirt* qemu* edk2-aarch64.noarch配置QEMU和libvirt修改/etc/libvirt/qemu.conf配置文件安装HAM RPM包执行yum install -y ham完成安装安装完成后您可以在/usr/include/ham.h找到API头文件在/usr/lib/libham.so找到动态库文件。 核心API接口详解HAM提供了五个关键API接口每个接口都有特定的功能和使用场景。让我们逐一深入了解1. ubturbo_ham_register - 初始化确定性迁移这是最重要的接口用于启动确定性迁移并完成迁移前的准备工作。该函数位于src/ham.h文件中函数原型如下int32_t ubturbo_ham_register(HamRamInfo *src, HamNumaInfo *dst);参数说明src源端虚拟机ramblock的描述信息dst目的端虚拟机借用内存的描述信息使用示例#include ham.h int main(void) { HamRamInfo srcInfo { .pid 100, .scna 1, .num 2, .blockList { {.uuid 1, .hva 0x1000, .size 4096}, {.uuid 2, .hva 0x2000, .size 8192} } }; HamNumaInfo dstInfo { .pid 101, .num 2, .numaList { {.numaId 34, .size 4096}, {.numaId 35, .size 8192} } }; int32_t result ubturbo_ham_register(srcInfo, dstInfo); if (result SUCCESS) { printf(迁移初始化成功\n); } else { printf(迁移初始化失败错误码%d\n, result); } return 0; }2. ubturbo_ham_migrate - 触发确定性迁移这个接口用于实际执行页面迁移支持不同的迁移阶段int32_t ubturbo_ham_migrate(HamRamPages *ramList, size_t ramNum, int32_t step);参数说明ramList源端虚拟机的待迁移页面描述信息ramNum待迁移页面描述信息数组长度step区分precopy阶段0和停机中断阶段1迁移阶段详解HAM_MIGRATE_PRECOPY(0)预复制阶段处理脏页HAM_MIGRATE_COMPLETION(1)完成阶段刷新缓存3. ubturbo_ham_unregister - 结束确定性迁移迁移完成后使用此接口释放相关资源void ubturbo_ham_unregister(void);这是一个无参数、无返回值的简单函数用于清理临时资源并关闭HAM设备。4. ubturbo_ham_rollback - 页面回迁处理当迁移失败时这个接口可以将已迁出的页面回迁到源端int32_t ubturbo_ham_rollback(pid_t srcPid);参数说明srcPid源端虚拟机进程ID5. ubturbo_ham_external_log_set - 自定义日志函数为了灵活处理日志输出HAM提供了日志注册接口void ubturbo_ham_external_log_set(ExternalLog logFunc);您可以根据需要将日志输出到系统日志、文件或其他自定义位置。 数据结构详解要正确使用HAM API您需要了解几个关键的数据结构HamRamInfo - 源端内存信息typedef struct { pid_t pid; // 迁移进程PID uint16_t scna; // 源端ub_controller标识符 uint32_t num; // 源端待迁移ramblock数量 HamRamBlock blockList[BATCH_NUM]; // 源端待迁移ramblock数组 } HamRamInfo;HamNumaInfo - 目的端NUMA信息typedef struct { pid_t pid; // 迁移进程的PID uint32_t num; // HamNuma的个数 HamNuma numaList[BATCH_NUM]; // HamNuma数组 } HamNumaInfo;HamRamBlock - 内存块信息typedef struct { uint32_t uuid; // ramblock的ID一般从0开始 uintptr_t hva; // ramblock的起始地址 size_t size; // ramblock的大小 } HamRamBlock;️ 完整迁移流程示例下面是一个完整的迁移示例展示了如何使用HAM API进行确定性迁移#include stdio.h #include stdlib.h #include ham.h // 自定义日志函数 static void custom_log_func(int level, const char *funcname, int linenr, const char *logBuf) { printf([HAM] %s:%d - %s\n, funcname, linenr, logBuf); } int main() { // 1. 设置自定义日志 ubturbo_ham_external_log_set(custom_log_func); // 2. 准备源端内存信息 HamRamInfo srcInfo { .pid 1234, .scna 1, .num 2, .blockList { {.uuid 0, .hva 0x1000000, .size 1024 * 1024}, // 1MB {.uuid 1, .hva 0x2000000, .size 2 * 1024 * 1024} // 2MB } }; // 3. 准备目的端NUMA信息 HamNumaInfo dstInfo { .pid 1235, .num 2, .numaList { {.numaId 0, .size 1024 * 1024}, {.numaId 1, .size 2 * 1024 * 1024} } }; // 4. 初始化迁移 int32_t ret ubturbo_ham_register(srcInfo, dstInfo); if (ret ! SUCCESS) { printf(迁移初始化失败错误码0x%x\n, ret); return -1; } printf(迁移初始化成功\n); // 5. 准备迁移页面数据 HamRamPages ramPages { .uuid 0, .hvaNum 10, .hvaList (uintptr_t[]){0x1000000, 0x1001000, 0x1002000, 0x1003000, 0x1004000, 0x1005000, 0x1006000, 0x1007000, 0x1008000, 0x1009000} }; // 6. 执行预复制阶段迁移 ret ubturbo_ham_migrate(ramPages, 1, HAM_MIGRATE_PRECOPY); if (ret ! SUCCESS) { printf(预复制阶段失败错误码0x%x\n, ret); // 回滚迁移 ubturbo_ham_rollback(srcInfo.pid); return -1; } printf(预复制阶段完成\n); // 7. 执行完成阶段迁移 ret ubturbo_ham_migrate(ramPages, 1, HAM_MIGRATE_COMPLETION); if (ret ! SUCCESS) { printf(完成阶段失败错误码0x%x\n, ret); ubturbo_ham_rollback(srcInfo.pid); return -1; } printf(完成阶段完成\n); // 8. 清理资源 ubturbo_ham_unregister(); printf(迁移完成资源已清理\n); return 0; } 错误处理与调试在使用HAM API时正确的错误处理非常重要。HAM定义了以下错误码错误码描述解决方法ERR_CHECK_PARAMETERS(0x1000)参数校验失败检查输入参数是否正确ERR_OPERATE_DEVICE(0x2000)设备打开失败检查HAM设备是否正常加载ERR_REGISTER(0x3000)内核初始化失败检查系统内核支持ERR_MIGRATE_PAGES(0x4000)页面迁移失败检查内存状态和权限ERR_ROLLBACK_PAGES(0x5000)页面回迁失败检查源端内存状态调试技巧使用ubturbo_ham_external_log_set()设置自定义日志函数检查系统日志/var/log/messages获取更多信息使用strace跟踪系统调用验证内存地址和权限设置 最佳实践与注意事项1.内存对齐要求确保内存地址按页对齐通常4KB检查NUMA节点的内存大小匹配2.性能优化建议批量处理迁移页面减少API调用次数合理设置预复制阶段和完成阶段的切换时机监控迁移过程中的系统资源使用情况3.安全注意事项确保只有授权进程可以访问HAM设备验证所有输入参数的有效性在异常情况下及时调用回滚接口4.兼容性考虑HAM支持openEuler 22.03及以上版本需要灵衢总线硬件支持确保内核版本符合要求 学习资源与参考文档要深入了解HAM的内部实现原理和高级用法您可以参考以下资源官方API文档doc/api_docs_reference.md - 包含所有API的详细说明和示例开发者指南doc/Developer_Guide.md - 开发者的完整指南用户指南doc/User_Guide.md - 用户安装和使用指南设计文档doc/Desgin_docs_Reference.md - 系统设计参考 总结通过本文的完整指南您已经掌握了HAM API的核心使用方法。从ubturbo_ham_register的初始化到ubturbo_ham_migrate的页面迁移再到ubturbo_ham_unregister的资源清理每个接口都有其特定的用途和最佳实践。HAM项目为虚拟机热迁移提供了确定性时长的解决方案通过灵衢总线的远端内存访问能力实现了零数据副本的高效迁移。无论您是系统管理员还是开发人员掌握HAM API都将帮助您构建更加可靠和高可用的虚拟化环境。现在就开始使用HAM API为您的系统带来革命性的迁移体验吧提示在实际生产环境中使用前建议先在测试环境中充分验证迁移流程和错误处理机制。【免费下载链接】hamBased on the remote memory access capability and high bandwidth of the UB, deterministic duration virtual machine live migration is achieved, addressing planned downtime issues and ensuring system high availability.项目地址: https://gitcode.com/openeuler/ham创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考