/*
 * 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 ? std::string("r") + std::string(kKretprobeDefaultMaxactives)
                   : "p") +
      std::string(":") + 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);
}

std::string FtraceProcfs::ReadKprobeStats() const {
  std::string path = root_ + "/kprobe_profile";
  return ReadFileIntoString(path);
}

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
