Merge pull request #866 from theopolis/ext_managed_worker

Set osquery_extensions for worker child
This commit is contained in:
Teddy Reed 2015-03-17 10:47:23 -07:00
commit 10f57c6602
4 changed files with 25 additions and 8 deletions

View File

@ -191,7 +191,7 @@ void Initializer::initWatcher() {
// Add a watcher service thread to start/watch an optional worker and set
// of optional extensions in the autoload paths.
if (Watcher::countExtensions() > 0 || !FLAGS_disable_watchdog) {
if (Watcher::hasManagedExtensions() || !FLAGS_disable_watchdog) {
Dispatcher::getInstance().addService(
std::make_shared<WatcherRunner>(argc_, argv_, !FLAGS_disable_watchdog));
}
@ -231,7 +231,7 @@ void Initializer::initWorkerWatcher(const std::string& name) {
}
}
bool Initializer::isWorker() { return (getenv("OSQUERYD_WORKER") != nullptr); }
bool Initializer::isWorker() { return (getenv("OSQUERY_WORKER") != nullptr); }
void Initializer::initConfigLogger() {
// Use a delay, meaning the amount of milliseconds waited for extensions.
@ -241,7 +241,7 @@ void Initializer::initConfigLogger() {
while (!Registry::setActive("config", FLAGS_config_plugin)) {
// If there is at least 1 autoloaded extension, it may broadcast a route
// to the active config plugin.
if (Watcher::countExtensions() == 0 || delay > timeout * 1000) {
if (!Watcher::hasManagedExtensions() || delay > timeout * 1000) {
LOG(ERROR) << "Config plugin not found: " << FLAGS_config_plugin;
::exit(EXIT_CATASTROPHIC);
}
@ -251,7 +251,7 @@ void Initializer::initConfigLogger() {
// Try the same wait for a logger pluing too.
while (!Registry::setActive("logger", FLAGS_logger_plugin)) {
if (Watcher::countExtensions() == 0 || delay > timeout * 1000) {
if (!Watcher::hasManagedExtensions() || delay > timeout * 1000) {
LOG(ERROR) << "Logger plugin not found: " << FLAGS_logger_plugin;
::exit(EXIT_CATASTROPHIC);
}

View File

@ -151,10 +151,22 @@ void Watcher::addExtensionPath(const std::string& path) {
}
}
bool Watcher::hasManagedExtensions() {
if (instance().extensions_.size() > 0) {
return true;
}
// A watchdog process may hint to a worker the number of managed extensions.
// Setting this counter to 0 will prevent the worker from waiting for missing
// dependent config plugins. Otherwise, its existance, will cause a worker to
// wait for missing plugins to broadcast from managed extensions.
return (getenv("OSQUERY_EXTENSIONS") != nullptr);
}
bool WatcherRunner::ok() {
interruptableSleep(getWorkerLimit(INTERVAL) * 1000);
// Watcher is OK to run if a worker or at least one extension exists.
return (Watcher::getWorker() >= 0 || Watcher::countExtensions() > 0);
return (Watcher::getWorker() >= 0 || Watcher::hasManagedExtensions());
}
void WatcherRunner::enter() {
@ -294,6 +306,12 @@ void WatcherRunner::createWorker() {
::exit(EXIT_FAILURE);
}
// Set an environment signaling to potential plugin-dependent workers to wait
// for extensions to broadcast.
if (Watcher::hasManagedExtensions()) {
setenv("OSQUERY_EXTENSIONS", "true", 1);
}
auto worker_pid = fork();
if (worker_pid < 0) {
// Unrecoverable error, cannot create a worker process.
@ -301,7 +319,7 @@ void WatcherRunner::createWorker() {
::exit(EXIT_FAILURE);
} else if (worker_pid == 0) {
// This is the new worker process, no watching needed.
setenv("OSQUERYD_WORKER", std::to_string(getpid()).c_str(), 1);
setenv("OSQUERY_WORKER", std::to_string(getpid()).c_str(), 1);
// Get the complete path of the osquery process binary.
auto exec_path = fs::system_complete(fs::path(qd[0]["path"]));
execve(exec_path.string().c_str(), argv_, environ);

View File

@ -132,7 +132,7 @@ class Watcher : private boost::noncopyable {
static void reset(pid_t child);
/// Return the number of autoloadable extensions.
static size_t countExtensions() { return instance().extensions_.size(); }
static bool hasManagedExtensions();
private:
/// Do not request the lock until extensions are used.

View File

@ -332,7 +332,6 @@ class ExtensionTests(test_base.ProcessGenerator, unittest.TestCase):
loader = test_base.Autoloader("/tmp/osqueryd-temp-ext.load",
[test_base.ARGS.build + "/osquery/example_extension.ext"])
daemon = self._run_daemon({
"disable_watchdog": True,
"extensions_autoload": loader.path,
"config_plugin": "example",
})