Просмотр исходного кода

28755: Proper error handling for checkpoint conflict

Signed-off-by: Dattatrayakumbhar <dattatraya.kumbhar@gslab.com>
dattatrayakumbhar04 8 лет назад
Родитель
Сommit
d400518f4d
1 измененных файлов с 46 добавлено и 21 удалено
  1. 46 21
      daemon/checkpoint.go

+ 46 - 21
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