1 |
commit: e4bdce024162b77ee4947674c2e4399fc4cf23f7 |
2 |
Author: Sven Eden <yamakuzure <AT> gmx <DOT> net> |
3 |
AuthorDate: Thu Dec 8 09:21:44 2016 +0000 |
4 |
Commit: David Seifert <soap <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Jan 4 13:41:54 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=e4bdce02 |
7 |
|
8 |
sci-misc/boinc: Update init script to fix bug 584386 and 603522 |
9 |
|
10 |
Gentoo-Bug: 584386 |
11 |
|
12 |
The boinc init script starts boinc_client in daemon mode, and relies on |
13 |
boinccmd to send a quit signal to stop the service. |
14 |
|
15 |
This leads to the following two problems: |
16 |
1) It is not possible to generate a pid file, as the pid read from the |
17 |
started boinc_client is invalid after it forked to background. |
18 |
2) The stop command immediately returns, but boinc_client can still be |
19 |
active for a long time, over a minute in fact, while it is stopping |
20 |
running projects and cleaning up its work data. This is especially |
21 |
problematic when boinc is stopped while shutting down the machine. |
22 |
|
23 |
Gentoo-Bug: 603522 |
24 |
|
25 |
The init script for boinc calls "chown -R" on "${RUNTIMEDIR}". |
26 |
This leads to the security issue, that the "boinc" user can create a |
27 |
hardlink within ${RUNTIMEDIR} pointing to a file that he does not |
28 |
own, and the next time the daemon is started, the init script (as |
29 |
root) will give ownership of the *target* of the hardlink to the |
30 |
boinc user. |
31 |
|
32 |
This commit removes the usage of "chown -R" from start_pre(), and |
33 |
adds a single call to "chown" to create_work_directory() if, and only |
34 |
if the working directory has been newly created. |
35 |
|
36 |
Other fixes and changes: |
37 |
|
38 |
Another problem found is the function cuda_check(), which assumes the cuda |
39 |
libraries to be installed in /opt/cuda/lib, leading to an invalid symlink |
40 |
for libcudart.so on 64 bit machines where the library is installed in |
41 |
/opt/cuda/lib64. |
42 |
|
43 |
This commit changes the following behaviour, besides some long overdue |
44 |
cleanup: |
45 |
1) start() no longer uses the --daemon option of the boinc_client, but |
46 |
the --background option of the start-stop-daemon command. Further it |
47 |
creates a pid file in the path set by the new config variable |
48 |
BOINC_PIDFILE, that has been added to boinc.conf. |
49 |
2) stop() no longer uses boinccmd to send a quit signal, but uses the |
50 |
--stop and --pidfile options of the start-stop-daemon command. The |
51 |
waiting time should be large enough to successfully await the end of |
52 |
the exiting task of the boinc_client program. |
53 |
3) cuda_check() now checks the validity of the libcudart.so symlink and |
54 |
removes it if it is invalid. Further it looks for a present |
55 |
libcudart.so library in /opt/cuda/lib* and picks the newest found to |
56 |
create a new symlink if none is present. |
57 |
4) The suspend() and resume() functions have been updated to use the |
58 |
start-stop-daemon command, so both the user:group and a possibly |
59 |
required password are now used to circumvent authentication errors. |
60 |
|
61 |
Package-Manager: portage-2.3.3 |
62 |
Closes: https://github.com/gentoo/gentoo/pull/3056 |
63 |
|
64 |
sci-misc/boinc/files/boinc.conf | 6 +++ |
65 |
sci-misc/boinc/files/boinc.init | 106 +++++++++++++++++++++++++++++++--------- |
66 |
2 files changed, 89 insertions(+), 23 deletions(-) |
67 |
|
68 |
diff --git a/sci-misc/boinc/files/boinc.conf b/sci-misc/boinc/files/boinc.conf |
69 |
index 0fef6ae..22fcca0 100644 |
70 |
--- a/sci-misc/boinc/files/boinc.conf |
71 |
+++ b/sci-misc/boinc/files/boinc.conf |
72 |
@@ -10,6 +10,12 @@ RUNTIMEDIR="/var/lib/boinc" |
73 |
# Location of the boinc command line binary |
74 |
BOINCBIN="/usr/bin/boinc_client" |
75 |
|
76 |
+# Location of the boinc_client pid file |
77 |
+BOINC_PIDFILE="/var/run/boinc_client.pid" |
78 |
+ |
79 |
+# Location of the boinccmd command |
80 |
+BOINCCMD="/usr/bin/boinccmd" |
81 |
+ |
82 |
# Allow remote gui RPC yes or no |
83 |
ALLOW_REMOTE_RPC="no" |
84 |
|
85 |
|
86 |
diff --git a/sci-misc/boinc/files/boinc.init b/sci-misc/boinc/files/boinc.init |
87 |
index 07b8b80..4067105 100644 |
88 |
--- a/sci-misc/boinc/files/boinc.init |
89 |
+++ b/sci-misc/boinc/files/boinc.init |
90 |
@@ -5,7 +5,6 @@ |
91 |
|
92 |
extra_started_commands="attach resume suspend" |
93 |
|
94 |
- |
95 |
depend() { |
96 |
# we can use dns and net, but we can also in most cases live without them |
97 |
use dns net ntp-client ntpd |
98 |
@@ -13,15 +12,19 @@ depend() { |
99 |
|
100 |
|
101 |
create_work_directory() { |
102 |
- if [ ! -d "${RUNTIMEDIR}" ]; then |
103 |
+ if [[ ! -d "${RUNTIMEDIR}" ]]; then |
104 |
einfo "Directory ${RUNTIMEDIR} does not exist, creating now." |
105 |
mkdir -p "${RUNTIMEDIR}" |
106 |
- if [ ! -d "${RUNTIMEDIR}" ]; then |
107 |
+ if [[ ! -d "${RUNTIMEDIR}" ]]; then |
108 |
eeror "Directory ${RUNTIMEDIR} could not be created!" |
109 |
return 1 |
110 |
fi |
111 |
+ |
112 |
+ # ensure proper ownership |
113 |
+ chown "${USER}:${GROUP}" "${RUNTIMEDIR}" |
114 |
fi |
115 |
- if [ ! -e "${RUNTIMEDIR}"/ca-bundle.crt ] ; then |
116 |
+ |
117 |
+ if [[ ! -e "${RUNTIMEDIR}"/ca-bundle.crt ]]; then |
118 |
ln -s /etc/ssl/certs/ca-certificates.crt "${RUNTIMEDIR}"/ca-bundle.crt |
119 |
fi |
120 |
|
121 |
@@ -30,9 +33,20 @@ create_work_directory() { |
122 |
|
123 |
|
124 |
cuda_check() { |
125 |
- if [ -f /opt/cuda/lib/libcudart.so ]; then |
126 |
- # symlink wont harm :] |
127 |
- ln -snf /opt/cuda/lib/libcudart.so "${RUNTIMEDIR}"/libcudart.so |
128 |
+ local libtarget="${RUNTIMEDIR}/libcudart.so" |
129 |
+ local libsource="$(ls -t /opt/cuda/lib*/libcudart.so 2>/dev/null | head -n 1)" |
130 |
+ |
131 |
+ # Remove a broken symlink |
132 |
+ if [[ -h "${libtarget}" ]] \ |
133 |
+ && [[ "${libsource}" != "$(readlink "${libtarget}")" ]]; then |
134 |
+ rm -f "${libtarget}" |
135 |
+ fi |
136 |
+ |
137 |
+ # symlink the correct path |
138 |
+ if [[ -n "${libsource}" ]] \ |
139 |
+ && [[ -f "${libsource}" ]] \ |
140 |
+ && [[ ! -h "${libtarget}" ]]; then |
141 |
+ ln -snf "$libsource" "${libtarget}" |
142 |
fi |
143 |
} |
144 |
|
145 |
@@ -43,17 +57,26 @@ env_check() { |
146 |
: ${GROUP:="boinc"} |
147 |
: ${RUNTIMEDIR:="/var/lib/boinc"} |
148 |
: ${BOINCBIN:="$(which boinc_client)"} |
149 |
+ : ${BOINC_PIDFILE:="/var/run/boinc_client.pid"} |
150 |
+ : ${BOINCCMD:="$(which /usr/bin/boinccmd)"} |
151 |
: ${ALLOW_REMOTE_RPC:="yes"} |
152 |
: ${NICELEVEL:="19"} |
153 |
# ARGS is not checked, it could have been explicitly set |
154 |
# to be empty by the user. |
155 |
|
156 |
# If the client was not found (how?) something is seriously wrong |
157 |
- if [ ! -x "$BOINCBIN" ] ; then |
158 |
+ if [[ ! -x "$BOINCBIN" ]]; then |
159 |
eerror "No boinc_client found!" |
160 |
return 1 |
161 |
fi |
162 |
|
163 |
+ # The boinccmd is crucial, or we can not attach, suspend or resume |
164 |
+ # the boinc client |
165 |
+ if [[ ! -x "$BOINCCMD" ]]; then |
166 |
+ eerror "No boinccmd_program found!" |
167 |
+ return 1 |
168 |
+ fi |
169 |
+ |
170 |
return 0 |
171 |
} |
172 |
|
173 |
@@ -75,10 +98,7 @@ start_pre() { |
174 |
create_work_directory || return 1 |
175 |
cuda_check |
176 |
|
177 |
- # always ensure proper ownership |
178 |
- chown -R "${USER}:${GROUP}" "${RUNTIMEDIR}" |
179 |
- |
180 |
- if [ ! -f "${RUNTIMEDIR}/lockfile" ]; then |
181 |
+ if [[ ! -f "${RUNTIMEDIR}/lockfile" ]]; then |
182 |
einfo "File \"${RUNTIMEDIR}/lockfile\" does not exist, assuming first run." |
183 |
einfo "You need to setup an account on the BOINC project homepage beforehand!" |
184 |
einfo "Go to http://boinc.berkeley.edu/ and locate your project." |
185 |
@@ -94,14 +114,17 @@ start_pre() { |
186 |
|
187 |
|
188 |
start() { |
189 |
- if [ "${ALLOW_REMOTE_RPC}" = "yes" ]; then |
190 |
+ if [[ "${ALLOW_REMOTE_RPC}" = "yes" ]]; then |
191 |
ARGS="${ARGS} --allow_remote_gui_rpc" |
192 |
fi |
193 |
|
194 |
- ARGS="${ARGS} --daemon --dir "${RUNTIMEDIR}" --redirectio" |
195 |
+ ARGS="${ARGS} --dir "${RUNTIMEDIR}" --redirectio" |
196 |
|
197 |
ebegin "Starting ${RC_SVCNAME}" |
198 |
- start-stop-daemon -S -N ${NICELEVEL} -u ${USER} -q -x "${BOINCBIN}" -- ${ARGS} |
199 |
+ start-stop-daemon --start --nicelevel ${NICELEVEL} \ |
200 |
+ --user "${USER}:${GROUP}" --quiet --make-pidfile \ |
201 |
+ --pidfile "$BOINC_PIDFILE" --background \ |
202 |
+ --exec "${BOINCBIN}" -- ${ARGS} |
203 |
eend $? |
204 |
} |
205 |
|
206 |
@@ -113,7 +136,7 @@ attach() { |
207 |
|
208 |
env_check || return 1 |
209 |
|
210 |
- einfo "If you cant find your account key just try to obtain it by using:" |
211 |
+ einfo "If you can't find your account key just try to obtain it by using:" |
212 |
einfo " boinccmd --passwd PASSWORD_FROM_GUI_RPC_AUTH --lookup_account URL EMAIL PASSWORD" |
213 |
|
214 |
printf " Enter the Project URL: " |
215 |
@@ -130,16 +153,19 @@ attach() { |
216 |
fi |
217 |
|
218 |
ebegin "${RC_SVCNAME}: Attaching to project" |
219 |
- start-stop-daemon -u ${USER} -q -d "${RUNTIMEDIR}" -x boinccmd -- ${password} --project_attach ${url} ${key} |
220 |
+ start-stop-daemon --user "${USER}:${GROUP}" --quiet \ |
221 |
+ --chdir "${RUNTIMEDIR}" --exec "${BOINCCMD}" \ |
222 |
+ -- ${password} --project_attach ${url} ${key} |
223 |
eend $? |
224 |
|
225 |
- sleep 10 |
226 |
+ sleep 10s |
227 |
tail "${RUNTIMEDIR}/stdoutdae.txt" |
228 |
} |
229 |
|
230 |
|
231 |
stop() { |
232 |
local password="" |
233 |
+ local stop_timeout="SIGTERM/60/SIGTERM/30/SIGKILL/30" |
234 |
|
235 |
env_check || return 1 |
236 |
|
237 |
@@ -148,20 +174,54 @@ stop() { |
238 |
fi |
239 |
|
240 |
ebegin "Stopping ${RC_SVCNAME}" |
241 |
- start-stop-daemon -u ${USER} -q -d "${RUNTIMEDIR}" -x boinccmd -- ${password} --quit |
242 |
+ start-stop-daemon --stop --quiet --progress \ |
243 |
+ --retry $stop_timeout \ |
244 |
+ --pidfile "${BOINC_PIDFILE}" |
245 |
eend $? |
246 |
} |
247 |
|
248 |
|
249 |
resume() { |
250 |
- for url in $(boinccmd --get_project_status | sed -n 's/\s*master URL: //p'); do |
251 |
- boinccmd --project ${url} resume |
252 |
+ env_check || return 1 |
253 |
+ |
254 |
+ local password="" |
255 |
+ local master_urls=( \ |
256 |
+ $("${BOINCCMD}" --get_project_status | \ |
257 |
+ sed -n 's/\s*master URL: //p') \ |
258 |
+ ) |
259 |
+ |
260 |
+ if need_passwd_arg; then |
261 |
+ password="--passwd \"$(cat "${RUNTIMEDIR}/gui_rpc_auth.cfg")\"" |
262 |
+ fi |
263 |
+ |
264 |
+ for url in "${master_urls[@]}"; do |
265 |
+ ebegin "Resuming $url" |
266 |
+ start-stop-daemon --user "${USER}:${GROUP}" --quiet \ |
267 |
+ --chdir "${RUNTIMEDIR}" --exec "${BOINCCMD}" \ |
268 |
+ -- ${password} --project ${url} resume |
269 |
+ eend $? |
270 |
done |
271 |
} |
272 |
|
273 |
|
274 |
suspend() { |
275 |
- for url in $(boinccmd --get_project_status | sed -n 's/\s*master URL: //p'); do |
276 |
- boinccmd --project ${url} suspend; |
277 |
+ env_check || return 1 |
278 |
+ |
279 |
+ local password="" |
280 |
+ local master_urls=( \ |
281 |
+ $("${BOINCCMD}" --get_project_status | \ |
282 |
+ sed -n 's/\s*master URL: //p') \ |
283 |
+ ) |
284 |
+ |
285 |
+ if need_passwd_arg; then |
286 |
+ password="--passwd \"$(cat "${RUNTIMEDIR}/gui_rpc_auth.cfg")\"" |
287 |
+ fi |
288 |
+ |
289 |
+ for url in "${master_urls[@]}"; do |
290 |
+ ebegin "Suspending $url" |
291 |
+ start-stop-daemon --user "${USER}:${GROUP}" --quiet \ |
292 |
+ --chdir "${RUNTIMEDIR}" --exec "${BOINCCMD}" \ |
293 |
+ -- ${password} --project ${url} suspend |
294 |
+ eend $? |
295 |
done |
296 |
} |