Skip to content

Commit 991fd38

Browse files
author
Jay Conrod
committed
cmd/go: don't lock .mod and .sum files for read in overlay
On Plan 9, locking a file requires a chmod call. In general, the go command should not modify files in the overlay, even metadata. With this change, we won't lock these files for reading. The go command already reported errors when attempting to write these files if they were in the overlay, but this change moves those checks to the point of access for clearer error messages. cmd/go/internal/lockedfile no longer imports cmd/go/internal/fsys. Fixes #44700 Change-Id: Ib544459dd6cf56ca0f7a27b3285f045f08040d7e Reviewed-on: https://go-review.googlesource.com/c/go/+/333012 Trust: Jay Conrod <jayconrod@google.com> Run-TryBot: Jay Conrod <jayconrod@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
1 parent 186a3bb commit 991fd38

File tree

6 files changed

+53
-15
lines changed

6 files changed

+53
-15
lines changed

src/cmd/go/internal/lockedfile/lockedfile_filelock.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"io/fs"
1212
"os"
1313

14-
"cmd/go/internal/fsys"
1514
"cmd/go/internal/lockedfile/internal/filelock"
1615
)
1716

@@ -21,7 +20,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
2120
// calls for Linux and Windows anyway, so it's simpler to use that approach
2221
// consistently.
2322

24-
f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm)
23+
f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
2524
if err != nil {
2625
return nil, err
2726
}

src/cmd/go/internal/lockedfile/lockedfile_plan9.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import (
1313
"os"
1414
"strings"
1515
"time"
16-
17-
"cmd/go/internal/fsys"
1816
)
1917

2018
// Opening an exclusive-use file returns an error.
@@ -59,7 +57,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
5957
// If the file was unpacked or created by some other program, it might not
6058
// have the ModeExclusive bit set. Set it before we call OpenFile, so that we
6159
// can be confident that a successful OpenFile implies exclusive use.
62-
if fi, err := fsys.Stat(name); err == nil {
60+
if fi, err := os.Stat(name); err == nil {
6361
if fi.Mode()&fs.ModeExclusive == 0 {
6462
if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil {
6563
return nil, err
@@ -72,7 +70,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
7270
nextSleep := 1 * time.Millisecond
7371
const maxSleep = 500 * time.Millisecond
7472
for {
75-
f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive)
73+
f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive)
7674
if err == nil {
7775
return f, nil
7876
}

src/cmd/go/internal/modfetch/fetch.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
"cmd/go/internal/base"
2424
"cmd/go/internal/cfg"
25+
"cmd/go/internal/fsys"
2526
"cmd/go/internal/lockedfile"
2627
"cmd/go/internal/par"
2728
"cmd/go/internal/robustio"
@@ -416,7 +417,18 @@ func initGoSum() (bool, error) {
416417

417418
goSum.m = make(map[module.Version][]string)
418419
goSum.status = make(map[modSum]modSumStatus)
419-
data, err := lockedfile.Read(GoSumFile)
420+
var (
421+
data []byte
422+
err error
423+
)
424+
if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok {
425+
// Don't lock go.sum if it's part of the overlay.
426+
// On Plan 9, locking requires chmod, and we don't want to modify any file
427+
// in the overlay. See #44700.
428+
data, err = os.ReadFile(actualSumFile)
429+
} else {
430+
data, err = lockedfile.Read(GoSumFile)
431+
}
420432
if err != nil && !os.IsNotExist(err) {
421433
return false, err
422434
}
@@ -716,6 +728,9 @@ Outer:
716728
if cfg.BuildMod == "readonly" {
717729
base.Fatalf("go: updates to go.sum needed, disabled by -mod=readonly")
718730
}
731+
if _, ok := fsys.OverlayPath(GoSumFile); ok {
732+
base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay")
733+
}
719734

720735
// Make a best-effort attempt to acquire the side lock, only to exclude
721736
// previous versions of the 'go' command from making simultaneous edits.

src/cmd/go/internal/modload/init.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,16 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
412412
}
413413

414414
gomod := ModFilePath()
415-
data, err := lockedfile.Read(gomod)
415+
var data []byte
416+
var err error
417+
if gomodActual, ok := fsys.OverlayPath(gomod); ok {
418+
// Don't lock go.mod if it's part of the overlay.
419+
// On Plan 9, locking requires chmod, and we don't want to modify any file
420+
// in the overlay. See #44700.
421+
data, err = os.ReadFile(gomodActual)
422+
} else {
423+
data, err = lockedfile.Read(gomodActual)
424+
}
416425
if err != nil {
417426
base.Fatalf("go: %v", err)
418427
}
@@ -1026,6 +1035,13 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements)
10261035
}
10271036
return
10281037
}
1038+
gomod := ModFilePath()
1039+
if _, ok := fsys.OverlayPath(gomod); ok {
1040+
if dirty {
1041+
base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
1042+
}
1043+
return
1044+
}
10291045

