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