我正在基于 Atmel Sama5d2 的定制板上运行 buildroot 定制 Linux(内核 4.9.87)。
我正在尝试仅在热插拔时使用 dhcp 在 eth0 接口上配置网络。
最初,该接口是在启动时使用auto eth0
into配置的/etc/network/interfaces
我将其更改为allow-hotplug eth0
具有以下文件
# cat /etc/network/interfaces
auto lo
iface lo inet loopback
allow-hotplug eth0
iface eth0 inet dhcp
进行此更改后,udhcpc 不会在启动时运行,并且如果未插入电缆,也不会再阻止 linux 启动 30 秒。
但是,当我插入或拔出电缆时,没有任何反应。
如果我手动运行,我会在接口ifup -a
上获得一个 IP 地址。eth0
从这个结果来看,我认为问题不是来自网络配置,而是更多来自处理低级事件。
我尝试使用 udevadm 监视电缆的插入/拔出,但在插入和拔出电缆时看不到任何内核事件(但我可以看到来自 USB 子系统的事件)。
我还编写了一条 udev 规则来记录事件,以防 udevadm 未中继此子系统事件。
# cat /etc/udev/rules.d/20-network.rules
SUBSYSTEM=="net", ACTION=="add", RUN+="/test.sh add"
SUBSYSTEM=="net", ACTION=="remove" , RUN+="/test.sh remove"
然而,这条规则也不会触发任何事情。
所以现在我认为我在检测网络电缆热插拔时遇到问题。
可能是内核配置错误,也可能是硬件接线错误。
我真的不知道如何在硬件级别检测插入/拔出事件,但我认为该事件要么由驱动程序本身直接发送到 udev,要么由部署它的众多内核框架之一发送到 udev。
您认为我可能缺少一些内核配置吗?
您认为可以在比使用 udev 更低的级别跟踪状态电缆吗?也许通过直接与 sysfs 交互?
答案1
此 udev 规则和脚本捕获网络接口更改:
/etc/udev/rules.d/90-netifchanges.rules
:
# Call custom script when ethernet device(s) are changed/added/removed/etc in system
SUBSYSTEM=="net" \
, RUN+="/usr/bin/systemd-cat /usr/local/bin/netifchanges.sh '$env{ACTION}' '$name' '$id' '$sys$devpath'"
/usr/local/bin/netifchanges.sh
记录到 systemd 日志的脚本:
#!/bin/bash -e
action=$1
ifname=$2
id=$3
syspath=$4
echo "Network interface $ifname ($id) $action"
printenv
可以在不重新启动的情况下进行测试:
udevadm control --reload-rules && udevadm -d trigger -v --type devices --subsystem-match net
然后查看日志journalctl -xe
。
如果您没有使用 systemd 运行:
删除/usr/bin/systemd-cat
替换为或或RUN+=".."
echo
logger "..."
echo "stuff" > /dev/kmsg
您的发行版使用的其他方法
此外,您可以通过添加虚拟接口来查看日志事件:
# ip link add dummy0 type dummy
# ip link set dummy0 up
# ip link set dummy0 down
# ip link delete dummy0
您还可以找到很多有关接口的信息,udevadm
例如:
# udevadm info -a /sys/class/net/eno1
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/pci0000:00/0000:00:19.0/net/eno1':
KERNEL=="eno1"
SUBSYSTEM=="net"
DRIVER==""
ATTR{gro_flush_timeout}=="0"
ATTR{proto_down}=="0"
ATTR{addr_assign_type}=="0"
ATTR{flags}=="0x1103"
ATTR{netdev_group}=="0"
ATTR{name_assign_type}=="4"
ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"
ATTR{operstate}=="up"
ATTR{link_mode}=="0"
ATTR{dev_port}=="0"
ATTR{address}=="74:d0:2b:2c:6e:d7"
ATTR{duplex}=="full"
ATTR{carrier_changes}=="4"
ATTR{type}=="1"
ATTR{addr_len}=="6"
ATTR{dev_id}=="0x0"
ATTR{iflink}=="3"
ATTR{mtu}=="1500"
ATTR{speed}=="1000"
ATTR{carrier_down_count}=="2"
ATTR{ifalias}==""
ATTR{carrier_up_count}=="2"
ATTR{ifindex}=="3"
ATTR{carrier}=="1"
ATTR{tx_queue_len}=="1000"
ATTR{dormant}=="0"
looking at parent device '/devices/pci0000:00/0000:00:19.0':
KERNELS=="0000:00:19.0"
SUBSYSTEMS=="pci"
DRIVERS=="e1000e"
ATTRS{device}=="0x1503"
ATTRS{label}==" Onboard LAN"
ATTRS{enable}=="1"
ATTRS{irq}=="56"
ATTRS{subsystem_vendor}=="0x1043"
ATTRS{devspec}==""
ATTRS{revision}=="0x06"
ATTRS{subsystem_device}=="0x849c"
ATTRS{local_cpus}=="ff"
ATTRS{local_cpulist}=="0-7"
ATTRS{class}=="0x020000"
ATTRS{driver_override}=="(null)"
ATTRS{broken_parity_status}=="0"
ATTRS{msi_bus}=="1"
ATTRS{vendor}=="0x8086"
ATTRS{consistent_dma_mask_bits}=="64"
ATTRS{ari_enabled}=="0"
ATTRS{index}=="1"
ATTRS{numa_node}=="-1"
ATTRS{d3cold_allowed}=="1"
ATTRS{dma_mask_bits}=="64"
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
这些链接到 sys 文件:
# cat /sys/class/net/eno1/operstate
up
udevadm monitor
还可以使用:
# udevadm -d monitor -p -k -u --subsystem-match=net
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent
KERNEL[99386.755966] add /devices/virtual/net/dummy0 (net)
ACTION=add
DEVPATH=/devices/virtual/net/dummy0
SUBSYSTEM=net
INTERFACE=dummy0
IFINDEX=12
SEQNUM=6842
rx-0: sd-device-monitor: Received device does not pass filter, ignoring
tx-0: sd-device-monitor: Received device does not pass filter, ignoring
UDEV [99386.773912] add /devices/virtual/net/dummy0 (net)
ACTION=add
DEVPATH=/devices/virtual/net/dummy0
SUBSYSTEM=net
INTERFACE=dummy0
IFINDEX=12
SEQNUM=6842
USEC_INITIALIZED=99386759873
ID_NET_NAMING_SCHEME=v240
ID_MM_CANDIDATE=1
ID_NET_DRIVER=dummy
ID_NET_LINK_FILE=/usr/lib/systemd/network/99-default.link
SYSTEMD_ALIAS=/sys/subsystem/net/devices/dummy0
TAGS=:systemd:
rx-0: sd-device-monitor: Received device does not pass filter, ignoring
tx-0: sd-device-monitor: Received device does not pass filter, ignoring
KERNEL[99392.704357] remove /devices/virtual/net/dummy0 (net)
ACTION=remove
DEVPATH=/devices/virtual/net/dummy0
SUBSYSTEM=net
INTERFACE=dummy0
IFINDEX=12
SEQNUM=6847
UDEV [99392.715832] remove /devices/virtual/net/dummy0 (net)
ACTION=remove
DEVPATH=/devices/virtual/net/dummy0
SUBSYSTEM=net
INTERFACE=dummy0
IFINDEX=12
SEQNUM=6847
USEC_INITIALIZED=99386759873
ID_NET_NAMING_SCHEME=v240
ID_MM_CANDIDATE=1
ID_NET_DRIVER=dummy
ID_NET_LINK_FILE=/usr/lib/systemd/network/99-default.link
SYSTEMD_ALIAS=/sys/subsystem/net/devices/dummy0
TAGS=:systemd: