Gnull 和 Voyd 的技术提示
大家好。我丈夫是 Chester Gnull,我是 Laverta Voyd,我是来为你们这些喜欢玩 Linux 的甜心们指路的女士。我和我的丈夫每个月都会给你们带来技术提示。我想你们肯定在想为什么我和我丈夫的姓氏不一样。嗯,Chester 不喜欢引人注目,所以他让编辑改了我们的姓,这样我们就不会收到烦人的电子邮件,也不会有人在现实生活中打扰我们。
我对 Linux 一窍不通。Chester,他很聪明,但他不太爱说话。这就是我来的原因。他做什么都离不开我,我也不介意,因为我喜欢说话,也喜欢主持。Chester 不明白我们为什么要说话,但那是编辑的要求,而且,嗯,他付钱给我们,所以我们觉得这没什么不对的。所以那些 LJ 的人会把提示发给我们,我的 Chester 负责挑选,我负责主持。而且,我说,我确实喜欢主持,但考虑到这里只是写写东西,我们就不会提供我的特色菜了,比如配香肠和真正的枫糖浆的饼干和肉汁,除了枫糖浆,其他都是自制的。但他们告诉我,这些提示对你们 Linux 用户来说也同样美味。我不太明白,但 Chester 说就是这样,我相信我的 Chester。
现在,亲爱的们,我们有一些提示要开始了。其中一个提示是编辑提供的,为了让事情顺利进行。他没有拿到 100 美元,但我想他当编辑已经足够多了。所以,我们希望你们给我们发送一些你们的提示。如果我们将您的技术提示放在这个专栏中,您将获得 100 美元。我们知道这买不到 Fleetwood 移动房屋,我说的是 Park Models 型号,甚至不是那种带两个浴室的高级 Entertainer Models 型号。但是 100 美元可以在您当地的 Piggly Wiggly 超市买到一些美味的食物。所以,甜心们,把你们的提示发过来吧,我们会非常感谢的。你们可以发送到 techtips@linuxjournal.com,编辑们会把它们转交给 Chester,剩下的就由我们来做。
这个提示使 Ubuntu 将 3ware RAID 控制器视为您系统中 Ubuntu 上的第一个串行设备。—Chester
正如您所看到的,Chester 真的很啰嗦,是吧?这就是他把我拉来做这个的原因。我的意思是,他是我爱的人,我知道,因为他会向我表达。但是偶尔说三个字也不会要了他的命,对吧,Chester?—Laverta
三个字。高兴了吗?—Chester
您可以在您的 PC 中安装 RAID 卡,并将 BIOS 配置为使 BIOS 将 RAID 卡视为您系统上的第一个 SCSI 设备。但是,Ubuntu(可能还有其他发行版)不一定会尊重您的 BIOS 设置。例如,我有一块 ASUS M2N32 WS Professional 主板,其中包括一个用于 3ware 9550SX-4LP RAID 卡的 PCI-X 插槽。我可以设置 BIOS 使该卡成为第一个设备。但是,如果我添加一个 SATA 驱动器,Ubuntu initrd 会将板载 SATA 视为系统上的第一个 SCSI 设备,尽管 BIOS 设置如此。
可能有一个内核启动参数可以覆盖此行为,但我还没有找到一个有效的。无论如何,如果仅仅是为了学习如何提取、修改 Ubuntu initrd 然后重新组装以供使用,我也喜欢以下解决方案。
以下是 Ubuntu initrd 违反 BIOS 设置的原因。Ubuntu 的 initrd 运行清单 1 中显示的脚本。
清单 1. initrd scripts/local-top/udev 文件
#!/bin/sh -e # initramfs local-top script for udev PREREQ="" # Output pre-requisites prereqs() { echo "$PREREQ" } case "$1" in prereqs) prereqs exit 0 ;; esac # Each call to udevplug can take up to three minutes if [ -x /sbin/usplash_write ]; then /sbin/usplash_write "TIMEOUT 540" trap "/sbin/usplash_write 'TIMEOUT 15'" 0 fi # Load drivers for storage controllers found on the # PCI bus; these show up the same for both IDE and # SCSI so there's no point differentiating between # the two. Do it in serial to try to provide some # predictability for which wins each time. /sbin/udevplug -s -Bpci -Iclass=0x01* # We also need to load drivers for bridges (0x06), # docking stations (0x0a), input devices (0x09), # serial devices (0x0c) and "intelligent" devices # (0x0e). This is both to support filesystems on the # end and just in case there's a keyboard on the end # and things go wrong. /sbin/udevplug -Bpci -Iclass=0x0[69ace]* # If we're booting from IDE, it might not be a PCI # controller, but might be an old-fashioned ISA # controller; in which case we need to load ide-generic. /sbin/modprobe -Qb ide-generic /sbin/udevplug -W
以下这行代码,用于发现存储控制器,恰好首先发现了 NVIDIA SATA
/sbin/udevplug -s -Bpci -Iclass=0x01*
您可以通过添加一行在这一行之前显式加载 3ware 模块的代码来强制此脚本首先找到 3ware 控制器。清单 2 显示了如何修改脚本来实现这一点(清单 2 仅是脚本相关部分的摘录)。
清单 2. 添加代码以首先发现 3ware 卡。
/sbin/modprobe 3w-9xxx # Load drivers for storage controllers found on the # PCI bus; these show up the same for both IDE and # SCSI, so there's no point differentiating between # the two. Do it in serial to try to provide some # predictability for which wins each time. /sbin/udevplug -s -Bpci -Iclass=0x01*
这强制脚本首先发现 3ware RAID 卡,并在 udevplug 发现其余 PCI 存储控制器之前将其分配为 /dev/sda。
这里的技巧是您需要解压缩 Ubuntu 默认的 initrd 文件,修改此脚本,然后重新打包并使用它来代替默认的 initrd。
以下是一种方法。这些说明假设您正在使用带有内核 2.6.15-27-amd64-generic 的 Ubuntu Dapper AMD64。如果您使用的是其他内核,则必须相应地更改命令。您可以比我更谨慎地使用这些说明,并对所有适当的命令使用 sudo。但是,我使用以下命令跳入 root shell:sudo -s -H命令,以便更容易阅读
$ sudo -s -H (enter password) # cd /root # mkdir initrd-tmp # cd initrd-tmp # gzip -dc /boot/2.6.15-27-amd64-generic | cpio -id
这将解压缩您的 initrd,以便您可以操作其内容。现在,编辑此文件。(使用您喜欢的编辑器。我以 vi 为例。)
# vi scripts/local-top/udev
这是包含清单 1 中代码的文件。如图清单 2 所示,添加 modprobe 命令。保存文件。
所有这些都假设模块 3w-9xxx 存在于您的 initrd 中。如果不存在,或者您需要在 initrd 中添加其他模块,则必须将其复制到以下位置(同样,这假设您正在使用 2.6.15-27-amd64-generic 内核 - 根据您的设置进行修改)
# cp <module> /root/initrd-tmp/lib/modules/ ↪2.6.15-27-amd64-generic/kernel/drivers/scsi
现在您需要重新打包 initrd 文件。我建议您将此 initrd 命名为与原始文件不同的名称,这样如果您做错了什么,您可以轻松地恢复到原始文件。
以下是如何将文件重新打包到新的 initrd 中。这假设您当前的工作目录仍然是 /root/initrd-tmp
# find . | cpio --quiet --dereference -o -H newc | gzip ↪-9 > /boot/2.6.15-27-amd64-generic-3w
现在更改您的引导加载程序以添加另一个引导选项以使用新的 initrd 文件。您可以替换现有的引导条目,但这很可能会带来麻烦(尽管例如 GRUB 允许您在引导时编辑引导条目,因此如果您使用 GRUB,总是有希望的)。如果您使用 GRUB,请将修改后的 initrd 指定为 initrd 映像,如下所示
initrd /boot/initrd.img-2.6.15-27-amd64-generic-3w
重新启动,并试用一下。
如果您在其他 RAID 卡(甚至其他存储卡)上遇到相同的问题,这应该适用于 3ware 以外的卡。您所要做的就是更改 /sbin/modprobe 以加载适用于您的卡的相应模块。不要忘记检查驱动程序模块是否在解压缩的 initrd 中,然后再重新打包。
我早就知道有人会遇到这个问题。你系统上的 inode 太多了,你这是在自找麻烦。这告诉你如何找出并解决它。—Chester
即使是最优秀的人也会遇到这种情况,你早上坐在电脑前,打开它,却发现它无法正常启动。经过一个小时的故障排除、诊断和抱怨后,您得出结论,您的硬盘驱动器出了问题。您想到了在这个过程中可能丢失的所有文件,并诅咒自己没有足够勤奋地备份。
大多数情况下,当您的操作系统崩溃时,您的文件仍然完好无损地保存在驱动器上;您只需要找到一种方法来访问它们。在某些情况下,您的问题可能是根分区损坏太严重而无法挂载,但并非损坏到无法恢复的程度。例如,您的根分区可能格式化为 XFS,而您只需要在分区上运行像 xfs_repair 这样的实用程序就可以使一切恢复正常。
一些发行版带有修复光盘,一些安装光盘具有修复选项。但是,您可能会发现引导到 Live CD 进行修复更有用,因为 Live CD 可能比修复光盘为您提供更多的实用程序。Knoppix 是许多 Linux Live CD 版本之一,它可以直接从 CD 运行,并允许您访问硬盘驱动器。
即使您处于最坏的情况并且必须恢复单个文件,您恢复文件或可能整个硬盘驱动器的全部内容所需要的只是 Knoppix 的副本(或您最喜欢的 Live CD 发行版)和一个便携式硬盘驱动器、U 盘或其他类型的 USB 便携式存储设备。或者,如果您的系统中有未使用的 SATA 或 IDE 插槽,您始终可以打开计算机并插入额外的驱动器(当然,要正确配置)。如果您使用便携式设备,那么便携式存储设备的大小取决于您想要保存多少内容。
仔细检查目标计算机上的 BIOS,确保将其设置为从 CD 启动。如果您的 BIOS 允许您使用 Esc 键、F8 或其他键中断启动顺序,以便选择要启动的驱动器,您甚至可能不必重新配置 BIOS。无论如何,从 CD 启动,Knoppix 应该会自动启动到桌面。
进入桌面后,剩下的就是搜索计算机的硬盘驱动器,找到要抢救的文件并传输到您的便携式媒体设备或其他内部设备。查找文件将需要您知道文件在硬盘驱动器上的位置,这将或多或少地取决于损坏的驱动器上的文件系统。
我早就知道有人会遇到这个问题。你系统上的 inode 太多了,你这是在自找麻烦。这告诉你如何找出并解决它。—Chester
系统管理员最常见的任务之一是存储管理。当您面临文件系统已满或几乎已满的情况时,最好有一些工具可供您使用,以帮助您找出“哪里”是占用大户。
搜索空间占用大户非常容易。使用一个简单的命令,您可以汇总树中每个目录(在本例中为 /usr)的内容,并查看哪些目录最大
du -k /usr/ |sort -n |tail -30 167156 /usr/include 168960 /usr/share/icons 173972 /usr/share/texmf 244332 /usr/bin 263144 /usr/lib/openoffice.org2.0 265492 /usr/share/doc 344536 /usr/share/locale 1223992 /usr/lib 1959412 /usr/share 4159996 /usr/
如您所见,/usr/share/ 和 /usr/lib/ 非常大,您可以向上滚动列表以进一步向下钻取。
一种相对罕见的情况是文件系统中的 inode 耗尽。在这种情况下,您将看到可用空间,但系统将无法写入新文件,因为它已耗尽 inode。要查找 inode 占用大户,请使用这个名为 inodu 的快速 Perl 脚本
#!/usr/bin/perl -w my $start=$ARGV[0]; foreach $object (`find '$start'`){ my @parts=split(/\//,$object); while(pop(@parts) ){ my $object = join('/',@parts); $object =~ s/\/+/\//g; $object2qty{$object}++; } } foreach $object (sort { $object2qty{$a} <=> $object2qty{$b} } keys %object2qty){ print $object2qty{$object} . "\t${object}\n"; }
这将汇总每个目录中文件系统对象的数量,并提供与前面示例非常相似的输出。像这样使用它
cd /usr ./inodu . 10420 ./include 10973 ./share/texmf 12012 ./share/man 13207 ./share/doc 14953 ./share/icons 16481 ./src/kernels 17201 ./src 22982 ./lib 105527 ./share 174270 . 174271
如您所见,share 和 lib 再次成为 inode 占用大户,使用了超过 100,000 个 inode!
如果您发现自己处于这些情况中的任何一种,那么有很多方法可以创建更多可用空间或 inode。首先,查找可以清除、移动或压缩的日志文件。要求用户清理他们的主目录。删除任何不必要的软件。如果您使用的是 Linux LVM 和 ext3fs,您可以使用 lvresize 和 resize2fs 扩展文件系统以增长文件系统。这会创建更多可用空间和 inode,但这仅在您的卷组中有可用空间的情况下才有效。如果您有可用磁盘空间,您可以创建一个新分区(例如,用于您的 /var 树),将文件移动到该分区并将其挂载为 /var。作为最后的手段,您可以移动文件和目录并使用符号链接,以便旧路径仍然有效。我说“最后的手段”是因为这种方法可能很快失控,并可能使事情变得非常混乱。
Nicholas Petreley 是 Linux Journal 的主编。
Brad Hall 与他的宠物鸡和 星际迷航:深空九号 中 Bashir 医生的真人大小纸板剪贴画一起住在佛罗里达州杰克逊维尔。
Matthew Hoskins 是新泽西理工学院的高级信息系统分析师。
Linux Journal 为我们发布的任何技术提示支付 100 美元。请将您的提示和您的联系信息发送至 techtips@linuxjournal.com。