From: Ilya Dryomov Date: Sat, 11 Apr 2015 10:07:49 +0000 (+0300) Subject: krbd: add krbd_unmap_by_spec() X-Git-Tag: v9.0.1~111^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=087ed0634031e86ef78f575be305c5742d07104f;p=ceph.git krbd: add krbd_unmap_by_spec() Make unmapping by (pool, image, snap) spec possible. For specs mapped multiple times unmap one device per krbd_unmap_by_spec() call. Signed-off-by: Ilya Dryomov --- diff --git a/src/include/krbd.h b/src/include/krbd.h index 702a76dbc6ac..656512f99c38 100644 --- a/src/include/krbd.h +++ b/src/include/krbd.h @@ -27,6 +27,8 @@ int krbd_map(struct krbd_ctx *ctx, const char *pool, const char *image, const char *snap, const char *options, char **pdevnode); int krbd_unmap(struct krbd_ctx *ctx, const char *devnode); +int krbd_unmap_by_spec(struct krbd_ctx *ctx, const char *pool, + const char *image, const char *snap); #ifdef __cplusplus } diff --git a/src/krbd.cc b/src/krbd.cc index da426b188c6e..33990bceaf62 100644 --- a/src/krbd.cc +++ b/src/krbd.cc @@ -375,6 +375,89 @@ out_enm: return r; } +static int spec_to_devno_and_krbd_id(struct udev *udev, const char *pool, + const char *image, const char *snap, + dev_t *pdevno, string *pid) +{ + struct udev_enumerate *enm; + struct udev_list_entry *l; + struct udev_device *dev; + unsigned int maj, min = 0; + string err; + int r; + + 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_add_match_sysattr(enm, "pool", pool); + if (r < 0) + goto out_enm; + + r = udev_enumerate_add_match_sysattr(enm, "name", image); + if (r < 0) + goto out_enm; + + r = udev_enumerate_add_match_sysattr(enm, "current_snap", snap); + if (r < 0) + goto out_enm; + + r = udev_enumerate_scan_devices(enm); + if (r < 0) + goto out_enm; + + l = udev_enumerate_get_list_entry(enm); + if (!l) { + r = -ENOENT; + goto out_enm; + } + + dev = udev_device_new_from_syspath(udev, udev_list_entry_get_name(l)); + if (!dev) { + r = -ENOMEM; + goto out_enm; + } + + maj = strict_strtoll(udev_device_get_sysattr_value(dev, "major"), 10, &err); + if (!err.empty()) { + cerr << "rbd: couldn't parse major: " << err << std::endl; + r = -EINVAL; + goto out_dev; + } + if (have_minor_attr()) { + min = strict_strtoll(udev_device_get_sysattr_value(dev, "minor"), 10, &err); + if (!err.empty()) { + cerr << "rbd: couldn't parse minor: " << err << std::endl; + r = -EINVAL; + goto out_dev; + } + } + + /* + * If an image is mapped more than once don't bother trying to unmap + * all devices - let users run unmap the same number of times they + * ran map. + */ + if (udev_list_entry_get_next(l)) + cerr << "rbd: " << pool << "/" << image << "@" << snap + << ": mapped more than once, unmapping " + << get_kernel_rbd_name(udev_device_get_sysname(dev)) + << " only" << std::endl; + + *pdevno = makedev(maj, min); + *pid = udev_device_get_sysname(dev); + +out_dev: + udev_device_unref(dev); +out_enm: + udev_enumerate_unref(enm); + return r; +} + static int wait_for_udev_remove(struct udev_monitor *mon, dev_t devno) { for (;;) { @@ -494,6 +577,30 @@ static int unmap_image(struct krbd_ctx *ctx, const char *devnode) return do_unmap(ctx->udev, wholedevno, id); } +static int unmap_image(struct krbd_ctx *ctx, const char *pool, + const char *image, const char *snap) + +{ + dev_t devno; + string id; + int r; + + if (!snap) + snap = "-"; + + r = spec_to_devno_and_krbd_id(ctx->udev, pool, image, snap, &devno, &id); + if (r < 0) { + if (r == -ENOENT) { + cerr << "rbd: " << pool << "/" << image << "@" << snap + << ": not a mapped image or snapshot" << std::endl; + r = -EINVAL; + } + return r; + } + + return do_unmap(ctx->udev, devno, id); +} + static void dump_one_image(Formatter *f, TextTable *tbl, const char *id, const char *pool, const char *image, const char *snap) @@ -636,6 +743,12 @@ extern "C" int krbd_unmap(struct krbd_ctx *ctx, const char *devnode) return unmap_image(ctx, devnode); } +extern "C" int krbd_unmap_by_spec(struct krbd_ctx *ctx, const char *pool, + const char *image, const char *snap) +{ + return unmap_image(ctx, pool, image, snap); +} + int krbd_showmapped(struct krbd_ctx *ctx, Formatter *f) { return dump_images(ctx, f);