/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/traced/probes/ftrace/ftrace_procfs.h"

#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <fstream>
#include <sstream>
#include <string>

#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"

namespace perfetto {

// Reading /trace produces human readable trace output.
// Writing to this file clears all trace buffers for all CPUS.

// Writing to /trace_marker file injects an event into the trace buffer.

// Reading /tracing_on returns 1/0 if tracing is enabled/disabled.
// Writing 1/0 to this file enables/disables tracing.
// Disabling tracing with this file prevents further writes but
// does not clear the buffer.

namespace {

namespace {
constexpr char kRssStatThrottledTrigger[] =
    "hist:keys=mm_id,member:bucket=size/0x80000"
    ":onchange($bucket).rss_stat_throttled(mm_id,curr,member,size)";

constexpr char kSuspendResumeMinimalTrigger[] =
    "hist:keys=start:size=128:onmatch(power.suspend_resume)"
    ".trace(suspend_resume_minimal, start) if action == 'syscore_resume'";
}

void KernelLogWrite(const char* s) {
  PERFETTO_DCHECK(*s && s[strlen(s) - 1] == '\n');
  if (FtraceProcfs::g_kmesg_fd != -1)
    base::ignore_result(base::WriteAll(FtraceProcfs::g_kmesg_fd, s, strlen(s)));
}

bool WriteFileInternal(const std::string& path,
                       const std::string& str,
                       int flags) {
  base::ScopedFile fd = base::OpenFile(path, flags);
  if (!fd)
    return false;
  ssize_t written = base::WriteAll(fd.get(), str.c_str(), str.length());
  ssize_t length = static_cast<ssize_t>(str.length());
  // This should either fail or write fully.
  PERFETTO_CHECK(written == length || written == -1);
  return written == length;
}

}  // namespace

// static
int FtraceProcfs::g_kmesg_fd = -1;  // Set by ProbesMain() in probes.cc .

const char* const FtraceProcfs::kTracingPaths[] = {
    "/sys/kernel/tracing/",
    "/sys/kernel/debug/tracing/",
    nullptr,
};

// static
std::unique_ptr<FtraceProcfs> FtraceProcfs::CreateGuessingMountPoint(
    const std::string& instance_path) {
  std::unique_ptr<FtraceProcfs> ftrace_procfs;
  size_t index = 0;
  while (!ftrace_procfs && kTracingPaths[index]) {
    std::string path = kTracingPaths[index++];
    if (!instance_path.empty())
      path += instance_path;

    ftrace_procfs = Create(path);
  }
  return ftrace_procfs;
}

// static
std::unique_ptr<FtraceProcfs> FtraceProcfs::Create(const std::string& root) {
  if (!CheckRootPath(root))
    return nullptr;
  return std::unique_ptr<FtraceProcfs>(new FtraceProcfs(root));
}

FtraceProcfs::FtraceProcfs(const std::string& root) : root_(root) {}
FtraceProcfs::~FtraceProcfs() = default;

bool FtraceProcfs::SetSyscallFilter(const std::set<size_t>& filter) {
  std::vector<std::string> parts;
  for (size_t id : filter) {
    base::StackString<16> m("id == %zu", id);
    parts.push_back(m.ToStdString());
  }

  std::string filter_str = "0";
  if (!parts.empty()) {
    filter_str = base::Join(parts, " || ");
  }

  for (const char* event : {"sys_enter", "sys_exit"}) {
    std::string path = root_ + "events/raw_syscalls/" + event + "/filter";
    if (!WriteToFile(path, filter_str)) {
      PERFETTO_ELOG("Failed to write file: %s", path.c_str());
      return false;
    }
  }
  return true;
}

bool FtraceProcfs::EnableEvent(const std::string& group,
                               const std::string& name) {
  std::string path = root_ + "events/" + group + "/" + name + "/enable";

  // Create any required triggers for the ftrace event being enabled.
  // Some ftrace events (synthetic events) need to set up an event trigger
  MaybeSetUpEventTriggers(group, name);

  if (WriteToFile(path, "1"))
    return true;
  path = root_ + "set_event";
  return AppendToFile(path, group + ":" + name);
}

bool FtraceProcfs::DisableEvent(const std::string& group,
                                const std::string& name) {
  std::string path = root_ + "events/" + group + "/" + name + "/enable";

  bool ret = WriteToFile(path, "0");
  if (!ret) {
    path = root_ + "set_event";
    ret = AppendToFile(path, "!" + group + ":" + name);
  }

  // Remove any associated event triggers after disabling the event
  MaybeTearDownEventTriggers(group, name);

  return ret;
}

bool FtraceProcfs::IsEventAccessible(const std::string& group,
                                     const std::string& name) {
  std::string path = root_ + "events/" + group + "/" + name + "/enable";

  return IsFileWriteable(path);
}

bool FtraceProcfs::DisableAllEvents() {
  std::string path = root_ + "events/enable";
  return WriteToFile(path, "0");
}

std::string FtraceProcfs::ReadEventFormat(const std::string& group,
                                          const std::string& name) const {
  std::string path = root_ + "events/" + group + "/" + name + "/format";
  return ReadFileIntoString(path);
}

std::string FtraceProcfs::GetCurrentTracer() {
  std::string path = root_ + "current_tracer";
  std::string current_tracer = ReadFileIntoString(path);
  return base::StripSuffix(current_tracer, "\n");
}

bool FtraceProcfs::SetCurrentTracer(const std::string& tracer) {
  std::string path = root_ + "current_tracer";
  return WriteToFile(path, tracer);
}

bool FtraceProcfs::ResetCurrentTracer() {
  return SetCurrentTracer("nop");
}

bool FtraceProcfs::AppendFunctionFilters(
    const std::vector<std::string>& filters) {
  std::string path = root_ + "set_ftrace_filter";
  std::string filter = base::Join(filters, "\n");

  // The same file accepts special actions to perform when a corresponding
  // kernel function is hit (regardless of active tracer). For example
  // "__schedule_bug:traceoff" would disable tracing once __schedule_bug is
  // called.
  // We disallow these commands as most of them break the isolation of
  // concurrent ftrace data sources (as the underlying ftrace instance is
  // shared).
  if (base::Contains(filter, ':')) {
    PERFETTO_ELOG("Filter commands are disallowed.");
    return false;
  }
  return AppendToFile(path, filter);
}

bool FtraceProcfs::ClearFunctionFilters() {
  std::string path = root_ + "set_ftrace_filter";
  return ClearFile(path);
}

bool FtraceProcfs::AppendFunctionGraphFilters(
    const std::vector<std::string>& filters) {
  std::string path = root_ + "set_graph_function";
  std::string filter = base::Join(filters, "\n");
  return AppendToFile(path, filter);
}

bool FtraceProcfs::ClearFunctionGraphFilters() {
  std::string path = root_ + "set_graph_function";
  return ClearFile(path);
}

std::vector<std::string> FtraceProcfs::ReadEventTriggers(
    const std::string& group,
    const std::string& name) const {
  std::string path = root_ + "events/" + group + "/" + name + "/trigger";
  std::string s = ReadFileIntoString(path);
  std::vector<std::string> triggers;

  for (base::StringSplitter ss(s, '\n'); ss.Next();) {
    std::string trigger = ss.cur_token();
    if (trigger.empty() || trigger[0] == '#')
      continue;

    base::StringSplitter ts(trigger, ' ');
    PERFETTO_CHECK(ts.Next());
    triggers.push_back(ts.cur_token());
  }

  return triggers;
}

bool FtraceProcfs::CreateEventTrigger(const std::string& group,
                                      const std::string& name,
                                      const std::string& trigger) {
  std::string path = root_ + "events/" + group + "/" + name + "/trigger";
  return WriteToFile(path, trigger);
}

bool FtraceProcfs::RemoveEventTrigger(const std::string& group,
                                      const std::string& name,
                                      const std::string& trigger) {
  std::string path = root_ + "events/" + group + "/" + name + "/trigger";
  return WriteToFile(path, "!" + trigger);
}

bool FtraceProcfs::RemoveAllEventTriggers(const std::string& group,
                                          const std::string& name) {
  std::vector<std::string> triggers = ReadEventTriggers(group, name);

  // Remove the triggers in reverse order since a trigger can depend
  // on another trigger created earlier.
  for (auto it = triggers.rbegin(); it != triggers.rend(); ++it)
    if (!RemoveEventTrigger(group, name, *it))
      return false;
  return true;
}

bool FtraceProcfs::MaybeSetUpEventTriggers(const std::string& group,
                                           const std::string& name) {
  bool ret = true;

  if (group == "synthetic") {
    if (name == "rss_stat_throttled") {
      ret = RemoveAllEventTriggers("kmem", "rss_stat") &&
            CreateEventTrigger("kmem", "rss_stat", kRssStatThrottledTrigger);
    } else if (name == "suspend_resume_minimal") {
      ret = RemoveAllEventTriggers("power", "suspend_resume") &&
            CreateEventTrigger("power", "suspend_resume", kSuspendResumeMinimalTrigger);
    }
  }

  if (!ret) {
    PERFETTO_PLOG("Failed to setup event triggers for %s:%s", group.c_str(),
                  name.c_str());
  }

  return ret;
}

bool FtraceProcfs::MaybeTearDownEventTriggers(const std::string& group,
                                              const std::string& name) {
  bool ret = true;

  if (group == "synthetic") {
    if (name == "rss_stat_throttled") {
      ret = RemoveAllEventTriggers("kmem", "rss_stat");
    } else if (name == "suspend_resume_minimal") {
      ret = RemoveEventTrigger("power", "suspend_resume", kSuspendResumeMinimalTrigger);
    }
  }

  if (!ret) {
    PERFETTO_PLOG("Failed to tear down event triggers for: %s:%s",
                  group.c_str(), name.c_str());
  }

  return ret;
}

bool FtraceProcfs::SupportsRssStatThrottled() {
  std::string group = "synthetic";
  std::string name = "rss_stat_throttled";

  // Check if the trigger already exists. Don't try recreating
  // or removing the trigger if it is already in use.
  auto triggers = ReadEventTriggers("kmem", "rss_stat");
  for (const auto& trigger : triggers) {
    // The kernel shows all the default values of a trigger
    // when read from and trace event 'trigger' file.
    //
    // Trying to match the complete trigger string is prone
    // to fail if, in the future, the kernel changes default
    // fields or values for event triggers.
    //
    // Do a partial match on the generated event name
    // (rss_stat_throttled) to detect if the trigger
    // is already created.
    if (trigger.find(name) != std::string::npos)
      return true;
  }

  // Attempt to create rss_stat_throttled hist trigger */
  bool ret = MaybeSetUpEventTriggers(group, name);

  return ret && MaybeTearDownEventTriggers(group, name);
}

std::string FtraceProcfs::ReadPrintkFormats() const {
  std::string path = root_ + "printk_formats";
  return ReadFileIntoString(path);
}

std::vector<std::string> FtraceProcfs::ReadEnabledEvents() {
  std::string path = root_ + "set_event";
  std::string s = ReadFileIntoString(path);
  base::StringSplitter ss(s, '\n');
  std::vector<std::string> events;
  while (ss.Next()) {
    std::string event = ss.cur_token();
    if (event.empty())
      continue;
    events.push_back(base::StripChars(event, ":", '/'));
  }
  return events;
}

std::string FtraceProcfs::ReadPageHeaderFormat() const {
  std::string path = root_ + "events/header_page";
  return ReadFileIntoString(path);
}

base::ScopedFile FtraceProcfs::OpenCpuStats(size_t cpu) const {
  std::string path = root_ + "per_cpu/cpu" + std::to_string(cpu) + "/stats";
  return base::OpenFile(path, O_RDONLY);
}

std::string FtraceProcfs::ReadCpuStats(size_t cpu) const {
  std::string path = root_ + "per_cpu/cpu" + std::to_string(cpu) + "/stats";
  return ReadFileIntoString(path);
}

size_t FtraceProcfs::NumberOfCpus() const {
  static size_t num_cpus = static_cast<size_t>(sysconf(_SC_NPROCESSORS_CONF));
  return num_cpus;
}

void FtraceProcfs::ClearTrace() {
  std::string path = root_ + "trace";
  PERFETTO_CHECK(ClearFile(path));  // Could not clear.

  // Truncating the trace file leads to tracing_reset_online_cpus being called
  // in the kernel.
  //
  // In case some of the CPUs were not online, their buffer needs to be
  // cleared manually.
  //
  // We cannot use PERFETTO_CHECK as we might get a permission denied error
  // on Android. The permissions to these files are configured in
  // platform/framework/native/cmds/atrace/atrace.rc.
  for (size_t cpu = 0; cpu < NumberOfCpus(); cpu++) {
    ClearPerCpuTrace(cpu);
  }
}

void FtraceProcfs::ClearPerCpuTrace(size_t cpu) {
  if (!ClearFile(root_ + "per_cpu/cpu" + std::to_string(cpu) + "/trace"))
    PERFETTO_ELOG("Failed to clear buffer for CPU %zd", cpu);
}

bool FtraceProcfs::WriteTraceMarker(const std::string& str) {
  std::string path = root_ + "trace_marker";
  return WriteToFile(path, str);
}

bool FtraceProcfs::SetCpuBufferSizeInPages(size_t pages) {
  if (pages * base::kPageSize > 1 * 1024 * 1024 * 1024) {
    PERFETTO_ELOG("Tried to set the per CPU buffer size to more than 1gb.");
    return false;
  }
  std::string path = root_ + "buffer_size_kb";
  return WriteNumberToFile(path, pages * (base::kPageSize / 1024ul));
}

bool FtraceProcfs::GetTracingOn() {
  std::string path = root_ + "tracing_on";
  char tracing_on = ReadOneCharFromFile(path);
  if (tracing_on == '\0')
    PERFETTO_PLOG("Failed to read %s", path.c_str());
  return tracing_on == '1';
}

bool FtraceProcfs::SetTracingOn(bool on) {
  std::string path = root_ + "tracing_on";
  if (!WriteToFile(path, on ? "1" : "0")) {
    PERFETTO_PLOG("Failed to write %s", path.c_str());
    return false;
  }
  if (on) {
    KernelLogWrite("perfetto: enabled ftrace\n");
    PERFETTO_LOG("enabled ftrace in %s", root_.c_str());
  } else {
    KernelLogWrite("perfetto: disabled ftrace\n");
    PERFETTO_LOG("disabled ftrace in %s", root_.c_str());
  }

  return true;
}

bool FtraceProcfs::IsTracingAvailable() {
  std::string current_tracer = GetCurrentTracer();

  // Ftrace tracing is available if current_tracer == "nop".
  // events/enable could be 0, 1, X or 0*. 0* means events would be
  // dynamically enabled so we need to treat as event tracing is in use.
  // However based on the discussion in asop/2328817, on Android events/enable
  // is "X" after boot up. To avoid causing more problem, the decision is just
  // look at current_tracer.
  // As the discussion in asop/2328817, if GetCurrentTracer failed to
  // read file and return "", we treat it as tracing is available.
  return current_tracer == "nop" || current_tracer == "";
}

bool FtraceProcfs::SetClock(const std::string& clock_name) {
  std::string path = root_ + "trace_clock";
  return WriteToFile(path, clock_name);
}

std::string FtraceProcfs::GetClock() {
  std::string path = root_ + "trace_clock";
  std::string s = ReadFileIntoString(path);

  size_t start = s.find('[');
  if (start == std::string::npos)
    return "";

  size_t end = s.find(']', start);
  if (end == std::string::npos)
    return "";

  return s.substr(start + 1, end - start - 1);
}

std::set<std::string> FtraceProcfs::AvailableClocks() {
  std::string path = root_ + "trace_clock";
  std::string s = ReadFileIntoString(path);
  std::set<std::string> names;

  size_t start = 0;
  size_t end = 0;

  for (;;) {
    end = s.find(' ', start);
    if (end == std::string::npos)
      end = s.size();
    while (end > start && s[end - 1] == '\n')
      end--;
    if (start == end)
      break;

    std::string name = s.substr(start, end - start);

    if (name[0] == '[')
      name = name.substr(1, name.size() - 2);

    names.insert(name);

    if (end == s.size())
      break;

    start = end + 1;
  }

  return names;
}

bool FtraceProcfs::WriteNumberToFile(const std::string& path, size_t value) {
  // 2^65 requires 20 digits to write.
  char buf[21];
  snprintf(buf, sizeof(buf), "%zu", value);
  return WriteToFile(path, std::string(buf));
}

bool FtraceProcfs::WriteToFile(const std::string& path,
                               const std::string& str) {
  return WriteFileInternal(path, str, O_WRONLY);
}

bool FtraceProcfs::AppendToFile(const std::string& path,
                                const std::string& str) {
  return WriteFileInternal(path, str, O_WRONLY | O_APPEND);
}

base::ScopedFile FtraceProcfs::OpenPipeForCpu(size_t cpu) {
  std::string path =
      root_ + "per_cpu/cpu" + std::to_string(cpu) + "/trace_pipe_raw";
  return base::OpenFile(path, O_RDONLY | O_NONBLOCK);
}

char FtraceProcfs::ReadOneCharFromFile(const std::string& path) {
  base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
  PERFETTO_CHECK(fd);
  char result = '\0';
  ssize_t bytes = PERFETTO_EINTR(read(fd.get(), &result, 1));
  PERFETTO_CHECK(bytes == 1 || bytes == -1);
  return result;
}

bool FtraceProcfs::ClearFile(const std::string& path) {
  base::ScopedFile fd = base::OpenFile(path, O_WRONLY | O_TRUNC);
  return !!fd;
}

bool FtraceProcfs::IsFileWriteable(const std::string& path) {
  return access(path.c_str(), W_OK) == 0;
}

std::string FtraceProcfs::ReadFileIntoString(const std::string& path) const {
  // You can't seek or stat the procfs files on Android.
  // The vast majority (884/886) of format files are under 4k.
  std::string str;
  str.reserve(4096);
  if (!base::ReadFile(path, &str))
    return "";
  return str;
}

const std::set<std::string> FtraceProcfs::GetEventNamesForGroup(
    const std::string& path) const {
  std::set<std::string> names;
  std::string full_path = root_ + path;
  base::ScopedDir dir(opendir(full_path.c_str()));
  if (!dir) {
    PERFETTO_DLOG("Unable to read events from %s", full_path.c_str());
    return names;
  }
  struct dirent* ent;
  while ((ent = readdir(*dir)) != nullptr) {
    if (strncmp(ent->d_name, ".", 1) == 0 ||
        strncmp(ent->d_name, "..", 2) == 0) {
      continue;
    }
    // Check ent is a directory.
    struct stat statbuf;
    std::string dir_path = full_path + "/" + ent->d_name;
    if (stat(dir_path.c_str(), &statbuf) == 0) {
      if (S_ISDIR(statbuf.st_mode)) {
        names.insert(ent->d_name);
      }
    }
  }
  return names;
}

uint32_t FtraceProcfs::ReadEventId(const std::string& group,
                                   const std::string& name) const {
  std::string path = root_ + "events/" + group + "/" + name + "/id";

  std::string str;
  if (!base::ReadFile(path, &str))
    return 0;

  if (str.size() && str[str.size() - 1] == '\n')
    str.resize(str.size() - 1);

  std::optional<uint32_t> id = base::StringToUInt32(str);
  if (!id)
    return 0;
  return *id;
}

// static
bool FtraceProcfs::CheckRootPath(const std::string& root) {
  base::ScopedFile fd = base::OpenFile(root + "trace", O_RDONLY);
  return static_cast<bool>(fd);
}

}  // namespace perfetto
