]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/rbd/action/Status.cc
import ceph pacific 16.2.5
[ceph.git] / ceph / src / tools / rbd / action / Status.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
f67539c2
TL
4#include "common/errno.h"
5#include "common/Formatter.h"
7c673cae
FG
6#include "tools/rbd/ArgumentTypes.h"
7#include "tools/rbd/Shell.h"
8#include "tools/rbd/Utils.h"
9#include "include/rbd_types.h"
11fdf7f2 10#include "include/stringify.h"
7c673cae
FG
11#include <iostream>
12#include <boost/program_options.hpp>
13
14namespace rbd {
15namespace action {
16namespace status {
17
18namespace at = argument_types;
19namespace po = boost::program_options;
20
f67539c2
TL
21namespace {
22
23const std::string IMAGE_CACHE_STATE = ".librbd/image_cache_state";
24
f67539c2
TL
25} // anonymous namespace
26
11fdf7f2
TL
27static int do_show_status(librados::IoCtx& io_ctx, const std::string &image_name,
28 librbd::Image &image, Formatter *f)
7c673cae 29{
7c673cae 30 int r;
11fdf7f2 31 std::list<librbd::image_watcher_t> watchers;
7c673cae 32
11fdf7f2 33 r = image.list_watchers(watchers);
7c673cae
FG
34 if (r < 0)
35 return r;
36
11fdf7f2
TL
37 uint64_t features;
38 r = image.features(&features);
39 if (r < 0) {
40 return r;
41 }
42
43 librbd::image_migration_status_t migration_status;
f67539c2 44 std::string source_spec;
11fdf7f2
TL
45 std::string source_pool_name;
46 std::string dest_pool_name;
47 std::string migration_state;
48 if ((features & RBD_FEATURE_MIGRATING) != 0) {
49 r = librbd::RBD().migration_status(io_ctx, image_name.c_str(),
50 &migration_status,
51 sizeof(migration_status));
7c673cae 52 if (r < 0) {
11fdf7f2
TL
53 std::cerr << "rbd: getting migration status failed: " << cpp_strerror(r)
54 << std::endl;
55 // not fatal
56 } else {
f67539c2
TL
57 if (migration_status.source_pool_id >= 0) {
58 librados::IoCtx src_io_ctx;
59 r = librados::Rados(io_ctx).ioctx_create2(migration_status.source_pool_id, src_io_ctx);
60 if (r < 0) {
61 source_pool_name = stringify(migration_status.source_pool_id);
62 } else {
63 source_pool_name = src_io_ctx.get_pool_name();
64 }
11fdf7f2 65 } else {
f67539c2
TL
66 r = image.get_migration_source_spec(&source_spec);
67 if (r < 0) {
68 std::cerr << "rbd: getting migration source spec failed: "
69 << cpp_strerror(r) << std::endl;
70 }
11fdf7f2 71 }
7c673cae 72
11fdf7f2
TL
73 librados::IoCtx dst_io_ctx;
74 r = librados::Rados(io_ctx).ioctx_create2(migration_status.dest_pool_id, dst_io_ctx);
75 if (r < 0) {
76 dest_pool_name = stringify(migration_status.dest_pool_id);
77 } else {
78 dest_pool_name = dst_io_ctx.get_pool_name();
79 }
7c673cae 80
11fdf7f2
TL
81 switch (migration_status.state) {
82 case RBD_IMAGE_MIGRATION_STATE_ERROR:
83 migration_state = "error";
84 break;
85 case RBD_IMAGE_MIGRATION_STATE_PREPARING:
86 migration_state = "preparing";
87 break;
88 case RBD_IMAGE_MIGRATION_STATE_PREPARED:
89 migration_state = "prepared";
90 break;
91 case RBD_IMAGE_MIGRATION_STATE_EXECUTING:
92 migration_state = "executing";
93 break;
94 case RBD_IMAGE_MIGRATION_STATE_EXECUTED:
95 migration_state = "executed";
96 break;
f91f0fd5
TL
97 case RBD_IMAGE_MIGRATION_STATE_ABORTING:
98 migration_state = "aborting";
99 break;
11fdf7f2
TL
100 default:
101 migration_state = "unknown";
102 }
103 }
104 }
7c673cae 105
b3b6e05e 106 std::string image_cache_str;
f67539c2 107 if (features & RBD_FEATURE_DIRTY_CACHE) {
f67539c2
TL
108 r = image.metadata_get(IMAGE_CACHE_STATE, &image_cache_str);
109 if (r < 0) {
b3b6e05e 110 std::cerr << "rbd: getting image cache state failed: " << cpp_strerror(r)
f67539c2 111 << std::endl;
b3b6e05e 112 // not fatal
f67539c2
TL
113 }
114 }
115
7c673cae
FG
116 if (f)
117 f->open_object_section("status");
118
119 if (f) {
120 f->open_array_section("watchers");
11fdf7f2 121 for (auto &watcher : watchers) {
7c673cae 122 f->open_object_section("watcher");
11fdf7f2
TL
123 f->dump_string("address", watcher.addr);
124 f->dump_unsigned("client", watcher.id);
125 f->dump_unsigned("cookie", watcher.cookie);
7c673cae
FG
126 f->close_section();
127 }
11fdf7f2
TL
128 f->close_section(); // watchers
129 if (!migration_state.empty()) {
130 f->open_object_section("migration");
f67539c2
TL
131 if (!source_spec.empty()) {
132 f->dump_string("source_spec", source_spec);
133 } else {
134 f->dump_string("source_pool_name", source_pool_name);
135 f->dump_string("source_pool_namespace",
136 migration_status.source_pool_namespace);
137 f->dump_string("source_image_name", migration_status.source_image_name);
138 f->dump_string("source_image_id", migration_status.source_image_id);
139 }
11fdf7f2
TL
140 f->dump_string("dest_pool_name", dest_pool_name);
141 f->dump_string("dest_pool_namespace",
142 migration_status.dest_pool_namespace);
143 f->dump_string("dest_image_name", migration_status.dest_image_name);
144 f->dump_string("dest_image_id", migration_status.dest_image_id);
145 f->dump_string("state", migration_state);
146 f->dump_string("state_description", migration_status.state_description);
147 f->close_section(); // migration
148 }
b3b6e05e
TL
149 if (!image_cache_str.empty()) {
150 f->dump_string("image_cache_state", image_cache_str);
f67539c2 151 }
7c673cae
FG
152 } else {
153 if (watchers.size()) {
154 std::cout << "Watchers:" << std::endl;
11fdf7f2
TL
155 for (auto &watcher : watchers) {
156 std::cout << "\twatcher=" << watcher.addr << " client." << watcher.id
157 << " cookie=" << watcher.cookie << std::endl;
7c673cae
FG
158 }
159 } else {
160 std::cout << "Watchers: none" << std::endl;
161 }
11fdf7f2
TL
162 if (!migration_state.empty()) {
163 if (!migration_status.source_pool_namespace.empty()) {
164 source_pool_name += ("/" + migration_status.source_pool_namespace);
165 }
166 if (!migration_status.dest_pool_namespace.empty()) {
167 dest_pool_name += ("/" + migration_status.dest_pool_namespace);
168 }
169
170 std::cout << "Migration:" << std::endl;
f67539c2
TL
171 std::cout << "\tsource: ";
172 if (!source_spec.empty()) {
173 std::cout << source_spec;
174 } else {
175 std::cout << source_pool_name << "/"
176 << migration_status.source_image_name;
177 if (!migration_status.source_image_id.empty()) {
178 std::cout << " (" << migration_status.source_image_id << ")";
179 }
11fdf7f2
TL
180 }
181 std::cout << std::endl;
182 std::cout << "\tdestination: " << dest_pool_name << "/"
183 << migration_status.dest_image_name << " ("
184 << migration_status.dest_image_id << ")" << std::endl;
185 std::cout << "\tstate: " << migration_state;
186 if (!migration_status.state_description.empty()) {
187 std::cout << " (" << migration_status.state_description << ")";
188 }
189 std::cout << std::endl;
190 }
f67539c2 191
b3b6e05e
TL
192 if (!image_cache_str.empty()) {
193 std::cout << "Image cache state: " << image_cache_str << std::endl;
f67539c2 194 }
7c673cae 195 }
11fdf7f2 196
7c673cae 197 if (f) {
11fdf7f2 198 f->close_section(); // status
7c673cae
FG
199 f->flush(std::cout);
200 }
201
202 return 0;
203}
204
205void get_arguments(po::options_description *positional,
206 po::options_description *options) {
207 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
208 at::add_format_options(options);
209}
210
11fdf7f2
TL
211int execute(const po::variables_map &vm,
212 const std::vector<std::string> &ceph_global_init_args) {
7c673cae
FG
213 size_t arg_index = 0;
214 std::string pool_name;
11fdf7f2 215 std::string namespace_name;
7c673cae
FG
216 std::string image_name;
217 std::string snap_name;
218 int r = utils::get_pool_image_snapshot_names(
11fdf7f2
TL
219 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name,
220 &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE,
221 utils::SPEC_VALIDATION_NONE);
7c673cae
FG
222 if (r < 0) {
223 return r;
224 }
225
226 at::Format::Formatter formatter;
227 r = utils::get_formatter(vm, &formatter);
228 if (r < 0) {
229 return r;
230 }
231
232 librados::Rados rados;
233 librados::IoCtx io_ctx;
234 librbd::Image image;
11fdf7f2
TL
235 r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "",
236 true, &rados, &io_ctx, &image);
7c673cae
FG
237 if (r < 0) {
238 return r;
239 }
240
11fdf7f2 241 r = do_show_status(io_ctx, image_name, image, formatter.get());
7c673cae
FG
242 if (r < 0) {
243 std::cerr << "rbd: show status failed: " << cpp_strerror(r) << std::endl;
244 return r;
245 }
246 return 0;
247}
248
249Shell::Action action(
250 {"status"}, {}, "Show the status of this image.", "", &get_arguments,
251 &execute);
252
253} // namespace status
254} // namespace action
255} // namespace rbd