You are not logged in.

#1 2014-07-27 22:46:15

thelollies
Member
Registered: 2013-04-20
Posts: 21

[Solved] Udev/systemd confusion

I'm trying to use udev and systemd to change my audio output to hdmi when hdmi is plugged in and change it back when it is removed. After reading around it seems that firing off a systemd service from udev is the right why to do it. Currently this is what I have:

Udev rule:

cat /etc/udev/rules.d/hdmi_sound.rules                                  ~
KERNEL=="card0", SUBSYSTEM=="drm", ACTION=="change", ENV{SYSTEMD_WANTS}=="hdmitoggle.service"

Systemd service:

cat /etc/systemd/system/hdmitoggle.service                              ~
[Unit]
Description=Toggle audio when hdmi inserted or removed

[Service]
ExecStart=/etc/pulse/hdmi-toggle.sh
User=georgia

Script:

cat /etc/pulse/hdmi-toggle.sh                                           ~
#! /bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>/home/georgia/log.out 2>&1

#export PULSE_RUNTIME_PATH="/run/user/1000/pulse/"
#export DISPLAY=:0
read hdmi_status < /sys/class/drm/card0-HDMI-A-1/status
echo $hdmi_status
if [[ $hdmi_status  == "connected" ]]; then
    echo "trying to set to hdmi"
    pacmd "set-card-profile 0 output:hdmi-stereo"
else
    echo "trying to set to analog"
    pacmd "set-card-profile 0 output:analog-stereo"
fi

The first three lines set the rest of the script to redirect stdout to ~/log.out. The confusing thing is the systemd service seems to only get run on boot (it is not enabled) and is not run when I unplug or plug in the hdmi. There is also an issue whereby pacmd doesn't seem to be able to see the PulseAudio daemon but this could be because it is getting called during boot.

I should note that the script works fine when just run normally. Also the contents of ~/log.out are (after the service runs during boot):

cat log.out                                                             ~
/etc/pulse/hdmi-toggle.sh: line 8: /sys/class/drm/card0-HDMI-A-1/status: No such file or directory

trying to set to analog
No PulseAudio daemon running, or not running as session daemon.

log.out looks like this after just running it normally:

disconnected
trying to set to analog

Last edited by thelollies (2014-07-28 05:21:12)

Offline

#2 2014-07-27 22:54:48

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,648
Website

Re: [Solved] Udev/systemd confusion

I've never been very good with udev rules - but that one just doesn't seem right.  It doesn't do anything.  The last element is just a further match criteria so the rule is only processed when there is already an environment variable with that name and value.

You could replace that systemd part with a RUN+= call to your script - though I don't know if this is the best way.

EDIT: I just did some research - and I may be mostly wrong about the above ... except for the difference between the double and single equals.  So at very least you'll need to change that.

Last edited by Trilby (2014-07-27 23:01:03)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3 2014-07-27 22:57:28

thelollies
Member
Registered: 2013-04-20
Posts: 21

Re: [Solved] Udev/systemd confusion

Admittedly I've never written a udev rule before, I assumed that the systemd_wants part was firing off the service. I modified it from here: http://jasonwryan.com/blog/2014/01/20/udev/

Offline

#4 2014-07-27 22:59:55

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,648
Website

Re: [Solved] Udev/systemd confusion

Well JWR definitely knows better than me - but I still suspect the double quotesequals (edit dumd typo) may be a typo in his blog.  See here: http://www.reactivated.net/writing_udev_rules.html#env

Last edited by Trilby (2014-07-30 19:59:15)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#5 2014-07-27 23:13:31

thelollies
Member
Registered: 2013-04-20
Posts: 21

Re: [Solved] Udev/systemd confusion

Ah I see what you're saying, I've changed it to single =. Unfortunately the script still doesn't seem to be run (I realised I had the service enabled so I've disabled it and it no longer runs on boot which is good).

It now looks like:

cat /etc/udev/rules.d/hdmi_sound.rules                                  ~
KERNEL=="card0", SUBSYSTEM=="drm", ACTION=="change", ENV{SYSTEMD_WANTS}="hdmitoggle.service"

I should add that this is the result of running udevadm monitor whilst I plug in and then unplug the hdmi:

