Fix: sessiond: freeze on channel creation on restart
[lttng-tools.git] / src / common / lockfile.c
CommitLineData
f9431861
JG
1/*
2 * Copyright (C) 2012 David Goulet <dgoulet@efficios.com>
3 * Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5 * SPDX-License-Identifier: LGPL-2.1-only
6 *
7 */
8
9#include <common/error.h>
10#include <common/lockfile.h>
11#include <common/macros.h>
12
13#include <assert.h>
14
cea28ac8
JG
15#include <fcntl.h>
16
f9431861
JG
17#ifdef HAVE_FLOCK
18
cea28ac8
JG
19#include <sys/file.h>
20
21static int lock_file(const char *filepath, int fd)
22{
23 int ret;
24
25 /*
26 * Attempt to lock the file. If this fails, there is
27 * already a process using the same lock file running
28 * and we should exit.
29 */
30 ret = flock(fd, LOCK_EX | LOCK_NB);
31 if (ret == -1) {
32 /* EWOULDBLOCK are expected if the file is locked: don't spam the logs. */
33 if (errno != EWOULDBLOCK) {
34 PERROR("Failed to apply lock on lock file: file_path=`%s`", filepath);
35 }
36 }
37
38 return ret;
39}
40
f9431861
JG
41#else /* HAVE_FLOCK */
42
cea28ac8
JG
43static int lock_file(const char *filepath, int fd)
44{
45 int ret;
46 struct flock lock = {};
47
48 lock.l_whence = SEEK_SET;
49 lock.l_type = F_WRLCK;
50
51 /*
52 * Attempt to lock the file. If this fails, there is
53 * already a process using the same lock file running
54 * and we should exit.
55 */
56 ret = fcntl(fd, F_SETLK, &lock);
57 if (ret == -1) {
58 /* EAGAIN and EACCESS are expected if the file is locked: don't spam the logs. */
59 if (errno != EAGAIN && errno != EACCES) {
60 PERROR("Failed to set lock on lock file: file_path=`%s`", filepath);
61 }
62 }
63
64 return ret;
65}
66
67#endif /* HAVE_FLOCK */
f9431861
JG
68
69int utils_create_lock_file(const char *filepath)
70{
cea28ac8 71 int ret, fd;
f9431861
JG
72
73 assert(filepath);
74
f9431861
JG
75 fd = open(filepath, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
76 if (fd < 0) {
cea28ac8 77 PERROR("Failed to open lock file `%s`", filepath);
f9431861
JG
78 fd = -1;
79 goto error;
80 }
81
82 /*
cea28ac8
JG
83 * Attempt to lock the file. If this fails, there is already a process using the same lock
84 * file running and we should exit.
85 *
86 * lock_file is chosen based on the build configuration, see implementations above.
f9431861 87 */
cea28ac8 88 ret = lock_file(filepath, fd);
f9431861 89 if (ret == -1) {
cea28ac8
JG
90 ERR("Could not get lock file `%s`, another instance is running.", filepath);
91
f9431861 92 if (close(fd)) {
cea28ac8 93 PERROR("Failed to close lock file fd: fd=%d", fd);
f9431861 94 }
cea28ac8 95
f9431861
JG
96 fd = ret;
97 goto error;
98 }
99
cea28ac8
JG
100 DBG("Acquired lock file: file_path=`%s`", filepath);
101
f9431861
JG
102error:
103 return fd;
104}
This page took 0.027343 seconds and 4 git commands to generate.