10301046
new, err := modFile.Format()
10311047
if err != nil {

src/cmd/go/internal/modload/modfile.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import (
88
"context"
99
"errors"
1010
"fmt"
11+
"os"
1112
"path/filepath"
1213
"strings"
1314
"sync"
1415
"unicode"
1516

1617
"cmd/go/internal/base"
1718
"cmd/go/internal/cfg"
19+
"cmd/go/internal/fsys"
1820
"cmd/go/internal/lockedfile"
1921
"cmd/go/internal/modfetch"
2022
"cmd/go/internal/par"
@@ -601,8 +603,16 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
601603
dir = filepath.Join(ModRoot(), dir)
602604
}
603605
gomod := filepath.Join(dir, "go.mod")
604-
605-
data, err := lockedfile.Read(gomod)
606+
var data []byte
607+
var err error
608+
if gomodActual, ok := fsys.OverlayPath(gomod); ok {
609+
// Don't lock go.mod if it's part of the overlay.
610+
// On Plan 9, locking requires chmod, and we don't want to modify any file
611+
// in the overlay. See #44700.
612+
data, err = os.ReadFile(gomodActual)
613+
} else {
614+
data, err = lockedfile.Read(gomodActual)
615+
}
606616
if err != nil {
607617
return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))}
608618
}

src/cmd/go/testdata/script/mod_overlay.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ go list -deps -overlay overlay.json .
2121
cd $WORK/gopath/src/get-doesnt-add-dep
2222
cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
2323
! go get -d -overlay overlay.json .
24-
stderr 'overlaid files can''t be opened for write'
24+
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
2525
cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
2626

2727
# Content of overlaid go.sum is used.
@@ -41,10 +41,10 @@ go mod verify -overlay overlay.json
4141
# attempting to update the file
4242
cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
4343
! go get -d -overlay overlay.json .
44-
stderr 'overlaid files can''t be opened for write'
44+
stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
4545
cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
4646
! go mod tidy -overlay overlay.json
47-
stderr 'overlaid files can''t be opened for write'
47+
stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
4848
cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
4949

5050
# -overlay works with -modfile.
@@ -56,7 +56,7 @@ go list -modfile=alternate.mod -overlay overlay.json .
5656
stdout 'found.the/module'
5757
# Even with -modfile, overlaid files can't be opened for write.
5858
! go get -modfile=alternate.mod -overlay overlay.json -d rsc.io/quote
59-
stderr 'overlaid files can''t be opened for write'
59+
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
6060

6161
# Carving out a module by adding an overlaid go.mod file
6262
cd $WORK/gopath/src/carve
@@ -78,7 +78,7 @@ go list -overlay overlay.json all
7878
stdout ^carve2/nomod$
7979
# Editing go.mod file fails because overlay is read only
8080
! go get -overlay overlay.json -d rsc.io/quote
81-
stderr 'overlaid files can''t be opened for write'
81+
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
8282
! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod
8383
# Editing go.mod file succeeds because we use -modfile to redirect to same file
8484
go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod -d rsc.io/quote

0 commit comments

Comments
 (0)