/**
 * @file daemon/oprofiled.c
 * Initialisation and setup
 *
 * @remark Copyright 2002, 2003 OProfile authors
 * @remark Read the file COPYING
 *
 * @author John Levon
 * @author Philippe Elie
 * Modified by Aravind Menon for Xen
 * These modifications are:
 * Copyright (C) 2005 Hewlett-Packard Co.
 */

#include "config.h"
 
#include "oprofiled.h"
#include "opd_printf.h"
#include "opd_events.h"
#include "opd_extended.h"

#include "op_config.h"
#include "op_version.h"
#include "op_hw_config.h"
#include "op_libiberty.h"
#include "op_file.h"
#include "op_abi.h"
#include "op_string.h"
#include "op_cpu_type.h"
#include "op_popt.h"
#include "op_lockfile.h"
#include "op_list.h"
#include "op_fileio.h"

#include <sys/types.h>
#include <sys/resource.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <dirent.h>
#include <limits.h>

sig_atomic_t signal_alarm;
sig_atomic_t signal_hup;
sig_atomic_t signal_term;
sig_atomic_t signal_child;
sig_atomic_t signal_usr1;
sig_atomic_t signal_usr2;

uint op_nr_counters;
op_cpu cpu_type;
int no_event_ok;
int vsfile;
int vsamples;
int varcs;
int vmodule;
int vmisc;
int vext;
int separate_lib;
int separate_kernel;
int separate_thread;
int separate_cpu;
int no_vmlinux;
char * vmlinux;
char * kernel_range;
char * session_dir;
int no_xen;
char * xenimage;
char * xen_range;
static char * verbose;
static char * binary_name_filter;
static char * events;
static char * ext_feature;
static int showvers;
static struct oprofiled_ops * opd_ops;
extern struct oprofiled_ops opd_26_ops;

#define OPD_IMAGE_FILTER_HASH_SIZE 32
static struct list_head images_filter[OPD_IMAGE_FILTER_HASH_SIZE];

static struct poptOption options[] = {
	{ "session-dir", 0, POPT_ARG_STRING, &session_dir, 0, "place sample database in dir instead of default location", "/var/lib/oprofile", },
	{ "kernel-range", 'r', POPT_ARG_STRING, &kernel_range, 0, "Kernel VMA range", "start-end", },
	{ "vmlinux", 'k', POPT_ARG_STRING, &vmlinux, 0, "vmlinux kernel image", "file", },
	{ "no-vmlinux", 0, POPT_ARG_NONE, &no_vmlinux, 0, "vmlinux kernel image file not available", NULL, },
	{ "xen-range", 0, POPT_ARG_STRING, &xen_range, 0, "Xen VMA range", "start-end", },
	{ "xen-image", 0, POPT_ARG_STRING, &xenimage, 0, "Xen image", "file", },
	{ "image", 0, POPT_ARG_STRING, &binary_name_filter, 0, "image name filter", "profile these comma separated image" },
	{ "separate-lib", 0, POPT_ARG_INT, &separate_lib, 0, "separate library samples for each distinct application", "[0|1]", },
	{ "separate-kernel", 0, POPT_ARG_INT, &separate_kernel, 0, "separate kernel samples for each distinct application", "[0|1]", },
	{ "separate-thread", 0, POPT_ARG_INT, &separate_thread, 0, "thread-profiling mode", "[0|1]" },
	{ "separate-cpu", 0, POPT_ARG_INT, &separate_cpu, 0, "separate samples for each CPU", "[0|1]" },
	{ "events", 'e', POPT_ARG_STRING, &events, 0, "events list", "[events]" },
	{ "version", 'v', POPT_ARG_NONE, &showvers, 0, "show version", NULL, },
	{ "verbose", 'V', POPT_ARG_STRING, &verbose, 0, "be verbose in log file", "all,sfile,arcs,samples,module,misc", },
	{ "ext-feature", 'x', POPT_ARG_STRING, &ext_feature, 1, "enable extended feature", "<extended-feature-name>:[args]", },
	POPT_AUTOHELP
	{ NULL, 0, 0, NULL, 0, NULL, NULL, },
};
 

void opd_open_logfile(void)
{
	if (open(op_log_file, O_WRONLY|O_CREAT|O_NOCTTY|O_APPEND, 0644) == -1) {
		perror("oprofiled: couldn't re-open stdout: ");
		exit(EXIT_FAILURE);
	}

	if (dup2(1, 2) == -1) {
		perror("oprofiled: couldn't dup stdout to stderr: ");
		exit(EXIT_FAILURE);
	}
}
 

/**
 * opd_fork - fork and return as child
 *
 * fork() and exit the parent with _exit().
 * Failure is fatal.
 */
