| 1 | #! /bin/sh |
|---|
| 2 | ### BEGIN INIT INFO |
|---|
| 3 | # Provides: boinc |
|---|
| 4 | # Required-Start: $all |
|---|
| 5 | # Required-Stop: $local_fs $remote_fs |
|---|
| 6 | # Default-Start: 2 3 4 5 |
|---|
| 7 | # Default-Stop: 0 1 6 |
|---|
| 8 | # Short-Description: BOINC core client |
|---|
| 9 | # Description: core client for the BOINC distributed computing |
|---|
| 10 | # infrastructure |
|---|
| 11 | ### END INIT INFO |
|---|
| 12 | |
|---|
| 13 | # Debian init.d script for the BOINC core client |
|---|
| 14 | # Copyright © 2005, 2006, 2007, 2008 |
|---|
| 15 | # Debian BOINC Maintainers <pkg-boinc-devel@lists.alioth.debian.org> |
|---|
| 16 | # |
|---|
| 17 | # This file is licensed under the terms of the GNU General Public License, |
|---|
| 18 | # Version 2 or any later version published by the Free Software Foundation. |
|---|
| 19 | |
|---|
| 20 | set -e |
|---|
| 21 | . /lib/lsb/init-functions |
|---|
| 22 | |
|---|
| 23 | # Default values for the variables that are also set in the defaults file. |
|---|
| 24 | ENABLED=0 |
|---|
| 25 | SCHEDULE=0 |
|---|
| 26 | BOINC_USER=boinc |
|---|
| 27 | BOINC_DIR=/var/lib/boinc-client |
|---|
| 28 | BOINC_CLIENT=/usr/bin/boinc |
|---|
| 29 | BOINC_OOM_ADJ=15 |
|---|
| 30 | |
|---|
| 31 | # Source defaults file. Edit that file to configure this script. |
|---|
| 32 | if [ -e /etc/default/boinc-client ]; then |
|---|
| 33 | . /etc/default/boinc-client |
|---|
| 34 | fi |
|---|
| 35 | |
|---|
| 36 | # Quit quietly, if $ENABLED is 0. |
|---|
| 37 | test "$ENABLED" != "0" || exit 0 |
|---|
| 38 | |
|---|
| 39 | if [ "$BOINC_CLIENT" = "/usr/bin/boinc" ]; then |
|---|
| 40 | test -x "$BOINC_CLIENT" || exit 0 |
|---|
| 41 | elif [ ! -x "$BOINC_CLIENT" ]; then |
|---|
| 42 | log_failure_msg "BOINC client '$BOINC_CLIENT' does not exist or is not" \ |
|---|
| 43 | "executable." |
|---|
| 44 | exit 5 |
|---|
| 45 | fi |
|---|
| 46 | |
|---|
| 47 | if [ ! -d "$BOINC_DIR" ]; then |
|---|
| 48 | log_failure_msg "BOINC data directory '$BOINC_DIR' does not exist." |
|---|
| 49 | exit 6 |
|---|
| 50 | fi |
|---|
| 51 | |
|---|
| 52 | if [ -z "$BOINC_USER" ]; then |
|---|
| 53 | log_failure_msg "BOINC_USER variable is empty. Set it to a user to run" \ |
|---|
| 54 | "the BOINC core client." |
|---|
| 55 | exit 6 |
|---|
| 56 | fi |
|---|
| 57 | |
|---|
| 58 | if [ ! -z "$BOINC_OPTS" ]; then |
|---|
| 59 | (echo $BOINC_OPTS | grep -- '--daemon' 1>/dev/null) && |
|---|
| 60 | log_warning_msg "\`--daemon' option detected \ |
|---|
| 61 | on /etc/default/boinc-client, this \ |
|---|
| 62 | can cause problems on boinc. The option \ |
|---|
| 63 | will be suppressed" |
|---|
| 64 | BOINC_OPTS=`echo "$BOINC_OPTS" | sed 's/--daemon//g'` |
|---|
| 65 | fi |
|---|
| 66 | |
|---|
| 67 | PIDFILE=/var/run/boinc.pid |
|---|
| 68 | DESC="BOINC core client" |
|---|
| 69 | NAME=`basename $BOINC_CLIENT` |
|---|
| 70 | BOINC_OPTS="--check_all_logins --redirectio --dir $BOINC_DIR $BOINC_OPTS" |
|---|
| 71 | |
|---|
| 72 | is_running() |
|---|
| 73 | { |
|---|
| 74 | retval=1 |
|---|
| 75 | if [ -r $PIDFILE ]; then |
|---|
| 76 | pid=`cat $PIDFILE` |
|---|
| 77 | if [ -e /proc/$pid ]; then |
|---|
| 78 | procname=`/bin/ps h -p $pid` |
|---|
| 79 | [ -n "$procname" ] && retval=0 |
|---|
| 80 | fi |
|---|
| 81 | fi |
|---|
| 82 | return $retval |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | start() |
|---|
| 86 | { |
|---|
| 87 | log_begin_msg "Starting $DESC: $NAME" |
|---|
| 88 | if is_running; then |
|---|
| 89 | log_progress_msg "already running" |
|---|
| 90 | else |
|---|
| 91 | if [ -x /usr/bin/xhost ]; then |
|---|
| 92 | # grant the boinc client to perform GPU computing |
|---|
| 93 | xhost local:boinc || echo -n "xhost error ignored, GPU computing may not be possible" |
|---|
| 94 | fi |
|---|
| 95 | start-stop-daemon --start --quiet --background --pidfile $PIDFILE \ |
|---|
| 96 | --make-pidfile --user $BOINC_USER --chuid $BOINC_USER \ |
|---|
| 97 | --chdir $BOINC_DIR --exec $BOINC_CLIENT -- $BOINC_OPTS |
|---|
| 98 | fi |
|---|
| 99 | log_end_msg 0 |
|---|
| 100 | |
|---|
| 101 | if [ "$SCHEDULE" = "1" ]; then |
|---|
| 102 | schedule |
|---|
| 103 | fi |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | stop() |
|---|
| 107 | { |
|---|
| 108 | log_begin_msg "Stopping $DESC: $NAME" |
|---|
| 109 | if ! is_running; then |
|---|
| 110 | log_progress_msg "not running" |
|---|
| 111 | else |
|---|
| 112 | start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE \ |
|---|
| 113 | --user $BOINC_USER --exec $BOINC_CLIENT |
|---|
| 114 | |
|---|
| 115 | # Wait until really stopped - $pid is set from is_running |
|---|
| 116 | # (waiting for max 60s (600 cycles at 100ms)) |
|---|
| 117 | i=0 |
|---|
| 118 | while kill -0 "$pid" 2> /dev/null; do |
|---|
| 119 | if [ $i = '600' ]; then |
|---|
| 120 | break; |
|---|
| 121 | else |
|---|
| 122 | if [ $i = '0' ]; then |
|---|
| 123 | echo -n " ... waiting " |
|---|
| 124 | elif [ $(($i%10)) = 0 ]; then |
|---|
| 125 | echo -n "." |
|---|
| 126 | fi |
|---|
| 127 | i=$(($i+1)) |
|---|
| 128 | sleep .1 |
|---|
| 129 | fi |
|---|
| 130 | done |
|---|
| 131 | fi |
|---|
| 132 | |
|---|
| 133 | rm -f "$BOINC_DIR/lockfile" |
|---|
| 134 | rm -f $PIDFILE |
|---|
| 135 | log_end_msg 0 |
|---|
| 136 | } |
|---|
| 137 | |
|---|
| 138 | chrt_many() |
|---|
| 139 | { |
|---|
| 140 | POLICY="$1" |
|---|
| 141 | PRIO="$2" |
|---|
| 142 | NICE="$3" |
|---|
| 143 | shift 3 |
|---|
| 144 | for i in "$@"; do |
|---|
| 145 | chrt -p $POLICY $PRIO $i || return |
|---|
| 146 | # increasing compatibility with older versions of renice |
|---|
| 147 | # in reaction to bug report #600134 |
|---|
| 148 | renice $NICE -p $i > /dev/null || renice -n $NICE -p $i |
|---|
| 149 | done |
|---|
| 150 | } |
|---|
| 151 | |
|---|
| 152 | schedule() |
|---|
| 153 | { |
|---|
| 154 | log_begin_msg "Setting up scheduling for $DESC and children:" |
|---|
| 155 | if ! is_running; then |
|---|
| 156 | log_progress_msg "$NAME not running" |
|---|
| 157 | else |
|---|
| 158 | if [ ! -x "`which ionice 2>/dev/null`" ]; then |
|---|
| 159 | log_progress_msg "ionice not found," |
|---|
| 160 | else |
|---|
| 161 | if ionice -c 3 -p $pid 2>/dev/null; then |
|---|
| 162 | log_progress_msg "idle," |
|---|
| 163 | else |
|---|
| 164 | log_progress_msg "ionice failed," |
|---|
| 165 | fi |
|---|
| 166 | fi |
|---|
| 167 | |
|---|
| 168 | children=`ps --ppid $pid -o pid= | tr '\n' ' '` |
|---|
| 169 | |
|---|
| 170 | if [ ! -x "`which chrt 2>/dev/null`" ]; then |
|---|
| 171 | log_progress_msg "chrt not found" |
|---|
| 172 | else |
|---|
| 173 | (chrt_many --idle 0 19 $pid $children >/dev/null \ |
|---|
| 174 | && log_progress_msg "idleprio") || \ |
|---|
| 175 | (chrt_many --batch 0 19 $pid $children >/dev/null \ |
|---|
| 176 | && log_progress_msg "batch") || \ |
|---|
| 177 | (chrt_many --other 0 19 $pid $children >/dev/null \ |
|---|
| 178 | && log_progress_msg "normal") || \ |
|---|
| 179 | log_progress_msg "chrt failed" |
|---|
| 180 | fi |
|---|
| 181 | for BPID in ${pid} ${children}; do |
|---|
| 182 | echo ${BOINC_OOM_AD} > /proc/${BPID}/oom_adj 2>/dev/null || true |
|---|
| 183 | done |
|---|
| 184 | fi |
|---|
| 185 | log_end_msg 0 |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | status() |
|---|
| 189 | { |
|---|
| 190 | STATUS="Status of $DESC:" |
|---|
| 191 | if is_running; then |
|---|
| 192 | log_success_msg "$STATUS running" |
|---|
| 193 | children=`ps --ppid $pid -o pid= | tr '\n' ' '` |
|---|
| 194 | if [ -x "`which chrt 2>/dev/null`" ]; then |
|---|
| 195 | log_success_msg "Scheduling of $DESC: $pid" |
|---|
| 196 | chrt -p $pid |
|---|
| 197 | |
|---|
| 198 | if [ -n "$children" ]; then |
|---|
| 199 | log_success_msg "Scheduling of $DESC's children: $children" |
|---|
| 200 | for i in $children; do |
|---|
| 201 | chrt -p $i |
|---|
| 202 | done |
|---|
| 203 | fi |
|---|
| 204 | fi |
|---|
| 205 | log_success_msg "OOM killer status for $DESC:" |
|---|
| 206 | for BPID in ${pid} ${children}; do echo PID ${BPID}: adj `cat /proc/${BPID}/oom_adj`, score `cat /proc/${BPID}/oom_score`; done |
|---|
| 207 | |
|---|
| 208 | # Display $BOINC_USER's cpu_share: |
|---|
| 209 | uid=`id -u $BOINC_USER` |
|---|
| 210 | cpu_share_file="/sys/kernel/uids/$uid/cpu_share" |
|---|
| 211 | if [ -f "$cpu_share_file" ]; then |
|---|
| 212 | log_success_msg "cpu_share: `cat "$cpu_share_file"`" |
|---|
| 213 | fi |
|---|
| 214 | else |
|---|
| 215 | log_success_msg "$STATUS stopped" |
|---|
| 216 | fi |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | # Patched 1..5 by fliteshare@gmail.com |
|---|
| 220 | # This patch delays the start of boinc-clients until the nVidia Tesla GPU's are initialized |
|---|
| 221 | # the 30 second delay is arbitrary but worked great on my machine (feel free to tweak) |
|---|
| 222 | case "$1" in |
|---|
| 223 | start) |
|---|
| 224 | stop # patch 1 |
|---|
| 225 | echo "Wait for Tesla init" # patch 2 |
|---|
| 226 | sleep 30 # patch 3 |
|---|
| 227 | echo "Tesla stacks build !" # patch 4 |
|---|
| 228 | start |
|---|
| 229 | echo "boinc-clients are cleared to run" # patch 5 |
|---|
| 230 | ;; |
|---|
| 231 | |
|---|
| 232 | stop) |
|---|
| 233 | stop |
|---|
| 234 | ;; |
|---|
| 235 | |
|---|
| 236 | restart|force-reload) |
|---|
| 237 | stop |
|---|
| 238 | sleep 1 |
|---|
| 239 | start |
|---|
| 240 | ;; |
|---|
| 241 | |
|---|
| 242 | status) |
|---|
| 243 | status |
|---|
| 244 | ;; |
|---|
| 245 | |
|---|
| 246 | schedule) |
|---|
| 247 | schedule |
|---|
| 248 | ;; |
|---|
| 249 | |
|---|
| 250 | *) |
|---|
| 251 | log_success_msg "Usage: $0 {start|stop|restart|force-reload|status|schedule}" >&2 |
|---|
| 252 | exit 1 |
|---|
| 253 | ;; |
|---|
| 254 | esac |
|---|
| 255 | |
|---|
| 256 | exit 0 |
|---|