// Copyright 2019 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/arc_vm.h"

#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

// Needs to be included after sys/socket.h
#include <linux/vm_sockets.h>

#include <utility>

#include <base/files/file.h>
#include <base/files/file_path.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/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_util.h>
#include <base/strings/string_split.h>
#include <base/system/sys_info.h>
#include <base/time/time.h>
#include <chromeos/constants/vm_tools.h>

#include "vm_tools/concierge/tap_device_builder.h"
#include "vm_tools/concierge/vm_util.h"

using std::string;

namespace vm_tools {
namespace concierge {
namespace {

// Name of the control socket used for controlling crosvm.
constexpr char kCrosvmSocket[] = "arcvm.sock";

// Path to the wayland socket.
constexpr char kWaylandSocket[] = "/run/chrome/wayland-0";

// 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 ARCVM's crosvm processes should belong to.
constexpr char kArcvmCpuCgroup[] = "/sys/fs/cgroup/cpu/vms/arc";

// Port for arc-powerctl running on the guest side.
constexpr unsigned int kVSockPort = 4242;

// Path to the custom parameter file.
constexpr char kCustomParameterFilePath[] = "/etc/arcvm_dev.conf";

// Custom parameter key to override the kernel path
constexpr char kKeyToOverrideKernelPath[] = "KERNEL_PATH";

// Shared directories and their tags
constexpr char kOemEtcSharedDir[] = "/run/arcvm/host_generated/oem/etc";
constexpr char kOemEtcSharedDirTag[] = "oem_etc";

// Uid and gid mappings for the android data directory. This is a
// comma-separated list of 3 values: <start of range inside the user namespace>
// <start of range outside the user namespace> <count>. The values are taken
// from platform2/arc/container-bundles/rvc/config.json.
constexpr char kAndroidUidMap[] =
    "0 655360 5000,5000 600 50,5050 660410 1994950";
constexpr char kAndroidGidMap[] =
    "0 655360 1065,1065 20119 1,1066 656426 3934,5000 600 50,5050 660410 "
    "1994950";

// For |kOemEtcSharedDir|, map host's chronos to guest's root, also arc-camera
// (603) to vendor_arc_camera (5003).
constexpr char kOemEtcUgidMap[] = "0 1000 1, 5000 600 50";

base::ScopedFD ConnectVSock(int cid) {
  DLOG(INFO) << "Creating VSOCK...";
  struct sockaddr_vm sa = {};
  sa.svm_family = AF_VSOCK;
  sa.svm_cid = cid;
  sa.svm_port = kVSockPort;

  base::ScopedFD fd(
      socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC, 0 /* protocol */));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "Failed to create VSOCK";
    return {};
  }

  DLOG(INFO) << "Connecting VSOCK";
  if (HANDLE_EINTR(connect(fd.get(),
                           reinterpret_cast<const struct sockaddr*>(&sa),
                           sizeof(sa))) == -1) {
    fd.reset();
    PLOG(ERROR) << "Failed to connect.";
    return {};
  }

  DLOG(INFO) << "VSOCK connected.";
  return fd;
}

bool ShutdownArcVm(int cid) {
  base::ScopedFD vsock(ConnectVSock(cid));
  if (!vsock.is_valid())
    return false;

  const std::string command("poweroff");
  if (HANDLE_EINTR(write(vsock.get(), command.c_str(), command.size())) !=
      command.size()) {
    PLOG(WARNING) << "Failed to write to ARCVM VSOCK";
    return false;
  }

  DLOG(INFO) << "Started shutting down ARCVM";
  return true;
}

std::string CreateSharedDataParam(const base::FilePath& data_dir,
                                  const std::string& tag,
                                  bool enable_caches) {
  return base::StringPrintf(
      "%s:%s:type=fs:cache=%s:uidmap=%s:gidmap=%s:timeout=3600:rewrite-"
      "security-xattrs=true",
      data_dir.value().c_str(), tag.c_str(), enable_caches ? "always" : "never",
      kAndroidUidMap, kAndroidGidMap);
}

}  // namespace

ArcVm::ArcVm(int32_t vsock_cid,
             std::unique_ptr<patchpanel::Client> network_client,
             std::unique_ptr<SeneschalServerProxy> seneschal_server_proxy,
             base::FilePath runtime_dir,
             ArcVmFeatures features)
    : VmBaseImpl(std::move(network_client)),
      vsock_cid_(vsock_cid),
      seneschal_server_proxy_(std::move(seneschal_server_proxy)),
      features_(features) {
  CHECK(base::DirectoryExists(runtime_dir));

  // Take ownership of the runtime directory.
  CHECK(runtime_dir_.Set(runtime_dir));
}

ArcVm::~ArcVm() {
  Shutdown();
}

