blob: a1b0415b859b9d68c7c86bd4d1986bfc50b2f49e [file] [log] [blame]
// Copyright 2019 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.
#ifndef SRC_STORAGE_FSHOST_FSHOST_BOOT_ARGS_H_
#define SRC_STORAGE_FSHOST_FSHOST_BOOT_ARGS_H_
#include <fcntl.h>
#include <fuchsia/boot/llcpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/status.h>
#include <zircon/types.h>
#include <map>
#include <fbl/string_printf.h>
#include <fbl/unique_fd.h>
namespace devmgr {
class FshostBootArgs {
public:
FshostBootArgs() : boot_args_(nullptr) {
zx::channel remote, local;
zx_status_t status = zx::channel::create(0, &local, &remote);
if (status != ZX_OK) {
// This service might be missing if we're running in a test environment. Log
// the error and continue.
fprintf(stderr,
"fshost: failed to get boot arguments (%s), assuming test "
"environment and continuing\n",
zx_status_get_string(status));
return;
}
auto path = fbl::StringPrintf("/svc/%s", llcpp::fuchsia::boot::Arguments::Name);
status = fdio_service_connect(path.data(), remote.release());
if (status != ZX_OK) {
// This service might be missing if we're running in a test environment. Log
// the error and continue.
fprintf(stderr,
"fshost: failed to get boot arguments (%s), assuming test "
"environment and continuing\n",
zx_status_get_string(status));
return;
}
boot_args_ = std::make_unique<llcpp::fuchsia::boot::Arguments::SyncClient>(std::move(local));
InitParams();
}
bool netboot() { return netsvc_netboot_ || zircon_system_disable_automount_; }
bool check_filesystems() { return zircon_system_filesystem_check_; }
bool wait_for_data() { return zircon_system_wait_for_data_; }
bool blobfs_enable_userpager() { return blobfs_userpager_; }
std::unique_ptr<std::string> pkgfs_file_with_prefix_and_name(const char* prefix,
const char* name) {
char key[256];
int len = snprintf(key, sizeof(key), "zircon.system.pkgfs.file.%s%s", prefix, name);
if (len >= (int)sizeof(key)) {
printf("fshost: failed to format pkgfs file boot argument key\n");
return nullptr;
}
if (!boot_args_) {
return nullptr;
}
auto ret = boot_args_->GetString(fidl::StringView{key, (uint64_t)len});
if (!ret.ok()) {
return nullptr;
}
return std::make_unique<std::string>(ret->value.data(), ret->value.size());
}
std::unique_ptr<std::string> pkgfs_cmd() {
if (!boot_args_)
return nullptr;
auto ret = boot_args_->GetString(fidl::StringView{"zircon.system.pkgfs.cmd"});
if (!ret.ok() || ret->value.is_null()) {
return nullptr;
}
return std::make_unique<std::string>(ret->value.data(), ret->value.size());
}
// Returns the write compression algorithm to pass to blobfs (via the --compression flag).
// If nullptr, no value should be passed.
const char* blobfs_write_compression_algorithm() const {
if (!blobfs_write_compression_algorithm_) {
return nullptr;
}
return blobfs_write_compression_algorithm_->c_str();
}
protected:
// Protected constructor for FshostBootArgs that allows injecting a
// different BootArgs member, for use in unit tests.
explicit FshostBootArgs(std::unique_ptr<llcpp::fuchsia::boot::Arguments::SyncClient>&& boot_args)
: boot_args_(std::move(boot_args)) {
InitParams();
}
private:
std::unique_ptr<llcpp::fuchsia::boot::Arguments::SyncClient> boot_args_;
bool netsvc_netboot_ = false;
bool zircon_system_disable_automount_ = false;
bool zircon_system_filesystem_check_ = false;
bool zircon_system_wait_for_data_ = true;
bool blobfs_userpager_ = false;
std::optional<std::string> blobfs_write_compression_algorithm_ = std::nullopt;
void InitParams() {
llcpp::fuchsia::boot::BoolPair defaults[] = {
{fidl::StringView{"netsvc.netboot"}, false},
{fidl::StringView{"zircon.system.disable-automount"}, false},
{fidl::StringView{"zircon.system.filesystem-check"}, false},
{fidl::StringView{"zircon.system.wait-for-data"}, true},
{fidl::StringView{"blobfs.userpager"}, false},
};
auto ret = boot_args_->GetBools(fidl::unowned_vec(defaults));
if (!ret.ok()) {
fprintf(stderr, "fshost: failed to get parameters: %s", ret.error());
return;
}
netsvc_netboot_ = ret->values[0];
zircon_system_disable_automount_ = ret->values[1];
zircon_system_filesystem_check_ = ret->values[2];
zircon_system_wait_for_data_ = ret->values[3];
blobfs_userpager_ = ret->values[4];
auto algorithm = boot_args_->GetString(fidl::StringView{"blobfs.write-compression-algorithm"});
if (!algorithm.ok()) {
fprintf(stderr, "fshost: failed to get parameters: %s", algorithm.error());
return;
}
if (!algorithm->value.is_null()) {
blobfs_write_compression_algorithm_ =
std::string(algorithm->value.data(), algorithm->value.size());
}
}
};
} // namespace devmgr
#endif // SRC_STORAGE_FSHOST_FSHOST_BOOT_ARGS_H_