Transmission-daemon init script with multiuser

Discussion of Transmission that doesn't fit in the other categories
Post Reply
simonbcn
Posts: 21
Joined: Fri May 08, 2009 1:10 am

Transmission-daemon init script with multiuser

Post by simonbcn »

Hi,
I've installed transmission-daemon on a server (with Ubuntu 11.04) from sources. I have created several init.d files to several users (each user has its transmission-daemon process with its config and its download folders).

I have used the init script in deb files (from Transmission stable PPA) adapted to my needs:

Code: Select all

#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          transmission-daemon
# Required-Start:    $local_fs $remote_fs $network
# Required-Stop:     $local_fs $remote_fs $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start or stop the transmission-daemon.
### END INIT INFO

NAME=transmission-daemon
DAEMON=/usr/local/bin/$NAME
USER=user
STOP_TIMEOUT=3
CONFIGDIR=/home/$USER/.config/transmission-daemon
PIDFILE=$CONFIGDIR/daemon.pid
OPTIONS="--config-dir $CONFIGDIR --logfile $CONFIGDIR/daemon.log"

export PATH="${PATH:+$PATH:}/sbin"

[ -x $DAEMON ] || exit 0

. /lib/lsb/init-functions

case "$1" in
    start)
        log_daemon_msg "Starting bittorrent daemon" "$NAME"
        start-stop-daemon --start --pidfile $PIDFILE --chuid $USER --exec $DAEMON -- $OPTIONS
        log_end_msg 0
        ;;
    stop)
        log_daemon_msg "Stopping bittorrent daemon" "$NAME"
        start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON --retry $STOP_TIMEOUT --oknodo
        log_end_msg 0
        ;;
    reload)
        log_daemon_msg "Reloading bittorrent daemon" "$NAME"
        start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON --oknodo --signal 1
        log_end_msg 0
        ;;
    restart|force-reload)
        log_daemon_msg "Restarting bittorrent daemon" "$NAME"
        start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON --retry $STOP_TIMEOUT --oknodo
        start_daemon
        log_end_msg 0
        ;;
    *)
        echo "Usage: /etc/init.d/$NAME {start|stop|reload|force-reload|restart}"
        exit 2
        ;;
esac

exit 0
It's very simply and it almost works but when I stop/reboot the server, it doesn't wait to the finish the transmission daemons.
I have searched more information about this and I've found this example in the wiki of this site, I have adapted to my needs but it doesn't work the stop part:

Code: Select all

Stopping bittorrent client transmission-daemon...
start-stop-daemon: warning: this system is not able to track process names longer than 15 characters, please use --exec instead of --name.
   Stopping bittorrent client transmission-daemon succeeded
It shows the warning in "start-stop-daemon --stop --quiet --retry=TERM/10/KILL/5 --pidfile $PIDFILE --name $NAME" ("transmission-daemon" name is > 15 characters) and it stops ALL transmission-daemons. I want only stop the transmission-daemon of that user.

Then I've tried with:

Code: Select all

#!/bin/sh 
### BEGIN INIT INFO
# Provides:          transmission-daemon
# Required-Start:    networking
# Required-Stop:     networking
# Default-Start:     2 3 5
# Default-Stop:      0 1 6
# Short-Description: Start the transmission BitTorrent daemon client.
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
DESC="bittorrent client"
NAME=transmission-daemon
DAEMON=$(which $NAME) || exit 0
USERNAME=user
SCRIPTNAME=$(basename $0)
CONFIGDIR=/home/$USERNAME/.config/transmission-daemon
PIDFILE=/var/run/$SCRIPTNAME.pid
TRANSMISSION_ARGS="-f --config-dir $CONFIGDIR --logfile $CONFIGDIR/daemon.log"

do_start()
{
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    start-stop-daemon --chuid $USERNAME --start --pidfile $PIDFILE --make-pidfile \
            --exec $DAEMON --background --test -- $TRANSMISSION_ARGS > /dev/null \
            || return 1
    start-stop-daemon --chuid $USERNAME --start --pidfile $PIDFILE --make-pidfile \
            --exec $DAEMON --background -- $TRANSMISSION_ARGS \
            || return 2
}

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/10/KILL/5 --pidfile $PIDFILE --exec $DAEMON
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2

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

        return "$RETVAL"
}

case "$1" in
  start)
        echo "Starting $DESC" "$NAME..."
        do_start
        case "$?" in
                0|1) echo "   Starting $DESC $NAME succeeded" ;;
                *)   echo "   Starting $DESC $NAME failed" ;;
        esac
        ;;
  stop)
        echo "Stopping $DESC $NAME..."
        do_stop
        case "$?" in
                0|1) echo "   Stopping $DESC $NAME succeeded" ;;
                *)   echo "   Stopping $DESC $NAME failed" ;;
        esac
        ;;
  restart)
        echo "Restarting $DESC $NAME..."
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                    0|1) echo "   Restarting $DESC $NAME succeeded" ;;
                    *)   echo "   Restarting $DESC $NAME failed: couldn't start $NAME" ;;
                esac
                ;;
          *)
                echo "   Restarting $DESC $NAME failed: couldn't stop $NAME" ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
        exit 3
        ;;
esac
In this way it seems to work.

To create the init script links I have executed:

Code: Select all

update-rc.d trans-user start 30 2 3 5 . stop 70 0 1 6 .

Is this correct?

If anyone has one suggestion or improvement, I appreciate it.

One note. In script of wiki page there is an error with the lines:

Code: Select all

DAEMON=$(which $NAME)
....
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
It doesn't work. If DAEMON doesn't exist "which" returns an empty string and then "[ -x "$DAEMON" ]" doesn't fail.
It's better this: "DAEMON=$(which $NAME) || exit 0", in same line it retrieves the path of DAEMON or it exits if it doesn't exist.
Regards.
killemov
Posts: 542
Joined: Sat Jul 31, 2010 5:04 pm

Re: Transmission-daemon init script with multiuser

Post by killemov »

There is a major flaw in the logic for your usage of the init script. And that is to take the script out of its boot/shutdown context.
You can run multiple daemons (only limited by resources but usually one for each user) by adding a few lines to some login script like .profile and give it a local configuration. ( transmission-daemon --config-dir ~/.transmission for example.) THEN you have to add functionality to gracefully kill (slay?) all the daemons users may have started when the OS shuts down.

You probably do NOT want to iterate over passwd (a file that contains all users) and create (spawn?) a daemon for each and every one.
Post Reply