Skip to contentSkip to conversation

Osd: temperature based object eviction for cache tiering

PATCH New Li Wang 2 participants 8 messages May 21, 2015 – May 26, 2015

lore
Share & tools
lore

Li Wang

author
#0 lore raw

PATCH 1/1 Osd: temperature based object eviction for cache tiering

This is an implementation of temperature based object eviction policy for cache tiering. The current eviction policy is based only on the latest access time, without considering the access frequency in the history. This policy is apt to leave the just-accessed object in the cache pool, even it will no longer be accessed. Obviously, this policy will make bad choices in some scenarios. This motivates us to present temperature based object eviction policy, which makes eviction decision by considering both latest access time and access frequency, while keeping the simplicity of the current algorithm framework, and making minimal revision to it. The algorithm is simple, associate each hitset with a weight, the latest hitset with the heaviest weight, say, 1000000. And the least latest hitset with a lighter weight, decayed by an user-defined factor, say, 50, then the least latest hitset has a weight of 1000000*(100-50)/100=500000, and so on. Each object in the cache pool will be calculated a total weight according to its appearance in all the hitsets, then those objects with the least total weights are chosen as the eviction candidates. In fact, the algorithm reduces to the current atime based eviction policy by setting decay rate be 100.

The patches:
https://github.com/ceph/ceph/pull/4737

MingXin Liu (5):
Osd: add three fields to pg_pool_t
Mon: expose commands for temperature related setting
Osd: add a temperature based object eviction policy for cache tiering
Mon: add temperature support for existing cache related commands
Doc: add temperature related stuff in documents and test scripts

 doc/dev/cache-pool.rst         |   4 ++
 doc/man/8/ceph.rst             |  12 +++--
 doc/rados/operations/pools.rst |   7 +++
 qa/workunits/cephtool/test.sh  |  14 ++++++
 src/common/config_opts.h       |   2 +
 src/mon/MonCommands.h          |   8 ++-
 src/mon/OSDMonitor.cc          | 101 ++++++++++++++++++++++++++++++++++---
 src/osd/ReplicatedPG.cc        | 110 ++++++++++++++++++++++-------------------
 src/osd/osd_types.cc           |  32 +++++++++++-
 src/osd/osd_types.h            |  49 ++++++++++++++++++
 10 files changed, 274 insertions(+), 65 deletions(-)
Signature · 1 line
1.9.1
author
#1 lore raw

PATCH 1/5 Osd: add three fields to pg_pool_t

From: MingXin Liu <[email protected]>

---
 src/osd/osd_types.cc | 32 ++++++++++++++++++++++++++++++--
 src/osd/osd_types.h  | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 2 deletions(-)
src/osd/osd_types.cc +30 -2
index a73b46f..ba81889 100644
@@ -871,7 +871,6 @@ void pool_snap_info_t::generate_test_instances(list<pool_snap_info_t*>& o)
   o.back()->name = "foo";
 }
 
-
 // -- pg_pool_t --
 
 void pg_pool_t::dump(Formatter *f) const
@@ -910,6 +909,7 @@ void pg_pool_t::dump(Formatter *f) const
   f->dump_int("read_tier", read_tier);
   f->dump_int("write_tier", write_tier);
   f->dump_string("cache_mode", get_cache_mode_name());
+  f->dump_string("cache_measure", get_cache_measure_name());
   f->dump_unsigned("target_max_bytes", target_max_bytes);
   f->dump_unsigned("target_max_objects", target_max_objects);
   f->dump_unsigned("cache_target_dirty_ratio_micro",
@@ -925,6 +925,11 @@ void pg_pool_t::dump(Formatter *f) const
   f->dump_unsigned("hit_set_period", hit_set_period);
   f->dump_unsigned("hit_set_count", hit_set_count);
   f->dump_unsigned("min_read_recency_for_promote", min_read_recency_for_promote);
+  f->dump_unsigned("hit_set_grade_decay_rate",hit_set_grade_decay_rate);
+  f->open_array_section("grade_table");
+  for (vector<uint32_t>::const_iterator p = grade_table.begin(); p != grade_table.end(); ++p)
+    f->dump_unsigned("grade", *p);
+  f->close_section();
   f->dump_unsigned("stripe_width", get_stripe_width());
   f->dump_unsigned("expected_num_objects", expected_num_objects);
 }
@@ -1226,7 +1231,7 @@ void pg_pool_t::encode(bufferlist& bl, uint64_t features) const
     return;
   }
 
-  ENCODE_START(17, 5, bl);
+  ENCODE_START(18, 5, bl);
   ::encode(type, bl);
   ::encode(size, bl);
   ::encode(crush_ruleset, bl);
@@ -1268,6 +1273,9 @@ void pg_pool_t::encode(bufferlist& bl, uint64_t features) const
   ::encode(last_force_op_resend, bl);
   ::encode(min_read_recency_for_promote, bl);
   ::encode(expected_num_objects, bl);
+  __u8 m = cache_measure;
+  ::encode(m, bl);
+  ::encode(hit_set_grade_decay_rate, bl);
   ENCODE_FINISH(bl);
 }
 
@@ -1385,6 +1393,16 @@ void pg_pool_t::decode(bufferlist::iterator& bl)
   } else {
     expected_num_objects = 0;
   }
+  if (struct_v >= 18) {
+    __u8 v;
+    ::decode(v, bl);
+    cache_measure = (cache_measure_t)v;
+    ::decode(hit_set_grade_decay_rate, bl);
+    set_grade(hit_set_grade_decay_rate, hit_set_count);
+  } else {
+    cache_measure = CACHEMEASURE_ATIME;
+    hit_set_grade_decay_rate = 0;
+  }
   DECODE_FINISH(bl);
   calc_pg_masks();
 }
@@ -1425,12 +1443,16 @@ void pg_pool_t::generate_test_instances(list<pg_pool_t*>& o)
   a.tiers.insert(1);
   a.tier_of = 2;
   a.cache_mode = CACHEMODE_WRITEBACK;
