/**
 * @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 "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 vsfile;
int vsamples;
int varcs;
int vmodule;
int vmisc;
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 int showvers;
static struct oprofiled_ops * opd_ops;
extern struct oprofiled_ops opd_24_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", },
	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;
	} 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 {
		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 (events == NULL) {
		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);
		}
	}

	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)
{
	switch (op_get_interface()) {
#ifndef ANDROID
		case OP_INTERFACE_24:
			printf("Using 2.4 OProfile kernel interface.\n");
			return &opd_24_ops;
#endif
		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;
}
