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
killsomehow, 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&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
}