]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph distributed storage system | |
5 | * | |
6 | * Copyright (C) 2014 Cloudwatt <libre.licensing@cloudwatt.com> | |
7 | * Copyright (C) 2014 Red Hat <contact@redhat.com> | |
8 | * | |
9 | * Author: Loic Dachary <loic@dachary.org> | |
10 | * | |
11 | * This library is free software; you can redistribute it and/or | |
12 | * modify it under the terms of the GNU Lesser General Public | |
13 | * License as published by the Free Software Foundation; either | |
14 | * version 2.1 of the License, or (at your option) any later version. | |
15 | * | |
16 | */ | |
17 | ||
18 | #include <boost/scoped_ptr.hpp> | |
19 | #include <boost/lexical_cast.hpp> | |
20 | #include <boost/program_options/option.hpp> | |
21 | #include <boost/program_options/options_description.hpp> | |
22 | #include <boost/program_options/variables_map.hpp> | |
23 | #include <boost/program_options/cmdline.hpp> | |
24 | #include <boost/program_options/parsers.hpp> | |
25 | #include <boost/algorithm/string.hpp> | |
26 | ||
27 | #include "global/global_context.h" | |
28 | #include "global/global_init.h" | |
29 | #include "common/ceph_argparse.h" | |
11fdf7f2 | 30 | #include "common/ceph_context.h" |
7c673cae FG |
31 | #include "common/config.h" |
32 | #include "common/Clock.h" | |
33 | #include "include/utime.h" | |
34 | #include "erasure-code/ErasureCodePlugin.h" | |
35 | ||
36 | namespace po = boost::program_options; | |
37 | ||
38 | class ErasureCodeCommand { | |
39 | po::variables_map vm; | |
40 | ErasureCodeProfile profile; | |
41 | boost::intrusive_ptr<CephContext> cct; | |
42 | public: | |
43 | int setup(int argc, char** argv); | |
44 | int run(); | |
45 | int plugin_exists(); | |
46 | int display_information(); | |
47 | }; | |
48 | ||
49 | int ErasureCodeCommand::setup(int argc, char** argv) { | |
50 | ||
51 | po::options_description desc("Allowed options"); | |
52 | desc.add_options() | |
53 | ("help,h", "produce help message") | |
54 | ("all", "implies " | |
55 | "--get_chunk_size 1024 " | |
56 | "--get_data_chunk_count " | |
57 | "--get_coding_chunk_count " | |
58 | "--get_chunk_count ") | |
59 | ("get_chunk_size", po::value<unsigned int>(), | |
60 | "display get_chunk_size(<object size>)") | |
61 | ("get_data_chunk_count", "display get_data_chunk_count()") | |
62 | ("get_coding_chunk_count", "display get_coding_chunk_count()") | |
63 | ("get_chunk_count", "display get_chunk_count()") | |
64 | ("parameter,P", po::value<vector<string> >(), | |
65 | "parameters") | |
66 | ("plugin_exists", po::value<string>(), | |
67 | "succeeds if the plugin given in argument exists and can be loaded") | |
68 | ; | |
69 | ||
70 | po::parsed_options parsed = | |
71 | po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); | |
72 | po::store( | |
73 | parsed, | |
74 | vm); | |
75 | po::notify(vm); | |
76 | ||
11fdf7f2 | 77 | vector<const char *> ceph_options; |
7c673cae FG |
78 | vector<string> ceph_option_strings = po::collect_unrecognized( |
79 | parsed.options, po::include_positional); | |
80 | ceph_options.reserve(ceph_option_strings.size()); | |
81 | for (vector<string>::iterator i = ceph_option_strings.begin(); | |
82 | i != ceph_option_strings.end(); | |
83 | ++i) { | |
84 | ceph_options.push_back(i->c_str()); | |
85 | } | |
86 | ||
87 | cct = global_init( | |
11fdf7f2 | 88 | NULL, ceph_options, CEPH_ENTITY_TYPE_CLIENT, |
7c673cae | 89 | CODE_ENVIRONMENT_UTILITY, |
11fdf7f2 | 90 | CINIT_FLAG_NO_MON_CONFIG); |
7c673cae | 91 | common_init_finish(g_ceph_context); |
11fdf7f2 | 92 | g_ceph_context->_conf.apply_changes(nullptr); |
7c673cae FG |
93 | |
94 | if (vm.count("help")) { | |
95 | cout << desc << std::endl; | |
96 | return 1; | |
97 | } | |
98 | ||
99 | if (vm.count("parameter")) { | |
100 | const vector<string> &p = vm["parameter"].as< vector<string> >(); | |
101 | for (vector<string>::const_iterator i = p.begin(); | |
102 | i != p.end(); | |
103 | ++i) { | |
104 | std::vector<std::string> strs; | |
105 | boost::split(strs, *i, boost::is_any_of("=")); | |
106 | if (strs.size() != 2) { | |
107 | cerr << "--parameter " << *i | |
108 | << " ignored because it does not contain exactly one =" << endl; | |
109 | } else { | |
110 | profile[strs[0]] = strs[1]; | |
111 | } | |
112 | } | |
113 | } | |
114 | ||
115 | return 0; | |
116 | } | |
117 | ||
118 | int ErasureCodeCommand::run() { | |
119 | if (vm.count("plugin_exists")) | |
120 | return plugin_exists(); | |
121 | else | |
122 | return display_information(); | |
123 | } | |
124 | ||
125 | int ErasureCodeCommand::plugin_exists() { | |
126 | ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); | |
127 | ErasureCodePlugin *plugin = 0; | |
128 | Mutex::Locker l(instance.lock); | |
129 | stringstream ss; | |
130 | int code = instance.load(vm["plugin_exists"].as<string>(), | |
11fdf7f2 | 131 | g_conf().get_val<std::string>("erasure_code_dir"), &plugin, &ss); |
7c673cae FG |
132 | if (code) |
133 | cerr << ss.str() << endl; | |
134 | return code; | |
135 | } | |
136 | ||
137 | int ErasureCodeCommand::display_information() { | |
138 | ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); | |
139 | ErasureCodeInterfaceRef erasure_code; | |
140 | ||
141 | if (profile.count("plugin") == 0) { | |
142 | cerr << "--parameter plugin=<plugin> is mandatory" << endl; | |
143 | return 1; | |
144 | } | |
145 | ||
146 | int code = instance.factory(profile["plugin"], | |
11fdf7f2 | 147 | g_conf().get_val<std::string>("erasure_code_dir"), |
7c673cae FG |
148 | profile, |
149 | &erasure_code, &cerr); | |
150 | if (code) | |
151 | return code; | |
152 | ||
153 | if (vm.count("all") || vm.count("get_chunk_size")) { | |
154 | unsigned int object_size = 1024; | |
155 | if (vm.count("get_chunk_size")) | |
156 | object_size = vm["get_chunk_size"].as<unsigned int>(); | |
157 | cout << "get_chunk_size(" << object_size << ")\t" | |
158 | << erasure_code->get_chunk_size(object_size) << endl; | |
159 | } | |
160 | if (vm.count("all") || vm.count("get_data_chunk_count")) | |
161 | cout << "get_data_chunk_count\t" | |
162 | << erasure_code->get_data_chunk_count() << endl; | |
163 | if (vm.count("all") || vm.count("get_coding_chunk_count")) | |
164 | cout << "get_coding_chunk_count\t" | |
165 | << erasure_code->get_coding_chunk_count() << endl; | |
166 | if (vm.count("all") || vm.count("get_chunk_count")) | |
167 | cout << "get_chunk_count\t" | |
168 | << erasure_code->get_chunk_count() << endl; | |
169 | return 0; | |
170 | } | |
171 | ||
172 | int main(int argc, char** argv) { | |
173 | ErasureCodeCommand eccommand; | |
174 | try { | |
175 | int err = eccommand.setup(argc, argv); | |
176 | if (err) | |
177 | return err; | |
178 | return eccommand.run(); | |
179 | } catch(po::error &e) { | |
180 | cerr << e.what() << endl; | |
181 | return 1; | |
182 | } | |
183 | } | |
184 | ||
185 | /* | |
186 | * Local Variables: | |
187 | * compile-command: "cd ../.. ; make -j4 && | |
188 | * make -j4 ceph_erasure_code && | |
189 | * libtool --mode=execute valgrind --tool=memcheck --leak-check=full \ | |
190 | * ./ceph_erasure_code \ | |
191 | * --parameter plugin=jerasure \ | |
192 | * --parameter technique=reed_sol_van \ | |
193 | * --parameter k=2 \ | |
194 | * --parameter m=2 \ | |
195 | * --get_chunk_size 1024 \ | |
196 | * --get_data_chunk_count \ | |
197 | * --get_coding_chunk_count \ | |
198 | * --get_chunk_count \ | |
199 | * " | |
200 | * End: | |
201 | */ |