func (devices *RbdSet) createImage(hash, baseHash string) error { var snapshot *rbd.Snapshot baseImgName := devices.getRbdImageName(baseHash) imgName := devices.getRbdImageName(hash) img := rbd.GetImage(devices.ioctx, baseImgName) // create snapshot for hash snapName := devices.getRbdSnapName(hash) if err := img.Open(snapName); err != nil { if err != rbd.RbdErrorNotFound { log.Errorf("Rbd open image %s with snap %s failed: %v", baseImgName, snapName, err) return err } // open image without snapshot name if err = img.Open(); err != nil { log.Errorf("Rbd open image %s failed: %v", baseImgName, err) return err } // create snapshot if snapshot, err = img.CreateSnapshot(snapName); err != nil { log.Errorf("Rbd create snaphost %s failed: %v", snapName, err) img.Close() return err } } else { snapshot = img.GetSnapshot(snapName) } // open snaphost success defer img.Close() // protect snapshot if err := snapshot.Protect(); err != nil { log.Errorf("Rbd protect snapshot %s failed: %v", snapName, err) return err } // clone image _, err := img.Clone(snapName, devices.ioctx, imgName, rbd.RbdFeatureLayering) if err != nil { log.Errorf("Rbd clone snapshot %s@%s to %s failed: %v", baseImgName, snapName, imgName, err) return err } return nil }