X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Findex%2Findex.c;h=694e3d18698dd3dfe142bc9e199026a9a8f6c9b4;hb=2abe796968937298012c0ec668f7fc88305683f2;hp=b5591d137c923a97617005f9a85145e09264cba4;hpb=f8f3885cc52af9d3c951da78989d6f4a25270411;p=lttng-tools.git diff --git a/src/common/index/index.c b/src/common/index/index.c index b5591d137..694e3d186 100644 --- a/src/common/index/index.c +++ b/src/common/index/index.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -35,7 +36,7 @@ * * Return allocated struct lttng_index_file, NULL on error. */ -struct lttng_index_file *lttng_index_file_create(char *path_name, +struct lttng_index_file *lttng_index_file_create(const char *path_name, char *stream_name, int uid, int gid, uint64_t size, uint64_t count, uint32_t major, uint32_t minor) { @@ -88,15 +89,10 @@ struct lttng_index_file *lttng_index_file_create(char *path_name, } fd = ret; - hdr.magic = htobe32(CTF_INDEX_MAGIC); - hdr.index_major = htobe32(major); - hdr.index_minor = htobe32(minor); - hdr.packet_index_len = htobe32(element_len); - + ctf_packet_index_file_hdr_init(&hdr, major, minor); size_ret = lttng_write(fd, &hdr, sizeof(hdr)); if (size_ret < sizeof(hdr)) { PERROR("write index header"); - ret = -1; goto error; } index_file->fd = fd; @@ -120,6 +116,93 @@ error: return NULL; } +struct lttng_index_file *lttng_index_file_create_from_trace_chunk( + struct lttng_trace_chunk *chunk, + const char *channel_path, char *stream_name, + uint64_t stream_file_size, uint64_t stream_count, + uint32_t index_major, uint32_t index_minor, + bool unlink_existing_file) +{ + struct lttng_index_file *index_file; + enum lttng_trace_chunk_status chunk_status; + int ret, fd = -1; + ssize_t size_ret; + struct ctf_packet_index_file_hdr hdr; + char index_directory_path[LTTNG_PATH_MAX]; + char index_file_path[LTTNG_PATH_MAX]; + const uint32_t element_len = ctf_packet_index_len(index_major, + index_minor); + const int flags = O_WRONLY | O_CREAT | O_TRUNC; + const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + + index_file = zmalloc(sizeof(*index_file)); + if (!index_file) { + PERROR("Failed to allocate lttng_index_file"); + goto error; + } + + ret = snprintf(index_directory_path, sizeof(index_directory_path), + "%s/" DEFAULT_INDEX_DIR, channel_path); + if (ret < 0 || ret >= sizeof(index_directory_path)) { + ERR("Failed to format index directory path"); + goto error; + } + + ret = utils_stream_file_path(index_directory_path, stream_name, + stream_file_size, stream_count, + DEFAULT_INDEX_FILE_SUFFIX, + index_file_path, sizeof(index_file_path)); + if (ret) { + goto error; + } + + if (unlink_existing_file) { + /* + * For tracefile rotation. We need to unlink the old + * file if present to synchronize with the tail of the + * live viewer which could be working on this same file. + * By doing so, any reference to the old index file + * stays valid even if we re-create a new file with the + * same name afterwards. + */ + chunk_status = lttng_trace_chunk_unlink_file(chunk, + index_file_path); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + goto error; + } + } + + chunk_status = lttng_trace_chunk_open_file(chunk, index_file_path, + flags, mode, &fd); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + goto error; + } + + ctf_packet_index_file_hdr_init(&hdr, index_major, index_minor); + size_ret = lttng_write(fd, &hdr, sizeof(hdr)); + if (size_ret < sizeof(hdr)) { + PERROR("Failed to write index header"); + goto error; + } + index_file->fd = fd; + index_file->major = index_major; + index_file->minor = index_minor; + index_file->element_len = element_len; + urcu_ref_init(&index_file->ref); + + return index_file; + +error: + if (fd >= 0) { + ret = close(fd); + if (ret < 0) { + PERROR("Failed to close file descriptor of index file"); + } + } + free(index_file); + return NULL; +} + /* * Write index values to the given index file. * @@ -128,12 +211,16 @@ error: int lttng_index_file_write(const struct lttng_index_file *index_file, const struct ctf_packet_index *element) { + int fd; + size_t len; ssize_t ret; - int fd = index_file->fd; - size_t len = index_file->element_len; + assert(index_file); assert(element); + fd = index_file->fd; + len = index_file->element_len; + if (fd < 0) { goto error; } @@ -168,10 +255,14 @@ int lttng_index_file_read(const struct lttng_index_file *index_file, } ret = lttng_read(fd, element, len); - if (ret < len) { + if (ret < 0) { PERROR("read index file"); goto error; } + if (ret < len) { + ERR("lttng_read expected %zu, returned %zd", len, ret); + goto error; + } return 0; error: @@ -219,11 +310,7 @@ struct lttng_index_file *lttng_index_file_open(const char *path_name, DBG("Index opening file %s in read only", fullpath); read_fd = open(fullpath, O_RDONLY); if (read_fd < 0) { - if (errno == ENOENT) { - ret = -ENOENT; - } else { - PERROR("opening index in read-only"); - } + PERROR("opening index in read-only"); goto error; } @@ -245,6 +332,10 @@ struct lttng_index_file *lttng_index_file_open(const char *path_name, ERR("Invalid header version"); goto error_close; } + if (element_len > sizeof(struct ctf_packet_index)) { + ERR("Index element length too long"); + goto error_close; + } index_file->fd = read_fd; index_file->major = major; @@ -263,7 +354,6 @@ error_close: PERROR("close read fd %d", read_fd); } } - ret = -1; error: free(index_file);