LCOV - code coverage report
Current view: top level - journal - journal-file.h (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 7 10 70.0 %
Date: 2019-08-22 15:41:25 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : #pragma once
       3             : 
       4             : #include <inttypes.h>
       5             : #include <sys/uio.h>
       6             : 
       7             : #if HAVE_GCRYPT
       8             : #  include <gcrypt.h>
       9             : #endif
      10             : 
      11             : #include "sd-event.h"
      12             : #include "sd-id128.h"
      13             : 
      14             : #include "hashmap.h"
      15             : #include "journal-def.h"
      16             : #include "mmap-cache.h"
      17             : #include "sparse-endian.h"
      18             : #include "time-util.h"
      19             : 
      20             : typedef struct JournalMetrics {
      21             :         /* For all these: -1 means "pick automatically", and 0 means "no limit enforced" */
      22             :         uint64_t max_size;     /* how large journal files grow at max */
      23             :         uint64_t min_size;     /* how large journal files grow at least */
      24             :         uint64_t max_use;      /* how much disk space to use in total at max, keep_free permitting */
      25             :         uint64_t min_use;      /* how much disk space to use in total at least, even if keep_free says not to */
      26             :         uint64_t keep_free;    /* how much to keep free on disk */
      27             :         uint64_t n_max_files;  /* how many files to keep around at max */
      28             : } JournalMetrics;
      29             : 
      30             : typedef enum direction {
      31             :         DIRECTION_UP,
      32             :         DIRECTION_DOWN
      33             : } direction_t;
      34             : 
      35             : typedef enum LocationType {
      36             :         /* The first and last entries, resp. */
      37             :         LOCATION_HEAD,
      38             :         LOCATION_TAIL,
      39             : 
      40             :         /* We already read the entry we currently point to, and the
      41             :          * next one to read should probably not be this one again. */
      42             :         LOCATION_DISCRETE,
      43             : 
      44             :         /* We should seek to the precise location specified, and
      45             :          * return it, as we haven't read it yet. */
      46             :         LOCATION_SEEK
      47             : } LocationType;
      48             : 
      49             : typedef enum OfflineState {
      50             :         OFFLINE_JOINED,
      51             :         OFFLINE_SYNCING,
      52             :         OFFLINE_OFFLINING,
      53             :         OFFLINE_CANCEL,
      54             :         OFFLINE_AGAIN_FROM_SYNCING,
      55             :         OFFLINE_AGAIN_FROM_OFFLINING,
      56             :         OFFLINE_DONE
      57             : } OfflineState;
      58             : 
      59             : typedef struct JournalFile {
      60             :         int fd;
      61             :         MMapFileDescriptor *cache_fd;
      62             : 
      63             :         mode_t mode;
      64             : 
      65             :         int flags;
      66             :         int prot;
      67             :         bool writable:1;
      68             :         bool compress_xz:1;
      69             :         bool compress_lz4:1;
      70             :         bool seal:1;
      71             :         bool defrag_on_close:1;
      72             :         bool close_fd:1;
      73             :         bool archive:1;
      74             : 
      75             :         direction_t last_direction;
      76             :         LocationType location_type;
      77             :         uint64_t last_n_entries;
      78             : 
      79             :         char *path;
      80             :         struct stat last_stat;
      81             :         usec_t last_stat_usec;
      82             : 
      83             :         Header *header;
      84             :         HashItem *data_hash_table;
      85             :         HashItem *field_hash_table;
      86             : 
      87             :         uint64_t current_offset;
      88             :         uint64_t current_seqnum;
      89             :         uint64_t current_realtime;
      90             :         uint64_t current_monotonic;
      91             :         sd_id128_t current_boot_id;
      92             :         uint64_t current_xor_hash;
      93             : 
      94             :         JournalMetrics metrics;
      95             :         MMapCache *mmap;
      96             : 
      97             :         sd_event_source *post_change_timer;
      98             :         usec_t post_change_timer_period;
      99             : 
     100             :         OrderedHashmap *chain_cache;
     101             : 
     102             :         pthread_t offline_thread;
     103             :         volatile OfflineState offline_state;
     104             : 
     105             :         unsigned last_seen_generation;
     106             : 
     107             :         uint64_t compress_threshold_bytes;
     108             : #if HAVE_XZ || HAVE_LZ4
     109             :         void *compress_buffer;
     110             :         size_t compress_buffer_size;
     111             : #endif
     112             : 
     113             : #if HAVE_GCRYPT
     114             :         gcry_md_hd_t hmac;
     115             :         bool hmac_running;
     116             : 
     117             :         FSSHeader *fss_file;
     118             :         size_t fss_file_size;
     119             : 
     120             :         uint64_t fss_start_usec;
     121             :         uint64_t fss_interval_usec;
     122             : 
     123             :         void *fsprg_state;
     124             :         size_t fsprg_state_size;
     125             : 
     126             :         void *fsprg_seed;
     127             :         size_t fsprg_seed_size;
     128             : #endif
     129             : } JournalFile;
     130             : 
     131             : int journal_file_open(
     132             :                 int fd,
     133             :                 const char *fname,
     134             :                 int flags,
     135             :                 mode_t mode,
     136             :                 bool compress,
     137             :                 uint64_t compress_threshold_bytes,
     138             :                 bool seal,
     139             :                 JournalMetrics *metrics,
     140             :                 MMapCache *mmap_cache,
     141             :                 Set *deferred_closes,
     142             :                 JournalFile *template,
     143             :                 JournalFile **ret);
     144             : 
     145             : int journal_file_set_offline(JournalFile *f, bool wait);
     146             : bool journal_file_is_offlining(JournalFile *f);
     147             : JournalFile* journal_file_close(JournalFile *j);
     148           0 : DEFINE_TRIVIAL_CLEANUP_FUNC(JournalFile*, journal_file_close);
     149             : 
     150             : int journal_file_open_reliably(
     151             :                 const char *fname,
     152             :                 int flags,
     153             :                 mode_t mode,
     154             :                 bool compress,
     155             :                 uint64_t compress_threshold_bytes,
     156             :                 bool seal,
     157             :                 JournalMetrics *metrics,
     158             :                 MMapCache *mmap_cache,
     159             :                 Set *deferred_closes,
     160             :                 JournalFile *template,
     161             :                 JournalFile **ret);
     162             : 
     163             : #define ALIGN64(x) (((x) + 7ULL) & ~7ULL)
     164             : #define VALID64(x) (((x) & 7ULL) == 0ULL)
     165             : 
     166             : /* Use six characters to cover the offsets common in smallish journal
     167             :  * files without adding too many zeros. */
     168             : #define OFSfmt "%06"PRIx64
     169             : 
     170      322962 : static inline bool VALID_REALTIME(uint64_t u) {
     171             :         /* This considers timestamps until the year 3112 valid. That should be plenty room... */
     172      322962 :         return u > 0 && u < (1ULL << 55);
     173             : }
     174             : 
     175      322962 : static inline bool VALID_MONOTONIC(uint64_t u) {
     176             :         /* This considers timestamps until 1142 years of runtime valid. */
     177      322962 :         return u < (1ULL << 55);
     178             : }
     179             : 
     180           0 : static inline bool VALID_EPOCH(uint64_t u) {
     181             :         /* This allows changing the key for 1142 years, every usec. */
     182           0 :         return u < (1ULL << 55);
     183             : }
     184             : 
     185             : #define JOURNAL_HEADER_CONTAINS(h, field) \
     186             :         (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field))
     187             : 
     188             : #define JOURNAL_HEADER_SEALED(h) \
     189             :         (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED))
     190             : 
     191             : #define JOURNAL_HEADER_COMPRESSED_XZ(h) \
     192             :         (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_XZ))
     193             : 
     194             : #define JOURNAL_HEADER_COMPRESSED_LZ4(h) \
     195             :         (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_LZ4))
     196             : 
     197             : int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret);
     198             : 
     199             : uint64_t journal_file_entry_n_items(Object *o) _pure_;
     200             : uint64_t journal_file_entry_array_n_items(Object *o) _pure_;
     201             : uint64_t journal_file_hash_table_n_items(Object *o) _pure_;
     202             : 
     203             : int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, Object **ret, uint64_t *offset);
     204             : int journal_file_append_entry(
     205             :                 JournalFile *f,
     206             :                 const dual_timestamp *ts,
     207             :                 const sd_id128_t *boot_id,
     208             :                 const struct iovec iovec[], unsigned n_iovec,
     209             :                 uint64_t *seqno,
     210             :                 Object **ret,
     211             :                 uint64_t *offset);
     212             : 
     213             : int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset);
     214             : int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
     215             : 
     216             : int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset);
     217             : int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
     218             : 
     219             : void journal_file_reset_location(JournalFile *f);
     220             : void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset);
     221             : int journal_file_compare_locations(JournalFile *af, JournalFile *bf);
     222             : int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
     223             : 
     224             : int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
     225             : 
     226             : int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
     227             : int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
     228             : int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
     229             : 
     230             : int journal_file_move_to_entry_by_offset_for_data(JournalFile *f, uint64_t data_offset, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
     231             : int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, uint64_t data_offset, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
     232             : int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, uint64_t data_offset, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
     233             : int journal_file_move_to_entry_by_monotonic_for_data(JournalFile *f, uint64_t data_offset, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
     234             : 
     235             : int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p);
     236             : 
     237             : void journal_file_dump(JournalFile *f);
     238             : void journal_file_print_header(JournalFile *f);
     239             : 
     240             : int journal_file_archive(JournalFile *f);
     241             : JournalFile* journal_initiate_close(JournalFile *f, Set *deferred_closes);
     242             : int journal_file_rotate(JournalFile **f, bool compress, uint64_t compress_threshold_bytes, bool seal, Set *deferred_closes);
     243             : 
     244             : int journal_file_dispose(int dir_fd, const char *fname);
     245             : 
     246             : void journal_file_post_change(JournalFile *f);
     247             : int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t);
     248             : 
     249             : void journal_reset_metrics(JournalMetrics *m);
     250             : void journal_default_metrics(JournalMetrics *m, int fd);
     251             : 
     252             : int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to);
     253             : int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to);
     254             : 
     255             : bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec);
     256             : 
     257             : int journal_file_map_data_hash_table(JournalFile *f);
     258             : int journal_file_map_field_hash_table(JournalFile *f);
     259             : 
     260       38056 : static inline bool JOURNAL_FILE_COMPRESS(JournalFile *f) {
     261       38056 :         assert(f);
     262       38056 :         return f->compress_xz || f->compress_lz4;
     263             : }

Generated by: LCOV version 1.14