std::unique_ptr<ArcVm> ArcVm::Create(
    base::FilePath kernel,
    base::FilePath rootfs,
    base::FilePath fstab,
    uint32_t cpus,
    base::FilePath pstore_path,
    uint32_t pstore_size,
    std::vector<ArcVm::Disk> disks,
    uint32_t vsock_cid,
    base::FilePath data_dir,
    std::unique_ptr<patchpanel::Client> network_client,
    std::unique_ptr<SeneschalServerProxy> seneschal_server_proxy,
    base::FilePath runtime_dir,
    ArcVmFeatures features,
    std::vector<string> params) {
  auto vm = base::WrapUnique(new ArcVm(vsock_cid, std::move(network_client),
                                       std::move(seneschal_server_proxy),
                                       std::move(runtime_dir), features));

  if (!vm->Start(std::move(kernel), std::move(rootfs), std::move(fstab), cpus,
                 std::move(pstore_path), pstore_size, std::move(disks),
                 std::move(data_dir), std::move(params))) {
    vm.reset();
  }

  return vm;
}

std::string ArcVm::GetVmSocketPath() const {
  return runtime_dir_.GetPath().Append(kCrosvmSocket).value();
}

bool ArcVm::Start(base::FilePath kernel,
                  base::FilePath rootfs,
                  base::FilePath fstab,
                  uint32_t cpus,
                  base::FilePath pstore_path,
                  uint32_t pstore_size,
                  std::vector<ArcVm::Disk> disks,
                  base::FilePath data_dir,
                  std::vector<string> params) {
  // Get the available network interfaces.
  network_devices_ = network_client_->NotifyArcVmStartup(vsock_cid_);
  if (network_devices_.empty()) {
    LOG(ERROR) << "No network devices available";
    return false;
  }

  // Open the tap device(s).
  std::vector<base::ScopedFD> tap_fds;
  for (const auto& dev : network_devices_) {
    auto fd = OpenTapDevice(dev.ifname(), true /*vnet_hdr*/,
                            nullptr /*ifname_out*/);
    if (!fd.is_valid()) {
      LOG(ERROR) << "Unable to open and configure TAP device " << dev.ifname();
    } else {
      tap_fds.emplace_back(std::move(fd));
    }
  }
  if (tap_fds.empty()) {
    LOG(ERROR) << "No TAP devices available";
    return false;
  }

  const std::string rootfs_flag = rootfs_writable() ? "--rwdisk" : "--disk";

  std::string oem_etc_shared_dir = base::StringPrintf(
      "%s:%s:type=fs:cache=always:uidmap=%s:gidmap=%s:timeout=3600:rewrite-"
      "security-xattrs=true",
      kOemEtcSharedDir, kOemEtcSharedDirTag, kOemEtcUgidMap, kOemEtcUgidMap);

  std::string shared_data = CreateSharedDataParam(data_dir, "data", true);
  std::string shared_data_media =
      CreateSharedDataParam(data_dir.Append("media"), "data_media", false);

  // Build up the process arguments.
  // clang-format off
  base::StringPairs args = {
    { kCrosvmBin,          "run" },
    { "--cpus",            std::to_string(cpus) },
    { "--mem",             GetVmMemoryMiB() },
    { rootfs_flag,         rootfs.value() },
    { "--cid",             std::to_string(vsock_cid_) },
    { "--socket",          GetVmSocketPath() },
    { "--gpu",             "" },
    { "--video-decoder",   ""},
    { "--wayland-sock",    kWaylandSocket },
    { "--wayland-sock",    "/run/arcvm/mojo/mojo-proxy.sock,name=mojo" },
    { "--serial",          "type=syslog,hardware=serial,num=1,earlycon=true" },
    { "--serial",          "type=syslog,hardware=virtio-console,num=1,"
                           "console=true" },
    { "--syslog-tag",      base::StringPrintf("ARCVM(%u)", vsock_cid_) },
    { "--ac97",            "backend=cras,capture=true" },
    { "--ac97",            "backend=cras,capture=true,capture_effects=aec" },
    { "--android-fstab",   fstab.value() },
    { "--pstore",          base::StringPrintf("path=%s,size=%d",
                              pstore_path.value().c_str(), pstore_size) },
    { "--shared-dir",     std::move(oem_etc_shared_dir) },
    { "--shared-dir",     std::move(shared_data) },
    { "--shared-dir",     std::move(shared_data_media) },
    { "--params",         base::JoinString(params, " ") },
  };
  // clang-format on

  if (USE_CROSVM_WL_DMABUF)
    args.emplace_back("--wayland-dmabuf", "");

  for (const auto& fd : tap_fds) {
    args.emplace_back("--tap-fd", std::to_string(fd.get()));
  }

  // Add any extra disks.
  for (const auto& disk : disks) {
    if (disk.writable) {
      args.emplace_back("--rwdisk", disk.path.value());
    } else {
      args.emplace_back("--disk", disk.path.value());
    }
  }

  // Add any custom parameters from file.
  base::FilePath file_path(kCustomParameterFilePath);
  std::string data;
  if (base::ReadFileToString(file_path, &data))
    LoadCustomParameters(data, &args);

  // Finally list the path to the kernel.
  const std::string kernel_path =
      RemoveParametersWithKey(kKeyToOverrideKernelPath, kernel.value(), &args);
  args.emplace_back(kernel_path, "");

  // Put everything into the brillo::ProcessImpl.
  for (std::pair<std::string, std::string>& arg : args) {
    process_.AddArg(std::move(arg.first));
    if (!arg.second.empty())
      process_.AddArg(std::move(arg.second));
  }

  // 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 ARCVM's crosvm processes.
  process_.SetPreExecCallback(base::Bind(
      &SetUpCrosvmProcess, base::FilePath(kArcvmCpuCgroup).Append("tasks")));

  if (!process_.Start()) {
    LOG(ERROR) << "Failed to start VM process";
    // Release any network resources.
    network_client_->NotifyArcVmShutdown(vsock_cid_);
    return false;
  }

  return true;
}

