Port fix: don't round mmap offset to next page
[babeltrace.git] / plugins / ctf / fs-src / data-stream-file.c
index 51908e0a8dfb2c70fceff85920a81415f7ba496d..2fddc39dfc9d2ec3cd0bc0f43ce8a43a33476a5b 100644 (file)
@@ -50,7 +50,7 @@
 static inline
 size_t remaining_mmap_bytes(struct ctf_fs_ds_file *ds_file)
 {
-       return ds_file->mmap_valid_len - ds_file->request_offset;
+       return ds_file->mmap_len - ds_file->request_offset;
 }
 
 static
@@ -62,11 +62,12 @@ int ds_file_munmap(struct ctf_fs_ds_file *ds_file)
                goto end;
        }
 
-       if (munmap(ds_file->mmap_addr, ds_file->mmap_len)) {
-               BT_LOGE("Cannot memory-unmap address %p (size %zu) of file \"%s\" (%p): %s",
+       if (bt_munmap(ds_file->mmap_addr, ds_file->mmap_len)) {
+               BT_LOGE_ERRNO("Cannot memory-unmap file",
+                       ": address=%p, size=%zu, file_path=\"%s\", file=%p",
                        ds_file->mmap_addr, ds_file->mmap_len,
-                       ds_file->file->path->str, ds_file->file->fp,
-                       strerror(errno));
+                       ds_file->file->path->str,
+                       ds_file->file ? ds_file->file->fp : NULL);
                ret = -1;
                goto end;
        }
@@ -91,28 +92,30 @@ enum bt_ctf_notif_iter_medium_status ds_file_mmap_next(
                        goto error;
                }
 
-               ds_file->mmap_offset += ds_file->mmap_valid_len;
+               /*
+                * mmap_len is guaranteed to be page-aligned except on the
+                * last mapping where it may not be possible (since the file's
+                * size itself may not be a page multiple).
+                */
+               ds_file->mmap_offset += ds_file->mmap_len;
                ds_file->request_offset = 0;
        }
 
-       ds_file->mmap_valid_len = MIN(ds_file->file->size - ds_file->mmap_offset,
+       ds_file->mmap_len = MIN(ds_file->file->size - ds_file->mmap_offset,
                        ds_file->mmap_max_len);
-       if (ds_file->mmap_valid_len == 0) {
+       if (ds_file->mmap_len == 0) {
                ret = BT_CTF_NOTIF_ITER_MEDIUM_STATUS_EOF;
                goto end;
        }
-       /* Round up to next page, assuming page size being a power of 2. */
-       ds_file->mmap_len = (ds_file->mmap_valid_len + page_size - 1)
-                       & ~(page_size - 1);
        /* Map new region */
        assert(ds_file->mmap_len);
-       ds_file->mmap_addr = mmap((void *) 0, ds_file->mmap_len,
+       ds_file->mmap_addr = bt_mmap((void *) 0, ds_file->mmap_len,
                        PROT_READ, MAP_PRIVATE, fileno(ds_file->file->fp),
                        ds_file->mmap_offset);
        if (ds_file->mmap_addr == MAP_FAILED) {
-               BT_LOGE("Cannot memory-map address (size %zu) of file \"%s\" (%p) at offset %zu: %s",
+               BT_LOGE("Cannot memory-map address (size %zu) of file \"%s\" (%p) at offset %jd: %s",
                                ds_file->mmap_len, ds_file->file->path->str,
-                               ds_file->file->fp, ds_file->mmap_offset,
+                               ds_file->file->fp, (intmax_t) ds_file->mmap_offset,
                                strerror(errno));
                goto error;
        }
@@ -176,7 +179,8 @@ end:
 
 static
 struct bt_ctf_stream *medop_get_stream(
-               struct bt_ctf_stream_class *stream_class, void *data)
+               struct bt_ctf_stream_class *stream_class, uint64_t stream_id,
+               void *data)
 {
        struct ctf_fs_ds_file *ds_file = data;
        struct bt_ctf_stream_class *ds_file_stream_class;
@@ -199,10 +203,12 @@ end:
        return stream;
 }
 
-static struct bt_ctf_notif_iter_medium_ops medops = {
+BT_HIDDEN
+struct bt_ctf_notif_iter_medium_ops ctf_fs_ds_file_medops = {
        .request_bytes = medop_request_bytes,
        .get_stream = medop_get_stream,
 };
+
 static
 struct ctf_fs_ds_index *ctf_fs_ds_index_create(size_t length)
 {
@@ -255,7 +261,7 @@ int get_ds_file_packet_bounds_clock_classes(struct ctf_fs_ds_file *ds_file,
                struct bt_ctf_clock_class **_timestamp_end_cc)
 {
        int ret;
-       struct bt_ctf_field *timestamp_field;
+       struct bt_ctf_field *timestamp_field = NULL;
        struct bt_ctf_field *packet_context_field = NULL;
        struct bt_ctf_clock_class *timestamp_begin_cc = NULL;
        struct bt_ctf_clock_class *timestamp_end_cc = NULL;
@@ -283,7 +289,7 @@ int get_ds_file_packet_bounds_clock_classes(struct ctf_fs_ds_file *ds_file,
                BT_LOGD("Cannot retrieve the clock mapped to timestamp_begin of stream \'%s\'",
                                ds_file->file->path->str);
        }
-       bt_put(timestamp_field);
+       BT_PUT(timestamp_field);
 
        timestamp_field = bt_ctf_field_structure_get_field_by_name(
                        packet_context_field, "timestamp_end");
@@ -399,9 +405,17 @@ struct ctf_fs_ds_index *build_index_from_idx_file(
                                index_file_path);
                goto error;
        }
+
+       /*
+        * The g_mapped_file API limits us to 4GB files on 32-bit.
+        * Traces with such large indexes have never been seen in the wild,
+        * but this would need to be adjusted to support them.
+        */
        filesize = g_mapped_file_get_length(mapped_file);
        if (filesize < sizeof(*header)) {
-               BT_LOGW("Invalid LTTng trace index file: file size < header size");
+               BT_LOGW("Invalid LTTng trace index file: "
+                       "file size (%zu bytes) < header size (%zu bytes)",
+                       filesize, sizeof(*header));
                goto error;
        }
 
@@ -410,14 +424,17 @@ struct ctf_fs_ds_index *build_index_from_idx_file(
 
        file_pos = g_mapped_file_get_contents(mapped_file) + sizeof(*header);
        if (be32toh(header->magic) != CTF_INDEX_MAGIC) {
-               BT_LOGW("Invalid LTTng trace index: \"magic\" validation failed");
+               BT_LOGW("Invalid LTTng trace index: \"magic\" field validation failed");
                goto error;
        }
 
        file_index_entry_size = be32toh(header->packet_index_len);
        file_entry_count = (filesize - sizeof(*header)) / file_index_entry_size;
        if ((filesize - sizeof(*header)) % file_index_entry_size) {
-               BT_LOGW("Invalid index file size; not a multiple of index entry size");
+               BT_LOGW("Invalid LTTng trace index: the index's size after the header "
+                       "(%zu bytes) is not a multiple of the index entry size "
+                       "(%zu bytes)", (filesize - sizeof(*header)),
+                       sizeof(*header));
                goto error;
        }
 
@@ -434,7 +451,7 @@ struct ctf_fs_ds_index *build_index_from_idx_file(
                uint64_t packet_size = be64toh(file_index->packet_size);
 
                if (packet_size % CHAR_BIT) {
-                       BT_LOGW("Invalid packet size encountered in index file");
+                       BT_LOGW("Invalid packet size encountered in LTTng trace index file");
                        goto error;
                }
 
@@ -444,14 +461,19 @@ struct ctf_fs_ds_index *build_index_from_idx_file(
 
                index_entry->offset = be64toh(file_index->offset);
                if (i != 0 && index_entry->offset < (index_entry - 1)->offset) {
-                       BT_LOGW("Invalid, non-monotonic, packet offset encountered in index file");
+                       BT_LOGW("Invalid, non-monotonic, packet offset encountered in LTTng trace index file: "
+                               "previous offset=%" PRIu64 ", current offset=%" PRIu64,
+                               (index_entry - 1)->offset, index_entry->offset);
                        goto error;
                }
 
                index_entry->timestamp_begin = be64toh(file_index->timestamp_begin);
                index_entry->timestamp_end = be64toh(file_index->timestamp_end);
                if (index_entry->timestamp_end < index_entry->timestamp_begin) {
-                       BT_LOGW("Invalid packet time bounds encountered in index file");
+                       BT_LOGW("Invalid packet time bounds encountered in LTTng trace index file (begin > end): "
+                               "timestamp_begin=%" PRIu64 "timestamp_end=%" PRIu64,
+                               index_entry->timestamp_begin,
+                               index_entry->timestamp_end);
                        goto error;
                }
 
@@ -460,12 +482,14 @@ struct ctf_fs_ds_index *build_index_from_idx_file(
                                index_entry->timestamp_begin,
                                &index_entry->timestamp_begin_ns);
                if (ret) {
+                       BT_LOGD("Failed to convert raw timestamp to nanoseconds since Epoch during index parsing");
                        goto error;
                }
                ret = convert_cycles_to_ns(timestamp_end_cc,
                                index_entry->timestamp_end,
                                &index_entry->timestamp_end_ns);
                if (ret) {
+                       BT_LOGD("Failed to convert raw timestamp to nanoseconds since Epoch during LTTng trace index parsing");
                        goto error;
                }
 
@@ -476,7 +500,9 @@ struct ctf_fs_ds_index *build_index_from_idx_file(
 
        /* Validate that the index addresses the complete stream. */
        if (ds_file->file->size != total_packets_size) {
-               BT_LOGW("Invalid index; indexed size != stream file size");
+               BT_LOGW("Invalid LTTng trace index file; indexed size != stream file size: "
+                       "file_size=%" PRIu64 ", total_packets_size=%" PRIu64,
+                       ds_file->file->size, total_packets_size);
                goto error;
        }
 end:
@@ -501,6 +527,7 @@ error:
 BT_HIDDEN
 struct ctf_fs_ds_file *ctf_fs_ds_file_create(
                struct ctf_fs_trace *ctf_fs_trace,
+               struct bt_ctf_notif_iter *notif_iter,
                struct bt_ctf_stream *stream, const char *path)
 {
        int ret;
@@ -524,8 +551,8 @@ struct ctf_fs_ds_file *ctf_fs_ds_file_create(
                goto error;
        }
 
-       ds_file->notif_iter = bt_ctf_notif_iter_create(
-               ctf_fs_trace->metadata->trace, page_size, medops, ds_file);
+       ds_file->notif_iter = notif_iter;
+       bt_ctf_notif_iter_set_medops_data(ds_file->notif_iter, ds_file);
        if (!ds_file->notif_iter) {
                goto error;
        }
@@ -565,10 +592,6 @@ void ctf_fs_ds_file_destroy(struct ctf_fs_ds_file *ds_file)
                ctf_fs_file_destroy(ds_file->file);
        }
 
-       if (ds_file->notif_iter) {
-               bt_ctf_notif_iter_destroy(ds_file->notif_iter);
-       }
-
        g_free(ds_file);
 }
 
This page took 0.027372 seconds and 4 git commands to generate.