static pid_t ppid; /* Parent PID for --sig-parent option */
static pid_t child_ppid; /* Internal parent PID use with daemonize. */
static char *rundir;
+static int lockfile_fd = -1;
/* Set to 1 when a SIGUSR1 signal is received. */
static int recv_child_signal;
}
}
+/*
+ * Generate the full lock file path using the rundir.
+ *
+ * Return the snprintf() return value thus a negative value is an error.
+ */
+static int generate_lock_file_path(char *path, size_t len)
+{
+ int ret;
+
+ assert(path);
+ assert(rundir);
+
+ /* Build lockfile path from rundir. */
+ ret = snprintf(path, len, "%s/" DEFAULT_LTTNG_SESSIOND_LOCKFILE, rundir);
+ if (ret < 0) {
+ PERROR("snprintf lockfile path");
+ }
+
+ return ret;
+}
+
/*
* Cleanup the daemon
*/
DBG("Removing directory %s", path);
(void) rmdir(path);
- /*
- * We do NOT rmdir rundir because there are other processes
- * using it, for instance lttng-relayd, which can start in
- * parallel with this teardown.
- */
-
- free(rundir);
-
DBG("Cleaning up all sessions");
/* Destroy session list mutex */
close_consumer_sockets();
+
+ /*
+ * Cleanup lock file by deleting it and finaly closing it which will
+ * release the file system lock.
+ */
+ if (lockfile_fd >= 0) {
+ char lockfile_path[PATH_MAX];
+
+ ret = generate_lock_file_path(lockfile_path, sizeof(lockfile_path));
+ if (ret > 0) {
+ ret = remove(lockfile_path);
+ if (ret < 0) {
+ PERROR("remove lock file");
+ }
+ ret = close(lockfile_fd);
+ if (ret < 0) {
+ PERROR("close lock file");
+ }
+ }
+ }
+
+ /*
+ * We do NOT rmdir rundir because there are other processes
+ * using it, for instance lttng-relayd, which can start in
+ * parallel with this teardown.
+ */
+
+ free(rundir);
+
/* <fun> */
DBG("%c[%d;%dm*** assert failed :-) *** ==> %c[%dm%c[%d;%dm"
"Matthew, BEET driven development works!%c[%dm",
return;
}
+/*
+ * Create lockfile using the rundir and return its fd.
+ */
+static int create_lockfile(void)
+{
+ int ret;
+ char lockfile_path[PATH_MAX];
+
+ ret = generate_lock_file_path(lockfile_path, sizeof(lockfile_path));
+ if (ret < 0) {
+ goto error;
+ }
+
+ ret = utils_create_lock_file(lockfile_path);
+error:
+ return ret;
+}
+
/*
* Write JUL TCP port using the rundir.
*/
}
}
+ lockfile_fd = create_lockfile();
+ if (lockfile_fd < 0) {
+ goto error;
+ }
+
/* Set consumer initial state */
kernel_consumerd_state = CONSUMER_STOPPED;
ust_consumerd_state = CONSUMER_STOPPED;
#include <inttypes.h>
#include <grp.h>
#include <pwd.h>
+#include <sys/file.h>
#include <common/common.h>
#include <common/runas.h>
return ret;
}
+/*
+ * Create lock file to the given path and filename.
+ * Returns the associated file descriptor, -1 on error.
+ */
+LTTNG_HIDDEN
+int utils_create_lock_file(const char *filepath)
+{
+ int ret;
+ int fd;
+
+ assert(filepath);
+
+ fd = open(filepath, O_CREAT,
+ O_WRONLY | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ if (fd < 0) {
+ PERROR("open lock file %s", filepath);
+ ret = -1;
+ goto error;
+ }
+
+ /*
+ * Attempt to lock the file. If this fails, there is
+ * already a process using the same lock file running
+ * and we should exit.
+ */
+ ret = flock(fd, LOCK_EX | LOCK_NB);
+ if (ret) {
+ WARN("Could not get lock file %s, another instance is running.",
+ filepath);
+ close(fd);
+ fd = ret;
+ goto error;
+ }
+
+error:
+ return fd;
+}
+
/*
* Recursively create directory using the given path and mode.
*