]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore/spdk: Fix the overflow error of parsing spdk coremask 32440/head
authorChunsong Feng <fengchunsong@huawei.com>
Thu, 19 Dec 2019 09:32:09 +0000 (17:32 +0800)
committerluo rixin <luorixin@huawei.com>
Mon, 9 Mar 2020 01:43:41 +0000 (09:43 +0800)
coremask supports up to 256 bits in DPDK19.05, but the use of stoll in
NVMEManager::try_get limits the maximum use to 64 bits. Parse coremask by
hex character from low to high.

Fixes: https://tracker.ceph.com/issues/43044
Signed-off-by: Hu Ye <yehu5@huawei.com>
Signed-off-by: Chunsong Feng <fengchunsong@huawei.com>
Signed-off-by: luo rixin <luorixin@huawei.com>
src/os/bluestore/NVMEDevice.cc

index bef0c6357605b50aed315baf5d68de1e22eba76e..ce6dd5bb5c6e471b03ba9a124e2c0070b12f30cf 100644 (file)
@@ -550,6 +550,35 @@ static void attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
   ctx->manager->register_ctrlr(ctx->trid, ctrlr, &ctx->driver);
 }
 
+static int hex2dec(unsigned char c)
+{
+  if (isdigit(c))
+    return c - '0';
+  else if (isupper(c))
+    return c - 'A' + 10;
+  else
+    return c - 'a' + 10;
+}
+
+static int find_first_bitset(const string& s)
+{
+  auto e = s.rend();
+  if (s.compare(0, 2, "0x") == 0 ||
+      s.compare(0, 2, "0X") == 0) {
+    advance(e, -2);
+  }
+  auto p = s.rbegin();
+  for (int pos = 0; p != e; ++p, pos += 4) {
+    if (!isxdigit(*p)) {
+      return -EINVAL;
+    }
+    if (int val = hex2dec(*p); val != 0) {
+      return pos + ffs(val);
+    }
+  }
+  return 0;
+}
+
 int NVMEManager::try_get(const spdk_nvme_transport_id& trid, SharedDriverData **driver)
 {
   std::lock_guard l(lock);
@@ -561,17 +590,9 @@ int NVMEManager::try_get(const spdk_nvme_transport_id& trid, SharedDriverData **
   }
 
   auto coremask_arg = g_conf().get_val<std::string>("bluestore_spdk_coremask");
-  int m_core_arg = -1;
-  try {
-    auto core_value = stoull(coremask_arg, nullptr, 16);
-    m_core_arg = ffsll(core_value);
-  } catch (const std::logic_error& e) {
-    derr << __func__ << " invalid bluestore_spdk_coremask: "
-        << coremask_arg << dendl;
-    return -EINVAL;
-  }
+  int m_core_arg = find_first_bitset(coremask_arg);
   // at least one core is needed for using spdk
-  if (m_core_arg == 0) {
+  if (m_core_arg <= 0) {
     derr << __func__ << " invalid bluestore_spdk_coremask, "
         << "at least one core is needed" << dendl;
     return -ENOENT;