mirror of
https://github.com/ceph/ceph
synced 2025-02-19 17:08: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_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 */
|
||||
|
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);
|
||||
}
|
||||
|
||||
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)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user