+  a.cache_measure = CACHEMEASURE_ATIME;
   a.read_tier = 1;
   a.write_tier = 1;
   a.hit_set_params = HitSet::Params(new BloomHitSet::Params);
   a.hit_set_period = 3600;
   a.hit_set_count = 8;
   a.min_read_recency_for_promote = 1;
+  a.hit_set_grade_decay_rate = 50;
+  a.grade_table.push_back(1000000);
+  a.grade_table.push_back(500000);
   a.set_stripe_width(12345);
   a.target_max_bytes = 1238132132;
   a.target_max_objects = 1232132;
@@ -1475,6 +1497,8 @@ ostream& operator<<(ostream& out, const pg_pool_t& p)
     out << " write_tier " << p.write_tier;
   if (p.cache_mode)
     out << " cache_mode " << p.get_cache_mode_name();
+  if (p.cache_mode)
+    out << " cache_measure " << p.get_cache_measure_name();
   if (p.target_max_bytes)
     out << " target_bytes " << p.target_max_bytes;
   if (p.target_max_objects)
@@ -1483,6 +1507,10 @@ ostream& operator<<(ostream& out, const pg_pool_t& p)
     out << " hit_set " << p.hit_set_params
 	<< " " << p.hit_set_period << "s"
 	<< " x" << p.hit_set_count;
+    if (p.cache_measure == pg_pool_t::CACHEMEASURE_TEMP) {
+      out << " decay_rate " << p.hit_set_grade_decay_rate
+      << " grade_table" << p.grade_table;
+    }
   }
   if (p.min_read_recency_for_promote)
     out << " min_read_recency_for_promote " << p.min_read_recency_for_promote;
src/osd/osd_types.h +49 -0

97 lines not on this page · raw message

Signature · 1 line
1.9.1
author
#5 lore raw

PATCH 3/5 Osd: add a temperature based object eviction policy for cache tiering

In reply to Li Wang

From: MingXin Liu <[email protected]>

---
 src/osd/ReplicatedPG.cc | 110 +++++++++++++++++++++++++-----------------------
 1 file changed, 58 insertions(+), 52 deletions(-)
src/osd/ReplicatedPG.cc +58 -52
index 4c549a5..b2d49c6 100644
@@ -10822,44 +10822,45 @@ bool ReplicatedPG::agent_maybe_evict(ObjectContextRef& obc)
     }
   }
 
