You are not logged in.

#1 2013-11-12 21:58:48

sciopath
Member
Registered: 2013-11-03
Posts: 5

udev rule stops after a few seconds

Hi,

Context (arch x86_64): I want to use my dualshock 3 to play steam games. qtsixa is installed to connect to my ds3 with bluetooth. I also need xboxdrv in order to map my gamepad buttons to match the xbox360 pattern: although some games where ported to linux straight from windows (exclusive support of xbox360 controller; no possible remap), they perfectly works with that driver.

I wrote a simple /etc/udev/rules.d/81-local.rules:

KERNELS=="input[0-9]*", SUBSYSTEMS=="input", ATTRS{name}=="PLAYSTATION(R)3 Controller (secret_mac)", RUN+="/etc/ds3_map"

... don't have much choice:

[root@obocho-ato ~]# udevadm info -a -p $(udevadm info -q path -n /dev/input/js1)

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/virtual/input/input17/js1':
    KERNEL=="js1"
    SUBSYSTEM=="input"
    DRIVER==""

  looking at parent device '/devices/virtual/input/input17':
    KERNELS=="input17"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{name}=="PLAYSTATION(R)3 Controller (secret_mac)"
    ATTRS{phys}==""
    ATTRS{uniq}==""
    ATTRS{properties}=="0"

[root@obocho-ato ~]#

And /etc/ds3_map:

#!/bin/bash

## dualshock 3
#echo run >> /root/test
INPU_NUMB=$(dmesg | tail -2 | grep 'PLAYSTATION(R)3' | awk -F "/input/" '{print$2}')
#echo $INPU_NUMB >> /root/test
EVEN_NUMB=$(ls /sys/devices/virtual/input/$INPU_NUMB/ | grep 'event[0-9]*' | grep -v 'uevent')
#echo $EVEN_NUMB >> /root/test
xboxdrv	--evdev /dev/input/$EVEN_NUMB \
	\
	--evdev-absmap ABS_X=x1,ABS_Y=y1 \
	--evdev-absmap ABS_Z=x2,ABS_RX=y2 \
	--evdev-absmap ABS_#12=lt,ABS_#13=rt \
	\
	--evdev-keymap KEY_#302=a,KEY_#301=b,BTN_DEAD=x,KEY_#300=y \
	--evdev-keymap BTN_TRIGGER=back,BTN_A=guide,BTN_TOP=start \
	--evdev-keymap BTN_THUMB=tl,BTN_THUMB2=tr \
	--evdev-keymap BTN_BASE5=lb,BTN_BASE6=rb  \
	--evdev-keymap BTN_TOP2=du,BTN_PINKIE=dr,BTN_BASE=dd,BTN_BASE2=dl \
	\
	--axismap -y1=y1,-y2=y2 \
	--mimic-xpad \
	--silent

The first part is the way I -barely, not good in bash- found to automatically detect the right event number required by xboxdrv command to remap correctly my ds3.

If I executive that script by hand, it works like a charm.
If I use the udev rule to launch the script when my ds3 is appaired, it works for something like 20 to 60 seconds before the script stops.
How can I debug that?

Thanks!

Last edited by sciopath (2013-11-12 22:01:08)

Offline

#2 2013-11-12 22:29:10

cris9288
Member
Registered: 2013-01-07
Posts: 347

Re: udev rule stops after a few seconds

Someone correct me if i'm wrong, but doesn't udev try and kill a script it launches after a certain period of time if it hasn't already completed. I'll see if I can dig up where I read this, brb...

Offline

#3 2013-11-13 00:03:30

WonderWoofy
Member
From: Los Gatos, CA
Registered: 2012-05-19
Posts: 8,412

Re: udev rule stops after a few seconds

cris9288 wrote:

Someone correct me if i'm wrong, but doesn't udev try and kill a script it launches after a certain period of time if it hasn't already completed. I'll see if I can dig up where I read this, brb...

This is indeed true.  Udev is not meant to launch long running scripts or programs like this.  It is by design.

