/* * Create the index file associated with a trace file. * * Return fd on success, a negative value on error. */ int index_create_file(char *path_name, char *stream_name, int uid, int gid, uint64_t size, uint64_t count) { int ret, fd = -1; ssize_t size_ret; struct ctf_packet_index_file_hdr hdr; char fullpath[PATH_MAX]; 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 = run_as_mkdir(fullpath, S_IRWXU | S_IRWXG, uid, gid); if (ret < 0) { if (ret != -EEXIST) { PERROR("Index trace directory creation error"); 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; 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)); size_ret = lttng_write(fd, &hdr, sizeof(hdr)); if (size_ret < sizeof(hdr)) { PERROR("write index header"); ret = -1; goto error; } return fd; error: if (fd >= 0) { int close_ret; close_ret = close(fd); if (close_ret < 0) { PERROR("close index fd"); } } return ret; }
/* * Write index values to the given fd of size len. * * Return "len" on success or else < len on error. errno contains error * details. */ ssize_t index_write(int fd, struct lttng_packet_index *index, size_t len) { ssize_t ret; assert(fd >= 0); assert(index); ret = lttng_write(fd, index, len); if (ret < len) { PERROR("writing index file"); } return ret; }
/* * Write to writable pipe used to notify a thread. */ int notify_thread_pipe(int wpipe) { ssize_t ret; /* Ignore if the pipe is invalid. */ if (wpipe < 0) { return 0; } ret = lttng_write(wpipe, "!", 1); if (ret < 1) { PERROR("write poll pipe"); } return (int) ret; }
/* * Write metadata to the cache, extend the cache if necessary. We support * non-contiguous updates but not overlapping ones. If there is contiguous * metadata in the cache, we send it to the ring buffer. The metadata cache * lock MUST be acquired to write in the cache. * * Return 0 on success, a negative value on error. */ int consumer_metadata_cache_write(struct lttng_consumer_channel *channel, unsigned int offset, unsigned int len, char *data) { int ret = 0; int size_ret; struct consumer_metadata_cache *cache; assert(channel); assert(channel->metadata_cache); cache = channel->metadata_cache; DBG("Writing %u bytes from offset %u in metadata cache", len, offset); if (offset + len > cache->cache_alloc_size) { ret = extend_metadata_cache(channel, len - cache->cache_alloc_size + offset); if (ret < 0) { ERR("Extending metadata cache"); goto end; } } memcpy(cache->data + offset, data, len); cache->total_bytes_written += len; if (offset + len > cache->max_offset) { cache->max_offset = offset + len; } if (cache->max_offset == cache->total_bytes_written) { char dummy = 'c'; cache->contiguous = cache->max_offset; if (channel->monitor) { size_ret = lttng_write(channel->metadata_stream->ust_metadata_poll_pipe[1], &dummy, 1); if (size_ret < 1) { ERR("Wakeup UST metadata pipe"); ret = -1; goto end; } } } end: return ret; }
/* * Write index values to the given fd of size len. * * Return "len" on success or else < len on error. errno contains error * details. */ ssize_t index_write(int fd, struct ctf_packet_index *index, size_t len) { ssize_t ret; assert(index); if (fd < 0) { ret = -EINVAL; goto error; } ret = lttng_write(fd, index, len); if (ret < len) { PERROR("writing index file"); } error: return ret; }
/* * Write index values to the given index file. * * Return 0 on success, -1 on error. */ int lttng_index_file_write(const struct lttng_index_file *index_file, const struct ctf_packet_index *element) { ssize_t ret; int fd = index_file->fd; size_t len = index_file->element_len; assert(element); if (fd < 0) { goto error; } ret = lttng_write(fd, element, len); if (ret < len) { PERROR("writing index file"); goto error; } return 0; error: return -1; }
void ht_cleanup_push(struct lttng_ht *ht) { ssize_t ret; int fd = ht_cleanup_pipe[1]; if (!ht) { return; } if (fd < 0) return; ret = lttng_write(fd, &ht, sizeof(ht)); if (ret < sizeof(ht)) { PERROR("write ht cleanup pipe %d", fd); if (ret < 0) { ret = -errno; } goto error; } /* All good. Don't send back the write positive ret value. */ ret = 0; error: assert(!ret); }
/* * Create the index file associated with a trace file. * * Return allocated struct lttng_index_file, NULL on error. */ struct lttng_index_file *lttng_index_file_create(char *path_name, char *stream_name, int uid, int gid, uint64_t size, uint64_t count, uint32_t major, uint32_t minor) { struct lttng_index_file *index_file; int ret, fd = -1; ssize_t size_ret; struct ctf_packet_index_file_hdr hdr; char fullpath[PATH_MAX]; uint32_t element_len = ctf_packet_index_len(major, minor); index_file = zmalloc(sizeof(*index_file)); if (!index_file) { PERROR("allocating lttng_index_file"); goto error; } 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; hdr.magic = htobe32(CTF_INDEX_MAGIC); hdr.index_major = htobe32(major); hdr.index_minor = htobe32(minor); hdr.packet_index_len = htobe32(element_len); 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; index_file->major = major; index_file->minor = minor; index_file->element_len = element_len; urcu_ref_init(&index_file->ref); return index_file; error: if (fd >= 0) { int close_ret; close_ret = close(fd); if (close_ret < 0) { PERROR("close index fd"); } } free(index_file); return NULL; }