+  int atime = -1, temp = 0;
+  uint64_t atime_upper = 0, atime_lower = 0;
+  uint64_t temp_upper = 0, temp_lower = 0;
+
   if (agent_state->evict_mode != TierAgentState::EVICT_MODE_FULL) {
     // is this object old and/or cold enough?
-    int atime = -1, temp = 0;
-    if (hit_set)
-      agent_estimate_atime_temp(soid, &atime, NULL /*FIXME &temp*/);
-
-    uint64_t atime_upper = 0, atime_lower = 0;
-    if (atime < 0 && obc->obs.oi.mtime != utime_t()) {
-      if (obc->obs.oi.local_mtime != utime_t()) {
-        atime = ceph_clock_now(NULL).sec() - obc->obs.oi.local_mtime;
-      } else {
-        atime = ceph_clock_now(NULL).sec() - obc->obs.oi.mtime;
+    if (pool.info.cache_measure == pg_pool_t::CACHEMEASURE_ATIME) {
+      agent_estimate_atime_temp(soid, &atime, NULL);
+
+      if (atime < 0 && obc->obs.oi.mtime != utime_t()) {
+        if (obc->obs.oi.local_mtime != utime_t()) {
+          atime = ceph_clock_now(NULL).sec() - obc->obs.oi.local_mtime;
+        } else {
+          atime = ceph_clock_now(NULL).sec() - obc->obs.oi.mtime;
+        }
       }
-    }
-    if (atime < 0) {
-      if (hit_set) {
-        atime = pool.info.hit_set_period * pool.info.hit_set_count; // "infinite"
-      } else {
-	atime_upper = 1000000;
+      if (atime < 0) {
+        if (hit_set) {
+          atime = pool.info.hit_set_period * pool.info.hit_set_count; // "infinite"
+        } else {
+	      atime_upper = 1000000;
+        }
       }
-    }
-    if (atime >= 0) {
-      agent_state->atime_hist.add(atime);
-      agent_state->atime_hist.get_position_micro(atime, &atime_lower,
+      if (atime >= 0) {
+        agent_state->atime_hist.add(atime);
+        agent_state->atime_hist.get_position_micro(atime, &atime_lower,
 						 &atime_upper);
-    }
+      }
+    } else {
+      agent_estimate_atime_temp(soid, NULL, &temp);
 
-    unsigned temp_upper = 0, temp_lower = 0;
-    /*
-    // FIXME: bound atime based on creation time?
-    agent_state->temp_hist.add(atime);
-    agent_state->temp_hist.get_position_micro(temp, &temp_lower, &temp_upper);
-    */
+      agent_state->temp_hist.add(temp);
+      agent_state->temp_hist.get_position_micro(temp, &temp_lower, &temp_upper);
+    }
 
     dout(20) << __func__
-	     << " atime " << atime
+         << " atime " << atime
 	     << " pos " << atime_lower << "-" << atime_upper
-	     << ", temp " << temp
+         <<" temp " << temp
 	     << " pos " << temp_lower << "-" << temp_upper
 	     << ", evict_effort " << agent_state->evict_effort
 	     << dendl;
@@ -10872,9 +10873,10 @@ bool ReplicatedPG::agent_maybe_evict(ObjectContextRef& obc)
     delete f;
     *_dout << dendl;
 
-    // FIXME: ignore temperature for now.
-
-    if (1000000 - atime_upper >= agent_state->evict_effort)
+    if (pool.info.cache_measure == pg_pool_t::CACHEMEASURE_ATIME) {
+      if(1000000 - atime_upper >= agent_state->evict_effort)
+        return false;
+    } else if (temp_lower >= agent_state->evict_effort)
       return false;
   }
 
@@ -11124,29 +11126,33 @@ void ReplicatedPG::agent_estimate_atime_temp(const hobject_t& oid,
 					     int *atime, int *temp)
 {
   assert(hit_set);
-  *atime = -1;
-  if (temp)
-    *temp = 0;
-  if (hit_set->contains(oid)) {
-    *atime = 0;
-    if (temp)
-      ++(*temp);
-    else
+  if (atime) {
+    *atime = -1;
+    if (hit_set->contains(oid)) {
+      *atime = 0;
       return;
-  }
-  time_t now = ceph_clock_now(NULL).sec();
-  for (map<time_t,HitSetRef>::reverse_iterator p =
-	 agent_state->hit_set_map.rbegin();
-       p != agent_state->hit_set_map.rend();
-       ++p) {
-    if (p->second->contains(oid)) {
-      if (*atime < 0)
-	*atime = now - p->first;
-      if (temp)
-	++(*temp);
-      else
+    }
+	time_t now = ceph_clock_now(NULL).sec();
+    for (map<time_t,HitSetRef>::reverse_iterator p =
+         agent_state->hit_set_map.rbegin();
+         p != agent_state->hit_set_map.rend(); ++p) {
+      if (p->second->contains(oid))
+        *atime = now - p->first;
+      if (*atime >= 0)
 	return;
     }
+  } else if (temp) {
+    *temp = 0;
+    unsigned i = 0;
+    if (hit_set->contains(oid))
+      *temp += pool.info.get_grade(0);
+    for (map<time_t,HitSetRef>::reverse_iterator p =
+         agent_state->hit_set_map.rbegin();
+         p != agent_state->hit_set_map.rend(); ++p) {
+      ++i;
+      if (p->second->contains(oid))
+        *temp += pool.info.get_grade(i);
+    }
   }
 }
 
Signature · 1 line
1.9.1
author
#7 lore raw

PATCH 5/5 Doc: add temperature related stuff in documents and test scripts

In reply to Li Wang

From: MingXin Liu <[email protected]>

---
 doc/dev/cache-pool.rst         |  4 ++++
 doc/man/8/ceph.rst             | 12 +++++++++---
 doc/rados/operations/pools.rst |  7 +++++++
 qa/workunits/cephtool/test.sh  | 14 ++++++++++++++
 4 files changed, 34 insertions(+), 3 deletions(-)
doc/dev/cache-pool.rst +4 -0
index f44cbd9..d3b6257 100644
@@ -179,5 +179,9 @@ the cache tier::
 
  ceph osd pool set foo-hot cache_min_evict_age 1800   # 30 minutes
 
+You can specify the objects evict policy(cache-measure),when cache-measure is set as atime
+the most recent objects are hotter than others,if use temperature as measure agent will consider
+both access time and frequency::
+ ceph osd tier cache-measure foo-hot <atime|temperature>
 
 
doc/man/8/ceph.rst +9 -3
index f950221..53133d8 100644
@@ -45,7 +45,7 @@ Synopsis
 
 | **ceph** **osd** **pool** [ *create* \| *delete* \| *get* \| *get-quota* \| *ls* \| *mksnap* \| *rename* \| *rmsnap* \| *set* \| *set-quota* \| *stats* ] ...
 
-| **ceph** **osd** **tier** [ *add* \| *add-cache* \| *cache-mode* \| *remove* \| *remove-overlay* \| *set-overlay* ] ...
+| **ceph** **osd** **tier** [ *add* \| *add-cache* \| *cache-mode* \| *cache-measure* \| *remove* \| *remove-overlay* \| *set-overlay* ] ...
 
 | **ceph** **pg** [ *debug* \| *deep-scrub* \| *dump* \| *dump_json* \| *dump_pools_json* \| *dump_stuck* \| *force_create_pg* \| *getmap* \| *ls* \| *ls-by-osd* \| *ls-by-pool* \| *ls-by-primary* \| *map* \| *repair* \| *scrub* \| *send_pg_creates* \| *set_full_ratio* \| *set_nearfull_ratio* \| *stat* ] ...
 
@@ -878,7 +878,7 @@ Only for tiered pools::
 	ceph osd pool get <poolname> hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|
 	target_max_objects|target_max_bytes|cache_target_dirty_ratio|
 	cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|
-	min_read_recency_for_promote
+	min_read_recency_for_promote|hit_set_grade_decay_rate
 
 Only for erasure coded pools::
 
@@ -927,7 +927,7 @@ Usage::
 	hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|
 	target_max_bytes|target_max_objects|cache_target_dirty_ratio|
 	cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|
-	min_read_recency_for_promote|write_fadvise_dontneed
+	min_read_recency_for_promote|write_fadvise_dontneed|hit_set_grade_decay_rate
 	<val> {--yes-i-really-mean-it}
 
 Subcommand ``set-quota`` sets object or byte limit on pool.
@@ -1049,6 +1049,12 @@ Usage::
 	ceph osd tier cache-mode <poolname> none|writeback|forward|readonly|
 	readforward|readproxy
 
+Subcommand ``cache-measure`` specifies the caching measure for cache tier <pool>.
+
+Usage::
+
+	ceph osd tier cache-measure <poolname> atime|temperature
+
 Subcommand ``remove`` removes the tier <tierpool> (the second one) from base pool
 <pool> (the first one).
 
doc/rados/operations/pools.rst +7 -0
index 36b9c94..2c6deab 100644
@@ -374,6 +374,13 @@ You may set values for the following keys:
 :Example: ``1000000`` #1M objects
 
 
+``hit_set_grade_decay_rate``
+:Description: Temperature grade decay rate between a hit_set and the follow one
+:Type: Integer
+:Valid Range: 0 - 100
+:Default: ``50``
+
+
 ``cache_min_flush_age``
 
 :Description: The time (in seconds) before the cache tiering agent will flush 
qa/workunits/cephtool/test.sh +14 -0
index 15d4e73..c51592a 100755
@@ -415,6 +415,20 @@ function test_tiering()
   ceph osd pool delete cache5 cache5 --yes-i-really-really-mean-it
   ceph osd pool delete basepoolB basepoolB --yes-i-really-really-mean-it
   ceph osd pool delete basepoolA basepoolA --yes-i-really-really-mean-it
+
+  #cache-measure
+  ceph osd pool create Mbase1 2
+  ceph osd pool create Mcache1 2
+  ceph osd tier add Mbase1 Mcache1
+  ceph osd pool set Mcache1 hit_set_type bloom
+  ceph osd pool set Mcache1 hit_set_count 4
+  ceph osd pool set Mcache1 hit_set_period 1200
+  ceph osd pool set Mcache1 hit_set_grade_decay_rate 3
+  ceph osd tier cache-mode writeback
+  ceph osd tier cache-measure temperature
+  ceph osd tier set-overlay Mbase1 Mcache1
+  ceph osd tier cache-measure atime
+  ceph osd tier cache-measure temperature
 }
 
 function test_auth()
Signature · 1 line
1.9.1
author
#2 lore raw

PATCH 2/5 Mon: expose commands for temperature related setting

In reply to Li Wang

From: MingXin Liu <[email protected]>

---
 src/mon/MonCommands.h |  8 +++--
 src/mon/OSDMonitor.cc | 87 ++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 88 insertions(+), 7 deletions(-)
src/mon/MonCommands.h +6 -2
index 8a36807..b26834d 100644
@@ -639,11 +639,11 @@ COMMAND("osd pool rename " \
 	"rename <srcpool> to <destpool>", "osd", "rw", "cli,rest")
 COMMAND("osd pool get " \
 	"name=pool,type=CephPoolname " \
-	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|auid|target_max_objects|target_max_bytes|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|erasure_code_profile|min_read_recency_for_promote|write_fadvise_dontneed|all", \
+	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|auid|target_max_objects|target_max_bytes|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|erasure_code_profile|min_read_recency_for_promote|write_fadvise_dontneed|hit_set_grade_decay_rate|all", \
 	"get pool parameter <var>", "osd", "r", "cli,rest")
 COMMAND("osd pool set " \
 	"name=pool,type=CephPoolname " \
-	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool|nodelete|nopgchange|nosizechange|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote|write_fadvise_dontneed " \
+	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool|nodelete|nopgchange|nosizechange|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote|write_fadvise_dontneed|hit_set_grade_decay_rate " \
 	"name=val,type=CephString " \
 	"name=force,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
 	"set pool parameter <var> to <val>", "osd", "rw", "cli,rest")
@@ -695,6 +695,10 @@ COMMAND("osd tier cache-mode " \
 	"name=pool,type=CephPoolname " \
 	"name=mode,type=CephChoices,strings=none|writeback|forward|readonly|readforward|readproxy", \
 	"specify the caching mode for cache tier <pool>", "osd", "rw", "cli,rest")
+COMMAND("osd tier cache-measure " \
+        "name=pool,type=CephPoolname " \
+        "name=measure,type=CephChoices,strings=atime|temperature", \
+        "specify the caching measure to judge hot objects for cache tier <pool>", "osd", "rw", "cli,rest")
 COMMAND("osd tier set-overlay " \
 	"name=pool,type=CephPoolname " \
 	"name=overlaypool,type=CephPoolname", \
src/mon/OSDMonitor.cc +82 -5

146 lines not on this page · raw message

Signature · 1 line
1.9.1
author
#6 lore raw

PATCH 4/5 Mon: add temperature support for existing cache related commands

In reply to Li Wang

From: MingXin Liu <[email protected]>

---
 src/common/config_opts.h |  2 ++
 src/mon/OSDMonitor.cc    | 14 +++++++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)
src/common/config_opts.h +2 -0
index e79eeaa..f661cbc 100644
@@ -550,10 +550,12 @@ OPTION(osd_hit_set_max_size, OPT_INT, 100000)  // max target size for a HitSet
 OPTION(osd_hit_set_namespace, OPT_STR, ".ceph-internal") // rados namespace for hit_set tracking
 
 OPTION(osd_tier_default_cache_mode, OPT_STR, "writeback")
+OPTION(osd_tier_default_cache_measure, OPT_STR, "atime")
 OPTION(osd_tier_default_cache_hit_set_count, OPT_INT, 4)
 OPTION(osd_tier_default_cache_hit_set_period, OPT_INT, 1200)
 OPTION(osd_tier_default_cache_hit_set_type, OPT_STR, "bloom")
 OPTION(osd_tier_default_cache_min_read_recency_for_promote, OPT_INT, 1) // number of recent HitSets the object must appear in to be promoted (on read)
+OPTION(osd_tier_default_cache_hit_set_grade_decay_rate, OPT_INT, 50)
 
 OPTION(osd_map_dedup, OPT_BOOL, true)
 OPTION(osd_map_max_advance, OPT_INT, 200) // make this < cache_size!
src/mon/OSDMonitor.cc +13 -1
index 0374778..ac84b56 100644
@@ -2723,13 +2723,15 @@ void OSDMonitor::get_health(list<pair<health_status_t,string> >& summary,
 	   p != osdmap.pools.end();
 	   ++p) {
 	const pg_pool_t& info = p->second;
-	if (info.cache_mode_requires_hit_set() &&
+	if ((info.cache_mode_requires_hit_set() ||
+        info.cache_measure == pg_pool_t::CACHEMEASURE_TEMP) &&
 	    info.hit_set_params.get_type() == HitSet::TYPE_NONE) {
 	  ++problem_cache_pools;
 	  if (detail) {
 	    ostringstream ss;
 	    ss << "pool '" << osdmap.get_pool_name(p->first)
 	       << "' with cache_mode " << info.get_cache_mode_name()
+           << " cache_measure " << info.get_cache_measure_name()
 	       << " needs hit_set_type to be set but it is not";
 	    detail->push_back(make_pair(HEALTH_WARN, ss.str()));
 	  }
@@ -6874,6 +6876,13 @@ done:
       err = -EINVAL;
       goto reply;
     }
+    string measurestr = g_conf->osd_tier_default_cache_measure;
+    pg_pool_t::cache_measure_t measure = pg_pool_t::get_cache_measure_from_str(measurestr);
+    if (measure < 0) {
+      ss << "osd tier cache default measure '" << measurestr << "' is not a valid cache measure";
+      err = -EINVAL;
+      goto reply;
+    }
     HitSet::Params hsp;
     if (g_conf->osd_tier_default_cache_hit_set_type == "bloom") {
       BloomHitSet::Params *bsp = new BloomHitSet::Params;
@@ -6902,11 +6911,14 @@ done:
     np->set_snap_epoch(pending_inc.epoch); // tier will update to our snap info
     ntp->tier_of = pool_id;
     ntp->cache_mode = mode;
+    ntp->cache_measure = measure;
     ntp->hit_set_count = g_conf->osd_tier_default_cache_hit_set_count;
     ntp->hit_set_period = g_conf->osd_tier_default_cache_hit_set_period;
     ntp->min_read_recency_for_promote = g_conf->osd_tier_default_cache_min_read_recency_for_promote;
+    ntp->hit_set_grade_decay_rate = g_conf->osd_tier_default_cache_hit_set_grade_decay_rate;
     ntp->hit_set_params = hsp;
     ntp->target_max_bytes = size;
+    ntp->set_grade(ntp->hit_set_grade_decay_rate, ntp->hit_set_count);
     ss << "pool '" << tierpoolstr << "' is now (or already was) a cache tier of '" << poolstr << "'";
     wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, ss.str(),
 					      get_last_committed() + 1));
Signature · 1 line
1.9.1
#3 lore raw

Re: [PATCH 2/5] Mon: expose commands for temperature related setting

In reply to Li Wang

As far as I can tell, this patch can be split in two different patches:

- add hit_set_grade_decay_rate option to 'osd pool set/get'
- add 'osd tier cache-measure'

Also, for the latter we could also use an explanatory commit message.

Aside from that, I don't see anything obviously wrong with the patch.

-Joao

Quoted 198 lines · Li Wang

From: MingXin Liu <[email protected]>

---
 src/mon/MonCommands.h |  8 +++--
 src/mon/OSDMonitor.cc | 87 ++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 88 insertions(+), 7 deletions(-)
src/mon/MonCommands.h +6 -2
index 8a36807..b26834d 100644
@@ -639,11 +639,11 @@ COMMAND("osd pool rename " \
 	"rename <srcpool> to <destpool>", "osd", "rw", "cli,rest")
 COMMAND("osd pool get " \
 	"name=pool,type=CephPoolname " \
-	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|auid|target_max_objects|target_max_bytes|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|erasure_code_profile|min_read_recency_for_promote|write_fadvise_dontneed|all", \
+	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|auid|target_max_objects|target_max_bytes|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|erasure_code_profile|min_read_recency_for_promote|write_fadvise_dontneed|hit_set_grade_decay_rate|all", \
 	"get pool parameter <var>", "osd", "r", "cli,rest")
 COMMAND("osd pool set " \
 	"name=pool,type=CephPoolname " \
-	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool|nodelete|nopgchange|nosizechange|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote|write_fadvise_dontneed " \
+	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool|nodelete|nopgchange|nosizechange|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote|write_fadvise_dontneed|hit_set_grade_decay_rate " \
 	"name=val,type=CephString " \
 	"name=force,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
 	"set pool parameter <var> to <val>", "osd", "rw", "cli,rest")
@@ -695,6 +695,10 @@ COMMAND("osd tier cache-mode " \
 	"name=pool,type=CephPoolname " \
 	"name=mode,type=CephChoices,strings=none|writeback|forward|readonly|readforward|readproxy", \
 	"specify the caching mode for cache tier <pool>", "osd", "rw", "cli,rest")
+COMMAND("osd tier cache-measure " \
+        "name=pool,type=CephPoolname " \
+        "name=measure,type=CephChoices,strings=atime|temperature", \
+        "specify the caching measure to judge hot objects for cache tier <pool>", "osd", "rw", "cli,rest")
 COMMAND("osd tier set-overlay " \
 	"name=pool,type=CephPoolname " \
 	"name=overlaypool,type=CephPoolname", \
src/mon/OSDMonitor.cc +82 -5
index 10597d0..0374778 100644
@@ -2803,7 +2803,7 @@ namespace {
     CACHE_TARGET_DIRTY_RATIO, CACHE_TARGET_FULL_RATIO,
     CACHE_MIN_FLUSH_AGE, CACHE_MIN_EVICT_AGE,
     ERASURE_CODE_PROFILE, MIN_READ_RECENCY_FOR_PROMOTE,
-    WRITE_FADVISE_DONTNEED};
+    WRITE_FADVISE_DONTNEED, HIT_SET_GRADE_DECAY_RATE};
 
   std::set<osd_pool_get_choices>
     subtract_second_from_first(const std::set<osd_pool_get_choices>& first,
@@ -3251,7 +3251,8 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
       ("cache_min_evict_age", CACHE_MIN_EVICT_AGE)
       ("erasure_code_profile", ERASURE_CODE_PROFILE)
       ("min_read_recency_for_promote", MIN_READ_RECENCY_FOR_PROMOTE)
-      ("write_fadvise_dontneed", WRITE_FADVISE_DONTNEED);
+      ("write_fadvise_dontneed", WRITE_FADVISE_DONTNEED)
+      ("hit_set_grade_decay_rate", HIT_SET_GRADE_DECAY_RATE);
 
     typedef std::set<osd_pool_get_choices> choices_set_t;
 
@@ -3259,7 +3260,7 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
       (HIT_SET_TYPE)(HIT_SET_PERIOD)(HIT_SET_COUNT)(HIT_SET_FPP)
       (TARGET_MAX_OBJECTS)(TARGET_MAX_BYTES)(CACHE_TARGET_FULL_RATIO)
       (CACHE_TARGET_DIRTY_RATIO)(CACHE_MIN_FLUSH_AGE)(CACHE_MIN_EVICT_AGE)
-      (MIN_READ_RECENCY_FOR_PROMOTE);
+      (MIN_READ_RECENCY_FOR_PROMOTE)(HIT_SET_GRADE_DECAY_RATE);
 
     const choices_set_t ONLY_ERASURE_CHOICES = boost::assign::list_of
       (ERASURE_CODE_PROFILE);
@@ -3389,6 +3390,10 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
 	    f->dump_int("min_read_recency_for_promote",
 			p->min_read_recency_for_promote);
 	    break;
+	  case HIT_SET_GRADE_DECAY_RATE:
+	    f->dump_int("hit_set_priority_decacy_rate",
+			p->hit_set_grade_decay_rate);
+	    break;
 	  case WRITE_FADVISE_DONTNEED:
 	    f->dump_string("write_fadvise_dontneed",
 			   p->has_flag(pg_pool_t::FLAG_WRITE_FADVISE_DONTNEED) ?
@@ -3476,6 +3481,10 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
 	    ss << "min_read_recency_for_promote: " <<
 	      p->min_read_recency_for_promote << "\n";
 	    break;
+	  case HIT_SET_GRADE_DECAY_RATE:
+	    ss << "hit_set_grade_decay_rate: " <<
+	      p->hit_set_grade_decay_rate << "\n";
+	    break;
 	  case WRITE_FADVISE_DONTNEED:
 	    ss << "write_fadvise_dontneed: " <<
 	      (p->has_flag(pg_pool_t::FLAG_WRITE_FADVISE_DONTNEED) ?
@@ -4466,7 +4475,8 @@ int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
        var == "hit_set_count" || var == "hit_set_fpp" ||
        var == "target_max_objects" || var == "target_max_bytes" ||
        var == "cache_target_full_ratio" || var == "cache_target_dirty_ratio" ||
-       var == "cache_min_flush_age" || var == "cache_min_evict_age")) {
+       var == "cache_min_flush_age" || var == "cache_min_evict_age" ||
+       var == "hit_set_grade_decay_rate")) {
     ss << "pool '" << poolstr << "' is not a tier pool: variable not applicable";
     return -EACCES;
   }
@@ -4652,12 +4662,12 @@ int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
     }
     p.hit_set_period = n;
   } else if (var == "hit_set_count") {
-
     if (interr.length()) {
       ss << "error parsing integer value '" << val << "': " << interr;
       return -EINVAL;
     }
     p.hit_set_count = n;
+    p.set_grade(p.hit_set_grade_decay_rate, n);
   } else if (var == "hit_set_fpp") {
     if (floaterr.length()) {
       ss << "error parsing floating point value '" << val << "': " << floaterr;
@@ -4723,6 +4733,17 @@ int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
       return -EINVAL;
     }
     p.min_read_recency_for_promote = n;
+  } else if (var == "hit_set_grade_decay_rate") {
+    if (interr.length()) {
+      ss << "error parsing integer value '" << val << "': " << interr;
+      return -EINVAL;
+    }
+    if (n > 100 || n < 0) {
+      ss << "value out of range,valid range is 0 - 100";
+      return -EINVAL;
+    }
+    p.hit_set_grade_decay_rate = n;
+    p.set_grade(n, p.hit_set_count);
   } else if (var == "write_fadvise_dontneed") {
     if (val == "true" || (interr.empty() && n == 1)) {
       p.flags |= pg_pool_t::FLAG_WRITE_FADVISE_DONTNEED;
@@ -6744,6 +6765,62 @@ done:
     wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, ss.str(),
 					      get_last_committed() + 1));
     return true;
+  } else if (prefix == "osd tier cache-measure") {
+    err = check_cluster_features(CEPH_FEATURE_OSD_CACHEPOOL, ss);
+    if (err == -EAGAIN)
+      goto wait;
+    if (err)
+      goto reply;
+    string poolstr;
+    cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
+    int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
+    if (pool_id < 0) {
+      ss << "unrecognized pool '" << poolstr << "'";
+      err = -ENOENT;
+      goto reply;
+    }
+    const pg_pool_t *p = osdmap.get_pg_pool(pool_id);
+    assert(p);
+    if (!p->is_tier()) {
+      ss << "pool '" << poolstr << "' is not a tier";
+      err = -EINVAL;
+      goto reply;
+    }
+    string measurestr;
+    cmd_getval(g_ceph_context, cmdmap, "measure", measurestr);
+    pg_pool_t::cache_measure_t measure = pg_pool_t::get_cache_measure_from_str(measurestr);
+    if (measure < 0) {
+      ss << "'" << measurestr << "' is not a valid cache measure";
+      err = -EINVAL;
+      goto reply;
+    }
+    if (p->grade_table.empty()) {
+      ss << "grade_table is empty,set hit_set and hit_set_decay_rate first";
+      err = -EINVAL;
+      goto reply;
+    }
+    if (p->hit_set_params.get_type() == HitSet::TYPE_NONE) {
+      ss << "hit_set_type cannot be none";
+      err = -EINVAL;
+      goto reply;
+    }
+
+    //pool already had this cache-measure set and there are no pending changes
+    if (p->cache_measure == measure &&
+    (pending_inc.new_pools.count(pool_id) == 0 ||
+     pending_inc.new_pools[pool_id].cache_measure == p->cache_measure)) {
+      ss << "set cache-measure for pool '" << poolstr << "'"
+         << " to " << pg_pool_t::get_cache_measure_name(measure);
+      err = 0;
+      goto reply;
+    }
+    pg_pool_t *np = pending_inc.get_new_pool(pool_id, p);
+    np->cache_measure = measure;
+    ss << "set cache-measure for pool '" << poolstr
+	<< "' to " << pg_pool_t::get_cache_measure_name(measure);
+    wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, ss.str(),
+					      get_last_committed() + 1));
+    return true;
   } else if (prefix == "osd tier add-cache") {
     err = check_cluster_features(CEPH_FEATURE_OSD_CACHEPOOL, ss);
     if (err == -EAGAIN)
author
#4 lore raw

Re: [PATCH 2/5] Mon: expose commands for temperature related setting

Thanks for reviewing. We will update and add reviewed-by after the patch accepted, the follow-up discussion is at
https://github.com/ceph/ceph/pull/4737

Quoted 216 lines · Joao Eduardo Luis

As far as I can tell, this patch can be split in two different patches:

- add hit_set_grade_decay_rate option to 'osd pool set/get'
- add 'osd tier cache-measure'

Also, for the latter we could also use an explanatory commit message.

Aside from that, I don't see anything obviously wrong with the patch.

-Joao

Quoted 188 lines · Li Wang

From: MingXin Liu <[email protected]>

---
  src/mon/MonCommands.h |  8 +++--
  src/mon/OSDMonitor.cc | 87 ++++++++++++++++++++++++++++++++++++++++++++++++---
  2 files changed, 88 insertions(+), 7 deletions(-)
src/mon/MonCommands.h +6 -2
index 8a36807..b26834d 100644
@@ -639,11 +639,11 @@ COMMAND("osd pool rename " \
  	"rename <srcpool> to <destpool>", "osd", "rw", "cli,rest")
  COMMAND("osd pool get " \
  	"name=pool,type=CephPoolname " \
-	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|auid|target_max_objects|target_max_bytes|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|erasure_code_profile|min_read_recency_for_promote|write_fadvise_dontneed|all", \
+	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|auid|target_max_objects|target_max_bytes|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|erasure_code_profile|min_read_recency_for_promote|write_fadvise_dontneed|hit_set_grade_decay_rate|all", \
  	"get pool parameter <var>", "osd", "r", "cli,rest")
  COMMAND("osd pool set " \
  	"name=pool,type=CephPoolname " \
-	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool|nodelete|nopgchange|nosizechange|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote|write_fadvise_dontneed " \
+	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool|nodelete|nopgchange|nosizechange|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote|write_fadvise_dontneed|hit_set_grade_decay_rate " \
  	"name=val,type=CephString " \
  	"name=force,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
  	"set pool parameter <var> to <val>", "osd", "rw", "cli,rest")
@@ -695,6 +695,10 @@ COMMAND("osd tier cache-mode " \
  	"name=pool,type=CephPoolname " \
  	"name=mode,type=CephChoices,strings=none|writeback|forward|readonly|readforward|readproxy", \
  	"specify the caching mode for cache tier <pool>", "osd", "rw", "cli,rest")
+COMMAND("osd tier cache-measure " \
+        "name=pool,type=CephPoolname " \
+        "name=measure,type=CephChoices,strings=atime|temperature", \
+        "specify the caching measure to judge hot objects for cache tier <pool>", "osd", "rw", "cli,rest")
  COMMAND("osd tier set-overlay " \
  	"name=pool,type=CephPoolname " \
  	"name=overlaypool,type=CephPoolname", \
src/mon/OSDMonitor.cc +75 -5
index 10597d0..0374778 100644
@@ -2803,7 +2803,7 @@ namespace {
      CACHE_TARGET_DIRTY_RATIO, CACHE_TARGET_FULL_RATIO,
      CACHE_MIN_FLUSH_AGE, CACHE_MIN_EVICT_AGE,
      ERASURE_CODE_PROFILE, MIN_READ_RECENCY_FOR_PROMOTE,
-    WRITE_FADVISE_DONTNEED};
+    WRITE_FADVISE_DONTNEED, HIT_SET_GRADE_DECAY_RATE};
 
    std::set<osd_pool_get_choices>
      subtract_second_from_first(const std::set<osd_pool_get_choices>& first,
@@ -3251,7 +3251,8 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
        ("cache_min_evict_age", CACHE_MIN_EVICT_AGE)
        ("erasure_code_profile", ERASURE_CODE_PROFILE)
        ("min_read_recency_for_promote", MIN_READ_RECENCY_FOR_PROMOTE)
-      ("write_fadvise_dontneed", WRITE_FADVISE_DONTNEED);
+      ("write_fadvise_dontneed", WRITE_FADVISE_DONTNEED)
+      ("hit_set_grade_decay_rate", HIT_SET_GRADE_DECAY_RATE);
 
      typedef std::set<osd_pool_get_choices> choices_set_t;
 
@@ -3259,7 +3260,7 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
        (HIT_SET_TYPE)(HIT_SET_PERIOD)(HIT_SET_COUNT)(HIT_SET_FPP)
        (TARGET_MAX_OBJECTS)(TARGET_MAX_BYTES)(CACHE_TARGET_FULL_RATIO)
        (CACHE_TARGET_DIRTY_RATIO)(CACHE_MIN_FLUSH_AGE)(CACHE_MIN_EVICT_AGE)
-      (MIN_READ_RECENCY_FOR_PROMOTE);
+      (MIN_READ_RECENCY_FOR_PROMOTE)(HIT_SET_GRADE_DECAY_RATE);
 
      const choices_set_t ONLY_ERASURE_CHOICES = boost::assign::list_of
        (ERASURE_CODE_PROFILE);
@@ -3389,6 +3390,10 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
  	    f->dump_int("min_read_recency_for_promote",
  			p->min_read_recency_for_promote);
  	    break;
+	  case HIT_SET_GRADE_DECAY_RATE:
+	    f->dump_int("hit_set_priority_decacy_rate",
+			p->hit_set_grade_decay_rate);
+	    break;
  	  case WRITE_FADVISE_DONTNEED:
  	    f->dump_string("write_fadvise_dontneed",
  			   p->has_flag(pg_pool_t::FLAG_WRITE_FADVISE_DONTNEED) ?
@@ -3476,6 +3481,10 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
  	    ss << "min_read_recency_for_promote: " <<
  	      p->min_read_recency_for_promote << "\n";
  	    break;
+	  case HIT_SET_GRADE_DECAY_RATE:
+	    ss << "hit_set_grade_decay_rate: " <<
+	      p->hit_set_grade_decay_rate << "\n";
+	    break;
  	  case WRITE_FADVISE_DONTNEED:
  	    ss << "write_fadvise_dontneed: " <<
  	      (p->has_flag(pg_pool_t::FLAG_WRITE_FADVISE_DONTNEED) ?
@@ -4466,7 +4475,8 @@ int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
         var == "hit_set_count" || var == "hit_set_fpp" ||
         var == "target_max_objects" || var == "target_max_bytes" ||
         var == "cache_target_full_ratio" || var == "cache_target_dirty_ratio" ||
-       var == "cache_min_flush_age" || var == "cache_min_evict_age")) {
+       var == "cache_min_flush_age" || var == "cache_min_evict_age" ||
+       var == "hit_set_grade_decay_rate")) {
      ss << "pool '" << poolstr << "' is not a tier pool: variable not applicable";
      return -EACCES;
    }
@@ -4652,12 +4662,12 @@ int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
      }
      p.hit_set_period = n;
    } else if (var == "hit_set_count") {
-
      if (interr.length()) {
        ss << "error parsing integer value '" << val << "': " << interr;
        return -EINVAL;
      }
      p.hit_set_count = n;
+    p.set_grade(p.hit_set_grade_decay_rate, n);
    } else if (var == "hit_set_fpp") {
      if (floaterr.length()) {
        ss << "error parsing floating point value '" << val << "': " << floaterr;
@@ -4723,6 +4733,17 @@ int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
        return -EINVAL;
      }
      p.min_read_recency_for_promote = n;
+  } else if (var == "hit_set_grade_decay_rate") {
+    if (interr.length()) {
+      ss << "error parsing integer value '" << val << "': " << interr;
+      return -EINVAL;
+    }
+    if (n > 100 || n < 0) {
+      ss << "value out of range,valid range is 0 - 100";
+      return -EINVAL;
+    }
+    p.hit_set_grade_decay_rate = n;
+    p.set_grade(n, p.hit_set_count);
    } else if (var == "write_fadvise_dontneed") {
      if (val == "true" || (interr.empty() && n == 1)) {
        p.flags |= pg_pool_t::FLAG_WRITE_FADVISE_DONTNEED;
@@ -6744,6 +6765,62 @@ done:
      wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, ss.str(),
  					      get_last_committed() + 1));
      return true;
