Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls/internal/lsp/filecache: TestConcurrency consistently failing with does not exist from chtimes on plan9-arm #57845

Closed
bcmills opened this issue Jan 17, 2023 · 9 comments
Assignees
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. OS-Plan9 Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@bcmills
Copy link
Contributor

bcmills commented Jan 17, 2023

https://build.golang.org/log/ffdc690f545f13901130fd7fac932b18896f9a7d:

--- FAIL: TestConcurrency (0.63s)
    filecache_test.go:99: failed to update access time: chtimes /tmp/gopls/28b553f1/TestConcurrency/49/495d62789f200d1955257f8adbc7610ed53f9a4a1b79e57f9ba0a4cc99e51c68: '.../49/495d62789f200d1955257f8adbc7610ed53f9a4a1b79e57f9ba0a4cc99e51c68' does not exist
FAIL
FAIL	golang.org/x/tools/gopls/internal/lsp/filecache	1.049s

@millerresearch, any thoughts on what might be going wrong with the filesystem here?

(CC @golang/plan9, @adonovan, @findleyr)

@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Jan 17, 2023
@gopherbot gopherbot added this to the Unreleased milestone Jan 17, 2023
@bcmills bcmills added OS-Plan9 gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository. arch-arm Issues solely affecting the 32-bit arm architecture. and removed gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository. arch-arm Issues solely affecting the 32-bit arm architecture. labels Jan 17, 2023
@bcmills
Copy link
Contributor Author

bcmills commented Jan 17, 2023

The test seems to also fail with the same failure mode on plan9-amd64-0intro from time to time, but less frequently. 🤔

@bcmills
Copy link
Contributor Author

bcmills commented Jan 17, 2023

This may be similar to #57747 — is os.Rename atomic on Plan 9?

@adonovan
Copy link
Member

adonovan commented Jan 17, 2023

This may be similar to #57747 — is os.Rename atomic on Plan 9?

No, it doesn't look like it. This is rename in GOROOT/src/os/file_plan9.go, and it does Stat and Remove before updating the directory:

	var d syscall.Dir
	d.Null()
	d.Name = newname

	buf := make([]byte, syscall.STATFIXLEN+len(d.Name))
	n, err := d.Marshal(buf[:])
	if err != nil {
		return &LinkError{"rename", oldname, newname, err}
	}

	// If newname already exists and is not a directory, rename replaces it.
	f, err := Stat(dirname + newname)
	if err == nil && !f.IsDir() {
		Remove(dirname + newname)
	}

	if err = syscall.Wstat(oldname, buf[:n]); err != nil { ... }

The locking fix (pending) should fix this too. Care to take a look at that CL? :)

@millerresearch
Copy link
Contributor

is os.Rename atomic on Plan 9?

No, it doesn't look like it. This is rename in GOROOT/src/os/file_plan9.go, and it does Stat and Remove before updating the directory:

Suppose instead it calls Wstat first to rename the file, and only if that fails with "new file already exists", it then does the Remove and goes back to retry the Wstat (repeating until success) ... would that make it acceptably atomic?

@bcmills
Copy link
Contributor Author

bcmills commented Jan 17, 2023

That wouldn't make it as atomic as POSIX, which I think is what the test expects today.

The POSIX invariant is:

If the link named by the new argument exists, […] a link named new shall remain visible to other threads throughout the renaming operation and refer either to the file referred to by new or old before the operation began.

That is: a rename onto an existing path must not cause the path to even temporarily fail to exist (platform bugs like #33041 notwithstanding).

I'll review Alan's file-locking CL, which should hopefully fix both Windows and Plan 9.

@millerresearch
Copy link
Contributor

That is: a rename onto an existing path must not cause the path to even temporarily fail to exist

I don't believe that's compatible with Plan 9 semantics; man 5 wstat says:

it is an error to change the name to that of an existing file

The Posix definition seems to be implicitly dependent on rename manipulating links; whereas Plan 9 is not Posix and has no links (hard or symbolic) - a file has one name, which would be part of the inode if Plan 9 had inodes ...

It would be possible to mimic Posix semantics by serialising rename operations with respect to file operations in other goroutines, but the invariant still wouldn't hold across separate simultaneous go programs.

@millerresearch
Copy link
Contributor

I'll review Alan's file-locking CL, which should hopefully fix both Windows and Plan 9.

Plan 9 doesn't have file locking either. It does implement internal/lockedfile.Open by setting the file's mode to io/fs.ModeExclusive, but that's a bit shaky because it means all subsequent opens of that file are implicitly locking. I've been expecting that to cause problems with go.mod, which is opened sometimes with locking and sometimes without.

@millerresearch
Copy link
Contributor

The test seems to also fail with the same failure mode on plan9-amd64-0intro from time to time, but less frequently.

I believe plan9-arm is the only Plan 9 builder running on a multiprocessor, so the others are less likely to reveal concurrency bugs. @0intro will correct me if that's not right.

@dle8 dle8 added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jan 19, 2023
@adonovan
Copy link
Member

This should be fixed by https://go.dev/cl/461800.

@golang golang locked and limited conversation to collaborators Jan 19, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. OS-Plan9 Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

5 participants