776 字
4 分钟
migration_thread核心迁移线程
2025-09-01
无标签

让我为您追踪一下 migration_thread 在整个流程中的使用位置,特别是从 qmp_migrate 开始的调用链。

很好的问题!让我为您详细追踪migration_thread在整个流程中的使用位置和调用链。

🎯 migration_thread的创建位置#

migration_thread是在migrate_fd_connect()函数中被创建的:

// 在migrate_fd_connect()函数中的第3821行
if (migrate_background_snapshot()) {
    // 后台快照模式:创建后台快照线程
    qemu_thread_create(&s->thread, "bg_snapshot",
            bg_migration_thread, s, QEMU_THREAD_JOINABLE);
} else {
    // 正常热迁移模式:创建迁移线程
    qemu_thread_create(&s->thread, "live_migration",
            migration_thread, s, QEMU_THREAD_JOINABLE);  // ← 这里!
}
s->migration_thread_running = true;  // 标记迁移线程正在运行

🔗 从qmp_migrate到migration_thread的完整调用链#

📋 详细调用流程#

1. QMP命令

2. qmp_migrate()                    # QMP接口入口

3. [传输方式选择]
   ├─ socket_start_outgoing_migration()
   ├─ fd_start_outgoing_migration()
   ├─ exec_start_outgoing_migration()
   ├─ file_start_outgoing_migration()
   └─ rdma_start_outgoing_migration()

4. migration_channel_connect()      # 通道连接处理(RDMA除外)

5. migrate_fd_connect()            # ⭐ 关键转折点

6. qemu_thread_create()            # 创建线程

7. migration_thread()              # 🎯 实际的迁移工作线程

🔍 关键函数详细分析#

1️⃣ migrate_fd_connect() - 线程创建的核心#

void migrate_fd_connect(MigrationState *s, Error *error_in) {
    // ... 前期准备工作 ...
    
    // 🎯 关键决策点:创建哪种线程?
    if (migrate_background_snapshot()) {
        // 创建背景快照线程
        qemu_thread_create(&s->thread, "bg_snapshot", bg_migration_thread, s, QEMU_THREAD_JOINABLE);
    } else {
        // 🚀 创建正常迁移线程 - migration_thread在这里被启动!
        qemu_thread_create(&s->thread, "live_migration", migration_thread, s, QEMU_THREAD_JOINABLE);
    }
    s->migration_thread_running = true;
}

2️⃣ migration_thread() - 实际工作函数#

static void *migration_thread(void *opaque) {
    MigrationState *s = opaque;
    
    // 📋 线程初始化
    thread = migration_threads_add("live_migration", qemu_get_thread_id());
    rcu_register_thread();
    
    // 🔧 设置阶段
    qemu_savevm_state_header(s->to_dst_file);
    
    // 🔄 主迁移循环 - 这里执行实际的迁移工作
    while (migration_is_active()) {
        if (urgent || !migration_rate_exceeded(s->to_dst_file)) {
            MigIterateState iter_state = migration_iteration_run(s);  // 脏页迭代传输
            if (iter_state == MIG_ITERATE_BREAK) {
                break;  // 迁移完成
            }
        }
        // 错误检测和处理...
    }
    
    // 🧹 清理工作
    migration_iteration_finish(s);
    return NULL;
}

⚡ migration_thread的核心作用#

🎯 主要职责#

  1. 迁移循环控制 - 管理整个迁移过程的主循环
  2. 脏页迭代传输 - 调用migration_iteration_run()进行数据传输
  3. 速率控制 - 通过migration_rate_exceeded()控制传输速度
  4. 错误处理 - 监控和处理迁移过程中的各种错误
  5. 状态管理 - 维护迁移状态转换

🔄 与其他组件的交互#

// migration_thread中的关键调用
while (migration_is_active()) {
    // 传输控制
    MigIterateState iter_state = migration_iteration_run(s);
    
    // 错误检测
    thr_error = migration_detect_error(s);
    
    // 速率限制
    urgent = migration_rate_limit();
}

📊 线程生命周期管理#

🚀 创建#

  • migrate_fd_connect()中通过qemu_thread_create()创建
  • 设置s->migration_thread_running = true

🏃 运行#

  • 执行实际的迁移工作循环
  • 处理脏页传输和状态管理

🛑 结束#

  • 迁移完成或出错时自动退出
  • migrate_fd_cleanup()中通过qemu_thread_join()等待线程结束

✅ 总结#

migration_thread是QEMU热迁移的核心工作线程,它:

  • ✅ 创建位置:在migrate_fd_connect()函数中
  • ✅ 调用链路:qmp_migrate() → 传输方式函数 → migration_channel_connect()migrate_fd_connect()qemu_thread_create(migration_thread)
  • ✅ 核心作用:执行实际的迁移工作循环,包括脏页传输、状态管理、错误处理等
  • ✅ 生命周期:从连接建立到迁移完成的整个过程

这个线程是热迁移功能的执行引擎,负责将虚拟机状态从源端传输到目标端!

[1 tool called]

migration_thread核心迁移线程
https://scudays.github.io/posts/icsas/migration_thread/migration_thread核心迁移线程/
作者
Days
发布于
2025-09-01
许可协议
CC BY-NC-SA 4.0