]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: before rbd map, warn if the image is already mapped 16517/head
authorlijing <lijing@gohighsec.com>
Sun, 23 Jul 2017 12:52:40 +0000 (20:52 +0800)
committerlijing <lijing@gohighsec.com>
Wed, 9 Aug 2017 02:19:21 +0000 (10:19 +0800)
RBD should check if an image is already mapped before mapping one image as serveral devices.

Fixes: http://tracker.ceph.com/issues/20580
Signed-off-by: Jing Li <lijing@gohighsec.com>
src/include/krbd.h
src/krbd.cc
src/tools/rbd/action/Kernel.cc

index c6f3c9d037c03c55fb5bcf540c47dce8d5158ece..4f6da4fbfafe1e7e64da44d7ec69a3e65840e4cd 100644 (file)
@@ -45,6 +45,10 @@ namespace ceph {
 
 int krbd_showmapped(struct krbd_ctx *ctx, ceph::Formatter *f);
 
+int krbd_is_image_mapped(struct krbd_ctx *ctx, const char *poolname, 
+                         const char *imgname, const char *snapname,
+                         std::ostringstream &mapped_info, bool &is_mapped);
+
 #endif /* __cplusplus */
 
 #endif /* CEPH_KRBD_H */
index 4f8b671b429acc35cd0b45df0f10413774b08406..7c5ade3dcec0933e9124179b58b37255c6468444 100644 (file)
@@ -764,3 +764,59 @@ int krbd_showmapped(struct krbd_ctx *ctx, Formatter *f)
 {
   return dump_images(ctx, f);
 }
+
+int krbd_is_image_mapped(struct krbd_ctx *ctx, const char *poolname, 
+                         const char *imgname, const char *snapname,
+                         std::ostringstream &mapped_info, bool &is_mapped) {
+  struct udev_enumerate *enm;
+  struct udev_list_entry *l;
+  struct udev *udev = ctx->udev; 
+  const char *mapped_id, *mapped_pool, *mapped_image, *mapped_snap;
+  int r;
+  is_mapped = false;
+
+  enm = udev_enumerate_new(udev);
+  if(!enm)
+    return -ENOMEM;
+
+  r = udev_enumerate_add_match_subsystem(enm, "rbd");
+  if (r < 0)
+    goto out_enm;
+
+  r = udev_enumerate_scan_devices(enm);
+  if (r < 0)
+    goto out_enm;
+
+  udev_list_entry_foreach(l, udev_enumerate_get_list_entry(enm)) {
+    struct udev_device *dev;
+
+    dev = udev_device_new_from_syspath(udev, udev_list_entry_get_name(l));
+    if (dev) {
+      mapped_id = udev_device_get_sysname(dev);
+      mapped_pool = udev_device_get_sysattr_value(dev, "pool");
+      mapped_image = udev_device_get_sysattr_value(dev, "name");
+      mapped_snap = udev_device_get_sysattr_value(dev, "current_snap");
+      string kname = get_kernel_rbd_name(mapped_id);
+
+      udev_device_unref(dev);
+      if (mapped_pool && poolname && strcmp(mapped_pool, poolname) == 0 &&
+          mapped_image && imgname && strcmp(mapped_image, imgname) == 0) {
+        if (!snapname || snapname[0] == '\0') {
+          mapped_info << "image " << *poolname << "/" << *imgname
+                      << " already mapped as " << kname;
+          is_mapped = true;
+          goto out_enm;
+        } else if (snapname && mapped_snap &&
+                  strcmp(snapname, mapped_snap) == 0) {
+          mapped_info << "image " << *poolname << "/" << *imgname << "@"
+                     << *snapname << " already mapped as " << kname;
+          is_mapped = true;
+          goto out_enm;
+        }
+      }
+    }
+  }
+out_enm:
+  udev_enumerate_unref(enm);
+  return r;
+}
index 1f1951fc8842539b269ca3d2b00d80d4bff87623..a9ba709c93f12a6ab4ef46a36af461e6e64952c0 100644 (file)
@@ -289,9 +289,10 @@ static int do_kernel_map(const char *poolname, const char *imgname,
 {
 #if defined(WITH_KRBD)
   struct krbd_ctx *krbd;
-  std::ostringstream oss;
+  std::ostringstream oss, mapped_info;
   char *devnode;
   int r;
+  bool img_mapped;
 
   r = krbd_create_from_context(g_ceph_context, &krbd);
   if (r < 0)
@@ -312,6 +313,15 @@ static int do_kernel_map(const char *poolname, const char *imgname,
     }
   }
 
+  r = krbd_is_image_mapped(krbd, poolname, imgname, snapname,
+                          mapped_info, img_mapped);
+  if (r < 0) {
+    std::cerr << "rbd: warning: can't get image map infomation: "
+             << cpp_strerror(r) << std::endl;
+  } else if (img_mapped) {
+    std::cerr << "rbd: warning: " << mapped_info.str() << std::endl;
+  }
+
   r = krbd_map(krbd, poolname, imgname, snapname, oss.str().c_str(), &devnode);
   if (r < 0) {
     print_error_description(poolname, imgname, snapname, r);