journalfile.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #ifndef NETDATA_JOURNALFILE_H
  3. #define NETDATA_JOURNALFILE_H
  4. #include "rrdengine.h"
  5. /* Forward declarations */
  6. struct rrdengine_instance;
  7. struct rrdengine_worker_config;
  8. struct rrdengine_datafile;
  9. struct rrdengine_journalfile;
  10. #define WALFILE_PREFIX "journalfile-"
  11. #define WALFILE_EXTENSION ".njf"
  12. #define WALFILE_EXTENSION_V2 ".njfv2"
  13. #define is_descr_journal_v2(descr) ((descr)->extent_entry != NULL)
  14. typedef enum __attribute__ ((__packed__)) {
  15. JOURNALFILE_FLAG_IS_AVAILABLE = (1 << 0),
  16. JOURNALFILE_FLAG_IS_MOUNTED = (1 << 1),
  17. JOURNALFILE_FLAG_MOUNTED_FOR_RETENTION = (1 << 2),
  18. JOURNALFILE_FLAG_METRIC_CRC_CHECK = (1 << 3),
  19. } JOURNALFILE_FLAGS;
  20. /* only one event loop is supported for now */
  21. struct rrdengine_journalfile {
  22. struct {
  23. SPINLOCK spinlock;
  24. void *data; // MMAPed file of journal v2
  25. uint32_t size; // Total file size mapped
  26. int fd;
  27. } mmap;
  28. struct {
  29. SPINLOCK spinlock;
  30. JOURNALFILE_FLAGS flags;
  31. int32_t refcount;
  32. time_t first_time_s;
  33. time_t last_time_s;
  34. time_t not_needed_since_s;
  35. uint32_t size_of_directory;
  36. } v2;
  37. struct {
  38. Word_t indexed_as;
  39. } njfv2idx;
  40. struct {
  41. SPINLOCK spinlock;
  42. uint64_t pos;
  43. } unsafe;
  44. uv_file file;
  45. struct rrdengine_datafile *datafile;
  46. };
  47. static inline uint64_t journalfile_current_size(struct rrdengine_journalfile *journalfile) {
  48. spinlock_lock(&journalfile->unsafe.spinlock);
  49. uint64_t size = journalfile->unsafe.pos;
  50. spinlock_unlock(&journalfile->unsafe.spinlock);
  51. return size;
  52. }
  53. // Journal v2 structures
  54. #define JOURVAL_V2_MAGIC (0x01230317)
  55. #define JOURVAL_V2_REBUILD_MAGIC (0x00230317)
  56. #define JOURVAL_V2_SKIP_MAGIC (0x02230317)
  57. struct journal_v2_block_trailer {
  58. union {
  59. uint8_t checksum[CHECKSUM_SZ]; /* CRC32 */
  60. uint32_t crc;
  61. };
  62. };
  63. // Journal V2
  64. // 28 bytes
  65. struct journal_page_header {
  66. union {
  67. uint8_t checksum[CHECKSUM_SZ]; // CRC check
  68. uint32_t crc;
  69. };
  70. uint32_t uuid_offset; // Points back to the UUID list which should point here (UUIDs should much)
  71. uint32_t entries; // Entries
  72. uuid_t uuid; // Which UUID this is
  73. };
  74. // 20 bytes
  75. struct journal_page_list {
  76. uint32_t delta_start_s; // relative to the start time of journal
  77. uint32_t delta_end_s; // relative to delta_start
  78. uint32_t extent_index; // Index to the extent (extent list) (bytes from BASE)
  79. uint32_t update_every_s;
  80. uint16_t page_length;
  81. uint8_t type;
  82. };
  83. // UUID_LIST
  84. // 36 bytes
  85. struct journal_metric_list {
  86. uuid_t uuid;
  87. uint32_t entries; // Number of entries
  88. uint32_t page_offset; // OFFSET that contains entries * struct( journal_page_list )
  89. uint32_t delta_start_s; // Min time of metric
  90. uint32_t delta_end_s; // Max time of metric (to be used to populate page_index)
  91. uint32_t update_every_s; // Last update every for this metric in this journal (last page collected)
  92. };
  93. // 16 bytes
  94. struct journal_extent_list {
  95. uint64_t datafile_offset; // Datafile offset to find the extent
  96. uint32_t datafile_size; // Size of the extent
  97. uint16_t file_index; // which file index is this datafile[index]
  98. uint8_t pages; // number of pages (not all are necesssarily valid)
  99. };
  100. // 72 bytes
  101. struct journal_v2_header {
  102. uint32_t magic;
  103. usec_t start_time_ut; // Min start time of journal
  104. usec_t end_time_ut; // Maximum end time of journal
  105. uint32_t extent_count; // Count of extents
  106. uint32_t extent_offset;
  107. uint32_t metric_count; // Count of metrics (unique UUIDS)
  108. uint32_t metric_offset;
  109. uint32_t page_count; // Total count of pages (descriptors @ time)
  110. uint32_t page_offset;
  111. uint32_t extent_trailer_offset; // CRC for entent list
  112. uint32_t metric_trailer_offset; // CRC for metric list
  113. uint32_t journal_v1_file_size; // This is the original journal file
  114. uint32_t journal_v2_file_size; // This is the total file size
  115. void *data; // Used when building the index
  116. };
  117. #define JOURNAL_V2_HEADER_PADDING_SZ (RRDENG_BLOCK_SIZE - (sizeof(struct journal_v2_header)))
  118. struct wal;
  119. void journalfile_v1_generate_path(struct rrdengine_datafile *datafile, char *str, size_t maxlen);
  120. void journalfile_v2_generate_path(struct rrdengine_datafile *datafile, char *str, size_t maxlen);
  121. struct rrdengine_journalfile *journalfile_alloc_and_init(struct rrdengine_datafile *datafile);
  122. void journalfile_v1_extent_write(struct rrdengine_instance *ctx, struct rrdengine_datafile *datafile, struct wal *wal, uv_loop_t *loop);
  123. int journalfile_close(struct rrdengine_journalfile *journalfile, struct rrdengine_datafile *datafile);
  124. int journalfile_unlink(struct rrdengine_journalfile *journalfile);
  125. int journalfile_destroy_unsafe(struct rrdengine_journalfile *journalfile, struct rrdengine_datafile *datafile);
  126. int journalfile_create(struct rrdengine_journalfile *journalfile, struct rrdengine_datafile *datafile);
  127. int journalfile_load(struct rrdengine_instance *ctx, struct rrdengine_journalfile *journalfile,
  128. struct rrdengine_datafile *datafile);
  129. void journalfile_v2_populate_retention_to_mrg(struct rrdengine_instance *ctx, struct rrdengine_journalfile *journalfile);
  130. void journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno __maybe_unused, uint8_t type __maybe_unused,
  131. Pvoid_t JudyL_metrics, Pvoid_t JudyL_extents_pos,
  132. size_t number_of_extents, size_t number_of_metrics, size_t number_of_pages, void *user_data);
  133. bool journalfile_v2_data_available(struct rrdengine_journalfile *journalfile);
  134. size_t journalfile_v2_data_size_get(struct rrdengine_journalfile *journalfile);
  135. void journalfile_v2_data_set(struct rrdengine_journalfile *journalfile, int fd, void *journal_data, uint32_t journal_data_size);
  136. struct journal_v2_header *journalfile_v2_data_acquire(struct rrdengine_journalfile *journalfile, size_t *data_size, time_t wanted_first_time_s, time_t wanted_last_time_s);
  137. void journalfile_v2_data_release(struct rrdengine_journalfile *journalfile);
  138. void journalfile_v2_data_unmount_cleanup(time_t now_s);
  139. typedef struct {
  140. bool init;
  141. Word_t last;
  142. time_t wanted_start_time_s;
  143. time_t wanted_end_time_s;
  144. struct rrdengine_instance *ctx;
  145. struct journal_v2_header *j2_header_acquired;
  146. } NJFV2IDX_FIND_STATE;
  147. struct rrdengine_datafile *njfv2idx_find_and_acquire_j2_header(NJFV2IDX_FIND_STATE *s);
  148. #endif /* NETDATA_JOURNALFILE_H */