From 08efb45889a5d91d105678bf10724aee1851d8f9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 3 Mar 2014 21:11:17 -0800 Subject: [PATCH] OSDMonitor: do not add non-empty tier pool unless forced In general, users should not use non-empty pools as new tiers or else things can behave strangely: - the data sets are unrelated behavior will be... strange. - if the cache pool is not "new" and does not do the OMAP flag, the OSD will not know not to flush omap objects to an EC base tier - probably other random stuff I'm forgetting Allow a user to shoot themselves in the foot with --force-nonempty. Implements: #7457 Signed-off-by: Sage Weil --- qa/workunits/cephtool/test.sh | 11 +++++++++++ src/mon/MonCommands.h | 3 ++- src/mon/OSDMonitor.cc | 11 +++++++++++ src/mon/PGMap.h | 6 ++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index 4da5cd58aa13c..d4ccc9d178e4f 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -74,6 +74,17 @@ ceph osd tier set-overlay metadata cache ceph osd tier remove-overlay metadata ceph osd tier remove metadata cache ceph osd tier remove data cache2 + +# make sure a non-empty pool fails +rados -p cache2 put /etc/passwd /etc/passwd +while ! ceph df | grep cache2 | grep ' 1 ' ; do + echo waiting for pg stats to flush + sleep 2 +done +expect_false ceph osd tier add data cache2 +ceph osd tier add data cache2 --force-nonempty +ceph osd tier remove data cache2 + ceph osd pool delete cache cache --yes-i-really-really-mean-it ceph osd pool delete cache2 cache2 --yes-i-really-really-mean-it diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index b84b26567c51c..230bd1014b10b 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -552,7 +552,8 @@ COMMAND("osd thrash " \ // tiering COMMAND("osd tier add " \ "name=pool,type=CephPoolname " \ - "name=tierpool,type=CephPoolname", + "name=tierpool,type=CephPoolname " \ + "name=force_nonempty,type=CephChoices,strings=--force-nonempty,req=false", "add the tier to base pool ", "osd", "rw", "cli,rest") COMMAND("osd tier remove " \ "name=pool,type=CephPoolname " \ diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 1cee7d5935a29..2f86b194c0bfc 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -4494,6 +4494,17 @@ done: err = -EINVAL; goto reply; } + // make sure new tier is empty + string force_nonempty; + cmd_getval(g_ceph_context, cmdmap, "force_nonempty", force_nonempty); + const pool_stat_t& tier_stats = + mon->pgmon()->pg_map.get_pg_pool_sum_stat(tierpool_id); + if (tier_stats.stats.sum.num_objects != 0 && + force_nonempty != "--force-nonempty") { + ss << "tier pool '" << tierpoolstr << "' is not empty; --force-nonempty to force"; + err = -ENOTEMPTY; + goto reply; + } // go pending_inc.get_new_pool(pool_id, p)->tiers.insert(tierpool_id); pending_inc.get_new_pool(tierpool_id, tp)->tier_of = pool_id; diff --git a/src/mon/PGMap.h b/src/mon/PGMap.h index 9c346403abec5..65eccd35cbdec 100644 --- a/src/mon/PGMap.h +++ b/src/mon/PGMap.h @@ -205,6 +205,12 @@ public: stamp = s; } + const pool_stat_t& get_pg_pool_sum_stat(int64_t pool) { + ceph::unordered_map::iterator p = pg_pool_sum.find(pool); + assert(p != pg_pool_sum.end()); + return p->second; + } + void update_pg(pg_t pgid, bufferlist& bl); void remove_pg(pg_t pgid); void update_osd(int osd, bufferlist& bl); -- 2.39.5