1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! Whole file checksums recorded in the manifest.
//!
//! With a checksum generator factory installed, RocksDB hashes every SST file
//! as it writes it and stores the digest and the generator's name in the
//! manifest alongside the file entry. Everything that claims to verify file
//! checksums reads those manifest entries:
//!
//! * `DB::VerifyFileChecksums` rehashes every live SST and blob file and
//! compares against the manifest.
//! * Backup reuses the recorded digest instead of hashing the source file
//! again, and checks the copy against it.
//! * Ingestion with
//! [`IngestExternalFileOptions::set_verify_file_checksum`](crate::IngestExternalFileOptions::set_verify_file_checksum)
//! checks the digest that came with the incoming file.
//!
//! `file_checksum_gen_factory` defaults to null, and none of that works without
//! it. `VerifyFileChecksums` refuses to run at all and returns
//! `InvalidArgument`, and backup goes back to hashing files itself.
//!
//! Turning the factory on does not backfill. Files already on disk carry no
//! digest, verification skips them one by one without complaining, and they
//! only pick one up when a compaction rewrites them.
//!
//! This is separate from the per block checksum that
//! [`BlockBasedOptions::set_checksum_type`](crate::BlockBasedOptions::set_checksum_type)
//! controls. Block checksums are stored inside the SST and verified on every
//! read, so readers detect block corruption whether or not a file checksum
//! exists. A file checksum covers the whole file in one digest, which is what
//! makes it useful for copying and moving files around, and useless for
//! locating corruption inside one.
//!
//! The generator's name surfaces in this crate as
//! [`LiveFileStorageInfoEntry::file_checksum_func_name`](crate::metadata::LiveFileStorageInfoEntry::file_checksum_func_name).
//! The digest itself is deliberately not exposed: the only C accessor returns it
//! as a NUL-terminated string with no length, and a digest can contain a zero
//! byte, so the value would be silently truncated.
use NonNull;
use crateffi;
/// A factory RocksDB asks for a checksum generator each time it creates an SST
/// file.
///
/// Install one with
/// [`Options::set_file_checksum_gen_factory`](crate::Options::set_file_checksum_gen_factory).
/// The setter copies the underlying `shared_ptr`, so a factory can be installed
/// on any number of `Options` and dropped as soon as the last call returns.
// `rocksdb_file_checksum_gen_factory_t` is a
// `std::shared_ptr<FileChecksumGenFactory>` and nothing else (c.cc:498).
// Destroying the handle only drops that one reference, and the only other
// operation this crate performs on it is the refcount bump in
// `rocksdb_options_set_file_checksum_gen_factory` (c.cc:6067), which is atomic.
// So the handle carries no thread affinity, and concurrent reads through
// `&FileChecksumGenFactory` cannot race.
unsafe
unsafe