]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd/action/Ggate.cc
24699b43ff8d7b7f523a4e590d1ad62196617c52
[ceph.git] / ceph / src / tools / rbd / action / Ggate.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include <sys/param.h>
5 #include <errno.h>
6 #include <unistd.h>
7
8 #include "include/stringify.h"
9 #include "common/SubProcess.h"
10
11 #include "tools/rbd/ArgumentTypes.h"
12 #include "tools/rbd/Shell.h"
13 #include "tools/rbd/Utils.h"
14
15 #include <boost/algorithm/string.hpp>
16 #include <boost/algorithm/string/predicate.hpp>
17 #include <boost/program_options.hpp>
18
19 #include <iostream>
20
21 namespace rbd {
22 namespace action {
23 namespace ggate {
24
25 namespace at = argument_types;
26 namespace po = boost::program_options;
27
28 #if defined(__FreeBSD__)
29 static int call_ggate_cmd(const po::variables_map &vm,
30 const std::vector<std::string> &args,
31 const std::vector<std::string> &ceph_global_args) {
32 SubProcess process("rbd-ggate", SubProcess::KEEP, SubProcess::KEEP,
33 SubProcess::KEEP);
34
35 for (auto &arg : ceph_global_args) {
36 process.add_cmd_arg(arg.c_str());
37 }
38
39 for (auto &arg : args) {
40 process.add_cmd_arg(arg.c_str());
41 }
42
43 if (process.spawn()) {
44 std::cerr << "rbd: failed to run rbd-ggate: " << process.err() << std::endl;
45 return -EINVAL;
46 } else if (process.join()) {
47 std::cerr << "rbd: rbd-ggate failed with error: " << process.err()
48 << std::endl;
49 return -EINVAL;
50 }
51
52 return 0;
53 }
54
55 int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) {
56 size_t arg_index = 0;
57 std::string pool_name;
58 std::string nspace_name;
59 std::string image_name;
60 std::string snap_name;
61 int r = utils::get_pool_image_snapshot_names(
62 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &nspace_name,
63 &image_name, &snap_name, true,
64 utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE);
65 if (r < 0) {
66 return r;
67 }
68
69 if (pool_name.empty()) {
70 // connect to the cluster to get the default pool
71 librados::Rados rados;
72 r = utils::init_rados(&rados);
73 if (r < 0) {
74 return r;
75 }
76
77 utils::normalize_pool_name(&pool_name);
78 }
79
80 spec->append(pool_name);
81 spec->append("/");
82 if (!nspace_name.empty()) {
83 spec->append(nspace_name);
84 spec->append("/");
85 }
86 spec->append(image_name);
87 if (!snap_name.empty()) {
88 spec->append("@");
89 spec->append(snap_name);
90 }
91
92 return 0;
93 }
94
95 int parse_options(const std::vector<std::string> &options,
96 std::vector<std::string> *args) {
97 for (auto &opts : options) {
98 std::vector<std::string> args_;
99 boost::split(args_, opts, boost::is_any_of(","));
100 for (auto &o : args_) {
101 args->push_back("--" + o);
102 }
103 }
104
105 return 0;
106 }
107 #endif
108
109 int execute_list(const po::variables_map &vm,
110 const std::vector<std::string> &ceph_global_init_args) {
111 #if !defined(__FreeBSD__)
112 std::cerr << "rbd: ggate is only supported on FreeBSD" << std::endl;
113 return -EOPNOTSUPP;
114 #else
115 std::vector<std::string> args;
116
117 args.push_back("list");
118
119 if (vm.count("format")) {
120 args.push_back("--format");
121 args.push_back(vm["format"].as<at::Format>().value);
122 }
123 if (vm["pretty-format"].as<bool>()) {
124 args.push_back("--pretty-format");
125 }
126
127 return call_ggate_cmd(vm, args, ceph_global_init_args);
128 #endif
129 }
130
131 int execute_map(const po::variables_map &vm,
132 const std::vector<std::string> &ceph_global_init_args) {
133 #if !defined(__FreeBSD__)
134 std::cerr << "rbd: ggate is only supported on FreeBSD" << std::endl;
135 return -EOPNOTSUPP;
136 #else
137 std::vector<std::string> args;
138
139 args.push_back("map");
140 std::string img;
141 int r = get_image_or_snap_spec(vm, &img);
142 if (r < 0) {
143 return r;
144 }
145 args.push_back(img);
146
147 if (vm["quiesce"].as<bool>()) {
148 std::cerr << "rbd: warning: quiesce is not supported" << std::endl;
149 }
150
151 if (vm["read-only"].as<bool>()) {
152 args.push_back("--read-only");
153 }
154
155 if (vm["exclusive"].as<bool>()) {
156 args.push_back("--exclusive");
157 }
158
159 if (vm.count("quiesce-hook")) {
160 std::cerr << "rbd: warning: quiesce-hook is not supported" << std::endl;
161 }
162
163 if (vm.count("options")) {
164 r = parse_options(vm["options"].as<std::vector<std::string>>(), &args);
165 if (r < 0) {
166 return r;
167 }
168 }
169
170 return call_ggate_cmd(vm, args, ceph_global_init_args);
171 #endif
172 }
173
174 int execute_unmap(const po::variables_map &vm,
175 const std::vector<std::string> &ceph_global_init_args) {
176 #if !defined(__FreeBSD__)
177 std::cerr << "rbd: ggate is only supported on FreeBSD" << std::endl;
178 return -EOPNOTSUPP;
179 #else
180 std::string device_name = utils::get_positional_argument(vm, 0);
181 if (!boost::starts_with(device_name, "/dev/")) {
182 device_name.clear();
183 }
184
185 std::string image_name;
186 if (device_name.empty()) {
187 int r = get_image_or_snap_spec(vm, &image_name);
188 if (r < 0) {
189 return r;
190 }
191 }
192
193 if (device_name.empty() && image_name.empty()) {
194 std::cerr << "rbd: unmap requires either image name or device path"
195 << std::endl;
196 return -EINVAL;
197 }
198
199 std::vector<std::string> args;
200
201 args.push_back("unmap");
202 args.push_back(device_name.empty() ? image_name : device_name);
203
204 if (vm.count("options")) {
205 int r = parse_options(vm["options"].as<std::vector<std::string>>(), &args);
206 if (r < 0) {
207 return r;
208 }
209 }
210
211 return call_ggate_cmd(vm, args, ceph_global_init_args);
212 #endif
213 }
214
215 int execute_attach(const po::variables_map &vm,
216 const std::vector<std::string> &ceph_global_init_args) {
217 #if !defined(__FreeBSD__)
218 std::cerr << "rbd: ggate is only supported on FreeBSD" << std::endl;
219 #else
220 std::cerr << "rbd: ggate attach command not supported" << std::endl;
221 #endif
222 return -EOPNOTSUPP;
223 }
224
225 int execute_detach(const po::variables_map &vm,
226 const std::vector<std::string> &ceph_global_init_args) {
227 #if !defined(__FreeBSD__)
228 std::cerr << "rbd: ggate is only supported on FreeBSD" << std::endl;
229 #else
230 std::cerr << "rbd: ggate detach command not supported" << std::endl;
231 #endif
232 return -EOPNOTSUPP;
233 }
234
235 } // namespace ggate
236 } // namespace action
237 } // namespace rbd