/**
 * @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[6];

	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++] = 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,
};
