Задержка назначения IP-адреса до тех пор, пока устройство сетевого адаптера не станет доступным
Я работаю над собственной встроенной платой с тремя интерфейсами Ethernet:
- eth0 и eth1 встроены в процессор (TI AM3356)
- eth2 сделан с помощью встроенного чипа LAN9512 (с использованием драйвера smsc95xx), подключенного через USB
При загрузке я хочу вызвать eth0 и eth1 без IP-адреса (они используются для промышленного Ethernet), и вызвать eth2 с IP-адресом (он используется для стандартной сетевой связи).
мой /etc/network/interfaces
Изначально выглядело так:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet manual
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down
auto eth1
iface eth1 inet manual
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down
auto eth2
iface eth2 inet static
address 10.1.1.10
netmask 255.255.255.0
gateway 10.1.1.20
Это вызывает все три сетевых интерфейса (и адаптер обратной связи), но не назначает указанный IP-адрес eth2.
Глядя в bootlog я получаю сообщение
ip: не могу найти устройство 'eth2'
... и сразу после этого сообщение от драйвера smsc95xx о том, что он зарегистрировал eth2. Поэтому я предполагаю, что это потому, что eth2 недоступен, когда скрипт init пытается присвоить ему IP-адрес (а вместо этого появляется сразу после).
Если я сделаю ifup eth2
После запуска платы IP-адрес назначается автоматически.
Я пытался взломать с некоторыми pre-up
вещи, и следующее, кажется, работает просто отлично:
auto eth2
iface eth2 inet static
address 10.1.1.10
netmask 255.255.255.0
gateway 10.1.1.20
pre-up while [ ! -e /sys/class/net/eth2 ]; do sleep 1; done;
Но это просто слишком похоже на взлом (и также зависнет система, если eth2 никогда не появится).
Есть ли "правильный" способ заставить IP-назначение ждать, пока интерфейс фактически не появится? - или мне придется сделать собственный сценарий для достижения этой цели?
Обратите внимание, что я работаю над встроенным Linux (ядро 3.18.9-rt5, построенное с PTXDist), работающим под управлением BusyBox, поэтому у меня может не быть доступа ко всем модным доступным инструментам.
2 ответа
Я закончил тем, что добавил следующее udev
править моим local.rules
файл:
KERNEL=="eth2", SUBSYSTEM=="net", SUBSYSTEMS=="usb", DRIVERS=="smsc95xx", RUN+="/home/bin/enableeth2.sh"
Сценарий (/home/bin/enableeth2.sh
) содержит следующее (и считается исполняемым):
#!/bin/bash
cd /sbin/
ifup eth2
Обратите внимание на изменение каталога на /sbin/
перед звонком ifup
вместо того, чтобы просто звонить /sbin/ifup eth2
, Это необходимо, поскольку BusyBox ifup
звонки ip
(находится в /sbin/
) внутренне, и так как путь, очевидно, не установлен, когда udev
правило работает, ifup
выдаст ошибку при попытке выполнить фактическую настройку адаптера.
Лучше всего ускорить запуск интерфейса. Это получается путем добавления allow-hotplug eth2
незамедлительно после auto eth2
в строфе /etc/network/interfaces
,
Согласно руководству Debian,
"автоматический" интерфейс запуска при запуске системы
"разрешить авто",,
интерфейс запуска allow-hotplug, когда ядро обнаруживает событие hotplug из интерфейса
Итак, это должно быть так:
auto eth2
allow-hotplug eth2
iface eth2 inet static
address 10.1.1.10
netmask 255.255.255.0
gateway 10.1.1.20
редактировать
Возможно, вам нужен udev
Правило ifup
интерфейс, когда Udev обнаруживает его. Вы могли бы использовать правило как:
KERNEL=="sd*", ATTRS{vendor}=="Yoyodyne", ATTRS{model}=="XYZ42", ATTRS{serial}=="123465789", RUN+="/path/to/my/script"
поместив его в файл в /etc/udev/rules.d
, Это для объекта USB, Vendor и Model должны быть зафиксированы в вашем случае, файл /path/to/my/script
это исполняемый файл, содержащий
#!/bin/bash
ifup InterfaceName
Это должно сделать это.