]>
git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd/action/List.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "tools/rbd/ArgumentTypes.h"
5 #include "tools/rbd/Shell.h"
6 #include "tools/rbd/Utils.h"
7 #include "include/stringify.h"
8 #include "include/types.h"
9 #include "common/errno.h"
10 #include "common/Formatter.h"
11 #include "common/TextTable.h"
13 #include <boost/program_options.hpp>
19 namespace at
= argument_types
;
20 namespace po
= boost::program_options
;
22 int do_list(librbd::RBD
&rbd
, librados::IoCtx
& io_ctx
, bool lflag
,
24 std::vector
<std::string
> names
;
25 int r
= rbd
.list(io_ctx
, names
);
31 f
->open_array_section("images");
32 for (std::vector
<std::string
>::const_iterator i
= names
.begin();
33 i
!= names
.end(); ++i
) {
35 f
->dump_string("name", *i
);
37 std::cout
<< *i
<< std::endl
;
49 f
->open_array_section("images");
51 tbl
.define_column("NAME", TextTable::LEFT
, TextTable::LEFT
);
52 tbl
.define_column("SIZE", TextTable::RIGHT
, TextTable::RIGHT
);
53 tbl
.define_column("PARENT", TextTable::LEFT
, TextTable::LEFT
);
54 tbl
.define_column("FMT", TextTable::RIGHT
, TextTable::RIGHT
);
55 tbl
.define_column("PROT", TextTable::LEFT
, TextTable::LEFT
);
56 tbl
.define_column("LOCK", TextTable::LEFT
, TextTable::LEFT
);
59 std::string pool
, image
, snap
, parent
;
61 for (std::vector
<std::string
>::const_iterator i
= names
.begin();
62 i
!= names
.end(); ++i
) {
63 librbd::image_info_t info
;
66 r
= rbd
.open_read_only(io_ctx
, im
, i
->c_str(), NULL
);
67 // image might disappear between rbd.list() and rbd.open(); ignore
68 // that, warn about other possible errors (EPERM, say, for opening
69 // an old-format image, because you need execute permission for the
73 std::cerr
<< "rbd: error opening " << *i
<< ": " << cpp_strerror(r
)
76 // in any event, continue to next image
80 // handle second-nth trips through loop
82 r
= im
.parent_info(&pool
, &image
, &snap
);
83 if (r
< 0 && r
!= -ENOENT
)
85 bool has_parent
= false;
87 parent
= pool
+ "/" + image
+ "@" + snap
;
91 if (im
.stat(info
, sizeof(info
)) < 0) {
97 im
.old_format(&old_format
);
99 std::list
<librbd::locker_t
> lockers
;
101 r
= im
.list_lockers(&lockers
, &exclusive
, NULL
);
105 if (!lockers
.empty()) {
106 lockstr
= (exclusive
) ? "excl" : "shr";
110 f
->open_object_section("image");
111 f
->dump_string("image", *i
);
112 f
->dump_unsigned("size", info
.size
);
114 f
->open_object_section("parent");
115 f
->dump_string("pool", pool
);
116 f
->dump_string("image", image
);
117 f
->dump_string("snapshot", snap
);
120 f
->dump_int("format", old_format
? 1 : 2);
121 if (!lockers
.empty())
122 f
->dump_string("lock_type", exclusive
? "exclusive" : "shared");
126 << stringify(si_t(info
.size
))
128 << ((old_format
) ? '1' : '2')
129 << "" // protect doesn't apply to images
131 << TextTable::endrow
;
134 std::vector
<librbd::snap_info_t
> snaplist
;
135 if (im
.snap_list(snaplist
) >= 0 && !snaplist
.empty()) {
136 for (std::vector
<librbd::snap_info_t
>::iterator s
= snaplist
.begin();
137 s
!= snaplist
.end(); ++s
) {
139 bool has_parent
= false;
141 im
.snap_set(s
->name
.c_str());
142 r
= im
.snap_is_protected(s
->name
.c_str(), &is_protected
);
145 if (im
.parent_info(&pool
, &image
, &snap
) >= 0) {
146 parent
= pool
+ "/" + image
+ "@" + snap
;
150 f
->open_object_section("snapshot");
151 f
->dump_string("image", *i
);
152 f
->dump_string("snapshot", s
->name
);
153 f
->dump_unsigned("size", s
->size
);
155 f
->open_object_section("parent");
156 f
->dump_string("pool", pool
);
157 f
->dump_string("image", image
);
158 f
->dump_string("snapshot", snap
);
161 f
->dump_int("format", old_format
? 1 : 2);
162 f
->dump_string("protected", is_protected
? "true" : "false");
165 tbl
<< *i
+ "@" + s
->name
166 << stringify(si_t(s
->size
))
168 << ((old_format
) ? '1' : '2')
169 << (is_protected
? "yes" : "")
170 << "" // locks don't apply to snaps
171 << TextTable::endrow
;
181 } else if (!names
.empty()) {
185 return r
< 0 ? r
: 0;
188 void get_arguments(po::options_description
*positional
,
189 po::options_description
*options
) {
190 options
->add_options()
191 ("long,l", po::bool_switch(), "long listing format");
192 at::add_pool_options(positional
, options
);
193 at::add_format_options(options
);
196 int execute(const po::variables_map
&vm
) {
197 size_t arg_index
= 0;
198 std::string pool_name
= utils::get_pool_name(vm
, &arg_index
);
200 at::Format::Formatter formatter
;
201 int r
= utils::get_formatter(vm
, &formatter
);
206 librados::Rados rados
;
207 librados::IoCtx io_ctx
;
208 r
= utils::init(pool_name
, &rados
, &io_ctx
);
214 r
= do_list(rbd
, io_ctx
, vm
["long"].as
<bool>(), formatter
.get());
216 std::cerr
<< "rbd: list: " << cpp_strerror(r
) << std::endl
;
223 Shell::SwitchArguments
switched_arguments({"long", "l"});
224 Shell::Action
action(
225 {"list"}, {"ls"}, "List rbd images.", "", &get_arguments
, &execute
);
228 } // namespace action