Netlink user-space and kernel-space communication - linux

I am learning programming in embedded systems using Linux as my main platform. And I want to create a Device Event Management Service. This service is a user-space application/daemon that will detect if a connected hardware module triggered an event. But my problem is I don't know where should I start.
I read about Netlink implementation for userspace-kernelspace communication and it seems its a good idea but not sure if it is the best solution. But I read that the UDEV device manager uses Netlink to wait a "uevent" from the kernel space but it is not clear for me how to do that.
I read about polling sysfs but it seems it is not a good idea to poll filesystem.
What do you think the implementation that should I use in my service? Should I use netlink(hard/no clue how to) or just polling the sysfs(not sure if it works)?
Thanks

Yes, polling is ill-advised. These resources: LJ article on Netlink, "Understanding and Programming with Netlink Sockets" make it seem not so hard to do netlink. Here's an example of netlink sockets in python.
udevtrigger is a great utility for reacting to udev changes.
http://www.linuxjournal.com/article/7356
http://smacked.org/docs/netlink.pdf
http://guichaz.free.fr/misc/iotop.py
http://manpages.ubuntu.com/manpages/gutsy/man8/udevtrigger.8.html

If all you do is wait for an event you can use sysfs, which will be a lot simpler than netlink. An example is the GPIO system's edge file.

Related

Uevent as a simple notification from kernel to userspace

There is a kernel driver sending events to an application. This is done using a procfs file that blocks on read until a new event must be reported. The application reads this file and gets blocked until there is new information.
This approach works but doesn't look nice to me.
Now I found uevent as a notification mechanism that seems to be used for this purpose.
But it seems to do much more than just that. I read about hotplugging devices, registration of devices and so on and I need to register a kobject to do that. All this makes me unsure if uevent is too excessive for simply sending a short message from one driver to a dedicated userspace application.
Is a uevent the appropriate means for what I want to do or is it too much overhead and I should use something more simple?
By the way I am trying to find a good example how to use uevent as a notification only. Is there something understandyble that doesn't focus on all the mentioned other features?

Can NETLINK_ROUTE channel be used to send messages from kernel module to a user-space program?

I have written a user-space program that polls for the status of the available Ethernet interfaces for their operational status using netlink sockets with NETLINK_ROUTE protocol.
But now I want to write a kernel module which uses the NETLINK_ROUTE channel to send customized notification message to this user-space program.
After reading the man page for netlink and rtnetlink I cannot conclude if it is doable. Any suggestions will be highly appreciated.
NETLINK_ROUTE is not a protocol - it's one of the netlink families. From manpage:
netlink_family selects the kernel module or netlink group to
communicate with.
Netlink was initially developed for fast and easy messaging about routing info and that's why NETLINK_ROUTE is first family and have own manpages, manuals, etc. But later other families were added to send other than routing info, e.g. NETLINK_SELINUX and NETLINK_FIREWALL.
After some time developers saw that there are way too many specific families. If somebody wants to use that fancy netlink protocol he needs to declare another family and make it even worse. So they added last family - NETLINK_GENERIC that works like multiplexer. There is a great manual about generic netlink on lwn - http://lwn.net/Articles/208755/. If you want working examples you can look at my code (https://github.com/dzeban/keymon)
So, if your notifications related to any specific netlink family like NETLINK_ROUTE - then use it. But if you want to just send your very own and custom info - use generic netlink.

udevadm vs linux hotplug

I am a bit confused with the questions listed below:
While I execute udevadm on my desktop, it is able to listen uevent sent from kernel.
I think before the execution of udevadm, it will check the availability of udevd.
That means, if the udevd is not available on my desktop, udevadm will not be able to work.
Is my thinking correct?
To have the same functionality of udevadm, I found that linux also provides another way
to archive this. It's called netlink. What confuses me is If I do things this way, I could have exactly the same thing that I have by using udevadm. Hence, what's the difference between udev vs. netlink socket?
socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); <----The socket I created to listen to uevent.
Thanks for avd's feedback. I still have some questions to ask after having your feedback.
There are not only udevd can listen message from kernel, but also udevadm does.
Is my thinking correct? Or udevadm is only to manage udevd.
By setting up the socket binding to the NETLINK_KOBJECT_UEVENT, the user space code can also listen uevent sent from kernel. At this point, It seems I have no reason to choose udev to complete this function. Is there any different between these two approaches?
In user space, Can two different processes listen to uevent simultaneously? Can netlink send the message to these processes in the same time?
Yes, you're right. udevadm is to manage udevd.
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 of udev 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)

Binding to Linux System Event?

for Linux, there is a nifty little library called xbindkeys that (surprise) binds commands of your choice to certain key combinations.
I am looking for something similar, except for a system hardware event. When I plug in my headphones to the output jack on my computer, I would like to be able to call a program. It would also be nice to be able to bind to the event when I un-plug my headphones.
Does anybody know if this is possible? Maybe through some cool Python X11 library?
Thanks in advance.
EDIT: Found the API for the jack abstraction layer: http://www.alsa-project.org/~tiwai/alsa-driver-api/ch06s02.html
Sadly, this only allows for polling of the device, not an event handler.
You probably want to use udev for this. I haven't used libudev, but here's something I found:
libudev - Monitoring Interface
libudev also provides a monitoring interface. The monitoring interface
will report events to the application when the status of a device
changes. This is useful for receiving notification when devices are
connected or disconnected from the system.
The actions are returned as the following strings:
add - Device is connected to the system
remove - Device is disconnected from the system
change - Something about the device changed
move - Device node was moved, renamed, or re-parented
That article goes on to show how it obtains a file descriptor via udev_monitor_get_fd, which it later monitors via select.
Most modern Linux desktops (notably Gnome and KDE) use "DBus".
DBus, in turn, utilizes HAL (older) and/or udev (newer).
Here are a couple of links that explain further:
https://www.linux.com/news/hardware/peripherals/180950-udev
http://w3.linux-magazine.com/issue/71/Dynamic_Device_Management_in%20Udev.pdf
http://dbus.freedesktop.org/doc/dbus-tutorial.html

Dbus on Kernel to user space

I have a question regardind dbus on the current(2.6.35) kernel. Is dbus a way of communication between kernel and user space? I can figure it out by myself. For exemple if you make use of the usb driver(inserting something like a usb flash pen) and monitoring the activity of the dbus(dbus-monitor) the answer might be yes. But in the source code(usb-skeleton.c and the driver for gadgets there's no sign of dbus). Dbus.h is not to be found in the kernel tree.
Thank you very much. Sorry if i've got this wrong but i am kind of a noob on device drivers and dbus!
D-Bus is for user space applications to communicate with one another.
If you want to communicate with a device driver you want to use either IOCTLs, netlink or create a new syscall. I've created netlink code in the past to speak to a special networking card, and it was relatively easy to do. Using the ioctl is also quite easy but you are limited by how much information you can/should pass via it.
If you are curious how dbus relates to a USB device being inserted, I think it is something like this:
D-Bus (or "daemon bus") is a means of communication between processes (inter-process communication or IPC for short) on Linux/Unix based systems.
It lets processes expose a "D-Bus service" with methods that clients can call. These methods usually map to real methods written in some programming language. D-Bus is language-independent, but most toolkits have some library to make it easier to use - e.g. QtDbus.
It is in no way related to the kernel or drivers, but of course no one prevents a driver from also having a D-Bus service if they want to. (This could be useful in some cases.)

Resources