/* vi: set sw=4 ts=4: */
/*
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
//config:config BOOTCHARTD
//config:	bool "bootchartd (10 kb)"
//config:	default y
//config:	help
//config:	bootchartd is commonly used to profile the boot process
//config:	for the purpose of speeding it up. In this case, it is started
//config:	by the kernel as the init process. This is configured by adding
//config:	the init=/sbin/bootchartd option to the kernel command line.
//config:
//config:	It can also be used to monitor the resource usage of a specific
//config:	application or the running system in general. In this case,
//config:	bootchartd is started interactively by running bootchartd start
//config:	and stopped using bootchartd stop.
//config:
//config:config FEATURE_BOOTCHARTD_BLOATED_HEADER
//config:	bool "Compatible, bloated header"
//config:	default y
//config:	depends on BOOTCHARTD
//config:	help
//config:	Create extended header file compatible with "big" bootchartd.
//config:	"Big" bootchartd is a shell script and it dumps some
//config:	"convenient" info into the header, such as:
//config:		title = Boot chart for `hostname` (`date`)
//config:		system.uname = `uname -srvm`
//config:		system.release = `cat /etc/DISTRO-release`
//config:		system.cpu = `grep '^model name' /proc/cpuinfo | head -1` ($cpucount)
//config:		system.kernel.options = `cat /proc/cmdline`
//config:	This data is not mandatory for bootchart graph generation,
//config:	and is considered bloat. Nevertheless, this option
//config:	makes bootchartd applet to dump a subset of it.
//config:
//config:config FEATURE_BOOTCHARTD_CONFIG_FILE
//config:	bool "Support bootchartd.conf"
//config:	default y
//config:	depends on BOOTCHARTD
//config:	help
//config:	Enable reading and parsing of $PWD/bootchartd.conf
//config:	and /etc/bootchartd.conf files.

//applet:IF_BOOTCHARTD(APPLET(bootchartd, BB_DIR_SBIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_BOOTCHARTD) += bootchartd.o

#include "libbb.h"
#include "common_bufsiz.h"
/* After libbb.h, since it needs sys/types.h on some systems */
#include <sys/utsname.h>

#ifdef __linux__
# include <sys/mount.h>
# ifndef MS_SILENT
#  define MS_SILENT      (1 << 15)
# endif
# ifndef MNT_DETACH
#  define MNT_DETACH 0x00000002
# endif
#endif

#if !ENABLE_TAR && !ENABLE_WERROR
# warning Note: bootchartd requires tar command, but you did not select it.
#elif !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_WERROR
# warning Note: bootchartd requires tar -z support, but you did not select it.
#endif

#define BC_VERSION_STR "0.8"

/* For debugging, set to 0:
 * strace won't work with DO_SIGNAL_SYNC set to 1.
 */
#define DO_SIGNAL_SYNC 1


//$PWD/bootchartd.conf and /etc/bootchartd.conf:
//supported options:
//# Sampling period (in seconds)
//SAMPLE_PERIOD=0.2
//
//not yet supported:
//# tmpfs size
//# (32 MB should suffice for ~20 minutes worth of log data, but YMMV)
//TMPFS_SIZE=32m
//
//# Whether to enable and store BSD process accounting information.  The
//# kernel needs to be configured to enable v3 accounting
//# (CONFIG_BSD_PROCESS_ACCT_V3). accton from the GNU accounting utilities
//# is also required.
//PROCESS_ACCOUNTING="no"
//
//# Tarball for the various boot log files
//BOOTLOG_DEST=/var/log/bootchart.tgz
//
//# Whether to automatically stop logging as the boot process completes.
//# The logger will look for known processes that indicate bootup completion
//# at a specific runlevel (e.g. gdm-binary, mingetty, etc.).
//AUTO_STOP_LOGGER="yes"
//
//# Whether to automatically generate the boot chart once the boot logger
//# completes.  The boot chart will be generated in $AUTO_RENDER_DIR.
//# Note that the bootchart package must be installed.
//AUTO_RENDER="no"
//
//# Image format to use for the auto-generated boot chart
//# (choose between png, svg and eps).
//AUTO_RENDER_FORMAT="png"
//
//# Output directory for auto-generated boot charts
//AUTO_RENDER_DIR="/var/log"


