# Need little help with UDEV (SOLVED)

## devsk

I want to assign /dev/video0 to the webcam (because that's the only way skype works with it) and assign /dev/video1 to the pvrusb2 device. I wrote this simple (but crazy) rule:

```
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{name}=="UVC Camera (046d:0991)", SYMLINK+="v4l/webcam", PROGRAM="/bin/sh -c '/bin/ln -sf /dev/v4l/webcam /dev/video0;/bin/ln -sf /dev/v4l/pvrusb2 /dev/video1'"

KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{name}=="", SYMLINK+="v4l/pvrusb2", PROGRAM="/bin/sh -c '/bin/ln -sf /dev/v4l/webcam /dev/video0;/bin/ln -sf /dev/v4l/pvrusb2 /dev/video1'"
```

And I get:

```
# l video[0-9]

lrwxrwxrwx 1 root root 15 Jun 21 21:12 video0 -> /dev/v4l/webcam

lrwxrwxrwx 1 root root 10 Jun 21 21:12 video1 -> v4l/video1

```

What I had expected was:

```
# l video[0-9]

lrwxrwxrwx 1 root root 15 Jun 21 21:13 video0 -> /dev/v4l/webcam

lrwxrwxrwx 1 root root 16 Jun 21 21:13 video1 -> /dev/v4l/pvrusb2
```

As you can see, its inherently racy because once udev finishes executing PROGRAM, the links are fine but when pvrusb2 finishes loading it replaces /dev/video1 link with the v4l/video1. It happens to be correct in this case but it can easily create a mess.

The basic problem is that I want a proper symlink for /dev/video0 which UDEV allows but the symlink gets replaced by the driver itself to point to the v4l/video* location. So, depending upon who (pvrusb2/uvcvideo or UDEV) wins the race, I get right or wrong symlinks.

One solution can be that I have a cron job running which can rectify the symlinks every 5 seconds with:

```
/bin/ln -sf /dev/v4l/webcam /dev/video0;/bin/ln -sf /dev/v4l/pvrusb2 /dev/video1
```

 but that sounds like crazy hack and may interfere with both driver loading and udev doing its thing.

I also tried putting sleep in PROGRAM="/bin/sh -c 'sleep 10;/bin/ln -sf...'" but that didn't help.

Anybody got better ideas?Last edited by devsk on Tue Jun 24, 2008 7:57 pm; edited 1 time in total

----------

## devsk

I know people around here (except me of course...  :Razz:  ) have the smarts. So, where are the ideas? c'mon people!

----------

## devsk

anyone? what happened to the UDEV experts around here?

----------

## PaulBredbury

Sounds like you want:

```
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{name}=="UVC Camera (046d:0991)", SYMLINK+="video0"

KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{name}=="", SYMLINK+="video1"
```

 *Quote:*   

> but the symlink gets replaced by the driver itself

 

What? What driver? Surely you mean "another udev rule"? In which case, there is OPTIONS="last_rule"

----------

## devsk

 *PaulBredbury wrote:*   

> Sounds like you want:
> 
> ```
> KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{name}=="UVC Camera (046d:0991)", SYMLINK+="video0"
> 
> ...

 No, I meant the pvrusb2 driver. Here is what I get with the above rules (which is BTW the first thing I tried) after modprobe pvrusb2:

```
# l /dev/video[01]

lrwxrwxrwx 1 root root 10 Jun 24 09:55 /dev/video0 -> v4l/video0

lrwxrwxrwx 1 root root 10 Jun 24 09:55 /dev/video1 -> v4l/video0

# l /dev/v4l/

total 0

drwxr-xr-x  2 root root      80 Jun 24 09:55 ./

drwxr-xr-x 17 root root   15860 Jun 24 09:55 ../

crw-rw----  1 root video 81, 64 Jun 24 09:55 radio0

crw-rw----  1 root video 81,  0 Jun 24 09:55 video0

```

Here is what I get with "last_rule":

```
# l /dev/video[01]

crw-rw---- 1 root root 81, 0 Jun 24 09:56 /dev/video0

lrwxrwxrwx 1 root root     6 Jun 24 09:56 /dev/video1 -> video0

# l /dev/v4l/

total 0

drwxr-xr-x  2 root root      60 Jun 24 09:56 ./

drwxr-xr-x 17 root root   15840 Jun 24 09:56 ../

crw-rw----  1 root video 81, 64 Jun 24 09:56 radio0

```

In both cases video0 is taken by the pvrusb2, exactly opposite of what I wanted.

----------

## PaulBredbury

Sounds like both rules are matching for the same device. There's a difference between ATTR and ATTRS - man udev explains.

Get debugging:

```
udevcontrol log_priority=debug
```

----------

## devsk

 *PaulBredbury wrote:*   

> Sounds like both rules are matching for the same device. There's a difference between ATTR and ATTRS - man udev explains.
> 
> Get debugging:
> 
> ```
> ...

 OK, changed to ATTR but the confusion continues. I will post the debug later.

After modprobe pvrusb2:

```
# l /dev/video[01]

lrwxrwxrwx 1 root root 10 Jun 24 11:14 /dev/video0 -> v4l/video0

lrwxrwxrwx 1 root root 10 Jun 24 11:14 /dev/video1 -> v4l/video0

```

After modprobe uvcvideo:

```
# l /dev/video[01]

lrwxrwxrwx 1 root root 10 Jun 24 11:15 /dev/video0 -> v4l/video1

lrwxrwxrwx 1 root root 10 Jun 24 11:15 /dev/video1 -> v4l/video1

```

----------

## devsk

Ok, I think we are getting closer. I removed the SYMLINK from the following line from file 40-video.rules and everything works like I need it:

```

# KERNEL=="video[0-9]*",        NAME="v4l/video%n", SYMLINK+="%k", GROUP="video"

KERNEL=="video[0-9]*",  NAME="v4l/video%n", GROUP="video"

```

What was happening was that it creates its own symlink from this file and it is opposite of the symlink that I want, and hence one module overwrites the symlink of the other.

Now, how do I make this change permanent?

----------

## PaulBredbury

Overrule 40-video.rules, by using OPTIONS="last_rule"

Alternatively, you could name your file 91-local.rules and use SYMLINK= instead of SYMLINK+=

Note the removal of the plus sign.

----------

## devsk

Ok got it! This is what worked without changing 40-video.rules.

```
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTR{name}=="UVC Camera (046d:0991)",  NAME="v4l/video%n", GROUP="video", SYMLINK="video0", OPTIONS="last_rule"

KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTR{name}=="",  NAME="v4l/video%n", GROUP="video", SYMLINK="video1", OPTIONS="last_rule"
```

The key was SYMLINK= instead of +=, adding NAME and OPTIONS="last_rule".

Thanks Paul for the help! Appreciate it!

----------

