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