]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/config: trim whitespace in config target 69675/head
authorNitzan Mordechai <nmordech@ibm.com>
Tue, 23 Jun 2026 10:23:54 +0000 (10:23 +0000)
committerNitzan Mordechai <nmordech@ibm.com>
Thu, 25 Jun 2026 06:52:47 +0000 (06:52 +0000)
When set\get\rm config values with leading or trailing spaces,
those spaces need to be removed before we are trying to get\set\rm
those keys.
add trim code before each approch and also for exist keys in config.

Fixes: https://tracker.ceph.com/issues/77598
Signed-off-by: Nitzan Mordechai <nmordech@ibm.com>
qa/workunits/mon/config.sh
src/mon/ConfigMap.cc
src/mon/ConfigMonitor.cc
src/test/mon/test_config_map.cc

index 10cbe5630e91db2829ef5b5d1149001cf9222262..d6c2d850f41f3d7e102883506f9f591cc7fd0228 100755 (executable)
@@ -73,6 +73,23 @@ ceph config rm client.foo debug_asok
 ceph config set client.foo debug_asok 66
 ceph config rm client.foo 'debug asok'
 
+# whitespace in who/section (e.g. "osd.0  " with stray trailing spaces)
+ceph config set 'osd.0  ' debug_asok 44
+ceph config get osd.0 debug_asok | grep 44
+while ! ceph tell osd.0 config get debug_asok | grep 44
+do
+    sleep 1
+done
+ceph config rm osd.0 debug_asok
+while ceph tell osd.0 config get debug_asok | grep 44
+do
+    sleep 1
+done
+
+ceph config set '  osd.0' debug_asok 55
+ceph config get osd.0 debug_asok | grep 55
+ceph config rm osd.0 debug_asok
+
 # help
 ceph config help debug_asok | grep debug_asok
 
index bfd837727d18a2c04f501593095d5221ef7e0518..45111a21562a600501781bc9a57635932d5e0953 100644 (file)
@@ -6,6 +6,7 @@
 #include "common/entity_name.h"
 
 #include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/trim.hpp>
 
 #define dout_subsys ceph_subsys_mon
 #undef dout_prefix
@@ -207,6 +208,7 @@ bool ConfigMap::parse_mask(
   boost::split(split, who, [](char c){ return c == '/'; });
   for (unsigned j = 0; j < split.size(); ++j) {
     auto& i = split[j];
+    boost::algorithm::trim(i);
     if (i == "global") {
       *section = "global";
       continue;
index e377008240e67257946ed08ac99a28e0bee9096c..62f38cd96bd6bf1723d6a80508d4ad9ea0e94450 100644 (file)
@@ -19,6 +19,7 @@
 #include "crush/CrushWrapper.h"
 
 #include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/trim.hpp>
 
 #define dout_subsys ceph_subsys_mon
 #undef dout_prefix
@@ -296,6 +297,7 @@ bool ConfigMonitor::preprocess_command(MonOpRequestRef op)
   } else if (prefix == "config get") {
     string who, name;
     cmd_getval(cmdmap, "who", who);
+    boost::algorithm::trim(who);
 
     EntityName entity;
     if (!entity.from_str(who) &&
index eef42de6bd1cc4527dd403a3a24a8d0cad7e94ec..f5ab05cc216c2ce5f940e92849142a10ca415f5b 100644 (file)
@@ -53,6 +53,67 @@ TEST(ConfigMap, parse_key)
   }
 }
 
+TEST(ConfigMap, parse_mask)
+{
+  {
+    std::string section;
+    OptionMask mask;
+    ASSERT_TRUE(ConfigMap::parse_mask("osd.2", &section, &mask));
+    ASSERT_EQ("osd.2", section);
+  }
+  {
+    std::string section;
+    OptionMask mask;
+    ASSERT_TRUE(ConfigMap::parse_mask("osd.2  ", &section, &mask));
+    ASSERT_EQ("osd.2", section);
+  }
+  {
+    std::string section;
+    OptionMask mask;
+    ASSERT_TRUE(ConfigMap::parse_mask("  osd.2", &section, &mask));
+    ASSERT_EQ("osd.2", section);
+  }
+  {
+    std::string section;
+    OptionMask mask;
+    ASSERT_TRUE(ConfigMap::parse_mask(" global ", &section, &mask));
+    ASSERT_EQ("global", section);
+  }
+}
+
+TEST(ConfigMap, add_option_who_whitespace)
+{
+  ConfigMap cm;
+  boost::intrusive_ptr<CephContext> cct{new CephContext(CEPH_ENTITY_TYPE_CLIENT), false};
+  auto crush = std::make_unique<CrushWrapper>();
+  crush->finalize();
+
+  int r = cm.add_option(
+    cct.get(), "debug_ms", "osd.2  ", "1/1",
+    [&](const std::string& name) {
+      return nullptr;
+    });
+  ASSERT_EQ(0, r);
+  ASSERT_EQ(1, cm.by_id.size());
+  ASSERT_EQ(1, cm.by_id["osd.2"].options.size());
+
+  EntityName n;
+  n.set(CEPH_ENTITY_TYPE_OSD, "2");
+  auto c = cm.generate_entity_map(n, {}, crush.get(), "none", nullptr);
+  ASSERT_EQ(1, c.size());
+  ASSERT_EQ("1/1", c["debug_ms"]);
+
+  r = cm.add_option(
+    cct.get(), "foo", "osd.2", "clean",
+    [&](const std::string& name) {
+      return nullptr;
+    });
+  ASSERT_EQ(0, r);
+
+  ASSERT_EQ(1, cm.by_id.size());
+  ASSERT_EQ(2, cm.by_id["osd.2"].options.size());
+}
+
 TEST(ConfigMap, add_option)
 {
   ConfigMap cm;