处理qvm终止

Posted by Underdog Linux on October 18, 2023

您可以注册以在 qvm 进程实例终止时收到通知,以便您可以采取适当的操作来响应终止。

更多关闭guest的信息,参考Booting and Shutting Down章节的Shutting down guests

受控终止

您可以编写一个极简的 vdev,当其 qvm 进程实例即将终止时,它可以启动适当的操作; 例如,因为其guest已关闭或变得无响应。

下面的示例来自虚构的 vdev qvmterm,它仅包含一个控制函数,仅当其 qvm 进程实例终止时才注册以接收回调。

仅当 qvm 进程实例终止时才会调用 vdev 的控制函数:

qvmterm_control(vdev_t *vdp, unsigned const ctrl, const char *const arg) {
	struct term_state *state = vdp->v_device;

	switch (ctrl) {
		
		case VDEV_CTRL_TERMINATE:
		// qvm已经终止
		// 对 vdev 进行任何必要的清理:结束它创建的所有工作线程、关闭其与后端驱动程序的连接等。
		// 在此示例中,配置 guest 虚拟机时,此 vdev 通过 vdev_thread_create() 函数创建了一个工作线程
		// (VDEV_CTRL_GUEST_CONFIGURED message block).
		// 结束线程
		pthread_cancel(state->thread); 
		pthread_join(state->thread, NULL);
		break;
	}

vdev 使用控制函数和安全变量要求填充其工厂结构 (qvmterm_factory),仅此而已:

qvmterm_register(void) {
	static struct vdev_factory qvmterm_factory = {
		    .next = NULL, // patched
		    .control = qvmterm_control,
		    .vread = NULL,
		    .vwrite = NULL,
		    .option_list = NULL,
		    .name = NULL, // patched
	    	.factory_flags = VFF_NONE,
		    .acc_sizes = 1u << 1,
		    // Make sure we have local data space for our internal structure.
		    .extra_space = sizeof(struct qvmterm_state),
		    // For the safety version of vdev-qvmterm, we require safety.
	    	// For the non-safety version we do not require safety.
		    //.safety = VDEV_SAFETY_SELECTED,
	};

	vdev_register_factory(&qvmterm_factory, QVM_VDEV_ABI);
}

有关编写 vdev 和 vdev API 的更多信息,请参阅:

虚拟机crash

要管理紧急 qvm 流程实例终止以响应未知状态,您可以在处理终止的 qvm 外部运行hypervisor 主机进程。 此进程包括执行system cleanuphardware shutdown tasks的代码,这些任务将在上述虚构的 vdev qvmterm 中的 VDEV_CTRL_TERMINATE 消息块中进行处理。

有关 qvm 退出代码的清单,参考Monitoring and Troubleshooting章节的qvm exit codes