static void opd_fork(void)
{
	switch (fork()) {
		case -1:
			perror("oprofiled: fork() failed: ");
			exit(EXIT_FAILURE);
			break;
		case 0:
			break;
		default:
			/* parent */
			_exit(EXIT_SUCCESS);
			break;
	}
}

 
static void opd_go_daemon(void)
{
	opd_fork();

	if (chdir(op_session_dir)) {
		fprintf(stderr, "oprofiled: opd_go_daemon: couldn't chdir to %s: %s",
			op_session_dir, strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (setsid() < 0) {
		perror("oprofiled: opd_go_daemon: couldn't setsid: ");
		exit(EXIT_FAILURE);
	}

	opd_fork();
}


static void opd_write_abi(void)
{
	char * cbuf;
 
	cbuf = xmalloc(strlen(op_session_dir) + 5);
	strcpy(cbuf, op_session_dir);
	strcat(cbuf, "/abi");
	op_write_abi_to_file(cbuf);
	free(cbuf);
}


/**
 * opd_alarm - sync files and report stats
 */
static void opd_alarm(int val __attribute__((unused)))
{
	signal_alarm = 1;
}
 

/* re-open logfile for logrotate */
static void opd_sighup(int val __attribute__((unused)))
{
	signal_hup = 1;
}


static void opd_sigterm(int val __attribute__((unused)))
{
	signal_term = 1;
}

static void opd_sigchild(int val __attribute__((unused)))
{
	signal_child = 1;
}
 

static void opd_sigusr1(int val __attribute__((unused)))
{
	signal_usr1 = 1;
}

 
static void opd_sigusr2(int val __attribute__((unused)))
{
	signal_usr2 = 1;
}


static void opd_setup_signals(void)
{
	struct sigaction act;
 
	act.sa_handler = opd_alarm;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);

	if (sigaction(SIGALRM, &act, NULL)) {
		perror("oprofiled: install of SIGALRM handler failed: ");
		exit(EXIT_FAILURE);
	}

	act.sa_handler = opd_sighup;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaddset(&act.sa_mask, SIGALRM);

	if (sigaction(SIGHUP, &act, NULL)) {
		perror("oprofiled: install of SIGHUP handler failed: ");
		exit(EXIT_FAILURE);
	}

	act.sa_handler = opd_sigterm;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaddset(&act.sa_mask, SIGTERM);

	if (sigaction(SIGTERM, &act, NULL)) {
		perror("oprofiled: install of SIGTERM handler failed: ");
		exit(EXIT_FAILURE);
	}

	act.sa_handler = opd_sigchild;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaddset(&act.sa_mask, SIGCHLD);

	if (sigaction(SIGCHLD, &act, NULL)) {
		perror("oprofiled: install of SIGCHLD handler failed: ");
		exit(EXIT_FAILURE);
	}

	act.sa_handler = opd_sigusr1;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaddset(&act.sa_mask, SIGTERM);

	if (sigaction(SIGUSR1, &act, NULL)) {
		perror("oprofiled: install of SIGUSR1 handler failed: ");
		exit(EXIT_FAILURE);
	}

	act.sa_handler = opd_sigusr2;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaddset(&act.sa_mask, SIGTERM);

	if (sigaction(SIGUSR2, &act, NULL)) {
		perror("oprofiled: install of SIGUSR2 handler failed: ");
		exit(EXIT_FAILURE);
	}
}


struct opd_hashed_name {
	char * name;
	struct list_head next;
};


static void add_image_filter(char const * name)
{
	size_t hash;
	struct opd_hashed_name * elt = xmalloc(sizeof(struct opd_hashed_name));
	elt->name = xmalloc(PATH_MAX);
	if (!realpath(name, elt->name)) {
		free(elt->name);
		free(elt);
		return;
	}
	hash = op_hash_string(elt->name);
	verbprintf(vmisc, "Adding to image filter: \"%s\"\n", elt->name);
	list_add(&elt->next, &images_filter[hash % OPD_IMAGE_FILTER_HASH_SIZE]);
}


static void opd_parse_image_filter(void)
{
	size_t i;
	char const * last = binary_name_filter;
	char const * cur = binary_name_filter;

	if (!binary_name_filter)
		return;

	for (i = 0; i < OPD_IMAGE_FILTER_HASH_SIZE; ++i)
		list_init(&images_filter[i]);

	while ((cur = strchr(last, ',')) != NULL) {
		char * tmp = op_xstrndup(last, cur - last);
		add_image_filter(tmp);
		free(tmp);
		last = cur + 1;
	}
	add_image_filter(last);
}


int is_image_ignored(char const * name)
{
	size_t hash;
	struct list_head * pos;

	if (!binary_name_filter)
		return 0;
	
	hash = op_hash_string(name);

	list_for_each(pos, &images_filter[hash % OPD_IMAGE_FILTER_HASH_SIZE]) {
		struct opd_hashed_name * hashed_name =
			list_entry(pos, struct opd_hashed_name, next);
		if (!strcmp(hashed_name->name, name))
			return 0;
	}

	return 1;
}


/** return the int in the given oprofilefs file */
int opd_read_fs_int(char const * path, char const * name, int fatal)
{
	char filename[PATH_MAX + 1];
	snprintf(filename, PATH_MAX, "%s/%s", path, name);
	return op_read_int_from_file(filename, fatal);
}


static void opd_handle_verbose_option(char const * name)
{
	if (!strcmp(name, "all")) {
		vsfile = 1;
		vsamples = 1;
		varcs = 1;
		vmodule = 1;
		vmisc = 1;
		vext= 1;
	} else if (!strcmp(name, "sfile")) {
		vsfile = 1;
	} else if (!strcmp(name, "arcs")) {
		varcs = 1;
	} else if (!strcmp(name, "samples")) {
		vsamples = 1;
	} else if (!strcmp(name, "module")) {
		vmodule = 1;
	} else if (!strcmp(name, "misc")) {
		vmisc = 1;
	} else if (!strcmp(name, "ext")) {
		vext= 1;
	} else {
		fprintf(stderr, "unknown verbose options\n");
		exit(EXIT_FAILURE);
	}
}

static void opd_parse_verbose(void)
{
	char const * last = verbose;
	char const * cur = verbose;

	if (!verbose)
		return;

	while ((cur = strchr(last, ',')) != NULL) {
		char * tmp = op_xstrndup(last, cur - last);
		opd_handle_verbose_option(tmp);
		free(tmp);
		last = cur + 1;
	}
	opd_handle_verbose_option(last);
}


static void opd_options(int argc, char const * argv[])
{
	poptContext optcon;
	char * tmp;

	optcon = op_poptGetContext(NULL, argc, argv, options, 0);

	if (showvers)
		show_version(argv[0]);

	opd_parse_verbose();

	if (separate_kernel)
		separate_lib = 1;

	cpu_type = op_get_cpu_type();
	op_nr_counters = op_get_nr_counters(cpu_type);

	if (!no_vmlinux) {
		if (!vmlinux || !strcmp("", vmlinux)) {
			fprintf(stderr, "oprofiled: no vmlinux specified.\n");
			poptPrintHelp(optcon, stderr, 0);
			exit(EXIT_FAILURE);
		}

		/* canonicalise vmlinux filename. fix #637805 */
		tmp = xmalloc(PATH_MAX);
		if (realpath(vmlinux, tmp))
			vmlinux = tmp;
		else
			free(tmp);

		if (!kernel_range || !strcmp("", kernel_range)) {
			fprintf(stderr, "oprofiled: no kernel VMA range specified.\n");
			poptPrintHelp(optcon, stderr, 0);
			exit(EXIT_FAILURE);
		}
	}

	if(opd_ext_initialize(ext_feature) != EXIT_SUCCESS)
		exit(EXIT_FAILURE);

	if (events == NULL && no_event_ok == 0) {
		fprintf(stderr, "oprofiled: no events specified.\n");
		poptPrintHelp(optcon, stderr, 0);
		exit(EXIT_FAILURE);
	}

	if (!xenimage || !strcmp("", xenimage)) {
		no_xen = 1;
	} else {
		no_xen = 0;

		/* canonicalise xen image filename. */
		tmp = xmalloc(PATH_MAX);
		if (realpath(xenimage, tmp))
			xenimage = tmp;
		else
			free(tmp);

		if (!xen_range || !strcmp("", xen_range)) {
			fprintf(stderr, "oprofiled: no Xen VMA range specified.\n");
			poptPrintHelp(optcon, stderr, 0);
			exit(EXIT_FAILURE);
		}
	}

	if (events != NULL)
		opd_parse_events(events);

	opd_parse_image_filter();

	poptFreeContext(optcon);
}


/* determine what kernel we're running and which daemon
 * to use
 */
static struct oprofiled_ops * get_ops(void)
{
	/* Support for 2.4 kernel was removed in oprofile 0.9.8, so
	 * only "2.6" interface is supported. Later kernels also
	 * comply with the 2.6 interface.
	 */
	switch (op_get_interface()) {
		case OP_INTERFACE_26:
			printf("Using 2.6+ OProfile kernel interface.\n");
			return &opd_26_ops;
		default:
			break;
	}

	fprintf(stderr, "Couldn't determine kernel version.\n");
	exit(EXIT_FAILURE);
	return NULL;
}


int main(int argc, char const * argv[])
{
	int err;
	struct rlimit rlim = { 2048, 2048 };

	opd_options(argc, argv);
	init_op_config_dirs(session_dir);

	opd_setup_signals();

	err = setrlimit(RLIMIT_NOFILE, &rlim);
	if (err)
		perror("warning: could not set RLIMIT_NOFILE to 2048: ");

	opd_write_abi();

	opd_ops = get_ops();

	opd_ops->init();

	opd_go_daemon();

	/* clean up every 10 minutes */
	alarm(60 * 10);

	if (op_write_lock_file(op_lock_file)) {
		fprintf(stderr, "oprofiled: could not create lock file %s\n",
			op_lock_file);
		exit(EXIT_FAILURE);
	}

	opd_ops->start();

	opd_ops->exit();

	return 0;
}
