diff options
author | Sven Eden <yamakuzure@gmx.net> | 2016-12-08 10:21:44 +0100 |
---|---|---|
committer | David Seifert <soap@gentoo.org> | 2017-01-04 15:41:54 +0200 |
commit | e4bdce024162b77ee4947674c2e4399fc4cf23f7 (patch) | |
tree | 5b2a5dcbd8ccd5329d93d2163309c546f2e4828b /sci-misc/boinc | |
parent | dev-python/pyproj: 1.9.5.1 bump, add python 3 support, bug #598758 (diff) | |
download | gentoo-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
Diffstat (limited to 'sci-misc/boinc')
-rw-r--r-- | sci-misc/boinc/files/boinc.conf | 6 | ||||
-rw-r--r-- | sci-misc/boinc/files/boinc.init | 106 |
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 } |