StartingSysVStyle

From MLDonkey
Jump to: navigation, search

Contents

Debian

MLDonkey is a badly-behaving program for an unixish environment in that sense that it expects to find it's configuration and state files from it's current work directory. In the unix-world, this is not the way to do things. Configuration files ought to reside inside the /etc directory structure, and state in /var, and for locally installed programs that are not thought of to be a part of the operating system itself, the respective directories are /local/etc and /local/var.

Since version 2.6.1 MLDonkey stores its files in $HOME/.mldonkey

Putting ini files in /etc and data in /var is not that easy because on a server system there can be several MLDonkey daemons working by different users.

Note that the "current work directory" is not the same thing as path of the executable file itself; for example when running the ls program from /bin/ls while in directory /foo/bar, the work directory of the program is /foo/bar, not /bin.

Solutions

Re-design the MLDonkey's idea of where to store files

Like said, expecting to find or create configuration and state files in the current work directory is not the usual way to do things in the unix-world.

Also no clear distinction between state and configuration exists in the core design, or phrased another way, the configuration is a set of parameters of the core state. Thus every time the state is saved, either by automatically every now and then (every 11 minutes, I think), or manually with the save command by the user, the configuration files are also (unconditionally) overwritten. Thus all configuration of the core must be made through an interface to the core itself, not by fiddling with the configuration files themselves if there modifications are expected to last.

If the MLDonkey core was like any other unixy daemon, no special arrangements needed to be made to start it in the usual SysV vein.

Start the core from a wrapper

This is how I've set up MLDonkey core to start up SysV style, from /etc/init.d. I have a meta-user called mldonkey for running the core, and the MLDonkey related programs are in it's home directory, /home/mldonkey. A wrapper script exists in /usr/local/bin, and it's called mldonkey.sh. Another file is in /etc/init.d, and this is called mldonkey and is symlinked to from the runlevel-directories.

Both of these files are being used on a Debian system with core version 2.4-rc8, but should work on all relatively unixy systems with no or little modifications.

(editor's note: I've included the files inline here, but they propably ought to be split into their own files. also, if you fiddle with the files as seen here, do state so)

Here are the files.

/usr/local/bin/mldonkey.sh:

#!/bin/bash
#
# a script that chdir(2)s to a directory, exec(3)s the mldonkey core
# passing all it's commandline parameters, and redirects the stdout to
# file.
#
# created to be used from an init.d -script, because MLDonkey expects
# the current work directory to be it's own, causing a lot of
# configuration and state files to be created there (if permitted)
#
# This file is protected by the GNU General Public License.
#
# mace
# ke touko 21 18:18:01 EEST 2003

# i believe that mlnet could be moved to /usr/local/bin
# MLBIN="/usr/local/bin/mlnet"
MLBIN="/home/mldonkey/mlnet"
MLDIR="/home/mldonkey"
MLOUT="$MLDIR/mldonkey.stdout"
MLOPT="$@ >>$MLOUT"

cd $MLDIR
echo "$(date)" >>$MLOUT
echo "''''''* MLDonkey starting via $0" >>$MLOUT
eval exec $MLBIN $MLOPT &

/etc/init.d/mldonkey

#! /bin/sh
#
# mldonkey      init.d script to start MLDonkey
#
#               Modified from "skeleton" by M. Smoorenberg and I.
#               Murdock.
#
# This file is protected by the GNU General Public License.
#
# mace
# ke touko 21 18:17:51 EEST 2003

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/mldonkey.sh
NAME=MLDonkey
DESC="MLDonkey, multinet peer-to-peer server/client"

test -x $DAEMON || exit 0

set -e

