/*
 * kinit/initrd.c
 *
 * Handle initrd, thus putting the backwards into backwards compatible
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include "do_mounts.h"
#include "kinit.h"
#include "xpio.h"

#define BUF_SIZE	65536	/* Should be a power of 2 */

/*
 * Copy the initrd to /dev/ram0, copy from the end to the beginning
 * to avoid taking 2x the memory.
 */
static int rd_copy_uncompressed(int ffd, int dfd)
{
	char buffer[BUF_SIZE];
	off_t bytes;
	struct stat st;

	DEBUG(("kinit: uncompressed initrd\n"));

	if ( ffd < 0 || fstat(ffd, &st) || !S_ISREG(st.st_mode) ||
	     (bytes = st.st_size) == 0 )
		return -1;

	while ( bytes ) {
		ssize_t blocksize = ((bytes-1) & (BUF_SIZE-1))+1;
		off_t offset = bytes-blocksize;

		DEBUG(("kinit: copying %zd bytes at offset %llu\n",
		       blocksize, offset));

		if ( xpread(ffd, buffer, blocksize, offset) != blocksize ||
		     xpwrite(dfd, buffer, blocksize, offset) != blocksize )
			return -1;

		ftruncate(ffd, offset); /* Free up memory */
		bytes = offset;
	}
	return 0;
}

static int rd_copy_image(const char *path)
{
	int ffd = open(path, O_RDONLY);
	int rv = -1;
	unsigned char gzip_magic[2];

	if ( ffd < 0 )
		goto barf;
	
	if ( xpread(ffd, gzip_magic, 2, 0) == 2 &&
	     gzip_magic[0] == 037 && gzip_magic[1] == 0213 ) {
		FILE *wfd = fopen("/dev/ram0", "w");
		if (!wfd)
			goto barf;
		rv = load_ramdisk_compressed(path, wfd, 0);
		fclose(wfd);
	} else {
		int dfd = open("/dev/ram0", O_WRONLY);
		if (dfd < 0)
			goto barf;
		rv = rd_copy_uncompressed(ffd, dfd);
		close(dfd);
	}

barf:
	if (ffd >= 0)
		close(ffd);
	return rv;
}

/*
 * Run /linuxrc, for emulation of old-style initrd
 */
static int
run_linuxrc(int argc, char *argv[], dev_t root_dev)
{
	int root_fd, old_fd;
	pid_t pid;
	long realroot = Root_RAM0;
	const char *ramdisk_name = "/dev/ram0";
	FILE *fp;

	DEBUG(("kinit: mounting initrd\n"));
	mkdir("/root", 0700);
	if ( !mount_block(ramdisk_name, "/root", NULL, MS_VERBOSE, NULL) )
		return -errno;

	/* Write the current "real root device" out to procfs */
	DEBUG(("kinit: real_root_dev = %#x\n", root_dev));
	fp = fopen("/proc/sys/kernel/real-root-dev", "w");
	fprintf(fp, "%u", root_dev);
	fclose(fp);

	mkdir("/old", 0700);
	root_fd = open_cloexec("/", O_RDONLY|O_DIRECTORY, 0);
	old_fd = open_cloexec("/old", O_RDONLY|O_DIRECTORY, 0);

	if ( root_fd < 0 || old_fd < 0 )
		return -errno;

	if ( chdir("/root") ||
	     mount(".", "/", NULL, MS_MOVE, NULL) ||
	     chroot(".") )
		return -errno;

	pid = fork();
	if ( pid == 0 ) {
		setsid();
		/* Looks like linuxrc doesn't get the init environment or parameters.
		   Weird, but so is the whole linuxrc bit. */
		execl("/linuxrc", "linuxrc", NULL);
		_exit(255);
	} else if ( pid > 0 ) {
		DEBUG(("kinit: Waiting for linuxrc to complete...\n"));
		while ( waitpid(pid, NULL, 0) != pid );
		DEBUG(("kinit: linuxrc done\n"));
	} else {
		return -errno;
	}

	if ( fchdir(old_fd) ||
	     mount("/", ".", NULL, MS_MOVE, NULL) ||
	     fchdir(root_fd) ||
	     chroot(".") )
		return -errno;

	close(root_fd);
	close(old_fd);

	getintfile("/proc/sys/kernel/real-root-dev", &realroot);

	/* If realroot is Root_RAM0, then the initrd did any necessary work */
	if (realroot == Root_RAM0) {
		if ( mount("/old", "/root", NULL, MS_MOVE, NULL) )
			return -errno;
	} else {
		mount_root(argc, argv, (dev_t)realroot, NULL);

		/* If /root/initrd exists, move the initrd there, otherwise discard */
		if ( !mount("/old", "/root/initrd", NULL, MS_MOVE, NULL) ) {
			/* We're good */
		} else {
			int olddev = open(ramdisk_name, O_RDWR);
			umount2("/old", MNT_DETACH);
			if ( olddev < 0 ||
			     ioctl(olddev, BLKFLSBUF, (long)0) ||
			     close(olddev) ) {
				fprintf(stderr, "%s: Cannot flush initrd contents\n", progname);
			}
		}
	}

	rmdir("/old");
	return 0;
}


int initrd_load(int argc, char *argv[], dev_t root_dev)
{
	if ( access("/initrd.image", R_OK) )
		return 0;	/* No initrd */

	DEBUG(("kinit: initrd found\n"));

	create_dev("/dev/ram0", Root_RAM0);

	if ( rd_copy_image("/initrd.image") || unlink("/initrd.image") ) {
		fprintf(stderr, "%s: initrd installation failed (too big?)\n",
			progname);
		return 0;	/* Failed to copy initrd */
	}

	DEBUG(("kinit: initrd copied\n"));

	if (root_dev != Root_RAM0) {
		int err;
		DEBUG(("kinit: running linuxrc\n"));
		err = run_linuxrc(argc, argv, root_dev);
		if (err)
			fprintf(stderr, "%s: running linuxrc: %s\n", progname, strerror(-err));
	} else {
		DEBUG(("kinit: permament (or pivoting) initrd, not running linuxrc\n"));
	}

	return 1;		/* initrd is root, or run_linuxrc took care of it */
}
