]>
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 - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2015 Red Hat | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | ||
16 | #include <errno.h> | |
7c673cae | 17 | #include "ceph_ver.h" |
9f95a23c | 18 | #include "include/types.h" |
7c673cae | 19 | #include "common/Formatter.h" |
9f95a23c | 20 | #include "common/ceph_argparse.h" |
7c673cae | 21 | #include "common/errno.h" |
9f95a23c | 22 | #include "denc_registry.h" |
7c673cae FG |
23 | |
24 | #define MB(m) ((m) * 1024 * 1024) | |
25 | ||
26 | void usage(ostream &out) | |
27 | { | |
28 | out << "usage: ceph-dencoder [commands ...]" << std::endl; | |
29 | out << "\n"; | |
30 | out << " version print version string (to stdout)\n"; | |
31 | out << "\n"; | |
32 | out << " import <encfile> read encoded data from encfile\n"; | |
33 | out << " export <outfile> write encoded data to outfile\n"; | |
34 | out << "\n"; | |
35 | out << " set_features <num> set feature bits used for encoding\n"; | |
36 | out << " get_features print feature bits (int) to stdout\n"; | |
37 | out << "\n"; | |
38 | out << " list_types list supported types\n"; | |
39 | out << " type <classname> select in-memory type\n"; | |
40 | out << " skip <num> skip <num> leading bytes before decoding\n"; | |
41 | out << " decode decode into in-memory object\n"; | |
42 | out << " encode encode in-memory object\n"; | |
43 | out << " dump_json dump in-memory object as json (to stdout)\n"; | |
44 | out << " hexdump print encoded data in hex\n"; | |
45 | out << "\n"; | |
46 | out << " copy copy object (via operator=)\n"; | |
47 | out << " copy_ctor copy object (via copy ctor)\n"; | |
48 | out << "\n"; | |
49 | out << " count_tests print number of generated test objects (to stdout)\n"; | |
50 | out << " select_test <n> select generated test object as in-memory object\n"; | |
51 | out << " is_deterministic exit w/ success if type encodes deterministically\n"; | |
52 | } | |
7c673cae | 53 | |
7c673cae FG |
54 | int main(int argc, const char **argv) |
55 | { | |
9f95a23c TL |
56 | register_common_dencoders(); |
57 | register_mds_dencoders(); | |
58 | register_osd_dencoders(); | |
59 | register_rbd_dencoders(); | |
60 | register_rgw_dencoders(); | |
7c673cae | 61 | |
9f95a23c | 62 | auto& dencoders = DencoderRegistry::instance().get(); |
7c673cae FG |
63 | |
64 | vector<const char*> args; | |
65 | argv_to_vec(argc, argv, args); | |
66 | env_to_vec(args); | |
67 | ||
68 | Dencoder *den = NULL; | |
69 | uint64_t features = CEPH_FEATURES_SUPPORTED_DEFAULT; | |
70 | bufferlist encbl; | |
71 | uint64_t skip = 0; | |
72 | ||
73 | if (args.empty()) { | |
74 | cerr << "-h for help" << std::endl; | |
75 | exit(1); | |
76 | } | |
77 | for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ++i) { | |
78 | string err; | |
79 | ||
80 | if (*i == string("help") || *i == string("-h") || *i == string("--help")) { | |
81 | usage(cout); | |
82 | exit(0); | |
83 | } else if (*i == string("version")) { | |
84 | cout << CEPH_GIT_NICE_VER << std::endl; | |
85 | } else if (*i == string("list_types")) { | |
9f95a23c TL |
86 | for (auto& dencoder : dencoders) |
87 | cout << dencoder.first << std::endl; | |
7c673cae FG |
88 | exit(0); |
89 | } else if (*i == string("type")) { | |
90 | ++i; | |
91 | if (i == args.end()) { | |
92 | cerr << "expecting type" << std::endl; | |
93 | exit(1); | |
94 | } | |
95 | string cname = *i; | |
96 | if (!dencoders.count(cname)) { | |
97 | cerr << "class '" << cname << "' unknown" << std::endl; | |
98 | exit(1); | |
99 | } | |
9f95a23c | 100 | den = dencoders[cname].get(); |
7c673cae FG |
101 | den->generate(); |
102 | } else if (*i == string("skip")) { | |
103 | ++i; | |
104 | if (i == args.end()) { | |
105 | cerr << "expecting byte count" << std::endl; | |
106 | exit(1); | |
107 | } | |
108 | skip = atoi(*i); | |
109 | } else if (*i == string("get_features")) { | |
110 | cout << CEPH_FEATURES_SUPPORTED_DEFAULT << std::endl; | |
111 | exit(0); | |
112 | } else if (*i == string("set_features")) { | |
113 | ++i; | |
114 | if (i == args.end()) { | |
115 | cerr << "expecting features" << std::endl; | |
116 | exit(1); | |
117 | } | |
118 | features = atoll(*i); | |
119 | } else if (*i == string("encode")) { | |
120 | if (!den) { | |
121 | cerr << "must first select type with 'type <name>'" << std::endl; | |
122 | exit(1); | |
123 | } | |
124 | den->encode(encbl, features | CEPH_FEATURE_RESERVED); // hack for OSDMap | |
125 | } else if (*i == string("decode")) { | |
126 | if (!den) { | |
127 | cerr << "must first select type with 'type <name>'" << std::endl; | |
128 | exit(1); | |
129 | } | |
130 | err = den->decode(encbl, skip); | |
131 | } else if (*i == string("copy_ctor")) { | |
132 | if (!den) { | |
133 | cerr << "must first select type with 'type <name>'" << std::endl; | |
134 | exit(1); | |
135 | } | |
136 | den->copy_ctor(); | |
137 | } else if (*i == string("copy")) { | |
138 | if (!den) { | |
139 | cerr << "must first select type with 'type <name>'" << std::endl; | |
140 | exit(1); | |
141 | } | |
142 | den->copy(); | |
143 | } else if (*i == string("dump_json")) { | |
144 | if (!den) { | |
145 | cerr << "must first select type with 'type <name>'" << std::endl; | |
146 | exit(1); | |
147 | } | |
148 | JSONFormatter jf(true); | |
149 | jf.open_object_section("object"); | |
150 | den->dump(&jf); | |
151 | jf.close_section(); | |
152 | jf.flush(cout); | |
153 | cout << std::endl; | |
154 | ||
155 | } else if (*i == string("hexdump")) { | |
156 | encbl.hexdump(cout); | |
157 | } else if (*i == string("import")) { | |
158 | ++i; | |
159 | if (i == args.end()) { | |
160 | cerr << "expecting filename" << std::endl; | |
161 | exit(1); | |
162 | } | |
163 | int r; | |
164 | if (*i == string("-")) { | |
165 | *i = "stdin"; | |
166 | // Read up to 1mb if stdin specified | |
167 | r = encbl.read_fd(STDIN_FILENO, MB(1)); | |
168 | } else { | |
169 | r = encbl.read_file(*i, &err); | |
170 | } | |
171 | if (r < 0) { | |
172 | cerr << "error reading " << *i << ": " << err << std::endl; | |
173 | exit(1); | |
174 | } | |
175 | ||
176 | } else if (*i == string("export")) { | |
177 | ++i; | |
178 | if (i == args.end()) { | |
179 | cerr << "expecting filename" << std::endl; | |
180 | exit(1); | |
181 | } | |
182 | int fd = ::open(*i, O_WRONLY|O_CREAT|O_TRUNC, 0644); | |
183 | if (fd < 0) { | |
184 | cerr << "error opening " << *i << " for write: " << cpp_strerror(errno) << std::endl; | |
185 | exit(1); | |
186 | } | |
187 | int r = encbl.write_fd(fd); | |
188 | if (r < 0) { | |
189 | cerr << "error writing " << *i << ": " << cpp_strerror(errno) << std::endl; | |
190 | exit(1); | |
191 | } | |
192 | ::close(fd); | |
193 | ||
194 | } else if (*i == string("count_tests")) { | |
195 | if (!den) { | |
196 | cerr << "must first select type with 'type <name>'" << std::endl; | |
197 | exit(1); | |
198 | } | |
199 | cout << den->num_generated() << std::endl; | |
200 | } else if (*i == string("select_test")) { | |
201 | if (!den) { | |
202 | cerr << "must first select type with 'type <name>'" << std::endl; | |
203 | exit(1); | |
204 | } | |
205 | ++i; | |
206 | if (i == args.end()) { | |
207 | cerr << "expecting instance number" << std::endl; | |
208 | exit(1); | |
209 | } | |
210 | int n = atoi(*i); | |
211 | err = den->select_generated(n); | |
212 | } else if (*i == string("is_deterministic")) { | |
213 | if (!den) { | |
214 | cerr << "must first select type with 'type <name>'" << std::endl; | |
215 | exit(1); | |
216 | } | |
217 | if (den->is_deterministic()) | |
218 | exit(0); | |
219 | else | |
220 | exit(1); | |
221 | } else { | |
222 | cerr << "unknown option '" << *i << "'" << std::endl; | |
223 | exit(1); | |
224 | } | |
225 | if (err.length()) { | |
226 | cerr << "error: " << err << std::endl; | |
227 | exit(1); | |
228 | } | |
229 | } | |
230 | return 0; | |
231 | } |