KERNEL[313.446792] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV  [313.448608] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
KERNEL[313.560896] change   /devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/intel_backlight (backlight)
UDEV  [313.561469] change   /devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/intel_backlight (backlight)
KERNEL[314.287011] change   /devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/intel_backlight (backlight)
UDEV  [314.287933] change   /devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/intel_backlight (backlight)
KERNEL[319.444255] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV  [319.446045] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
KERNEL[319.534471] change   /devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/intel_backlight (backlight)
UDEV  [319.535301] change   /devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/intel_backlight (backlight)
KERNEL[320.283677] change   /devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/intel_backlight (backlight)
UDEV  [320.284648] change   /devices/pci0000:00/0000:00:02.0/drm/card0/card0-LVDS-1/intel_backlight (backlight)

Last edited by thelollies (2014-07-27 23:16:12)

Offline

#6 2014-07-27 23:26:34

qinohe
Member
From: Netherlands
Registered: 2012-06-20
Posts: 1,494

Re: [Solved] Udev/systemd confusion

Hi, could you try it with this for systemd
Btw. you can log with syslog or journal(which is standard)

[Unit]
Description=Toggle audio when hdmi inserted or removed

[Service]
ExecStart=/etc/pulse/hdmi-toggle.sh
Type=oneshot
RemainAfterExit=yes
StandardOutput=syslog
User=georgia

[Install]
WantedBy=multi-user.target

Offline

#7 2014-07-27 23:38:55

thelollies
Member
Registered: 2013-04-20
Posts: 21

Re: [Solved] Udev/systemd confusion

qinohe wrote:

Hi, could you try it with this for systemd
Btw. you can log with syslog or journal(which is standard)

[Unit]
Description=Toggle audio when hdmi inserted or removed

[Service]
ExecStart=/etc/pulse/hdmi-toggle.sh
Type=oneshot
RemainAfterExit=yes
StandardOutput=syslog
User=georgia

[Install]
WantedBy=multi-user.target

No luck. After rebooting and trying again the hdmi still doesn't trigger the script. I'm not even sure the udev rule is running the service, is there a way to verify this? If I run

udevadm test --action="change" /devices/pci0000:00/0000:00:02.0/drm/card0

the log.out file is not generated and nothing appears in

systemctl status hdmitoggle.service -l

Offline

#8 2014-07-28 05:20:24

thelollies
Member
Registered: 2013-04-20
Posts: 21

Re: [Solved] Udev/systemd confusion

I found that I needed to tag my udev rule but this still didn't help. In the end I started to doubt whether handing off to a systemd service which in turn hands off to a script made sense so decided to go back to using RUN+= to run a script straight from UDEV. I tinkered with my script and managed to get it working through udev, the end product:

cat /etc/pulse/hdmitoggle.sh                                          
#! /bin/bash

printenv
export PULSE_RUNTIME_PATH="/run/user/1000/pulse/"
export DISPLAY=:0
read hdmi_status < /sys/class/drm/card0-HDMI-A-1/status
echo $hdmi_status
sleep 1
if [[ $hdmi_status  == "connected" ]]; then
    pacmd set-card-profile 0 "output:hdmi-stereo"
else
    pacmd set-card-profile 0 "output:analog-stereo"
fi
cat /etc/udev/rules.d/10-local.rules                                    
SUBSYSTEM=="drm", ACTION=="change", RUN+="/bin/bash /etc/pulse/hdmitoggle.sh"

Offline

#9 2014-07-28 06:17:54

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

Re: [Solved] Udev/systemd confusion

The reason you would hand it off to systemd is because udev does not handle any long running processes.  So if you script happens to get stuck somewhere, udev will actually just kill it. 

That said, I know others who have used RUN+="/path/to/script" just fine for this type of thing.

Offline

#10 2014-07-30 19:08:29

thelollies
Member
Registered: 2013-04-20
Posts: 21

Re: [Solved] Udev/systemd confusion

Yeah that's why I went down the systemd path in the first place until it occured to me that my script should only run for a very short amount of time. For future reference, any idea why I couldn't get the systemd handoff working correctly? At best it only ran once (at boot).

Offline

Board footer

Powered by FluxBB