bool ArcVm::Shutdown() {
  // Notify arc-patchpanel that ARCVM is down.
  // This should run before the process existence check below since we still
  // want to release the network resources on crash.
  if (!network_client_->NotifyArcVmShutdown(vsock_cid_)) {
    LOG(WARNING) << "Unable to notify networking services";
  }

  // Do a sanity check here to make sure the process is still around.  It may
  // have crashed and we don't want to be waiting around for an RPC response
  // that's never going to come.  kill with a signal value of 0 is explicitly
  // documented as a way to check for the existence of a process.
  if (!CheckProcessExists(process_.pid())) {
    LOG(INFO) << "ARCVM process is already gone. Do nothing";
    process_.Release();
    return true;
  }

  LOG(INFO) << "Shutting down ARCVM";

  // Ask arc-powerctl running on the guest to power off the VM.
  // TODO(yusukes): We should call ShutdownArcVm() only after the guest side
  // service is fully started. b/143711798
  if (ShutdownArcVm(vsock_cid_) &&
      WaitForChild(process_.pid(), kChildExitTimeout)) {
    LOG(INFO) << "ARCVM is shut down";
    process_.Release();
    return true;
  }

  LOG(WARNING) << "Failed to shut down ARCVM gracefully. Trying to turn it "
               << "down via the crosvm socket.";
  RunCrosvmCommand("stop", GetVmSocketPath());

  // We can't actually trust the exit codes that crosvm gives us so just see if
  // it exited.
  if (WaitForChild(process_.pid(), kChildExitTimeout)) {
    process_.Release();
    return true;
  }

  LOG(WARNING) << "Failed to stop VM " << vsock_cid_ << " via crosvm socket";

  // Kill the process with SIGTERM.
  if (process_.Kill(SIGTERM, kChildExitTimeout.InSeconds())) {
    process_.Release();
    return true;
  }

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

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

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

bool ArcVm::AttachUsbDevice(uint8_t bus,
                            uint8_t addr,
                            uint16_t vid,
                            uint16_t pid,
                            int fd,
                            UsbControlResponse* response) {
  return vm_tools::concierge::AttachUsbDevice(GetVmSocketPath(), bus, addr, vid,
                                              pid, fd, response);
}

bool ArcVm::DetachUsbDevice(uint8_t port, UsbControlResponse* response) {
  return vm_tools::concierge::DetachUsbDevice(GetVmSocketPath(), port,
                                              response);
}

bool ArcVm::ListUsbDevice(std::vector<UsbDevice>* devices) {
  return vm_tools::concierge::ListUsbDevice(GetVmSocketPath(), devices);
}

void ArcVm::HandleSuspendImminent() {
  RunCrosvmCommand("suspend", GetVmSocketPath());
}

void ArcVm::HandleSuspendDone() {
  RunCrosvmCommand("resume", GetVmSocketPath());
}

// static
bool ArcVm::SetVmCpuRestriction(CpuRestrictionState cpu_restriction_state) {
  return VmBaseImpl::SetVmCpuRestriction(cpu_restriction_state,
                                         kArcvmCpuCgroup);
}

uint32_t ArcVm::IPv4Address() const {
  for (const auto& dev : network_devices_) {
    if (dev.ifname() == "arc0")
      return dev.ipv4_addr();
  }
  return 0;
}

VmInterface::Info ArcVm::GetInfo() {
  VmInterface::Info info = {
      .ipv4_address = IPv4Address(),
      .pid = pid(),
      .cid = cid(),
      .seneschal_server_handle = seneschal_server_handle(),
      .status = VmInterface::Status::RUNNING,
  };

  return info;
}

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

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

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

}  // namespace concierge
}  // namespace vm_tools
