/* 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_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("proc_stat.log", "w");
	FILE *proc_diskstats = xfopen("proc_diskstats.log", "w");
	//FILE *proc_netdev = xfopen("proc_netdev.log", "w");
	FILE *proc_ps = xfopen("proc_ps.log", "w");
	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("header", "w");

	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;
}
