Skip to content

Commit 1eb6bfe

Browse files
Merge pull request ceph#60631 from kamoltat/wip-ksirivad-fix-3az-unset
[3AZ] src/mon : Allow user to specify crush_rule, size and min_size when unsetting a stretch pool
2 parents 746fcba + ecce751 commit 1eb6bfe

File tree

6 files changed

+99
-6
lines changed

6 files changed

+99
-6
lines changed

doc/rados/operations/pools.rst

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ To move the pool back to non-stretch, run a command of the following form:
840840

841841
.. prompt:: bash $
842842

843-
ceph osd pool stretch unset {pool-name}
843+
ceph osd pool stretch unset {pool-name} {crush_rule} {size} {min_size}
844844

845845
Here are the breakdowns of the arguments:
846846

@@ -852,6 +852,28 @@ Here are the breakdowns of the arguments:
852852
:Type: String
853853
:Required: Yes.
854854

855+
.. describe:: {crush_rule}
856+
857+
The crush rule to use after exiting the stretch pool. The type of pool must match the type of crush_rule
858+
(replicated or erasure).
859+
860+
:Type: String
861+
:Required: Yes.
862+
863+
.. describe:: {size}
864+
865+
The number of replicas for objects after exiting stretch pool.
866+
867+
:Type: Integer
868+
:Required: Yes.
869+
870+
.. describe:: {min_size}
871+
872+
The minimum number of replicas required for I/O after exiting stretch pool.
873+
874+
:Type: Integer
875+
:Required: Yes.
876+
855877
Showing values of a stretch pool
856878
================================
857879
To show values for a stretch pool, run a command of the following form:

qa/tasks/stretch_cluster.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class TestStretchCluster(MgrTestCase):
5858
PEERING_CRUSH_BUCKET_TARGET = 3
5959
PEERING_CRUSH_BUCKET_BARRIER = 'datacenter'
6060
CRUSH_RULE = 'replicated_rule_custom'
61+
DEFAULT_CRUSH_RULE = 'replicated_rule'
6162
SIZE = 6
6263
MIN_SIZE = 3
6364
BUCKET_MAX = SIZE // PEERING_CRUSH_BUCKET_TARGET
@@ -594,6 +595,17 @@ def test_mon_failures_in_stretch_pool(self):
594595
success_hold_time=self.SUCCESS_HOLD_TIME
595596
)
596597

598+
# Unset the pool back to replicated rule expects PGs to be 100% active+clean
599+
self.mgr_cluster.mon_manager.raw_cluster_cmd(
600+
'osd', 'pool', 'stretch', 'unset',
601+
self.POOL, self.DEFAULT_CRUSH_RULE,
602+
str(self.SIZE), str(self.MIN_SIZE))
603+
self.wait_until_true_and_hold(
604+
lambda: self._pg_all_active_clean(),
605+
timeout=self.RECOVERY_PERIOD,
606+
success_hold_time=self.SUCCESS_HOLD_TIME
607+
)
608+
597609
def test_set_stretch_pool_no_active_pgs(self):
598610
"""
599611
Test setting a pool to stretch cluster and checks whether
@@ -686,10 +698,20 @@ def test_set_stretch_pool_no_active_pgs(self):
686698
timeout=self.RECOVERY_PERIOD,
687699
success_hold_time=self.SUCCESS_HOLD_TIME)
688700

689-
# Bring back osds iin DC2 expects PGs to be 100% active+clean
701+
# Bring back osds in DC2 expects PGs to be 100% active+clean
690702
self._bring_back_all_osds_in_dc('dc2')
691703
self.wait_until_true_and_hold(
692704
lambda: self._pg_all_active_clean(),
693705
timeout=self.RECOVERY_PERIOD,
694706
success_hold_time=self.SUCCESS_HOLD_TIME
695707
)
708+
# Unset the pool back to replicated rule expects PGs to be 100% active+clean
709+
self.mgr_cluster.mon_manager.raw_cluster_cmd(
710+
'osd', 'pool', 'stretch', 'unset',
711+
self.POOL, self.DEFAULT_CRUSH_RULE,
712+
str(self.SIZE), str(self.MIN_SIZE))
713+
self.wait_until_true_and_hold(
714+
lambda: self._pg_all_active_clean(),
715+
timeout=self.RECOVERY_PERIOD,
716+
success_hold_time=self.SUCCESS_HOLD_TIME
717+
)

qa/tasks/test_netsplit_3az_stretch_pool.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class TestNetSplit(CephTestCase):
2121
PEERING_CRUSH_BUCKET_BARRIER = 'datacenter'
2222
POOL = 'pool_stretch'
2323
CRUSH_RULE = 'replicated_rule_custom'
24+
DEFAULT_CRUSH_RULE = 'replicated_rule'
2425
SIZE = 6
2526
MIN_SIZE = 3
2627
BUCKET_MAX = SIZE // PEERING_CRUSH_BUCKET_TARGET
@@ -278,4 +279,14 @@ def test_mon_netsplit(self):
278279
timeout=self.RECOVERY_PERIOD,
279280
success_hold_time=self.SUCCESS_HOLD_TIME
280281
)
282+
# Unset the pool back to replicated rule expects PGs to be 100% active+clean
283+
self.mgr_cluster.mon_manager.raw_cluster_cmd(
284+
'osd', 'pool', 'stretch', 'unset',
285+
self.POOL, self.DEFAULT_CRUSH_RULE,
286+
str(self.SIZE), str(self.MIN_SIZE))
287+
self.wait_until_true_and_hold(
288+
lambda: self._pg_all_active_clean(),
289+
timeout=self.RECOVERY_PERIOD,
290+
success_hold_time=self.SUCCESS_HOLD_TIME
291+
)
281292
log.info("test_mon_netsplit passed!")

qa/workunits/mon/mon-stretch-pool.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,12 @@ expect_false ceph osd pool stretch set non_exist_pool 2 3 datacenter $TEST_CRUSH
9797
expect_false ceph osd pool stretch set $TEST_POOL_STRETCH 2 3 non_exist_barrier $TEST_CRUSH_RULE 6 3
9898
# Non existence crush_rule should return appropriate error
9999
expect_false ceph osd pool stretch set $TEST_POOL_STRETCH 2 3 datacenter $TEST_CRUSH_RULE 6 3
100+
# Unsetting a pool with missing arguments
101+
expect_false ceph osd pool stretch unset $TEST_POOL_STRETCH
100102
# Unsetting a non existence pool should return error
101-
expect_false ceph osd pool stretch unset non_exist_pool
103+
expect_false ceph osd pool stretch unset non_exist_pool replicated_rule 6 3
102104
# Unsetting a non-stretch pool should return error
103-
expect_false ceph osd pool stretch unset $TEST_POOL_STRETCH
105+
expect_false ceph osd pool stretch unset $TEST_POOL_STRETCH replicated_rule 6 3
104106

105107
# Create a custom crush rule
106108
ceph osd getcrushmap > crushmap
@@ -139,7 +141,7 @@ expect_true ceph osd pool stretch set $TEST_POOL_STRETCH 2 3 datacenter $TEST_CR
139141
expect_true ceph osd pool stretch show $TEST_POOL_STRETCH
140142

141143
# Unset the stretch pool and expects it to work
142-
expect_true ceph osd pool stretch unset $TEST_POOL_STRETCH
144+
expect_true ceph osd pool stretch unset $TEST_POOL_STRETCH replicated_rule 6 3
143145
# try to show the stretch pool values again, should return error since
144146
# the pool is not a stretch pool anymore.
145147
expect_false ceph osd pool stretch show $TEST_POOL_STRETCH

src/mon/MonCommands.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1237,7 +1237,10 @@ COMMAND("osd pool stretch set "
12371237
"make the pool stretched across the specified number of CRUSH buckets",
12381238
"osd", "rw")
12391239
COMMAND("osd pool stretch unset "
1240-
"name=pool,type=CephPoolname",
1240+
"name=pool,type=CephPoolname "
1241+
"name=crush_rule,type=CephString "
1242+
"name=size,type=CephInt,range=0 "
1243+
"name=min_size,type=CephInt,range=0 ",
12411244
"unset the stretch mode for the pool",
12421245
"osd", "rw")
12431246
COMMAND("osd utilization",

src/mon/OSDMonitor.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9237,11 +9237,44 @@ int OSDMonitor::prepare_command_pool_stretch_unset(const cmdmap_t& cmdmap,
92379237
ss << "pool " << pool_name << " is not a stretch pool";
92389238
return -ENOENT;
92399239
}
9240+
CrushWrapper& crush = _get_stable_crush();
9241+
string crush_rule_str;
9242+
cmd_getval(cmdmap, "crush_rule", crush_rule_str);
9243+
if (crush_rule_str.empty()) {
9244+
ss << "crush_rule must be provided";
9245+
return -EINVAL;
9246+
}
9247+
9248+
int crush_rule = crush.get_rule_id(crush_rule_str);
9249+
if (crush_rule < 0) {
9250+
ss << "crush rule " << crush_rule_str << " does not exist";
9251+
return -ENOENT;
9252+
}
9253+
9254+
if (!crush.rule_valid_for_pool_type(crush_rule, p.get_type())) {
9255+
ss << "crush rule " << crush_rule << " type does not match pool";
9256+
return -EINVAL;
9257+
}
9258+
9259+
int64_t pool_size = cmd_getval_or<int64_t>(cmdmap, "size", 0);
9260+
if (pool_size < 0) {
9261+
ss << "pool size must be non-negative";
9262+
return -EINVAL;
9263+
}
9264+
9265+
int64_t pool_min_size = cmd_getval_or<int64_t>(cmdmap, "min_size", 0);
9266+
if (pool_min_size < 0) {
9267+
ss << "pool min_size must be non-negative";
9268+
return -EINVAL;
9269+
}
92409270

92419271
// unset stretch values
92429272
p.peering_crush_bucket_count = 0;
92439273
p.peering_crush_bucket_target = 0;
92449274
p.peering_crush_bucket_barrier = 0;
9275+
p.crush_rule = static_cast<__u8>(crush_rule);
9276+
p.size = static_cast<__u8>(pool_size);
9277+
p.min_size = static_cast<__u8>(pool_min_size);
92459278
p.last_change = pending_inc.epoch;
92469279
pending_inc.new_pools[pool] = p;
92479280
ss << "pool " << pool_name

0 commit comments

Comments
 (0)