[bootsvc] Set loader service directly in launchpad, not ambient value
The BootfsLoaderService> is only for the next process bootsvc
launches. It shouldn't be connected to bootsvc's own dynamic
linker.
Change-Id: Ia4dd85d8df83f083013875b685d7cf727cd02f4c
diff --git a/zircon/system/core/bootsvc/main.cpp b/zircon/system/core/bootsvc/main.cpp
index cd3d61b..52a523a 100644
--- a/zircon/system/core/bootsvc/main.cpp
+++ b/zircon/system/core/bootsvc/main.cpp
@@ -3,10 +3,6 @@
// found in the LICENSE file.
#include <ctype.h>
-#include <sstream>
-#include <stdio.h>
-#include <utility>
-
#include <fbl/string.h>
#include <fbl/vector.h>
#include <fuchsia/boot/c/fidl.h>
@@ -14,6 +10,10 @@
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/debuglog.h>
+#include <sstream>
+#include <stdio.h>
+#include <thread>
+#include <utility>
#include <zircon/boot/image.h>
#include <zircon/dlfcn.h>
#include <zircon/process.h>
@@ -94,11 +94,6 @@
return ZX_OK;
}
-struct LaunchNextProcessArgs {
- fbl::RefPtr<bootsvc::BootfsService> bootfs;
- fbl::RefPtr<bootsvc::SvcfsService> svcfs;
-};
-
// Launch the next process in the boot chain.
// It will receive:
// - stdout wired up via a debuglog handle
@@ -109,9 +104,9 @@
// - A handle to each of the bootdata VMOs the kernel provided
// - A handle to a channel containing the root resource, with type
// BOOTSVC_ROOT_RESOURCE_CHANNEL_HND
-int LaunchNextProcess(void* raw_ctx) {
- fbl::unique_ptr<LaunchNextProcessArgs> args(static_cast<LaunchNextProcessArgs*>(raw_ctx));
-
+void LaunchNextProcess(fbl::RefPtr<bootsvc::BootfsService> bootfs,
+ fbl::RefPtr<bootsvc::SvcfsService> svcfs,
+ fbl::RefPtr<bootsvc::BootfsLoaderService> loader_svc) {
const char* bootsvc_next = getenv("bootsvc.next");
if (bootsvc_next == nullptr) {
bootsvc_next = "bin/devcoordinator";
@@ -126,19 +121,19 @@
zx::vmo program;
uint64_t file_size;
const char* next_program = next_args[0].c_str();
- zx_status_t status = args->bootfs->Open(next_program, &program, &file_size);
+ zx_status_t status = bootfs->Open(next_program, &program, &file_size);
ZX_ASSERT_MSG(status == ZX_OK, "bootsvc: failed to open '%s': %s\n", next_program,
zx_status_get_string(status));
// Get the bootfs fuchsia.io.Node service channel that we will hand to the
// next process in the boot chain.
zx::channel bootfs_conn;
- status = args->bootfs->CreateRootConnection(&bootfs_conn);
+ status = bootfs->CreateRootConnection(&bootfs_conn);
ZX_ASSERT_MSG(status == ZX_OK, "bootfs conn creation failed: %s\n",
zx_status_get_string(status));
zx::channel svcfs_conn;
- status = args->svcfs->CreateRootConnection(&svcfs_conn);
+ status = svcfs->CreateRootConnection(&svcfs_conn);
ZX_ASSERT_MSG(status == ZX_OK, "svcfs conn creation failed: %s\n",
zx_status_get_string(status));
@@ -147,6 +142,17 @@
launchpad_t* lp;
launchpad_create(0, next_program, &lp);
+ {
+ // Use the local loader service backed directly by the primary BOOTFS.
+ zx::channel local_loader_conn;
+ status = loader_svc->Connect(&local_loader_conn);
+ ZX_ASSERT_MSG(status == ZX_OK,
+ "failed to connect to BootfsLoaderService : %s\n",
+ zx_status_get_string(status));
+ zx_handle_t old =
+ launchpad_use_loader_service(lp, local_loader_conn.release());
+ ZX_ASSERT(old == ZX_HANDLE_INVALID);
+ }
launchpad_load_from_vmo(lp, program.release());
launchpad_clone(lp, LP_CLONE_DEFAULT_JOB);
@@ -181,20 +187,6 @@
} else {
printf("bootsvc: Launched %s\n", next_program);
}
- return 0;
-}
-
-void StartLaunchNextProcessThread(const fbl::RefPtr<bootsvc::BootfsService>& bootfs,
- const fbl::RefPtr<bootsvc::SvcfsService>& svcfs) {
- auto args = std::make_unique<LaunchNextProcessArgs>();
- args->bootfs = bootfs;
- args->svcfs = svcfs;
-
- thrd_t t;
- int status = thrd_create(&t, LaunchNextProcess, args.release());
- ZX_ASSERT(status == thrd_success);
- status = thrd_detach(t);
- ZX_ASSERT(status == thrd_success);
}
} // namespace
@@ -258,24 +250,16 @@
// Creating the loader service
printf("bootsvc: Creating loader service...\n");
- fbl::RefPtr<bootsvc::BootfsLoaderService> loader;
- status = bootsvc::BootfsLoaderService::Create(bootfs_svc, loop.dispatcher(), &loader);
+ fbl::RefPtr<bootsvc::BootfsLoaderService> loader_svc;
+ status = bootsvc::BootfsLoaderService::Create(bootfs_svc, loop.dispatcher(), &loader_svc);
ZX_ASSERT_MSG(status == ZX_OK, "BootfsLoaderService creation failed: %s\n",
zx_status_get_string(status));
- // Switch to the local loader service backed directly by the primary bootfs
- // to allow us to load the next process.
- zx::channel local_loader_conn;
- status = loader->Connect(&local_loader_conn);
- ZX_ASSERT_MSG(status == ZX_OK, "failed to connect to BootfsLoaderService : %s\n",
- zx_status_get_string(status));
- zx_handle_close(dl_set_loader_service(local_loader_conn.release()));
-
// Launch the next process in the chain. This must be in a thread, since
// it may issue requests to the loader, which runs in the async loop that
// starts running after this.
printf("bootsvc: Launching next process...\n");
- StartLaunchNextProcessThread(bootfs_svc, svcfs_svc);
+ std::thread(LaunchNextProcess, bootfs_svc, svcfs_svc, loader_svc).detach();
// Begin serving the bootfs fileystem and loader
loop.Run();