1 /*
2 * virpidfile.c: manipulation of pidfiles
3 *
4 * Copyright (C) 2010-2012, 2014 Red Hat, Inc.
5 * Copyright (C) 2006, 2007 Binary Karma
6 * Copyright (C) 2006 Shuveb Hussain
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see
20 * <http://www.gnu.org/licenses/>.
21 *
22 */
23
24 #include <config.h>
25
26 #include <fcntl.h>
27 #include <signal.h>
28 #include <sys/stat.h>
29
30 #include "virpidfile.h"
31 #include "virfile.h"
32 #include "viralloc.h"
33 #include "virbuffer.h"
34 #include "virutil.h"
35 #include "virlog.h"
36 #include "virerror.h"
37 #include "virstring.h"
38 #include "virprocess.h"
39
40 #define VIR_FROM_THIS VIR_FROM_NONE
41
42 VIR_LOG_INIT("util.pidfile");
43
virPidFileBuildPath(const char * dir,const char * name)44 char *virPidFileBuildPath(const char *dir, const char* name)
45 {
46 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
47
48 virBufferAsprintf(&buf, "%s", dir);
49 virBufferEscapeString(&buf, "/%s.pid", name);
50
51 return virBufferContentAndReset(&buf);
52 }
53
54
virPidFileWritePath(const char * pidfile,pid_t pid)55 int virPidFileWritePath(const char *pidfile,
56 pid_t pid)
57 {
58 int rc;
59 int fd;
60 char pidstr[VIR_INT64_STR_BUFLEN];
61
62 if ((fd = open(pidfile,
63 O_WRONLY | O_CREAT | O_TRUNC,
64 S_IRUSR | S_IWUSR)) < 0) {
65 rc = -errno;
66 goto cleanup;
67 }
68
69 g_snprintf(pidstr, sizeof(pidstr), "%lld", (long long) pid);
70
71 if (safewrite(fd, pidstr, strlen(pidstr)) < 0) {
72 rc = -errno;
73 VIR_FORCE_CLOSE(fd);
74 goto cleanup;
75 }
76
77 rc = 0;
78
79 cleanup:
80 if (VIR_CLOSE(fd) < 0)
81 rc = -errno;
82
83 return rc;
84 }
85
86
virPidFileWrite(const char * dir,const char * name,pid_t pid)87 int virPidFileWrite(const char *dir,
88 const char *name,
89 pid_t pid)
90 {
91 g_autofree char *pidfile = NULL;
92
93 if (name == NULL || dir == NULL)
94 return -EINVAL;
95
96 if (g_mkdir_with_parents(dir, 0777) < 0)
97 return -errno;
98
99 if (!(pidfile = virPidFileBuildPath(dir, name)))
100 return -ENOMEM;
101
102 return virPidFileWritePath(pidfile, pid);
103 }
104
105
virPidFileReadPath(const char * path,pid_t * pid)106 int virPidFileReadPath(const char *path,
107 pid_t *pid)
108 {
109 int fd;
110 int rc;
111 ssize_t bytes;
112 long long pid_value = 0;
113 char pidstr[VIR_INT64_STR_BUFLEN];
114 char *endptr = NULL;
115
116 *pid = 0;
117
118 if ((fd = open(path, O_RDONLY)) < 0) {
119 rc = -errno;
120 goto cleanup;
121 }
122
123 bytes = saferead(fd, pidstr, sizeof(pidstr));
124 if (bytes < 0) {
125 rc = -errno;
126 VIR_FORCE_CLOSE(fd);
127 goto cleanup;
128 }
129 pidstr[bytes] = '\0';
130
131 if (virStrToLong_ll(pidstr, &endptr, 10, &pid_value) < 0 ||
132 !(*endptr == '\0' || g_ascii_isspace(*endptr)) ||
133 (pid_t) pid_value != pid_value) {
134 rc = -EINVAL;
135 goto cleanup;
136 }
137
138 *pid = pid_value;
139 rc = 0;
140
141 cleanup:
142 if (VIR_CLOSE(fd) < 0)
143 rc = -errno;
144
145 return rc;
146 }
147
148
virPidFileRead(const char * dir,const char * name,pid_t * pid)149 int virPidFileRead(const char *dir,
150 const char *name,
151 pid_t *pid)
152 {
153 g_autofree char *pidfile = NULL;
154
155 *pid = 0;
156
157 if (name == NULL || dir == NULL)
158 return -EINVAL;
159
160 if (!(pidfile = virPidFileBuildPath(dir, name)))
161 return -ENOMEM;
162
163 return virPidFileReadPath(pidfile, pid);
164 }
165
166
167
168 /**
169 * virPidFileReadPathIfAlive:
170 * @path: path to pidfile
171 * @pid: variable to return pid in
172 * @binpath: path of executable associated with the pidfile
173 *
174 * This will attempt to read a pid from @path, and store it
175 * in @pid. The @pid will only be set, however, if the
176 * pid in @path is running, and its executable path
177 * resolves to @binpath. This adds protection against
178 * recycling of previously reaped pids.
179 *
180 * If @binpath is NULL the check for the executable path
181 * is skipped.
182 *
183 * Returns -1 upon error, or zero on successful
184 * reading of the pidfile. If the PID was not still
185 * alive, zero will be returned, but @pid will be
186 * set to -1.
187 */
virPidFileReadPathIfAlive(const char * path,pid_t * pid,const char * binPath)188 int virPidFileReadPathIfAlive(const char *path,
189 pid_t *pid,
190 const char *binPath)
191 {
192 int rc;
193 bool isLink = false;
194 size_t procLinkLen;
195 const char deletedText[] = " (deleted)";
196 size_t deletedTextLen = strlen(deletedText);
197 pid_t retPid;
198 g_autofree char *procPath = NULL;
199 g_autofree char *procLink = NULL;
200 g_autofree char *resolvedBinPath = NULL;
201 g_autofree char *resolvedProcLink = NULL;
202
203 /* only set this at the very end on success */
204 *pid = -1;
205
206 if (virPidFileReadPath(path, &retPid) < 0)
207 return -1;
208
209 #ifndef WIN32
210 /* Check that it's still alive. Safe to skip this sanity check on
211 * mingw, which lacks kill(). */
212 if (kill(retPid, 0) < 0) {
213 *pid = -1;
214 return 0;
215 }
216 #endif
217
218 if (!binPath) {
219 /* we only knew the pid, and that pid is alive, so we can
220 * return it.
221 */
222 *pid = retPid;
223 return 0;
224 }
225
226 procPath = g_strdup_printf("/proc/%lld/exe", (long long)retPid);
227
228 if ((rc = virFileIsLink(procPath)) < 0)
229 return -1;
230
231 if (rc == 1)
232 isLink = true;
233
234 if (isLink && virFileLinkPointsTo(procPath, binPath)) {
235 /* the link in /proc/$pid/exe is a symlink to a file
236 * that has the same inode as the file at binpath.
237 */
238 *pid = retPid;
239 return 0;
240 }
241
242 /* Even if virFileLinkPointsTo returns a mismatch, it could be
243 * that the binary was deleted/replaced after it was executed. In
244 * that case the link in /proc/$pid/exe will contain
245 * "$procpath (deleted)". Read that link, remove the " (deleted)"
246 * part, and see if it has the same canonicalized name as binpath.
247 */
248 if (!(procLink = g_file_read_link(procPath, NULL)))
249 return -1;
250
251 procLinkLen = strlen(procLink);
252 if (procLinkLen > deletedTextLen)
253 procLink[procLinkLen - deletedTextLen] = 0;
254
255 if (virFileResolveAllLinks(binPath, &resolvedBinPath) < 0)
256 return -1;
257 if (virFileResolveAllLinks(procLink, &resolvedProcLink) < 0)
258 return -1;
259
260 if (STRNEQ(resolvedBinPath, resolvedProcLink))
261 return -1;
262
263 *pid = retPid;
264 return 0;
265 }
266
267
268 /**
269 * virPidFileReadIfAlive:
270 * @dir: directory containing pidfile
271 * @name: base filename of pidfile
272 * @pid: variable to return pid in
273 * @binpath: path of executable associated with the pidfile
274 *
275 * This will attempt to read a pid from the pidfile @name
276 * in directory @dir, and store it in @pid. The @pid will
277 * only be set, however, if the pid in @name is running,
278 * and its executable path resolves to @binpath. This adds
279 * protection against recycling of previously reaped pids.
280 *
281 * Returns -1 upon error, or zero on successful
282 * reading of the pidfile. If the PID was not still
283 * alive, zero will be returned, but @pid will be
284 * set to -1.
285 */
virPidFileReadIfAlive(const char * dir,const char * name,pid_t * pid,const char * binpath)286 int virPidFileReadIfAlive(const char *dir,
287 const char *name,
288 pid_t *pid,
289 const char *binpath)
290 {
291 g_autofree char *pidfile = NULL;
292
293 if (name == NULL || dir == NULL)
294 return -1;
295
296 if (!(pidfile = virPidFileBuildPath(dir, name)))
297 return -1;
298
299 if (virPidFileReadPathIfAlive(pidfile, pid, binpath) < 0)
300 return -1;
301
302 return 0;
303 }
304
305
virPidFileDeletePath(const char * pidfile)306 int virPidFileDeletePath(const char *pidfile)
307 {
308 int rc = 0;
309
310 if (unlink(pidfile) < 0 && errno != ENOENT)
311 rc = -errno;
312
313 return rc;
314 }
315
316
virPidFileDelete(const char * dir,const char * name)317 int virPidFileDelete(const char *dir,
318 const char *name)
319 {
320 g_autofree char *pidfile = NULL;
321
322 if (name == NULL || dir == NULL)
323 return -EINVAL;
324
325 if (!(pidfile = virPidFileBuildPath(dir, name)))
326 return -ENOMEM;
327
328 return virPidFileDeletePath(pidfile);
329 }
330
virPidFileAcquirePath(const char * path,bool waitForLock,pid_t pid)331 int virPidFileAcquirePath(const char *path,
332 bool waitForLock,
333 pid_t pid)
334 {
335 int fd = -1;
336 char pidstr[VIR_INT64_STR_BUFLEN];
337
338 if (path[0] == '\0')
339 return 0;
340
341 while (1) {
342 struct stat a, b;
343 if ((fd = open(path, O_WRONLY|O_CREAT, 0644)) < 0) {
344 virReportSystemError(errno,
345 _("Failed to open pid file '%s'"),
346 path);
347 return -1;
348 }
349
350 if (virSetCloseExec(fd) < 0) {
351 virReportSystemError(errno,
352 _("Failed to set close-on-exec flag '%s'"),
353 path);
354 VIR_FORCE_CLOSE(fd);
355 return -1;
356 }
357
358 if (fstat(fd, &b) < 0) {
359 virReportSystemError(errno,
360 _("Unable to check status of pid file '%s'"),
361 path);
362 VIR_FORCE_CLOSE(fd);
363 return -1;
364 }
365
366 if (virFileLock(fd, false, 0, 1, waitForLock) < 0) {
367 virReportSystemError(errno,
368 _("Failed to acquire pid file '%s'"),
369 path);
370 VIR_FORCE_CLOSE(fd);
371 return -1;
372 }
373
374 /* Now make sure the pidfile we locked is the same
375 * one that now exists on the filesystem
376 */
377 if (stat(path, &a) < 0) {
378 VIR_DEBUG("Pid file '%s' disappeared: %s",
379 path, g_strerror(errno));
380 VIR_FORCE_CLOSE(fd);
381 /* Someone else must be racing with us, so try again */
382 continue;
383 }
384
385 if (a.st_ino == b.st_ino)
386 break;
387
388 VIR_DEBUG("Pid file '%s' was recreated", path);
389 VIR_FORCE_CLOSE(fd);
390 /* Someone else must be racing with us, so try again */
391 }
392
393 g_snprintf(pidstr, sizeof(pidstr), "%lld", (long long) pid);
394
395 if (ftruncate(fd, 0) < 0) {
396 virReportSystemError(errno,
397 _("Failed to truncate pid file '%s'"),
398 path);
399 VIR_FORCE_CLOSE(fd);
400 return -1;
401 }
402
403 if (safewrite(fd, pidstr, strlen(pidstr)) < 0) {
404 virReportSystemError(errno,
405 _("Failed to write to pid file '%s'"),
406 path);
407 VIR_FORCE_CLOSE(fd);
408 }
409
410 return fd;
411 }
412
413
virPidFileAcquire(const char * dir,const char * name,bool waitForLock,pid_t pid)414 int virPidFileAcquire(const char *dir,
415 const char *name,
416 bool waitForLock,
417 pid_t pid)
418 {
419 g_autofree char *pidfile = NULL;
420
421 if (name == NULL || dir == NULL)
422 return -EINVAL;
423
424 if (!(pidfile = virPidFileBuildPath(dir, name)))
425 return -ENOMEM;
426
427 return virPidFileAcquirePath(pidfile, waitForLock, pid);
428 }
429
430
virPidFileReleasePath(const char * path,int fd)431 int virPidFileReleasePath(const char *path,
432 int fd)
433 {
434 int rc = 0;
435 /*
436 * We need to unlink before closing the FD to avoid
437 * a race, but Win32 won't let you unlink an open
438 * file handle. So on that platform we do the reverse
439 * and just have to live with the possible race.
440 */
441 #ifdef WIN32
442 VIR_FORCE_CLOSE(fd);
443 if (unlink(path) < 0 && errno != ENOENT)
444 rc = -errno;
445 #else
446 if (unlink(path) < 0 && errno != ENOENT)
447 rc = -errno;
448 VIR_FORCE_CLOSE(fd);
449 #endif
450 return rc;
451 }
452
453
virPidFileRelease(const char * dir,const char * name,int fd)454 int virPidFileRelease(const char *dir,
455 const char *name,
456 int fd)
457 {
458 g_autofree char *pidfile = NULL;
459
460 if (name == NULL || dir == NULL)
461 return -EINVAL;
462
463 if (!(pidfile = virPidFileBuildPath(dir, name)))
464 return -ENOMEM;
465
466 return virPidFileReleasePath(pidfile, fd);
467 }
468
469
470 int
virPidFileConstructPath(bool privileged,const char * runstatedir,const char * progname,char ** pidfile)471 virPidFileConstructPath(bool privileged,
472 const char *runstatedir,
473 const char *progname,
474 char **pidfile)
475 {
476 g_autofree char *rundir = NULL;
477
478 if (privileged) {
479 /*
480 * This is here just to allow calling this function with
481 * statedir == NULL; of course only when !privileged.
482 */
483 if (!runstatedir) {
484 virReportError(VIR_ERR_INTERNAL_ERROR,
485 "%s", _("No runstatedir specified"));
486 return -1;
487 }
488 *pidfile = g_strdup_printf("%s/%s.pid", runstatedir, progname);
489 } else {
490 rundir = virGetUserRuntimeDirectory();
491
492 if (g_mkdir_with_parents(rundir, 0700) < 0) {
493 virReportSystemError(errno,
494 _("Cannot create user runtime directory '%s'"),
495 rundir);
496 return -1;
497 }
498
499 *pidfile = g_strdup_printf("%s/%s.pid", rundir, progname);
500 }
501
502 return 0;
503 }
504
505
506 /**
507 * virPidFileForceCleanupPath:
508 *
509 * Check if the pidfile is left around and clean it up whatever it
510 * takes. This doesn't raise an error. This function must not be
511 * called multiple times with the same path, be it in threads or
512 * processes. This function does not raise any errors.
513 *
514 * Returns 0 if the pidfile was successfully cleaned up, -1 otherwise.
515 */
516 int
virPidFileForceCleanupPathFull(const char * path,bool group)517 virPidFileForceCleanupPathFull(const char *path, bool group)
518 {
519 pid_t pid = 0;
520 int fd = -1;
521
522 if (!virFileExists(path))
523 return 0;
524
525 if (virPidFileReadPath(path, &pid) < 0)
526 return -1;
527
528 fd = virPidFileAcquirePath(path, false, 0);
529 if (fd < 0) {
530 virResetLastError();
531
532 if (pid > 1 && group)
533 pid = virProcessGroupGet(pid);
534
535 /* Only kill the process if the pid is valid one. 0 means
536 * there is somebody else doing the same pidfile cleanup
537 * machinery. */
538 if (group)
539 virProcessKillPainfullyDelay(pid, true, 0, true);
540 else if (pid)
541 virProcessKillPainfully(pid, true);
542
543 if (virPidFileDeletePath(path) < 0)
544 return -1;
545 }
546
547 if (fd)
548 virPidFileReleasePath(path, fd);
549
550 return 0;
551 }
552
553 int
virPidFileForceCleanupPath(const char * path)554 virPidFileForceCleanupPath(const char *path)
555 {
556 return virPidFileForceCleanupPathFull(path, false);
557 }
558