bufferlist bl;
bl.append(orig_src, len);
- ConfFile cf(&bl);
- if (cf.parse() != 0) {
+ ConfFile cf;
+ std::deque<std::string> parse_errors;
+ if (cf.parse_bufferlist(&bl, &parse_errors) != 0) {
derr << "cannot parse buffer" << dendl;
goto done_err;
}
cout << "added entity " << ename << " auth " << eauth << std::endl;
}
if (caps_fn) {
- ConfFile *cf = new ConfFile(caps_fn);
- if (cf->parse() != 0) {
+ ConfFile cf;
+ std::deque<std::string> parse_errors;
+ if (cf.parse_file(caps_fn, &parse_errors) != 0) {
cerr << "could not parse caps file " << caps_fn << std::endl;
exit(1);
}
+ complain_about_parse_errors(&parse_errors);
map<string, bufferlist> caps;
const char *key_names[] = { "mon", "osd", "mds", NULL };
for (int i=0; key_names[i]; i++) {
std::string val;
- if (cf->read("global", key_names[i], val) == 0) {
+ if (cf.read("global", key_names[i], val) == 0) {
bufferlist bl;
::encode(val, bl);
string s(key_names[i]);
default_global = true;
}
-ConfFile::ConfFile(const char *fname)
+ConfFile::ConfFile()
: parse_lock("ConfFile::parse_lock", false, false, false)
{
- common_init();
-
- if (fname)
- filename = strdup(fname);
- else
- filename = NULL;
-}
-
-ConfFile::ConfFile(ceph::bufferlist *_pbl)
- : parse_lock("ConfFile::parse_lock", false, false, false)
-{
- common_init();
- pbl = _pbl;
}
ConfFile::~ConfFile()
return ret;
}
+int ConfFile::parse_file(const char *fname, std::deque<std::string> *parse_errors)
+{
+ common_init();
+
+ if (fname)
+ filename = strdup(fname);
+ else
+ filename = NULL;
+
+ return parse();
+}
+
+int ConfFile::parse_bufferlist(ceph::bufferlist *pbl_,
+ std::deque<std::string> *parse_errors)
+{
+ common_init();
+ pbl = pbl_;
+
+ return parse();
+}
+
int ConfFile::parse()
{
ConfSection *section = NULL;
#define CEPH_CONFUTILS_H
+#include <deque>
#include <string.h>
#include <map>
#include <string>
int _read(int fd, char *buf, size_t size);
int _close(int fd);
+ int parse();
public:
- ConfFile(const char *fname);
- ConfFile(ceph::bufferlist *bl);
+ ConfFile();
~ConfFile();
const SectionList& get_section_list() { return sections_list; }
ConfLine *_find_var(const char *section, const char* var);
- int parse();
+ int parse_file(const char *fname, std::deque<std::string> *parse_errors);
+ int parse_bufferlist(ceph::bufferlist *bl,
+ std::deque<std::string> *parse_errors);
int read(const char *section, const char *var, std::string &val);
#include "include/color.h"
#include <errno.h>
+#include <deque>
#include <syslog.h>
int keyring_init(md_config_t *conf)
return conf;
}
+void complain_about_parse_errors(std::deque<std::string> *parse_errors)
+{
+ if (parse_errors->empty())
+ return;
+ derr << "Errors while parsing config file!" << dendl;
+ int cur_err = 0;
+ static const int MAX_PARSE_ERRORS = 20;
+ for (std::deque<std::string>::const_iterator p = parse_errors->begin();
+ p != parse_errors->end(); ++p)
+ {
+ derr << *p << dendl;
+ if (cur_err == MAX_PARSE_ERRORS) {
+ derr << "Suppressed " << (parse_errors->size() - MAX_PARSE_ERRORS)
+ << " more errors." << dendl;
+ break;
+ }
+ ++cur_err;
+ }
+}
+
void common_init(std::vector < const char* >& args,
uint32_t module_type, code_environment_t code_env, int flags)
{
ceph_argparse_early_args(args, module_type, flags);
md_config_t *conf = common_preinit(iparams, code_env, flags);
- int ret = conf->parse_config_files(iparams.get_conf_files());
+ std::deque<std::string> parse_errors;
+ int ret = conf->parse_config_files(iparams.get_conf_files(), &parse_errors);
if (ret == -EDOM) {
derr << "common_init: error parsing config file." << dendl;
_exit(1);
_dout_open_log();
}
+ // Now we're ready to complain about config file parse errors
+ complain_about_parse_errors(&parse_errors);
+
// signal stuff
int siglist[] = { SIGPIPE, 0 };
block_signals(NULL, siglist);
#ifndef CEPH_COMMON_INIT_H
#define CEPH_COMMON_INIT_H
+#include <deque>
#include <stdint.h>
#include <string>
#include <vector>
int keyring_init(md_config_t *conf);
md_config_t *common_preinit(const CephInitParameters &iparams,
enum code_environment_t code_env, int flags);
+void complain_about_parse_errors(std::deque<std::string> *parse_errors);
void common_init(std::vector < const char* >& args,
uint32_t module_type, code_environment_t code_env, int flags);
}
int md_config_t::
-parse_config_files(const std::list<std::string> &conf_files)
+parse_config_files(const std::list<std::string> &conf_files,
+ std::deque<std::string> *parse_errors)
{
// open new conf
list<string>::const_iterator c = conf_files.begin();
while (true) {
if (c == conf_files.end())
return -EINVAL;
- ConfFile *cf_ = new ConfFile(c->c_str());
- int res = cf_->parse();
+ ConfFile *cf_ = new ConfFile();
+ int res = cf_->parse_file(c->c_str(), parse_errors);
if (res == 0) {
cf = cf_;
break;
~md_config_t();
// Parse a config file
- int parse_config_files(const std::list<std::string> &conf_files);
+ int parse_config_files(const std::list<std::string> &conf_files,
+ std::deque<std::string> *parse_errors);
// Absorb config settings from the environment
void parse_env();
if (ret)
return ret;
librados::RadosClient *radosp = (librados::RadosClient *)cluster;
+
return radosp->connect();
}
std::list<std::string> conf_files;
get_str_list(path, conf_files);
- int ret = g_conf.parse_config_files(conf_files);
+ std::deque<std::string> parse_errors;
+ int ret = g_conf.parse_config_files(conf_files, &parse_errors);
if (ret)
return ret;
g_conf.parse_env(); // environment variables override
g_conf.expand_all_meta(); // handle metavariables in the config
+
+ complain_about_parse_errors(&parse_errors);
+
return 0;
}
";
TEST(ParseFiles1, ConfUtils) {
+ std::deque<std::string> err;
std::string simple_conf_1_f(next_tempfile(simple_conf_1));
- ConfFile cf1(simple_conf_1_f.c_str());
- ASSERT_EQ(cf1.parse(), 0);
+ ConfFile cf1;
+ ASSERT_EQ(cf1.parse_file(simple_conf_1_f.c_str(), &err), 0);
+ ASSERT_EQ(err.size(), 0U);
std::string simple_conf_2_f(next_tempfile(simple_conf_1));
- ConfFile cf2(simple_conf_2_f.c_str());
- ASSERT_EQ(cf2.parse(), 0);
+ ConfFile cf2;
+ ASSERT_EQ(cf2.parse_file(simple_conf_2_f.c_str(), &err), 0);
+ ASSERT_EQ(err.size(), 0U);
bufferlist bl3;
bl3.append(simple_conf_1, strlen(simple_conf_1));
- ConfFile cf3(&bl3);
- ASSERT_EQ(cf3.parse(), 0);
+ ConfFile cf3;
+ ASSERT_EQ(cf3.parse_bufferlist(&bl3, &err), 0);
+ ASSERT_EQ(err.size(), 0U);
bufferlist bl4;
bl4.append(simple_conf_2, strlen(simple_conf_2));
- ConfFile cf4(&bl4);
- ASSERT_EQ(cf4.parse(), 0);
+ ConfFile cf4;
+ ASSERT_EQ(cf4.parse_bufferlist(&bl4, &err), 0);
+ ASSERT_EQ(err.size(), 0U);
}
TEST(ReadFiles1, ConfUtils) {
+ std::deque<std::string> err;
std::string simple_conf_1_f(next_tempfile(simple_conf_1));
- ConfFile cf1(simple_conf_1_f.c_str());
- ASSERT_EQ(cf1.parse(), 0);
+ ConfFile cf1;
+ ASSERT_EQ(cf1.parse_file(simple_conf_1_f.c_str(), &err), 0);
+ ASSERT_EQ(err.size(), 0U);
std::string val;
ASSERT_EQ(cf1.read("global", "keyring", val), 0);
bufferlist bl2;
bl2.append(simple_conf_2, strlen(simple_conf_2));
- ConfFile cf2(&bl2);
- ASSERT_EQ(cf2.parse(), 0);
+ ConfFile cf2;
+ ASSERT_EQ(cf2.parse_bufferlist(&bl2, &err), 0);
+ ASSERT_EQ(err.size(), 0U);
ASSERT_EQ(cf2.read("osd0", "keyring", val), 0);
ASSERT_EQ(val, "osd_keyring");
}
TEST(ReadFiles2, ConfUtils) {
+ std::deque<std::string> err;
std::string conf3_f(next_tempfile(conf3));
- ConfFile cf1(conf3_f.c_str());
+ ConfFile cf1;
std::string val;
- ASSERT_EQ(cf1.parse(), 0);
+ ASSERT_EQ(cf1.parse_file(conf3_f.c_str(), &err), 0);
+ ASSERT_EQ(err.size(), 0U);
ASSERT_EQ(cf1.read("global", "log file", val), 0);
ASSERT_EQ(val, "/quite/a/long/path/for/a/log/file");
ASSERT_EQ(cf1.read("global", "pid file", val), 0);
ASSERT_EQ(val, "spork");
std::string unicode_config_1f(next_tempfile(unicode_config_1));
- ConfFile cf2(unicode_config_1f.c_str());
- ASSERT_EQ(cf2.parse(), 0);
+ ConfFile cf2;
+ ASSERT_EQ(cf2.parse_file(unicode_config_1f.c_str(), &err), 0);
+ ASSERT_EQ(err.size(), 0U);
ASSERT_EQ(cf2.read("global", "log file", val), 0);
ASSERT_EQ(val, "\x66\xd1\x86\xd1\x9d\xd3\xad\xd3\xae");
}
// FIXME: illegal configuration files don't return a parse error currently.
TEST(IllegalFiles, ConfUtils) {
+ std::deque<std::string> err;
std::string illegal_conf1_f(next_tempfile(illegal_conf1));
- ConfFile cf1(illegal_conf1_f.c_str());
+ ConfFile cf1;
std::string val;
- ASSERT_EQ(cf1.parse(), 0);
+ ASSERT_EQ(cf1.parse_file(illegal_conf1_f.c_str(), &err), 0);
+ ASSERT_EQ(err.size(), 0U); // FIXME
bufferlist bl2;
bl2.append(illegal_conf2, strlen(illegal_conf2));
- ConfFile cf2(&bl2);
- ASSERT_EQ(cf2.parse(), 0);
+ ConfFile cf2;
+ ASSERT_EQ(cf2.parse_bufferlist(&bl2, &err), 0);
+ ASSERT_EQ(err.size(), 0U); // FIXME
std::string illegal_conf3_f(next_tempfile(illegal_conf3));
- ConfFile cf3(illegal_conf3_f.c_str());
- ASSERT_EQ(cf3.parse(), 0);
+ ConfFile cf3;
+ ASSERT_EQ(cf3.parse_file(illegal_conf3_f.c_str(), &err), 0);
+ ASSERT_EQ(err.size(), 0U); // FIXME
}