+int get_block_offset_size(LttTracefile *tf, guint block_num,
+ uint64_t *offset, uint32_t *size)
+{
+ uint64_t offa, offb;
+
+ if (unlikely(block_num >= tf->num_blocks))
+ return -1;
+
+ offa = g_array_index(tf->buf_index, uint64_t, block_num);
+ if (likely(block_num < tf->num_blocks - 1))
+ offb = g_array_index(tf->buf_index, uint64_t, block_num + 1);
+ else
+ offb = tf->file_size;
+ *offset = offa;
+ *size = offb - offa;
+ return 0;
+}
+
+static int ltt_trace_update_block_index(LttTracefile *tf, uint64_t offset,
+ unsigned long firstBlock)
+{
+ int i = firstBlock;
+ int page_size = getpagesize();
+ unsigned int header_map_size = PAGE_ALIGN(ltt_subbuffer_header_size());
+
+ g_assert(tf->buf_index->len == i);
+ while (offset < tf->file_size) {
+ ltt_subbuffer_header_t *header;
+ uint64_t *off;
+ uint64_t size;
+
+ /* map block header */
+ header = mmap(0, header_map_size, PROT_READ,
+ MAP_PRIVATE, tf->fd, (off_t)offset);
+ if(header == MAP_FAILED) {
+ perror("Error in allocating memory for buffer of tracefile");
+ return -1;
+ }
+
+ /* read len, offset += len */
+ size = ltt_get_uint32(LTT_GET_BO(tf), &header->sb_size);
+
+ /* Only index completly writen blocks */
+ if (offset + size <= tf->file_size) {
+
+ tf->buf_index = g_array_set_size(tf->buf_index, i + 1);
+ off = &g_array_index(tf->buf_index, uint64_t, i);
+ *off = offset;
+
+ /* Store current buffer end cycle as the last file timestamp */
+ /* TODO ybrosseau 2010-11-04: Might want to convert it to a LttTime */
+ tf->end_timestamp = ltt_get_uint64(LTT_GET_BO(tf),
+ &header->cycle_count_end);
+
+ ++i;
+ }
+ offset += size;
+ /* unmap block header */
+ if(munmap(header, header_map_size)) {
+ g_warning("unmap size : %u\n", header_map_size);
+ perror("munmap error");
+ return -1;
+ }
+ }
+ tf->num_blocks = i;
+
+ return 0;
+}
+
+/* parse the new information from the file and reajust the number of blocks.
+ *
+ * Return value : 0 success, -1 error
+ */
+int ltt_trace_continue_block_index(LttTracefile *tf)
+{
+ int ret;
+ uint64_t offset;
+ uint32_t last_block_size;
+ unsigned long i = tf->num_blocks;
+ int page_size = getpagesize();
+ unsigned int header_map_size = PAGE_ALIGN(ltt_subbuffer_header_size());
+
+ get_block_offset_size(tf, tf->num_blocks-1, &offset, &last_block_size);
+
+ ltt_subbuffer_header_t *header_tmp = mmap(0, header_map_size, PROT_READ,
+ MAP_PRIVATE, tf->fd, (off_t)offset);
+ if(header_tmp == MAP_FAILED) {
+ perror("Error in allocating memory for buffer of tracefile");
+ return -1;
+ }
+
+ /* read len, offset += len */
+ offset += ltt_get_uint32(LTT_GET_BO(tf), &header_tmp->sb_size);
+
+ ret = ltt_trace_update_block_index(tf, offset, i);
+
+ return ret;
+}
+
+int ltt_trace_create_block_index(LttTracefile *tf)
+{
+ int ret;
+ uint64_t offset = 0;
+ unsigned long i = 0;
+
+ tf->buf_index = g_array_sized_new(FALSE, TRUE, sizeof(uint64_t),
+ DEFAULT_N_BLOCKS);
+ if(!tf->buf_index)
+ return -1;
+ ret = ltt_trace_update_block_index(tf, offset, i);
+ return ret;
+}