3

I like to switch on a green LED(connected through GPIOs), when eth0 is connected. When disconnected I like to switch the green LED of and a red one on.

Thought that udev is maybe the right place for it. I created the simple demo rule:

KERNEL=="eth0", SUBSYSTEM=="net", ACTION=="add", RUN+="/sbin/set_BSPleds eth0 on"

This rule should call a script when the eth0 is added. It was never executed. After I was looking to the udev monitor by entering "udevadm monitor -k -u" at the shell. There were no events coming when I unplug/plug the lan cable.

root@sama5d3xek:/etc/udev/rules.d# udevadm monitor -k -uh0
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

root@sama5d3xek:/etc/udev/rules.d#

Seems that there are no uevents for eth0. The ethernet driver is provided my ATMEL. I am building a custom Linux by the help of Yocto.

My question is, how to get the "link down"/"link up" events to udev? If it does not works with udev, what alternative way is the best?

Stefan Jaritz
  • 1,999
  • 7
  • 36
  • 60

2 Answers2

3

As others have already mentioned, it seems one can't use udev for this.

Ubuntu: wait for network link up and execute a bash command suggests

inotifywait -e modify /sys/class/net/eth0/carrier; echo 'Change detected'

(Currently, / is on nfs for my box, so I can't really say if it will work.)

In other posts, there are some concerns about using the inotify API on /sys: inotify_add_watch fails on /sys/class/net/eth0/operstate .

I think the Right Way(TM) do do this would be to use the netlink(7) API, preferably through a daemon such as netplugd.

Hope that helps :)

Community
  • 1
  • 1
user2247306
  • 183
  • 4
  • Even if you're `/` is on *nfs*, `/sys` is still mounted from your kernel. So this must work (or not work) same as on other `/` rootfs based... (read remarks about *inotify* on `/sys` partition. – F. Hauri - Give Up GitHub Nov 29 '16 at 20:56
2

Ethernet devices are devices, but connections are not.

You could trace connection through /dev/xconsole, dmesg or /var/log/kern.log.

Sample, using rsyslog:

You could (as root):

echo ':msg, contains, "Link is" |/run/netlink' >/etc/rsyslog.d/netlinkstate.conf
mkfifo /run/netlink
chgrp user /run/netlink
chmod 640 /run/netlink
service rsyslog force-reload

Then, logged as user, simply:

read line < /run/netlink

will wait for input from fifo, then hold until something happen.

state=${line#*Link is } eventtime=${line%% $HOSTNAME*}
echo $eventtime $state
2016-11-21T17:40:50.956181+01:00 Down

or

echo $eventtime $state
2016-11-21T17:40:50.956181+01:00 Up 100 Mbps Full Duplex, Flow Control: Rx/Tx

echo $eventtime ${state%% *}
2016-11-21T17:40:50.956181+01:00 Up

Under , you could use timeout for emptying fifo and read only last entry:

while read -t .01 entry </run/netlink;do line="$entry";done
state=${line#*Link is }
eventtime=${line%% $HOSTNAME*}
shortstate=${state%% *}

Nota: I've used /run to store fifo. This could be not the better place as this won't exist on next reboot.

F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137