如何解决 udev 在 gentoo 启动时未创建 /dev/hda3 的问题?

如何解决 udev 在 gentoo 启动时未创建 /dev/hda3 的问题?

我的旧 gentoo 笔记本电脑似乎有 udev 问题,可能是因为我使用 更新软件emerge,升级 udev+kernel,收到一些消息“升级 udev/kernel 后执行这些操作”并思考“我将查看屏幕输出,阅读这些消息并在重新启动系统之前处理这些事情”。不幸的是,由于有点匆忙,我当然忘记查看这些消息,关闭机器,将其物理移动到家里现在的位置并启动,结果却找不到/dev/hda3.

现在我已经设法通过手动创建/dev/hda3然后init继续系统启动来解决这个问题(下面详细描述),但我需要一些关于如何一劳永逸地解决这个问题的建议(所以我不必重复每次启动时的程序如下)。

(如果有人可以指出 Gentoo 机器上的某个地方,在那里我可以找到我已安装的软件包的所有安装后消息,那么我就可以找到那些与 udev 和我应该阅读的内核相关的说明。)

相关软件版本:

Gentoo-hardened-kernel 2.6.36-r6(首选)和 2.6.28-r9(关闭前使用了 21 个月)。下面描述的繁琐的手动启动过程已被验证适用于两个内核版本。 udev 软件包是 udev-151-r4。

启动时一切似乎都很好(机器启动内核,挂载 /proc、/sys 和 /dev,启动 udevd 并根据 uevents 填充 /dev,处理 uevents,挂载 /dev/pts),直到进入“检查根文件系统”步骤。

它在那里发出

Failed to open the device '/dev/hda3': No such file or directory

然后它要求我输入 root 密码(或按 Ctrl-D 继续)。

我输入该内容,然后在 shell 中mount告诉我 that rootfsis located on 以及 that /dev/rootis located on /。另外,mount抱怨/etc/mtab不可写(例如只读/只读文件系统)。鉴于启动尚未完成,所有这些对我来说都是有意义的。

这样做ls /dev表明没有hdahda1hda2hda3设备,它们通常应该在那里(我希望 udev 创建它们)。另外值得一提的是,也不/dev包含sdasda1sda2sda3设备,因此我们没有看到更新的 udev 或内核改变其调用不同磁盘设备的约定的问题。也不存在任何/dev/disk磁盘设备可以“隐藏”的目录。

因此,我的下一步(可能很脏)是手动创建hdahda1hda2under hda3/dev我偷看了我的其他一台 gentoo 服务器,以找出主要和次要编号以及适当的权限和组成员身份):

mknod /dev/hda b 3 0
mknod /dev/hda1 b 3 1
mknod /dev/hda2 b 3 2
mknod /dev/hda3 b 3 3
chmod 660 /dev/hda*
chgrp disk /dev/hda*

不幸的是,执行 Ctrl-D 或exit在此处写入不会继续中断的启动顺序,而是会启动重新启动(这会使计算机进入未找到状态/dev/hda),因此不幸的是,解决这个问题的途径无济于事。

我尝试了另一种解决方法(失败了),在启动后立即按“I”(以及尝试“i”)init并开始运行各种初始化脚本(如安装 /proc、/sys 等),但我从来没有在引导序列到达(失败)尝试检查 /dev/hda3 之前设法进入交互式引导模式。

相反,我继续使用我的/dev/hda3设备来挂载我的操作系统文件系统:
mount -o remount -o rw /dev/hda3 /

所以,现在我可以对我的机器的文件系统进行写访问,这给了我一些有关解决此情况的选项:修改配置文件、启动各种初始化脚本和子系统等。

做一件事不是不过,工作是改变运行级别。原因是init 3失败并出现错误消息init: /dev/initctl: No such file or directory。我再次偷看了我的另一台 Gentoo 服务器,发现这是一个具有权限且属于 的/dev/initctl管道,因此我重新创建了它:600root:root

mknod /dev/initctl p chmod 600 /dev/initctl

现在init 3失败了,但有点不同;它挂起一段时间,然后放弃该消息init: timeout opening/writing control channel /dev/initctl。这是有道理的,因为原始init进程(进程 ID 为 1)没有/dev/initctl打开新创建的进程以供读取。

现在,阅读init手册页我意识到发送SIGUSR将使initclose 并重新打开/dev/initctl确切地我需要什么,所以我执行命令来获取所有kill -l信号及其编号的列表(其中我看到SIGUSR1编号为 10),然后发出命令
kill -10 1
makereopen ,然后重试输入运行级别 3:init/dev/initctl
init 3

现在init尝试进入运行级别3并执行大量脚本。不幸的是,所有这些脚本都失败了ERROR: cannot run syslog-ng until sysinit completes。因此,我重新启动系统(现在实际上按照我所听的预期工作init/dev/initctl我登录然后root发出问题reboot),重复上述步骤(重新安装/dev/hda3为可写除外)直到并包括发送SIGUSR1到的点init。现在我试图init以更温和的方式恢复启动顺序,使其重新读取文件/etc/inittab

init q

没有什么似乎已经发生了。因此,我将调查/etc/inittab在哪里找到似乎名为 的运行级别条目sysinit。我冒险并重新运行:

init sysinit

这次init抱怨一条使用消息。再次阅读/etc/inittab,我看到该条目使用sysinit参数调用了.所以,我决定尝试一下/sbin/rcsysinit:

/sbin/rc sysinit

现在系统重试启动许多服务并成功了! 不仅如此,当重新运行用于安装的初始化脚本时/proc/sys还会/dev检查它们是否已经安装(这证明了在代码中进行健全性检查和错误检查并在遇到问题时采取相应行动是多么有价值)特殊情况下)。对此感到满意,我决定也运行该条/etc/inittab目的命令bootwait,因为该命令也缺少运行级别字母或数字。

/sbin/rc boot

同样,启动了许多初始化脚本,主要用于网络。没有报告意外错误,因此我很高兴重试进入运行级别 3:

init 3

一旦初始化脚本完成,机器就启动了,我可以作为 root 登录(理论上,可以解决这个混乱的根本原因)!

答案1

我重新编译了内核,确保既没有设置CONFIG_SYSFS_DEPRECATEDCONFIG_SYSFS_DEPRECATED_V2没有设置。

然而,经过几次CONFIG_IDE未设置的重试(以及未能找到任何硬盘驱动器的内核),事实证明我必须CONFIG_IDE 以及在已弃用的 ATA/ATAPI 支持下找到的更多内核配置选项。再次,我对其他服务器(具有正常工作的 /dev/hda 检测)进行了偷看,并添加了缺少的 ATA/ATAPI 相关内核选项。 哪个我实际上添加的选项我没有注意到,但这里是在 ATA/ATAPI 下激活的所有选项的列表: CONFIG_IDE_GD
CONFIG_IDE_GD_ATA
CONFIG_IDE_PROC_FS
CONFIG_IDE_GENERIC
CONFIG_IDE_PCIBUS_ORDER
CONFIG_BLK_DEV_GENERIC
CONFIG_BLK_DEV_PIIX

我还禁用了对串行 ATA 和并行 ATA 的支持。

所以现在我有一个可以启动并成功找到我的/dev/hda3设备的内核。

我确实知道这是一个不好的做法,依赖于已弃用的 ATA/ATAPI 内核支持和不是使用更现代的 SATA/PATA 内核支持。最终我不得不迁移到 SATA/PATA。但现在,我很高兴(并且对我的 Linux 系统有了更多的了解)。

(如果我发布一个问题然后回答它并选择我自己的答案作为被接受的答案,我深表歉意。希望这个答案/问题仍然对 U&L 是一个有用的贡献)

相关内容