// 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/callback_helpers.h>
#include <base/check.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/notreached.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_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[] = "prl_vm_app";
// 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(scoped_refptr<dbus::Bus> bus,
                  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(bus, 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,
    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,
    scoped_refptr<dbus::Bus> bus,
    std::unique_ptr<SeneschalServerProxy> seneschal_server_proxy,
    dbus::ObjectProxy* vm_permission_service_proxy,
    dbus::ObjectProxy* vmplugin_service_proxy,
    VmBuilder vm_builder) {
  auto vm = std::unique_ptr<PluginVm>(new PluginVm(
      std::move(id), std::move(network_client), std::move(bus),
      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(std::move(stateful_dir), subnet_index, enable_vnet_hdr,
                 std::move(vm_builder))) {
    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(bus_, vm_permission_service_proxy_, id_);
  }

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

  TrySuspendVm(bus_, 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(bus_, 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,
      .type = VmInfo::PLUGIN_VM,
  };

  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)) {
    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,
                   scoped_refptr<dbus::Bus> bus,
                   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),
                 std::move(seneschal_server_proxy),
                 std::move(runtime_dir)),
      id_(std::move(id)),
      iso_dir_(std::move(iso_dir)),
      bus_(std::move(bus)),
      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));

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

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

bool PluginVm::Start(base::FilePath stateful_dir,
                     int subnet_index,
                     bool enable_vnet_hdr,
                     VmBuilder vm_builder) {
  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(bus_, 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);
  vm_builder.AppendTapFd(std::move(tap_fd))
      .AppendCustomParam("--plugin", plugin_bin_path.value())
      .AppendCustomParam("--seccomp-policy-dir", plugin_policy_dir.value())
      .AppendCustomParam("--plugin-gid-map-file",
                         plugin_bin_path.AddExtension("gid_maps").value());

  // 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(bus_, 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(bus_, vm_permission_service_proxy_,
                                         permission_token_)) {
    LOG(INFO) << "VM " << id_ << ": microphone access enabled";
    bind_mounts.push_back("/run/cras/plugin/unified:/run/cras:true");
  } else {
    LOG(INFO) << "VM " << id_ << ": microphone access disabled";
    bind_mounts.push_back("/run/cras/plugin/playback:/run/cras: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));
  for (auto& mount : bind_mounts)
    vm_builder.AppendCustomParam("--plugin-mount", 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.
  vm_builder.AppendCustomParam(
      "--plugin-mount-file",
      plugin_bin_path.AddExtension("bind_mounts").value());

  // 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::BindOnce(
      &SetUpCrosvmProcess, base::FilePath(kPluginVmCpuCgroup).Append("tasks")));

  if (!StartProcess(vm_builder.BuildVmArgs())) {
    LOG(ERROR) << "Failed to start VM process";
    return false;
  }

  return true;
}

}  // namespace concierge
}  // namespace vm_tools
