Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / erasure-code / ceph_erasure_code.cc
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");
94   g_conf->set_val_or_die("erasure_code_dir", directory, false);
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  */