You are not logged in.

#1 2014-05-13 13:56:08

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

udev rule, what am I doing wrong?

My mouse is quite nice, but for some reason is installed also as a joystick that always go up left.

So I wanted to write a udev rule to setup the chmod of the /dev files to 000 so no programs can try to use that dummy joystick...
I used udevadm info -q all -a -n on the dummy device name (/dev/input/event13) to get some information to distinguish it from the correctly working mouse and I wrote a simple udev rule.

The rule is read according to  udevadm test, but it seems the system does not apply it at all... what am I doing wrong?

The udev rule:

SUBSYSTEMS=="input", DRIVERS=="usbhid", ATTRS{manufacturer}=="A4TECH", ATTRS{idProduct}=="9090", ATTRS{bInterfaceProtocol}=="01", ATTRS{bInterfaceNumber}=="00", MODE="0000"

udevadm info -q all -a -n

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:14.0/usb3/3-3/3-3:1.0/0003:09DA:9090.0005/input/input24/event13':
    KERNEL=="event13"
    SUBSYSTEM=="input"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0/0003:09DA:9090.0005/input/input24':
    KERNELS=="input24"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{name}=="A4TECH USB Device"
    ATTRS{phys}=="usb-0000:00:14.0-3/input0"
    ATTRS{uniq}==""
    ATTRS{properties}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0/0003:09DA:9090.0005':
    KERNELS=="0003:09DA:9090.0005"
    SUBSYSTEMS=="hid"
    DRIVERS=="hid-generic"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0':
    KERNELS=="3-3:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usbhid"
    ATTRS{bInterfaceClass}=="03"
    ATTRS{bInterfaceSubClass}=="01"
    ATTRS{bInterfaceProtocol}=="01"
    ATTRS{bNumEndpoints}=="01"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceNumber}=="00"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-3':
    KERNELS=="3-3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{devpath}=="3"
    ATTRS{idVendor}=="09da"
    ATTRS{speed}=="12"
    ATTRS{bNumInterfaces}==" 2"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{busnum}=="3"
    ATTRS{devnum}=="16"
    ATTRS{configuration}==""
    ATTRS{bMaxPower}=="100mA"
    ATTRS{authorized}=="1"
    ATTRS{bmAttributes}=="a0"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{maxchild}=="0"
    ATTRS{bcdDevice}=="0191"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{version}==" 1.10"
    ATTRS{urbnum}=="12421"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="A4TECH"
    ATTRS{removable}=="removable"
    ATTRS{idProduct}=="9090"
    ATTRS{bDeviceClass}=="00"
    ATTRS{product}=="USB Device"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3':
    KERNELS=="usb3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{devpath}=="0"
    ATTRS{idVendor}=="1d6b"
    ATTRS{speed}=="480"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{authorized_default}=="1"
    ATTRS{busnum}=="3"
    ATTRS{devnum}=="1"
    ATTRS{configuration}==""
    ATTRS{bMaxPower}=="0mA"
    ATTRS{authorized}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{maxchild}=="14"
    ATTRS{bcdDevice}=="0314"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{serial}=="0000:00:14.0"
    ATTRS{version}==" 2.00"
    ATTRS{urbnum}=="364"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Linux 3.14.1-1-ARCH xhci_hcd"
    ATTRS{removable}=="unknown"
    ATTRS{idProduct}=="0002"
    ATTRS{bDeviceClass}=="09"
    ATTRS{product}=="xHCI Host Controller"

  looking at parent device '/devices/pci0000:00/0000:00:14.0':
    KERNELS=="0000:00:14.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="xhci_hcd"
    ATTRS{irq}=="44"
    ATTRS{subsystem_vendor}=="0x1558"
    ATTRS{broken_parity_status}=="0"
    ATTRS{class}=="0x0c0330"
    ATTRS{enabled}=="1"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{local_cpus}=="00000000,00000000,00000000,000000ff"
    ATTRS{device}=="0x8c31"
    ATTRS{msi_bus}==""
    ATTRS{local_cpulist}=="0-7"
    ATTRS{vendor}=="0x8086"
    ATTRS{subsystem_device}=="0x3537"
    ATTRS{numa_node}=="-1"
    ATTRS{d3cold_allowed}=="1"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

Offline

#2 2014-05-13 15:15:12

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,302

Re: udev rule, what am I doing wrong?

So you say that your mouse is seen as a mouse and as a joystick by udev.

How do you know that '/dev/input/event13' is the uevent for the mouse seen as a joystick?

How do you know that the match keys of your udev rule apply to the mouse seen as a joystick?

Offline

#3 2014-05-13 15:26:11

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

