summaryrefslogtreecommitdiff
path: root/posts/brck.md
blob: 04160a9bb12b6eff32097de9fbeb15171453edb1 (plain)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
---
title: "Brck"
description: "A simple bit rot checker for legacy file systems."
published: 2024-03-24
---

I've just released [Brck][brck-repo], a simple bit rot checker for legacy file
systems. It records and compares the modification times and cryptographic hash
sums of regular files. When a file's hash changed but it's modification time
did not, then Brck reports the file as corrupted so you have a chance to
restore the file from backup. You do have backups, right? 😉

You can find the source code [here][brck-repo]. What follows is an excerpt from
the README.

## Installation

Brck is available on [crates.io][brck-cratesio]. You can install it using
Rust's package manager [Cargo][cargo].

    $ cargo install brck

## Usage

Without any options, Brck will record all regular files in current working
directory recursively and write those records to a gzipped `.brck` file.

    $ brck

When you run the same command again, Brck will compare the recorded files
against the current file system and report any corrupted files.

    $ brck
    corrupted: ./test_file
    Error: Found 1 denied difference

Brck is quiet by default. Increase the verbosity using `-v` or request a
summary using `-s`. Alternatively, enable the JSON output using `-J` and
perform your own post-processing, e.g., using [jq][]:

    $ brck -vvJ | jq -sr 'group_by(.type)[] | [.[0].type, length] | @tsv' 2>/dev/null
    added   4
    corrupted       1
    unchanged       1219

See the built-in help for all supported options:

    $ brck --help

## Features

- Parallel sequential processing: Brck processes files in parallel, yet outputs
  and records files in-order

- One-pass: Brck reads your files only once

- Constant memory: Brck's memory footprint is independent of the number of
  processed files

- Relative paths: Brck records relative paths such that you can move the
  containing directory around

- Quiet by default: Without any options, Brck prints denied differences to
  standard output, and errors to standard error; nothing else

- Human readable or machine readable, newline-delimited JSON output, at your
  option

- Graceful shutdown on the first interrupt signal, forceful immediate shutdown
  on the second

- [Pledged][pledge] and [unveiled][unveil] on OpenBSD

## Limitations

- Brck doesn't follow symlinks.

- Brck doesn't track hardlinks. Performance will be suboptimal in the presence
  of large hardlinked files because Brck hashes each copy individually.

- Brck doesn't track reflinks. Modern copy-on-write file systems are out of
  scope because they should check file content integrity themselves, like
  OpenZFS and Btrfs do.

- Brck may leak file meta data because its `.brck` file may have different
  permissions than the listed files.

- Brck doesn't respect platform-specific temporary directories such as `TMPDIR`
  on UNIX. Instead, it creates its temporary files in the current working
  directory, next to the `.brck` file. This way, Brck can update the files
  atomically on POSIX-conform systems.

- Brck may fail to remove its temporary files, e.g., in the event of a
  segfault.

## See also

- Definition of *bit rot* in the [Jargon File][jargon]
  ([archive][jargon-archive])

- A similar Python program named [Bitrot][python-bitrot]

- A similar Rust program named [Legdur][legdur-cratesio]

- A blog post on [Things UNIX can do atomically][rcrowley]

[brck-repo]: https://git.skreutz.com/brck.git/
[brck-cratesio]: https://crates.io/crates/brck
[cargo]: https://doc.rust-lang.org/cargo/
[jq]: https://jqlang.org/
[pledge]: https://man.openbsd.org/pledge
[unveil]: https://man.openbsd.org/unveil
[jargon]: http://www.catb.org/jargon/html/B/bit-rot.html
[jargon-archive]: https://web.archive.org/web/20240312124910/http://www.catb.org/jargon/html/B/bit-rot.html
[legdur-cratesio]: https://crates.io/crates/legdur
[python-bitrot]: https://github.com/ambv/bitrot/
[rcrowley]: https://web.archive.org/web/20160304224616/http://rcrowley.org/2010/01/06/things-unix-can-do-atomically
Generated by cgit. See skreutz.com for my tech blog and contact information.