]>
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" | |
30 | #include "common/config.h" | |
31 | #include "common/Clock.h" | |
32 | #include "include/utime.h" | |
33 | #include "erasure-code/ErasureCodePlugin.h" | |
34 | ||
35 | namespace po = boost::program_options; | |
36 | ||
37 | class ErasureCodeCommand { | |
38 | po::variables_map vm; | |
39 | ErasureCodeProfile profile; | |
40 | boost::intrusive_ptr<CephContext> cct; | |
41 | public: | |
42 | int setup(int argc, char** argv); | |
43 | int run(); | |
44 | int plugin_exists(); | |
45 | int display_information(); | |
46 | }; | |
47 | ||
48 | int ErasureCodeCommand::setup(int argc, char** argv) { | |
49 | ||
50 | po::options_description desc("Allowed options"); | |
51 | desc.add_options() | |
52 | ("help,h", "produce help message") | |
53 | ("all", "implies " | |
54 | "--get_chunk_size 1024 " | |
55 | "--get_data_chunk_count " | |
56 | "--get_coding_chunk_count " | |
57 | "--get_chunk_count ") | |
58 | ("get_chunk_size", po::value<unsigned int>(), | |
59 | "display get_chunk_size(<object size>)") | |
60 | ("get_data_chunk_count", "display get_data_chunk_count()") | |
61 | ("get_coding_chunk_count", "display get_coding_chunk_count()") | |
62 | ("get_chunk_count", "display get_chunk_count()") | |
63 | ("parameter,P", po::value<vector<string> >(), | |
64 | "parameters") | |
65 | ("plugin_exists", po::value<string>(), | |
66 | "succeeds if the plugin given in argument exists and can be loaded") | |
67 | ; | |
68 | ||
69 | po::parsed_options parsed = | |
70 | po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); | |
71 | po::store( | |
72 | parsed, | |
73 | vm); | |
74 | po::notify(vm); | |
75 | ||
76 | vector<const char *> ceph_options, def_args; | |
77 | vector<string> ceph_option_strings = po::collect_unrecognized( | |
78 | parsed.options, po::include_positional); | |
79 | ceph_options.reserve(ceph_option_strings.size()); | |
80 | for (vector<string>::iterator i = ceph_option_strings.begin(); | |
81 | i != ceph_option_strings.end(); | |
82 | ++i) { | |
83 | ceph_options.push_back(i->c_str()); | |
84 | } | |
85 | ||
86 | cct = global_init( | |
87 | &def_args, ceph_options, CEPH_ENTITY_TYPE_CLIENT, | |
88 | CODE_ENVIRONMENT_UTILITY, | |
89 | CINIT_FLAG_NO_DEFAULT_CONFIG_FILE); | |
90 | common_init_finish(g_ceph_context); | |
91 | g_ceph_context->_conf->apply_changes(NULL); | |
92 | const char* env = getenv("CEPH_LIB"); | |
93 | string directory(env ? env : ".libs"); | |
c07f9fc5 | 94 | g_conf->set_val_or_die("erasure_code_dir", directory, false); |
7c673cae FG |
95 | |
96 | if (vm.count("help")) { | |
97 | cout << desc << std::endl; | |
98 | return 1; | |
99 | } | |
100 | ||
101 | if (vm.count("parameter")) { | |
102 | const vector<string> &p = vm["parameter"].as< vector<string> >(); | |
103 | for (vector<string>::const_iterator i = p.begin(); | |
104 | i != p.end(); | |
105 | ++i) { | |
106 | std::vector<std::string> strs; | |
107 | boost::split(strs, *i, boost::is_any_of("=")); | |
108 | if (strs.size() != 2) { | |
109 | cerr << "--parameter " << *i | |
110 | << " ignored because it does not contain exactly one =" << endl; | |
111 | } else { | |
112 | profile[strs[0]] = strs[1]; | |
113 | } | |
114 | } | |
115 | } | |
116 | ||
117 | return 0; | |
118 | } | |
119 | ||
120 | int ErasureCodeCommand::run() { | |
121 | if (vm.count("plugin_exists")) | |
122 | return plugin_exists(); | |
123 | else | |
124 | return display_information(); | |
125 | } | |
126 | ||
127 | int ErasureCodeCommand::plugin_exists() { | |
128 | ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); | |
129 | ErasureCodePlugin *plugin = 0; | |
130 | Mutex::Locker l(instance.lock); | |
131 | stringstream ss; | |
132 | int code = instance.load(vm["plugin_exists"].as<string>(), | |
133 | g_conf->get_val<std::string>("erasure_code_dir"), &plugin, &ss); | |
134 | if (code) | |
135 | cerr << ss.str() << endl; | |
136 | return code; | |
137 | } | |
138 | ||
139 | int ErasureCodeCommand::display_information() { | |
140 | ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); | |
141 | ErasureCodeInterfaceRef erasure_code; | |
142 | ||
143 | if (profile.count("plugin") == 0) { | |
144 | cerr << "--parameter plugin=<plugin> is mandatory" << endl; | |
145 | return 1; | |
146 | } | |
147 | ||
148 | int code = instance.factory(profile["plugin"], | |
149 | g_conf->get_val<std::string>("erasure_code_dir"), | |
150 | profile, | |
151 | &erasure_code, &cerr); | |
152 | if (code) | |
153 | return code; | |
154 | ||
155 | if (vm.count("all") || vm.count("get_chunk_size")) { | |
156 | unsigned int object_size = 1024; | |
157 | if (vm.count("get_chunk_size")) | |
158 | object_size = vm["get_chunk_size"].as<unsigned int>(); | |
159 | cout << "get_chunk_size(" << object_size << ")\t" | |
160 | << erasure_code->get_chunk_size(object_size) << endl; | |
161 | } | |
162 | if (vm.count("all") || vm.count("get_data_chunk_count")) | |
163 | cout << "get_data_chunk_count\t" | |
164 | << erasure_code->get_data_chunk_count() << endl; | |
165 | if (vm.count("all") || vm.count("get_coding_chunk_count")) | |
166 | cout << "get_coding_chunk_count\t" | |
167 | << erasure_code->get_coding_chunk_count() << endl; | |
168 | if (vm.count("all") || vm.count("get_chunk_count")) | |
169 | cout << "get_chunk_count\t" | |
170 | << erasure_code->get_chunk_count() << endl; | |
171 | return 0; | |
172 | } | |
173 | ||
174 | int main(int argc, char** argv) { | |
175 | ErasureCodeCommand eccommand; | |
176 | try { | |
177 | int err = eccommand.setup(argc, argv); | |
178 | if (err) | |
179 | return err; | |
180 | return eccommand.run(); | |
181 | } catch(po::error &e) { | |
182 | cerr << e.what() << endl; | |
183 | return 1; | |
184 | } | |
185 | } | |
186 | ||
187 | /* | |
188 | * Local Variables: | |
189 | * compile-command: "cd ../.. ; make -j4 && | |
190 | * make -j4 ceph_erasure_code && | |
191 | * libtool --mode=execute valgrind --tool=memcheck --leak-check=full \ | |
192 | * ./ceph_erasure_code \ | |
193 | * --parameter plugin=jerasure \ | |
194 | * --parameter technique=reed_sol_van \ | |
195 | * --parameter k=2 \ | |
196 | * --parameter m=2 \ | |
197 | * --get_chunk_size 1024 \ | |
198 | * --get_data_chunk_count \ | |
199 | * --get_coding_chunk_count \ | |
200 | * --get_chunk_count \ | |
201 | * " | |
202 | * End: | |
203 | */ |