// Copyright 2017 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/maitred/service_impl.h"

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <stdint.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>

#include <linux/fs.h>
#include <linux/vm_sockets.h>

#include <map>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/synchronization/lock.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/posix/safe_strerror.h>
#include <base/process/process_iterator.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/file_utils.h>

#include "vm_tools/common/paths.h"

using std::string;

namespace vm_tools {
namespace maitred {
namespace {

// Default name of the interface in the VM.
constexpr char kInterfaceName[] = "eth0";
constexpr char kLoopbackName[] = "lo";

constexpr char kHostIpPath[] = "/run/host_ip";

const std::vector<string> kDefaultNameservers = {
    "8.8.8.8", "8.8.4.4", "2001:4860:4860::8888", "2001:4860:4860::8844"};
constexpr char kResolvConfOptions[] =
    "options single-request timeout:1 attempts:5\n";
constexpr char kResolvConfPath[] = "/run/resolv.conf";
constexpr char kRunPath[] = "/run";
constexpr char kTmpResolvConfPath[] = "/run/resolv.conf.tmp";

// Convert a 32-bit int in network byte order into a printable string.
string AddressToString(uint32_t address) {
  struct in_addr in = {
      .s_addr = address,
  };
  char buf[INET_ADDRSTRLEN];
  if (inet_ntop(AF_INET, &in, buf, INET_ADDRSTRLEN) == nullptr) {
    PLOG(ERROR) << "Failed to parse address " << address;
    return string("<unknown>");
  }

  return string(buf);
}

// Set a network interface's flags to be up and running. Returns 0 on success,
// or the saved errno otherwise.
int EnableInterface(int sockfd, const char* ifname) {
  struct ifreq ifr;
  int ret;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));

  ret = HANDLE_EINTR(ioctl(sockfd, SIOCGIFFLAGS, &ifr));
  if (ret) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to fetch flags for interface " << ifname;
    return saved_errno;
  }

  ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
  ret = HANDLE_EINTR(ioctl(sockfd, SIOCSIFFLAGS, &ifr));
  if (ret) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to set flags for interface " << ifname;
    return saved_errno;
  }

  return 0;
}

// Prints an error log with the message in |error| concatenated with the
// string representation of the current value of errno. The same error message
// will also be stored in |out_error|.
void PLogAndSaveError(const string& error, string* out_error) {
  string error_with_strerror = error + ": " + base::safe_strerror(errno);
  LOG(ERROR) << error_with_strerror;
  out_error->assign(error_with_strerror);
}

// Sets a sysctl node to a supplied value.
bool SetSysctl(const char* path, const char* val, string* out_error) {
  DCHECK(out_error);
  base::ScopedFD sysctl_node(open(path, O_RDWR | O_CLOEXEC));

  if (!sysctl_node.is_valid()) {
    PLogAndSaveError(base::StringPrintf("unable to open sysctl node: %s", path),
                     out_error);
    return false;
  }

  ssize_t count = write(sysctl_node.get(), val, strlen(val));
  if (count != strlen(val)) {
    PLogAndSaveError(
        base::StringPrintf("failed to write sysctl node: %s", path), out_error);
    return false;
  }

  return true;
}

bool EnableLro(const char* ifname, string* out_error) {
  DCHECK(out_error);

  base::ScopedFD sockfd(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
  if (!sockfd.is_valid()) {
    PLogAndSaveError("failed to create socket for ethtool ioctl", out_error);
    return false;
  }

  struct ifreq ifr;
  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));

  struct ethtool_value val;
  val.cmd = ETHTOOL_GFLAGS;
  ifr.ifr_data = reinterpret_cast<char*>(&val);

  if (HANDLE_EINTR(ioctl(sockfd.get(), SIOCETHTOOL, &ifr)) != 0) {
    PLogAndSaveError(
        base::StringPrintf("failed to get ethtool flags for %s", ifname),
        out_error);
    return false;
  }

  val.cmd = ETHTOOL_SFLAGS;
  val.data |= ETH_FLAG_LRO;

  if (HANDLE_EINTR(ioctl(sockfd.get(), SIOCETHTOOL, &ifr)) != 0) {
    PLogAndSaveError(base::StringPrintf("failed to enable LRO for %s", ifname),
                     out_error);
    return false;
  }

  return true;
}

