From 6ea4aed9b0e96e037cd0e4c6accc1197a63e1ac0 Mon Sep 17 00:00:00 2001 From: zhongjiawei Date: Tue, 23 Aug 2022 10:32:23 +0800 Subject: [PATCH] runc: write state.json atomically We want to make sure that the state file is syned and cannot be read partially or truncated. Conflict:NA Reference:https://github.com/opencontainers/runc/pull/2467/commits/a4a306d2a2850e26052c86c329dc2d1a0521f723 --- libcontainer/container_linux.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 7be84a63..e9031267 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -1384,14 +1384,30 @@ func (c *linuxContainer) updateState(process parentProcess) (*State, error) { } return state, nil } +func (c *linuxContainer) saveState(s *State) (retErr error) { + tmpFile, err := ioutil.TempFile(c.root, "state-") + if err != nil { + return err + } -func (c *linuxContainer) saveState(s *State) error { - f, err := os.Create(filepath.Join(c.root, stateFilename)) + defer func() { + if retErr != nil { + tmpFile.Close() + os.Remove(tmpFile.Name()) + } + }() + + err = utils.WriteJSON(tmpFile, s) if err != nil { return err } - defer f.Close() - return utils.WriteJSON(f, s) + err = tmpFile.Close() + if err != nil { + return err + } + + stateFilePath := filepath.Join(c.root, stateFilename) + return os.Rename(tmpFile.Name(), stateFilePath) } func (c *linuxContainer) deleteState() error { -- 2.30.0