在 Ubuntu 12.04 系统中,我们想使用 中生成的 udev 规则来配置(物理)网络接口的名称(例如 eth0、eth1 等)/etc/udev/rules.d/70-persistent-net.rules
。虽然启动介质是只读的,但我们仍希望能够持续(重新)配置这些规则以供将来启动(例如更换网卡后)。为了持久性,我们希望将规则存储到(可写的)本地硬盘(不同于只读启动介质)。
问题似乎是,如何尽早通知 udev 有关存储的规则:显然,在安装存储规则的本地硬盘之前,这不可能发生。安装磁盘取决于 udev 识别本地硬盘设备。同时,udev 还会识别网络接口并触发其配置(可能在本地硬盘的规则生效之前)。
在启动期间如何正确协调所需的初始化?
答案1
我们当前的解决方案使用三个新的 upstart 作业,似乎有效(请评论):
我们使用一个新的 upstart 任务
/etc/init/hold-interfaces.conf
来延迟网络接口的配置(在 upstart 作业中/etc/init/network-interface.conf
),直到存储的网络规则被安装(到/etc/udev/rules.d/71-persistent-net.rules
,其中/etc/
在期间被覆盖initrd/init
以tmpfs
实现可写性)。# /etc/init/hold-interfaces.conf start on starting network-interface and started mark-configured instance holding${INTERFACE:+/}${INTERFACE:-} task exec :
条件
start on
要求starting network-interface
。这是禁止 upstart 作业在未修改现有作业文件(在本例中/etc/init/network-interface.conf
)的情况下启动的常用方法,参见。新贵食谱。由于作业将有单独的实例
network-interface
(每个接口一个),因此也必须有相应的实例hold-interfaces
。因此,instance
声明(类似于在中找到的声明/etc/init/network-interface-security.conf
)。条件
start on
还要求started mark-configured
。这表示网络规则已更新,允许继续初始化接口。无法直接等待发出 upstart 事件:此类事件仅允许 的单个实例hold-interfaces
继续。建议的解决方法是使用专用 upstart 作业模拟某种持久事件,在本例中/etc/init/mark-configured.conf
(参见LP:#447654)。
新的 upstart 作业
/etc/init/mark-configured.conf
提供了所有网络配置文件已更新的持久指示:start on network-rules-ready task exec :
- 单个事件
network-rules-ready
足以启动此作业。此后,作业mark-configured
将被称为 ,started
它将释放 的等待实例,hold-interfaces
从而释放 的等待实例network-interface
。
- 单个事件
第三个新的 upstart 作业
/etc/init/configure_interfaces.conf
安装网络规则,停止延迟network-interface
作业(因为它们可能使用旧网络规则的配置数据启动),发出释放事件并重新触发所有添加网络设备的 udev 事件。# /etc/init/configure_interfaces.conf start on local-filesystems task script find_and_mount_local_hard_disk # abbreviated install_stored_rules_and_other_network_configurations # abbreviated udevadm control --reload-rules # Stop all active network-interface upstart jobs (with data from old rules) stop_active_network_interface_jobs # abbreviated, using: initctl stop network-interface <interface> # Allow next network-interface jobs # (with data from stored rules) to complete. initctl emit --no-wait network-rules-ready # Trigger udev recognition. udevadm trigger --action='add' --subsystem-match='net' end script
在测试系统(具有三个网络接口)上,这似乎有效。另一方面,我们不确定它是否有时会失败/至少在其他系统上失败:
find_and_mount_local_hard_disk
是否能保证运行时所有本地硬盘设备都可用?是否存在竞争条件,可能导致某些网络设备无法被识别?(例如:在读取新的 udev 规则之前,内核可能会将新设备传递给 udev,以便它
network-interface
使用旧规则启动 upstart 作业。upstart 可能需要一段时间才能识别此作业并停止它。是否有可能同时加载 udev 新规则,停止network-interface
作业会错过新出现的作业,并且发出信号network-rules-ready
,以便稍后仍使用旧属性启动设备?)/etc/init/network-interface-security.conf
如何适当延迟/控制新启动的作业?是否应延迟/重新触发其他作业或事件?/etc/init/network-interface-security.conf
如果受影响的网络配置安装得足够早(与网络规则一起),则应该适当延迟这些作业。- 此外,如果任何被保留的接口配置为
auto
,/etc/network/interfaces
这将延迟信号static-network-up
(/etc/network/if-up.d/upstart
在所有auto
接口启动后由 发出)。因此,大多数依赖网络的作业应该适当延迟,包括启动 SysV init 脚本(由 触发/etc/init/rc-sysinit.conf
)。
还有其他问题吗?
(有没有更简单的方法可以通过内核、udev、upstart 或其他功能延迟所有网络设备(和相关启动任务)的配置,直到本地硬盘挂载并且新的网络规则生效之后?)