StartingSysVStyle
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 init-script expects the MLDonkey core to die gracefully when signaled in the default way by the SysV system. This should be checked and if need be, the core should be sent a
kill
somehow, possibly with telnet and a here-document.
The core should handle the TERM signal, sent by standard kill, just fine /Pango
- I wish people who've packaged MLDonkey would review and comment on this. At least a Debian-package does exists, even if it would be rather unmaintained at the moment.
- I'd also like to hear from the designers of MLDonkey why it was decided for the core to expect to find the configuration&state files in the current work directory.
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
- Perhaps this issue about the core expecting to find the conf&state files in the current work directory should be split to another file alltogether, it seems to take considerable space on this page.
~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&file
viewtopic&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 }