I checked the udevadm info -q all -a -n output of the correct device (the mouse) and the incorrect one (the joystick).
The main difference is ATTRS{bInterfaceProtocol}, ATTRS{bInterfaceNumber}, and the name of the /dev device.

Here is /proc/bus/input/devices relevant part, the first section is the bad device, the second is the good one.

I: Bus=0003 Vendor=09da Product=9090 Version=0111
N: Name="A4TECH USB Device"
P: Phys=usb-0000:00:14.0-3.2/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.2/3-3.2:1.0/0003:09DA:9090.0017/input/input42
U: Uniq=
H: Handlers=sysrq kbd event13 js0 
B: PROP=0
B: EV=12001f
B: KEY=4c37fff072ff32d bf54445600000000 c00000000000001 30c100b17c007 ffa67bfad951dfff febeffdfffefffff fffffffffffffffe
B: REL=40
B: ABS=ffffff01000701ff
B: MSC=10
B: LED=1f

I: Bus=0003 Vendor=09da Product=9090 Version=0111
N: Name="A4TECH USB Device"
P: Phys=usb-0000:00:14.0-3.2/input1
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.2/3-3.2:1.1/0003:09DA:9090.0018/input/input43
U: Uniq=
H: Handlers=event14 mouse1 
B: PROP=0
B: EV=17
B: KEY=ffff0000 0 0 0 0
B: REL=143
B: MSC=10

Last edited by ezzetabi (2014-05-13 15:29:15)

Offline

#4 2014-05-13 15:42:39

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,302

Re: udev rule, what am I doing wrong?

if you know the name in /dev, you could try to use the DEVPATH instead of SUBSYSTEMS and DRIVERS and keeping the other match keys.

Offline

#5 2014-05-13 16:05:32

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

If possible I would like to have a rule that does depend on the order I plug stuff to the computer...

Offline

#6 2014-05-13 16:49:46

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

The original problem is you can select only using data from a single parent of a device...


So I tried something different, this rule gets the parent of the two dummy devices and it should be fairly safe::

ATTR{name}=="A4TECH USB Device", SUBSYSTEM=="input", ATTRS{bInterfaceProtocol}=="01", ATTRS{bInterfaceNumber}=="00", RUN+="/root/write_down.sh -- %k -- %n"

Is there a way to stop the device tree from being expanded? I tried OPTIONS+=ignore_device, but it has no effects.

Offline

#7 2014-05-13 20:50:34

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,302

Re: udev rule, what am I doing wrong?

I don't understand your post #5 and the link with the original problem with your mouse.

And in your post #6, what is this: "/root/write_down.sh -- %k -- %n"?
Does this last udev rule works?

And what is the meaning of "Is there a way to stop the device tree from being expanded"? what device tree? expanded by what?

Sorry I am lost...

Offline

#8 2014-05-14 09:45:57

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

Lets go in order...

I know the bogus joystick is usually called /dev/input/js0 and /dev/input/event13, but if I plug USB devices in another other is well possible that the name will be different.


The original rule I wrote does not work because in udev rules you can refer to the device (with lines like ATTR or KERNEL) and a single parent (with lines like ATTRS or KERNELS). In that rule instead I refer to multiple parents. So it does not match.


write_down.sh is just a bash script that writes in a file its arguments ("$@"), it was a test to see if udev actually applies the rule when I plugin the mouse. And yes, it works. %k and %n are the kernel name of the device and the kernel number.


Finally, udef devices are organized as tree structure. In this case all the /dev nodes are leaves. But the two bogus ones have a different parent than the good ones.

See this picture:

                |
                B
 -------------------------
 |                       |
 X                       O
----------           -----------
|        |           |         |
bogus1  bogus2      good1     good2

bogus are the two not working /dev devices I want to disable (a non-existing joystick). goods are instead the good ones that represent the mouse.

The rule in previous message correctly detect the X that is parent of the two bogus devices. So my question was, can I avoid the creation of two bogus nodes when I match their parent?


I am also lost.

Last edited by ezzetabi (2014-05-14 09:46:28)

Offline

#9 2014-05-14 11:14:32

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

I solved calling this script with the "%p" parameter... any suggestion to improve it?

#!/bin/sh
set -e

cd "/sys/$1"
DUMMYNODES="`ls -1 | grep '^js[0-9]*$\|^event[0-9]*$'`"
cd '/dev/input'
rm -f $DUMMYNODES

I uses the device address to get the names of the bogus nodes and deletes them. Brutal, but effective.

Offline

#10 2014-05-14 15:23:39

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,302

Re: udev rule, what am I doing wrong?

It works, but I get the feeling that it is not the best solution..

Did you try with the MODE="0000" instead of your script in the last working rule?

And is not one of 'bogus1' and 'bogus2' a link to the other?

