mycat 实施指南_高级文件系统实施者指南,第6部分

mycat 实施指南

你准备好了吗?

在本文中,我们将完成将Linux系统转换为devfs或设备文件系统的操作。 对于那些刚刚加入devfs系列的人,请阅读本系列的第4部分,我在其中解释了devfs如何解决内核级别的设备注册难题。 然后阅读本系列的第5部分 ,我在其中介绍了使Linux系统与devfs兼容所需的所有步骤,以便您准备好最终转换为devfs。

如果您还没有阅读第5部分,那么在按照此处的说明进行操作之前非常重要。 如果您跳过第5部分中的步骤,几乎可以保证我们将要安装的init包装程序将无法正常工作,并且最终您将得到无法启动的系统,需要进行紧急复苏。 那不是好事。 但是,如果您已经阅读了第5部分,那么就可以开始了。

初始化包装器

开端

我在第5部分结束时介绍了init包装器的概念,并解释了为什么它非常适合解决一些devfs初始化问题。 事不宜迟,让我们逐步介绍完整的init包装器,看看每个部分的功能。 我们将从顶部开始:

#!/bin/bash
# Copyright 2001 Daniel Robbins <drobbins@gentoo.org>, Gentoo Technologies, Inc.
# Distributed under the GNU General Public License, version 2.0 or later.

trap ":" INT QUIT TSTP	
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
umask 022

if [ $$ -ne 1 ]
then
	exec /sbin/init.system $*
fi

如您所见,init包装器是一个真正的bash脚本,因为脚本顶部有一个#!/bin/bash 。 现在是时候提到我们的初始化包装程序要求运行bash 2.0或更高版本的好时机; 键入/bin/bash --version以查看您的bash shell是否足够新。 如果不是,则可能要查看是否已安装/bin/bash2可执行文件。 如果是这样,请将脚本的第一行更改为#!/bin/bash2

现在,让我们遍历脚本。 trap命令防止脚本在执行过程中被用户中断(例如,在引导过程中按Ctrl-C)。 然后,我们export一个合理的默认路径,并将默认umask设置为022。在引导过程中尽早设置默认umask始终是一个好主意,因为许多早期的2.4内核发行版中存在一个错误,导致默认的umask为0,这可能构成安全威胁。

接下来,我们遇到第一个条件语句if [ $$ -ne 1 ]bash$$扩展为当前正在运行的进程的进程ID,因此您可以看到我们确实在问一个问题:“我们的进程ID是否为1以外的任何数字?” 这有什么意义? 好吧,如果我们在引导过程中被内核启动,则我们将始终将PID设置为1,因为PID 1是为init过程保留的。 如果我们的PID 不为 1,那么我们就知道在系统启动后正在从命令行运行。 这很常见,因为/sbin/init命令具有双重目的,即允许超级用户更改已经引导的系统的运行级别。 如果是这种情况,我们只需exec原始的/sbin/init ,现在将其重命名为/sbin/init.system 。 我们使用$*变量将任何命令行参数传递给init.system ,我们的init包装器终止,并且init.system开始执行。

内核启动选项

但是,如果我们的包装器是在启动时由内核启动的,则bash的PID 将为 1,并且随着bash继续执行我们的包装器,此条件将被完全跳过。 说到下面几行:

