[devmgr] Make vfs_exit private to Coordinator
In order to isolate more of Coordinator's dependencies, move vfs_exit
from main.cpp into coordinator.cpp.
Test: Ran Fuchsia and /system/test/ddk tests.
Change-Id: I14592bd2f7438ded87f4136c62df86a367e0e36d
diff --git a/system/core/devmgr/devmgr/coordinator.cpp b/system/core/devmgr/devmgr/coordinator.cpp
index 61f3b60..c8f056d 100644
--- a/system/core/devmgr/devmgr/coordinator.cpp
+++ b/system/core/devmgr/devmgr/coordinator.cpp
@@ -56,16 +56,26 @@
constexpr char kBootFirmwareDir[] = "/boot/lib/firmware";
constexpr char kSystemFirmwareDir[] = "/system/lib/firmware";
+// Tells VFS to exit by shutting down the fshost.
+void vfs_exit(const zx::event& fshost_event) {
+ zx_status_t status;
+ if ((status = fshost_event.signal(0, FSHOST_SIGNAL_EXIT)) != ZX_OK) {
+ printf("devmgr: Failed to signal VFS exit\n");
+ return;
+ } else if ((status = fshost_event.wait_one(FSHOST_SIGNAL_EXIT_DONE,
+ zx::deadline_after(zx::sec(5)),
+ nullptr)) != ZX_OK) {
+ printf("devmgr: Failed to wait for VFS exit completion\n");
+ }
+}
+
} // namespace
namespace devmgr {
uint32_t log_flags = LOG_ERROR | LOG_INFO;
-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), asan_drivers_(asan_drivers) {}
+Coordinator::Coordinator(CoordinatorConfig config) : config_(std::move(config)) {}
bool Coordinator::InSuspend() const {
return suspend_context_.flags() == SuspendContext::Flags::kSuspend;
@@ -213,17 +223,17 @@
}
if ((len == 6) && !memcmp(cmd, "reboot", 6)) {
- devmgr_vfs_exit();
+ vfs_exit(config_.fshost_event);
Suspend(DEVICE_SUSPEND_FLAG_REBOOT);
return ZX_OK;
}
if ((len == 17) && !memcmp(cmd, "reboot-bootloader", 17)) {
- devmgr_vfs_exit();
+ vfs_exit(config_.fshost_event);
Suspend(DEVICE_SUSPEND_FLAG_REBOOT_BOOTLOADER);
return ZX_OK;
}
if ((len == 15) && !memcmp(cmd, "reboot-recovery", 15)) {
- devmgr_vfs_exit();
+ vfs_exit(config_.fshost_event);
Suspend(DEVICE_SUSPEND_FLAG_REBOOT_RECOVERY);
return ZX_OK;
}
@@ -232,7 +242,7 @@
return ZX_OK;
}
if (len == 8 && (!memcmp(cmd, "poweroff", 8) || !memcmp(cmd, "shutdown", 8))) {
- devmgr_vfs_exit();
+ vfs_exit(config_.fshost_event);
Suspend(DEVICE_SUSPEND_FLAG_POWEROFF);
return ZX_OK;
}
@@ -557,8 +567,8 @@
}
dh->set_hrpc(dh_hrpc);
- if ((r = dc_launch_devhost(dh.get(), loader_service_, get_devhost_bin(asan_drivers_), name,
- hrpc, zx::unowned_job(devhost_job_))) < 0) {
+ if ((r = dc_launch_devhost(dh.get(), loader_service_, get_devhost_bin(config_.asan_drivers),
+ name, hrpc, zx::unowned_job(config_.devhost_job))) < 0) {
zx_handle_close(dh->hrpc());
return r;
}
@@ -718,7 +728,7 @@
dev->wait.set_object(dev->hrpc.get());
dev->wait.set_trigger(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED);
- if ((r = dev->wait.Begin(dispatcher_)) != ZX_OK) {
+ if ((r = dev->wait.Begin(config_.dispatcher)) != ZX_OK) {
devfs_unpublish(dev.get());
return r;
}
@@ -743,7 +753,7 @@
dev.get(), dev->name, dev->prop_count, dev->args.get(), dev->parent);
if (!invisible) {
- r = dev->publish_task.Post(dispatcher_);
+ r = dev->publish_task.Post(config_.dispatcher);
if (r != ZX_OK) {
return r;
}
@@ -761,7 +771,7 @@
if (dev->flags & DEV_CTX_INVISIBLE) {
dev->flags &= ~DEV_CTX_INVISIBLE;
devfs_advertise(dev);
- zx_status_t r = dev->publish_task.Post(dispatcher_);
+ zx_status_t r = dev->publish_task.Post(config_.dispatcher);
if (r != ZX_OK) {
return r;
}
@@ -870,7 +880,8 @@
if (parent->retries > 0) {
// Add device with an exponential backoff.
- zx_status_t r = parent->publish_task.PostDelayed(dispatcher_, parent->backoff);
+ zx_status_t r = parent->publish_task.PostDelayed(config_.dispatcher,
+ parent->backoff);
if (r != ZX_OK) {
return r;
}
@@ -1957,14 +1968,14 @@
}
fbl::unique_ptr<Driver> Coordinator::ValidateDriver(fbl::unique_ptr<Driver> drv) {
- if ((drv->flags & ZIRCON_DRIVER_NOTE_FLAG_ASAN) && !asan_drivers_) {
+ if ((drv->flags & ZIRCON_DRIVER_NOTE_FLAG_ASAN) && !config_.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;
+ config_.asan_drivers = true;
}
return drv;
}
@@ -1977,7 +1988,7 @@
if (!driver) {
return;
}
- async::PostTask(dispatcher_, [this, drv = driver.release()] {
+ async::PostTask(config_.dispatcher, [this, drv = driver.release()] {
drivers_.push_back(drv);
BindDriver(drv);
});
@@ -2029,7 +2040,7 @@
}
}
-// BindDRiver is called when a new driver becomes available to
+// 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).
void Coordinator::BindDriver(Driver* drv) {
diff --git a/system/core/devmgr/devmgr/coordinator.h b/system/core/devmgr/devmgr/coordinator.h
index 15327b9..fa5b203 100644
--- a/system/core/devmgr/devmgr/coordinator.h
+++ b/system/core/devmgr/devmgr/coordinator.h
@@ -14,6 +14,7 @@
#include <lib/async/cpp/wait.h>
#include <lib/fit/function.h>
#include <lib/zx/channel.h>
+#include <lib/zx/event.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/socket.h>
@@ -262,6 +263,19 @@
const char* sys_device_driver = nullptr;
};
+struct CoordinatorConfig {
+ // Job for all devhosts.
+ zx::job devhost_job;
+ // Event that controls the fshost.
+ zx::event fshost_event;
+ // Async dispatcher for the coordinator.
+ async_dispatcher_t* dispatcher;
+ // Whether we require /system.
+ bool require_system;
+ // Whether we require ASan drivers.
+ bool asan_drivers;
+};
+
class Coordinator {
public:
Coordinator(const Coordinator&) = delete;
@@ -270,8 +284,7 @@
Coordinator(Coordinator&&) = delete;
Coordinator& operator=(Coordinator&&) = delete;
- Coordinator(zx::job devhost_job, async_dispatcher_t* dispatcher, bool require_system,
- bool asan_drivers);
+ explicit Coordinator(CoordinatorConfig config);
zx_status_t InitializeCoreDevices();
@@ -337,8 +350,9 @@
void DriverAddedInit(Driver* drv, const char* version);
void DriverAddedSys(Driver* drv, const char* version);
- async_dispatcher_t* dispatcher() const { return dispatcher_; }
- bool require_system() const { return require_system_; }
+ const zx::event& fshost_event() const { return config_.fshost_event; }
+ async_dispatcher_t* dispatcher() const { return config_.dispatcher; }
+ bool require_system() const { return config_.require_system; }
void set_running(bool running) { running_ = running; }
void set_loader_service(DevhostLoaderService* loader_service) {
@@ -363,11 +377,7 @@
bool system_loaded() const { return system_loaded_; }
private:
- zx::job devhost_job_;
- async_dispatcher_t* dispatcher_;
- bool require_system_;
- bool asan_drivers_;
-
+ CoordinatorConfig config_;
bool running_ = false;
bool launched_first_devhost_ = false;
DevhostLoaderService* loader_service_ = nullptr;
diff --git a/system/core/devmgr/devmgr/devmgr.h b/system/core/devmgr/devmgr/devmgr.h
index 95035fb..1adac8e 100644
--- a/system/core/devmgr/devmgr/devmgr.h
+++ b/system/core/devmgr/devmgr/devmgr.h
@@ -28,9 +28,6 @@
// Clones the channel connected to the root of devfs.
zx::channel devfs_root_clone();
-// Tells VFS to exit by shutting down the fshost.
-void devmgr_vfs_exit();
-
zx_handle_t get_root_resource();
zx::job get_sysinfo_job_root();
diff --git a/system/core/devmgr/devmgr/main.cpp b/system/core/devmgr/devmgr/main.cpp
index 2eb9a31..0cb38d5 100644
--- a/system/core/devmgr/devmgr/main.cpp
+++ b/system/core/devmgr/devmgr/main.cpp
@@ -64,8 +64,6 @@
zx::job fuchsia_job;
zx::channel svchost_outgoing;
- zx::event fshost_event;
-
zx::channel fs_root;
} g_handles;
@@ -150,13 +148,13 @@
zx::time deadline = zx::deadline_after(zx::sec(appmgr_timeout));
do {
- zx_status_t status = g_handles.fshost_event.wait_one(FSHOST_SIGNAL_READY, deadline,
- nullptr);
+ zx_status_t status = coordinator->fshost_event().wait_one(FSHOST_SIGNAL_READY, deadline,
+ nullptr);
if (status == ZX_ERR_TIMED_OUT) {
if (g_handles.appmgr_server.is_valid()) {
if (coordinator->require_system()) {
- printf("devmgr: appmgr not launched in %zus, closing appmgr handle\n",
- appmgr_timeout);
+ fprintf(stderr, "devmgr: appmgr not launched in %zus, closing appmgr handle\n",
+ appmgr_timeout);
}
g_handles.appmgr_server.reset();
}
@@ -164,10 +162,13 @@
continue;
}
if (status != ZX_OK) {
- printf("devmgr: error waiting on fuchsia start event: %d\n", status);
+ fprintf(stderr, "devmgr: error waiting on fuchsia start event: %d\n", status);
break;
}
- g_handles.fshost_event.signal(FSHOST_SIGNAL_READY, 0);
+ status = coordinator->fshost_event().signal(FSHOST_SIGNAL_READY, 0);
+ if (status != ZX_OK) {
+ fprintf(stderr, "devmgr: error signaling fshost: %d\n", status);
+ }
if (!drivers_loaded) {
// we're starting the appmgr because /system is present
@@ -436,7 +437,8 @@
// pass fuchsia start event to fshost
zx::event fshost_event_duplicate;
- if (g_handles.fshost_event.duplicate(ZX_RIGHT_SAME_RIGHTS, &fshost_event_duplicate) == ZX_OK) {
+ if (coordinator->fshost_event().duplicate(ZX_RIGHT_SAME_RIGHTS, &fshost_event_duplicate) ==
+ ZX_OK) {
handles[n] = fshost_event_duplicate.release();
types[n++] = PA_HND(PA_USER1, 0);
}
@@ -753,18 +755,6 @@
}
}
-void devmgr_vfs_exit() {
- zx_status_t status;
- if ((status = g_handles.fshost_event.signal(0, FSHOST_SIGNAL_EXIT)) != ZX_OK) {
- printf("devmgr: Failed to signal VFS exit\n");
- return;
- } else if ((status = g_handles.fshost_event.wait_one(FSHOST_SIGNAL_EXIT_DONE,
- zx::deadline_after(zx::sec(5)),
- nullptr)) != ZX_OK) {
- printf("devmgr: Failed to wait for VFS exit completion\n");
- }
-}
-
zx::channel fs_clone(const char* path) {
if (!strcmp(path, "dev")) {
return devfs_root_clone();
@@ -805,20 +795,25 @@
fetch_root_resource();
g_handles.root_job = zx::job::default_job();
+ bool require_system = devmgr::getenv_bool("devmgr.require-system", false);
- zx::job devhost_job;
- zx_status_t status = CreateDevhostJob(*g_handles.root_job, &devhost_job);
+ async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
+ devmgr::CoordinatorConfig config;
+ config.dispatcher = loop.dispatcher();
+ config.require_system = require_system;
+ config.asan_drivers = devmgr::getenv_bool("devmgr.devhost.asan", false);
+ zx_status_t status = CreateDevhostJob(*g_handles.root_job, &config.devhost_job);
if (status != ZX_OK) {
- printf("unable to create devhost job\n");
+ fprintf(stderr, "devmgr: unable to create devhost job: %d\n", status);
+ return 1;
+ }
+ status = zx::event::create(0, &config.fshost_event);
+ if (status != ZX_OK) {
+ fprintf(stderr, "devmgr: unable to create fshost event: %d\n", status);
return 1;
}
- 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,
- asan_drivers);
+ devmgr::Coordinator coordinator(std::move(config));
devmgr::devfs_init(&coordinator.root_device(), loop.dispatcher());
// Check if whatever launched devmgr gave a channel to be connected to /dev.
@@ -843,7 +838,6 @@
}
zx::channel::create(0, &g_handles.appmgr_client, &g_handles.appmgr_server);
- zx::event::create(0, &g_handles.fshost_event);
char** e = environ;
while (*e) {