/**
 * @file daemon/init.c
 * Daemon set up and main loop for 2.6
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author John Levon
 * @author Philippe Elie
 * @Modifications Daniel Hansel
 * Modified by Aravind Menon for Xen
 * These modifications are:
 * Copyright (C) 2005 Hewlett-Packard Co.
 */

#include "config.h"
 
#include "oprofiled.h"
#include "opd_stats.h"
#include "opd_sfile.h"
#include "opd_pipe.h"
#include "opd_kernel.h"
#include "opd_trans.h"
#include "opd_anon.h"
#include "opd_perfmon.h"
#include "opd_printf.h"
#include "opd_extended.h"

#include "op_version.h"
#include "op_config.h"
#include "op_deviceio.h"
#include "op_get_time.h"
#include "op_libiberty.h"
#include "op_fileio.h"

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/time.h>
#include <wait.h>
#include <string.h>

size_t kernel_pointer_size;

static fd_t devfd;
static char * sbuf;
static size_t s_buf_bytesize;
extern char * session_dir;
static char start_time_str[32];
static int jit_conversion_running;

static void opd_sighup(void);
static void opd_alarm(void);
static void opd_sigterm(void);
static void opd_sigchild(void);
static void opd_do_jitdumps(void);

/**
 * opd_open_files - open necessary files
 *
 * Open the device files and the log file,
 * and mmap() the hash map.
 */
static void opd_open_files(void)
{
	devfd = op_open_device("/dev/oprofile/buffer");
	if (devfd == -1) {
		if (errno == EINVAL)
			fprintf(stderr, "Failed to open device. Possibly you have passed incorrect\n"
				"parameters. Check /var/log/messages.");
		else
			perror("Failed to open profile device");
		exit(EXIT_FAILURE);
	}

	/* give output before re-opening stdout as the logfile */
	printf("Using log file %s\n", op_log_file);

	/* set up logfile */
	close(0);
	close(1);

	if (open("/dev/null", O_RDONLY) == -1) {
		perror("oprofiled: couldn't re-open stdin as /dev/null: ");
		exit(EXIT_FAILURE);
	}

	opd_open_logfile();
	opd_create_pipe();

	printf("oprofiled started %s", op_get_time());
	printf("kernel pointer size: %lu\n",
		(unsigned long)kernel_pointer_size);
	fflush(stdout);
}
 

/** Done writing out the samples, indicate with complete_dump file */
static void complete_dump(void)
{
	FILE * status_file;

retry:
	status_file = fopen(op_dump_status, "w");

	if (!status_file && errno == EMFILE) {
		if (sfile_lru_clear()) {
			printf("LRU cleared but file open fails for %s.\n",
			       op_dump_status);
			abort();
		}
		goto retry;
	}

	if (!status_file) {
		perror("warning: couldn't set complete_dump: ");
		return;
	}

	fprintf(status_file, "1\n");
	fclose(status_file);
}

 
/**
 * opd_do_samples - process a sample buffer
 * @param opd_buf  buffer to process
 *
 * Process a buffer of samples.
 *
 * If the sample could be processed correctly, it is written
 * to the relevant sample file.
 */
static void opd_do_samples(char const * opd_buf, ssize_t count)
{
	size_t num = count / kernel_pointer_size;
 
	opd_stats[OPD_DUMP_COUNT]++;

	verbprintf(vmisc, "Read buffer of %d entries.\n", (unsigned int)num);
 
	opd_process_samples(opd_buf, num);

	complete_dump();
}
 
static void opd_do_jitdumps(void)
{ 
	pid_t childpid;
	int arg_num;
	unsigned long long end_time = 0ULL;
	struct timeval tv;
	char end_time_str[32];
	char opjitconv_path[PATH_MAX + 1];
	char * exec_args[7];

	if (jit_conversion_running)
		return;
	jit_conversion_running = 1;

	childpid = fork();
	switch (childpid) {
		case -1:
			perror("Error forking JIT dump process!");
			break;
		case 0:
			gettimeofday(&tv, NULL);
			end_time = tv.tv_sec;
			sprintf(end_time_str, "%llu", end_time);
			sprintf(opjitconv_path, "%s/%s", OP_BINDIR, "opjitconv");
			arg_num = 0;
			exec_args[arg_num++] = "opjitconv";
			if (vmisc)
				exec_args[arg_num++] = "-d";
			exec_args[arg_num++] = "--delete-jitdumps";
			exec_args[arg_num++] = session_dir;
			exec_args[arg_num++] = start_time_str;
			exec_args[arg_num++] = end_time_str;
			exec_args[arg_num] = (char *) NULL;
			execvp(opjitconv_path, exec_args);
			fprintf(stderr, "Failed to exec %s: %s\n",
			        exec_args[0], strerror(errno));
			/* We don't want any cleanup in the child */
			_exit(EXIT_FAILURE);
		default:
			break;
	} 

} 

