blob: 4938d1da45d9ede592e0e2f4d8004b83da9194b8 [file] [log] [blame]
// Copyright 2020 The Chromium OS 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 "vm_tools/concierge/vm_builder.h"
#include <utility>
#include <base/strings/string_util.h>
#include "vm_tools/concierge/vm_util.h"
namespace vm_tools {
namespace concierge {
VmBuilder::VmBuilder() = default;
VmBuilder::VmBuilder(VmBuilder&&) = default;
VmBuilder& VmBuilder::operator=(VmBuilder&& other) = default;
VmBuilder::~VmBuilder() = default;
VmBuilder& VmBuilder::SetKernel(base::FilePath kernel) {
kernel_ = std::move(kernel);
return *this;
}
VmBuilder& VmBuilder::SetInitrd(base::FilePath initrd) {
initrd_ = std::move(initrd);
return *this;
}
VmBuilder& VmBuilder::SetBios(base::FilePath bios) {
bios_ = std::move(bios);
return *this;
}
VmBuilder& VmBuilder::SetRootfs(const struct Rootfs& rootfs) {
rootfs_ = rootfs;
return *this;
}
VmBuilder& VmBuilder::SetCpus(int32_t cpus) {
cpus_ = cpus;
return *this;
}
VmBuilder& VmBuilder::SetVsockCid(uint32_t vsock_cid) {
vsock_cid_ = vsock_cid;
return *this;
}
VmBuilder& VmBuilder::AppendDisks(std::vector<Disk> disks) {
disks_ = std::move(disks);
return *this;
}
VmBuilder& VmBuilder::SetMemory(const std::string& memory_in_mb) {
memory_in_mib_ = memory_in_mb;
return *this;
}
VmBuilder& VmBuilder::SetBalloonBias(const std::string& balloon_bias_mib) {
balloon_bias_mib_ = balloon_bias_mib;
return *this;
}
VmBuilder& VmBuilder::SetSyslogTag(const std::string& syslog_tag) {
syslog_tag_ = syslog_tag;
return *this;
}
VmBuilder& VmBuilder::SetSocketPath(const std::string& socket_path) {
vm_socket_path_ = socket_path;
return *this;
}
VmBuilder& VmBuilder::AppendTapFd(base::ScopedFD fd) {
tap_fds_.push_back(std::move(fd));
return *this;
}
VmBuilder& VmBuilder::AppendKernelParam(const std::string& param) {
kernel_params_.push_back(param);
return *this;
}
VmBuilder& VmBuilder::AppendAudioDevice(const std::string& device) {
audio_devices_.push_back(device);
return *this;
}
VmBuilder& VmBuilder::AppendSerialDevice(const std::string& device) {
serial_devices_.push_back(device);
return *this;
}
VmBuilder& VmBuilder::AppendWaylandSocket(const std::string& socket) {
wayland_sockets_.push_back(socket);
return *this;
}
VmBuilder& VmBuilder::AppendSharedDir(const std::string& shared_dir) {
shared_dirs_.push_back(shared_dir);
return *this;
}
VmBuilder& VmBuilder::AppendCustomParam(const std::string& key,
const std::string& value) {
custom_params_.emplace_back(key, value);
return *this;
}
VmBuilder& VmBuilder::EnableGpu(bool enable) {
enable_gpu_ = enable;
return *this;
}
VmBuilder& VmBuilder::EnableVulkan(bool enable) {
enable_vulkan_ = enable;
return *this;
}
VmBuilder& VmBuilder::EnableBigGl(bool enable) {
enable_big_gl_ = enable;
return *this;
}
VmBuilder& VmBuilder::SetGpuCachePath(base::FilePath gpu_cache_path) {
gpu_cache_path_ = std::move(gpu_cache_path);
return *this;
}
VmBuilder& VmBuilder::SetGpuCacheSize(std::string gpu_cache_size_str) {
gpu_cache_size_str_ = std::move(gpu_cache_size_str);
return *this;
}
VmBuilder& VmBuilder::EnableSoftwareTpm(bool enable) {
enable_software_tpm_ = enable;
return *this;
}
VmBuilder& VmBuilder::EnableVideoDecoder(bool enable) {
enable_video_decoder_ = enable;
return *this;
}
VmBuilder& VmBuilder::EnableVideoEncoder(bool enable) {
enable_video_encoder_ = enable;
return *this;
}
VmBuilder& VmBuilder::EnableBattery(bool enable) {
enable_battery_ = enable;
return *this;
}
VmBuilder& VmBuilder::EnableSmt(bool enable) {
enable_smt_ = enable;
return *this;
}
VmBuilder& VmBuilder::EnableDelayRt(bool enable) {
enable_delay_rt_ = enable;
return *this;
}
VmBuilder& VmBuilder::EnableODirect(bool enable) {
for (auto& d : disks_) {
d.EnableODirect(enable);
}
return *this;
}
base::StringPairs VmBuilder::BuildVmArgs() const {
base::StringPairs args = {{kCrosvmBin, "run"}};
args.emplace_back("--cpus", std::to_string(cpus_));
if (!memory_in_mib_.empty())
args.emplace_back("--mem", memory_in_mib_);
if (!balloon_bias_mib_.empty())
args.emplace_back("--balloon_bias_mib", balloon_bias_mib_);
for (const auto& tap_fd : tap_fds_)
args.emplace_back("--tap-fd", std::to_string(tap_fd.get()));
if (vsock_cid_.has_value())
args.emplace_back("--cid", std::to_string(vsock_cid_.value()));
if (!vm_socket_path_.empty())
args.emplace_back("--socket", vm_socket_path_);
for (const auto& w : wayland_sockets_)
args.emplace_back("--wayland-sock", w);
for (const auto& s : serial_devices_)
args.emplace_back("--serial", s);
if (!syslog_tag_.empty())
args.emplace_back("--syslog-tag", syslog_tag_);
if (enable_smt_.has_value()) {
if (!enable_smt_.value())
args.emplace_back("--no-smt", "");
}
if (enable_delay_rt_)
args.emplace_back("--delay-rt", "");
if (kernel_params_.size() > 0)
args.emplace_back("--params", base::JoinString(kernel_params_, " "));
if (rootfs_.has_value()) {
const auto& rootfs = rootfs_.value();
if (rootfs.device.find("pmem") != std::string::npos) {
if (rootfs.writable) {
args.emplace_back("--rw-pmem-device", rootfs.path.value());
} else {
args.emplace_back("--pmem-device", rootfs.path.value());
}
// TODO(davidriley): Re-add rootflags=dax once guest kernel has fix for
// b/169339326.
args.emplace_back("--params", "root=/dev/pmem0 ro");
} else {
if (rootfs.writable) {
args.emplace_back("--rwroot", rootfs.path.value());
} else {
args.emplace_back("--root", rootfs.path.value());
}
}
}
for (const auto& a : audio_devices_)
args.emplace_back("--ac97", a);
for (const auto& d : disks_) {
auto disk_args = d.GetCrosvmArgs();
args.insert(std::end(args), std::begin(disk_args), std::end(disk_args));
}
if (enable_gpu_) {
std::string gpu_arg = "--gpu=vulkan=";
gpu_arg += enable_vulkan_ ? "true" : "false";
if (enable_big_gl_) {
gpu_arg += ",gles=false";
}
if (!gpu_cache_path_.empty()) {
gpu_arg += ",cache-path=" + gpu_cache_path_.value();
}
if (!gpu_cache_size_str_.empty()) {
gpu_arg += ",cache-size=" + gpu_cache_size_str_;
}
args.emplace_back(gpu_arg, "");
}
if (enable_software_tpm_)
args.emplace_back("--software-tpm", "");
if (enable_video_decoder_)
args.emplace_back("--video-decoder", "");
if (enable_video_encoder_)
args.emplace_back("--video-encoder", "");
if (enable_battery_)
args.emplace_back("--battery", "");
for (const auto& shared_dir : shared_dirs_)
args.emplace_back("--shared-dir", shared_dir);
for (const auto& custom_param : custom_params_)
args.emplace_back(custom_param.first, custom_param.second);
if (!initrd_.empty())
args.emplace_back("-i", initrd_.value());
if (!bios_.empty())
args.emplace_back("--bios", bios_.value());
// Kernel should be at the end.
if (!kernel_.empty())
args.emplace_back(kernel_.value(), "");
return args;
}
} // namespace concierge
} // namespace vm_tools