| // 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 "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::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::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) { |
| EnableGpu(enable, ""); |
| return *this; |
| } |
| |
| VmBuilder& VmBuilder::EnableGpu(bool enable, const std::string& gpu_arg) { |
| enable_gpu_ = enable; |
| gpu_arg_ = gpu_arg; |
| return *this; |
| } |
| |
| VmBuilder& VmBuilder::EnableWaylandDmaBuf(bool enable) { |
| enable_wayland_dma_buf_ = enable; |
| 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; |
| } |
| |
| 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_); |
| |
| 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 (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_wayland_dma_buf_) |
| args.emplace_back("--wayland-dmabuf", ""); |
| |
| if (enable_gpu_) { |
| if (gpu_arg_.empty()) |
| args.emplace_back("--gpu", ""); |
| else |
| 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()); |
| |
| // Kernel should be at the end. |
| if (!kernel_.empty()) |
| args.emplace_back(kernel_.value(), ""); |
| |
| return args; |
| } |
| |
| } // namespace concierge |
| } // namespace vm_tools |