case "$1" in
  start)
        echo -n "Starting $DESC: $NAME"
        start-stop-daemon --start --chuid mldonkey \
                --pidfile /var/run/$NAME.pid --exec $DAEMON
        echo "."
        ;;
  stop)
        echo -n "Stopping $DESC: $NAME "
        start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
                --exec $DAEMON
        echo "."
        ;;
  #reload)
        #
        #       If the daemon can reload its config files on the fly
        #       for example by sending it SIGHUP, do it here.
        #
        #       If the daemon responds to changes in its config file
        #       directly anyway, make this a do-nothing entry.
        #
        # echo -n "Reloading $DESC configuration..."
        # start-stop-daemon --stop --signal 1 --quiet --pidfile \
        #       /var/run/$NAME.pid --exec $DAEMON
        # echo "done."
  #;;
  restart|force-reload)
        #
        #       If the "reload" option is implemented, move the "force-reload"
        #       option to the "reload" entry above. If not, "force-reload" is
        #       just the same as "restart".
        #
        echo -n "Restarting $DESC: $NAME"
        start-stop-daemon --stop --quiet --pidfile \
                /var/run/$NAME.pid --exec $DAEMON
        sleep 1
        start-stop-daemon --start --quiet --pidfile \
                /var/run/$NAME.pid --exec $DAEMON
        echo "."
        ;;
  *)
        N=/etc/init.d/$NAME
        # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
        echo "Usage: $N {start|stop|restart|force-reload}" >&2
        exit 1
        ;;
esac

exit 0

To launch this script automatically when machine boots up and to be able to execute /etc/init.d/mldonkey {start|stop|restart|force-reload}:

chmod +x /etc/init.d/mldonkey
update-rc.d mldonkey start 98 2 3 4 5 . stop 20 0 1 6 .

To do about this page:

The core should handle the TERM signal, sent by standard kill, just fine /Pango

I've seen at least another ocaml daemon working that way, so I guess it's a caml tradition vs unix tradition problem. It also has the advantage of being more platform agnostic (for the best and for the worse). Separating setup from state is another problem that has its roots in the use of the Options module. I'm not sure how to fix it (if it needs to be) /Pango

~RedHat (-like)

/etc/rc.d/init.d/mldonkeyd:

#!/bin/bash
#
# mldonkeyd	This shell script takes care of starting and stopping
#		the mldonkey file-sharing client.
#
# description:	mldonkey filesharing client.
# processname: mldonkey

# Source function library.
. /etc/rc.d/init.d/functions

# Adjust these value to your needs
prog="MlDonkey"                 # Name of program
nice_level=18                   # nice level
user=mldonkey                   # Username to run mldonkey

dl_rate_fast=90
upload_rate_fast=12
connections_fast=800
dl_rate_slow=60
upload_rate_slow=10
connections_slow=400

# Make sure the path to all of the binaries is right
awk=/bin/awk			# awk
grep=/bin/grep			# grep
nc=/usr/bin/nc			# perhaps named netcat on your system
renice=/usr/bin/renice		# renice
sleep=/bin/sleep		# sleep
sudo=/usr/bin/sudo		# sudo
su=/bin/su			# su
ddir=/home/mldonkey/bin		# path to mldonkey
bin=mldonkey			# program name

# The Script

start(){
  # cheching for another mldonkey session
  status $ddir/$bin > /dev/null
  ret=$?

  # if none found, start mldonkey
  if [[ $ret -eq 3 ]]; then
    cd $ddir

    # Remove old servers
    rm -Rf servers.ini*

    # Remove tmp files
    rm -Rf *.tmp

    #  you should not change this lines...
    $sudo -u $user $ddir/$bin > /dev/null 2>&1 &
    ret=$?

    if [[ $ret -eq 0 ]]; then
      action $"Starting $prog: " /bin/true

      $sleep 5
      $renice $nice_level -u $user > /dev/null

      # Overnet Support
      #OVER_IP1=resolveip overnet.dyndns.org || $awk '{print $6}'
      #OVER_PR1=4665
      #OVER_IP2=Resolveip fudge.punkcookies.com || $awk '{print $6}'
      #OVER_PR2=12000
      #boot $OVER_IP1 $OVER_PR1
      #boot $OVER_IP2 $OVER_PR2

      # you can change or add commands below the first STOPHERE and q
      #
      # open Connection to telnet interface
      sh -c "$nc localhost 4000 > /dev/null <<STOPHERE
        clh
	ovweb
	q
      STOPHERE"

    else
      action $"Starting $prog: " /bin/false
    fi

    [[ $ret -eq 0 ]] && touch /var/lock/mldonkey-client
    return $ret

  else
    action $"Starting $prog failed (allready active) " /bin/false
    return $ret
  fi
}

