static int trace_dump_metadata(struct trace_dumper_configuration_s *conf, struct trace_record_file *record_file, struct trace_mapped_buffer *mapped_buffer) { int rc = open_trace_file_if_necessary(conf); if (0 != rc) { return rc; } if (trace_dumper_wait_record_file_async_io_completion(record_file, TRACE_FOREVER) < 0) { const size_t n_bytes = record_file->async_writes->aio_nbytes; const off64_t offset = record_file->async_writes->aio_offset; if (trace_dumper_async_timed_out()) { DEBUG("Metadata dumping deferred due to", n_bytes, "previous data pending async write at ", offset, "for the file", record_file->filename, strerror(errno)); } else { ERR("Delayed write of ", n_bytes, "failed at", offset, "with err", errno, strerror(errno)); } return -1; } if (trace_dumper_net_num_records_pending(record_file) > 0) { DEBUG("Metadata dumping deferred because the internal buffer is not fully flushed for the file", record_file->filename); errno = EAGAIN; return -1; } mapped_buffer->metadata.metadata_payload_record.ts = trace_get_nsec(); /* TODO: write a validator for metadata. */ record_file->post_write_validator = NULL; /* TODO: Introduce rollback logic, like we have for regular data writes */ rc = write_metadata_header_start(conf, record_file, mapped_buffer); if (0 != rc) { return -1; } if (mapped_buffer->metadata.metadata_iovec_len > 0) { TRACE_ASSERT(NULL != mapped_buffer->metadata.metadata_iovec); rc = trace_dumper_write(conf, record_file, mapped_buffer->metadata.metadata_iovec, mapped_buffer->metadata.metadata_iovec_len); if ((size_t) rc != (mapped_buffer->metadata.metadata_iovec_len / 2) * sizeof(struct trace_record)) { if (0 == errno) { errno = EIO; } return -1; } } else { syslog(LOG_USER|LOG_WARNING, "Trace dumper could not dump metadata for the process %s (pid %u) because it has length 0", mapped_buffer->name, mapped_buffer->pid); } return write_metadata_end(conf, record_file, mapped_buffer); }
static int trace_dump_metadata(struct trace_dumper_configuration_s *conf, struct trace_mapped_buffer *mapped_buffer) { struct trace_record rec; unsigned int num_records; int rc; mapped_buffer->metadata.metadata_payload_record.ts = trace_get_nsec(); memset(&rec, 0, sizeof(rec)); rc = write_metadata_header_start(conf, mapped_buffer); if (0 != rc) { return -1; } num_records = mapped_buffer->metadata.size / (TRACE_RECORD_PAYLOAD_SIZE) + ((mapped_buffer->metadata.size % (TRACE_RECORD_PAYLOAD_SIZE)) ? 1 : 0); rc = trace_dumper_write(conf, &conf->record_file, mapped_buffer->metadata.metadata_iovec, 2 * num_records); if ((unsigned int) rc != num_records * sizeof(struct trace_record)) { return -1; } rc = write_metadata_end(conf, mapped_buffer); return rc; }