1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
8 #include "include/stringify.h"
9 #include "common/SubProcess.h"
11 #include "tools/rbd/ArgumentTypes.h"
12 #include "tools/rbd/Shell.h"
13 #include "tools/rbd/Utils.h"
15 #include <boost/algorithm/string/predicate.hpp>
16 #include <boost/scope_exit.hpp>
17 #include <boost/program_options.hpp>
25 namespace at
= argument_types
;
26 namespace po
= boost::program_options
;
28 static int call_ggate_cmd(const po::variables_map
&vm
,
29 const std::vector
<const char*> &args
)
31 SubProcess
process("rbd-ggate", SubProcess::KEEP
, SubProcess::KEEP
,
34 if (vm
.count("conf")) {
35 process
.add_cmd_arg("--conf");
36 process
.add_cmd_arg(vm
["conf"].as
<std::string
>().c_str());
38 if (vm
.count("cluster")) {
39 process
.add_cmd_arg("--cluster");
40 process
.add_cmd_arg(vm
["cluster"].as
<std::string
>().c_str());
43 process
.add_cmd_arg("--id");
44 process
.add_cmd_arg(vm
["id"].as
<std::string
>().c_str());
46 if (vm
.count("name")) {
47 process
.add_cmd_arg("--name");
48 process
.add_cmd_arg(vm
["name"].as
<std::string
>().c_str());
50 if (vm
.count("mon_host")) {
51 process
.add_cmd_arg("--mon_host");
52 process
.add_cmd_arg(vm
["mon_host"].as
<std::string
>().c_str());
54 if (vm
.count("keyfile")) {
55 process
.add_cmd_arg("--keyfile");
56 process
.add_cmd_arg(vm
["keyfile"].as
<std::string
>().c_str());
58 if (vm
.count("keyring")) {
59 process
.add_cmd_arg("--keyring");
60 process
.add_cmd_arg(vm
["keyring"].as
<std::string
>().c_str());
63 for (std::vector
<const char*>::const_iterator p
= args
.begin();
65 process
.add_cmd_arg(*p
);
67 if (process
.spawn()) {
68 std::cerr
<< "rbd: failed to run rbd-ggate: " << process
.err() << std::endl
;
70 } else if (process
.join()) {
71 std::cerr
<< "rbd: rbd-ggate failed with error: " << process
.err()
79 void get_list_arguments(po::options_description
*positional
,
80 po::options_description
*options
)
83 int execute_list(const po::variables_map
&vm
)
85 std::vector
<const char*> args
;
87 args
.push_back("list");
89 return call_ggate_cmd(vm
, args
);
92 void get_map_arguments(po::options_description
*positional
,
93 po::options_description
*options
)
95 at::add_image_or_snap_spec_options(positional
, options
,
96 at::ARGUMENT_MODIFIER_NONE
);
97 options
->add_options()
98 ("read-only", po::bool_switch(), "map read-only")
99 ("exclusive", po::bool_switch(), "forbid writes by other clients")
100 ("device", po::value
<std::string
>(), "specify ggate device");
103 int execute_map(const po::variables_map
&vm
)
105 size_t arg_index
= 0;
106 std::string pool_name
;
107 std::string image_name
;
108 std::string snap_name
;
109 int r
= utils::get_pool_image_snapshot_names(
110 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, &pool_name
, &image_name
,
111 &snap_name
, utils::SNAPSHOT_PRESENCE_PERMITTED
,
112 utils::SPEC_VALIDATION_NONE
);
117 std::vector
<const char*> args
;
119 args
.push_back("map");
121 img
.append(pool_name
);
123 img
.append(image_name
);
124 if (!snap_name
.empty()) {
126 img
.append(snap_name
);
128 args
.push_back(img
.c_str());
130 if (vm
["read-only"].as
<bool>())
131 args
.push_back("--read-only");
133 if (vm
["exclusive"].as
<bool>())
134 args
.push_back("--exclusive");
136 if (vm
.count("device")) {
137 args
.push_back("--device");
138 args
.push_back(vm
["device"].as
<std::string
>().c_str());
141 return call_ggate_cmd(vm
, args
);
144 void get_unmap_arguments(po::options_description
*positional
,
145 po::options_description
*options
)
147 positional
->add_options()
148 ("device-spec", "specify ggate device");
151 int execute_unmap(const po::variables_map
&vm
)
153 std::string device_name
= utils::get_positional_argument(vm
, 0);
154 if (!boost::starts_with(device_name
, "/dev/")) {
158 if (device_name
.empty()) {
159 std::cerr
<< "rbd: ggate unmap requires device path" << std::endl
;
163 std::vector
<const char*> args
;
165 args
.push_back("unmap");
166 args
.push_back(device_name
.c_str());
168 return call_ggate_cmd(vm
, args
);
171 Shell::SwitchArguments
switched_arguments({"read-only", "exclusive"});
173 Shell::Action
action_list(
174 {"ggate", "list"}, {"ggate", "ls"}, "List mapped ggate devices.", "",
175 &get_list_arguments
, &execute_list
);
177 Shell::Action
action_map(
178 {"ggate", "map"}, {}, "Map an image to a ggate device.", "",
179 &get_map_arguments
, &execute_map
);
181 Shell::Action
action_unmap(
182 {"ggate", "unmap"}, {}, "Unmap a ggate device.", "",
183 &get_unmap_arguments
, &execute_unmap
);
186 } // namespace action