[CRIU]tty: Can't open 9 (index 0): Bad file descriptor" occurred in the restoring step

本文介绍了解决在使用CRIU进行LXC容器快照时遇到的错误的方法,通过修改容器内的文件系统挂载配置并手动卸载部分文件系统来避免错误的发生。

在利用CRIU来dump LXC时会出现类似如下的错误:

 (00.266862) 1: Error (tty.c:614): tty: Can't open 9 (index 0): Bad file descriptor 

出现这个问题的原因是index为0 的一个终端可能正在被使用,解决方法是挂载/dev/pts时使用newinstance 选项,这个在linux内核源代码里的有关devpts的文档有详细说明,newinstance就是为了linux container而存在的,这样linux container中的tty实例就不会和host或其他的container共享。这个有点类似于namespace的功能,不能instance中的index相互独立。具体做法是在container运行之前删掉/dev/ptm:

rm /path_to_ct/dev/ptmx

然后在container中的/etc/fstab 文件中追加如下语句: 

devpts /dev/pts devpts rw,newinstance,ptmxmode=0666 0 0 


然后进入ssh进入container中执行如下操作:

rm /dev/ptmx 
ln -s /dev/pts/ptmx /dev/ptmx 

另外 CRIU只能操作container中的特定的文件系统,在执行dump操作时,那些不支持的文件系统要手动umount掉,目前ubuntu 容器中需要umount掉的文件系统有如下: 

umount /sys/fs/fuse/connections/ 
umount /sys/kernel/debug/ 
umount /sys/kernel/security/
umount /sys/fs/pstore/

原来准备将以上命令放于一个脚本中执行,虽然执行成功,但是还会出现上述错误,看来只能在命令行一条条的执行了:

sudo rm /dev/ptmx 
sudo ln -s /dev/pts/ptmx /dev/ptmx 
不知道是什么原因,为什么在脚本里执行成功了却没有效果,知道的人可以一起探讨一下。



