From: Mykola Golub Date: Thu, 5 Nov 2020 17:56:25 +0000 (+0000) Subject: rbd-nbd: always check device when searching re-attached process X-Git-Tag: v16.1.0~585^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5dd897cc4871d0d7248376ceff57ebf4410fba56;p=ceph.git rbd-nbd: always check device when searching re-attached process Previously, if the same image was mapped twice and then one wanted to re-attach it could try to use a wrong device. Also list-mapped could produce incorrect listing after re-attach. Signed-off-by: Mykola Golub --- diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index eee700a5ee8..713a0b83b63 100644 --- a/src/tools/rbd_nbd/rbd-nbd.cc +++ b/src/tools/rbd_nbd/rbd-nbd.cc @@ -815,9 +815,11 @@ private: std::map m_mapped_info_cache; int get_mapped_info(int pid, Config *cfg) { + ceph_assert(!cfg->devpath.empty()); + auto it = m_mapped_info_cache.find(pid); if (it != m_mapped_info_cache.end()) { - if (it->second.devpath.empty()) { + if (it->second.devpath != cfg->devpath) { return -EINVAL; } *cfg = it->second; @@ -868,22 +870,28 @@ private: } std::ostringstream err_msg; - r = parse_args(args, &err_msg, cfg); + Config c; + r = parse_args(args, &err_msg, &c); if (r < 0) { return r; } - if (cfg->command != Map && cfg->command != Attach) { + if (c.command != Map && c.command != Attach) { return -ENOENT; } - cfg->pid = pid; - + c.pid = pid; m_mapped_info_cache.erase(pid); - if (!cfg->devpath.empty()) { - m_mapped_info_cache[pid] = *cfg; + if (!c.devpath.empty()) { + m_mapped_info_cache[pid] = c; + if (c.devpath != cfg->devpath) { + return -ENOENT; + } + } else { + c.devpath = cfg->devpath; } + *cfg = c; return 0; } @@ -901,8 +909,8 @@ private: } Config cfg; - if (get_mapped_info(pid, &cfg) >=0 && cfg.devpath == devpath && - cfg.command == Attach) { + cfg.devpath = devpath; + if (get_mapped_info(pid, &cfg) >=0 && cfg.command == Attach) { return cfg.pid; } } @@ -1867,7 +1875,8 @@ static bool find_mapped_dev_by_spec(Config *cfg, int skip_pid=-1) { while (it.get(&c)) { if (c.pid != skip_pid && c.poolname == cfg->poolname && c.nsname == cfg->nsname && - c.imgname == cfg->imgname && c.snapname == cfg->snapname) { + c.imgname == cfg->imgname && c.snapname == cfg->snapname && + (cfg->devpath.empty() || c.devpath == cfg->devpath)) { *cfg = c; return true; } @@ -2014,7 +2023,7 @@ static int parse_args(vector& args, std::ostream *err_msg, if (cfg->devpath.empty()) { *err_msg << "rbd-nbd: must specify device to attach"; return -EINVAL; - } + } [[fallthrough]]; case Map: if (args.begin() == args.end()) {