From 87081d58e521efefc9262548d674ad8b49cdc143 Mon Sep 17 00:00:00 2001 From: xie xingguo Date: Sat, 24 Jun 2017 11:31:16 +0800 Subject: [PATCH] mon/OSDMonitor: reject updating upmap if number of osd overflows/underflows This can avoid, e.g.: ~#:./bin/ceph osd pg-upmap 0.7 1 2 3 4 set 0.7 pg_upmap mapping to [1,2,3,4] ~#:./bin/ceph pg dump PG_STAT OBJECTS MISSING_ON_PRIMARY DEGRADED MISPLACED UNFOUND BYTES LOG DISK_LOG STATE STATE_STAMP VERSION REPORTED UP UP_PRIMARY ACTING ACTING_PRIMARY LAST_SCRUB SCRUB_STAMP LAST_DEEP_SCRUB DEEP_SCRUB_STAMP 0.7 0 0 0 0 0 0 0 0 peering 2017-06-24 10:11:03.938102 0'0 53:18 [1,2,3,4] 1 [1,2,3,4] 1 0'0 2017-06-24 09:38:50.162197 0'0 2017-06-24 09:38:50.162197 Signed-off-by: xie xingguo --- src/mon/OSDMonitor.cc | 24 ++++++++++++++++++++++++ src/osd/OSDMap.h | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index fd3fd8fed76..e13fd3bde8b 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -8856,6 +8856,22 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, goto reply; } + int pool_min_size = osdmap.get_pg_pool_min_size(pgid); + if ((int)id_vec.size() < pool_min_size) { + ss << "num of osds (" << id_vec.size() <<") < pool min size (" + << pool_min_size << ")"; + err = -EINVAL; + goto reply; + } + + int pool_size = osdmap.get_pg_pool_size(pgid); + if ((int)id_vec.size() > pool_size) { + ss << "num of osds (" << id_vec.size() <<") > pool size (" + << pool_size << ")"; + err = -EINVAL; + goto reply; + } + vector new_pg_upmap; for (auto osd : id_vec) { if (osd != CRUSH_ITEM_NONE && !osdmap.exists(osd)) { @@ -8895,6 +8911,14 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, goto reply; } + int pool_size = osdmap.get_pg_pool_size(pgid); + if ((int)(id_vec.size() / 2) > pool_size) { + ss << "num of osd pairs (" << id_vec.size() / 2 <<") > pool size (" + << pool_size << ")"; + err = -EINVAL; + goto reply; + } + vector> new_pg_upmap_items; for (auto p = id_vec.begin(); p != id_vec.end(); ++p) { int from = *p++; diff --git a/src/osd/OSDMap.h b/src/osd/OSDMap.h index 37fd980977b..8e236cf805b 100644 --- a/src/osd/OSDMap.h +++ b/src/osd/OSDMap.h @@ -1038,6 +1038,24 @@ public: return p && pgid.ps() < p->get_pg_num(); } + int get_pg_pool_min_size(pg_t pgid) const { + if (!pg_exists(pgid)) { + return -ENOENT; + } + const pg_pool_t *p = get_pg_pool(pgid.pool()); + assert(p); + return p->get_min_size(); + } + + int get_pg_pool_size(pg_t pgid) const { + if (!pg_exists(pgid)) { + return -ENOENT; + } + const pg_pool_t *p = get_pg_pool(pgid.pool()); + assert(p); + return p->get_size(); + } + private: /// pg -> (raw osd list) void _pg_to_raw_osds( -- 2.39.5