<think>我们正在解决EGLFS报错"Failed to open /dev/fb0"和"Can&#39;t continue without a display"的问题。根据引用[1],我们知道FrameBuffer(/dev/fb0)的问题可以通过设置环境变量来使用libggi解决。此外,还需要考虑FrameBuffer是否已启用以及权限问题。 步骤: 1. 确认FrameBuffer已启用:检查内核是否支持FrameBuffer以及是否已加载相应模块。 2. 检查/dev/fb0设备是否存在,以及当前用户是否有访问权限。 3. 设置环境变量,使用libggi作为显示接口(如引用[1]所示)。 4. 对于使用EGLFS的Qt应用程序,我们可能需要指定平台插件为eglfs,并设置相关环境变量。 具体操作: 1. 检查FrameBuffer: 运行命令:`ls /dev/fb*` 查看是否存在fb设备。如果不存在,可能需要加载内核模块。 例如,加载模块:`modprobe fbcon`(可能会自动加载相关fb模块)。 2. 权限问题: 将当前用户加入video组(通常fb设备属于video组): `sudo usermod -aG video [username]` 然后注销重新登录,或者重启。 3. 设置环境变量: 对于使用libggi的情况(如引用[1]): 在用户主目录的.bash_profile(或.bashrc)中添加: export GGI_DISPLAY="display-fbdev:-noinput" 然后执行:`source ~/.bash_profile` 或重新登录。 4. 对于Qt应用程序,我们通常设置: 在运行程序前设置环境变量: export QT_QPA_PLATFORM=eglfs export QT_QPA_EGLFS_INTEGRATION=eglfs_kms # 或者eglfs_kms,取决于系统,也可以不设置 但是,如果出现无法打开/dev/fb0,也可以尝试使用其他集成方式(如kms)或者使用FrameBuffer后端。 5. 如果上述方法无效,可以考虑直接指定FrameBuffer设备: export QT_QPA_EGLFS_FB=/dev/fb0 # 或者尝试其他fb设备,如fb1 6. 检查是否有多用户登录占用了显示(如tty7上的图形界面),如果是,可以尝试切换到其他tty运行。 7. 如果系统没有FrameBuffer设备,可能需要在内核中启用FrameBuffer支持。 8. 另外,检查是否有其他进程占用了FrameBuffer设备,可以使用`fuser /dev/fb0`查看。 注意:EGLFS通常需要直接访问GPU,因此还需要确保GPU驱动已正确安装(如树莓派的vc4,Intel的i915等)。 总结: 首先确保FrameBuffer设备存在且可读,然后设置环境变量。如果使用libggi,则设置GGI_DISPLAY;如果使用Qt,则设置Qt相关的环境变量。 如果问题仍然存在,可能需要查看具体的错误日志,或者尝试使用其他平台插件(如linuxfb)来测试。 由于引用中没有直接提到Qt的EGLFS,但提到了FrameBuffer的开启和libggi的使用,我们可以参考其思路:确保FrameBuffer可用,然后通过环境变量指定显示接口。 另外,引用[3]是一段代码,似乎与图形尺寸检查有关,但与我们当前问题关系不大。 因此,针对用户的问题,我们主要参考引用[1]的方法,并结合Qt的常见设置。 最终,给出一个综合性的解决方案: 步骤一:检查FrameBuffer设备 - 运行命令:`ls -l /dev/fb*` 确认设备存在且权限正确(通常为crw-rw----,属于video组)。 - 如果没有,检查内核配置并加载模块(如modprobe fbtft,具体模块名取决于硬件)。 步骤二:添加用户到video组并重启(如果权限不足) 步骤三:设置环境变量 - 如果应用程序使用libggi,则设置GGI_DISPLAY(如引用[1]所示)。 - 对于Qt应用程序,设置: export QT_QPA_PLATFORM=eglfs export QT_QPA_EGLFS_INTEGRATION=none # 或者eglfs_kms,可以尝试不同值 export QT_QPA_EGLFS_FB=/dev/fb0 # 指定fb设备 步骤四:如果上述设置后仍然无效,可以尝试以root权限运行(仅用于测试权限问题,生产环境应避免)。 步骤五:检查Qt的文档,确认是否支持当前硬件平台。 注意:在某些嵌入式平台上(如树莓派),可能需要额外的配置,比如在config.txt中启用GPU等。 如果用户是在树莓派上运行,可能需要设置: export QT_QPA_EGLFS_PHYSICAL_WIDTH=... # 物理尺寸(毫米) export QT_QPA_EGLFS_PHYSICAL_HEIGHT=... 或者指定显示旋转等。 由于引用中没有提供更多关于硬件的信息,我们给出通用解决方案。 最后,生成相关问题: </think>针对 EGLFS 报错 `Failed to open /dev/fb0` 和 `Can&#39;t continue without a display` 的问题,以下是系统级解决方案,结合 FrameBuffer 配置和权限管理: --- ### **解决方案** #### 1. **启用 FrameBuffer 支持** - 加载内核模块: ```bash sudo modprobe fbtft dma=1 # 启用 FrameBuffer 和 DMA 加速 sudo modprobe fbcon # 加载 FrameBuffer 控制台 ``` - 确保设备节点存在: ```bash sudo mknod /dev/fb0 c 29 0 # 手动创建设备节点(主设备号29) sudo chmod 0666 /dev/fb0 # 开放读写权限 ``` #### 2. **配置环境变量** 在用户配置文件(如 `~/.bashrc` 或 `~/.profile`)中添加: ```bash export GGI_DISPLAY="display-fbdev:-noinput" # 强制使用 FrameBuffer 输出[^1] export QT_QPA_PLATFORM=eglfs # 指定 Qt 使用 EGLFS 后端 export QT_QPA_EGLFS_FB=/dev/fb0 # 显式绑定到 fb0 设备 ``` 执行 `source ~/.bashrc` 生效。 #### 3. **用户权限配置** - 将用户加入 `video` 和 `input` 组: ```bash sudo usermod -aG video,input $(whoami) ``` - 重启或重新登录激活组权限。 #### 4. **验证 FrameBuffer 状态** ```bash ls -l /dev/fb* # 检查设备权限(应为 crw-rw----) cat /proc/fb # 查看激活的 FrameBuffer 设备 fbset -fb /dev/fb0 -i # 检查当前显示模式 ``` 若输出包含 `fb0` 且分辨率正确,则配置成功。 #### 5. **调试 EGLFS** - 启用详细日志: ```bash export QT_LOGGING_RULES="qt.qpa.*=true" ``` - 检查错误日志: ```bash journalctl -b --grep="eglfs" # 检索内核日志中的 EGLFS 错误 ``` --- ### **关键原理** 1. **`/dev/fb0` 访问失败**: - 权限不足(需 `video` 组权限)或设备未创建(需 `modprobe` 加载驱动)。 - 解决方案:权限配置 + 手动创建设备节点[^1][^2]。 2. **`Can&#39;t continue without a display`**: - EGLFS 未找到有效显示接口(需绑定 FrameBuffer)。 - 解决方案:通过 `GGI_DISPLAY` 强制指定 `fbdev` 后端[^1]。 3. **尺寸校验问题**: - 引用[^3]中代码表明,目标显示区域尺寸必须 ≥ 源区域尺寸,需确保分辨率匹配: ```c if (dst->x2 - dst->x1 < src->x2 - src->x1 || ...) return -EINVAL; // 尺寸不匹配返回错误 ``` 通过 `fbset` 调整分辨率(如 `fbset -xres 1280 -yres 720`)。 --- ### **问题排查流程图** ```mermaid graph TD A[报错 /dev/fb0 失败] --> B{检查 /dev/fb0 存在?} B -- 否 --> C[加载内核模块 + 创建设备] B -- 是 --> D{用户权限?} D -- 无 --> E[加入 video 组] D -- 有 --> F{分辨率是否匹配?} F -- 否 --> G[用 fbset 调整] F -- 是 --> H[配置 GGI_DISPLAY 变量] H --> I[验证 EGLFS 日志] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值