X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Flibrbd%2Fapi%2FImage.cc;fp=src%2Fceph%2Fsrc%2Flibrbd%2Fapi%2FImage.cc;h=27049183b65626f3f5749fa1b0f40f37cecf5aff;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/librbd/api/Image.cc b/src/ceph/src/librbd/api/Image.cc new file mode 100644 index 0000000..2704918 --- /dev/null +++ b/src/ceph/src/librbd/api/Image.cc @@ -0,0 +1,121 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/api/Image.h" +#include "include/rados/librados.hpp" +#include "common/dout.h" +#include "common/errno.h" +#include "cls/rbd/cls_rbd_client.h" +#include "librbd/ImageCtx.h" +#include "librbd/ImageState.h" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::api::Image: " << __func__ << ": " + +namespace librbd { +namespace api { + +template +int Image::list_images(librados::IoCtx& io_ctx, ImageNameToIds *images) { + CephContext *cct = (CephContext *)io_ctx.cct(); + ldout(cct, 20) << "io_ctx=" << &io_ctx << dendl; + + // new format images are accessed by class methods + int r; + int max_read = 1024; + string last_read = ""; + do { + map images_page; + r = cls_client::dir_list(&io_ctx, RBD_DIRECTORY, + last_read, max_read, &images_page); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "error listing image in directory: " + << cpp_strerror(r) << dendl; + return r; + } else if (r == -ENOENT) { + break; + } + for (map::const_iterator it = images_page.begin(); + it != images_page.end(); ++it) { + images->insert(*it); + } + if (!images_page.empty()) { + last_read = images_page.rbegin()->first; + } + r = images_page.size(); + } while (r == max_read); + + return 0; +} + +template +int Image::list_children(I *ictx, const ParentSpec &parent_spec, + PoolImageIds *pool_image_ids) +{ + CephContext *cct = ictx->cct; + int r = ictx->state->refresh_if_required(); + if (r < 0) { + return r; + } + + // no children for non-layered or old format image + if (!ictx->test_features(RBD_FEATURE_LAYERING, ictx->snap_lock)) { + return 0; + } + + pool_image_ids->clear(); + // search all pools for children depending on this snapshot + librados::Rados rados(ictx->md_ctx); + std::list > pools; + r = rados.pool_list2(pools); + if (r < 0) { + lderr(cct) << "error listing pools: " << cpp_strerror(r) << dendl; + return r; + } + + for (auto it = pools.begin(); it != pools.end(); ++it) { + int64_t base_tier; + r = rados.pool_get_base_tier(it->first, &base_tier); + if (r == -ENOENT) { + ldout(cct, 1) << "pool " << it->second << " no longer exists" << dendl; + continue; + } else if (r < 0) { + lderr(cct) << "error retrieving base tier for pool " << it->second + << dendl; + return r; + } + if (it->first != base_tier) { + // pool is a cache; skip it + continue; + } + + IoCtx ioctx; + r = rados.ioctx_create2(it->first, ioctx); + if (r == -ENOENT) { + ldout(cct, 1) << "pool " << it->second << " no longer exists" << dendl; + continue; + } else if (r < 0) { + lderr(cct) << "error accessing child image pool " << it->second + << dendl; + return r; + } + + set image_ids; + r = cls_client::get_children(&ioctx, RBD_CHILDREN, parent_spec, + image_ids); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "error reading list of children from pool " << it->second + << dendl; + return r; + } + pool_image_ids->insert({*it, image_ids}); + } + + return 0; +} + +} // namespace api +} // namespace librbd + +template class librbd::api::Image;