v16 Run Kodi as specific user
#1
Hello!

This question is related to Raspberry Pi, but I think it's so general that it better fits in here.

My system (running raspbian) has two sound cards:
Code:
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 0: ALSA [bcm2835 ALSA], device 1: bcm2835 ALSA [bcm2835 IEC958/HDMI]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: sndrpihifiberry [snd_rpi_hifiberry_digi], device 0: HifiBerry Digi HiFi wm8804-spdif-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
With the help of the kind people in this forum I found a way to make Kodi use the SPDIF output for music and HDMI for everything else (see here).

However, for this solution I needed to set the SPDIF sound card as default in /etc/asound.conf.

The problem is, for the other programs on my system I would need the HDMI output as default. For example RetroPie would only use the default sound card and in this case it would be nice if this was the HDMI output.

I thought a clean way to achieve this would be a user "kodi" that runs Kodi. I followed the instructions here (http://kodi.wiki/view/HOW-TO:Autostart_K...o_run_Kodi) to create this user. In the home folder of this user I added a file .asoundrc that sets the SPDIF as default:
Code:
$ cat /home/kodi/.asoundrc
defaults.ctl.card 1
defaults.pcm.card 1
defaults.pcm.device 1

So far so good. But When I start Kodi (for example with "sudo service kodi start") the process belongs to the user "pi". Even when I'm logged in as user "kodi" I cannot start kodi:

Code:
kodi@raspberrypi:/home/pi$ kodi-standalone
[sudo] password for kodi:
("kodi" is not part of the sudo group, I am unsure if this would be a good idea).

But even if "kodi" could run kodi-standalone, I would need to make sure the kodi service would run as this user to use the correct .asoundrc.

How can this be done?

Thank you in advance!

Finally, here's the init script (it came with my kodi package):

Code:
#! /bin/sh
### BEGIN INIT INFO
# Provides:          kodi
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: XBMC media centre
# Description:       Starts the XBMC media centre in standalone mode
### END INIT INFO

# Author: Michael Gorven <[email protected]>

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="media centre"
NAME=kodi
STARTAS=/usr/bin/kodi-standalone
DAEMON=/bin/sh
DAEMON_ARGS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
GEOMETRY=/var/run/kodi.fbset

# Defaults
ENABLED=0
USER=kodi
NICE=0

# Exit if the package is not installed
[ -x "$STARTAS" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Backwards compatibility with previous package name
[ -r /etc/default/xbmc ] && . /etc/default/xbmc

# Exit if service is not enabled
[ "$ENABLED" = "1" ] || exit 0

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
    fbset --show | grep geometry | cut -d' ' -f 6- > $GEOMETRY
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    start-stop-daemon --start --quiet --pidfile $PIDFILE --user $USER --exec $DAEMON --startas $STARTAS --test > /dev/null \
        || return 1
    start-stop-daemon --start --quiet --pidfile $PIDFILE --nicelevel $NICE --chuid $USER --background --make-pidfile --exec $DAEMON --startas $STARTAS -- \
        $DAEMON_ARGS \
        || return 2
    # Add code here, if necessary, that waits for the process to be ready
    # to handle requests from services started subsequently which depend
    # on this one.  As a last resort, sleep for some time.
    sleep 10
    start-stop-daemon --start --quiet --pidfile $PIDFILE --user $USER --exec $DAEMON --startas $STARTAS --test > /dev/null \
        || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
    # Return
    #   0 if daemon has been stopped
    #   1 if daemon was already stopped
    #   2 if daemon could not be stopped
    #   other if a failure occurred
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --user $USER --exec $DAEMON --startas $STARTAS

    # Kodi doesn't actually handle signals, so we have to send an RPC request to ask it to exit
    if [ -x /usr/bin/wget ]; then
        wget --post-data '{"jsonrpc": "2.0", "method": "Application.Quit", "params": [], "id": 0}' --header 'Content-Type: application/json' -O /dev/null --quiet http://localhost:8080/jsonrpc
    fi
    # Wait for children to finish too if this is a daemon that forks
    # and if the daemon is only ever run from this initscript.
    # If the above conditions are not satisfied then add some other code
    # that waits for the process to drop all resources that could be
    # needed by services started subsequently.  A last resort is to
    # sleep for some time.
    start-stop-daemon --stop --quiet --retry=0/30/KILL/5 --user $USER --name $NAME.bin
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2

    # Many daemons don't delete their pidfiles when they exit.
    rm -f $PIDFILE

    # Try to fix the display
    VT="$(fgconsole)"
    if [ "$VT" ]; then
        chvt 7
        chvt "$VT"
    fi

    if [ -e $GEOMETRY ]; then
        fbset --geometry $(cat $GEOMETRY)
    fi

    return "$RETVAL"
}

case "$1" in
  start)
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
    do_start
    case "$?" in
        0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
        2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
    ;;
  stop)
    [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
    do_stop
    case "$?" in
        0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
        2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
    ;;
  status)
    status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
    ;;
  restart|force-reload)
    #
    # If the "reload" option is implemented then remove the
    # 'force-reload' alias
    #
    log_daemon_msg "Restarting $DESC" "$NAME"
    do_stop
    case "$?" in
      0|1)
        do_start
        case "$?" in
            0) log_end_msg 0 ;;
            1) log_end_msg 1 ;; # Old process is still running
            *) log_end_msg 1 ;; # Failed to start
        esac
        ;;
      *)
        # Failed to stop
        log_end_msg 1
        ;;
    esac
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
    exit 3
    ;;
esac

:
Reply
#2
With the help of debianforum.de I found the cause of this problem:

The /etc/default/kodi looked like this:

Code:
# Set this to 1 to enable startup
ENABLED=1

# The user to run Kodi as
USER=pi

# Adjust niceness of Kodi (decrease for higher priority)
NICE=-5

I changed USER to kodi and now the init script at least tries to start kodi as user kodi. Still this does not work because of missing privileges. I try to find out which ones...
Reply

Logout Mark Read Team Forum Stats Members Help
Run Kodi as specific user0