// Copyright (c) 2011 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.

// Implementation of bootstat_log(), part of the Chromium OS 'bootstat'
// facility.

#include <assert.h>
#include <libgen.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/fcntl.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <rootdev/rootdev.h>

#include "bootstat.h"
#include "bootstat_test.h"

static const char kBootstageMarkFile[] = "/sys/kernel/debug/bootstage/mark";

//
// Default path to directory where output statistics will be stored.
//
static const char kDefaultOutputDirectoryName[] = "/tmp";

//
// Paths to the statistics files we snapshot as part of the data to
// be logged.
//
static const char kDefaultUptimeStatisticsFileName[] = "/proc/uptime";

static const char* output_directory_name = kDefaultOutputDirectoryName;
static const char* uptime_statistics_file_name =
    kDefaultUptimeStatisticsFileName;

static const char* disk_statistics_file_name_for_test = NULL;

// Stores the path representing the stats file for the root disk in
// |stats_path| of length |len|.
// Returns |stats_path| on success, NULL on failure.
static char* get_disk_statistics_file_name(char* stats_path, size_t len) {
  char boot_path[PATH_MAX];
  int ret = rootdev(boot_path, sizeof(boot_path),
                    true,  // Do full resolution.
                    false);  // Do not remove partition number.
  if (ret < 0) {
    return NULL;
  }

  // The general idea is to use the the root device's sysfs entry to
  // get the path to the root disk's sysfs entry.
  // Example:
  // - rootdev() returns "/dev/sda3"
  // - Use /sys/class/block/sda3/../ to get to root disk (sda) sysfs entry.
  //   This is because /sys/class/block/sda3 is a symlink that maps to:
  //     /sys/devices/pci.../.../ata./host./target.../.../block/sda/sda3
  const char* root_device_name = basename(boot_path);
  if (!root_device_name) {
    return NULL;
  }

  ret = snprintf(stats_path, len,
                 "/sys/class/block/%s/../stat", root_device_name);
  if (ret >= PATH_MAX || ret < 0) {
    return NULL;
  }
  return stats_path;
}

static void append_logdata(const char* input_path,
                           const char* output_name_prefix,
                           const char* event_name)
{
  if (!input_path || !output_name_prefix || !event_name)
    return;
  const mode_t kFileCreationMode =
      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
  char output_path[PATH_MAX];
  char buffer[256];
  ssize_t num_read;
  int ifd, ofd;
  int output_path_len;

  ifd = open(input_path, O_RDONLY);
  if (ifd < 0) {
    return;
  }

  //
  // For those not up on the more esoteric features of printf
  // formats:  the "%.*s" format is used to truncate the event name
  // to the proper number of characters..
  //
  // The assertion for output_path overflow should only be able to
  // fail if output_directory_name is changed from its default,
  // which can only happen in unit tests, and then only in the event
  // of a serious test bug.
  //
  output_path_len = snprintf(output_path, sizeof(output_path), "%s/%s-%.*s",
                             output_directory_name,
                             output_name_prefix,
                             BOOTSTAT_MAX_EVENT_LEN - 1, event_name);
  // output_path_len is unused when the assert() is disabled. Prevent the
  // warning.
  (void)output_path_len;
  assert(output_path_len < sizeof(output_path));
  ofd = open(output_path, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW,
             kFileCreationMode);
  if (ofd < 0) {
    (void)close(ifd);
    return;
  }

  while ((num_read = read(ifd, buffer, sizeof(buffer))) > 0) {
    ssize_t num_written = write(ofd, buffer, num_read);
    if (num_written != num_read)
      break;
  }
  (void)close(ofd);
  (void)close(ifd);
}

static void write_mark(const char *event_name)
{
  ssize_t ret __attribute__((unused));
  int fd = open(kBootstageMarkFile, O_WRONLY);

  if (fd < 0) {
    return;
  }

  /*
   * It's not necessary to check the return value,
   * but the compiler will generate a warning if we don't.
   */
  ret = write(fd, event_name, strlen(event_name));
  close(fd);
}

void bootstat_log(const char* event_name)
{
  const char* disk_statistics_file_name;
  char stats_path[PATH_MAX];
  write_mark(event_name);
  append_logdata(uptime_statistics_file_name, "uptime", event_name);
  if (disk_statistics_file_name_for_test) {
    disk_statistics_file_name = disk_statistics_file_name_for_test;
  } else {
    disk_statistics_file_name = get_disk_statistics_file_name(
        stats_path, sizeof(stats_path));
  }
  append_logdata(disk_statistics_file_name, "disk", event_name);
}

void bootstat_set_output_directory_for_test(const char* dirname)
{
  if (dirname != NULL)
    output_directory_name = dirname;
  else
    output_directory_name = kDefaultOutputDirectoryName;
}

void bootstat_set_uptime_file_name_for_test(const char* filename)
{
  if (filename != NULL)
    uptime_statistics_file_name = filename;
  else
    uptime_statistics_file_name = kDefaultUptimeStatisticsFileName;
}

void bootstat_set_disk_file_name_for_test(const char* filename)
{
  disk_statistics_file_name_for_test = filename;
}
