// Copyright 2018 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/plugin_vm.h"

#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <algorithm>
#include <sstream>
#include <utility>
#include <vector>

#include <base/bind_helpers.h>
#include <base/files/file.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>

#include "vm_tools/concierge/plugin_vm_helper.h"
#include "vm_tools/concierge/tap_device_builder.h"
#include "vm_tools/concierge/vm_permission_interface.h"
#include "vm_tools/concierge/vm_util.h"
#include "vm_tools/concierge/vmplugin_dispatcher_interface.h"

using std::string;

namespace vm_tools {
namespace concierge {
namespace {

// Path to the plugin binaries and other assets.
constexpr char kPluginDir[] = "/opt/pita";
constexpr char kPluginDlcDir[] = "/run/imageloader/pita/package/root/opt/pita";

// Name of the plugin VM binary.
constexpr char kPluginBin[] = "pvm";
// Name of the sub-directory containing plugin's seccomp policy.
constexpr char kPluginPolicyDir[] = "policy";

// Name of the runtime directory inside the jail.
constexpr char kRuntimeDir[] = "/run/pvm";

// Name of the stateful directory inside the jail.
constexpr char kStatefulDir[] = "/pvm";

// Name of the directory holding ISOs inside the jail.
constexpr char kIsoDir[] = "/iso";

// How long we give VM to suspend.
constexpr base::TimeDelta kVmSuspendTimeout = base::TimeDelta::FromSeconds(25);

// How long to wait before timing out on child process exits.
constexpr base::TimeDelta kChildExitTimeout = base::TimeDelta::FromSeconds(10);

// The CPU cgroup where all the PluginVm crosvm processes should belong to.
constexpr char kPluginVmCpuCgroup[] = "/sys/fs/cgroup/cpu/vms/plugin";

// Offset in a subnet of the client/guest.
constexpr size_t kGuestAddressOffset = 1;

std::unique_ptr<patchpanel::Subnet> MakeSubnet(
    const patchpanel::IPv4Subnet& subnet) {
  return std::make_unique<patchpanel::Subnet>(
      subnet.base_addr(), subnet.prefix_len(), base::DoNothing());
}

void TrySuspendVm(dbus::ObjectProxy* vmplugin_service_proxy, const VmId& id) {
  bool dispatcher_shutting_down = false;
  base::TimeTicks suspend_start_time(base::TimeTicks::Now());
  do {
    pvm::dispatcher::VmOpResult result =
        pvm::dispatcher::SuspendVm(vmplugin_service_proxy, id);

    switch (result) {
      case pvm::dispatcher::VmOpResult::SUCCESS:
        return;

      case pvm::dispatcher::VmOpResult::DISPATCHER_SHUTTING_DOWN:
        // The dispatcher is in process of shutting down, and is supposed
        // to suspend all running VMs. Wait a second, and try again, until we
        // get "dispatcher not available" response.
        if (!dispatcher_shutting_down) {
          LOG(INFO) << "Dispatcher is shutting down, will retry suspend";
          dispatcher_shutting_down = true;
        }
        base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
        break;

      case pvm::dispatcher::VmOpResult::DISPATCHER_NOT_AVAILABLE:
        if (!dispatcher_shutting_down)
          LOG(ERROR) << "Failed to suspend VM: dispatcher is not available";
        return;

      default:
        // TODO(dtor): handle cases when suspend fails because VM is already
        // transitioning into some state, such as suspending or shutting down,
        // in which case dispatcher will reject our request.
        LOG(ERROR) << "Failed to suspend VM: " << static_cast<int>(result);
        return;
    }
  } while (base::TimeTicks::Now() - suspend_start_time < kVmSuspendTimeout);
}

}  // namespace

// static
std::unique_ptr<PluginVm> PluginVm::Create(
    VmId id,
    uint32_t cpus,
    std::vector<string> params,
    base::FilePath stateful_dir,
    base::FilePath iso_dir,
    base::FilePath root_dir,
    base::FilePath runtime_dir,
    std::unique_ptr<patchpanel::Client> network_client,
    int subnet_index,
    bool enable_vnet_hdr,
    std::unique_ptr<SeneschalServerProxy> seneschal_server_proxy,
    dbus::ObjectProxy* vm_permission_service_proxy,
    dbus::ObjectProxy* vmplugin_service_proxy) {
  auto vm = base::WrapUnique(new PluginVm(
      std::move(id), std::move(network_client), subnet_index, enable_vnet_hdr,
      std::move(seneschal_server_proxy), vm_permission_service_proxy,
      vmplugin_service_proxy, std::move(iso_dir), std::move(root_dir),
      std::move(runtime_dir)));

  if (!vm->CreateUsbListeningSocket() ||
      !vm->Start(cpus, std::move(params), std::move(stateful_dir))) {
    vm.reset();
  }

  return vm;
}

PluginVm::~PluginVm() {
  StopVm();
}

bool PluginVm::StopVm() {
  // Notify arc-patchpanel that the VM is down.
  // This should run before the process existence check below since we still
  // want to release the network resources on crash.
  // Note the client will only be null during testing.
  if (network_client_ && !network_client_->NotifyPluginVmShutdown(id_hash_)) {
    LOG(WARNING) << "Unable to notify networking services";
  }

  // Notify permission service of VM destruction.
  if (!permission_token_.empty()) {
    vm_permission::UnregisterVm(vm_permission_service_proxy_, id_);
  }

  // Do a sanity check here to make sure the process is still around.
  if (!CheckProcessExists(process_.pid())) {
    // The process is already gone.
    process_.Release();
    return true;
  }

  TrySuspendVm(vmplugin_service_proxy_, id_);
  if (!CheckProcessExists(process_.pid())) {
    process_.Release();
    return true;
  }

  // Kill the process with SIGTERM. For Plugin VMs this will cause plugin to
  // try to suspend the VM.
  if (process_.Kill(SIGTERM, kChildExitTimeout.InSeconds())) {
    return true;
  }

  LOG(WARNING) << "Failed to kill plugin VM with SIGTERM";

  // Kill it with fire.
  if (process_.Kill(SIGKILL, kChildExitTimeout.InSeconds())) {
    return true;
  }

  LOG(ERROR) << "Failed to kill plugin VM with SIGKILL";
  return false;
}

bool PluginVm::Shutdown() {
  // Notify arc-patchpanel that the VM is down.
  // This should run before the process existence check below since we still
  // want to release the network resources on crash.
  // Note the client will only be null during testing.
  if (network_client_ && !network_client_->NotifyPluginVmShutdown(id_hash_)) {
    LOG(WARNING) << "Unable to notify networking services";
  }

  return !CheckProcessExists(process_.pid()) ||
         pvm::dispatcher::ShutdownVm(vmplugin_service_proxy_, id_) ==
             pvm::dispatcher::VmOpResult::SUCCESS;
}

VmInterface::Info PluginVm::GetInfo() {
  VmInterface::Info info = {
      .ipv4_address = subnet_->AddressAtOffset(kGuestAddressOffset),
      .pid = process_.pid(),
      .cid = 0,
      .seneschal_server_handle = seneschal_server_handle(),
      .permission_token = permission_token_,
      .status = VmInterface::Status::RUNNING,
  };

  return info;
}

bool PluginVm::GetVmEnterpriseReportingInfo(
    GetVmEnterpriseReportingInfoResponse* response) {
  response->set_success(false);
  response->set_failure_reason("Not implemented");
  return false;
}

vm_tools::concierge::DiskImageStatus PluginVm::ResizeDisk(
    uint64_t new_size, std::string* failure_reason) {
  *failure_reason = "Not implemented";
  return DiskImageStatus::DISK_STATUS_FAILED;
}

vm_tools::concierge::DiskImageStatus PluginVm::GetDiskResizeStatus(
    std::string* failure_reason) {
  *failure_reason = "Not implemented";
  return DiskImageStatus::DISK_STATUS_FAILED;
}

// static
base::ScopedFD PluginVm::CreateUnixSocket(const base::FilePath& path,
                                          int type) {
  base::ScopedFD fd(socket(AF_UNIX, type, 0));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "Failed to create AF_UNIX socket";
    return base::ScopedFD();
  }

