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 <taraprabhala@Prabhalas-MacBook-Pro.local>
(cherry picked from commit 715f38de91)
This commit is contained in:
Prabhala Tara Aasrita authored and Mergify committed 2026-07-28 19:46:04 +00:00
1 parent 3b678364c8
commit ebf90170bc
6 files changed
+336 -7

No files matched your search

@@ -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 {
@@ -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)