From d400518f4d139733f1f5b9333f493b1f9d76b8a1 Mon Sep 17 00:00:00 2001 From: dattatrayakumbhar04 Date: Sat, 3 Dec 2016 12:21:48 +0000 Subject: [PATCH] 28755: Proper error handling for checkpoint conflict Signed-off-by: Dattatrayakumbhar --- daemon/checkpoint.go | 67 ++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/daemon/checkpoint.go b/daemon/checkpoint.go index b8c4b8c87b..a4136d2c37 100644 --- a/daemon/checkpoint.go +++ b/daemon/checkpoint.go @@ -16,6 +16,41 @@ var ( validCheckpointNamePattern = api.RestrictedNamePattern ) +// getCheckpointDir verifies checkpoint directory for create,remove, list options and checks if checkpoint already exists +func getCheckpointDir(checkDir, checkpointID string, ctrName string, ctrID string, ctrCheckpointDir string, create bool) (string, error) { + var checkpointDir string + var err2 error + if checkDir != "" { + checkpointDir = filepath.Join(checkDir, ctrID, "checkpoints") + } else { + checkpointDir = ctrCheckpointDir + } + checkpointAbsDir := filepath.Join(checkpointDir, checkpointID) + stat, err := os.Stat(checkpointAbsDir) + if create { + switch { + case err == nil && stat.IsDir(): + err2 = fmt.Errorf("checkpoint with name %s already exists for container %s", checkpointID, ctrName) + case err != nil && os.IsNotExist(err): + err2 = nil + case err != nil: + err2 = err + case err == nil: + err2 = fmt.Errorf("%s exists and is not a directory", checkpointAbsDir) + } + } else { + switch { + case err != nil: + err2 = fmt.Errorf("checkpoint %s does not exists for container %s", checkpointID, ctrName) + case err == nil && stat.IsDir(): + err2 = nil + case err == nil: + err2 = fmt.Errorf("%s exists and is not a directory", checkpointAbsDir) + } + } + return checkpointDir, err2 +} + // CheckpointCreate checkpoints the process running in a container with CRIU func (daemon *Daemon) CheckpointCreate(name string, config types.CheckpointCreateOptions) error { container, err := daemon.GetContainer(name) @@ -27,17 +62,16 @@ func (daemon *Daemon) CheckpointCreate(name string, config types.CheckpointCreat return fmt.Errorf("Container %s not running", name) } - var checkpointDir string - if config.CheckpointDir != "" { - checkpointDir = config.CheckpointDir - } else { - checkpointDir = container.CheckpointDir() - } - if !validCheckpointNamePattern.MatchString(config.CheckpointID) { return fmt.Errorf("Invalid checkpoint ID (%s), only %s are allowed", config.CheckpointID, validCheckpointNameChars) } + checkpointDir, err := getCheckpointDir(config.CheckpointDir, config.CheckpointID, name, container.ID, container.CheckpointDir(), true) + + if err != nil { + return fmt.Errorf("cannot checkpoint container %s: %s", name, err) + } + err = daemon.containerd.CreateCheckpoint(container.ID, config.CheckpointID, checkpointDir, config.Exit) if err != nil { return fmt.Errorf("Cannot checkpoint container %s: %s", name, err) @@ -54,15 +88,11 @@ func (daemon *Daemon) CheckpointDelete(name string, config types.CheckpointDelet if err != nil { return err } - - var checkpointDir string - if config.CheckpointDir != "" { - checkpointDir = config.CheckpointDir - } else { - checkpointDir = container.CheckpointDir() + checkpointDir, err := getCheckpointDir(config.CheckpointDir, config.CheckpointID, name, container.ID, container.CheckpointDir(), false) + if err == nil { + return os.RemoveAll(filepath.Join(checkpointDir, config.CheckpointID)) } - - return os.RemoveAll(filepath.Join(checkpointDir, config.CheckpointID)) + return err } // CheckpointList lists all checkpoints of the specified container @@ -74,12 +104,7 @@ func (daemon *Daemon) CheckpointList(name string, config types.CheckpointListOpt return nil, err } - var checkpointDir string - if config.CheckpointDir != "" { - checkpointDir = config.CheckpointDir - } else { - checkpointDir = container.CheckpointDir() - } + checkpointDir, err := getCheckpointDir(config.CheckpointDir, "", name, container.ID, container.CheckpointDir(), true) if err := os.MkdirAll(checkpointDir, 0755); err != nil { return nil, err