mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
rbd: add support for rbd striping
RBD supports creating rbd images with object size, stripe unit and stripe count to support striping. This PR adds the support for the same. More details about striping at https://docs.ceph.com/en/quincy/man/8/rbd/#striping fixes: #3124 Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
8f99fe7250
commit
4b57cc3ec5
147
e2e/rbd.go
147
e2e/rbd.go
@ -4080,6 +4080,153 @@ var _ = Describe("RBD", func() {
|
||||
})
|
||||
})
|
||||
|
||||
By("validate rbd image stripe", func() {
|
||||
stripeUnit := 4096
|
||||
stripeCount := 8
|
||||
objectSize := 131072
|
||||
err := deleteResource(rbdExamplePath + "storageclass.yaml")
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to delete storageclass: %v", err)
|
||||
}
|
||||
|
||||
err = createRBDStorageClass(
|
||||
f.ClientSet,
|
||||
f,
|
||||
defaultSCName,
|
||||
nil,
|
||||
map[string]string{
|
||||
"stripeUnit": fmt.Sprintf("%d", stripeUnit),
|
||||
"stripeCount": fmt.Sprintf("%d", stripeCount),
|
||||
"objectSize": fmt.Sprintf("%d", objectSize),
|
||||
},
|
||||
deletePolicy)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to create storageclass: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
err = deleteResource(rbdExamplePath + "storageclass.yaml")
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to delete storageclass: %v", err)
|
||||
}
|
||||
err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, nil, deletePolicy)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to create storageclass: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
err = createRBDSnapshotClass(f)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to create storageclass: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
err = deleteRBDSnapshotClass()
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to delete VolumeSnapshotClass: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// create PVC and bind it to an app
|
||||
pvc, err := loadPVC(pvcPath)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to load PVC: %v", err)
|
||||
}
|
||||
|
||||
pvc.Namespace = f.UniqueName
|
||||
|
||||
err = createPVCAndvalidatePV(f.ClientSet, pvc, deployTimeout)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to create PVC and application: %v", err)
|
||||
}
|
||||
// validate created backend rbd images
|
||||
validateRBDImageCount(f, 1, defaultRBDPool)
|
||||
validateOmapCount(f, 1, rbdType, defaultRBDPool, volumesType)
|
||||
err = validateStripe(f, pvc, stripeUnit, stripeCount, objectSize)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to validate stripe: %v", err)
|
||||
}
|
||||
|
||||
snap := getSnapshot(snapshotPath)
|
||||
snap.Namespace = f.UniqueName
|
||||
snap.Spec.Source.PersistentVolumeClaimName = &pvc.Name
|
||||
|
||||
err = createSnapshot(&snap, deployTimeout)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to create snapshot: %v", err)
|
||||
}
|
||||
// validate created backend rbd images
|
||||
// parent PVC + snapshot
|
||||
totalImages := 2
|
||||
validateRBDImageCount(f, totalImages, defaultRBDPool)
|
||||
validateOmapCount(f, 1, rbdType, defaultRBDPool, volumesType)
|
||||
validateOmapCount(f, 1, rbdType, defaultRBDPool, snapsType)
|
||||
pvcClone, err := loadPVC(pvcClonePath)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to load PVC: %v", err)
|
||||
}
|
||||
|
||||
// create clone PVC as ROX
|
||||
pvcClone.Namespace = f.UniqueName
|
||||
pvcClone.Spec.AccessModes = []v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}
|
||||
err = createPVCAndvalidatePV(f.ClientSet, pvcClone, deployTimeout)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to create PVC: %v", err)
|
||||
}
|
||||
// validate created backend rbd images
|
||||
// parent pvc + snapshot + clone
|
||||
totalImages = 3
|
||||
validateRBDImageCount(f, totalImages, defaultRBDPool)
|
||||
validateOmapCount(f, 2, rbdType, defaultRBDPool, volumesType)
|
||||
validateOmapCount(f, 1, rbdType, defaultRBDPool, snapsType)
|
||||
err = validateStripe(f, pvcClone, stripeUnit, stripeCount, objectSize)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to validate stripe for clone: %v", err)
|
||||
}
|
||||
// delete snapshot
|
||||
err = deleteSnapshot(&snap, deployTimeout)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to delete snapshot: %v", err)
|
||||
}
|
||||
// delete clone pvc
|
||||
err = deletePVCAndValidatePV(f.ClientSet, pvcClone, deployTimeout)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to delete PVC: %v", err)
|
||||
}
|
||||
|
||||
pvcSmartClone, err := loadPVC(pvcSmartClonePath)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to load pvcSmartClone: %v", err)
|
||||
}
|
||||
pvcSmartClone.Namespace = f.UniqueName
|
||||
|
||||
err = createPVCAndvalidatePV(f.ClientSet, pvcSmartClone, deployTimeout)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to create pvc: %v", err)
|
||||
}
|
||||
// validate created backend rbd images
|
||||
// parent pvc + temp clone + clone
|
||||
totalImages = 3
|
||||
validateRBDImageCount(f, totalImages, defaultRBDPool)
|
||||
validateOmapCount(f, 2, rbdType, defaultRBDPool, volumesType)
|
||||
err = validateStripe(f, pvcSmartClone, stripeUnit, stripeCount, objectSize)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to validate stripe for clone: %v", err)
|
||||
}
|
||||
// delete parent pvc
|
||||
err = deletePVCAndValidatePV(f.ClientSet, pvc, deployTimeout)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to delete PVC: %v", err)
|
||||
}
|
||||
|
||||
// delete clone pvc
|
||||
err = deletePVCAndValidatePV(f.ClientSet, pvcSmartClone, deployTimeout)
|
||||
if err != nil {
|
||||
e2elog.Failf("failed to delete PVC: %v", err)
|
||||
}
|
||||
// validate created backend rbd images
|
||||
validateRBDImageCount(f, 0, defaultRBDPool)
|
||||
validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType)
|
||||
})
|
||||
|
||||
// Make sure this should be last testcase in this file, because
|
||||
// it deletes pool
|
||||
By("Create a PVC and delete PVC when backend pool deleted", func() {
|
||||
|
@ -942,3 +942,69 @@ func waitToRemoveImagesFromTrash(f *framework.Framework, poolName string, t int)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// imageInfo strongly typed JSON spec for image info.
|
||||
type imageInfo struct {
|
||||
Name string `json:"name"`
|
||||
StripeUnit int `json:"stripe_unit"`
|
||||
StripeCount int `json:"stripe_count"`
|
||||
ObjectSize int `json:"object_size"`
|
||||
}
|
||||
|
||||
// getImageInfo queries rbd about the given image and returns its metadata, and returns
|
||||
// error if provided image is not found.
|
||||
func getImageInfo(f *framework.Framework, imageName, poolName string) (imageInfo, error) {
|
||||
// rbd --format=json info [image-spec | snap-spec]
|
||||
var imgInfo imageInfo
|
||||
|
||||
stdOut, stdErr, err := execCommandInToolBoxPod(
|
||||
f,
|
||||
fmt.Sprintf("rbd info %s %s --format json", rbdOptions(poolName), imageName),
|
||||
rookNamespace)
|
||||
if err != nil {
|
||||
return imgInfo, fmt.Errorf("failed to get rbd info: %w", err)
|
||||
}
|
||||
if stdErr != "" {
|
||||
return imgInfo, fmt.Errorf("failed to get rbd info: %v", stdErr)
|
||||
}
|
||||
err = json.Unmarshal([]byte(stdOut), &imgInfo)
|
||||
if err != nil {
|
||||
return imgInfo, fmt.Errorf("unmarshal failed: %w. raw buffer response: %s",
|
||||
err, stdOut)
|
||||
}
|
||||
|
||||
return imgInfo, nil
|
||||
}
|
||||
|
||||
// validateStripe validate the stripe count, stripe unit and object size of the
|
||||
// image.
|
||||
func validateStripe(f *framework.Framework,
|
||||
pvc *v1.PersistentVolumeClaim,
|
||||
stripeUnit,
|
||||
stripeCount,
|
||||
objectSize int,
|
||||
) error {
|
||||
imageData, err := getImageInfoFromPVC(pvc.Namespace, pvc.Name, f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
imgInfo, err := getImageInfo(f, imageData.imageName, defaultRBDPool)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if imgInfo.ObjectSize != objectSize {
|
||||
return fmt.Errorf("objectSize %d does not match expected %d", imgInfo.ObjectSize, objectSize)
|
||||
}
|
||||
|
||||
if imgInfo.StripeUnit != stripeUnit {
|
||||
return fmt.Errorf("stripeUnit %d does not match expected %d", imgInfo.StripeUnit, stripeUnit)
|
||||
}
|
||||
|
||||
if imgInfo.StripeCount != stripeCount {
|
||||
return fmt.Errorf("stripeCount %d does not match expected %d", imgInfo.StripeCount, stripeCount)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user