blob: f9db5da92a72da779a1bb7f5fc0b54c563bc8069 [file] [log] [blame]
// Copyright 2022 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 <fidl/fuchsia.io/cpp/wire.h>
#include <lib/fdio/namespace.h>
#include <lib/service/llcpp/service.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/status.h>
#include <iostream>
#include "src/lib/fxl/test/test_settings.h"
#include "src/storage/bin/start-storage-benchmark/block-device.h"
#include "src/storage/bin/start-storage-benchmark/command-line-options.h"
#include "src/storage/bin/start-storage-benchmark/memfs.h"
#include "src/storage/bin/start-storage-benchmark/running-filesystem.h"
extern "C" bool run_odu_test(const char* const* args);
namespace storage_benchmark {
namespace {
fs_management::DiskFormat FilesystemOptionToDiskFormat(FilesystemOption filesystem) {
switch (filesystem) {
case FilesystemOption::kUnset:
ZX_PANIC("No filesystem specified");
case FilesystemOption::kMemfs:
ZX_PANIC("Memfs does not have a disk format");
case FilesystemOption::kMinfs:
return fs_management::DiskFormat::kDiskFormatMinfs;
case FilesystemOption::kFxfs:
return fs_management::DiskFormat::kDiskFormatFxfs;
case FilesystemOption::kF2fs:
return fs_management::DiskFormat::kDiskFormatF2fs;
}
}
zx::status<std::unique_ptr<RunningFilesystem>> StartFilesystem(const CommandLineOptions& options) {
if (options.filesystem == FilesystemOption::kMemfs) {
return Memfs::Create();
}
auto fvm_block_device_path = FindFvmBlockDevicePath();
if (fvm_block_device_path.is_error()) {
FX_LOGS(ERROR) << "Unable to find FVM device";
return fvm_block_device_path.take_error();
}
auto fvm_client = ConnectToFvm(*fvm_block_device_path);
if (fvm_client.is_error()) {
FX_LOGS(ERROR) << "Unable to connect to FVM: " << fvm_client.status_string();
return fvm_client.take_error();
}
auto fvm_volume = FvmVolume::Create(*fvm_client, options.partition_size);
if (fvm_volume.is_error()) {
FX_LOGS(ERROR) << "Unable to create FVM volume: " << fvm_volume.status_string();
return fvm_volume.take_error();
}
std::string block_device_path = fvm_volume->path();
if (options.zxcrypt) {
auto zxcrypt_path = CreateZxcryptVolume(block_device_path);
if (zxcrypt_path.is_error()) {
FX_LOGS(ERROR) << "Unable to create zxcrypt volume: " << zxcrypt_path.status_string();
return zxcrypt_path.take_error();
}
block_device_path = *zxcrypt_path;
}
fs_management::DiskFormat disk_format = FilesystemOptionToDiskFormat(options.filesystem);
if (zx::status<> status = FormatBlockDevice(block_device_path, disk_format); status.is_error()) {
FX_LOGS(ERROR) << "Failed to format device: " << status.status_string();
return status.take_error();
}
return StartBlockDeviceFilesystem(block_device_path, disk_format, *std::move(fvm_volume));
}
int Run(const fxl::CommandLine& command_line) {
// Mark this process as critical to the job so that the runner knows when we're done whilst
// children might be running.
zx::job::default_job()->set_critical(0, *zx::process::self());
if (!fxl::SetTestSettings(command_line)) {
std::cerr << "Failed to set test settings" << std::endl;
return EXIT_FAILURE;
}
auto options = storage_benchmark::ParseCommandLine(command_line);
if (options.is_error()) {
std::cerr << "Failed to parse command line: " << options.error_value() << std::endl;
return EXIT_FAILURE;
}
auto filesystem = StartFilesystem(*options);
if (filesystem.is_error()) {
std::cerr << "Failed to start filesystem: " << filesystem.status_string() << std::endl;
return EXIT_FAILURE;
}
auto filesystem_connection = filesystem->GetFilesystemRoot();
if (filesystem_connection.is_error()) {
std::cerr << "Unable to get filesystem root: " << filesystem_connection.status_string()
<< std::endl;
return EXIT_FAILURE;
}
fdio_ns_t* ns;
if (zx_status_t status = fdio_ns_get_installed(&ns); status != ZX_OK) {
std::cerr << "Unable to get installed namespace: " << zx_status_get_string(status) << std::endl;
return EXIT_FAILURE;
}
if (zx_status_t status = fdio_ns_bind(ns, options->mount_path.c_str(),
filesystem_connection->TakeChannel().release());
status != ZX_OK) {
std::cerr << "Unable to bind " << options->mount_path
<< " to namespace: " << zx_status_get_string(status) << std::endl;
return EXIT_FAILURE;
}
std::vector<const char*> args;
for (const auto& arg : options->benchmark_options) {
args.push_back(arg.c_str());
}
args.push_back(nullptr);
if (!run_odu_test(args.data())) {
std::cerr << "run_odu_test failed" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
} // namespace
} // namespace storage_benchmark
int main(int argc, char* argv[]) {
return storage_benchmark::Run(fxl::CommandLineFromArgcArgv(argc, argv));
}