1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 #include "tools/rbd/ArgumentTypes.h"
6 #include "tools/rbd/Shell.h"
8 #include <boost/program_options.hpp>
10 #include "include/ceph_assert.h"
15 namespace at
= argument_types
;
16 namespace po
= boost::program_options
;
18 #define DECLARE_DEVICE_OPERATIONS(ns) \
20 int execute_list(const po::variables_map &vm, \
21 const std::vector<std::string> &ceph_global_args); \
22 int execute_map(const po::variables_map &vm, \
23 const std::vector<std::string> &ceph_global_args); \
24 int execute_unmap(const po::variables_map &vm, \
25 const std::vector<std::string> &ceph_global_args); \
26 int execute_attach(const po::variables_map &vm, \
27 const std::vector<std::string> &ceph_global_args); \
28 int execute_detach(const po::variables_map &vm, \
29 const std::vector<std::string> &ceph_global_args); \
32 DECLARE_DEVICE_OPERATIONS(ggate
);
33 DECLARE_DEVICE_OPERATIONS(kernel
);
34 DECLARE_DEVICE_OPERATIONS(nbd
);
35 DECLARE_DEVICE_OPERATIONS(wnbd
);
41 struct DeviceOperations
{
42 int (*execute_list
)(const po::variables_map
&vm
,
43 const std::vector
<std::string
> &ceph_global_args
);
44 int (*execute_map
)(const po::variables_map
&vm
,
45 const std::vector
<std::string
> &ceph_global_args
);
46 int (*execute_unmap
)(const po::variables_map
&vm
,
47 const std::vector
<std::string
> &ceph_global_args
);
48 int (*execute_attach
)(const po::variables_map
&vm
,
49 const std::vector
<std::string
> &ceph_global_args
);
50 int (*execute_detach
)(const po::variables_map
&vm
,
51 const std::vector
<std::string
> &ceph_global_args
);
54 const DeviceOperations ggate_operations
= {
58 ggate::execute_attach
,
59 ggate::execute_detach
,
62 const DeviceOperations krbd_operations
= {
65 kernel::execute_unmap
,
66 kernel::execute_attach
,
67 kernel::execute_detach
,
70 const DeviceOperations nbd_operations
= {
78 const DeviceOperations wnbd_operations
= {
95 void validate(boost::any
& v
, const std::vector
<std::string
>& values
,
96 DeviceType
*target_type
, int) {
97 po::validators::check_first_occurrence(v
);
98 const std::string
&s
= po::validators::get_single_string(values
);
102 v
= boost::any(DEVICE_TYPE_WNBD
);
105 v
= boost::any(DEVICE_TYPE_NBD
);
106 } else if (s
== "ggate") {
107 v
= boost::any(DEVICE_TYPE_GGATE
);
108 } else if (s
== "krbd") {
109 v
= boost::any(DEVICE_TYPE_KRBD
);
112 throw po::validation_error(po::validation_error::invalid_option_value
);
116 void add_device_type_option(po::options_description
*options
) {
117 options
->add_options()
118 ("device-type,t", po::value
<DeviceType
>(),
120 "device type [wnbd]");
122 "device type [ggate, krbd (default), nbd]");
126 void add_device_specific_options(po::options_description
*options
) {
127 options
->add_options()
128 ("options,o", po::value
<std::vector
<std::string
>>(),
129 "device specific options");
132 device_type_t
get_device_type(const po::variables_map
&vm
) {
133 if (vm
.count("device-type")) {
134 return vm
["device-type"].as
<device_type_t
>();
137 return DEVICE_TYPE_KRBD
;
139 return DEVICE_TYPE_WNBD
;
143 const DeviceOperations
*get_device_operations(const po::variables_map
&vm
) {
144 switch (get_device_type(vm
)) {
145 case DEVICE_TYPE_GGATE
:
146 return &ggate_operations
;
147 case DEVICE_TYPE_KRBD
:
148 return &krbd_operations
;
149 case DEVICE_TYPE_NBD
:
150 return &nbd_operations
;
151 case DEVICE_TYPE_WNBD
:
152 return &wnbd_operations
;
159 } // anonymous namespace
161 void get_list_arguments(po::options_description
*positional
,
162 po::options_description
*options
) {
163 add_device_type_option(options
);
164 at::add_format_options(options
);
167 int execute_list(const po::variables_map
&vm
,
168 const std::vector
<std::string
> &ceph_global_init_args
) {
169 return (*get_device_operations(vm
)->execute_list
)(vm
, ceph_global_init_args
);
172 void get_map_arguments(po::options_description
*positional
,
173 po::options_description
*options
) {
174 add_device_type_option(options
);
175 at::add_image_or_snap_spec_options(positional
, options
,
176 at::ARGUMENT_MODIFIER_NONE
);
177 options
->add_options()
178 ("show-cookie", po::bool_switch(), "show device cookie")
179 ("cookie", po::value
<std::string
>(), "specify device cookie")
180 ("read-only", po::bool_switch(), "map read-only")
181 ("exclusive", po::bool_switch(), "disable automatic exclusive lock transitions")
182 ("quiesce", po::bool_switch(), "use quiesce hooks")
183 ("quiesce-hook", po::value
<std::string
>(), "quiesce hook path");
184 add_device_specific_options(options
);
187 int execute_map(const po::variables_map
&vm
,
188 const std::vector
<std::string
> &ceph_global_init_args
) {
189 return (*get_device_operations(vm
)->execute_map
)(vm
, ceph_global_init_args
);
192 void get_unmap_arguments(po::options_description
*positional
,
193 po::options_description
*options
) {
194 add_device_type_option(options
);
195 positional
->add_options()
196 ("image-or-snap-or-device-spec",
197 "image, snapshot, or device specification\n"
198 "[<pool-name>/]<image-name>[@<snap-name>] or <device-path>");
199 at::add_pool_option(options
, at::ARGUMENT_MODIFIER_NONE
);
200 at::add_image_option(options
, at::ARGUMENT_MODIFIER_NONE
);
201 at::add_snap_option(options
, at::ARGUMENT_MODIFIER_NONE
);
202 add_device_specific_options(options
);
205 int execute_unmap(const po::variables_map
&vm
,
206 const std::vector
<std::string
> &ceph_global_init_args
) {
207 return (*get_device_operations(vm
)->execute_unmap
)(vm
, ceph_global_init_args
);
210 void get_attach_arguments(po::options_description
*positional
,
211 po::options_description
*options
) {
212 add_device_type_option(options
);
213 at::add_image_or_snap_spec_options(positional
, options
,
214 at::ARGUMENT_MODIFIER_NONE
);
215 options
->add_options()
216 ("device", po::value
<std::string
>()->required(), "specify device path")
217 ("show-cookie", po::bool_switch(), "show device cookie")
218 ("cookie", po::value
<std::string
>(), "specify device cookie")
219 ("read-only", po::bool_switch(), "attach read-only")
220 ("force", po::bool_switch(), "force attach")
221 ("exclusive", po::bool_switch(), "disable automatic exclusive lock transitions")
222 ("quiesce", po::bool_switch(), "use quiesce hooks")
223 ("quiesce-hook", po::value
<std::string
>(), "quiesce hook path");
224 add_device_specific_options(options
);
227 int execute_attach(const po::variables_map
&vm
,
228 const std::vector
<std::string
> &ceph_global_init_args
) {
229 return (*get_device_operations(vm
)->execute_attach
)(vm
, ceph_global_init_args
);
232 void get_detach_arguments(po::options_description
*positional
,
233 po::options_description
*options
) {
234 add_device_type_option(options
);
235 positional
->add_options()
236 ("image-or-snap-or-device-spec",
237 "image, snapshot, or device specification\n"
238 "[<pool-name>/]<image-name>[@<snap-name>] or <device-path>");
239 at::add_pool_option(options
, at::ARGUMENT_MODIFIER_NONE
);
240 at::add_image_option(options
, at::ARGUMENT_MODIFIER_NONE
);
241 at::add_snap_option(options
, at::ARGUMENT_MODIFIER_NONE
);
242 add_device_specific_options(options
);
245 int execute_detach(const po::variables_map
&vm
,
246 const std::vector
<std::string
> &ceph_global_init_args
) {
247 return (*get_device_operations(vm
)->execute_detach
)(vm
, ceph_global_init_args
);
250 Shell::SwitchArguments
switched_arguments({"exclusive", "force", "quiesce",
251 "read-only", "show-cookie"});
253 Shell::Action
action_list(
254 {"device", "list"}, {"showmapped"}, "List mapped rbd images.", "",
255 &get_list_arguments
, &execute_list
);
256 // yet another alias for list command
257 Shell::Action
action_ls(
258 {"device", "ls"}, {}, "List mapped rbd images.", "",
259 &get_list_arguments
, &execute_list
, false);
261 Shell::Action
action_map(
262 {"device", "map"}, {"map"}, "Map an image to a block device.", "",
263 &get_map_arguments
, &execute_map
);
265 Shell::Action
action_unmap(
266 {"device", "unmap"}, {"unmap"}, "Unmap a rbd device.", "",
267 &get_unmap_arguments
, &execute_unmap
);
269 Shell::Action
action_attach(
270 {"device", "attach"}, {}, "Attach image to device.", "",
271 &get_attach_arguments
, &execute_attach
);
273 Shell::Action
action_detach(
274 {"device", "detach"}, {}, "Detach image from device.", "",
275 &get_detach_arguments
, &execute_detach
);
277 } // namespace device
278 } // namespace action