// Writes a resolv.conf with the supplied |nameservers| and |search_domains|.
// The default Chrome OS resolver options will be used. Returns true on
// success, and returns false on failure with an error message stored in
// |out_error|.
bool WriteResolvConf(const std::vector<string> nameservers,
                     const std::vector<string> search_domains,
                     string* out_error) {
  DCHECK(out_error);

  base::ScopedFD resolv_fd(
      HANDLE_EINTR(open(kRunPath, O_TMPFILE | O_WRONLY | O_CLOEXEC, 0644)));
  if (!resolv_fd.is_valid()) {
    PLogAndSaveError(
        base::StringPrintf("failed to open tmpfile in %s", kRunPath),
        out_error);
    return false;
  }

  for (auto& ns : nameservers) {
    string nameserver_line = base::StringPrintf("nameserver %s\n", ns.c_str());
    if (!base::WriteFileDescriptor(resolv_fd.get(), nameserver_line.c_str(),
                                   nameserver_line.length())) {
      PLogAndSaveError("failed to write nameserver to tmpfile", out_error);
      return false;
    }
  }

  if (!search_domains.empty()) {
    string search_domains_line = base::StringPrintf(
        "search %s\n", base::JoinString(search_domains, " ").c_str());
    if (!base::WriteFileDescriptor(resolv_fd.get(), search_domains_line.c_str(),
                                   search_domains_line.length())) {
      PLogAndSaveError("failed to write search domains to tmpfile", out_error);
      return false;
    }
  }

  if (!base::WriteFileDescriptor(resolv_fd.get(), kResolvConfOptions,
                                 strlen(kResolvConfOptions))) {
    PLogAndSaveError("failed to write resolver options to tmpfile", out_error);
    return false;
  }

  // The file has been successfully written to, so link it into place.
  // First link it to a named file with linkat(2), then atomically move it
  // into place with rename(2). linkat(2) will not overwrite the destination,
  // hence the need to do this in two steps.
  const base::FilePath source_path(
      base::StringPrintf("/proc/self/fd/%d", resolv_fd.get()));
  if (HANDLE_EINTR(linkat(AT_FDCWD, source_path.value().c_str(), AT_FDCWD,
                          kTmpResolvConfPath, AT_SYMLINK_FOLLOW)) < 0) {
    PLogAndSaveError(
        base::StringPrintf("failed to link tmpfile to %s", kTmpResolvConfPath),
        out_error);
    return false;
  }

  if (HANDLE_EINTR(rename(kTmpResolvConfPath, kResolvConfPath)) < 0) {
    PLogAndSaveError(
        base::StringPrintf("failed to rename tmpfile to %s", kResolvConfPath),
        out_error);
    return false;
  }

  return true;
}

}  // namespace

ServiceImpl::ServiceImpl(std::unique_ptr<vm_tools::maitred::Init> init)
    : init_(std::move(init)),
      lxd_env_({{"LXD_DIR", "/mnt/stateful/lxd"},
                {"LXD_CONF", "/mnt/stateful/lxd_conf"}}) {}

bool ServiceImpl::Init() {
  string error;

  return WriteResolvConf(kDefaultNameservers, {}, &error);
}

