You are not logged in.

#1 2017-02-16 15:34:09

analbeard
Member
From: London
Registered: 2014-11-07
Posts: 48

Firing custom udev rule on plug/unplug of specific display port

I'm attempting to automate my display setup under i3 for adding/removing external displays. At the moment I'm triggering it off a USB mouse connection, but this isn't perfect. I'd rather do it with events created when I plug HDMI1/unplug DP2, however as I have two external monitors I need to be more specific than just using changes to the drm subsystem (this is because the script they call to change the layout works out how many displays are connected and configures them using preconfigured xrandr layouts I want). Currently, if I unplug/replug HDMI1 I get:

KERNEL[25116.905179] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV  [25116.907416] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)

KERNEL[25126.970943] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV  [25126.971858] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)

and for DP2 I get:

KERNEL[25132.963164] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV  [25132.965877] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)

KERNEL[25139.268747] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV  [25139.270983] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)

As you can see, these are identical and mean I can't easily watch for a specific action on a specific port.

Whilst writing this I noticed that the contents of /sys/class/drm point to different devices under /sys/devices which would allow me to pick a specific output:

lrwxrwxrwx  1 root root    0 Feb 15 17:18 card0-DP-2 -> ../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-2
lrwxrwxrwx  1 root root    0 Feb 15 17:18 card0-HDMI-A-1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-HDMI-A-1

Running udevadm info on card0-DP-2 gives the following:

  looking at device '/devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-2':
    KERNEL=="card0-DP-2"
    SUBSYSTEM=="drm"
    DRIVER==""
    ATTR{dpms}=="On"
    ATTR{edid}==""
    ATTR{enabled}=="enabled"
    ATTR{status}=="connected"

  looking at parent device '/devices/pci0000:00/0000:00:02.0/drm/card0':
    KERNELS=="card0"
    SUBSYSTEMS=="drm"
    DRIVERS==""
    ATTRS{gt_RP0_freq_mhz}=="1050"
    ATTRS{gt_RP1_freq_mhz}=="350"
    ATTRS{gt_RPn_freq_mhz}=="350"
    ATTRS{gt_act_freq_mhz}=="350"
    ATTRS{gt_boost_freq_mhz}=="1050"
    ATTRS{gt_cur_freq_mhz}=="350"
    ATTRS{gt_max_freq_mhz}=="1050"
    ATTRS{gt_min_freq_mhz}=="350"

  looking at parent device '/devices/pci0000:00/0000:00:02.0':
    KERNELS=="0000:00:02.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="i915"
    ATTRS{boot_vga}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{class}=="0x030000"
    ATTRS{consistent_dma_mask_bits}=="39"
    ATTRS{d3cold_allowed}=="1"
    ATTRS{device}=="0x191b"
    ATTRS{dma_mask_bits}=="39"
    ATTRS{driver_override}=="(null)"
    ATTRS{enable}=="1"
    ATTRS{index}=="1"
    ATTRS{irq}=="135"
    ATTRS{label}==" Onboard IGD"
    ATTRS{local_cpulist}=="0-7"
    ATTRS{local_cpus}=="ff"
    ATTRS{msi_bus}=="1"
    ATTRS{numa_node}=="-1"
    ATTRS{subsystem_device}=="0x06e4"
    ATTRS{subsystem_vendor}=="0x1028"
    ATTRS{vendor}=="0x8086"

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

So, based on this I tried the following rule:

KERNEL=="card0-DP-2", SUBSYSTEM=="drm", SUBSYSTEMS=="drm", ATTR{status}=="connected", RUN+="/path/to/script"

However, even if I add ACTION=="change" to that, nothing runs if I unplug/plug DP2. Any suggestions as to where I can go with this?

To recap (as I realise this has gone on a bit), I want to run the same script when DP2 is connected and when HDMI1 is disconnected, not at any other time. Hopefully someone has some ideas!

Last edited by analbeard (2017-02-16 15:36:44)


Late 2016 Dell XPS15 | i7-6700HQ | 16GB DDR4 | Samsung PM961 NVMe 512Gb SSD
LightDM/i3 | rEFInd | linux-ck

Offline

#2 2017-02-16 18:26:33

stupidus
Member
Registered: 2012-02-27
Posts: 124

Re: Firing custom udev rule on plug/unplug of specific display port

Could you not just use the kernel messages to see that something changed, and then run a script that uses the xrandr output to check what changed? And depending on that the script could take the appropriate action.

Offline

#3 2017-02-16 22:04:27

seth
Member
Registered: 2012-09-03
Posts: 50,012

Re: Firing custom udev rule on plug/unplug of specific display port

KERNEL=="card0-DP-2"

UDEV  [25116.907416] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)

Offline

#4 2017-02-17 08:35:12

analbeard
Member
From: London
Registered: 2014-11-07
Posts: 48

Re: Firing custom udev rule on plug/unplug of specific display port

stupidus wrote:

Could you not just use the kernel messages to see that something changed, and then run a script that uses the xrandr output to check what changed? And depending on that the script could take the appropriate action.

Sorry, when you say the kernel messages do you mean via udev? I can do this, however it's not quite how I wanted it to work. The reason for this is I plug/unplug the ports in a different order (back to front, then front to back when I disconnect everything), so unless I pull both display cables at the same time my script isn't going to get the right info (it'll see a screen connected which is about to be pulled).

seth wrote:

KERNEL=="card0-DP-2"

UDEV  [25116.907416] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)

OK, so are you implying that although udevadm info gives me the ability to distinguish between the outputs, udev isn't actually seeing this when I plug/unplug? (apologies for being dense)


Late 2016 Dell XPS15 | i7-6700HQ | 16GB DDR4 | Samsung PM961 NVMe 512Gb SSD
LightDM/i3 | rEFInd | linux-ck

Offline

#5 2017-02-17 11:52:08

seth
Member
Registered: 2012-09-03
Posts: 50,012

Re: Firing custom udev rule on plug/unplug of specific display port

You get events from "card0", not "card0-DP-2", so you'll have to listen to them, fire your script, poll the attached outputs and act accordingly.

Also the "subsystem" match is superflous if you match "subsystems" (and I don't know which takes precedence, but likely "subsystem" as it's the stronger match)

There's btw https://wiki.archlinux.org/index.php/ud … le_plug_in

And you're not "dense"; you got a slight hint on the issue to think about what you're doing. Then asked back things you're not sure about. A dense person gets a direct instruction and does anything but it ;-)

Offline

Board footer

Powered by FluxBB