
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>

#define CREATE_TRACE_POINTS
#include "kotrace.h"

MODULE_AUTHOR("Lockheed Martin");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A mtest module to verify ftrace");

static ssize_t
trace_data_store(
  struct kobject *kobj, struct kobj_attribute *attr, const char *buf, 
  size_t size)
{
  printk(KERN_INFO "kotrace tracing %d bytes\n", (int)size);
  trace_kotrace_print(0);
  trace_printk("kotrace hello\n");
  /* trace_kotrace_buffer(size, buf); */
  return size;
}

// Name, permissions, and read/write callbacks
static struct kobj_attribute kotrace_data_attribute =
  __ATTR(trace_data, 0222, NULL, trace_data_store);

// List of attributes
static struct attribute *attrs[] = {
  &kotrace_data_attribute.attr,
  NULL,
};

// Defined as a group just for convenience
static struct attribute_group attr_group = {
  .attrs = attrs,
};

// A single kernel object
static struct kobject *kotrace_kobj;

// Runs at module load time
static int __init module_load(void)
{
  int rc = 0;
  printk(KERN_INFO "kotrace module loaded\n");

  // Create the kobject 
  kotrace_kobj = kobject_create_and_add("kotrace", NULL);
  if (!kotrace_kobj) return -ENOMEM;

  // Create the attribute files
  rc = sysfs_create_group(kotrace_kobj, &attr_group);
  if (rc) kobject_put(kotrace_kobj);
  return rc;
}

// Runs at module unload time
static void __exit module_unload(void)
{
  sysfs_remove_group(kotrace_kobj, &attr_group);
  kobject_put(kotrace_kobj);
  printk(KERN_INFO "kotrace module unloaded\n");
}

module_init(module_load);
module_exit(module_unload);