stop(){
  sh -c "$nc localhost 4000 > /dev/null  <<STOPHERE
    commit
    close_fds
    kill
  STOPHERE"
  ret=$?

  if [[ $ret -eq 0 ]]; then
    # better sleep a while, before killing
    $sleep 20

    # kill mldonkey if it is still running
      ps ax |$grep $ddir/$bin |$grep -v $grep |$awk '{print "kill" $1}'| sh

      action $"Stopping $prog: " /bin/true
  else
      action $"Stopping $prog: " /bin/false
  fi
  #  for status
  rm -f /var/lock/mldonkey-client
  return $ret
}

restart(){
  stop
  start
}

fast(){
  # cheching for mldonkey session
  status $ddir/$bin > /dev/null
  ret=$?

  # if none found, start mldonkey
  if [[ $ret -eq 3 ]]; then
    start
  fi

  sh -c "$nc localhost 4000 > /dev/null << STOPHERE
        set max_hard_download_rate $dl_rate_fast
        set max_hard_upload_rate $upload_rate_fast
        set max_opened_connections $connections_fast
        q
  STOPHERE"
}

slow(){
  # cheching for mldonkey session
  status $ddir/$bin > /dev/null
  ret=$?

  # if none found, start mldonkey
  if [[ $ret -eq 3 ]]; then
    start
  fi

  sh -c "$nc localhost 4000 > /dev/null << STOPHERE
        set max_hard_download_rate $dl_rate_slow
        set max_hard_upload_rate $upload_rate_slow
        set max_opened_connections $connections_slow
        q
  STOPHERE"
}



# See how we were called.
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status $ddir/$bin
    ;;
  restart)
    restart
    ;;
  slow)
    slow
    ;;
  fast)
    fast
    ;;
  *)
    echo $"Usage: $0 {start|stop|status|restart|slow|fast}"
    exit 1
esac

exit $?

(written by Christoph for RedHat 8.0, check thread [Forums&fileviewtopic&t=902 here])

For mldonkey 2.6.1 and later, you would also need to check whether mldonkey died not gracely (due to a power loss or whatever). Mldonkey creates a pid file with the process ID of mlnet process. The file is located in $HOME/.mldonkey/mlnet.pid. You should delete it BEFORE starting mldonkey.

Here it is a modified version of the start subcommand:

pid_file=$ddir/.mldonkey/mlnet.pid  # PID of mlnet

# The Script

start(){
  # cheching for another mldonkey session
  status $ddir/$bin > /dev/null
  ret=$?

  # if none found, start mldonkey
  if [[ $ret -eq 3 ]]; then
    cd $ddir

    # Remove old servers
    rm -Rf servers.ini*

    # Remove tmp files
    rm -Rf *.tmp

    # NEW!!
    # Delete the PID file if mlnet is not running
    [[ -f $pid_file ]] && ! pgrep mlnet 2>&1 >/dev/null && rm -Rf $pid_file

    #  you should not change this lines...
    $su - $user -c $ddir/$bin > /dev/null 2>&1 &
    ret=$?

    if [[ $ret -eq 0 ]]; then
      action $"Starting $prog: " /bin/true

      $sleep 5
      $renice $nice_level -u $user > /dev/null

      # Overnet Support
      #OVER_IP1=resolveip overnet.dyndns.org | $awk '{print $6}'
      #OVER_PR1=4665
      #OVER_IP2=Resolveip fudge.punkcookies.com | $awk '{print $6}'
      #OVER_PR2=12000
      #boot $OVER_IP1 $OVER_PR1
      #boot $OVER_IP2 $OVER_PR2

      # you can change or add commands below the first STOPHERE and q
      #
      # open Connection to telnet interface
      sh -c "$nc localhost 4000 > /dev/null <<STOPHERE
        auth admin mypassword
        clh
        ovweb
        q
      STOPHERE"

    else
      action $"Starting $prog: " /bin/false
    fi

    [[ $ret -eq 0 ]] && touch /var/lock/mldonkey-client
    return $ret

  else
    action $"Starting $prog failed (already active) " /bin/false
    return $ret
  fi
}
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox