712 字
4 分钟
未命名
让我帮您追踪 s->threshold_size = expected_bw_per_ms * migrate_downtime_limit();
这行代码的调用链。
[6 tools called]
让我为您详细追踪 s->threshold_size = expected_bw_per_ms * migrate_downtime_limit();
这行代码的完整调用链。
🔗 完整调用链追踪
📍 代码位置
// 在migration_update_counters()函数中,第3190行
s->threshold_size = expected_bw_per_ms * migrate_downtime_limit();
🎯 调用链分析
1️⃣ 所在函数: migration_update_counters()
static void migration_update_counters(MigrationState *s, int64_t current_time)
{
uint64_t transferred, transferred_pages, time_spent;
uint64_t current_bytes;
uint64_t switchover_bw;
double expected_bw_per_ms;
double bandwidth;
// ... 计算实际传输带宽 ...
if (switchover_bw) {
// 如果用户指定了切换带宽,使用用户指定值
expected_bw_per_ms = switchover_bw / 1000;
} else {
// 如果用户没有指定,使用估算的带宽
expected_bw_per_ms = bandwidth;
}
// 🎯 关键代码:动态计算阈值
s->threshold_size = expected_bw_per_ms * migrate_downtime_limit();
// ... 更新其他统计信息 ...
}
2️⃣ 调用者 1: migration_rate_limit()
bool migration_rate_limit(void)
{
int64_t now = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
MigrationState *s = migrate_get_current();
bool urgent = false;
migration_update_counters(s, now); // ← 调用位置
// ... 速率限制逻辑 ...
}
3️⃣ 调用者 2: bg_migration_thread()
static void *bg_migration_thread(void *opaque)
{
// ... 初始化 ...
while (migration_is_active()) {
MigIterateState iter_state = bg_migration_iteration_run(s);
// ... 迭代处理 ...
// 直接调用更新计数器
migration_update_counters(s, qemu_clock_get_ms(QEMU_CLOCK_REALTIME)); // ← 调用位置
}
// ... 清理 ...
}
4️⃣ 最终调用者: migration_thread()
static void *migration_thread(void *opaque)
{
// ... 设置阶段 ...
// 主迁移循环:持续迁移直到完成或失败
while (migration_is_active()) {
if (urgent || !migration_rate_exceeded(s->to_dst_file)) {
MigIterateState iter_state = migration_iteration_run(s);
// ... 处理迭代结果 ...
}
// ... 错误检测 ...
urgent = migration_rate_limit(); // ← 这里调用migration_rate_limit()
}
// ... 清理 ...
}
🔄 完整调用链路图
QMP命令: migrate
↓
qmp_migrate()
↓
[传输方式选择]
↓
migration_channel_connect()
↓
migrate_fd_connect()
↓
qemu_thread_create(&s->thread, "live_migration", migration_thread, s, ...)
↓
migration_thread() # 主迁移线程
↓
while (migration_is_active()) { # 主循环
↓
migration_iteration_run() # 执行迁移迭代
↓
migration_rate_limit() # 速率控制检查
↓
migration_update_counters() # 更新统计信息
↓
s->threshold_size = expected_bw_per_ms * migrate_downtime_limit(); # 🎯 目标代码
}
⚡ 调用时机和频率
🕐 何时调用
每个迁移迭代后: 在
migration_thread
的主循环中速率限制检查时: 通过
migration_rate_limit()
间接调用背景迁移时: 在
bg_migration_thread
中直接调用
📊 调用频率
高频调用: 每次迁移循环迭代都会调用
实时更新: 根据当前网络状况动态调整阈值
自适应机制: 带宽变化时立即反映到阈值计算中
🎯 调用目的
动态阈值调整: 根据实际传输性能更新停机阈值
带宽估算: 基于实际传输速度或用户配置计算期望带宽
性能统计: 更新迁移性能指标(mbps、pages_per_second 等)
💡 关键理解
这行代码的核心作用是:
实时调整: 在迁移过程中动态调整停机阈值
自适应性: 根据网络状况和传输性能自动优化
精确控制: 确保停机时间在用户设置的限制范围内
这就是为什么 QEMU 热迁移能够在不同网络环境下都能保持较好的停机时间控制!