You spoke of 'OPTIONS+=ignore_device' in one of your post;
I don't see that in 'man udev';
do you have a link to some documentation about that option please?

It would be better to prevent the creation of 'bogus1' and 'bogus2', I think;
using 'rm -f' in a script run by root, without any human control, seems dangerous to me.

Offline

#11 2014-05-14 16:06:06

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

About ignore_device: http://lwn.net/Articles/364728/ it does not exist anymore.

No bogus1 and bogus2 are both the same (non-existing) joystick, but one from the Joystick API and one from the evdev interface. In fact one is usually called js0 and the other event13; see also our wiki.

About your points I agree, but I cannot find a way to set mode to 000 or to disable the creation of the bogus nodes... MODE="0000" has apparently no effect.


Edit: probably this note about how to make rule based on two parents can help: http://linhes.org/issues/651#note-6

Last edited by ezzetabi (2014-05-14 16:21:50)

Offline

#12 2014-05-14 20:05:52

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

This set of rules actually work to make a rule based on two parents you can use a ENV variable.

But the mode is set up to 040 instead of 000! The filename is 99-something.rules should it should be called last.
Besides the udevadm test command states mode 0... [full command:  udevadm test $(udevadm info -q path -n /dev/input/js0) 2>&1 ]

A part of udev what possibly change the permissions?

KERNEL=="event[0-9]*", SUBSYSTEM=="input", ATTRS{name}=="A4TECH USB Device", ENV{.bogus_mouse_event}="YES"
KERNEL=="event[0-9]*", ENV{.bogus_mouse_event}="YES", ATTRS{bInterfaceProtocol}=="01", ATTRS{bInterfaceNumber}=="00", MODE="0000"

KERNEL=="js[0-9]*", SUBSYSTEM=="input", ATTRS{name}=="A4TECH USB Device", ENV{.bogus_mouse_js}="YES"
KERNEL=="js[0-9]*", ENV{.bogus_mouse_js}="YES", ATTRS{bInterfaceProtocol}=="01", ATTRS{bInterfaceNumber}=="00", MODE="0000"

Offline

#13 2014-05-14 20:19:27

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

Solved just changing the mode with a rm command...

KERNEL=="event[0-9]*", SUBSYSTEM=="input", ATTRS{name}=="A4TECH USB Device", ENV{.bogus_mouse_event}="ONE"
KERNEL=="event[0-9]*", ENV{.bogus_mouse_event}="ONE", ATTRS{manufacturer}=="A4TECH", ATTRS{idProduct}=="9090", ENV{.bogus_mouse_event}="TWO"
KERNEL=="event[0-9]*", ENV{.bogus_mouse_event}="TWO", ATTRS{bInterfaceProtocol}=="01", ATTRS{bInterfaceNumber}=="00", RUN+="/usr/bin/rm %N"

KERNEL=="js[0-9]*", SUBSYSTEM=="input", ATTRS{name}=="A4TECH USB Device", ENV{.bogus_mouse_js}="ONE"
KERNEL=="js[0-9]*", ENV{.bogus_mouse_js}="ONE", ATTRS{manufacturer}=="A4TECH", ATTRS{idProduct}=="9090", ENV{.bogus_mouse_js}="TWO"
KERNEL=="js[0-9]*", ENV{.bogus_mouse_js}="TWO", ATTRS{bInterfaceProtocol}=="01", ATTRS{bInterfaceNumber}=="00", RUN+="/usr/bin/rm %N"

But the question still stand, what can possibly change the permission after udev?

Last edited by ezzetabi (2014-05-14 20:20:00)

Offline

#14 2014-05-14 21:15:45

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,302

Re: udev rule, what am I doing wrong?

When you test the value of your created internal variables, you use a single '=' instead of a double '==';
the single '=' is to create the variable and the double '==' to test the value;
so I think there is a typo in your rules; maybe it is why the MODE="0000" try was unsuccessful.

I will look again to that issue tomorrow, I can't at the moment...

Offline

#15 2014-05-15 09:11:34

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

Good grief... you are right. This explains why my external USB keyboard was not working... However this cannot explain why the MODE="0000" did not work, the broken rule matches _more_ devices than wanted and it does match the bogus nodes. Besides the test shown MODE 0...

Here is the fixed rule:

KERNEL=="event[0-9]*", SUBSYSTEM=="input", ATTRS{name}=="A4TECH USB Device", ENV{.bogus_mouse_event}="ONE"
KERNEL=="event[0-9]*", ENV{.bogus_mouse_event}=="ONE", ATTRS{manufacturer}=="A4TECH", ATTRS{idProduct}=="9090", ENV{.bogus_mouse_event}="TWO"
KERNEL=="event[0-9]*", ENV{.bogus_mouse_event}=="TWO", ATTRS{bInterfaceProtocol}=="01", ATTRS{bInterfaceNumber}=="00", RUN+="/usr/bin/rm %N"

