QEMU是如何以后台进程运行的?

本文分析了QEMU被libvirt启动后如何转换为后台进程的详细过程,包括信号处理、进程名设置、数据目录查找、PID文件创建、内存锁定以及信号处理函数的配置等步骤。QEMU通过os_daemonize()函数实现后台化,os_set_proc_name()用于更改进程名称,os_mlock()用于内存锁定防止交换到外存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


当使用libvirt启动QEMU后,QEMU进程便成为后台进程在运行,刚刚分析了QEMU启动的代码,将其转换为daemon进程的过程简单解释如下(QEMU-2.3.0):


1 概述

  QEMU在被libvirt启动的时候,可以传入一些参数来设置QEMU进程的运行状态,主要参数有:-runas指定以某个用户的权限运行虚拟机、-chroot改变当前QEMU的工作根目录、-daemonize让QEMU以后台进程的形式运行。
  主要的参数解析工作为函数os_parse_cmd_args(),通过系统调用getpwnam得到用户的相关信息,并赋值给变量user_pwd;得到工作根目录的字符串,并赋值给变量chroot_dir;如果是后台进程,则将变量daemonize赋值为1.
除了以上QEMU进程状态外,还有信号设置、进程名字更改、改变回话ID等。

2 启动代码分析

在main函数中,关于设置QEMU运行状态的参数的调用顺序如下:

os_setup_early_signal_handling() 2815
os_daemonize() 3772
parse_name() -> os_set_proc_name() 3783
os_find_datadir 3857
qemu_create_pidfile 4019
os_set_line_buffering 4110
realtime_init() -> os_mlock() 4228
os_setup_signal_handling 4292
os_setup_post 4354
2.1 os_setup_early_signal_handling()

代码如下:

void os_setup_early_signal_handling(void)
{
    struct sigaction act;
    sigfillset(&act.sa_mask); //初始化信号集合,将所有的信号加入集合中。
    act.sa_flags = 0; 
    act.sa_handler = SIG_IGN; //忽略所选信号。
    sigaction(SIGPIPE, &act, NULL);
}

  忽略信号SIGPIPE,

### 如何在Termux中使用Docker和QEMU #### 安装必要的依赖项 为了能够在Termux环境中运行Docker以及模拟其他架构,首先需要安装一些基础工具。这包括但不限于`proot`、`qemu-user-static`以及其他辅助软件包。 ```bash pkg update && pkg upgrade -y pkg install proot-distro wget curl tar qemu-user-static ``` 上述命令会更新并升级现有的软件包列表,并安装用于创建不同Linux发行版环境的支持程序和其他必需组件[^1]。 #### 设置Proot-Distro来支持容器化应用 由于Android系统的特殊性质,在其上直接操作内核模块受到诸多限制,因此借助于`proot-distro`可以绕过这些约束条件从而更方便地部署各种服务端应用程序。 启动一个新的基于Debian的虚拟系统作为后续工作的基底: ```bash proot-distro install debian echo "deb http://httpredir.debian.org/debian buster-backports main contrib non-free" \ >> $PREFIX/etc/apt/sources.list.d/backports.list proot-distro login debian ``` 这里选择了较稳定的版本之一——Buster,并启用了回溯仓库以便获取最新特性与修复补丁[^2]。 #### 配置Docker引擎及其关联组件 进入新建立好的debian实例内部继续完成剩余部分的工作流程;具体来说就是下载官方提供的二进制文件而非传统的APT源方式因为后者可能无法正常工作在此类受限环境下。 执行如下脚本以自动化整个过程: ```bash version="20.10.7" arch=$(uname -m) mkdir -p ~/docker/bin cd ~/docker/bin wget https://download.docker.com/linux/static/stable/${arch}/docker-${version}.tgz tar zxvf docker-${version}.tgz --strip-components=1 rm docker-${version}.tgz chmod +x dockerd docker ln -sf $(pwd)/dockerd ${PREFIX}/bin/dockerd ln -sf $(pwd)/docker ${PREFIX}/bin/docker ``` 这段代码片段负责从互联网拉取指定版本号下的静态编译版Docker套件并将之放置到合适的位置供以后调用。 #### 启动Docker守护进程并与主机网络隔离 考虑到安全性和稳定性因素,默认情况下应该让容器化的进程独立运作而不干扰宿主设备上的任何资源。为此可以通过下面的方法开启后台监听模式同时绑定特定地址范围内的接口。 ```bash nohup dockerd --data-root=$HOME/.local/share/docker/ & disown %1 sleep 5s ``` 此时已经具备了基本的功能框架,但是针对某些特殊的场景比如跨平台镜像构建还需要额外加载相应的CPU仿真器插件才能顺利开展下一步动作。 #### 使用QEMU进行多架构兼容处理 当涉及到非本地体系结构的应用打包时,则离不开强大的硬件抽象层所提供的帮助。对于ARM系列而言,只需简单几步就能达成目的。 先确认当前是否已存在合适的翻译库: ```bash docker run --privileged multiarch/qemu-user-static:register --reset ``` 如果一切正常的话就不会有任何输出信息返回给终端界面。这意味着现在起无论何时只要遇到不匹配的目标机器描述符都会自动激活对应的解释机制进而保障指令集之间的无缝转换。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值