+  } else if (prefix == "osd tier cache-measure") {
+    err = check_cluster_features(CEPH_FEATURE_OSD_CACHEPOOL, ss);
+    if (err == -EAGAIN)
+      goto wait;
+    if (err)
+      goto reply;
+    string poolstr;
+    cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
+    int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
+    if (pool_id < 0) {
+      ss << "unrecognized pool '" << poolstr << "'";
+      err = -ENOENT;
+      goto reply;
+    }
+    const pg_pool_t *p = osdmap.get_pg_pool(pool_id);
+    assert(p);
+    if (!p->is_tier()) {
+      ss << "pool '" << poolstr << "' is not a tier";
+      err = -EINVAL;
+      goto reply;
+    }
+    string measurestr;
+    cmd_getval(g_ceph_context, cmdmap, "measure", measurestr);
+    pg_pool_t::cache_measure_t measure = pg_pool_t::get_cache_measure_from_str(measurestr);
+    if (measure < 0) {
+      ss << "'" << measurestr << "' is not a valid cache measure";
+      err = -EINVAL;
+      goto reply;
+    }
+    if (p->grade_table.empty()) {
+      ss << "grade_table is empty,set hit_set and hit_set_decay_rate first";
+      err = -EINVAL;
+      goto reply;
+    }
+    if (p->hit_set_params.get_type() == HitSet::TYPE_NONE) {
+      ss << "hit_set_type cannot be none";
+      err = -EINVAL;
+      goto reply;
+    }
+
+    //pool already had this cache-measure set and there are no pending changes
+    if (p->cache_measure == measure &&
+    (pending_inc.new_pools.count(pool_id) == 0 ||
+     pending_inc.new_pools[pool_id].cache_measure == p->cache_measure)) {
+      ss << "set cache-measure for pool '" << poolstr << "'"
+         << " to " << pg_pool_t::get_cache_measure_name(measure);
+      err = 0;
+      goto reply;
+    }

src/mon/OSDMonitor.cc done: · line 6826

Quoted 10 lines
src/mon/OSDMonitor.cc +7 -0
+    pg_pool_t *np = pending_inc.get_new_pool(pool_id, p);
+    np->cache_measure = measure;
+    ss << "set cache-measure for pool '" << poolstr
+	<< "' to " << pg_pool_t::get_cache_measure_name(measure);
+    wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, ss.str(),
+					      get_last_committed() + 1));
+    return true;
    } else if (prefix == "osd tier add-cache") {
      err = check_cluster_features(CEPH_FEATURE_OSD_CACHEPOOL, ss);
      if (err == -EAGAIN)

--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html