Commit 21d208bd authored by Georgios Bitzes's avatar Georgios Bitzes
Browse files

Drop use of XrdOucStream to parse Configuration, use ConfigurationReader instead

parent 524ef128
Pipeline #1097885 passed with stages
in 50 minutes and 12 seconds
......@@ -4,7 +4,12 @@ All notable changes to this project will be documented in this file.
## Unreleased
- A race condition was sometimes causing elections to fail spuriously, making
the election of a stable leader to require slightly more rounds than it should have.
- Implementation of health indicators through ``QUARKDB-HEALTH-LOCAL`` command.
- Added support for RESPv3 push types, activated on a per-client basis through
``ACTIVATE-PUSH-TYPES`` command.
- Add convenience command ``DEQUE-CLEAR``.
- Add support for ``MATCHLOC`` in ``LHSCAN``, used to filter out results based
on locality hint.
- Protection for a strange case of corruption which brought down a development
test cluster. (last-applied jumped ahead of commit-index by 1024, causing all
writes to stall). From now on, similar kind of corruption should only take out
......
......@@ -26,9 +26,11 @@
#include <unistd.h>
#include <fcntl.h>
#include "config/ConfigurationReader.hh"
#include "Configuration.hh"
#include "utils/Macros.hh"
#include "utils/FileUtils.hh"
#include "utils/StringUtils.hh"
#include "Utils.hh"
using namespace quarkdb;
......@@ -36,27 +38,28 @@ using namespace quarkdb;
bool Configuration::fromFile(const std::string &filename, Configuration &out) {
qdb_log("Reading configuration file from " << filename);
XrdOucStream stream(NULL, getenv("XRDINSTANCE"), NULL, "=====> ");
std::string contents;
if(!readFile(filename, contents)) {
qdb_error("Could not read configuration file: " << filename);
return false;
}
return Configuration::fromString(contents, out);
}
int fd;
static bool fetchSingle(ConfigurationReader &reader, std::string &dest) {
reader.advanceWord();
if ((fd = open(filename.c_str(), O_RDONLY, 0)) < 0) {
qdb_log("config: error " << errno << " when opening " << filename);
if(reader.eof()) {
return false;
}
stream.Attach(fd);
out.configurationPath = filename;
return Configuration::fromStream(stream, out);
}
dest = reader.getCurrentWord();
static bool fetchSingle(XrdOucStream &stream, std::string &dest) {
char *val;
if (!(val = stream.GetWord())) {
if(dest.empty()) {
return false;
}
dest = val;
return true;
}
......@@ -116,78 +119,71 @@ static bool parseTraceLevel(const std::string &buffer, TraceLevel &trace) {
return true;
}
bool Configuration::fromStream(XrdOucStream &stream, Configuration &out) {
std::string buffer;
char *option;
while ((option = stream.GetMyFirstWord())) {
bool ismine;
if ((ismine = !strncmp("redis.", option, 6)) && option[6]) option += 6;
if(ismine) {
bool success;
if(!strcmp("mode", option)) {
success = fetchSingle(stream, buffer) && parseMode(buffer, out.mode);
}
else if(!strcmp("database", option)) {
success = fetchSingle(stream, out.database);
}
else if(!strcmp("myself", option)) {
success = fetchSingle(stream, buffer) && parseServer(buffer, out.myself);
}
else if(!strcmp("trace", option)) {
success = fetchSingle(stream, buffer) && parseTraceLevel(buffer, out.trace);
}
else if(!strcmp("certificate", option)) {
success = fetchSingle(stream, out.certificatePath);
}
else if(!strcmp("certificate_key", option)) {
success = fetchSingle(stream, out.certificateKeyPath);
}
else if(!strcmp("write_ahead_log", option)) {
success = fetchSingle(stream, buffer) && parseBool(buffer, out.writeAheadLog);
}
else if(!strcmp("password_file", option)) {
success = fetchSingle(stream, out.passwordFilePath);
}
else if(!strcmp("password", option)) {
success = fetchSingle(stream, out.password);
}
else if(!strcmp("require_password_for_localhost", option)) {
success = fetchSingle(stream, buffer) && parseBool(buffer, out.requirePasswordForLocalhost);
}
else {
qdb_warn("Error when parsing configuration - unknown option " << quotes(option));
return false;
}
if(!success) {
qdb_warn("Error when parsing configuration option " << quotes("redis." << option));
return false;
}
bool Configuration::fromReader(ConfigurationReader &reader, Configuration &out) {
while(!reader.eof()) {
std::string current = reader.getCurrentWord();
bool isMine = StringUtils::startsWith(current, "redis.");
if(!isMine) {
reader.advanceLine();
continue;
}
}
return out.isValid();
}
current = std::string(current.begin()+6, current.end());
bool Configuration::fromString(const std::string &str, Configuration &out) {
XrdOucStream stream(NULL, getenv("XRDINSTANCE"), NULL, "=====> ");
bool success = false;
std::string buffer;
int fd[2];
if(pipe(fd) != 0) {
throw FatalException("unable to create pipe");
}
if(StringUtils::startsWith("mode", current)) {
success = fetchSingle(reader, buffer) && parseMode(buffer, out.mode);
}
else if(StringUtils::startsWith(current, "database")) {
success = fetchSingle(reader, out.database);
}
else if(StringUtils::startsWith(current, "myself")) {
success = fetchSingle(reader, buffer) && parseServer(buffer, out.myself);
}
else if(StringUtils::startsWith(current, "trace")) {
success = fetchSingle(reader, buffer) && parseTraceLevel(buffer, out.trace);
}
else if(StringUtils::startsWith(current, "certificate")) {
success = fetchSingle(reader, out.certificatePath);
}
else if(StringUtils::startsWith(current, "certificate_key")) {
success = fetchSingle(reader, out.certificateKeyPath);
}
else if(StringUtils::startsWith(current, "write_ahead_log")) {
success = fetchSingle(reader, buffer) && parseBool(buffer, out.writeAheadLog);
}
else if(StringUtils::startsWith(current, "password_file")) {
success = fetchSingle(reader, out.passwordFilePath);
}
else if(StringUtils::startsWith(current, "password")) {
success = fetchSingle(reader, out.password);
}
else if(StringUtils::startsWith(current, "require_password_for_localhost")) {
success = fetchSingle(reader, buffer) && parseBool(buffer, out.requirePasswordForLocalhost);
}
else {
qdb_warn("Error when parsing configuration - unknown option " << quotes(current));
return false;
}
if(!success) {
qdb_warn("Error when parsing configuration option " << quotes("redis." << current));
return false;
}
if(write(fd[1], str.c_str(), str.size()) < 0) {
throw FatalException("unable to write to pipe");
reader.advanceLine();
}
close(fd[1]);
stream.Attach(fd[0]);
return Configuration::fromStream(stream, out);
return out.isValid();
}
bool Configuration::fromString(const std::string &str, Configuration &out) {
ConfigurationReader reader(str);
return Configuration::fromReader(reader, out);
}
bool Configuration::isValid() {
......
......@@ -27,13 +27,13 @@
#include <string>
#include <vector>
#include <XrdOuc/XrdOucStream.hh>
#include "Common.hh"
#include "utils/Macros.hh"
namespace quarkdb {
class ConfigurationReader;
enum class Mode {
standalone = 0,
raft = 1,
......@@ -56,8 +56,8 @@ inline std::string modeToString(const Mode &mode) {
class Configuration {
public:
static bool fromFile(const std::string &filename, Configuration &out);
static bool fromStream(XrdOucStream &stream, Configuration &out);
static bool fromString(const std::string &str, Configuration &out);
static bool fromReader(ConfigurationReader &reader, Configuration &out);
bool isValid();
Mode getMode() const { return mode; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment