From: Junio C Hamano <gitster@pobox.com>
To: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, me@ttaylorr.com,
Derrick Stolee <derrickstolee@github.com>
Subject: Re: [PATCH 1/2] fsck: verify checksums of all .bitmap files
Date: Mon, 01 May 2023 12:07:39 -0700 [thread overview]
Message-ID: <xmqqv8hb50qs.fsf@gitster.g> (raw)
In-Reply-To: <d608d2faa8602df6a52117c8c57c0ca8e43beb4f.1682965295.git.gitgitgadget@gmail.com> (Derrick Stolee via GitGitGadget's message of "Mon, 01 May 2023 18:21:34 +0000")
"Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com> writes:
> +static int verify_bitmap_file(const char *name)
> +{
> + struct stat st;
> + unsigned char *data;
> + int fd = git_open(name);
> + int res = 0;
> +
> + /* A non-existent file is valid. */
> + if (fstat(fd, &st)) {
> + close(fd);
> + return 0;
> + }
git_open() may return a negative value to signal an error, and
fstat() would return negative to signal its own error, and feeding
the negative fd to close() would also be an error without molesting
other open file descriptors we would want to keep, and we do not
check the return value from close(), so all of the above may be
safe, but makes us feel a bit dirty.
/* It is OK not to have the file */
if (fd < 0 || fstat(fd, &st)) {
if (0 <= fd)
close(fd);
return 0;
}
is probably not overly too verbose and makes the result a bit more
palatable, perhaps.
> + data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
> + close(fd);
> + if (!hashfile_checksum_valid(data, st.st_size))
> + res = error(_("bitmap file '%s' has invalid checksum"),
> + name);
> +
> + munmap(data, st.st_size);
> + return res;
> +}
OK.
> +int verify_bitmap_files(struct repository *r)
> +{
> + int res = 0;
> +
> + for (struct multi_pack_index *m = get_multi_pack_index(r);
> + m; m = m->next) {
> + char *midx_bitmap_name = midx_bitmap_filename(m);
> + res |= verify_bitmap_file(midx_bitmap_name);
> + free(midx_bitmap_name);
> + }
> +
> + for (struct packed_git *p = get_all_packs(r);
> + p; p = p->next) {
> + char *pack_bitmap_name = pack_bitmap_filename(p);
> + res |= verify_bitmap_file(pack_bitmap_name);
> + free(pack_bitmap_name);
> + }
> +
> + return res;
> +}
OK.
> diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh
> index 0882cbb6e4a..d7353d8d443 100755
> --- a/t/t5326-multi-pack-bitmaps.sh
> +++ b/t/t5326-multi-pack-bitmaps.sh
> @@ -434,4 +434,42 @@ test_expect_success 'tagged commits are selected for bitmapping' '
> )
> '
>
> +corrupt_file () {
> + chmod a+w "$1" &&
> + printf "bogus" | dd of="$1" bs=1 seek="12" conv=notrunc
> +}
> +
> +test_expect_success 'git fsck correctly identifies good and bad bitmaps' '
> + git init valid &&
> + test_when_finished rm -rf valid &&
> +
> + test_commit_bulk 20 &&
> + git repack -adbf &&
> +
> + # Move pack-bitmap aside so it is not deleted
> + # in next repack.
> + packbitmap=$(ls .git/objects/pack/pack-*.bitmap) &&
> + mv "$packbitmap" "$packbitmap.bak" &&
> +
> + test_commit_bulk 10 &&
> + git repack -b --write-midx &&
> + midxbitmap=$(ls .git/objects/pack/multi-pack-index-*.bitmap) &&
> +
> + # Copy MIDX bitmap to backup. Copy pack bitmap from backup.
> + cp "$midxbitmap" "$midxbitmap.bak" &&
> + cp "$packbitmap.bak" "$packbitmap" &&
So, at this point, we have only one pack, and we could enable the
midx bitmap and/or pack bitmap from their .bak. We first enable
only the pack bitmap while leaving midx bitmap disabled.
> + # fsck works at first
> + git fsck &&
OK.
> + corrupt_file "$packbitmap" &&
> + test_must_fail git fsck 2>err &&
> + grep "bitmap file '\''$packbitmap'\'' has invalid checksum" err &&
And when the only thing enabled, i.e. pack bitmap, is broken, we
notice the breakage. OK.
> + cp "$packbitmap.bak" "$packbitmap" &&
> + corrupt_file "$midxbitmap" &&
Now we repair the pack bitmap and break midx bitmap. Both are
enabled in this case.
> + test_must_fail git fsck 2>err &&
> + grep "bitmap file '\''$midxbitmap'\'' has invalid checksum" err
And we notice midx bitmap is corrupt.
Is it worth checking at this point if we detect breakages in both
bitmaps, if we have pack bitmap and midx bitmap, both broken?
Other than these tiny nits, looking very good.
Thanks.
next prev parent reply other threads:[~2023-05-01 19:07 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-01 18:21 [PATCH 0/2] fsck: verify .bitmap checksums, cleanup Derrick Stolee via GitGitGadget
2023-05-01 18:21 ` [PATCH 1/2] fsck: verify checksums of all .bitmap files Derrick Stolee via GitGitGadget
2023-05-01 19:07 ` Junio C Hamano [this message]
2023-05-01 18:21 ` [PATCH 2/2] fsck: use local repository Derrick Stolee via GitGitGadget
2023-05-01 19:10 ` Junio C Hamano
2023-05-02 13:27 ` [PATCH v2 0/2] fsck: verify .bitmap checksums, cleanup Derrick Stolee via GitGitGadget
2023-05-02 13:27 ` [PATCH v2 1/2] fsck: verify checksums of all .bitmap files Derrick Stolee via GitGitGadget
2023-05-02 13:27 ` [PATCH v2 2/2] fsck: use local repository Derrick Stolee via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqv8hb50qs.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=derrickstolee@github.com \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
--cc=me@ttaylorr.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).