From: Chunsong Feng Date: Thu, 19 Dec 2019 09:32:09 +0000 (+0800) Subject: os/bluestore/spdk: Fix the overflow error of parsing spdk coremask X-Git-Tag: v15.1.1~64^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d79efbabb83acf742ff565a487797eca8f5fe8ed;p=ceph.git os/bluestore/spdk: Fix the overflow error of parsing spdk coremask 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 Signed-off-by: Chunsong Feng Signed-off-by: luo rixin --- diff --git a/src/os/bluestore/NVMEDevice.cc b/src/os/bluestore/NVMEDevice.cc index bef0c6357605..ce6dd5bb5c6e 100644 --- a/src/os/bluestore/NVMEDevice.cc +++ b/src/os/bluestore/NVMEDevice.cc @@ -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("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;