/* Globals */
struct globals {
	char jiffy_line[COMMON_BUFSIZE];
} FIX_ALIASING;
#define G (*(struct globals*)bb_common_bufsiz1)
#define INIT_G() do { setup_common_bufsiz(); } while (0)

static void dump_file(FILE *fp, const char *filename)
{
	int fd = open(filename, O_RDONLY);
	if (fd >= 0) {
		fputs(G.jiffy_line, fp);
		fflush(fp);
		bb_copyfd_eof(fd, fileno(fp));
		close(fd);
		fputc('\n', fp);
	}
}

static int dump_procs(FILE *fp, int look_for_login_process)
{
	struct dirent *entry;
	DIR *dir = opendir("/proc");
	int found_login_process = 0;

	fputs(G.jiffy_line, fp);
	while ((entry = readdir(dir)) != NULL) {
		char name[sizeof("/proc/%u/cmdline") + sizeof(int)*3];
		int stat_fd;
		unsigned pid = bb_strtou(entry->d_name, NULL, 10);
		if (errno)
			continue;

		/* Android's version reads /proc/PID/cmdline and extracts
		 * non-truncated process name. Do we want to do that? */

		sprintf(name, "/proc/%u/stat", pid);
		stat_fd = open(name, O_RDONLY);
		if (stat_fd >= 0) {
			char *p;
			char stat_line[4*1024];
			int rd = safe_read(stat_fd, stat_line, sizeof(stat_line)-2);

			close(stat_fd);
			if (rd < 0)
				continue;
			stat_line[rd] = '\0';
			p = strchrnul(stat_line, '\n');
			*p++ = '\n';
			*p = '\0';
			fputs(stat_line, fp);
			if (!look_for_login_process)
				continue;
			p = strchr(stat_line, '(');
			if (!p)
				continue;
			p++;
			strchrnul(p, ')')[0] = '\0';
			/* Is it gdm, kdm or a getty? */
			if (((p[0] == 'g' || p[0] == 'k' || p[0] == 'x')
			     && p[1] == 'd' && p[2] == 'm' && p[3] == '\0'
			    )
			 || strstr(p, "getty")
			) {
				found_login_process = 1;
			}
		}
	}
	closedir(dir);
	fputc('\n', fp);
	return found_login_process;
}

static char *make_tempdir(void)
{
	char template[] = "/tmp/bootchart.XXXXXX";
	char *tempdir = xstrdup(mkdtemp(template));
	if (!tempdir) {
#ifdef __linux__
		/* /tmp is not writable (happens when we are used as init).
		 * Try to mount a tmpfs, then cd and lazily unmount it.
		 * Since we unmount it at once, we can mount it anywhere.
		 * Try a few locations which are likely ti exist.
		 */
		static const char dirs[] ALIGN1 = "/mnt\0""/tmp\0""/boot\0""/proc\0";
		const char *try_dir = dirs;
		while (mount("none", try_dir, "tmpfs", MS_SILENT, "size=16m") != 0) {
			try_dir += strlen(try_dir) + 1;
			if (!try_dir[0])
				bb_perror_msg_and_die("can't %smount tmpfs", "");
		}
		//bb_error_msg("mounted tmpfs on %s", try_dir);
		xchdir(try_dir);
		if (umount2(try_dir, MNT_DETACH) != 0) {
			bb_perror_msg_and_die("can't %smount tmpfs", "un");
		}
#else
		bb_simple_perror_msg_and_die("can't create temporary directory");
#endif
	} else {
		xchdir(tempdir);
	}
	return tempdir;
}

