udevadm vs linux hotplug
- Yes, you're right.
udevadm
is to manageudevd
. - This is where you're really confused. Let me clarify this.
udev
is userspace device manager. udev is responsible for your devices to appear in /dev directory. It's also responsible for hotplug functionality. To make things done udev works by receiving messages from kernel. Kernel sends messages via netlink socket. Netlink is just IPC facility implemented as separate socket family specifically for kernel to userspace interaction. So kernel sends messages of special format (uevent) over netlink socket. On the other site (in userspace) there must be someone who is listening for this messages and that's what udev does. Main part ofudev
is udev daemon -udevd
. That daemon listens for that messages and creates special device files under /dev path and provide to you (linux user) interface to manage devices and hotplug (udev rules).
I've answered related question - check it here.
Extra answers:
From udevadm manpage:
udevadm expects a command and command specific options. It controls
the runtime behavior of systemd-udevd, requests kernel events, manages
the event queue, and provides simple debugging mechanisms.So it's just a managing tool though it can requests kernel event on admin command.
(I might not understand you question correctly). You can write your own daemon to listen for uevents. That's what gentoo's mdev does.
Netlink allows you to provide multiple listeners for netlink messages. But it depends on a way that kernel socket sends message (unicast, multicast, broadcast) and netlink family. Netlink itself is a collection of families, so it may depends on what netlink you are using. For example, NETLINK_GENERIC family allows you to bind multiple userspace sockets for messages and you will receive that messages. I think the best way to answer this question is to write some simple listening code (probably with some help of libudev)
uevent sent from kernel to user space (udev)
It sends netlink message called uevent. uevent is just string of some special format that is sent via netlink socket. Example:
"add@/class/input/input9/mouse2\0 // message
ACTION=add\0 // action type
DEVPATH=/class/input/input9/mouse2\0 // path in /sys
SUBSYSTEM=input\0 // subsystem (class)
SEQNUM=1064\0 // sequence number
PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/22/22:1.0\0 // device path in /sys
PHYSDEVBUS=usb\0 // bus
PHYSDEVDRIVER=usbhid\0 // driver
MAJOR=13\0 // major number
MINOR=34\0", // minor numberKernel function that actually sends uevent is
kobject_uevent_env
and it's wrapperkobject_uevent
that is called in many places.Yes, udev works by receiving uevents from netlink socket. But there is an option - kernel can call usermode helper. In this case kernel spawns one process per hotplug event, supplying environment variables to each new process describing that particular hotplug event. If you look at
kobject_uevent_env
you'll see that netlink message is actually#ifdef
'ed and default action is to call that usermode helperIn theory netlink messages can be broadcast, multicast and unicast, but kernel sends broadcast message with
netlink_broadcast_filtered
call. Anyway that message goes to socket ofNETLINK_KOBJECT_UEVENT
family. You can see netlink socket creation inuevent_net_init
.Answering your comment question. You will not see any
send
function in kernel.send
is a system call - it's interface that kernel provides to userspace, but kernel itself does not use any of syscalls. There is a long chain of function calls (in net/netlink/af_netlink.c and net/core/dev.c) fromkobject_uevent_env
to final sending that doesn't contain anysend
- in kernel sending skb (socket buffer) is something like placing buffer in queue and then calling scheduler to deliver that buffer and notify userspace that is waiting on syscallrecv
Resources:
- lib/kobject_uevent.c
- https://www.kernel.org/doc/pending/hotplug.txt - has userspace program that listens for uevents and prints it.
- https://bootlin.com/doc/legacy/udev/udev.pdf
How to create a callback for monitor plugged on an intel graphics?
As a crude solution, you may be able to poll on sysfs. On my laptop I have:
$ cat /sys/class/drm/card0-LVDS-1/status
connected
$ cat /sys/class/drm/card0-VGA-1/status
disconnected
I'm guessing this requires kernel DRM and possibly KMS.
To see if you can trigger something automatically, you could run udevadm monitor --property
, and watch while you are (dis-)connecting the monitor to see if events are reported.
With my radeon, I get an event the first time I connect a VGA monitor, but no events on subsequent disconnects and reconnects. The event should look something like (using yours as an example):
KERNEL[1303765357.560848] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV_LOG=0
ACTION=change
DEVPATH=/devices/pci0000:00/0000:00:02.0/drm/card0
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=dri/card0
DEVTYPE=drm_minor
SEQNUM=2943
MAJOR=226
MINOR=0
Unfortunately there's not a lot to match against, but as long as there's only one video card in the picture that's not too important. Find where udev gets rules from on your system (probably /etc/udev/rules.d/
), and create a 99-monitor-hotplug.rules
file with:
ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/root/hotplug.sh"
udev
will then run hotplug.sh
when a display is connected. As a test, I put the following in /root/hotplug.sh
(don't forget to make this script executable):
#!/bin/sh
for output in DVI-I-1 LVDS-1 VGA-1; do
echo $output >> /root/hotplug.log
cat /sys/class/drm/card0-$output/status >> /root/hotplug.log
done
With that, I got an entry in hotplug.log
after I connected an external display. Even filtering for ACTION=="change"
, I still got some events on boot, so you may want to take that into account somehow in your script.
libudev how to use poll with the file descriptor
The program doesn't actually stop; it continues running, but std::cout gets messed up when you try to print a NULL string (not all events have all properties). A fix is to make the three prints (devnode, subsystem, devtype) conditional.
Related Topics
Run Meteor as a Daemon Process
How to Use 'Catdoc' to Display Dock File Encoded in Utf-8
Udev-How to Get Value of a Child Device Attributes
Gitlab Ce Doesn't Add a Public Key to Authorized_Keys
Printing Floating Point Numbers in Assembler
Cpu Usage from Linux Then Using It in a Arithmetic Expression
Prevalence of 64Bit Vs 32Bit Platforms
Possible to Assign a New Ip Address on Every Http Request
Bash Script Commands Not Working in Cron
Is There Some Cases in Which Sigkill Will Not Work
How to Continously Run a Unix Script in Background Without Using Crontab.
Yocto: How to Install Header Files Along with Kernel Module in Sdk