summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Eden <yamakuzure@gmx.net>2016-12-08 10:21:44 +0100
committerDavid Seifert <soap@gentoo.org>2017-01-04 15:41:54 +0200
commite4bdce024162b77ee4947674c2e4399fc4cf23f7 (patch)
tree5b2a5dcbd8ccd5329d93d2163309c546f2e4828b
parentdev-python/pyproj: 1.9.5.1 bump, add python 3 support, bug #598758 (diff)
downloadgentoo-e4bdce024162b77ee4947674c2e4399fc4cf23f7.tar.gz
gentoo-e4bdce024162b77ee4947674c2e4399fc4cf23f7.tar.bz2
gentoo-e4bdce024162b77ee4947674c2e4399fc4cf23f7.zip
sci-misc/boinc: Update init script to fix bug 584386 and 603522
Gentoo-Bug: 584386 The boinc init script starts boinc_client in daemon mode, and relies on boinccmd to send a quit signal to stop the service. This leads to the following two problems: 1) It is not possible to generate a pid file, as the pid read from the started boinc_client is invalid after it forked to background. 2) The stop command immediately returns, but boinc_client can still be active for a long time, over a minute in fact, while it is stopping running projects and cleaning up its work data. This is especially problematic when boinc is stopped while shutting down the machine. Gentoo-Bug: 603522 The init script for boinc calls "chown -R" on "${RUNTIMEDIR}". This leads to the security issue, that the "boinc" user can create a hardlink within ${RUNTIMEDIR} pointing to a file that he does not own, and the next time the daemon is started, the init script (as root) will give ownership of the *target* of the hardlink to the boinc user. This commit removes the usage of "chown -R" from start_pre(), and adds a single call to "chown" to create_work_directory() if, and only if the working directory has been newly created. Other fixes and changes: Another problem found is the function cuda_check(), which assumes the cuda libraries to be installed in /opt/cuda/lib, leading to an invalid symlink for libcudart.so on 64 bit machines where the library is installed in /opt/cuda/lib64. This commit changes the following behaviour, besides some long overdue cleanup: 1) start() no longer uses the --daemon option of the boinc_client, but the --background option of the start-stop-daemon command. Further it creates a pid file in the path set by the new config variable BOINC_PIDFILE, that has been added to boinc.conf. 2) stop() no longer uses boinccmd to send a quit signal, but uses the --stop and --pidfile options of the start-stop-daemon command. The waiting time should be large enough to successfully await the end of the exiting task of the boinc_client program. 3) cuda_check() now checks the validity of the libcudart.so symlink and removes it if it is invalid. Further it looks for a present libcudart.so library in /opt/cuda/lib* and picks the newest found to create a new symlink if none is present. 4) The suspend() and resume() functions have been updated to use the start-stop-daemon command, so both the user:group and a possibly required password are now used to circumvent authentication errors. Package-Manager: portage-2.3.3 Closes: https://github.com/gentoo/gentoo/pull/3056
-rw-r--r--sci-misc/boinc/files/boinc.conf6
-rw-r--r--sci-misc/boinc/files/boinc.init106
2 files changed, 89 insertions, 23 deletions
diff --git a/sci-misc/boinc/files/boinc.conf b/sci-misc/boinc/files/boinc.conf
index 0fef6ae58e37..22fcca0d3001 100644
--- a/sci-misc/boinc/files/boinc.conf
+++ b/sci-misc/boinc/files/boinc.conf
@@ -10,6 +10,12 @@ RUNTIMEDIR="/var/lib/boinc"
# Location of the boinc command line binary
BOINCBIN="/usr/bin/boinc_client"
+# Location of the boinc_client pid file
+BOINC_PIDFILE="/var/run/boinc_client.pid"
+
+# Location of the boinccmd command
+BOINCCMD="/usr/bin/boinccmd"
+
# Allow remote gui RPC yes or no
ALLOW_REMOTE_RPC="no"
diff --git a/sci-misc/boinc/files/boinc.init b/sci-misc/boinc/files/boinc.init
index 07b8b80c411c..4067105eeb71 100644
--- a/sci-misc/boinc/files/boinc.init
+++ b/sci-misc/boinc/files/boinc.init
@@ -5,7 +5,6 @@
extra_started_commands="attach resume suspend"
-
depend() {
# we can use dns and net, but we can also in most cases live without them
use dns net ntp-client ntpd
@@ -13,15 +12,19 @@ depend() {
create_work_directory() {
- if [ ! -d "${RUNTIMEDIR}" ]; then
+ if [[ ! -d "${RUNTIMEDIR}" ]]; then
einfo "Directory ${RUNTIMEDIR} does not exist, creating now."
mkdir -p "${RUNTIMEDIR}"
- if [ ! -d "${RUNTIMEDIR}" ]; then
+ if [[ ! -d "${RUNTIMEDIR}" ]]; then
eeror "Directory ${RUNTIMEDIR} could not be created!"
return 1
fi
+
+ # ensure proper ownership
+ chown "${USER}:${GROUP}" "${RUNTIMEDIR}"
fi
- if [ ! -e "${RUNTIMEDIR}"/ca-bundle.crt ] ; then
+
+ if [[ ! -e "${RUNTIMEDIR}"/ca-bundle.crt ]]; then
ln -s /etc/ssl/certs/ca-certificates.crt "${RUNTIMEDIR}"/ca-bundle.crt
fi
@@ -30,9 +33,20 @@ create_work_directory() {
cuda_check() {
- if [ -f /opt/cuda/lib/libcudart.so ]; then
- # symlink wont harm :]
- ln -snf /opt/cuda/lib/libcudart.so "${RUNTIMEDIR}"/libcudart.so
+ local libtarget="${RUNTIMEDIR}/libcudart.so"
+ local libsource="$(ls -t /opt/cuda/lib*/libcudart.so 2>/dev/null | head -n 1)"
+
+ # Remove a broken symlink
+ if [[ -h "${libtarget}" ]] \
+ && [[ "${libsource}" != "$(readlink "${libtarget}")" ]]; then
+ rm -f "${libtarget}"
+ fi
+
+ # symlink the correct path
+ if [[ -n "${libsource}" ]] \
+ && [[ -f "${libsource}" ]] \
+ && [[ ! -h "${libtarget}" ]]; then
+ ln -snf "$libsource" "${libtarget}"
fi
}
@@ -43,17 +57,26 @@ env_check() {
: ${GROUP:="boinc"}
: ${RUNTIMEDIR:="/var/lib/boinc"}
: ${BOINCBIN:="$(which boinc_client)"}
+ : ${BOINC_PIDFILE:="/var/run/boinc_client.pid"}
+ : ${BOINCCMD:="$(which /usr/bin/boinccmd)"}
: ${ALLOW_REMOTE_RPC:="yes"}
: ${NICELEVEL:="19"}
# ARGS is not checked, it could have been explicitly set
# to be empty by the user.
# If the client was not found (how?) something is seriously wrong
- if [ ! -x "$BOINCBIN" ] ; then
+ if [[ ! -x "$BOINCBIN" ]]; then
eerror "No boinc_client found!"
return 1
fi
+ # The boinccmd is crucial, or we can not attach, suspend or resume
+ # the boinc client
+ if [[ ! -x "$BOINCCMD" ]]; then
+ eerror "No boinccmd_program found!"
+ return 1
+ fi
+
return 0
}
@@ -75,10 +98,7 @@ start_pre() {
create_work_directory || return 1
cuda_check
- # always ensure proper ownership
- chown -R "${USER}:${GROUP}" "${RUNTIMEDIR}"
-
- if [ ! -f "${RUNTIMEDIR}/lockfile" ]; then
+ if [[ ! -f "${RUNTIMEDIR}/lockfile" ]]; then
einfo "File \"${RUNTIMEDIR}/lockfile\" does not exist, assuming first run."
einfo "You need to setup an account on the BOINC project homepage beforehand!"
einfo "Go to http://boinc.berkeley.edu/ and locate your project."
@@ -94,14 +114,17 @@ start_pre() {
start() {
- if [ "${ALLOW_REMOTE_RPC}" = "yes" ]; then
+ if [[ "${ALLOW_REMOTE_RPC}" = "yes" ]]; then
ARGS="${ARGS} --allow_remote_gui_rpc"
fi
- ARGS="${ARGS} --daemon --dir "${RUNTIMEDIR}" --redirectio"
+ ARGS="${ARGS} --dir "${RUNTIMEDIR}" --redirectio"
ebegin "Starting ${RC_SVCNAME}"
- start-stop-daemon -S -N ${NICELEVEL} -u ${USER} -q -x "${BOINCBIN}" -- ${ARGS}
+ start-stop-daemon --start --nicelevel ${NICELEVEL} \
+ --user "${USER}:${GROUP}" --quiet --make-pidfile \
+ --pidfile "$BOINC_PIDFILE" --background \
+ --exec "${BOINCBIN}" -- ${ARGS}
eend $?
}
@@ -113,7 +136,7 @@ attach() {
env_check || return 1
- einfo "If you cant find your account key just try to obtain it by using:"
+ einfo "If you can't find your account key just try to obtain it by using:"
einfo " boinccmd --passwd PASSWORD_FROM_GUI_RPC_AUTH --lookup_account URL EMAIL PASSWORD"
printf " Enter the Project URL: "
@@ -130,16 +153,19 @@ attach() {
fi
ebegin "${RC_SVCNAME}: Attaching to project"
- start-stop-daemon -u ${USER} -q -d "${RUNTIMEDIR}" -x boinccmd -- ${password} --project_attach ${url} ${key}
+ start-stop-daemon --user "${USER}:${GROUP}" --quiet \
+ --chdir "${RUNTIMEDIR}" --exec "${BOINCCMD}" \
+ -- ${password} --project_attach ${url} ${key}
eend $?
- sleep 10
+ sleep 10s
tail "${RUNTIMEDIR}/stdoutdae.txt"
}
stop() {
local password=""
+ local stop_timeout="SIGTERM/60/SIGTERM/30/SIGKILL/30"
env_check || return 1
@@ -148,20 +174,54 @@ stop() {
fi
ebegin "Stopping ${RC_SVCNAME}"
- start-stop-daemon -u ${USER} -q -d "${RUNTIMEDIR}" -x boinccmd -- ${password} --quit
+ start-stop-daemon --stop --quiet --progress \
+ --retry $stop_timeout \
+ --pidfile "${BOINC_PIDFILE}"
eend $?
}
resume() {
- for url in $(boinccmd --get_project_status | sed -n 's/\s*master URL: //p'); do
- boinccmd --project ${url} resume
+ env_check || return 1
+
+ local password=""
+ local master_urls=( \
+ $("${BOINCCMD}" --get_project_status | \
+ sed -n 's/\s*master URL: //p') \
+ )
+
+ if need_passwd_arg; then
+ password="--passwd \"$(cat "${RUNTIMEDIR}/gui_rpc_auth.cfg")\""
+ fi
+
+ for url in "${master_urls[@]}"; do
+ ebegin "Resuming $url"
+ start-stop-daemon --user "${USER}:${GROUP}" --quiet \
+ --chdir "${RUNTIMEDIR}" --exec "${BOINCCMD}" \
+ -- ${password} --project ${url} resume
+ eend $?
done
}
suspend() {
- for url in $(boinccmd --get_project_status | sed -n 's/\s*master URL: //p'); do
- boinccmd --project ${url} suspend;
+ env_check || return 1
+
+ local password=""
+ local master_urls=( \
+ $("${BOINCCMD}" --get_project_status | \
+ sed -n 's/\s*master URL: //p') \
+ )
+
+ if need_passwd_arg; then
+ password="--passwd \"$(cat "${RUNTIMEDIR}/gui_rpc_auth.cfg")\""
+ fi
+
+ for url in "${master_urls[@]}"; do
+ ebegin "Suspending $url"
+ start-stop-daemon --user "${USER}:${GROUP}" --quiet \
+ --chdir "${RUNTIMEDIR}" --exec "${BOINCCMD}" \
+ -- ${password} --project ${url} suspend
+ eend $?
done
}