static void do_logging(unsigned sample_period_us, int process_accounting)
{
	FILE *proc_stat = xfopen_for_write("proc_stat.log");
	FILE *proc_diskstats = xfopen_for_write("proc_diskstats.log");
	//FILE *proc_netdev = xfopen_for_write("proc_netdev.log");
	FILE *proc_ps = xfopen_for_write("proc_ps.log");
	int look_for_login_process = (getppid() == 1);
	unsigned count = 60*1000*1000 / sample_period_us; /* ~1 minute */

	if (process_accounting) {
		close(xopen("kernel_pacct", O_WRONLY | O_CREAT | O_TRUNC));
		acct("kernel_pacct");
	}

	while (--count && !bb_got_signal) {
		char *p;
		int len = open_read_close("/proc/uptime", G.jiffy_line, sizeof(G.jiffy_line)-2);
		if (len < 0)
			goto wait_more;
		/* /proc/uptime has format "NNNNNN.MM NNNNNNN.MM" */
		/* we convert it to "NNNNNNMM\n" (using first value) */
		G.jiffy_line[len] = '\0';
		p = strchr(G.jiffy_line, '.');
		if (!p)
			goto wait_more;
		while (isdigit(*++p))
			p[-1] = *p;
		p[-1] = '\n';
		p[0] = '\0';

		dump_file(proc_stat, "/proc/stat");
		dump_file(proc_diskstats, "/proc/diskstats");
		//dump_file(proc_netdev, "/proc/net/dev");
		if (dump_procs(proc_ps, look_for_login_process)) {
			/* dump_procs saw a getty or {g,k,x}dm
			 * stop logging in 2 seconds:
			 */
			if (count > 2*1000*1000 / sample_period_us)
				count = 2*1000*1000 / sample_period_us;
		}
		fflush_all();
 wait_more:
		usleep(sample_period_us);
	}
}

static void finalize(char *tempdir, const char *prog, int process_accounting)
{
	//# Stop process accounting if configured
	//local pacct=
	//[ -e kernel_pacct ] && pacct=kernel_pacct

	FILE *header_fp = xfopen_for_write("header");

	if (process_accounting)
		acct(NULL);

	if (prog)
		fprintf(header_fp, "profile.process = %s\n", prog);

	fputs("version = "BC_VERSION_STR"\n", header_fp);
	if (ENABLE_FEATURE_BOOTCHARTD_BLOATED_HEADER) {
		char *hostname;
		char *kcmdline;
		time_t t;
		struct tm tm_time;
		/* x2 for possible localized weekday/month names */
		char date_buf[sizeof("Mon Jun 21 05:29:03 CEST 2010") * 2];
		struct utsname unamebuf;

		hostname = safe_gethostname();
		time(&t);
		localtime_r(&t, &tm_time);
		strftime(date_buf, sizeof(date_buf), "%a %b %e %H:%M:%S %Z %Y", &tm_time);
		fprintf(header_fp, "title = Boot chart for %s (%s)\n", hostname, date_buf);
		if (ENABLE_FEATURE_CLEAN_UP)
			free(hostname);

		uname(&unamebuf); /* never fails */
		/* same as uname -srvm */
		fprintf(header_fp, "system.uname = %s %s %s %s\n",
				unamebuf.sysname,
				unamebuf.release,
				unamebuf.version,
				unamebuf.machine
		);

		//system.release = `cat /etc/DISTRO-release`
		//system.cpu = `grep '^model name' /proc/cpuinfo | head -1` ($cpucount)

		kcmdline = xmalloc_open_read_close("/proc/cmdline", NULL);
		/* kcmdline includes trailing "\n" */
		fprintf(header_fp, "system.kernel.options = %s", kcmdline);
		if (ENABLE_FEATURE_CLEAN_UP)
			free(kcmdline);
	}
	fclose(header_fp);

	/* Package log files */
	system(xasprintf("tar -zcf /var/log/bootlog.tgz header %s *.log", process_accounting ? "kernel_pacct" : ""));
	/* Clean up (if we are not in detached tmpfs) */
	if (tempdir) {
		unlink("header");
		unlink("proc_stat.log");
		unlink("proc_diskstats.log");
		//unlink("proc_netdev.log");
		unlink("proc_ps.log");
		if (process_accounting)
			unlink("kernel_pacct");
		rmdir(tempdir);
	}

	/* shell-based bootchartd tries to run /usr/bin/bootchart if $AUTO_RENDER=yes:
	 * /usr/bin/bootchart -o "$AUTO_RENDER_DIR" -f $AUTO_RENDER_FORMAT "$BOOTLOG_DEST"
	 */
}

//usage:#define bootchartd_trivial_usage
//usage:       "start [PROG ARGS]|stop|init"
//usage:#define bootchartd_full_usage "\n\n"
//usage:       "Create /var/log/bootchart.tgz with boot chart data\n"
//usage:     "\nstart: start background logging; with PROG, run PROG, then kill logging with USR1"
//usage:     "\nstop: send USR1 to all bootchartd processes"
//usage:     "\ninit: start background logging; stop when getty/xdm is seen (for init scripts)"
//usage:     "\nUnder PID 1: as init, then exec $bootchart_init, /init, /sbin/init"

