From ebf90170bc42d9934b526bfb87fddeb5b171cfcb Mon Sep 17 00:00:00 2001
From: Prabhala Tara Aasrita
Date: Wed, 22 Jul 2026 16:33:56 +0530
Subject: [PATCH] pool: support CRUSH MSR rules for EC pools
Added failureDomains and osdsPerDomain fields to the
ErasureCodedSpec, which maps to the crush-num-failure-domains and
crush-osds-per-failure-domain Ceph EC profile parameters. This enables
creating EC pools that distribute chunks across fewer, larger hosts
without needing one host per data chunk.
Signed-off-by: Prabhala Tara Aasrita
(cherry picked from commit 715f38de91470f841d1e55828c4176822c5ddfde)
---
Documentation/CRDs/specification.md | 28 ++++
.../charts/rook-ceph/templates/resources.yaml | 133 ++++++++++++++++++
deploy/examples/crds.yaml | 133 ++++++++++++++++++
pkg/apis/ceph.rook.io/v1/types.go | 15 ++
.../ceph/client/erasure-code-profile.go | 6 +
.../ceph/client/erasure-code-profile_test.go | 28 +++-
6 files changed, 336 insertions(+), 7 deletions(-)
diff --git a/Documentation/CRDs/specification.md b/Documentation/CRDs/specification.md
index 00bbf510e..647839ace 100644
--- a/Documentation/CRDs/specification.md
+++ b/Documentation/CRDs/specification.md
@@ -7199,6 +7199,34 @@ k8s.io/apimachinery/pkg/api/resource.Quantity
Value must be a multiple of 4096 (4Ki).
+
+
+crushNumFailureDomains
+
+int32
+
+ |
+
+(Optional)
+ Number of failure domains to use for erasure coded chunk placement.
+When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+that distributes chunks across this many failure domains.
+ |
+
+
+
+crushOSDsPerFailureDomain
+
+int32
+
+ |
+
+(Optional)
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+that allows up to this many chunks on OSDs within each failure domain.
+ |
+
ExternalSpec
diff --git a/deploy/charts/rook-ceph/templates/resources.yaml b/deploy/charts/rook-ceph/templates/resources.yaml
index 936f9f6ab..ac71a150f 100644
--- a/deploy/charts/rook-ceph/templates/resources.yaml
+++ b/deploy/charts/rook-ceph/templates/resources.yaml
@@ -468,6 +468,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -494,6 +510,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -7790,6 +7809,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -7816,6 +7851,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -8000,6 +8038,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -8026,6 +8080,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -12954,6 +13011,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -12980,6 +13053,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -14611,6 +14687,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -14637,6 +14729,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -15704,6 +15799,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -15730,6 +15841,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -15909,6 +16023,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -15935,6 +16065,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
diff --git a/deploy/examples/crds.yaml b/deploy/examples/crds.yaml
index a1efdc324..b5caea65f 100644
--- a/deploy/examples/crds.yaml
+++ b/deploy/examples/crds.yaml
@@ -470,6 +470,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -496,6 +512,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -7785,6 +7804,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -7811,6 +7846,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -7995,6 +8033,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -8021,6 +8075,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -12943,6 +13000,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -12969,6 +13042,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -14600,6 +14676,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -14626,6 +14718,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -15690,6 +15785,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -15716,6 +15827,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
@@ -15895,6 +16009,22 @@ spec:
This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
minimum: 0
type: integer
+ crushNumFailureDomains:
+ description: |-
+ Number of failure domains to use for erasure coded chunk placement.
+ When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ that distributes chunks across this many failure domains.
+ format: int32
+ minimum: 1
+ type: integer
+ crushOSDsPerFailureDomain:
+ description: |-
+ Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ that allows up to this many chunks on OSDs within each failure domain.
+ format: int32
+ minimum: 1
+ type: integer
dataChunks:
description: |-
Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
@@ -15921,6 +16051,9 @@ spec:
- codingChunks
- dataChunks
type: object
+ x-kubernetes-validations:
+ - message: crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together
+ rule: has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)
failureDomain:
description: 'The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map'
type: string
diff --git a/pkg/apis/ceph.rook.io/v1/types.go b/pkg/apis/ceph.rook.io/v1/types.go
index 067f2c9c6..583e9cd6a 100755
--- a/pkg/apis/ceph.rook.io/v1/types.go
+++ b/pkg/apis/ceph.rook.io/v1/types.go
@@ -1434,6 +1434,7 @@ type QuotaSpec struct {
}
// ErasureCodedSpec represents the spec for erasure code in a pool
+// +kubebuilder:validation:XValidation:message="crushNumFailureDomains and crushOSDsPerFailureDomain must be specified together",rule="has(self.crushNumFailureDomains) == has(self.crushOSDsPerFailureDomain)"
type ErasureCodedSpec struct {
// Number of coding chunks per object in an erasure coded storage pool (required for erasure-coded pool type).
// This is the number of OSDs that can be lost simultaneously before data cannot be recovered.
@@ -1457,6 +1458,20 @@ type ErasureCodedSpec struct {
// +kubebuilder:validation:Enum={"4Ki","16Ki","64Ki","256Ki","1Mi"}
// +optional
StripeUnit *resource.Quantity `json:"stripeUnit,omitempty"`
+
+ // Number of failure domains to use for erasure coded chunk placement.
+ // When specified along with crushOSDsPerFailureDomain, a CRUSH MSR rule will be created
+ // that distributes chunks across this many failure domains.
+ // +kubebuilder:validation:Minimum=1
+ // +optional
+ CrushNumFailureDomains int32 `json:"crushNumFailureDomains,omitempty"`
+
+ // Number of OSDs allowed per failure domain for erasure coded chunk placement.
+ // When specified along with crushNumFailureDomains, a CRUSH MSR rule will be created
+ // that allows up to this many chunks on OSDs within each failure domain.
+ // +kubebuilder:validation:Minimum=1
+ // +optional
+ CrushOSDsPerFailureDomain int32 `json:"crushOSDsPerFailureDomain,omitempty"`
}
// +genclient
diff --git a/pkg/daemon/ceph/client/erasure-code-profile.go b/pkg/daemon/ceph/client/erasure-code-profile.go
index b6f2cb130..74495d892 100644
--- a/pkg/daemon/ceph/client/erasure-code-profile.go
+++ b/pkg/daemon/ceph/client/erasure-code-profile.go
@@ -92,6 +92,12 @@ func CreateErasureCodeProfile(context *clusterd.Context, clusterInfo *ClusterInf
if pool.DeviceClass != "" {
profilePairs = append(profilePairs, fmt.Sprintf("crush-device-class=%s", pool.DeviceClass))
}
+ if pool.ErasureCoded.CrushNumFailureDomains > 0 {
+ profilePairs = append(profilePairs, fmt.Sprintf("crush-num-failure-domains=%d", pool.ErasureCoded.CrushNumFailureDomains))
+ }
+ if pool.ErasureCoded.CrushOSDsPerFailureDomain > 0 {
+ profilePairs = append(profilePairs, fmt.Sprintf("crush-osds-per-failure-domain=%d", pool.ErasureCoded.CrushOSDsPerFailureDomain))
+ }
if pool.ErasureCoded.StripeUnit != nil && !pool.ErasureCoded.StripeUnit.IsZero() {
stripeBytes, ok := pool.ErasureCoded.StripeUnit.AsInt64()
if !ok {
diff --git a/pkg/daemon/ceph/client/erasure-code-profile_test.go b/pkg/daemon/ceph/client/erasure-code-profile_test.go
index 4b50a64c4..194b85f80 100644
--- a/pkg/daemon/ceph/client/erasure-code-profile_test.go
+++ b/pkg/daemon/ceph/client/erasure-code-profile_test.go
@@ -29,27 +29,33 @@ import (
)
func TestCreateProfile(t *testing.T) {
- testCreateProfile(t, "", "myroot", "")
+ testCreateProfile(t, "", "myroot", "", 0, 0)
}
func TestCreateProfileWithFailureDomain(t *testing.T) {
- testCreateProfile(t, "osd", "", "")
+ testCreateProfile(t, "osd", "", "", 0, 0)
}
func TestCreateProfileWithDeviceClass(t *testing.T) {
- testCreateProfile(t, "osd", "", "hdd")
+ testCreateProfile(t, "osd", "", "hdd", 0, 0)
}
-func testCreateProfile(t *testing.T, failureDomain, crushRoot, deviceClass string) {
+func TestCreateProfileWithMSR(t *testing.T) {
+ testCreateProfile(t, "host", "", "", 5, 3)
+}
+
+func testCreateProfile(t *testing.T, failureDomain, crushRoot, deviceClass string, failureDomains, osdsPerDomain int32) {
stripeUnit := resource.MustParse("4Ki")
spec := cephv1.PoolSpec{
FailureDomain: failureDomain,
CrushRoot: crushRoot,
DeviceClass: deviceClass,
ErasureCoded: cephv1.ErasureCodedSpec{
- DataChunks: 2,
- CodingChunks: 3,
- StripeUnit: &stripeUnit,
+ DataChunks: 2,
+ CodingChunks: 3,
+ StripeUnit: &stripeUnit,
+ CrushNumFailureDomains: failureDomains,
+ CrushOSDsPerFailureDomain: osdsPerDomain,
},
}
@@ -82,6 +88,14 @@ func testCreateProfile(t *testing.T, failureDomain, crushRoot, deviceClass strin
assert.Equal(t, fmt.Sprintf("crush-device-class=%s", deviceClass), args[nextArg])
nextArg++
}
+ if failureDomains > 0 {
+ assert.Equal(t, fmt.Sprintf("crush-num-failure-domains=%d", failureDomains), args[nextArg])
+ nextArg++
+ }
+ if osdsPerDomain > 0 {
+ assert.Equal(t, fmt.Sprintf("crush-osds-per-failure-domain=%d", osdsPerDomain), args[nextArg])
+ nextArg++
+ }
if spec.ErasureCoded.StripeUnit != nil && !spec.ErasureCoded.StripeUnit.IsZero() {
stripeBytes, ok := spec.ErasureCoded.StripeUnit.AsInt64()
assert.True(t, ok)