KERNEL=="js[0-9]*", SUBSYSTEM=="input", ATTRS{name}=="A4TECH USB Device", ENV{.bogus_mouse_js}="ONE"
KERNEL=="js[0-9]*", ENV{.bogus_mouse_js}=="ONE", ATTRS{manufacturer}=="A4TECH", ATTRS{idProduct}=="9090", ENV{.bogus_mouse_js}="TWO"
KERNEL=="js[0-9]*", ENV{.bogus_mouse_js}=="TWO", ATTRS{bInterfaceProtocol}=="01", ATTRS{bInterfaceNumber}=="00", RUN+="/usr/bin/rm %N"

It gets the A4TECH usb device 9090 bogus nodes and deletes them.

I think I will update the wiki eventually: the linked udev page about writing rules is outdated and there is no explanation how to make rules to match a node using multiple parents of it.

Last edited by ezzetabi (2014-05-15 09:18:26)

Offline

#16 2014-05-15 21:07:06

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,302

Re: udev rule, what am I doing wrong?

I searched about the MODE key in udev rules; in some cases the ':=' operator may be used, instead of just '=', to prevent later changes of the value.
But as the "/usr/bin/rm %N" command works, you already have a way to get rid of the bogus joystick nodes created for your mouse.
Unfortunately I did not find a way to prevent the creation of the bogus nodes, instead of to remove them after their creation.
If I stumble upon something some day, I will tell you then...

Finally, I wanted to add a clarification about the use of the '*' character in wildcard patterns inside a udev rule:

udev rules understand and use shell globbing patterns, not regular expression patterns.

So "event[0-9]*" doesn't mean "event" followed by zero or more digit characters, as in a regular expression;
but it means "event" followed by one digit character, followed by zero or more any characters, because it is the '*' of the shell globbing pattern, as in a path expansion.
Consequently the value "event1abcd" will match, and "event" will not match (it must be followed by one digit), as opposed to the same pattern using a regular expression where "event1abcd" will not match, and "event" will match.
I wanted to precise that, in case you made this error, as I also did, when writing your udev rules.
Greetings.

Offline

#17 2014-05-15 21:37:31

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

I got the idea it was like the regular expressions reading the file /usr/lib/udev/rules.d/50-udev-default.rules, thanks for explaining it is not the case. It should not be a problem in this case fortunately.


About the MODE, I noticed a weird behavior, both with the = or := operator. I changed the RUN rule with MODE="0000" and plugged the mouse. (MODE:="0000" is the same)

This is what happen:

# cd /dev/input
# ls -l1 |grep 'event13\|js'
c---rw----+ 1 root root 13, 77 15 mag 23.28 event13
c---rw----+ 1 root root 13,  0 15 mag 23.28 js0
# udevadm test $(udevadm info -q path -n /dev/input/event13 ) &>/dev/null 
# ls -l1 |grep 'event13\|js'
c---------+ 1 root root 13, 77 15 mag 23.29 event13
c---rw----+ 1 root root 13,  0 15 mag 23.28 js0
# udevadm test $(udevadm info -q path -n /dev/input/js0 ) &>/dev/null 
# ls -l1 |grep 'event13\|js'
c---------+ 1 root root 13, 77 15 mag 23.29 event13
c---------+ 1 root root 13,  0 15 mag 23.30 js0
# 

It seems that while testing it notices the wrong mode setting and it fixes it...

Last edited by ezzetabi (2014-05-15 21:38:19)

Offline

#18 2014-05-16 09:45:15

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,302

Re: udev rule, what am I doing wrong?

From the udev wiki page in 'Testing rules before loading' about the 'udevadm test' command:

This will not perform all actions in your new rules but it will however process symlink rules on existing devices which might come in handy if you are unable to load them otherwise

Your tests show that 'udevadm test' processes also the rules with a MODE change on existing devices.

I don't know why the rules with a MODE change are not applied just after the creation of the nodes, but seem to require a re-parsing of the rules after their creation.
Nevertheless you now have another way to neutralize the bogus nodes by running the 'udevadm test' commands at the end of the starting sequence, and so forcing the MODE change then. Maybe 'udevadm trigger' could be used too for that.

Offline

#19 2014-05-16 10:03:02

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: udev rule, what am I doing wrong?

It is not a way at all. Such a manual intervention, as root nevertheless, is equivalent to execute chmod 000 directly!
I am still curious why it does not work outright, but until I find an automatic way I will keep the rm command.

Offline

Board footer

Powered by FluxBB