return ret;
}
-/*
- * Create the tracefile on disk.
- *
- * Return 0 on success or else a negative value.
- */
-int lttng_create_output_file(struct lttng_consumer_stream *stream)
-{
- int ret;
- char full_path[PATH_MAX];
- char *path_name_id = NULL;
- char *path;
-
- assert(stream);
-
- /* Don't create anything if this is set for streaming. */
- if (stream->net_seq_idx != (uint64_t) -1ULL) {
- ret = 0;
- goto end;
- }
-
- ret = snprintf(full_path, sizeof(full_path), "%s/%s",
- stream->chan->pathname, stream->name);
- if (ret < 0) {
- PERROR("snprintf create output file");
- goto error;
- }
-
- /*
- * If we split the trace in multiple files, we have to add the tracefile
- * current count at the end of the tracefile name
- */
- if (stream->chan->tracefile_size > 0) {
- ret = asprintf(&path_name_id, "%s_%" PRIu64, full_path,
- stream->tracefile_count_current);
- if (ret < 0) {
- PERROR("Allocating path name ID");
- goto error;
- }
- path = path_name_id;
- } else {
- path = full_path;
- }
-
- ret = run_as_open(path, O_WRONLY | O_CREAT | O_TRUNC,
- S_IRWXU | S_IRWXG | S_IRWXO, stream->uid, stream->gid);
- if (ret < 0) {
- PERROR("open stream path %s", path);
- goto error_open;
- }
- stream->out_fd = ret;
- stream->tracefile_size_current = 0;
-
-error_open:
- free(path_name_id);
-error:
-end:
- return ret;
-}
-
-/*
- * Change the output tracefile according to the tracefile_size and
- * tracefile_count parameters. The stream lock MUST be held before calling this
- * function because we are modifying the stream status.
- *
- * Return 0 on success or else a negative value.
- */
-static int rotate_output_file(struct lttng_consumer_stream *stream)
-{
- int ret;
-
- assert(stream);
- assert(stream->tracefile_size_current);
-
- ret = close(stream->out_fd);
- if (ret < 0) {
- PERROR("Closing tracefile");
- goto end;
- }
-
- if (stream->chan->tracefile_count > 0) {
- stream->tracefile_count_current =
- (stream->tracefile_count_current + 1) %
- stream->chan->tracefile_count;
- } else {
- stream->tracefile_count_current++;
- }
-
- return lttng_create_output_file(stream);
-
-end:
- return ret;
-}
-
/*
* Mmap the ring buffer, read it and write the data to the tracefile. This is a
* core function for writing trace buffers to either the local filesystem or
if (stream->chan->tracefile_size > 0 &&
(stream->tracefile_size_current + len) >
stream->chan->tracefile_size) {
- ret = rotate_output_file(stream);
+ ret = utils_rotate_stream_file(stream->chan->pathname,
+ stream->name, stream->chan->tracefile_size,
+ stream->chan->tracefile_count, stream->uid, stream->gid,
+ stream->out_fd, &(stream->tracefile_count_current));
if (ret < 0) {
ERR("Rotating output file");
goto end;
}
- outfd = stream->out_fd;
+ outfd = stream->out_fd = ret;
}
stream->tracefile_size_current += len;
}
if (stream->chan->tracefile_size > 0 &&
(stream->tracefile_size_current + len) >
stream->chan->tracefile_size) {
- ret = rotate_output_file(stream);
+ ret = utils_rotate_stream_file(stream->chan->pathname,
+ stream->name, stream->chan->tracefile_size,
+ stream->chan->tracefile_count, stream->uid, stream->gid,
+ stream->out_fd, &(stream->tracefile_count_current));
if (ret < 0) {
ERR("Rotating output file");
goto end;
}
- outfd = stream->out_fd;
+ outfd = stream->out_fd = ret;
}
stream->tracefile_size_current += len;
}
int (*recv_stream)(struct lttng_consumer_stream *stream),
int (*update_stream)(int sessiond_key, uint32_t state));
void lttng_consumer_destroy(struct lttng_consumer_local_data *ctx);
-int lttng_create_output_file(struct lttng_consumer_stream *stream);
ssize_t lttng_consumer_on_read_subbuffer_mmap(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len,
#include <common/sessiond-comm/relayd.h>
#include <common/compat/fcntl.h>
#include <common/relayd/relayd.h>
+#include <common/utils.h>
#include "kernel-consumer.h"
assert(stream);
- ret = lttng_create_output_file(stream);
- if (ret < 0) {
- ERR("Creating output file");
- goto error;
+ /* Don't create anything if this is set for streaming. */
+ if (stream->net_seq_idx == (uint64_t) -1ULL) {
+ ret = utils_create_stream_file(stream->chan->pathname, stream->name,
+ stream->chan->tracefile_size, stream->tracefile_count_current,
+ stream->uid, stream->gid);
+ if (ret < 0) {
+ goto error;
+ }
+ stream->out_fd = ret;
+ stream->tracefile_size_current = 0;
}
if (stream->output == LTTNG_EVENT_MMAP) {
#include <common/compat/fcntl.h>
#include <common/consumer-metadata-cache.h>
#include <common/consumer-timer.h>
+#include <common/utils.h>
#include "ust-consumer.h"
/*
* Called when a stream is created.
+ *
+ * Return 0 on success or else a negative value.
*/
int lttng_ustconsumer_on_recv_stream(struct lttng_consumer_stream *stream)
{
- return lttng_create_output_file(stream);
+ int ret;
+
+ /* Don't create anything if this is set for streaming. */
+ if (stream->net_seq_idx == (uint64_t) -1ULL) {
+ ret = utils_create_stream_file(stream->chan->pathname, stream->name,
+ stream->chan->tracefile_size, stream->tracefile_count_current,
+ stream->uid, stream->gid);
+ if (ret < 0) {
+ goto error;
+ }
+ stream->out_fd = ret;
+ stream->tracefile_size_current = 0;
+ }
+ ret = 0;
+
+error:
+ return ret;
}
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <inttypes.h>
#include <common/common.h>
+#include <common/runas.h>
#include "utils.h"
error:
return ret;
}
+
+/*
+ * Create the stream tracefile on disk.
+ *
+ * Return 0 on success or else a negative value.
+ */
+int utils_create_stream_file(char *path_name, char *file_name, uint64_t size,
+ uint64_t count, int uid, int gid)
+{
+ int ret, out_fd;
+ char full_path[PATH_MAX], *path_name_id = NULL, *path;
+
+ assert(path_name);
+ assert(file_name);
+
+ ret = snprintf(full_path, sizeof(full_path), "%s/%s",
+ path_name, file_name);
+ if (ret < 0) {
+ PERROR("snprintf create output file");
+ goto error;
+ }
+
+ /*
+ * If we split the trace in multiple files, we have to add the count at the
+ * end of the tracefile name
+ */
+ if (size > 0) {
+ ret = asprintf(&path_name_id, "%s_%" PRIu64, full_path, count);
+ if (ret < 0) {
+ PERROR("Allocating path name ID");
+ goto error;
+ }
+ path = path_name_id;
+ } else {
+ path = full_path;
+ }
+
+ out_fd = run_as_open(path, O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRWXU | S_IRWXG | S_IRWXO, uid, gid);
+ if (out_fd < 0) {
+ PERROR("open stream path %s", path);
+ goto error_open;
+ }
+ ret = out_fd;
+
+error_open:
+ free(path_name_id);
+error:
+ return ret;
+}
+
+/*
+ * Change the output tracefile according to the given size and count The
+ * new_count pointer is set during this operation.
+ *
+ * From the consumer, the stream lock MUST be held before calling this function
+ * because we are modifying the stream status.
+ *
+ * Return 0 on success or else a negative value.
+ */
+int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size,
+ uint64_t count, int uid, int gid, int out_fd, uint64_t *new_count)
+{
+ int ret;
+
+ ret = close(out_fd);
+ if (ret < 0) {
+ PERROR("Closing tracefile");
+ goto error;
+ }
+
+ if (count > 0) {
+ *new_count = (*new_count + 1) % count;
+ } else {
+ (*new_count)++;
+ }
+
+ return utils_create_stream_file(path_name, file_name, size, *new_count,
+ uid, gid);
+error:
+ return ret;
+}
int utils_set_fd_cloexec(int fd);
int utils_create_pid_file(pid_t pid, const char *filepath);
int utils_mkdir_recursive(const char *path, mode_t mode);
+int utils_create_stream_file(char *path_name, char *file_name, uint64_t size,
+ uint64_t count, int uid, int gid);
+int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size,
+ uint64_t count, int uid, int gid, int out_fd, uint64_t *new_count);
#endif /* _COMMON_UTILS_H */
# URI unit tests
test_uri_SOURCES = test_uri.c
-test_uri_LDADD = $(LIBTAP) $(LIBCOMMON)
+test_uri_LDADD = $(LIBTAP) $(LIBCOMMON) $(LIBHASHTABLE)
# Session unit test
SESSIONS=$(top_srcdir)/src/bin/lttng-sessiond/session.c \