If you want to do something like this, make a systemd service file that launches your script, and then have the udev rule launch the systemd service.  You can use ENV{SYSTEMD_WANTS}+="whatever.service" in the udev rule.

Offline

#4 2013-11-13 20:13:30

sciopath
Member
Registered: 2013-11-03
Posts: 5

Re: udev rule stops after a few seconds

Thank you for your replies.

I'm not familiar with systemd service creation; have to learn something new.

Offline

#5 2013-11-14 00:43:18

WonderWoofy
Member
From: Los Gatos, CA
Registered: 2012-05-19
Posts: 8,412

Re: udev rule stops after a few seconds

Don't worry, its a pretty easy syntax to learn... ini style.

Offline

#6 2013-11-17 22:10:04

sciopath
Member
Registered: 2013-11-03
Posts: 5

Re: udev rule stops after a few seconds

Ok, so I spent some time tonight trying to get it work: no luck.

[root@obocho-ato ~]# cat /etc/udev/rules.d/81-local.rules 
#KERNELS=="input[0-9]*", SUBSYSTEMS=="input", ATTRS{name}=="PLAYSTATION(R)3 Controller (secret_mac)", RUN+="/etc/ds3_map"
KERNELS=="input[0-9]*", SUBSYSTEMS=="input", ATTRS{name}=="PLAYSTATION(R)3 Controller (secret_mac)", TAG+="systemd", ENV{SYSTEMD_WANTS}+="testtest.service"

And even a real simple service (inspired by the sixad driver) like this one doesn't give the expected result:

[root@obocho-ato ~]# cat /etc/systemd/system/testtest.service 
[Unit]
Description=test
# It does not conflict, if the input plugin is disabled.
#Conflicts=bluetooth.service
After=bluetooth.target
Requires=bluetooth.service

[Service]
Type=simple
ExecStart=/usr/bin/echo "1-2 1-2" >> /root/test
#Restart=on-failure

[Install]
WantedBy=bluetooth.target
#WantedBy=multi-user.target

[root@obocho-ato ~]# systemctl enable testtest

Nothing happens when I connect my gamepad. What am I missing?

Offline

#7 2013-11-17 22:23:28

WonderWoofy
Member
From: Los Gatos, CA
Registered: 2012-05-19
Posts: 8,412

Re: udev rule stops after a few seconds

The ExecStart= line is not a shell.  Therefore pipes and redirects do not work.  You need to either write it as an actual shell script that is run by the service, or use a direct call to bash to spawn a shell and command (see below).

<snip>
ExecStart=/usr/bin/bash -c 'echo "1-2 1-2" >> /root/test'
<snip> 

In that particular instance, you should probably also use a Type=oneshot since it is a single command that is fully expected to exit.  I'm not sure about what Type you will need with your actual, non-test, service file.

Offline

#8 2013-11-17 23:00:07

sciopath
Member
Registered: 2013-11-03
Posts: 5

Re: udev rule stops after a few seconds

WonderWoofy wrote:

The ExecStart= line is not a shell.  Therefore pipes and redirects do not work.  You need to either write it as an actual shell script that is run by the service, or use a direct call to bash to spawn a shell and command (see below).

<snip>
ExecStart=/usr/bin/bash -c 'echo "1-2 1-2" >> /root/test'
<snip> 

In that particular instance, you should probably also use a Type=oneshot since it is a single command that is fully expected to exit.  I'm not sure about what Type you will need with your actual, non-test, service file.

Good point, replacing by 

ExecStart=/etc/ds3_map

with the

echo run >> /root/test

uncommented in my first post script creates the file.

So I guess the script fully execute then quit immediately after the service launch. Ideally, it should only quit when I disconnect the device.

Offline

#9 2013-11-17 23:57:36

WonderWoofy
Member
From: Los Gatos, CA
Registered: 2012-05-19
Posts: 8,412

Re: udev rule stops after a few seconds

See the systemd man pages to see how make it stay active after it finishes the command.  I have never tried to use a udev rule to stop a system unit though... so I'm not sure how you would go about that.

Offline

Board footer

Powered by FluxBB