int bootchartd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int bootchartd_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned sample_period_us;
	pid_t parent_pid, logger_pid;
	smallint cmd;
	int process_accounting;
	enum {
		CMD_STOP = 0,
		CMD_START,
		CMD_INIT,
		CMD_PID1, /* used to mark pid 1 case */
	};

	INIT_G();

	parent_pid = getpid();
	if (argv[1]) {
		cmd = index_in_strings("stop\0""start\0""init\0", argv[1]);
		if (cmd < 0)
			bb_show_usage();
		if (cmd == CMD_STOP) {
			pid_t *pidList = find_pid_by_name("bootchartd");
			while (*pidList != 0) {
				if (*pidList != parent_pid)
					kill(*pidList, SIGUSR1);
				pidList++;
			}
			return EXIT_SUCCESS;
		}
	} else {
		if (parent_pid != 1)
			bb_show_usage();
		cmd = CMD_PID1;
	}

	/* Here we are in START, INIT or CMD_PID1 state */

	/* Read config file: */
	sample_period_us = 200 * 1000;
	process_accounting = 0;
	if (ENABLE_FEATURE_BOOTCHARTD_CONFIG_FILE) {
		char* token[2];
		parser_t *parser = config_open2("/etc/bootchartd.conf" + 5, fopen_for_read);
		if (!parser)
			parser = config_open2("/etc/bootchartd.conf", fopen_for_read);
		while (config_read(parser, token, 2, 0, "#=", PARSE_NORMAL & ~PARSE_COLLAPSE)) {
			if (strcmp(token[0], "SAMPLE_PERIOD") == 0 && token[1])
				sample_period_us = atof(token[1]) * 1000000;
			if (strcmp(token[0], "PROCESS_ACCOUNTING") == 0 && token[1]
			 && (strcmp(token[1], "on") == 0 || strcmp(token[1], "yes") == 0)
			) {
				process_accounting = 1;
			}
		}
		config_close(parser);
		if ((int)sample_period_us <= 0)
			sample_period_us = 1; /* prevent division by 0 */
	}

	/* Create logger child: */
	logger_pid = fork_or_rexec(argv);

	if (logger_pid == 0) { /* child */
		char *tempdir;

		bb_signals(0
			+ (1 << SIGUSR1)
			+ (1 << SIGUSR2)
			+ (1 << SIGTERM)
			+ (1 << SIGQUIT)
			+ (1 << SIGINT)
			+ (1 << SIGHUP)
			, record_signo);

		if (DO_SIGNAL_SYNC)
			/* Inform parent that we are ready */
			raise(SIGSTOP);

		/* If we are started by kernel, PATH might be unset.
		 * In order to find "tar", let's set some sane PATH:
		 */
		if (cmd == CMD_PID1 && !getenv("PATH"))
			putenv((char*)bb_PATH_root_path);

		tempdir = make_tempdir();
		do_logging(sample_period_us, process_accounting);
		finalize(tempdir, cmd == CMD_START ? argv[2] : NULL, process_accounting);
		return EXIT_SUCCESS;
	}

	/* parent */

	USE_FOR_NOMMU(argv[0][0] &= 0x7f); /* undo fork_or_rexec() damage */

	if (DO_SIGNAL_SYNC) {
		/* Wait for logger child to set handlers, then unpause it.
		 * Otherwise with short-lived PROG (e.g. "bootchartd start true")
		 * we might send SIGUSR1 before logger sets its handler.
		 */
		waitpid(logger_pid, NULL, WUNTRACED);
		kill(logger_pid, SIGCONT);
	}

	if (cmd == CMD_PID1) {
		char *bootchart_init = getenv("bootchart_init");
		if (bootchart_init)
			execl(bootchart_init, bootchart_init, NULL);
		execl("/init", "init", NULL);
		execl("/sbin/init", "init", NULL);
		bb_perror_msg_and_die("can't execute '%s'", "/sbin/init");
	}

	if (cmd == CMD_START && argv[2]) { /* "start PROG ARGS" */
		pid_t pid = xvfork();
		if (pid == 0) { /* child */
			argv += 2;
			BB_EXECVP_or_die(argv);
		}
		/* parent */
		waitpid(pid, NULL, 0);
		kill(logger_pid, SIGUSR1);
	}

	return EXIT_SUCCESS;
}
