[devmgr] Move dc_asan_drivers out of global scope
Move dc_asan_drivers and dc_launched_first_devhost out of global scope,
and into Coordinator.
Test: Ran Fuchsia and /system/test/ddk tests.
Change-Id: I7d4ca3031025c41c18520501c1ec2383a1adc66f
diff --git a/system/core/devmgr/devmgr/coordinator.cpp b/system/core/devmgr/devmgr/coordinator.cpp
index f814506..fe083f6 100644
--- a/system/core/devmgr/devmgr/coordinator.cpp
+++ b/system/core/devmgr/devmgr/coordinator.cpp
@@ -62,12 +62,10 @@
uint32_t log_flags = LOG_ERROR | LOG_INFO;
-bool dc_asan_drivers = false;
-bool dc_launched_first_devhost = false;
-
-Coordinator::Coordinator(zx::job devhost_job, async_dispatcher_t* dispatcher, bool require_system)
+Coordinator::Coordinator(zx::job devhost_job, async_dispatcher_t* dispatcher, bool require_system,
+ bool asan_drivers)
: devhost_job_(std::move(devhost_job)), dispatcher_(dispatcher),
- require_system_(require_system) {}
+ require_system_(require_system), asan_drivers_(asan_drivers) {}
bool Coordinator::InSuspend() const {
return suspend_context_.flags() == SuspendContext::Flags::kSuspend;
@@ -426,14 +424,14 @@
}
}
-static const char* get_devhost_bin() {
+static const char* get_devhost_bin(bool asan_drivers) {
// If there are any ASan drivers, use the ASan-supporting devhost for
// all drivers because even a devhost launched initially with just a
// non-ASan driver might later load an ASan driver. One day we might
// be able to be more flexible about which drivers must get loaded into
// the same devhost and thus be able to use both ASan and non-ASan
// devhosts at the same time when only a subset of drivers use ASan.
- if (dc_asan_drivers)
+ if (asan_drivers)
return "/boot/bin/devhost.asan";
return "/boot/bin/devhost";
}
@@ -479,9 +477,8 @@
}
static zx_status_t dc_launch_devhost(Devhost* host, DevhostLoaderService* loader_service,
- const char* name, zx_handle_t hrpc, zx::unowned_job devhost_job) {
- const char* devhost_bin = get_devhost_bin();
-
+ const char* devhost_bin, const char* name, zx_handle_t hrpc,
+ zx::unowned_job devhost_job) {
launchpad_t* lp;
launchpad_create_with_jobs(devhost_job->get(), 0, name, &lp);
launchpad_load_from_file(lp, devhost_bin);
@@ -544,8 +541,6 @@
log(INFO, "devcoord: launch devhost '%s': pid=%zu\n",
name, host->koid());
- dc_launched_first_devhost = true;
-
return ZX_OK;
}
@@ -567,10 +562,12 @@
}
dh->set_hrpc(dh_hrpc);
- if ((r = dc_launch_devhost(dh.get(), loader_service_, name, hrpc, zx::unowned_job(devhost_job_))) < 0) {
+ if ((r = dc_launch_devhost(dh.get(), loader_service_, get_devhost_bin(asan_drivers_), name,
+ hrpc, zx::unowned_job(devhost_job_))) < 0) {
zx_handle_close(dh->hrpc());
return r;
}
+ launched_first_devhost_ = true;
if (parent) {
dh->set_parent(parent);
@@ -2005,34 +2002,79 @@
(memcmp(&root_device_binding, drv->binding.get(), sizeof(root_device_binding)) == 0);
}
-// DriverAddedInit is called from driver enumeration during
-// startup and before the devcoordinator starts running. Enumerated
-// drivers are added directly to the all-drivers or fallback list.
-//
-// TODO: fancier priorities
-void Coordinator::DriverAddedInit(Driver* drv, const char* version) {
- if (version[0] == '*') {
- // fallback driver, load only if all else fails
- fallback_drivers_.push_front(drv);
- } else if (version[0] == '!') {
- // debugging / development hack
- // prioritize drivers with version "!..." over others
- drivers_.push_front(drv);
- } else {
- drivers_.push_back(drv);
+fbl::unique_ptr<Driver> Coordinator::ValidateDriver(fbl::unique_ptr<Driver> drv) {
+ if ((drv->flags & ZIRCON_DRIVER_NOTE_FLAG_ASAN) && !asan_drivers_) {
+ if (launched_first_devhost_) {
+ log(ERROR, "%s (%s) requires ASan: cannot load after boot;"
+ " consider devmgr.devhost.asan=true\n",
+ drv->libname.c_str(), drv->name.c_str());
+ return nullptr;
+ }
+ asan_drivers_ = true;
}
+ return drv;
}
// DriverAdded is called when a driver is added after the
// devcoordinator has started. The driver is added to the new-drivers
// list and work is queued to process it.
void Coordinator::DriverAdded(Driver* drv, const char* version) {
- async::PostTask(dispatcher_, [this, drv] {
+ auto driver = ValidateDriver(fbl::unique_ptr<Driver>(drv));
+ if (!driver) {
+ return;
+ }
+ async::PostTask(dispatcher_, [this, drv = driver.release()] {
drivers_.push_back(drv);
BindDriver(drv);
});
}
+// DriverAddedInit is called from driver enumeration during
+// startup and before the devcoordinator starts running. Enumerated
+// drivers are added directly to the all-drivers or fallback list.
+//
+// TODO: fancier priorities
+void Coordinator::DriverAddedInit(Driver* drv, const char* version) {
+ auto driver = ValidateDriver(fbl::unique_ptr<Driver>(drv));
+ if (!driver) {
+ return;
+ }
+ if (version[0] == '*') {
+ // fallback driver, load only if all else fails
+ fallback_drivers_.push_front(driver.release());
+ } else if (version[0] == '!') {
+ // debugging / development hack
+ // prioritize drivers with version "!..." over others
+ drivers_.push_front(driver.release());
+ } else {
+ drivers_.push_back(driver.release());
+ }
+}
+
+// Drivers added during system scan (from the dedicated thread)
+// are added to system_drivers for bulk processing once
+// CTL_ADD_SYSTEM is sent.
+//
+// TODO: fancier priority management
+void Coordinator::DriverAddedSys(Driver* drv, const char* version) {
+ auto driver = ValidateDriver(fbl::unique_ptr<Driver>(drv));
+ if (!driver) {
+ return;
+ }
+ log(INFO, "devmgr: adding system driver '%s' '%s'\n", driver->name.c_str(),
+ driver->libname.c_str());
+ if (load_vmo(driver->libname.c_str(), &driver->dso_vmo)) {
+ log(ERROR, "devmgr: system driver '%s' '%s' could not cache DSO\n", driver->name.c_str(),
+ driver->libname.c_str());
+ }
+ if (version[0] == '*') {
+ // de-prioritize drivers that are "fallback"
+ system_drivers_.push_back(driver.release());
+ } else {
+ system_drivers_.push_front(driver.release());
+ }
+}
+
// BindDRiver is called when a new driver becomes available to
// the Coordinator. Existing devices are inspected to see if the
// new driver is bindable to them (unless they are already bound).
@@ -2108,26 +2150,6 @@
drivers_.splice(drivers_.end(), fallback_drivers_);
}
-// Drivers added during system scan (from the dedicated thread)
-// are added to system_drivers for bulk processing once
-// CTL_ADD_SYSTEM is sent.
-//
-// TODO: fancier priority management
-void Coordinator::DriverAddedSys(Driver* drv, const char* version) {
- log(INFO, "devmgr: adding system driver '%s' '%s'\n", drv->name.c_str(), drv->libname.c_str());
-
- if (load_vmo(drv->libname.c_str(), &drv->dso_vmo)) {
- log(ERROR, "devmgr: system driver '%s' '%s' could not cache DSO\n", drv->name.c_str(),
- drv->libname.c_str());
- }
- if (version[0] == '*') {
- // de-prioritize drivers that are "fallback"
- system_drivers_.push_back(drv);
- } else {
- system_drivers_.push_front(drv);
- }
-}
-
void coordinator_setup(Coordinator* coordinator, DevmgrArgs args) {
log(INFO, "devmgr: coordinator_setup()\n");
@@ -2152,8 +2174,6 @@
coordinator->set_suspend_fallback(getenv_bool("devmgr.suspend-timeout-fallback", false));
coordinator->set_suspend_debug(getenv_bool("devmgr.suspend-timeout-debug", false));
- dc_asan_drivers = getenv_bool("devmgr.devhost.asan", false);
-
zx_status_t status = coordinator->InitializeCoreDevices();
if (status != ZX_OK) {
log(ERROR, "devmgr: failed to initialize core devices\n");
diff --git a/system/core/devmgr/devmgr/coordinator.h b/system/core/devmgr/devmgr/coordinator.h
index 59d5b93..2fa6e8a 100644
--- a/system/core/devmgr/devmgr/coordinator.h
+++ b/system/core/devmgr/devmgr/coordinator.h
@@ -415,7 +415,8 @@
Coordinator(Coordinator&&) = delete;
Coordinator& operator=(Coordinator&&) = delete;
- Coordinator(zx::job devhost_job, async_dispatcher_t* dispatcher, bool require_system);
+ Coordinator(zx::job devhost_job, async_dispatcher_t* dispatcher, bool require_system,
+ bool asan_drivers);
zx_status_t InitializeCoreDevices();
@@ -510,8 +511,10 @@
zx::job devhost_job_;
async_dispatcher_t* dispatcher_;
bool require_system_;
+ bool asan_drivers_;
bool running_ = false;
+ bool launched_first_devhost_ = false;
DevhostLoaderService* loader_service_ = nullptr;
// This socket is used by DmPrintf for output, and DmPrintf can be called in
// the context of a const member function, therefore it is also const. Given
@@ -547,6 +550,8 @@
bool suspend_debug_ = false;
bool system_available_ = false;
bool system_loaded_ = false;
+
+ fbl::unique_ptr<Driver> ValidateDriver(fbl::unique_ptr<Driver> drv);
};
void coordinator_setup(Coordinator* coordinator, DevmgrArgs args);
@@ -561,9 +566,6 @@
zx_device_prop_t* props, size_t prop_count,
bool autobind);
-extern bool dc_asan_drivers;
-extern bool dc_launched_first_devhost;
-
// Methods for composing FIDL RPCs to the devhosts
zx_status_t dh_send_remove_device(const Device* dev);
zx_status_t dh_send_create_device(Device* dev, Devhost* dh, zx::channel rpc, zx::vmo driver,
diff --git a/system/core/devmgr/devmgr/drivers.cpp b/system/core/devmgr/devmgr/drivers.cpp
index 31c4c29..5eca592 100644
--- a/system/core/devmgr/devmgr/drivers.cpp
+++ b/system/core/devmgr/devmgr/drivers.cpp
@@ -20,20 +20,18 @@
#include <zircon/driver/binding.h>
-namespace devmgr {
-
namespace {
struct AddContext {
const char* libname;
- DriverLoadCallback func;
+ devmgr::DriverLoadCallback func;
};
bool is_driver_disabled(const char* name) {
// driver.<driver_name>.disable
char opt[16 + DRIVER_NAME_LEN_MAX];
snprintf(opt, 16 + DRIVER_NAME_LEN_MAX, "driver.%s.disable", name);
- return getenv_bool(opt, false);
+ return devmgr::getenv_bool(opt, false);
}
void found_driver(zircon_driver_note_payload_t* note,
@@ -49,19 +47,7 @@
return;
}
- const char* libname = context->libname;
-
- if ((note->flags & ZIRCON_DRIVER_NOTE_FLAG_ASAN) && !dc_asan_drivers) {
- if (dc_launched_first_devhost) {
- log(ERROR, "%s (%s) requires ASan: cannot load after boot;"
- " consider devmgr.devhost.asan=true\n",
- libname, note->name);
- return;
- }
- dc_asan_drivers = true;
- }
-
- auto drv = fbl::make_unique<Driver>();
+ auto drv = fbl::make_unique<devmgr::Driver>();
if (drv == nullptr) {
return;
}
@@ -76,7 +62,7 @@
drv->binding_size = static_cast<uint32_t>(bindlen);
drv->flags = note->flags;
- drv->libname.Set(libname);
+ drv->libname.Set(context->libname);
drv->name.Set(note->name);
#if VERBOSE_DRIVER_LOAD
@@ -96,6 +82,8 @@
} // namespace
+namespace devmgr {
+
void find_loadable_drivers(const char* path, DriverLoadCallback func) {
DIR* dir = opendir(path);
diff --git a/system/core/devmgr/devmgr/main.cpp b/system/core/devmgr/devmgr/main.cpp
index cd5cc27..200bb99 100644
--- a/system/core/devmgr/devmgr/main.cpp
+++ b/system/core/devmgr/devmgr/main.cpp
@@ -814,8 +814,10 @@
async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
bool require_system = devmgr::getenv_bool("devmgr.require-system", false);
+ bool asan_drivers = devmgr::getenv_bool("devmgr.devhost.asan", false);
- devmgr::Coordinator coordinator(std::move(devhost_job), loop.dispatcher(), require_system);
+ devmgr::Coordinator coordinator(std::move(devhost_job), loop.dispatcher(), require_system,
+ asan_drivers);
devmgr::devfs_init(&coordinator.root_device(), loop.dispatcher());
// Check if whatever launched devmgr gave a channel to be connected to /dev.