grpc::Status ServiceImpl::ConfigureNetwork(grpc::ServerContext* ctx,
                                           const NetworkConfigRequest* request,
                                           EmptyMessage* response) {
  static_assert(sizeof(uint32_t) == sizeof(in_addr_t),
                "in_addr_t is not the same width as uint32_t");
  LOG(INFO) << "Received network configuration request";

  const IPv4Config& ipv4_config = request->ipv4_config();
  if (ipv4_config.address() == 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "IPv4 address cannot be 0");
  }
  if (ipv4_config.netmask() == 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "IPv4 netmask cannot be 0");
  }
  if (ipv4_config.gateway() == 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "IPv4 gateway cannot be 0");
  }

  // Enable IP forwarding first. This will disable LRO, which we'll then have
  // to reenable manually later.
  string error;
  if (!SetSysctl("/proc/sys/net/ipv4/ip_forward", "1", &error)) {
    return grpc::Status(grpc::INTERNAL, error);
  }
  // accept_ra = 2: To accept RA packet even if forwarding == 1
  if (!SetSysctl(base::StringPrintf("/proc/sys/net/ipv6/conf/%s/accept_ra",
                                    kInterfaceName)
                     .c_str(),
                 "2", &error)) {
    return grpc::Status(grpc::INTERNAL, error);
  }
  if (!SetSysctl("/proc/sys/net/ipv6/conf/all/forwarding", "1", &error)) {
    return grpc::Status(grpc::INTERNAL, error);
  }

  base::ScopedFD fd(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
  if (!fd.is_valid()) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to create socket";
    return grpc::Status(grpc::INTERNAL, string("failed to create socket: ") +
                                            strerror(saved_errno));
  }

  // Set up the address.
  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, kInterfaceName, sizeof(ifr.ifr_name));

  // Holy fuck, who designed this interface?  Did you know that ifr_addr and
  // ifr_name are actually macros?!?  For example, ifr_addr expands to
  // ifr_ifru.ifru_addr and ifr_name expands to ifr_ifrn.ifrn_name.  This is
  // because the address, the flags, the netmask, and basically everything
  // else all share the same underlying storage via a union.  "Let's just put
  // everything into one union.  Who needs type safety anyway?". smh.
  struct sockaddr_in* addr =
      reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_addr);
  addr->sin_family = AF_INET;
  addr->sin_addr.s_addr = static_cast<in_addr_t>(ipv4_config.address());

  if (HANDLE_EINTR(ioctl(fd.get(), SIOCSIFADDR, &ifr)) != 0) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to set IPv4 address for interface " << kInterfaceName
                << " to " << AddressToString(ipv4_config.address());
    return grpc::Status(grpc::INTERNAL, string("failed to set IPv4 address: ") +
                                            strerror(saved_errno));
  }

  LOG(INFO) << "Set IPv4 address for interface " << kInterfaceName << " to "
            << AddressToString(ipv4_config.address());

  // Set the netmask.
  struct sockaddr_in* netmask =
      reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_netmask);
  netmask->sin_family = AF_INET;
  netmask->sin_addr.s_addr = static_cast<in_addr_t>(ipv4_config.netmask());

  if (HANDLE_EINTR(ioctl(fd.get(), SIOCSIFNETMASK, &ifr)) != 0) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to set IPv4 netmask for interface " << kInterfaceName
                << " to " << AddressToString(ipv4_config.netmask());
    return grpc::Status(grpc::INTERNAL, string("failed to set IPv4 netmask: ") +
                                            strerror(saved_errno));
  }

  LOG(INFO) << "Set IPv4 netmask for interface " << kInterfaceName << " to "
            << AddressToString(ipv4_config.netmask());

  // Set the interface up and running.  This needs to happen before the kernel
  // will let us set the gateway.
  int ret = EnableInterface(fd.get(), kInterfaceName);
  if (ret) {
    return grpc::Status(
        grpc::INTERNAL,
        string("failed to enable network interface: ") + strerror(ret));
  }
  LOG(INFO) << "Set interface " << kInterfaceName << " up and running";

  // Forcibly enables Large Receive Offload via ethtool. Linux will
  // conservatively disable LRO if IP forwarding is enabled since LRO mangles
  // packets in a way that makes it unsafe to forward. virtio-net uses Generic
  // Receive Offload, which is safe to use with IP forwarding.
  if (!EnableLro(kInterfaceName, &error)) {
    // Don't fail the entire network config since this may run with a 4.19
    // kernel that doesn't support setting LRO on virtio-net.
    LOG(WARNING) << "Failed to enable LRO: " << error;
  }

  // Bring up the loopback interface too.
  ret = EnableInterface(fd.get(), kLoopbackName);
  if (ret) {
    return grpc::Status(
        grpc::INTERNAL,
        string("failed to enable loopback interface") + strerror(ret));
  }

  // Set the gateway.
  struct rtentry route;
  memset(&route, 0, sizeof(route));

  struct sockaddr_in* gateway =
      reinterpret_cast<struct sockaddr_in*>(&route.rt_gateway);
  gateway->sin_family = AF_INET;
  gateway->sin_addr.s_addr = static_cast<in_addr_t>(ipv4_config.gateway());

  struct sockaddr_in* dst =
      reinterpret_cast<struct sockaddr_in*>(&route.rt_dst);
  dst->sin_family = AF_INET;
  dst->sin_addr.s_addr = INADDR_ANY;

  struct sockaddr_in* genmask =
      reinterpret_cast<struct sockaddr_in*>(&route.rt_genmask);
  genmask->sin_family = AF_INET;
  genmask->sin_addr.s_addr = INADDR_ANY;

  route.rt_flags = RTF_UP | RTF_GATEWAY;

  string gateway_str = AddressToString(ipv4_config.gateway());
  if (HANDLE_EINTR(ioctl(fd.get(), SIOCADDRT, &route)) != 0) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to set default IPv4 gateway for interface "
                << kInterfaceName << " to " << gateway_str;
    return grpc::Status(grpc::INTERNAL, string("failed to set IPv4 gateway: ") +
                                            strerror(saved_errno));
  }

  LOG(INFO) << "Set default IPv4 gateway for interface " << kInterfaceName
            << " to " << gateway_str;

  // Write the host IP address to a file for LXD containers to use.
  base::FilePath host_ip_path(kHostIpPath);
  size_t gateway_str_len = gateway_str.size();
  if (base::WriteFile(host_ip_path, gateway_str.c_str(), gateway_str_len) !=
      gateway_str_len) {
    LOG(ERROR) << "Failed to write host IPv4 address to file";
    return grpc::Status(grpc::INTERNAL, "failed to write host IPv4 address");
  }

  if (!base::SetPosixFilePermissions(host_ip_path, 0644)) {
    LOG(ERROR) << "Failed to set host IPv4 address file permissions";
    return grpc::Status(grpc::INTERNAL,
                        "failed to set host IPv4 address permissions");
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::Shutdown(grpc::ServerContext* ctx,
                                   const EmptyMessage* request,
                                   EmptyMessage* response) {
  LOG(INFO) << "Received shutdown request";

  if (!init_) {
    return grpc::Status(grpc::FAILED_PRECONDITION, "not running as init");
  }

  init_->Shutdown();

  shutdown_cb_.Run();

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::LaunchProcess(
    grpc::ServerContext* ctx,
    const vm_tools::LaunchProcessRequest* request,
    vm_tools::LaunchProcessResponse* response) {
  LOG(INFO) << "Received request to launch process";
  if (!init_) {
    return grpc::Status(grpc::FAILED_PRECONDITION, "not running as init");
  }

  if (request->argv_size() <= 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "missing argv");
  }

  if (request->respawn() && request->wait_for_exit()) {
    return grpc::Status(grpc::INVALID_ARGUMENT,
                        "respawn and wait_for_exit cannot both be true");
  }

  std::vector<string> argv(request->argv().begin(), request->argv().end());
  std::map<string, string> env;
  for (const auto& pair : request->env()) {
    env[pair.first] = pair.second;
  }

  Init::ProcessLaunchInfo launch_info;
  if (!init_->Spawn(std::move(argv), std::move(env), request->respawn(),
                    request->use_console(), request->wait_for_exit(),
                    &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn process");
  }

  switch (launch_info.status) {
    case Init::ProcessStatus::UNKNOWN:
      LOG(WARNING) << "Child process has unknown status";

      response->set_status(vm_tools::UNKNOWN);
      break;
    case Init::ProcessStatus::EXITED:
      LOG(INFO) << "Requested process " << request->argv()[0] << " exited with "
                << "status " << launch_info.code;

      response->set_status(vm_tools::EXITED);
      response->set_code(launch_info.code);
      break;
    case Init::ProcessStatus::SIGNALED:
      LOG(INFO) << "Requested process " << request->argv()[0] << " killed by "
                << "signal " << launch_info.code;

      response->set_status(vm_tools::SIGNALED);
      response->set_code(launch_info.code);
      break;
    case Init::ProcessStatus::LAUNCHED:
      LOG(INFO) << "Launched process " << request->argv()[0];

      response->set_status(vm_tools::LAUNCHED);
      break;
    case Init::ProcessStatus::FAILED:
      LOG(ERROR) << "Failed to launch requested process";

      response->set_status(vm_tools::FAILED);
      break;
  }

  // Return OK no matter what because the RPC itself succeeded even if there
  // was an issue with launching the process.
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::Mount(grpc::ServerContext* ctx,
                                const MountRequest* request,
                                MountResponse* response) {
  LOG(INFO) << "Received mount request";

  const base::FilePath target_path = base::FilePath(request->target());
  if (request->create_target()) {
    // Create a mount point if it doesn't exist.
    if (!brillo::MkdirRecursively(target_path, 0755).is_valid()) {
      PLOG(ERROR) << "Failed to create " << request->target();
      return grpc::Status(grpc::INTERNAL,
                          base::StringPrintf("failed to create a directory: %s",
                                             request->target().c_str()));
    }
  }

  int ret = mount(request->source().c_str(), request->target().c_str(),
                  request->fstype().c_str(), request->mountflags(),
                  request->options().c_str());

  if (ret < 0 && errno == EINVAL && request->mkfs_if_needed()) {
    // When the source has an invalid superblock (e.g. not formatted), run
    // mkfs.btrfs and retry mount.

    LOG(INFO) << "Formatting" << request->source() << " as btrfs";

    Init::ProcessLaunchInfo launch_info;
    if (!init_->Spawn({"mkfs.btrfs", request->source().c_str()}, lxd_env_,
                      false /*respawn*/, false /*use_console*/,
                      true /*wait_for_exit*/, &launch_info)) {
      return grpc::Status(grpc::INTERNAL, "failed to spawn mkfs.btrfs");
    }
    if (launch_info.status != Init::ProcessStatus::EXITED) {
      return grpc::Status(grpc::INTERNAL, "mkfs.btrfs did not complete");
    }

    ret = mount(request->source().c_str(), request->target().c_str(),
                request->fstype().c_str(), request->mountflags(),
                request->options().c_str());
  }

  if (ret < 0) {
    response->set_error(errno);
    PLOG(ERROR) << "Failed to mount \"" << request->source() << "\" on \""
                << request->target() << "\"";
  } else {
    response->set_error(0);
    LOG(INFO) << "Mounted \"" << request->source() << "\" on \""
              << request->target() << "\"";
  }

  if (request->permissions() != 0) {
    ret = chmod(request->target().c_str(), request->permissions());

    if (ret < 0) {
      response->set_error(errno);
      PLOG(ERROR) << "Failed to change the mode of \""
                  << "\"" << request->target() << "\"";

      // Unmount the disk. Since this is cleanup, we ignore its return value.
      umount(request->target().c_str());
      return grpc::Status(grpc::INTERNAL, "failed to change the mode");
    }
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::ResetIPv6(grpc::ServerContext* ctx,
                                    const vm_tools::EmptyMessage* request,
                                    vm_tools::EmptyMessage* response) {
  // This method is deprecated, but should otherwise perform the same actions
  // as OnHostNetworkChanged.
  return OnHostNetworkChanged(ctx, request, response);
}

grpc::Status ServiceImpl::OnHostNetworkChanged(
    grpc::ServerContext* ctx,
    const vm_tools::EmptyMessage* request,
    vm_tools::EmptyMessage* response) {
  LOG(INFO) << "Received OnHostNetworkChanged request";
  string error;

  // Reset IPv6 to force SLAAC renegotiation.
  if (!SetSysctl(base::StringPrintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6",
                                    kInterfaceName)
                     .c_str(),
                 "1", &error)) {
    return grpc::Status(grpc::INTERNAL, error + ", cannot disable ipv6");
  }
  if (!SetSysctl(base::StringPrintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6",
                                    kInterfaceName)
                     .c_str(),
                 "0", &error)) {
    return grpc::Status(grpc::INTERNAL, error + ", cannot enable ipv6");
  }

  // Send SIGHUP to dnsmasq to flush caches.
  base::NamedProcessIterator iter("dnsmasq", nullptr);
  while (const base::ProcessEntry* entry = iter.NextProcessEntry())
    kill(entry->pid(), SIGHUP);

  // TODO(http://crbug/1058730): Existing sockets should also be shut down.
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::ConfigureContainerGuest(
    grpc::ServerContext* ctx,
    const vm_tools::ConfigureContainerGuestRequest* request,
    vm_tools::EmptyMessage* response) {
  LOG(INFO) << "Received ConfigureContainerGuest request";
  Init::ProcessLaunchInfo launch_info;

  // Tell garcon what the host ip is.
  unlink(vm_tools::kGarconHostIpFile);
  if (symlink(kHostIpPath, vm_tools::kGarconHostIpFile) != 0) {
    return grpc::Status(
        grpc::INTERNAL,
        string("failed to link host ip where garcon expects it: ") +
            strerror(errno));
  }

  // Tell garcon what the token is.
  base::FilePath token_path{vm_tools::kGarconContainerTokenFile};
  if (base::WriteFile(token_path, request->container_token().c_str(),
                      request->container_token().size()) !=
      request->container_token().size()) {
    return grpc::Status(grpc::INTERNAL,
                        "failed to write container token to file");
  }

  // Run garcon.
  if (!init_->Spawn({"/etc/init.d/cros-garcon", "daemon"}, {}, true /*respawn*/,
                    false /*use_console*/, false /*wait_for_exit*/,
                    &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to launch garcon");
  }
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::StartTermina(grpc::ServerContext* ctx,
                                       const StartTerminaRequest* request,
                                       StartTerminaResponse* response) {
  LOG(INFO) << "Received StartTermina request";

  if (!request->allow_privileged_containers())
    lxd_env_.emplace("LXD_UNPRIVILEGED_ONLY", "true");

  response->set_mount_result(StartTerminaResponse::UNKNOWN);

  if (!init_) {
    return grpc::Status(grpc::FAILED_PRECONDITION, "not running as init");
  }

  Init::ProcessLaunchInfo launch_info;
  stateful_device_ = request->stateful_device().empty()
                         ? "/dev/vdb"
                         : request->stateful_device();
  if (!init_->Spawn({"mkfs.btrfs", stateful_device_}, lxd_env_,
                    false /*respawn*/, false /*use_console*/,
                    true /*wait_for_exit*/, &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn mkfs.btrfs");
  }
  if (launch_info.status != Init::ProcessStatus::EXITED) {
    return grpc::Status(grpc::INTERNAL, "mkfs.btrfs did not complete");
  }
  // mkfs.btrfs will fail if the disk is already formatted as btrfs.
  // Optimistically continue on - if the mount fails, then return an error.

  int ret = mount(stateful_device_.c_str(), "/mnt/stateful", "btrfs", 0,
                  "user_subvol_rm_allowed,discard");
  if (ret != 0) {
    int saved_errno = errno;
    PLOG(ERROR) << "Failed to mount stateful disk";

    ret = mount(stateful_device_.c_str(), "/mnt/stateful", "btrfs", 0,
                "user_subvol_rm_allowed,discard,usebackuproot");

    if (ret != 0) {
      int saved_errno_retry = errno;
      response->set_mount_result(StartTerminaResponse::FAILURE);
      return grpc::Status(grpc::INTERNAL,
                          string("failed to mount stateful(") +
                              stateful_device_ + "): " + strerror(saved_errno) +
                              ", " + strerror(saved_errno_retry));
    } else {
      response->set_mount_result(StartTerminaResponse::PARTIAL_DATA_LOSS);
    }
  } else {
    response->set_mount_result(StartTerminaResponse::SUCCESS);
  }

  // Register our crash reporter.
  if (!init_->Spawn({"/sbin/crash_reporter", "--init"}, {} /*env*/,
                    false /*respawn*/, true /*use_console*/,
                    true /*wait_for_exit*/, &launch_info)) {
    LOG(ERROR) << "Failed to spawn crash_reporter registration";
  } else if (launch_info.status != Init::ProcessStatus::EXITED ||
             launch_info.code != 0) {
    LOG(ERROR) << "Failed to register crash_reporter";
  }

  // Resize the stateful filesystem to fill the block device in case
  // the size was increased while the VM wasn't booted.
  if (!init_->Spawn({"btrfs", "filesystem", "resize", "max", "/mnt/stateful"},
                    lxd_env_, false /*respawn*/, false /*use_console*/,
                    true /*wait_for_exit*/, &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn btrfs resize");
  }
  // btrfs resize operation should not fail, but if it does, attempt to
  // continue anyway.
  if (launch_info.status != Init::ProcessStatus::EXITED) {
    PLOG(ERROR) << "btrfs resize did not complete";
  } else if (launch_info.code != 0) {
    PLOG(ERROR) << "btrfs resize returned non-zero";
  }

  // TODO(davidriley): Replace this #if with StartBorealis.
#if !USE_VM_BOREALIS
  // Start lxcfs.
  if (!init_->Spawn({"lxcfs", "/var/lib/lxcfs"}, {} /*env*/, true /*respawn*/,
                    true /*use_console*/, false /*wait_for_exit*/,
                    &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn lxcfs");
  }
  if (launch_info.status != Init::ProcessStatus::LAUNCHED) {
    return grpc::Status(grpc::INTERNAL, "lxcfs did not launch");
  }

  std::vector<std::string> tremplin_argv{"tremplin", "-lxd_subnet",
                                         request->lxd_ipv4_subnet()};
  for (const auto feature : request->feature()) {
    tremplin_argv.emplace_back("-feature");
    tremplin_argv.emplace_back(request->Feature_Name(feature));
  }

  if (!init_->Spawn(tremplin_argv, lxd_env_, true /*respawn*/,
                    true /*use_console*/, false /*wait_for_exit*/,
                    &launch_info)) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn tremplin");
  }
  if (launch_info.status != Init::ProcessStatus::LAUNCHED) {
    return grpc::Status(grpc::INTERNAL, "tremplin did not launch");
  }

  if (!init_->Spawn({"ndproxyd", "eth0", "lxdbr0"}, lxd_env_, true /*respawn*/,
                    true /*use_console*/, false /*wait_for_exit*/,
                    &launch_info)) {
    LOG(WARNING) << "failed to spawn ndproxyd";
  } else if (launch_info.status != Init::ProcessStatus::LAUNCHED) {
    LOG(WARNING) << "ndproxyd did not launch";
  }

  if (!init_->Spawn({"mcastd", "eth0", "lxdbr0"}, lxd_env_, true /*respawn*/,
                    true /*use_console*/, false /*wait_for_exit*/,
                    &launch_info)) {
    LOG(WARNING) << "failed to spawn mcastd";
  } else if (launch_info.status != Init::ProcessStatus::LAUNCHED) {
    LOG(WARNING) << "mcastd did not launch";
  }
#endif

  return grpc::Status::OK;
}

void ServiceImpl::ResizeCommandExitCallback(Init::ProcessStatus status,
                                            int code) {
  base::AutoLock auto_lock(resize_state_.lock);
  LOG(INFO) << "Resize command completed";
  resize_state_.resize_in_progress = false;

  if (status == Init::ProcessStatus::EXITED) {
    LOG(INFO) << "btrfs filesystem resize exited with code " << code;
    if (code == 0) {
      // Resize was successful.
      resize_state_.current_size = resize_state_.target_size;
    }
  } else if (status == Init::ProcessStatus::SIGNALED) {
    LOG(INFO) << "btrfs filesystem resize was terminated by signal " << code;
  } else {
    LOG(ERROR) << "Unexpected exit status " << static_cast<int>(status);
  }
}

grpc::Status ServiceImpl::ResizeFilesystem(
    grpc::ServerContext* ctx,
    const ResizeFilesystemRequest* request,
    ResizeFilesystemResponse* response) {
  base::AutoLock auto_lock(resize_state_.lock);

  if (resize_state_.resize_in_progress) {
    LOG(INFO) << "Resize already in progress";
    response->set_status(ResizeFilesystemResponse::ALREADY_IN_PROGRESS);
    return grpc::Status::OK;
  }

  if (stateful_device_.empty()) {
    return grpc::Status(grpc::INTERNAL, "unknown stateful device");
  }

  base::ScopedFD stateful_fd(
      open(stateful_device_.c_str(), O_RDONLY | O_CLOEXEC));
  if (!stateful_fd.is_valid()) {
    return grpc::Status(grpc::INTERNAL, "unable to open mount point");
  }

  // The disk resize should be complete by the time this function is called
  // (when expanding), but it's possible that the guest kernel hasn't processed
  // the configuration change notification and updated the block device size
  // yet. This loop waits until the disk is at least as large as the target
  // filesystem size. If the disk resize does not finish in a reasonable amount
  // of time, fall through and attempt the btrfs resize anyway; it will fail if
  // the disk is still not a sufficient size.
  useconds_t retry_delay = 100000;  // 0.1 seconds
  int size_retries = 5;             // Retry up to 6 times (6.3 seconds).
  while (size_retries--) {
    uint64_t disk_bytes = 0;
    if (ioctl(stateful_fd.get(), BLKGETSIZE64, &disk_bytes) == 0 &&
        disk_bytes >= request->size()) {
      break;
    }
    usleep(retry_delay);
    retry_delay *= 2;
  }
  if (size_retries < 0) {
    LOG(WARNING) << "disk size did not match expected value";
  }

  Init::ProcessLaunchInfo launch_info;
  if (!init_->Spawn({"btrfs", "filesystem", "resize",
                     std::to_string(request->size()), "/mnt/stateful"},
                    lxd_env_, false /*respawn*/, true /*use_console*/,
                    false /*wait_for_exit*/, &launch_info,
                    base::Bind(&ServiceImpl::ResizeCommandExitCallback,
                               base::Unretained(this)))) {
    return grpc::Status(grpc::INTERNAL, "failed to spawn btrfs resize");
  }

  if (launch_info.status != Init::ProcessStatus::LAUNCHED) {
    return grpc::Status(grpc::INTERNAL, "btrfs resize could not be launched");
  }

  resize_state_.resize_in_progress = true;
  resize_state_.target_size = request->size();

  response->set_status(ResizeFilesystemResponse::STARTED);
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::GetResizeStatus(
    grpc::ServerContext* ctx,
    const EmptyMessage* request,
    vm_tools::GetResizeStatusResponse* response) {
  base::AutoLock auto_lock(resize_state_.lock);
  response->set_resize_in_progress(resize_state_.resize_in_progress);
  response->set_current_size(resize_state_.current_size);
  response->set_target_size(resize_state_.target_size);
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::GetResizeBounds(
    grpc::ServerContext* ctx,
    const EmptyMessage* request,
    vm_tools::GetResizeBoundsResponse* response) {
  Init::ProcessLaunchInfo launch_info;
  if (!init_->Spawn(
          {"btrfs", "inspect-internal", "min-dev-size", "/mnt/stateful"},
          lxd_env_, false /*respawn*/, false /*use_console*/,
          true /*wait_for_exit*/, &launch_info)) {
    LOG(ERROR) << "btrfs inspect-internal min-dev-size failed: "
               << launch_info.output;
    return grpc::Status(grpc::INTERNAL,
                        "btrfs inspect-internal min-dev-size failed");
  }

  std::string& btrfs_out = launch_info.output;

  // btrfs inspect-internal min-dev-size returns a string like:
  // "9701425152 bytes (9.04GiB)"
  // Extract the first space-separated word and parse it as a 64-bit integer.
  size_t space_pos = btrfs_out.find_first_of(' ');
  if (space_pos == std::string::npos) {
    LOG(ERROR) << "failed to parse btrfs output (no space found): "
               << btrfs_out;
    return grpc::Status(grpc::INTERNAL, "failed to parse btrfs output");
  }

  std::string min_size_str = btrfs_out.substr(0, space_pos);
  uint64_t min_size = 0;
  if (!base::StringToUint64(min_size_str, &min_size)) {
    LOG(ERROR) << "failed to parse btrfs output as uint64: " << min_size_str;
    return grpc::Status(grpc::INTERNAL, "failed to parse btrfs output");
  }

  response->set_minimum_size(min_size);
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::Mount9P(grpc::ServerContext* ctx,
                                  const Mount9PRequest* request,
                                  MountResponse* response) {
  LOG(INFO) << "Received request to mount 9P file system";
  base::ScopedFD server(socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC, 0));
  if (!server.is_valid()) {
    response->set_error(errno);
    PLOG(ERROR) << "Failed to create vsock socket";
    return grpc::Status(grpc::INTERNAL, "unable to create vsock socket");
  }

  struct sockaddr_vm svm = {
      .svm_family = AF_VSOCK,
      .svm_port = static_cast<unsigned int>(request->port()),
      .svm_cid = VMADDR_CID_HOST,
  };
  if (connect(server.get(), reinterpret_cast<struct sockaddr*>(&svm),
              sizeof(svm)) != 0) {
    response->set_error(errno);
    PLOG(ERROR) << "Unable to connect to server";
    return grpc::Status(grpc::INTERNAL, "unable to connect to server");
  }

  // Do the mount.
  string data = base::StringPrintf(
      "trans=fd,rfdno=%d,wfdno=%d,cache=none,access=any,version=9p2000.L",
      server.get(), server.get());
  if (mount("9p", request->target().c_str(), "9p",
            MS_NOSUID | MS_NODEV | MS_NOEXEC, data.c_str()) != 0) {
    response->set_error(errno);
    PLOG(ERROR) << "Failed to mount 9p file system";
    return grpc::Status(grpc::INTERNAL, "failed to mount file system");
  }

  LOG(INFO) << "Mounted 9P file system on " << request->target();
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::SetResolvConfig(grpc::ServerContext* ctx,
                                          const SetResolvConfigRequest* request,
                                          EmptyMessage* response) {
  LOG(INFO) << "Received request to update VM resolv.conf";
  const vm_tools::ResolvConfig& resolv_config = request->resolv_config();

  std::vector<string> nameservers(resolv_config.nameservers().begin(),
                                  resolv_config.nameservers().end());
  if (nameservers.empty()) {
    LOG(WARNING) << "Host sent empty nameservers list; using default";
    nameservers = kDefaultNameservers;
  }

  std::vector<string> search_domains(resolv_config.search_domains().begin(),
                                     resolv_config.search_domains().end());
  string error;
  if (!WriteResolvConf(nameservers, search_domains, &error)) {
    return grpc::Status(grpc::INTERNAL, error);
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::SetTime(grpc::ServerContext* ctx,
                                  const vm_tools::SetTimeRequest* request,
                                  EmptyMessage* response) {
  struct timeval new_time;
  new_time.tv_sec = request->time().seconds();
  new_time.tv_usec = request->time().nanos() / 1000;

  LOG(INFO) << "Recieved request to set time to " << new_time.tv_sec << "s, "
            << new_time.tv_usec << "us";

  if (new_time.tv_sec == 0) {
    LOG(ERROR) << "Ignored attempt to set time to the epoch";

    return grpc::Status(grpc::INVALID_ARGUMENT,
                        "ignored attempt to set time to the epoch");
  }

  if (settimeofday(&new_time, /*tz=*/nullptr) < 0) {
    string error = strerror(errno);
    LOG(ERROR) << "Failed to set time: " << error;
    return grpc::Status(
        grpc::INTERNAL,
        base::StringPrintf("failed to set time: %s", error.c_str()));
  }

  LOG(INFO) << "Successfully set time.";
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::GetKernelVersion(
    grpc::ServerContext* ctx,
    const EmptyMessage* request,
    vm_tools::GetKernelVersionResponse* response) {
  LOG(INFO) << "Received request to get kernel version information.";

  struct utsname buffer;
  if (uname(&buffer) < 0) {
    const std::string error_message = base::StringPrintf(
        "Failed to retrieve kernel version: %s", strerror(errno));
    LOG(ERROR) << error_message;
    return grpc::Status(grpc::INTERNAL, error_message);
  }

  response->set_kernel_release(buffer.release);
  response->set_kernel_version(buffer.version);

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::PrepareToSuspend(grpc::ServerContext* ctx,
                                           const EmptyMessage* request,
                                           EmptyMessage* response) {
  LOG(INFO) << "Received request to prepare to suspend.";

  // Commit filesystem caches to disks. This is important especially when a disk
  // is on external storage which can be unplugged while the device is asleep.
  sync();

  return grpc::Status::OK;
}

}  // namespace maitred
}  // namespace vm_tools
