Skip to content

Commit

Permalink
endpoint: atomically replace header files
Browse files Browse the repository at this point in the history
Write contents of the header file to a temporary file first. It will
then be atomically renamed to the real file. This makes sure we never
end up with corrupted on inconsistent header files on the filesystem.
Also make sure the symlink to the old header file in the downgrade case
is created atomically. The github.com/google/renameio package is used
for the atomic replace and symlink creation.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
  • Loading branch information
tklauser authored and pchaigno committed Jul 2, 2020
1 parent e6123cb commit 542f0c2
Show file tree
Hide file tree
Showing 12 changed files with 558 additions and 7 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ require (
github.com/google/gofuzz v1.1.0
github.com/google/gopacket v1.1.17
github.com/google/gops v0.3.10
github.com/google/renameio v0.1.0
github.com/gorilla/mux v1.7.0
github.com/hashicorp/consul/api v1.2.0
github.com/hashicorp/go-immutable-radix v1.1.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 20 additions & 7 deletions pkg/endpoint/bpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
"github.com/cilium/cilium/pkg/revert"
"github.com/cilium/cilium/pkg/version"

"github.com/google/renameio"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
Expand Down Expand Up @@ -136,31 +137,43 @@ func (e *Endpoint) writeHeaderfile(prefix string) error {
e.getLogger().WithFields(logrus.Fields{
logfields.Path: headerPath,
}).Debug("writing header file")
f, err := os.Create(headerPath)

// Write new contents to a temporary file which will be atomically renamed to the
// real file at the end of this function. This will make sure we never end up with
// corrupted header files on the filesystem.
f, err := renameio.TempFile(prefix, headerPath)
if err != nil {
return fmt.Errorf("failed to open file %s for writing: %s", headerPath, err)
return fmt.Errorf("failed to open temporary file: %s", err)
}
defer f.Close()
defer f.Cleanup()

if err = e.writeInformationalComments(f); err != nil {
return err
}

if err = e.owner.Datapath().WriteEndpointConfig(f, e); err != nil {
return err
}

err = f.CloseAtomicallyReplace()

// Create symlink with old header filename, to allow downgrade to pre-1.8
// Cilium. Can be removed once v1.8 is the oldest supported release.
// We don't add the symlink for the host endpoint so that it is not
// restored when downgrading to <1.8.
if !e.IsHost() {
// restored when downgrading to <1.8. To avoid linking to a
// nonexistent file, only create the symlink if the header file
// creation/replacement file suceeded above.
if !e.IsHost() && err == nil {
oldHeaderPath := filepath.Join(prefix, common.OldCHeaderFileName)
if _, err := os.Stat(oldHeaderPath); err != nil {
// The symlink doesn't already exists.
if err := os.Symlink(common.CHeaderFileName, oldHeaderPath); err != nil {
if err := renameio.Symlink(common.CHeaderFileName, oldHeaderPath); err != nil {
e.getLogger().WithError(err).Error("Failed to create C header file symlink")
}
}
}

return e.owner.Datapath().WriteEndpointConfig(f, e)
return err
}

// addNewRedirectsFromDesiredPolicy must be called while holding the endpoint lock for
Expand Down
16 changes: 16 additions & 0 deletions vendor/github.com/google/renameio/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions vendor/github.com/google/renameio/CONTRIBUTING.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

202 changes: 202 additions & 0 deletions vendor/github.com/google/renameio/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions vendor/github.com/google/renameio/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions vendor/github.com/google/renameio/doc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 542f0c2

Please sign in to comment.