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 "common/errno.h"
11 #include <boost/program_options.hpp>
17 namespace at
= argument_types
;
18 namespace po
= boost::program_options
;
20 void get_arguments(po::options_description
*positional
,
21 po::options_description
*options
, bool enabled
) {
22 at::add_image_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
);
23 positional
->add_options()
24 ("features", po::value
<at::ImageFeatures
>()->multitoken(),
25 ("image features\n" + at::get_short_features_help(false)).c_str());
27 at::add_create_journal_options(options
);
31 void get_arguments_disable(po::options_description
*positional
,
32 po::options_description
*options
) {
33 get_arguments(positional
, options
, false);
36 void get_arguments_enable(po::options_description
*positional
,
37 po::options_description
*options
) {
38 get_arguments(positional
, options
, true);
41 int execute(const po::variables_map
&vm
, bool enabled
) {
43 std::string pool_name
;
44 std::string image_name
;
45 std::string snap_name
;
46 int r
= utils::get_pool_image_snapshot_names(
47 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, &pool_name
, &image_name
,
48 &snap_name
, utils::SNAPSHOT_PRESENCE_NONE
, utils::SPEC_VALIDATION_NONE
);
53 librbd::ImageOptions opts
;
54 r
= utils::get_journal_options(vm
, &opts
);
59 std::vector
<std::string
> feature_names
;
60 if (vm
.count(at::POSITIONAL_ARGUMENTS
)) {
61 const std::vector
<std::string
> &args
=
62 vm
[at::POSITIONAL_ARGUMENTS
].as
<std::vector
<std::string
> >();
63 feature_names
.insert(feature_names
.end(), args
.begin() + arg_index
,
67 if (feature_names
.empty()) {
68 std::cerr
<< "rbd: at least one feature name must be specified"
73 boost::any
features_any(static_cast<uint64_t>(0));
74 at::ImageFeatures image_features
;
75 at::validate(features_any
, feature_names
, &image_features
, 0);
77 librados::Rados rados
;
78 librados::IoCtx io_ctx
;
80 r
= utils::init_and_open_image(pool_name
, image_name
, "", "", false,
81 &rados
, &io_ctx
, &image
);
86 r
= image
.update_features(boost::any_cast
<uint64_t>(features_any
), enabled
);
88 std::cerr
<< "rbd: failed to update image features: " << cpp_strerror(r
)
95 int execute_disable(const po::variables_map
&vm
) {
96 return execute(vm
, false);
99 int execute_enable(const po::variables_map
&vm
) {
100 return execute(vm
, true);
103 Shell::Action
action_disable(
104 {"feature", "disable"}, {}, "Disable the specified image feature.", "",
105 &get_arguments_disable
, &execute_disable
);
106 Shell::Action
action_enable(
107 {"feature", "enable"}, {}, "Enable the specified image feature.", "",
108 &get_arguments_enable
, &execute_enable
);
110 } // namespace feature
111 } // namespace action