/*
 * 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 <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'";
}  // namespace

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::CreateKprobeEvent(const std::string& group,
                                     const std::string& name,
                                     bool is_retprobe) {
  std::string path = root_ + "kprobe_events";
  std::string probe =
      (is_retprobe ? "r:" : "p:") + group + "/" + name + " " + name;

  PERFETTO_DLOG("Writing \"%s >> %s\"", probe.c_str(), path.c_str());

  bool ret = AppendToFile(path, probe);
  if (!ret) {
    if (errno == EEXIST) {
      // The kprobe event defined by group/name already exists.
      // TODO maybe because the /sys/kernel/tracing/kprobe_events file has not
      // been properly cleaned up after tracing
      PERFETTO_DLOG("Kprobe event %s::%s already exists", group.c_str(),
                    name.c_str());
      return true;
    }
    PERFETTO_PLOG("Failed writing '%s' to '%s'", probe.c_str(), path.c_str());
  }

  return ret;
}

// Utility function to remove kprobe event from the system
bool FtraceProcfs::RemoveKprobeEvent(const std::string& group,
                                     const std::string& name) {
  PERFETTO_DLOG("RemoveKprobeEvent %s::%s", group.c_str(), name.c_str());
  std::string path = root_ + "kprobe_events";
  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, num_cpus = NumberOfCpus(); cpu < num_cpus; 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) {
  std::string path = root_ + "buffer_size_kb";
  return WriteNumberToFile(path, pages * (base::GetSysPageSize() / 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;
}

uint32_t FtraceProcfs::ReadBufferPercent() {
  std::string path = root_ + "buffer_percent";
  std::string raw = ReadFileIntoString(path);
  std::optional<uint32_t> percent =
      base::StringToUInt32(base::StripSuffix(raw, "\n"));
  return percent.has_value() ? *percent : 0;
}

bool FtraceProcfs::SetBufferPercent(uint32_t percent) {
  std::string path = root_ + "buffer_percent";
  return WriteNumberToFile(path, percent);
}

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
