]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/api/Image.cc
update sources to v12.2.3
[ceph.git] / ceph / src / librbd / api / Image.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "librbd/api/Image.h"
5#include "include/rados/librados.hpp"
6#include "common/dout.h"
7#include "common/errno.h"
8#include "cls/rbd/cls_rbd_client.h"
9#include "librbd/ImageCtx.h"
10#include "librbd/ImageState.h"
11
12#define dout_subsys ceph_subsys_rbd
13#undef dout_prefix
14#define dout_prefix *_dout << "librbd::api::Image: " << __func__ << ": "
15
16namespace librbd {
17namespace api {
18
19template <typename I>
20int Image<I>::list_images(librados::IoCtx& io_ctx, ImageNameToIds *images) {
21 CephContext *cct = (CephContext *)io_ctx.cct();
22 ldout(cct, 20) << "io_ctx=" << &io_ctx << dendl;
23
24 // new format images are accessed by class methods
25 int r;
26 int max_read = 1024;
27 string last_read = "";
28 do {
29 map<string, string> images_page;
30 r = cls_client::dir_list(&io_ctx, RBD_DIRECTORY,
31 last_read, max_read, &images_page);
32 if (r < 0 && r != -ENOENT) {
33 lderr(cct) << "error listing image in directory: "
34 << cpp_strerror(r) << dendl;
35 return r;
36 } else if (r == -ENOENT) {
37 break;
38 }
39 for (map<string, string>::const_iterator it = images_page.begin();
40 it != images_page.end(); ++it) {
41 images->insert(*it);
42 }
43 if (!images_page.empty()) {
44 last_read = images_page.rbegin()->first;
45 }
46 r = images_page.size();
47 } while (r == max_read);
48
49 return 0;
50}
51
52template <typename I>
53int Image<I>::list_children(I *ictx, const ParentSpec &parent_spec,
54 PoolImageIds *pool_image_ids)
55{
56 CephContext *cct = ictx->cct;
7c673cae
FG
57
58 // no children for non-layered or old format image
59 if (!ictx->test_features(RBD_FEATURE_LAYERING, ictx->snap_lock)) {
60 return 0;
61 }
62
63 pool_image_ids->clear();
64 // search all pools for children depending on this snapshot
65 librados::Rados rados(ictx->md_ctx);
66 std::list<std::pair<int64_t, std::string> > pools;
b32b8144 67 int r = rados.pool_list2(pools);
7c673cae
FG
68 if (r < 0) {
69 lderr(cct) << "error listing pools: " << cpp_strerror(r) << dendl;
70 return r;
71 }
72
73 for (auto it = pools.begin(); it != pools.end(); ++it) {
74 int64_t base_tier;
75 r = rados.pool_get_base_tier(it->first, &base_tier);
76 if (r == -ENOENT) {
77 ldout(cct, 1) << "pool " << it->second << " no longer exists" << dendl;
78 continue;
79 } else if (r < 0) {
80 lderr(cct) << "error retrieving base tier for pool " << it->second
81 << dendl;
82 return r;
83 }
84 if (it->first != base_tier) {
85 // pool is a cache; skip it
86 continue;
87 }
88
89 IoCtx ioctx;
90 r = rados.ioctx_create2(it->first, ioctx);
91 if (r == -ENOENT) {
92 ldout(cct, 1) << "pool " << it->second << " no longer exists" << dendl;
93 continue;
94 } else if (r < 0) {
95 lderr(cct) << "error accessing child image pool " << it->second
96 << dendl;
97 return r;
98 }
99
100 set<string> image_ids;
101 r = cls_client::get_children(&ioctx, RBD_CHILDREN, parent_spec,
102 image_ids);
103 if (r < 0 && r != -ENOENT) {
104 lderr(cct) << "error reading list of children from pool " << it->second
105 << dendl;
106 return r;
107 }
108 pool_image_ids->insert({*it, image_ids});
109 }
110
111 return 0;
112}
113
114} // namespace api
115} // namespace librbd
116
117template class librbd::api::Image<librbd::ImageCtx>;