mirror of
https://github.com/ceph/ceph
synced 2025-04-10 19:53:05 +00:00
rbd: before rbd map, warn if the image is already mapped
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>
This commit is contained in:
parent
27c1d62ae9
commit
d6a66fc8f4
@ -45,6 +45,10 @@ namespace ceph {
|
|||||||
|
|
||||||
int krbd_showmapped(struct krbd_ctx *ctx, ceph::Formatter *f);
|
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 /* __cplusplus */
|
||||||
|
|
||||||
#endif /* CEPH_KRBD_H */
|
#endif /* CEPH_KRBD_H */
|
||||||
|
56
src/krbd.cc
56
src/krbd.cc
@ -764,3 +764,59 @@ int krbd_showmapped(struct krbd_ctx *ctx, Formatter *f)
|
|||||||
{
|
{
|
||||||
return dump_images(ctx, 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;
|
||||||
|
}
|
||||||
|
@ -289,9 +289,10 @@ static int do_kernel_map(const char *poolname, const char *imgname,
|
|||||||
{
|
{
|
||||||
#if defined(WITH_KRBD)
|
#if defined(WITH_KRBD)
|
||||||
struct krbd_ctx *krbd;
|
struct krbd_ctx *krbd;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss, mapped_info;
|
||||||
char *devnode;
|
char *devnode;
|
||||||
int r;
|
int r;
|
||||||
|
bool img_mapped;
|
||||||
|
|
||||||
r = krbd_create_from_context(g_ceph_context, &krbd);
|
r = krbd_create_from_context(g_ceph_context, &krbd);
|
||||||
if (r < 0)
|
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);
|
r = krbd_map(krbd, poolname, imgname, snapname, oss.str().c_str(), &devnode);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
print_error_description(poolname, imgname, snapname, r);
|
print_error_description(poolname, imgname, snapname, r);
|
||||||
|
Loading…
Reference in New Issue
Block a user