Skip to content

Add POSIX mirror lifecycle outline & witness support#989

Merged
AlCutter merged 2 commits into
transparency-dev:mainfrom
AlCutter:posix_mirror_outline_witness
Jun 24, 2026
Merged

Add POSIX mirror lifecycle outline & witness support#989
AlCutter merged 2 commits into
transparency-dev:mainfrom
AlCutter:posix_mirror_outline_witness

Conversation

@AlCutter

@AlCutter AlCutter commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

This PR adds an skeleton POSIX storage implementation for the mirror lifecycle, and connects it up to the POSIX mirror binary.

Towards #945

@AlCutter AlCutter requested a review from roger2hk June 8, 2026 13:48
@AlCutter AlCutter force-pushed the posix_mirror_outline_witness branch from ebdf08d to 34b51b2 Compare June 8, 2026 17:34
@AlCutter AlCutter force-pushed the posix_mirror_outline_witness branch 2 times, most recently from d5fe3cf to 96f5aab Compare June 19, 2026 16:17
@AlCutter AlCutter force-pushed the posix_mirror_outline_witness branch from 96f5aab to dd9d61a Compare June 23, 2026 10:43
@AlCutter AlCutter marked this pull request as ready for review June 23, 2026 10:48
@AlCutter AlCutter requested a review from a team as a code owner June 23, 2026 10:48
Comment thread storage/posix/files.go Outdated
// Oh dear, panic Mr Mainwaring!
panic(fmt.Errorf("failed to unlock tree state: %v", err))
}
m.s.mu.Unlock()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a chance of mutex deadlock. The mutex unlock will not trigger when the err is not nil on L1151.

Defer the mutex unlock immediately after m.s.mu.Lock().

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

I've done two things:

  1. changed all "double lock" locations to defer the unlocks separately (because that's a more correct pattern)
  2. changed this location to panic() on failure to lock to match all the others - this also "fixes" the deadlock issue, but makes behaviour consistent across lifecycles (we can later decide if we want to modify the behaviour).

Comment thread cmd/mtc/mirror/posix/main.go Outdated
r, err := os.ReadFile(path)
if err != nil {
slog.ErrorContext(ctx, "Failed to read witness cosigner file", slog.String("path", *witnessSignerPath), slog.Any("error", err))
slog.ErrorContext(ctx, "Failed to read cosigner file", slog.String("path", path), slog.Any("error", err))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too familiar with the terminology. Should we say signer instead of cosigner in the error log in this function?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit dependent on context, sadly - these are cosigners from the PoV of tlog-* and MTC spec PoV, and the type of key these are expected to be are Cosignature/v1, but from the note library PoV they're note.Signers.

I've renamed anything to do with them as ...Cosigner... in this file for consistency, as the operator is more likely to be familiar with.

Comment thread cmd/mtc/mirror/posix/main.go Outdated
// with the `tlog-mirror` spec, allowing the root of the storage directory to be exported directly to read-only clients.
func newMirrorTarget(ctx context.Context, w *witness.Witness, origin string, mirrorSigner note.Signer) (*tessera.MirrorTarget, error) {
targetDir := filepath.Join(*storageDir, url.PathEscape(origin))
if err := os.MkdirAll(targetDir, 0o700); err != nil && !errors.Is(err, os.ErrExist) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be safe to remove !errors.Is(err, os.ErrExist) as no error will be returned if the directory is already created.

If path is already a directory, MkdirAll does nothing and returns nil.

https://pkg.go.dev/os#MkdirAll

Comment thread cmd/mtc/mirror/posix/main.go Outdated
// with the `tlog-mirror` spec, allowing the root of the storage directory to be exported directly to read-only clients.
func newMirrorTarget(ctx context.Context, w *witness.Witness, origin string, mirrorSigner note.Signer) (*tessera.MirrorTarget, error) {
targetDir := filepath.Join(*storageDir, url.PathEscape(origin))
if err := os.MkdirAll(targetDir, 0o700); err != nil && !errors.Is(err, os.ErrExist) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0o700 seems to be contradicted to the godoc comment "allowing the root of the storage directory to be exported directly to read-only clients".

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

==> 0o755

@AlCutter AlCutter merged commit 20980b0 into transparency-dev:main Jun 24, 2026
20 checks passed
@AlCutter AlCutter deleted the posix_mirror_outline_witness branch June 24, 2026 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants