Merge pull request #1530 from theopolis/fix_db_proc

[#1529] Allow DB Readonly with RocksDB lite
This commit is contained in:
Teddy Reed 2015-09-28 09:50:36 -07:00
commit cbf9a17b4a
4 changed files with 35 additions and 10 deletions

View File

@ -567,8 +567,6 @@ Status getDatabaseValue(const std::string& domain,
PluginResponse response;
auto status = Registry::call("database", "rocks", request, response);
if (!status.ok()) {
VLOG(1) << "Cannot get database " << domain << "/" << key << ": "
<< status.getMessage();
return status;
}

View File

@ -124,6 +124,11 @@ DBHandle::DBHandle(const std::string& path, bool in_memory) {
VLOG(1) << "Opening RocksDB handle: " << path;
auto s = rocksdb::DB::Open(options_, path, column_families_, &handles_, &db_);
if (!s.ok()) {
#if defined(ROCKSDB_LITE)
// RocksDB LITE does not support readonly mode.
VLOG(1) << "Opening RocksDB failed: Continuing without storage support";
#else
VLOG(1) << "Opening RocksDB failed: Continuing with read-only support";
// The database was readable but could not be opened, either (1) it is not
// writable or (2) it is already opened by another process.
// Try to open the database in a ReadOnly mode.
@ -132,6 +137,9 @@ DBHandle::DBHandle(const std::string& path, bool in_memory) {
if (!s.ok()) {
throw std::runtime_error(s.ToString());
}
#endif
// Also disable event publishers.
Flag::updateValue("disable_events", "true");
read_only_ = true;
}
@ -206,6 +214,9 @@ rocksdb::ColumnFamilyHandle* DBHandle::getHandleForColumnFamily(
Status DBHandle::Get(const std::string& domain,
const std::string& key,
std::string& value) {
if (getDB() == nullptr) {
return Status(1, "Database not opened");
}
auto cfh = getHandleForColumnFamily(domain);
if (cfh == nullptr) {
return Status(1, "Could not get column family for " + domain);
@ -249,6 +260,10 @@ Status DBHandle::Delete(const std::string& domain, const std::string& key) {
Status DBHandle::Scan(const std::string& domain,
std::vector<std::string>& results) {
if (getDB() == nullptr) {
return Status(1, "Database not opened");
}
auto cfh = getHandleForColumnFamily(domain);
if (cfh == nullptr) {
return Status(1, "Could not get column family for " + domain);

View File

@ -376,7 +376,7 @@ EventID EventSubscriberPlugin::getEventID() {
{
boost::lock_guard<boost::mutex> lock(event_id_lock_);
status = db->Get(kEvents, eid_key, last_eid_value);
if (!status.ok()) {
if (!status.ok() || last_eid_value.empty()) {
last_eid_value = "0";
}

View File

@ -19,6 +19,7 @@
#include <osquery/core.h>
#include <osquery/tables.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
namespace osquery {
namespace tables {
@ -116,7 +117,8 @@ void genProcessMap(const std::string& pid, QueryData& results) {
}
r["permissions"] = fields[1];
r["offset"] = BIGINT(std::stoll(fields[2], nullptr, 16));
auto offset = std::stoll(fields[2], nullptr, 16);
r["offset"] = (offset != 0) ? BIGINT(offset) : r["start"];
r["device"] = fields[3];
r["inode"] = fields[4];
@ -154,20 +156,32 @@ struct SimpleProcStat {
std::string start_time;
};
SimpleProcStat getProcStat(const std::string& pid) {
static inline SimpleProcStat getProcStat(const std::string& pid) {
SimpleProcStat stat;
std::string content;
if (readFile(getProcAttr("stat", pid), content).ok()) {
auto detail_start = content.find_last_of(")");
auto start = content.find_last_of(")");
// Start parsing stats from ") <MODE>..."
auto details = osquery::split(content.substr(detail_start + 2), " ");
if (start == std::string::npos || content.size() <= start + 2) {
return stat;
}
auto details = osquery::split(content.substr(start + 2), " ");
if (details.size() <= 19) {
return stat;
}
stat.state = details.at(0);
stat.parent = details.at(1);
stat.group = details.at(2);
stat.user_time = details.at(11);
stat.system_time = details.at(12);
stat.nice = details.at(16);
try {
stat.start_time = TEXT(AS_LITERAL(BIGINT_LITERAL, details.at(19)) / 100);
} catch (const boost::bad_lexical_cast& e) {
stat.start_time = "-1";
}
}
if (readFile(getProcAttr("status", pid), content).ok()) {
@ -221,12 +235,10 @@ void genProcess(const std::string& pid, QueryData& results) {
r["group"] = proc_stat.group;
r["state"] = proc_stat.state;
r["nice"] = proc_stat.nice;
// Read/parse cmdline arguments.
r["cmdline"] = readProcCMDLine(pid);
r["cwd"] = readProcLink("cwd", pid);
r["root"] = readProcLink("root", pid);
r["uid"] = proc_stat.real_uid;
r["euid"] = proc_stat.effective_uid;
r["gid"] = proc_stat.real_gid;