X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Findex%2Findex.c;h=066618e8bd1a70ea3a7bb7ebe9e2b4b76ece1cc1;hp=3d22ca61cc1ad720e7e50270137053c6d5f5a787;hb=de7e372efecc2cf51921f2ac5a657337e04a39d3;hpb=309167d2a6f59d0c8cbf64eb23ba912cdea76a34 diff --git a/src/common/index/index.c b/src/common/index/index.c index 3d22ca61c..066618e8b 100644 --- a/src/common/index/index.c +++ b/src/common/index/index.c @@ -16,11 +16,15 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE +#define _LGPL_SOURCE #include +#include +#include +#include #include #include +#include #include #include "index.h" @@ -34,24 +38,55 @@ int index_create_file(char *path_name, char *stream_name, int uid, int gid, uint64_t size, uint64_t count) { int ret, fd = -1; - struct lttng_packet_index_file_hdr hdr; + ssize_t size_ret; + struct ctf_packet_index_file_hdr hdr; + char fullpath[PATH_MAX]; - ret = utils_create_stream_file(path_name, stream_name, size, count, uid, + ret = snprintf(fullpath, sizeof(fullpath), "%s/" DEFAULT_INDEX_DIR, + path_name); + if (ret < 0) { + PERROR("snprintf index path"); + goto error; + } + + /* Create index directory if necessary. */ + ret = utils_mkdir(fullpath, S_IRWXU | S_IRWXG, uid, gid); + if (ret < 0) { + if (errno != EEXIST) { + PERROR("Index trace directory creation error"); + goto error; + } + } + + /* + * 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. + */ + ret = utils_unlink_stream_file(fullpath, stream_name, size, count, uid, + gid, DEFAULT_INDEX_FILE_SUFFIX); + if (ret < 0 && errno != ENOENT) { + goto error; + } + ret = utils_create_stream_file(fullpath, stream_name, size, count, uid, gid, DEFAULT_INDEX_FILE_SUFFIX); if (ret < 0) { goto error; } fd = ret; - memcpy(hdr.magic, INDEX_MAGIC, sizeof(hdr.magic)); - hdr.index_major = htobe32(INDEX_MAJOR); - hdr.index_minor = htobe32(INDEX_MINOR); + hdr.magic = htobe32(CTF_INDEX_MAGIC); + hdr.index_major = htobe32(CTF_INDEX_MAJOR); + hdr.index_minor = htobe32(CTF_INDEX_MINOR); + hdr.packet_index_len = htobe32(sizeof(struct ctf_packet_index)); - do { - ret = write(fd, &hdr, sizeof(hdr)); - } while (ret < 0 && errno == EINTR); - if (ret < 0) { + size_ret = lttng_write(fd, &hdr, sizeof(hdr)); + if (size_ret < sizeof(hdr)) { PERROR("write index header"); + ret = -1; goto error; } @@ -72,21 +107,98 @@ error: /* * Write index values to the given fd of size len. * - * Return 0 on success or else a negative value on error. + * Return "len" on success or else < len on error. errno contains error + * details. */ -int index_write(int fd, struct lttng_packet_index *index, size_t len) +ssize_t index_write(int fd, struct ctf_packet_index *index, size_t len) { - int ret; + ssize_t ret; - assert(fd >= 0); assert(index); - do { - ret = write(fd, index, len); - } while (ret < 0 && errno == EINTR); - if (ret < 0) { + if (fd < 0) { + ret = -EINVAL; + goto error; + } + + ret = lttng_write(fd, index, len); + if (ret < len) { PERROR("writing index file"); } +error: + return ret; +} + +/* + * Open index file using a given path, channel name and tracefile count. + * + * Return read only FD on success or else a negative value. + */ +int index_open(const char *path_name, const char *channel_name, + uint64_t tracefile_count, uint64_t tracefile_count_current) +{ + int ret, read_fd; + ssize_t read_len; + char fullpath[PATH_MAX]; + struct ctf_packet_index_file_hdr hdr; + + assert(path_name); + assert(channel_name); + + if (tracefile_count > 0) { + ret = snprintf(fullpath, sizeof(fullpath), "%s/" DEFAULT_INDEX_DIR "/%s_%" + PRIu64 DEFAULT_INDEX_FILE_SUFFIX, path_name, + channel_name, tracefile_count_current); + } else { + ret = snprintf(fullpath, sizeof(fullpath), "%s/" DEFAULT_INDEX_DIR "/%s" + DEFAULT_INDEX_FILE_SUFFIX, path_name, channel_name); + } + if (ret < 0) { + PERROR("snprintf index path"); + goto error; + } + + 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"); + } + goto error; + } + + read_len = lttng_read(read_fd, &hdr, sizeof(hdr)); + if (read_len < 0) { + PERROR("Reading index header"); + goto error_close; + } + + if (be32toh(hdr.magic) != CTF_INDEX_MAGIC) { + ERR("Invalid header magic"); + goto error_close; + } + if (be32toh(hdr.index_major) != CTF_INDEX_MAJOR || + be32toh(hdr.index_minor) != CTF_INDEX_MINOR) { + ERR("Invalid header version"); + goto error_close; + } + + return read_fd; + +error_close: + if (read_fd >= 0) { + int close_ret; + + close_ret = close(read_fd); + if (close_ret < 0) { + PERROR("close read fd %d", read_fd); + } + } + ret = -1; + +error: return ret; }