Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
(I'm running gentoo, so maybe that's the source of my problem. The folks over on forums.gentoo.org don't seem to be able to answer this question.)
udev is supposed to be the be-all end-all for /dev management. If that is the case then there must be a way to have udev build /dev entries automatically. Not just for some things, but for all things. Sure, it's my responsibility to set up the rules if I add something non-standard, and that's fine. But the mechanism to do so has to be in place. That MUST be part of udev, otherwise udev is not an acceptable solution for managing /dev.
I have a PCI I/O board in my system. The device driver, a loadable module, works perfectly but I have to use a MAKEDEV script to build the /dev entries. When I reboot the system these nodes disappear so I have to (manually) create them again. What *should* happen is that when the device driver is loaded (on boot, or manually as I keep reloading after tweaking values) udev should recognize this and create or destroy the relevant entries. Maybe udev only needs to call the MAKEDEV script, but whatever happens should do so automatically.
The module is called s626.ko, and the devices built are /dev/s626a[0-3]. If I had a second board in the system the devices would be called /dev/s626b[0-3].
Right now what happens is -- nothing. Oh, sure, an entry appears and disappears in /sys as I load and unload the module, but there is no activity beyond that.
So what event happens to make udev aware that new /dev nodes must be created? How can I verify that udev is picking up on this event?
Someone pointed out that udev has the option to tar up the /dev directory on shutdown for restoration on boot later, so I could create the entries once then activate the 'save' feature. That is not a solution. A cop-out, a hack, but certainly not a solution. Because of the dynamic nature of the modern /dev structure, device major numbers can change, so the "static" (perhaps "stale" is a better word) entries in the tar file run a great risk of being wrong on subsequent boots.
I've gone through all the documentation I could find. Some of the better stuff (still does not help me here, though):
- udev manpage
- "Writing udev rules" but Daniel Drake. This is a pretty good document, but does not cover my situation.
- "UDEV Primer" on Decibels Linux. More good info, but doesn't cover my situation.
Any suggestions on how to proceed or where to start digging?
This is not a standard kernel module, we compile it separately. It's part of the SDK we get with the product.
On one system I load it at boot. On another system I load it when I need to work with that card (used to control and monitor an external device).
Here's the output. Actually, there are 3 non-standard cards in this system. I have the same issue with udev for all of them. I figured I'll get help on the easy one first before I tackle the rest. That said, I can not tell you which entries correspond to the s626 card I mention. But here you go:
i would try adding it to /etc/modprobe.conf so that it will load on boot. I think it will play a little better with udev if it is loaded at boot because the modules are loaded before udev scans for all devices.
i would try adding it to /etc/modprobe.conf so that it will load on boot. I think it will play a little better with udev if it is loaded at boot because the modules are loaded before udev scans for all devices.
OK, thanks, I'll give this a shot, might not be until next week before I'm back near that system.
udev is designed to work with things like USB device insertion and removal, and these certainly happen after the computer boots. So how is it that udev works with these devices but not other devices?
To my simple mental model it's the same thing: The kernel says "Hey! New Hardware!" or "Hey! That hardware went away!". These are triggered by (or in conjunction with) changes to /sys, which happens when a USB drive is inserted/removed or when a module is loaded/unloaded, as evidenced by the udevmonitor snippet included in my previous post.
Can someone explain the difference?
Again, thanks for your explanations and suggestions.
Yes, but *I* can load and unload modules. I need udev to react to that. Maybe I'm being obtuse, but I see "udevmonitor --kernel" acknowledging my loading and unloading of a module, so why can't udev react to these events?
It seems to me that your driver was written without an actual device registration occurring (this is common for “old” drivers). For example, if you use something low-level like register_chrdev() instead of something higer-level like misc_register(), you will get reserved major and minor numbers, yet no uevent for device creation will be sent. In your case, if such a uevent was sent, it udevmonitor would have told you with
Code:
add /class/foo/bar (foo)
So you will be unable to alter an already-in-kernel device path (the canonical way to use udev to manage device nodes) without patching your module. For example, you won’t be able to do something like this (a disk-by-id rule from gentoo) with your particular device:
What you can do is use the ACTION and DEVPATH matches. So in that case, since there is no device to be named, you run mknod from within udev upon its detection of the driver. For example,
Where mkS626.sh is a shell script located in “/lib/udev” (it should be very short-running). In this script you can basically put anything you want (including mknod calls), and the entire script will be run upon module loading. You can use a similar script for a “remove” ACTION (you can even use the same script, and have two branches, depending on what your script may glean from sysfs info or whatever).
P.S., if you want to see detailed, matchable variables in udevmonitor, try using
It seems to me that your driver was written without an actual device registration occurring (this is common for old drivers).
...
What you can do is use the ACTION and DEVPATH matches. So in that case, since there is no device to be named, you run mknod from within udev upon its detection of the driver.
...
Thanks! I can't try it out until tomorrow, but this seems to be exactly the kind of information I was looking for.
I neglected to mention that the script will inherit all environment variables from udev (including ACTION and DEVPATH). If you want to pass your own custom environment variables, you can use ENV{foo}=bar. Then, in your script, you can access $foo as you normally would. You can use the ACTION environment variable to write one script with two branches, checking for add or remove as the value of $ACTION.
P.S., a caveat about variable assignment syntax: the udev rules use syntax similar to C, where == indicates testing for equality, and = indicates assignment. When writing the matching part of the rule, use the first form (e.g., ACTION=="add", DEVPATH=="/bus/pci/drivers/S626"). When assigning a variable for a successful match, use the second form (e.g., RUN="mk_S626.sh").
P.P.S., remember that the script will be run with root permissions. Approach it security-wise the same way you approach writing init-scripts.
Osor: Your description of what was not happening with the old drivers was a huge help. The ACTION and DEVPATH matches were exactly what I needed.
I created a script to create or destroy the nodes and symlinks, based on the manufacturer's MAKEDEV script, but much cleaner. I load a module: the nodes appear. I rmmod the device, the nodes disappear. Yee-ha.
This thread was triply useful because I have another device which has the same problem: the device driver is older and so udev integration required the same handling. That script works perfectly, too.
So I'm 100% good for two of my boards.
For my third board I'm about 95% there....
The script calculates the device minor numbers, creates the nodes, then changes the group and mode:
Code:
...
node="/dev/${module}${i}"
# clean out stale nodes
rm -f $node
mknod $node c $major $i
chgrp $group $node
chmod $mode $node
...
I load and unload the module, the nodes appear and disappear. But there is a random element to it: sometimes the nodes don't change group, sometimes the nodes don't change mode. I turned on udev debugging (via "udevcontrol log_priority=debug") and monitored the tail of /var/adm/messages. Here are some of the error messages I see:
.... mknod: '/dev/pcan8': File exists
.... chgrp: cannot access '/dev/pcan25': No such file or directory
.... chmod: cannot access '/dev/pcan4': No such file or directory
Now, as far as I can tell the script runs once and only once when the module is loaded. All of the nodes are always created, they just end up in various combinations of group and ownership. It almost seems there is some sort of race condition going on here, but I don't see how that can be. Any thoughts on what might be going on?
...I load and unload the module, the nodes appear and disappear. But there is a random element to it: sometimes the nodes don't change group, sometimes the nodes don't change mode.
... All of the nodes are always created, they just end up in various combinations of group and ownership. It almost seems there is some sort of race condition going on here, but I don't see how that can be. Any thoughts on what might be going on?
OK, this is weird. I rebooted, and everything loaded fine. No group or ownership problems on the devices. I only rebooted once (hey, this isn't Windows) so I can't say the results are conclusive.
I then tried several unloads and loads of the module. No randomness -- groups fine, modes fine.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.