void proxy::req_get::on_read_chunk(const ioremap::elliptics::sync_read_result &srr, const ioremap::elliptics::error_info &error) { if (error) { BH_LOG(logger(), SWARM_LOG_ERROR , "Get %s %s: on_read_chunk: %s" , m_key.remote().c_str(), m_key.to_string().c_str(), error.message().c_str()); HANDY_MDS_GET_REPLY(500); send_reply(500); return; } BH_LOG(logger(), SWARM_LOG_INFO , "Get %s %s: on_read_chunk: chunk was read" , m_key.remote().c_str(), m_key.to_string().c_str()); const auto &rr = srr.front(); auto file = rr.file(); std::string data = file.to_string(); if (m_first_chunk) { m_first_chunk = false; ioremap::thevoid::http_response reply; reply.set_code(200); reply.headers().set_content_length(m_size); if (NULL == server()->m_magic.get()) { server()->m_magic.reset(new magic_provider()); } reply.headers().set_content_type(server()->m_magic->type(data)); { time_t timestamp = (time_t)(rr.io_attribute()->timestamp.tsec); char ts_str[128] = {0}; struct tm tmp; strftime(ts_str, sizeof (ts_str), "%a, %d %b %Y %T %Z", gmtime_r(×tamp, &tmp)); if (m_if_modified_since) { if (*m_if_modified_since == ts_str) { HANDY_MDS_GET_REPLY(304); send_reply(304); return; } } reply.headers().set_last_modified(ts_str); } HANDY_MDS_GET_REPLY(reply.code()); send_headers(std::move(reply), std::function<void (const boost::system::error_code &)>()); } send_data(std::move(data), std::bind(&proxy::req_get::on_sent_chunk, shared_from_this(), std::placeholders::_1)); m_offset += file.size(); }
void session::read_file(const key &id, const std::string &file, uint64_t offset, uint64_t size) { transform(id); session sess = clone(); sess.set_exceptions_policy(throw_at_get); read_result_entry result = sess.read_data(id, offset, size).get_one(); dnet_io_attr *io = result.io_attribute(); int err; file_descriptor fd(open(file.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0644)); if (fd.fd() < 0) { err = -errno; throw_error(err, id, "Failed to open read completion file: '%s'", file.c_str()); } err = pwrite(fd.fd(), result.file().data(), result.file().size(), offset); if (err <= 0) { err = -errno; throw_error(err, id, "Failed to write data into completion file: '%s'", file.c_str()); } BH_LOG(get_logger(), DNET_LOG_NOTICE, "%s: read completed: file: '%s', offset: %llu, size: %llu, status: %d.", dnet_dump_id(&id.id()), file, offset, uint64_t(io->size), int(result.command()->status)); }
void proxy::req_get::read_chunk() { // if (server()->logger().level() >= ioremap::swarm::SWARM_LOG_INFO) { std::ostringstream oss; oss << "Get " << m_key.remote() << " " << m_key.to_string() << ": read_chunk: chunk_size=" << m_chunk_size << " file_size=" << m_size << " offset=" << m_offset << " data_left=" << (m_size - m_offset) << " groups: ["; auto groups = m_session->get_groups(); for (auto itb = groups.begin(), it = itb; it != groups.end(); ++it) { if (it != itb) oss << ", "; oss << *it; } oss << ']'; BH_LOG(logger(), SWARM_LOG_INFO, "%s", oss.str().c_str()); } m_session->set_timeout(server()->timeout.read); if (m_first_chunk) { if (server()->timeout_coef.data_flow_rate) { m_session->set_timeout( m_session->get_timeout() + m_size / server()->timeout_coef.data_flow_rate); } } else { m_session->set_ioflags(m_session->get_ioflags() | DNET_IO_FLAGS_NOCSUM); } auto arr = m_session->read_data(m_key, m_offset, m_chunk_size); arr.connect(wrap(std::bind(&proxy::req_get::on_read_chunk, shared_from_this(), std::placeholders::_1, std::placeholders::_2))); }
void acceptors_list<Connection>::add_acceptor(const std::string &address) { acceptors.emplace_back(new acceptor_type(get_acceptor_service())); auto &acceptor = acceptors.back(); try { endpoint_type endpoint = create_endpoint(*acceptor, address); acceptor->open(endpoint.protocol()); acceptor->set_option(boost::asio::socket_base::reuse_address(true)); acceptor->bind(endpoint); acceptor->listen(data.backlog_size); BH_LOG(data.logger, SWARM_LOG_INFO, "Started to listen address: %s, backlog: %d", address, data.backlog_size); local_endpoints.emplace_back(boost::lexical_cast<std::string>(endpoint)); protocols.push_back(endpoint.protocol()); complete_socket_creation(endpoint); } catch (boost::system::system_error &error) { std::cerr << "Can not bind socket \"" << address << "\": " << error.what() << std::endl; std::cerr.flush(); acceptors.pop_back(); if (local_endpoints.size() > acceptors.size()) local_endpoints.pop_back(); if (protocols.size() > acceptors.size()) protocols.pop_back(); throw; } start_acceptor(acceptors.size() - 1); }
static void init_procfs_provider(struct dnet_node *n, struct dnet_config *cfg) { try { add_provider(n, new procfs_provider(n), "procfs"); } catch (const std::exception &e) { BH_LOG(*cfg->log, DNET_LOG_ERROR, "monitor: failed to initialize procfs_stat_provider: %s.", e.what()); } }
void send_error(int status, int error, const char *fmt, ...) { va_list args; va_start(args, fmt); char buffer[1024]; int sz = vsnprintf(buffer, sizeof(buffer), fmt, args); BH_LOG(this->server()->logger(), SWARM_LOG_ERROR, "%s: %d", buffer, error); warp::JsonValue val; rapidjson::Value ev(rapidjson::kObjectType); rapidjson::Value esv(buffer, sz, val.GetAllocator()); ev.AddMember("message", esv, val.GetAllocator()); ev.AddMember("code", error, val.GetAllocator()); val.AddMember("error", ev, val.GetAllocator()); va_end(args); std::string data = val.ToString(); thevoid::http_response http_reply; http_reply.set_code(status); http_reply.headers().set_content_length(data.size()); http_reply.headers().set_content_type("text/json"); this->send_reply(std::move(http_reply), std::move(data)); }
BENCHMARK_RELATIVE_X(Limits, Experimental) { static auto log = initialize< blackhole::verbose_logger_t<level_t>, blackhole::formatter::string_t, blackhole::sink::stream_t >(FORMAT_VERBOSE)(blackhole::sink::stream_t::output_t::stdout)(); BH_LOG(log, level_t::info, MESSAGE_LONG); }
extern "C" struct dnet_node *dnet_parse_config(const char *file, int mon) { dnet_node *node = NULL; config_data *data = NULL; try { data = static_cast<config_data *>(dnet_config_data_create()); if (!data) throw std::bad_alloc(); data->config_path = file; auto parser = data->parse_config(); const config root = parser->root(); const config logger = root.at("logger"); const config options = root.at("options"); const config backends = root.at("backends"); parse_logger(data, logger); parse_options(data, options); parse_backends(data, backends); if (data->daemon_mode && !mon) dnet_background(); if (!data->cfg_addr_num) throw config_error("no local address specified, exiting"); node = dnet_server_node_create(data); if (!node) throw config_error("failed to create node"); static_assert(sizeof(dnet_addr) == sizeof(address), "Size of dnet_addr and size of address must be equal"); if (data->remotes.size() != 0) { int err = dnet_add_state(node, reinterpret_cast<const dnet_addr *>(data->remotes.data()), data->remotes.size(), 0); if (err < 0) BH_LOG(*node->log, DNET_LOG_WARNING, "Failed to connect to remote nodes: %d", err); } } catch (std::exception &exc) { if (data && data->cfg_state.log) { dnet_backend_log(data->cfg_state.log, DNET_LOG_ERROR, "cnf: failed to read config file '%s': %s", file, exc.what()); } else { fprintf(stderr, "cnf: %s\n", exc.what()); fflush(stderr); } if (node) dnet_server_node_destroy(node); else if (data) dnet_config_data_destroy(data); return NULL; } return node; }
void proxy::req_get::on_lookup(const ioremap::elliptics::sync_lookup_result &slr, const ioremap::elliptics::error_info &error) { if (error) { if (error.code() == -ENOENT) { BH_LOG(logger(), SWARM_LOG_INFO , "Get %s %s: on_lookup: file not found" , m_key.remote().c_str(), m_key.to_string().c_str()); HANDY_MDS_GET_REPLY(404); send_reply(404); } else { BH_LOG(logger(), SWARM_LOG_ERROR , "Get %s %s: on_lookup: %s" , m_key.remote().c_str(), m_key.to_string().c_str(), error.message().c_str()); HANDY_MDS_GET_REPLY(500); send_reply(500); } return; } const auto &entry = slr.front(); auto total_size = entry.file_info()->size; if (m_offset >= total_size) { BH_LOG(logger(), SWARM_LOG_INFO , "Get %s %s: offset greater than total_size" , m_key.remote().c_str() , m_key.to_string().c_str()); HANDY_MDS_GET_REPLY(400); send_reply(400); return; } total_size -= m_offset; if (m_size == 0 || m_size > total_size) { m_size = total_size; } std::vector<int> groups; for (auto it = slr.begin(), end = slr.end(); it != end; ++it) { groups.push_back(it->command()->id.group_id); } m_session->set_groups(groups); read_chunk(); }
void acceptors_list<Connection>::handle_accept(size_t index, connection_ptr_type conn, const boost::system::error_code &err) { if (!err) { conn->start(local_endpoints.at(index)); } else { BH_LOG(data.logger, SWARM_LOG_ERROR, "Failed to accept connection: %s", err.message().c_str()); } start_acceptor(index); }
monitor::monitor(struct dnet_node *n, struct dnet_config *cfg) : m_node(n) , m_server(*this, get_monitor_port(n), cfg->family) , m_statistics(*this, cfg) { #if defined(HAVE_HANDYSTATS) && !defined(HANDYSTATS_DISABLE) if (cfg->handystats_config != nullptr) { //TODO: add parse/configuration errors logging when handystats will allow to get them if (HANDY_CONFIG_FILE(cfg->handystats_config)) { BH_LOG(*cfg->log, DNET_LOG_INFO, "monitor: initializing stats subsystem, config file '%s'", cfg->handystats_config); } else { BH_LOG(*cfg->log, DNET_LOG_ERROR, "monitor: initializing stats subsystem, error parsing config file '%s', using defaults", cfg->handystats_config); } } else { BH_LOG(*cfg->log, DNET_LOG_INFO, "monitor: initializing stats subsystem, no config file specified, using defaults"); } HANDY_INIT(); #else BH_LOG(*cfg->log, DNET_LOG_INFO, "monitor: stats subsystem disabled at compile time"); #endif }
int dnet_monitor_init(struct dnet_node *n, struct dnet_config *cfg) { if (!get_monitor_port(n) || !cfg->family) { n->monitor = NULL; BH_LOG(*cfg->log, DNET_LOG_ERROR, "monitor: monitor hasn't been initialized because monitor port is zero."); return 0; } try { n->monitor = static_cast<void*>(new ioremap::monitor::monitor(n, cfg)); } catch (const std::exception &e) { BH_LOG(*cfg->log, DNET_LOG_ERROR, "monitor: failed to initialize monitor on port: %d: %s.", get_monitor_port(n), e.what()); return -ENOMEM; } ioremap::monitor::init_io_stat_provider(n, cfg); ioremap::monitor::init_backends_stat_provider(n, cfg); ioremap::monitor::init_procfs_provider(n, cfg); ioremap::monitor::init_top_provider(n, cfg); return 0; }
BENCHMARK_BASELINE(Filtering, Rejected) { static auto log = initialize< blackhole::verbose_logger_t<level_t>, blackhole::formatter::string_t, blackhole::sink::null_t >(FORMAT_BASE)()(std::bind(&filter_by::verbosity, std::placeholders::_1, level_t::info)); BH_LOG(log, level_t::debug, MESSAGE_LONG)( "id", 42, "info", "le string" ); }
BENCHMARK_RELATIVE(Logger, Verbose) { static auto log = initialize< blackhole::verbose_logger_t<level_t>, blackhole::formatter::string_t, blackhole::sink::null_t >(FORMAT_VERBOSE)()(); BH_LOG(log, level_t::info, MESSAGE_LONG)( "id", 42, "info", "le string" ); }
void proxy::req_delete::on_lookup(const ioremap::elliptics::sync_lookup_result &slr, const ioremap::elliptics::error_info &error) { if (error) { BH_LOG(logger(), SWARM_LOG_ERROR, "Delete request=\"%s\" lookup error: %s" , url_str.c_str(), error.message().c_str()); HANDY_MDS_DELETE_REPLY(error.code() == -ENOENT ? 404 : 500); send_reply(error.code() == -ENOENT ? 404 : 500); return; } const auto &entry = slr.front(); total_size = entry.file_info()->size; // all_with_ack because all doesn't mean all in some cases e.g. remove act session->set_filter(ioremap::elliptics::filters::all_with_ack); session->set_timeout(server()->timeout.remove); BH_LOG(logger(), SWARM_LOG_DEBUG, "Delete %s: data size %d" , url_str.c_str(), static_cast<int>(total_size)); session->remove(key).connect(wrap(std::bind(&req_delete::on_finished, shared_from_this(), std::placeholders::_1, std::placeholders::_2))); }
void session::write_file(const key &id, const std::string &file, uint64_t local_offset, uint64_t offset, uint64_t size) { transform(id); session sess = clone(); sess.set_exceptions_policy(throw_at_wait); int err; file_descriptor fd(open(file.c_str(), O_RDONLY | O_LARGEFILE | O_CLOEXEC)); if (fd.fd() < 0) { err = -errno; throw_error(err, id, "Failed to open read completion file '%s'", file.c_str()); } struct stat stat; memset(&stat, 0, sizeof(stat)); err = fstat(fd.fd(), &stat); if (err) { err = -errno; throw_error(err, id, "Failed to stat to be written file '%s'", file.c_str()); } if (local_offset >= (uint64_t)stat.st_size) { BH_LOG(get_logger(), DNET_LOG_NOTICE, "%s: File is already uploaded: '%s'", dnet_dump_id(&id.id()), file); return; } if (!size || size + local_offset >= (uint64_t)stat.st_size) size = stat.st_size - local_offset; dnet_io_control ctl; memset(&ctl, 0, sizeof(struct dnet_io_control)); ctl.data = NULL; ctl.fd = fd.fd(); ctl.local_offset = local_offset; memcpy(ctl.io.id, id.id().id, DNET_ID_SIZE); memcpy(ctl.io.parent, id.id().id, DNET_ID_SIZE); ctl.io.size = size; ctl.io.offset = offset; ctl.io.timestamp.tsec = stat.st_mtime; ctl.io.timestamp.tnsec = 0; ctl.id = id.id(); write_data(ctl).wait(); }
static void init_top_provider(struct dnet_node *n, struct dnet_config *cfg) { try { bool top_loaded = false; const auto monitor = get_monitor(n); if (monitor) { auto top_stats = monitor->get_statistics().get_top_stats(); if (top_stats) { add_provider(n, new top_provider(top_stats), "top"); top_loaded = true; } } const auto monitor_cfg = get_monitor_config(n); if (top_loaded && monitor_cfg) { BH_LOG(*cfg->log, DNET_LOG_INFO, "monitor: top provider loaded: top length: %lu, events size: %lu, period: %d", monitor_cfg->top_length, monitor_cfg->events_size, monitor_cfg->period_in_seconds); } else { BH_LOG(*cfg->log, DNET_LOG_INFO, "monitor: top provider is disabled"); } } catch (const std::exception &e) { BH_LOG(*cfg->log, DNET_LOG_ERROR, "monitor: failed to initialize top_stat_provider: %s.", e.what()); } }
void proxy::req_get::on_sent_chunk(const boost::system::error_code &error) { if (error) { BH_LOG(logger(), SWARM_LOG_ERROR , "Get %s %s: on_sent_chunk: %s" , m_key.remote().c_str(), m_key.to_string().c_str(), error.message().c_str()); reply()->close(error); return; } BH_LOG(logger(), SWARM_LOG_INFO , "Get %s %s: chunk was sent" , m_key.remote().c_str(), m_key.to_string().c_str()); if (m_offset < m_size) { read_chunk(); return; } // if (server()->logger().level() >= ioremap::swarm::SWARM_LOG_INFO) { auto end_time = std::chrono::system_clock::now(); auto spent_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - m_beg_time).count(); std::ostringstream oss; oss << "Get " << m_key.remote() << " " << m_key.to_string() << ": on_finished: request=" << request().url().path() << " spent_time=" << spent_time << " file_size=" << m_size; BH_LOG(logger(), SWARM_LOG_INFO, "%s", oss.str().c_str()); } reply()->close(error); HANDY_TIMER_STOP("mds.get.time", reinterpret_cast<uint64_t>(this)); }
void proxy::req_delete::on_finished(const ioremap::elliptics::sync_remove_result &srr, const ioremap::elliptics::error_info &error) { (void) error; bool has_bad_response = false; size_t enoent_count = 0; for (auto it = srr.begin(), end = srr.end(); it != end; ++it) { int status = it->status(); int group = it->command()->id.group_id; const auto &err = it->error(); if (status != 0) { BH_LOG(logger(), SWARM_LOG_INFO, "Delete request=\"%s\" group=%d status=%d error=\"%s\"" , url_str.c_str(), group, status, err.message().c_str()); if (status != -ENOENT) { has_bad_response = true; } else { enoent_count += 1; } } else { BH_LOG(logger(), SWARM_LOG_INFO, "Delete request=\"%s\" group=%d status=0", url_str.c_str(), group); } } // The reason for this check: ELL-250 if (srr.size() != session->get_groups().size()) { BH_LOG(logger(), SWARM_LOG_ERROR, "Delete request=\"%s\" unknown client errors" , url_str.c_str()); has_bad_response = true; } if (has_bad_response) { BH_LOG(logger(), SWARM_LOG_ERROR, "Delete request=\"%s\" remove is failed" , url_str.c_str()); HANDY_MDS_DELETE_REPLY(500); send_reply(500); return; } if (enoent_count == srr.size()) { BH_LOG(logger(), SWARM_LOG_ERROR, "Delete request=\"%s\" key not found" , url_str.c_str()); HANDY_MDS_DELETE_REPLY(404); send_reply(404); return; } BH_LOG(logger(), SWARM_LOG_INFO, "Delete request=\"%s\" remove is done" , url_str.c_str()); HANDY_MDS_DELETE_REPLY(200); send_reply(200); HANDY_TIMER_STOP("mds.delete.time", reinterpret_cast<uint64_t>(this)); return; }
void proxy::req_get::on_request(const ioremap::thevoid::http_request &req, const boost::asio::const_buffer &buffer) { HANDY_TIMER_START("mds.get.time", reinterpret_cast<uint64_t>(this)); HANDY_MDS_GET(); m_beg_time = std::chrono::system_clock::now(); url_str = req.url().path(); BH_LOG(logger(), SWARM_LOG_INFO, "Get: handle request: %s", url_str.c_str()); namespace_ptr_t ns; try { ns = server()->get_namespace(url_str, "/get"); auto &&prep_session = server()->prepare_session(url_str, ns); m_session = prep_session.first; m_session->set_timeout(server()->timeout.read); m_key = prep_session.second; m_key.transform(*m_session); m_key.set_id(m_key.id()); } catch (const std::exception &ex) { BH_LOG(logger(), SWARM_LOG_INFO, "Get: request = \"%s\"; err: \"%s\"", req.url().path().c_str(), ex.what()); HANDY_MDS_GET_REPLY(400); send_reply(400); return; } if (!server()->check_basic_auth(ns->name, ns->auth_key_for_read, req.headers().get("Authorization"))) { auto token = server()->get_auth_token(req.headers().get("Authorization")); BH_LOG(logger(), SWARM_LOG_INFO, "%s: invalid token \"%s\"" , url_str.c_str(), token.empty() ? "<none>" : token.c_str()); ioremap::thevoid::http_response reply; ioremap::swarm::http_headers headers; reply.set_code(401); headers.add("WWW-Authenticate", std::string("Basic realm=\"") + ns->name + "\""); headers.add("Content-Length", "0"); reply.set_headers(headers); HANDY_MDS_GET_REPLY(reply.code()); send_reply(std::move(reply)); return; } if (m_session->get_groups().empty()) { BH_LOG(logger(), SWARM_LOG_INFO , "Get %s: on_request: cannot find couple of groups for the request" , url_str.c_str()); HANDY_MDS_GET_REPLY(404); send_reply(404); return; } auto query_list = req.url().query(); m_offset = get_arg<uint64_t>(query_list, "offset", 0); m_size = get_arg<uint64_t>(query_list, "size", 0); m_if_modified_since = req.headers().get("If-Modified-Since"); m_first_chunk = true; m_chunk_size = server()->m_read_chunk_size; { std::ostringstream oss; oss << "Get " << m_key.remote() << " " << m_key.to_string() << ": lookup from groups ["; const auto &groups = m_session->get_groups(); for (auto bit = groups.begin(), it = bit, end = groups.end(); it != end; ++it) { if (it != bit) oss << ", "; oss << *it; } oss << ']'; auto msg = oss.str(); BH_LOG(logger(), SWARM_LOG_INFO, "%s", msg.c_str()); } { auto ioflags = m_session->get_ioflags(); m_session->set_ioflags(ioflags | DNET_IO_FLAGS_NOCSUM); m_session->set_timeout(server()->timeout.lookup); m_session->set_filter(ioremap::elliptics::filters::positive); auto alr = m_session->quorum_lookup(m_key); alr.connect(wrap(std::bind(&proxy::req_get::on_lookup, shared_from_this(), std::placeholders::_1, std::placeholders::_2))); m_session->set_ioflags(ioflags); } }
void proxy::req_delete::on_request(const ioremap::thevoid::http_request &req, const boost::asio::const_buffer &buffer) { HANDY_TIMER_START("mds.delete.time", reinterpret_cast<uint64_t>(this)); HANDY_MDS_DELETE(); try { BH_LOG(logger(), SWARM_LOG_INFO, "Delete: handle request: %s", req.url().path().c_str()); namespace_ptr_t ns; url_str = req.url().path(); try { ns = server()->get_namespace(url_str, "/delete"); auto &&prep_session = server()->prepare_session(url_str, ns); session.reset(prep_session.first); key = prep_session.second; } catch (const std::exception &ex) { BH_LOG(logger(), SWARM_LOG_INFO, "Delete: request = \"%s\", err = \"%s\"", url_str.c_str(), ex.what() ); HANDY_MDS_DELETE_REPLY(400); send_reply(400); return; } if (!server()->check_basic_auth(ns->name, ns->auth_key_for_write, req.headers().get("Authorization"))) { auto token = server()->get_auth_token(req.headers().get("Authorization")); BH_LOG(logger(), SWARM_LOG_INFO, "%s: invalid token \"%s\"" , url_str.c_str(), token.empty() ? "<none>" : token.c_str()); ioremap::thevoid::http_response reply; ioremap::swarm::http_headers headers; reply.set_code(401); headers.add("WWW-Authenticate", std::string("Basic realm=\"") + ns->name + "\""); headers.add("Content-Length", "0"); reply.set_headers(headers); HANDY_MDS_DELETE_REPLY(reply.code()); send_reply(std::move(reply)); return; } if (session->state_num() < server()->die_limit()) { throw std::runtime_error("Too low number of existing states"); } session->set_timeout(server()->timeout.lookup); session->set_filter(ioremap::elliptics::filters::positive); auto alr = session->quorum_lookup(key); alr.connect(wrap(std::bind(&proxy::req_delete::on_lookup, shared_from_this(), std::placeholders::_1, std::placeholders::_2))); } catch (const std::exception &ex) { BH_LOG(logger(), SWARM_LOG_ERROR, "Delete request=\"%s\" error: %s" , url_str.c_str(), ex.what()); HANDY_MDS_DELETE_REPLY(500); send_reply(500); } catch (...) { BH_LOG(logger(), SWARM_LOG_ERROR, "Delete request=\"%s\" error: unknown" , url_str.c_str()); HANDY_MDS_DELETE_REPLY(500); send_reply(500); } }