Skip to content

Conversation

apostasie
Copy link
Contributor

@apostasie apostasie commented Jun 18, 2025

This is part 3 of internal/FS series.

<!> unlike the previous PRs that were essentially consolidation and enforcing atomic writes, this here is more ambitious, and adds net new features (eg: rollbacks and disaster recovery) - as such, it may be more controversial, so, open to discussion here, as usual <!>

This expands on the previous goal (Atomicity and Durability of WriteFile) by providing a new version of WriteFile that no longer relies on file renames - hence no longer changing inode - making it now 100% compatible with os.WriteFile and usable everywhere (including when files are mounted).

Furthermore, it also focuses on enabling Consistency, by introducing:

  • disaster recovery:
    • if WriteFile fails, the file is immediately reverted to its previous version (or removed if it did not exist prior)
    • if WriteFile is hard interrupted for any reason, the next ReadFile or WriteFile call will first revert it to its original content (or remove it if it did not exist)
  • rollback: on a successful write, WriteFileWithRollback will return a rollback function that can revert changes

rollback should be used in the future to ensure higher-level operations consistency and to facilitate cleanup in case of failures. This should make higher-level operations failures able to revert state / cleanup leftover easier.

I do appreciate this is additional complexity, and some of the code is not trivial.
But then:

  • the complexity is already here in things like container.Create and other places that are manually rollbacking in a baroque / ad-hoc form
  • IMHO this is what it takes to implement higher-level consistent data operations

Finally note that this changeset is purely internal to the filesystem package and does not change anything in the rest of nerdctl codebase.

Let me know your thoughts overall, and if this is desirable or not.

@apostasie apostasie force-pushed the 2025-06-fs-3 branch 2 times, most recently from 1d98065 to f315d4a Compare June 18, 2025 20:29
@apostasie apostasie force-pushed the 2025-06-fs-3 branch 3 times, most recently from 1dd7373 to de499d0 Compare June 19, 2025 17:54
@apostasie apostasie changed the title WIP: internal/filesystem consolidation, part 3 [WIP]: internal/filesystem consolidation, part 3 Jun 19, 2025
@apostasie apostasie changed the title [WIP]: internal/filesystem consolidation, part 3 internal/filesystem consolidation, part 3 (no rename FileWrite, disaster recovery and rollbacks) Jun 19, 2025
@apostasie apostasie changed the title internal/filesystem consolidation, part 3 (no rename FileWrite, disaster recovery and rollbacks) internal/filesystem consolidation, part 3 (no rename WriteFile, disaster recovery and rollbacks) Jun 19, 2025
@apostasie apostasie marked this pull request as ready for review June 19, 2025 18:39
@AkihiroSuda AkihiroSuda added this to the v2.1.3 milestone Jun 20, 2025
@AkihiroSuda AkihiroSuda mentioned this pull request Jun 20, 2025
@AkihiroSuda
Copy link
Member

No merge conflict, but could you rebase just in case


import "github.com/containerd/nerdctl/v2/pkg/internal/filesystem"

func InitFS(path string) error {
Copy link
Member

Choose a reason for hiding this comment

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

Needs a explanation comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

@apostasie
Copy link
Contributor Author

Rebased and comment added.

@AkihiroSuda
Copy link
Member

Comment seems still missing

@apostasie
Copy link
Contributor Author

apostasie commented Jun 20, 2025

Comment seems still missing

My bad. Added it to the call: https://github.com/containerd/nerdctl/pull/4324/files#diff-202c9b24bcda33888c16a71750bd47809ffd474e126bfd2be11857033c0272f0R149

Will add more to the func declaration then.

WriteFile now:
- no longer relies on Rename, hence no longer changing files inodes
- have disaster recovery and rollback

Signed-off-by: apostasie <spam_blackhole@farcloser.world>
@apostasie
Copy link
Contributor Author

CI failures:

  • EL8 rootful: TestSharedNetworkSetup flaky
  • EL8 rootless - newly introduced TestContainerHealthCheckAdvance seems flaky
  • rootful canary timeouting - looks like the runs are taking longer lately, so, maybe we need to adjust timeouts
  • windows failure I have seen on another PR - something fishy going on with windows networking

@apostasie
Copy link
Contributor Author

Comment seems still missing

Added expanded comment to function declaration (along with comment on function call).

Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

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

Thanks

@AkihiroSuda AkihiroSuda merged commit 190a713 into containerd:main Jun 20, 2025
38 checks passed
err := ensureRecovery(fp)
assert.NilError(t, err)

cn, _ := os.ReadFile(fp)
Copy link
Member

Choose a reason for hiding this comment

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

Any reason not to check err?

// Create file
dir := t.TempDir()
fp := filepath.Join(dir, "pre-existing-file")
_ = os.WriteFile(fp, []byte("original content"), 0o600)
Copy link
Member

Choose a reason for hiding this comment

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

Any reason not to check err?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is indeed a bit lazy - though, given the (test) codepath, if this is failing, presumably everything is failing...
I see you merged.
If this is important, I can update in a follow on.

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