  struct sockaddr_un sa;

  if (path.value().length() >= sizeof(sa.sun_path)) {
    LOG(ERROR) << "Path is too long for a UNIX socket: " << path.value();
    return base::ScopedFD();
  }

  memset(&sa, 0, sizeof(sa));
  sa.sun_family = AF_UNIX;
  // The memset above took care of NUL terminating, and we already verified
  // the length before that.
  memcpy(sa.sun_path, path.value().data(), path.value().length());

  // Delete any old socket instances.
  if (PathExists(path) && !DeleteFile(path, false)) {
    PLOG(ERROR) << "failed to delete " << path.value();
    return base::ScopedFD();
  }

  // Bind the socket.
  if (bind(fd.get(), reinterpret_cast<const sockaddr*>(&sa), sizeof(sa)) < 0) {
    PLOG(ERROR) << "failed to bind " << path.value();
    return base::ScopedFD();
  }

  return fd;
}

// static
bool PluginVm::SetVmCpuRestriction(CpuRestrictionState cpu_restriction_state) {
  return VmBaseImpl::SetVmCpuRestriction(cpu_restriction_state,
                                         kPluginVmCpuCgroup);
}

bool PluginVm::CreateUsbListeningSocket() {
  usb_listen_fd_ = CreateUnixSocket(runtime_dir_.GetPath().Append("usb.sock"),
                                    SOCK_SEQPACKET);
  if (!usb_listen_fd_.is_valid()) {
    return false;
  }

  // Start listening for connections. We only expect one client at a time.
  if (listen(usb_listen_fd_.get(), 1) < 0) {
    PLOG(ERROR) << "Unable to listen for connections on USB socket";
    return false;
  }

  usb_listen_watcher_ = base::FileDescriptorWatcher::WatchReadable(
      usb_listen_fd_.get(),
      base::BindRepeating(&PluginVm::OnListenFileCanReadWithoutBlocking,
                          base::Unretained(this)));
  if (!usb_listen_watcher_) {
    LOG(ERROR) << "Failed to watch USB listening socket";
    return false;
  }

  return true;
}

bool PluginVm::AttachUsbDevice(uint8_t bus,
                               uint8_t addr,
                               uint16_t vid,
                               uint16_t pid,
                               int fd,
                               UsbControlResponse* response) {
  base::ScopedFD dup_fd(dup(fd));
  if (!dup_fd.is_valid()) {
    PLOG(ERROR) << "Unable to duplicate incoming file descriptor";
    return false;
  }

  if (usb_vm_fd_.is_valid() && usb_req_waiting_xmit_.empty()) {
    usb_listen_watcher_.reset();
    usb_vm_read_watcher_ = base::FileDescriptorWatcher::WatchReadable(
        usb_vm_fd_.get(),
        base::BindRepeating(&PluginVm::OnVmFileCanReadWithoutBlocking,
                            base::Unretained(this)));
    usb_vm_write_watcher_ = base::FileDescriptorWatcher::WatchWritable(
        usb_vm_fd_.get(),
        base::BindRepeating(&PluginVm::OnVmFileCanWriteWithoutBlocking,
                            base::Unretained(this)));
    if (!usb_vm_read_watcher_ || !usb_vm_write_watcher_) {
      LOG(ERROR) << "Failed to start watching USB VM socket";
      usb_vm_read_watcher_.reset();
      usb_vm_write_watcher_.reset();
      return false;
    }
  }

  UsbCtrlRequest req{};
  req.type = ATTACH_DEVICE;
  req.handle = ++usb_last_handle_;
  req.DevInfo.bus = bus;
  req.DevInfo.addr = addr;
  req.DevInfo.vid = vid;
  req.DevInfo.pid = pid;
  usb_req_waiting_xmit_.emplace_back(std::move(req), std::move(dup_fd));

  // TODO(dtor): report status only when plugin responds; requires changes to
  // the VM interface API.
  response->type = UsbControlResponseType::OK;
  response->port = usb_last_handle_;
  return true;
}

bool PluginVm::DetachUsbDevice(uint8_t port, UsbControlResponse* response) {
  auto iter = std::find_if(
      usb_devices_.begin(), usb_devices_.end(),
      [port](const auto& info) { return std::get<2>(info) == port; });
  if (iter == usb_devices_.end()) {
    response->type = UsbControlResponseType::NO_SUCH_PORT;
    return true;
  }

  if (usb_vm_fd_.is_valid() && usb_req_waiting_xmit_.empty()) {
    usb_listen_watcher_.reset();
    usb_vm_read_watcher_ = base::FileDescriptorWatcher::WatchReadable(
        usb_vm_fd_.get(),
        base::BindRepeating(&PluginVm::OnVmFileCanReadWithoutBlocking,
                            base::Unretained(this)));
    usb_vm_write_watcher_ = base::FileDescriptorWatcher::WatchWritable(
        usb_vm_fd_.get(),
        base::BindRepeating(&PluginVm::OnVmFileCanWriteWithoutBlocking,
                            base::Unretained(this)));
    if (!usb_vm_read_watcher_ || !usb_vm_write_watcher_) {
      LOG(ERROR) << "Failed to start watching USB VM socket";
      usb_vm_read_watcher_.reset();
      usb_vm_write_watcher_.reset();
      return false;
    }
  }

  UsbCtrlRequest req{};
  req.type = DETACH_DEVICE;
  req.handle = port;
  usb_req_waiting_xmit_.emplace_back(req, base::ScopedFD());

  // TODO(dtor): report status only when plugin responds; requires changes to
  // the VM interface API.
  response->type = UsbControlResponseType::OK;
  response->port = port;
  return true;
}

bool PluginVm::ListUsbDevice(std::vector<UsbDevice>* device) {
  device->resize(usb_devices_.size());
  std::transform(usb_devices_.begin(), usb_devices_.end(), device->begin(),
                 [](const auto& info) {
                   UsbDevice d{};
                   std::tie(d.vid, d.pid, d.port) = info;
                   return d;
                 });
  return true;
}

void PluginVm::HandleUsbControlResponse() {
  UsbCtrlResponse resp;
  int ret = HANDLE_EINTR(read(usb_vm_fd_.get(), &resp, sizeof(resp)));
  if (ret <= 0) {
    // If we get 0 bytes from read() that means that the other side closed
    // the connection. Disconnect the socket and wait for new connection.
    // Do the same if we get any error besides EAGAIN.
    if (ret == 0 || errno != EAGAIN) {
      usb_vm_read_watcher_.reset();
      usb_vm_write_watcher_.reset();
      usb_vm_fd_.reset();

      usb_listen_watcher_ = base::FileDescriptorWatcher::WatchReadable(
          usb_listen_fd_.get(),
          base::BindRepeating(&PluginVm::OnListenFileCanReadWithoutBlocking,
                              base::Unretained(this)));
      if (!usb_listen_watcher_) {
        LOG(ERROR) << "Failed to restart watching USB listening socket";
      }
    }
  } else if (ret != sizeof(resp)) {
    LOG(ERROR) << "Partial read of " << ret
               << " from USB VM socket, discarding";
  } else {
    auto req_iter = std::find_if(
        usb_req_waiting_response_.begin(), usb_req_waiting_response_.end(),
        [&resp](const auto& req) {
          return resp.type == req.type && resp.handle == req.handle;
        });
    if (req_iter == usb_req_waiting_response_.end()) {
      LOG(ERROR) << "Unexpected response (type " << resp.type << ", handle "
                 << resp.handle << ")";
      return;
    }

    if (resp.status != UsbCtrlResponse::Status::OK) {
      LOG(ERROR) << "Request (type " << resp.type << ", handle " << resp.handle
                 << ") failed: " << resp.status;
    }

    switch (req_iter->type) {
      case ATTACH_DEVICE:
        if (resp.status == UsbCtrlResponse::Status::OK) {
          usb_devices_.emplace_back(req_iter->DevInfo.vid,
                                    req_iter->DevInfo.pid, req_iter->handle);
        }
        break;
      case DETACH_DEVICE: {
        // We will attempt to clean up even if plugin signalled error as there
        // is no way the device will continue be operational.
        auto dev_iter = std::find_if(usb_devices_.begin(), usb_devices_.end(),
                                     [&resp](const auto& info) {
                                       return std::get<2>(info) == resp.handle;
                                     });
        if (dev_iter == usb_devices_.end()) {
          LOG(ERROR) << "Received detach response for unknown handle "
                     << resp.handle;
        }
      } break;
      default:
        NOTREACHED();
    }

    usb_req_waiting_response_.erase(req_iter);
  }
}

void PluginVm::OnListenFileCanReadWithoutBlocking() {
  int ret = HANDLE_EINTR(accept4(usb_listen_fd_.get(), nullptr, nullptr,
                                 SOCK_CLOEXEC | SOCK_NONBLOCK));
  if (ret < 0) {
    PLOG(ERROR) << "Unable to accept connection on USB listening socket";
    return;
  }

  // Start managing socket connected to the VM.
  usb_vm_fd_.reset(ret);

  // Switch watcher from listener FD to connected socket FD.
  // We monitor both writes and reads to detect disconnects.
  usb_listen_watcher_.reset();
  usb_vm_read_watcher_ = base::FileDescriptorWatcher::WatchReadable(
      usb_vm_fd_.get(),
      base::BindRepeating(&PluginVm::OnVmFileCanReadWithoutBlocking,
                          base::Unretained(this)));
  if (!usb_req_waiting_xmit_.empty()) {
    usb_vm_write_watcher_ = base::FileDescriptorWatcher::WatchWritable(
        usb_vm_fd_.get(),
        base::BindRepeating(&PluginVm::OnVmFileCanWriteWithoutBlocking,
                            base::Unretained(this)));
  }
  if (!usb_vm_read_watcher_ ||
      (!usb_req_waiting_xmit_.empty() && !usb_vm_write_watcher_)) {
    LOG(ERROR) << "Failed to start watching USB VM socket";
    usb_vm_write_watcher_.reset();
    usb_vm_read_watcher_.reset();
    usb_vm_fd_.reset();
    return;
  }
}

void PluginVm::OnVmFileCanReadWithoutBlocking() {
  PluginVm::HandleUsbControlResponse();
}

void PluginVm::OnVmFileCanWriteWithoutBlocking() {
  DCHECK(usb_vm_fd_.is_valid());

  if (!usb_req_waiting_xmit_.empty()) {
    UsbCtrlRequest req = usb_req_waiting_xmit_.front().first;
    struct iovec io {};
    io.iov_base = &req;
    io.iov_len = sizeof(req);

    struct msghdr msg {};
    msg.msg_iov = &io;
    msg.msg_iovlen = 1;

    char buf[CMSG_SPACE(sizeof(int))];
    base::ScopedFD fd(std::move(usb_req_waiting_xmit_.front().second));
    if (fd.is_valid()) {
      msg.msg_control = buf;
      msg.msg_controllen = CMSG_LEN(sizeof(int));

      struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
      cmsg->cmsg_len = CMSG_LEN(sizeof(int));
      cmsg->cmsg_level = SOL_SOCKET;
      cmsg->cmsg_type = SCM_RIGHTS;

      *(reinterpret_cast<int*> CMSG_DATA(cmsg)) = fd.get();
    }

    int ret = HANDLE_EINTR(sendmsg(usb_vm_fd_.get(), &msg, MSG_EOR));
    if (ret == sizeof(req)) {
      usb_req_waiting_response_.emplace_back(req);
      usb_req_waiting_xmit_.pop_front();
    } else if (ret >= 0) {
      PLOG(ERROR) << "Partial write of " << ret
                  << " while sending USB request; will retry";
    } else if (errno != EINTR) {
      PLOG(ERROR) << "Failed to send USB request";
    }
  } else {
    usb_listen_watcher_.reset();
    usb_vm_write_watcher_.reset();

    usb_vm_read_watcher_ = base::FileDescriptorWatcher::WatchReadable(
        usb_vm_fd_.get(),
        base::BindRepeating(&PluginVm::OnVmFileCanReadWithoutBlocking,
                            base::Unretained(this)));
    if (!usb_vm_read_watcher_) {
      LOG(ERROR) << "Failed to switch to watching USB VM socket for reads";
    }
  }
}

// static
bool PluginVm::WriteResolvConf(const base::FilePath& parent_dir,
                               const std::vector<string>& nameservers,
                               const std::vector<string>& search_domains) {
  // Create temporary directory on the same file system so that we
  // can atomically replace old resolv.conf with new one.
  base::ScopedTempDir temp_dir;
  if (!temp_dir.CreateUniqueTempDirUnderPath(parent_dir)) {
    LOG(ERROR) << "Failed to create temporary directory under "
               << parent_dir.value();
    return false;
  }

  base::FilePath path = temp_dir.GetPath().Append("resolv.conf");
  base::File file(path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
  if (!file.IsValid()) {
    LOG(ERROR) << "Failed to create temporary file " << path.value();
    return false;
  }

  for (auto& ns : nameservers) {
    string nameserver_line = base::StringPrintf("nameserver %s\n", ns.c_str());
    if (!file.WriteAtCurrentPos(nameserver_line.c_str(),
                                nameserver_line.length())) {
      LOG(ERROR) << "Failed to write nameserver to temporary file";
      return false;
    }
  }

  if (!search_domains.empty()) {
    string search_domains_line = base::StringPrintf(
        "search %s\n", base::JoinString(search_domains, " ").c_str());
    if (!file.WriteAtCurrentPos(search_domains_line.c_str(),
                                search_domains_line.length())) {
      LOG(ERROR) << "Failed to write search domains to temporary file";
      return false;
    }
  }

  constexpr char kResolvConfOptions[] =
      "options single-request timeout:1 attempts:5\n";
  if (!file.WriteAtCurrentPos(kResolvConfOptions, strlen(kResolvConfOptions))) {
    LOG(ERROR) << "Failed to write search resolver options to temporary file";
    return false;
  }

  // This should flush the buffers.
  file.Close();

  base::File::Error err;
  if (!ReplaceFile(path, parent_dir.Append("resolv.conf"), &err)) {
    LOG(ERROR) << "Failed to replace resolv.conf with new instance: "
               << base::File::ErrorToString(err);
    return false;
  }

  return true;
}

bool PluginVm::SetResolvConfig(const std::vector<string>& nameservers,
                               const std::vector<string>& search_domains) {
  return WriteResolvConf(root_dir_.GetPath().Append("etc"), nameservers,
                         search_domains);
}

void PluginVm::VmToolsStateChanged(bool running) {
  LOG(INFO) << "Tools are " << (running ? "" : "not ")
            << "running in plugin VM";

  if (running)
    pvm::helper::CleanUpAfterInstall(id_, iso_dir_);
}

PluginVm::PluginVm(VmId id,
                   std::unique_ptr<patchpanel::Client> network_client,
                   int subnet_index,
                   bool enable_vnet_hdr,
                   std::unique_ptr<SeneschalServerProxy> seneschal_server_proxy,
                   dbus::ObjectProxy* vm_permission_service_proxy,
                   dbus::ObjectProxy* vmplugin_service_proxy,
                   base::FilePath iso_dir,
                   base::FilePath root_dir,
                   base::FilePath runtime_dir)
    : VmBaseImpl(std::move(network_client)),
      id_(std::move(id)),
      iso_dir_(std::move(iso_dir)),
      subnet_index_(subnet_index),
      enable_vnet_hdr_(enable_vnet_hdr),
      seneschal_server_proxy_(std::move(seneschal_server_proxy)),
      vm_permission_service_proxy_(vm_permission_service_proxy),
      vmplugin_service_proxy_(vmplugin_service_proxy),
      usb_last_handle_(0) {
  CHECK(vm_permission_service_proxy_);
  CHECK(vmplugin_service_proxy_);
  CHECK(base::DirectoryExists(iso_dir_));
  CHECK(base::DirectoryExists(root_dir));
  CHECK(base::DirectoryExists(runtime_dir));

  // Take ownership of the root and runtime directories.
  CHECK(root_dir_.Set(root_dir));
  CHECK(runtime_dir_.Set(runtime_dir));

  std::ostringstream oss;
  oss << id_;
  id_hash_ = std::hash<std::string>{}(oss.str());
}

bool PluginVm::Start(uint32_t cpus,
                     std::vector<string> params,
                     base::FilePath stateful_dir) {
  if (!pvm::helper::IsDlcVm()) {
    LOG(ERROR) << "PluginVM DLC is not installed.";
    return false;
  }

  // Register the VM with permission service and obtain permission
  // token.
  if (!vm_permission::RegisterVm(vm_permission_service_proxy_, id_,
                                 vm_permission::VmType::PLUGIN_VM,
                                 &permission_token_)) {
    LOG(ERROR) << "Failed to register with permission service";
    return false;
  }

  // Get the network interface.
  patchpanel::NetworkDevice network_device;
  if (!network_client_->NotifyPluginVmStartup(id_hash_, subnet_index_,
                                              &network_device)) {
    LOG(ERROR) << "No network devices available";
    return false;
  }
  subnet_ = MakeSubnet(network_device.ipv4_subnet());

  // Open the tap device.
  base::ScopedFD tap_fd = OpenTapDevice(
      network_device.ifname(), enable_vnet_hdr_, nullptr /*ifname_out*/);
  if (!tap_fd.is_valid()) {
    LOG(ERROR) << "Unable to open and configure TAP device "
               << network_device.ifname();
    return false;
  }

  auto plugin_bin_path = base::FilePath(kPluginDlcDir).Append(kPluginBin);
  auto plugin_policy_dir =
      base::FilePath(kPluginDlcDir).Append(kPluginPolicyDir);
  // Build up the process arguments.
  // clang-format off
  std::vector<string> args = {
    kCrosvmBin,                 "run",
    "--cpus",                   std::to_string(cpus),
    "--tap-fd",                 std::to_string(tap_fd.get()),
    "--plugin",                 plugin_bin_path.value(),
    "--seccomp-policy-dir",     plugin_policy_dir.value(),
    "--plugin-gid-map-file",    plugin_bin_path
                                    .AddExtension("gid_maps")
                                    .value(),
  };
  // clang-format on

  // These are bind mounts with parts may change (i.e. they are either VM
  // or config specific).
  std::vector<string> bind_mounts = {
      base::StringPrintf("%s:%s:false", kPluginDlcDir, kPluginDir),
      // This is directory where the VM image resides.
      base::StringPrintf("%s:%s:true", stateful_dir.value().c_str(),
                         kStatefulDir),
      // This is directory where ISO images for the VM reside.
      base::StringPrintf("%s:%s:false", iso_dir_.value().c_str(), kIsoDir),
      // This is directory where control socket, 9p socket, and other axillary
      // runtime data lives.
      base::StringPrintf("%s:%s:true", runtime_dir_.GetPath().value().c_str(),
                         kRuntimeDir),
      // Plugin '/etc' directory.
      base::StringPrintf("%s:%s:true",
                         root_dir_.GetPath().Append("etc").value().c_str(),
                         "/etc"),
  };

  if (vm_permission::IsCameraEnabled(vm_permission_service_proxy_,
                                     permission_token_)) {
    LOG(INFO) << "VM " << id_ << ": camera access enabled";
    bind_mounts.push_back("/run/camera:/run/camera:true");
  } else {
    LOG(INFO) << "VM " << id_ << ": camera access disabled";
  }

  if (vm_permission::IsMicrophoneEnabled(vm_permission_service_proxy_,
                                         permission_token_)) {
    LOG(INFO) << "VM " << id_ << ": microphone access enabled";
    bind_mounts.push_back(
        "/run/cras/.cras_unified:/run/cras/.cras_socket:true");
  } else {
    LOG(INFO) << "VM " << id_ << ": microphone access disabled";
    bind_mounts.push_back("/run/cras/.cras_socket::true");
  }

  // TODO(kimjae): This is a temporary hack to have relative files to be found
  // even when started from DLC paths. Clean this up once a cleaner solution
  // can be leveraged.
  bind_mounts.push_back(
      base::StringPrintf("%s:%s:false", kPluginDlcDir, kPluginDlcDir));

  // Put everything into the brillo::ProcessImpl.
  for (auto& arg : args) {
    process_.AddArg(std::move(arg));
  }

  for (auto& mount : bind_mounts) {
    process_.AddArg("--plugin-mount");
    process_.AddArg(std::move(mount));
  }

  // Because some of the static paths are mounted in /run/pvm... in the
  // plugin jail, they have to come after the dynamic paths above.
  process_.AddArg("--plugin-mount-file");
  process_.AddArg(plugin_bin_path.AddExtension("bind_mounts").value());

  for (auto& param : params) {
    // Because additional parameters may start with a '--', we should use
    // --params=<Param> instead of --params <Param> to make explicit <Param>
    // is a parameter for the plugin rather than just another parameter to
    // the crosvm process.
    process_.AddArg(std::string("--params=") + param);
  }

  // Change the process group before exec so that crosvm sending SIGKILL to
  // the whole process group doesn't kill us as well. The function also
  // changes the cpu cgroup for PluginVm crosvm processes.
  process_.SetPreExecCallback(base::Bind(
      &SetUpCrosvmProcess, base::FilePath(kPluginVmCpuCgroup).Append("tasks")));

  if (!process_.Start()) {
    LOG(ERROR) << "Failed to start VM process";
    return false;
  }

  return true;
}

}  // namespace concierge
}  // namespace vm_tools
