blob: c8cca50bf66071e9310cb24d936546c074674f6f [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file
#include "src/devices/bin/driver_manager/base_package_resolver.h"
#include <fcntl.h>
#include "src/devices/bin/driver_manager/manifest_parser.h"
#include "src/devices/lib/log/log.h"
#include "src/zircon/lib/zircon/include/zircon/status.h"
namespace internal {
zx::status<std::unique_ptr<Driver>> BasePackageResolver::FetchDriver(
const std::string& package_url) {
auto result = GetPathFromUrl(package_url);
if (result.is_error()) {
LOGF(ERROR, "Failed to get path from '%s' %s", package_url.c_str(), result.status_string());
return result.take_error();
}
zx::vmo vmo;
zx_status_t status = load_vmo(result.value(), &vmo);
if (status != ZX_OK) {
LOGF(ERROR, "Failed to load driver vmo: %s", result.value().c_str());
return zx::error(ZX_ERR_INTERNAL);
}
Driver* driver = nullptr;
DriverLoadCallback callback = [&driver](Driver* d, const char* version) mutable { driver = d; };
status = load_driver_vmo(boot_args_, package_url, std::move(vmo), std::move(callback));
if (status != ZX_OK) {
LOGF(ERROR, "Failed to load driver: %s", result.value().c_str());
return zx::error(ZX_ERR_INTERNAL);
}
if (!driver) {
LOGF(INFO, "Driver %s not found, probably disabled", package_url.data());
return zx::ok(nullptr);
}
auto base_path_result = GetBasePathFromUrl(package_url);
if (base_path_result.is_error()) {
return base_path_result.take_error();
}
int fd;
if ((fd = open(base_path_result.value().c_str(), O_RDONLY, O_DIRECTORY)) < 0) {
LOGF(ERROR, "Failed to open package dir: '%s'", base_path_result.value().c_str());
return zx::error(ZX_ERR_INTERNAL);
}
driver->package_dir = fbl::unique_fd(fd);
return zx::ok(std::unique_ptr<Driver>(driver));
}
} // namespace internal