From 957c155cdf03ef1b3bb53d1e107850924bda2c89 Mon Sep 17 00:00:00 2001 From: cenhuilin Date: Fri, 8 Jul 2022 02:00:53 +0000 Subject: [PATCH] Write state.json atomically We want to make sure that the state file is syned and cannot be read partially or truncated. Signed-off-by: Mrunal Patel --- libcontainer/container_linux.go | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 7be84a6..709a95e 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -1385,13 +1385,30 @@ func (c *linuxContainer) updateState(process parentProcess) (*State, error) { return state, nil } -func (c *linuxContainer) saveState(s *State) error { - f, err := os.Create(filepath.Join(c.root, stateFilename)) - if err != nil { - return err - } - defer f.Close() - return utils.WriteJSON(f, s) +func (c *linuxContainer) saveState(s *State) (retErr error) { + tmpFile, err := ioutil.TempFile(c.root, "state-") + if err != nil { + return err + } + + defer func() { + if retErr != nil { + tmpFile.Close() + os.Remove(tmpFile.Name()) + } + }() + + err = utils.WriteJSON(tmpFile, s) + if err != nil { + return err + } + 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.33.0