mount -n /proc
devfs="yes"
for copt in `cat /proc/cmdline`
do
	if [ "${copt%=*}" = "wrapper" ]
	then
		parms=${copt##*=}
		#parse wrapper option
		if [ "${parms/nodevfs//}" != "${parms}" ]
		then
			devfs="no"
		fi
	fi
done

如果我们已经处理了这段代码,则意味着在引导过程中内核正在运行我们。 作为我们的第一要务,我们将/ proc挂接到当前是只读的根文件系统。 之后,我们执行了一大块复杂的bash代码,利用了非常方便的Linux功能。 您可能不知道这一点,但是内核允许我们通过查看/ proc / cmdline的内容来查看LILO或GRUB传递了哪些选项。 在我的开发框中,/ proc / cmdline的内容如下:

# cat /proc/cmdline
root=/dev/hda6 hda=89355,16,63 mem=524224K

上面,我们通过扫描/ proc / cmdline的存在以发现我们自己创建的内核启动变量(称为wrapper ,从而发挥其优势。 如果wrapper=nodevfs出现在内核引导选项中,则该脚本知道不启用devfs。 但是,如果此变量未出现在/ proc / cmdline中,则我们的包装器将继续进行devfs初始化。 这个故事的寓意是,您可以通过使用wrapper=nodevfs内核引导选项进行引导来轻松禁用devfs。 如果这样做, devfs变量将设置为no 。 否则,它将为yes

结语

这是包装的其余部分:

if [ "$devfs" = "yes" ]
then
 if [ -e /dev/.devfsd ] 
 then
	clear
	echo
	echo "The init wrapper has detected that /dev has been automatically mounted by"
	echo "the kernel. This will prevent devfs from automatically saving and"
	echo "restoring device permissions. While not optimal, your system will still"
	echo "be able to boot, but any perm/ownership changes or creation of new compat."
	echo "device nodes will not be persistent across reboots until you fix this"
	echo "problem."
	echo
	echo "Fortunately, the fix for this problem is quite simple; all you need to"
	echo "do is pass the \"devfs=nomount\" boot option to the kernel (via GRUB"
	echo "or LILO) the next time you boot.  Then /dev will not be auto-mounted."
	echo "The next time you compile your kernel, be sure that you do not"
	echo "enable the \"Automatically mount filesystem at boot\" devfs kernel"
	echo "configuration option.  Then the \"devfs=nomount\" hack will no longer be"
	echo "needed."
	echo
     read -t 15 -p "(hit Enter to continue or wait 15 seconds...)" 
 else	
	mount -n /dev /dev-state -o bind
	mount -n -t devfs none /dev
	if [ -d /dev-state/compat ]
	then
			echo Copying devices from /dev-state/compat to /dev
			cp -ax /dev-state/compat/* /dev
	fi
 fi
 /sbin/devfsd /dev >/dev/null 2>&1;
fi 

exec /sbin/init.system $*

现在,我们得出一个大型条件语句,该条件语句仅在devfs设置为yes时才执行。 如果不是这种情况,则将完全跳过devfs初始化,甚至不会挂载devfs。 这将导致传统的非devfs引导。

但是,如果我们要设置devfs,那么我们将深入研究该条件。 在内部,我们检查内核是否已经挂载了devfs。 我们通过检查/dev/.devfsd字符设备是否存在来完成此操作。 挂载devfs时,该设备将由内核自动创建,并且我们未来的devfsd进程将使用该设备与内核进行通信。 如果已经安装了devfs(因为用户选择了“在启动时自动安装devfs”内核选项),我们将打印出一条信息性消息,让用户知道我们将无法设置devfs的持久性功能,因为如果devfs 尚未被内核挂载,则只能这样做。

设备持久性

但是,如果一切正常,我们将执行上一篇文章结尾介绍的devfs设置:/ dev绑定安装到/ dev-state,而devfs文件系统安装在/ dev上。 然后,我们执行一个我没有提到上一篇文章的步骤; 我们检查是否存在/ dev-state / compat目录,然后将其内容递归复制到/ dev。 尽管此过程乍看起来似乎有点多余(我们将利用devfsd的设备持久性功能,对吗?),这确实是必要且有用的。 之所以需要一个compat目录,是因为devfsd的持久性功能只能与启用了devfs的驱动程序一起使用 。

因此,如果碰巧正在使用非devfs内核模块,则需要在/ dev中手动创建设备节点。 这种方法的问题在于, devfsd将忽略此新设备节点,这意味着下次重新启动时,它将消失。 我们对这个问题的解决方案是拥有/ dev-state / compat目录。 如果您有一个非devfs模块,只需在/ dev-state / compat中创建您的老式设备节点,由于我们方便的初始化包装程序的周全步骤,它们将在启动时手动添加到devfs文件系统中。

最后,我们启动devfsd ,然后退出条件并exec 真正的 init /sbin/init.system以开始标准的系统引导过程。 好吧,除了我们现在已经拥有支持devfs的系统之外,所有的东西都是标准的! :)

初始化包装器安装

这是我们如何安装初始化包装器的方法。 首先, 获取wrapper.sh的源代码 ,并将其保存在系统中的某个位置。 然后,执行以下操作:

# cd /sbin
# cp init init.system
# cp /path/to/wrapper.sh init
# chmod +x init

初始化包装器现在就位。

调整量

通过使用初始化包装器,我们避免了很多复杂的初始化脚本调整。 但是,可能有一项我们无法避免的调整。 既然我们已经在/ dev挂载了devfs文件系统,那么您的rc脚本可能会很难卸载根文件系统。 幸运的是,有一个简单的解决方案。 只需grep你的rc脚本目录中所有出现的umount通过键入cd /etc/rc.d; grep -r umount * cd /etc/rc.d; grep -r umount *cd /etc/init.d; grep -r umount * cd /etc/init.d; grep -r umount *取决于特定发行版的rc脚本的安装位置。 然后,在每个引用umount脚本中,确保使用-r选项调用它。 特别重要的是用于umount根文件系统的特定umount命令,尽管在整个地方都使用umount -r也可以。 :)

如果卸载失败,则-r选项告诉umount尝试将文件系统重新安装为只读。 这足以使根文件系统进入一致状态,并使其准备好重新启动,即使由于/ dev上的现有挂载而无法将其卸载也由于打开的设备节点而无法自行卸载它时也是如此。

现在,我们几乎可以重新启动了。 但是在进行此操作之前,我们先来看一下devfsd并鞭打/etc/devfsd.conf,以便启用兼容设备和设备持久性。 不用担心,我们离完成向devfs的过渡仅一步之遥。

devfsd.conf

将/etc/devfsd.conf加载到您喜欢的编辑器中。 这是我推荐的devfsd.conf的前四行:

REGISTER        .*              MKOLDCOMPAT
UNREGISTER      .*              RMOLDCOMPAT
REGISTER        .*              MKNEWCOMPAT
UNREGISTER      .*              RMNEWCOMPAT

以上四行分别由一个事件 ( REGISTERUNREGISTER ),一个正则表达式( .* )和一个动作( *COMPAT字符串)组成。 那么,它们全都意味着什么呢? 第一行告诉devfsd在内核中注册了任何设备( .*是将与任何设备匹配的正则表达式)时执行MKOLDCOMPAT操作。 MKOLDCOMPAT操作内置于devfsd ,可以理解为“制造与通过devfs注册的设备相对应的任何旧兼容设备”。 您可能已经发现,在设备注销时运行的RM*COMPAT操作会导致这些特殊兼容性设备神奇地消失。 总的来说,这四行代码指示devfsd在设备注册时创建兼容性设备(如果有),并在设备未注册时删除兼容性设备。 由于这些行,当IDE设备驱动程序向系统注册/dev/ide/host0/bus0/target0/lun0/disc devfs样式的设备时, devfs自动创建一个匹配的/dev/hda兼容性样式的设备。 这对于诸如mountfsck命令可能正在读取包含旧式设备名称的/ etc / fstab极为有用。 通常,兼容性设备的创建使向devfs的过渡是无缝的。 我的devfsd.conf中的下一行是:

模块自动加载

LOOKUP          .*              MODLOAD

该条目告诉devfsd每当“查找”任何设备( .* )时执行MODLOAD操作,这是当程序寻找特定设备节点的存在时发生的情况。 MODLOAD操作将导致执行modprobe /dev/mydev ,其中/ dev / mydev是特定进程试图查找的设备的名称。 借助此功能(连同正确配置的/etc/modules.conf一起使用),可以在启动音乐播放器和其他整洁的东西时按需自动加载声卡驱动程序。

设备持久性

这是我的devfsd.conf的以下几行:

REGISTER        ^pt[sy]/.*      IGNORE
CHANGE          ^pt[sy]/.*      IGNORE
REGISTER        .*              COPY    /dev-state/$devname $devpath
CHANGE          .*              COPY    $devpath /dev-state/$devname
CREATE          .*              COPY    $devpath /dev-state/$devname

接下来的几行告诉devfsd使用/ dev-state作为任何设备许可或所有权更改以及用户可能创建的任何新兼容性设备的存储库。 在前两行中,当在内核中注册了任何伪终端设备或更改了它们的属性时,我们明确告诉devfsd不要执行任何特殊操作。 没有这些行,伪终端的权限和所有权将在重新启动后保留下来。 这不是最佳选择,因为在系统启动后,我们应该始终在伪终端设备上拥有一组新的默认权限。

接下来的三行打开所有其他设备的/ dev-state持久性。 具体来说,当设备注册或启动devfsd本身时,我们将从 / dev-state恢复所有属性(以及在任何现有的兼容设备上进行复制),并且我们将立即备份对属性的任何更改以及任何新的-将兼容设备创建为/ dev-state。

功能和符号链接

为了完成我的devfsd.conf,我有以下几行:

REGISTER        ^cdrom/cdrom0$          CFUNCTION GLOBAL symlink cdroms/cdrom0 cdrom
UNREGISTER      ^cdrom/cdrom0$          CFUNCTION GLOBAL unlink cdrom
REGISTER        ^misc/psaux$            CFUNCTION GLOBAL symlink misc/psaux mouse
UNREGISTER      ^misc/psaux$            CFUNCTION GLOBAL unlink mouse

最后四行是可选的,但是值得一看。 虽然/ dev-state持久性在设备节点上的工作非常出色,但它对符号链接完全没有影响,而符号链接被忽略了。 因此,这引发了一个问题:如何确保/ dev / mouse或/ dev / cdrom符号链接不仅存在,而且在重新启动后保持不变? 对我们来说幸运的是, devfsd是非常可配置的,这四行代码(或类似的东西,已针对您的特定系统定制)将达到目的。 在注册/ dev / cdrom / cdrom0设备时,前两个指令devfsd会创建一个/ dev / cdrom符号链接。 为此, devfsd实际上对指定的libc函数(在本例中为symlink()unlink()执行动态调用。 在/ dev / misc / psaux(PS / 2鼠标)设备注册到devfs时,文件的最后两行使用相同的方法来创建/ dev / mouse符号链接。 自定义这些行到您的系统,然后保存此文件。 如果愿意,可以下载此devfsd.conf以在您自己的系统上使用。

重新启动前的注意事项

重新启动之前,您可能需要查看Richard Gooch的devfs常见问题; 你可能会发现关于devfs的命名方案特别有用当你与新样式的设备名称(见熟悉的信息相关主题下文)。 我还建议您打印本系列第5部分的副本,以防需要使用我的“紧急bash抢救”说明来解决与引导相关的问题。 请记住,如果由于某种原因新的初始化包装器被炸毁,则可以始终按照我的紧急救援说明将其删除,将根文件系统重新安装为可读写,然后执行以下步骤:

# cd /sbin
# mv init wrapper.sh
# mv init.system init

执行完这些步骤,将文件系统重新安装为只读并重新引导后,系统将恢复为预包装状态。 现在继续,重新启动,并享受devfs!


翻译自: https://www.ibm.com/developerworks/opensource/library/l-fs6/index.html

mycat 实施指南

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值