/**
 * opd_do_read - enter processing loop
 * @param buf  buffer to read into
 * @param size  size of buffer
 *
 * Read some of a buffer from the device and process
 * the contents.
 */
static void opd_do_read(char * buf, size_t size)
{
	opd_open_pipe();

	while (1) {
		ssize_t count = -1;

		/* loop to handle EINTR */
		while (count < 0) {
			count = op_read_device(devfd, buf, size);

			/* we can lose an alarm or a hup but
			 * we don't care.
			 */
			if (signal_alarm) {
				signal_alarm = 0;
				opd_alarm();
			}

			if (signal_hup) {
				signal_hup = 0;
				opd_sighup();
			}

			if (signal_term)
				opd_sigterm();

			if (signal_child)
				opd_sigchild();

			if (signal_usr1) {
				signal_usr1 = 0;
				perfmon_start();
			}

			if (signal_usr2) {
				signal_usr2 = 0;
				perfmon_stop();
			}

			if (is_jitconv_requested()) {
				verbprintf(vmisc, "Start opjitconv was triggered\n");
				opd_do_jitdumps();
			}
		}

		opd_do_samples(buf, count);
	}
	
	opd_close_pipe();
}


/** opd_alarm - sync files and report stats */
static void opd_alarm(void)
{
	sfile_sync_files();
	opd_print_stats();
	alarm(60 * 10);
}
 

/** re-open files for logrotate/opcontrol --reset */
static void opd_sighup(void)
{
	printf("Received SIGHUP.\n");
	/* We just close them, and re-open them lazily as usual. */
	sfile_close_files();
	close(1);
	close(2);
	opd_open_logfile();
}


static void clean_exit(void)
{
	perfmon_exit();
	unlink(op_lock_file);
}


static void opd_sigterm(void)
{
	opd_do_jitdumps();
	opd_print_stats();
	printf("oprofiled stopped %s", op_get_time());
	opd_ext_deinitialize();

	exit(EXIT_FAILURE);
}

/* SIGCHLD received from JIT dump child process. */
static void opd_sigchild(void)
{
	int child_status;
	wait(&child_status);
	jit_conversion_running = 0;
	if (WIFEXITED(child_status) && (!WEXITSTATUS(child_status))) {
		verbprintf(vmisc, "JIT dump processing complete.\n");
	} else {
		printf("JIT dump processing exited abnormally: %d\n",
		       WEXITSTATUS(child_status));
	}

}
 
static void opd_26_init(void)
{
	size_t i;
	size_t opd_buf_size;
	unsigned long long start_time = 0ULL;
	struct timeval tv;

	opd_create_vmlinux(vmlinux, kernel_range);
	opd_create_xen(xenimage, xen_range);

	opd_buf_size = opd_read_fs_int("/dev/oprofile/", "buffer_size", 1);
	kernel_pointer_size = opd_read_fs_int("/dev/oprofile/", "pointer_size", 1);

	s_buf_bytesize = opd_buf_size * kernel_pointer_size;

	sbuf = xmalloc(s_buf_bytesize);

	opd_reread_module_info();

	for (i = 0; i < OPD_MAX_STATS; i++)
		opd_stats[i] = 0;

	perfmon_init();

	cookie_init();
	sfile_init();
	anon_init();

	/* must be /after/ perfmon_init() at least */
	if (atexit(clean_exit)) {
		perfmon_exit();
		perror("oprofiled: couldn't set exit cleanup: ");
		exit(EXIT_FAILURE);
	}

	/* trigger kernel module setup before returning control to opcontrol */
	opd_open_files();
	gettimeofday(&tv, NULL);
	start_time = 0ULL;
	start_time = tv.tv_sec;
	sprintf(start_time_str, "%llu", start_time);
		  
}


static void opd_26_start(void)
{
	/* simple sleep-then-process loop */
	opd_do_read(sbuf, s_buf_bytesize);
}


static void opd_26_exit(void)
{
	opd_print_stats();
	printf("oprofiled stopped %s", op_get_time());

	free(sbuf);
	free(vmlinux);
	/* FIXME: free kernel images, sfiles etc. */
}

struct oprofiled_ops opd_26_ops = {
	.init = opd_26_init,
	.start = opd_26_start,
	.exit = opd_26_exit,
};
