/*
 * Handle autoconfiguration of md devices.  This is ugly, partially since
 * it still relies on a sizable kernel component.
 *
 * This file is derived from the Linux kernel.
 */

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/sysmacros.h>
#include <sys/md.h>
#include <linux/major.h>

#include "kinit.h"
#include "do_mounts.h"

#define  LEVEL_NONE              (-1000000)

/*
 * When md (and any require personalities) are compiled into the kernel
 * (not a module), arrays can be assembles are boot time using with AUTODETECT
 * where specially marked partitions are registered with md_autodetect_dev(),
 * and with MD_BOOT where devices to be collected are given on the boot line
 * with md=.....
 * The code for that is here.
 */

static int raid_noautodetect, raid_autopart;

static struct {
	int minor;
	int partitioned;
	int level;
	int chunk;
	char *device_names;
} md_setup_args[MAX_MD_DEVS];

static int md_setup_ents;

/**
 *	get_option - Parse integer from an option string
 *	@str: option string
 *	@pint: (output) integer value parsed from @str
 *
 *	Read an int from an option string; if available accept a subsequent
 *	comma as well.
 *
 *	Return values:
 *	0 : no int in string
 *	1 : int found, no subsequent comma
 *	2 : int found including a subsequent comma
 */

static int get_option(char **str, int *pint)
{
	char *cur = *str;

	if (!cur || !(*cur))
		return 0;
	*pint = strtol(cur, str, 0);
	if (cur == *str)
		return 0;
	if (**str == ',') {
		(*str)++;
		return 2;
	}

	return 1;
}

/*
 * Find the partitioned md device major number... of course this *HAD*
 * to be done dynamically instead of using a registered number.
 * Sigh.  Double sigh.
 */
static int mdp_major(void)
{
	static int found = 0;
	FILE *f;
	char line[512], *p;
	int is_blk, major_no;

	if (found)
		return found;

	f = fopen("/proc/devices", "r");
	is_blk = 0;
	while (fgets(line, sizeof line, f)) {
		if (!strcmp(line, "Block devices:\n"))
			is_blk = 1;
		if (is_blk) {
			major_no = strtol(line, &p, 10);
			while (*p && isspace(*p))
				p++;

			if (major_no == 0)	/* Not a number */
				is_blk = 0;
			else if (major_no > 0 && !strcmp(p, "mdp")) {
				found = major_no;
				break;
			}
		}
	}
	fclose(f);

	if (!found) {
		fprintf(stderr,
			"Error: mdp devices detected but no mdp device found!\n");
		exit(1);
	}

	return found;
}

/*
 * Parse the command-line parameters given our kernel, but do not
 * actually try to invoke the MD device now; that is handled by
 * md_setup_drive after the low-level disk drivers have initialised.
 *
 * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
 *             assigns the task of parsing integer arguments to the
 *             invoked program now).  Added ability to initialise all
 *             the MD devices (by specifying multiple "md=" lines)
 *             instead of just one.  -- KTK
 * 18May2000: Added support for persistent-superblock arrays:
 *             md=n,0,factor,fault,device-list   uses RAID0 for device n
 *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
 *             md=n,device-list      reads a RAID superblock from the devices
 *             elements in device-list are read by name_to_kdev_t so can be
 *             a hex number or something like /dev/hda1 /dev/sdb
 * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
 *		Shifted name_to_kdev_t() and related operations to md_set_drive()
 *		for later execution. Rewrote section to make devfs compatible.
 */
static int md_setup(char *str)
{
	int minor_num, level, factor, fault, partitioned = 0;
	char *pername = "";
	char *str1;
	int ent;

	if (*str == 'd') {
		partitioned = 1;
		str++;
	}
	if (get_option(&str, &minor_num) != 2) {	/* MD Number */
		fprintf(stderr, "md: Too few arguments supplied to md=.\n");
		return 0;
	}
	str1 = str;
	if (minor_num >= MAX_MD_DEVS) {
		fprintf(stderr, "md: md=%d, Minor device number too high.\n",
			minor_num);
		return 0;
	}
	for (ent = 0; ent < md_setup_ents; ent++)
		if (md_setup_args[ent].minor == minor_num &&
		    md_setup_args[ent].partitioned == partitioned) {
			fprintf(stderr,
				"md: md=%s%d, Specified more than once. "
				"Replacing previous definition.\n",
				partitioned ? "d" : "", minor_num);
			break;
		}
	if (ent >= MAX_MD_DEVS) {
		fprintf(stderr, "md: md=%s%d - too many md initialisations\n",
			partitioned ? "d" : "", minor_num);
		return 0;
	}
	if (ent >= md_setup_ents)
		md_setup_ents++;
	switch (get_option(&str, &level)) {	/* RAID level */
	case 2:		/* could be 0 or -1.. */
		if (level == 0 || level == LEVEL_LINEAR) {
			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
			    get_option(&str, &fault) != 2) {
				fprintf(stderr,
					"md: Too few arguments supplied to md=.\n");
				return 0;
			}
			md_setup_args[ent].level = level;
			md_setup_args[ent].chunk = 1 << (factor + 12);
			if (level == LEVEL_LINEAR)
				pername = "linear";
			else
				pername = "raid0";
			break;
		}
		/* FALL THROUGH */
	case 1:		/* the first device is numeric */
		str = str1;
		/* FALL THROUGH */
	case 0:
		md_setup_args[ent].level = LEVEL_NONE;
		pername = "super-block";
	}

	fprintf(stderr, "md: Will configure md%s%d (%s) from %s, below.\n",
		partitioned?"_d":"", minor_num, pername, str);
	md_setup_args[ent].device_names = str;
	md_setup_args[ent].partitioned = partitioned;
	md_setup_args[ent].minor = minor_num;

	return 1;
}

#define MdpMinorShift 6

static void md_setup_drive(void)
{
	int dev_minor, i, ent, partitioned;
	dev_t dev;
	dev_t devices[MD_SB_DISKS + 1];

	for (ent = 0; ent < md_setup_ents; ent++) {
		int fd;
		int err = 0;
		char *devname;
		mdu_disk_info_t dinfo;
		char name[16];
		struct stat st_chk;

		dev_minor = md_setup_args[ent].minor;
		partitioned = md_setup_args[ent].partitioned;
		devname = md_setup_args[ent].device_names;

		snprintf(name, sizeof name,
			 "/dev/md%s%d", partitioned ? "_d" : "", dev_minor);

		if (stat(name, &st_chk) == 0)
			continue;

		if (partitioned)
			dev = makedev(mdp_major(), dev_minor << MdpMinorShift);
		else
			dev = makedev(MD_MAJOR, dev_minor);
		create_dev(name, dev);
		for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
			char *p;

			p = strchr(devname, ',');
			if (p)
				*p++ = 0;

			dev = name_to_dev_t(devname);
			if (!dev) {
				fprintf(stderr, "md: Unknown device name: %s\n",
					devname);
				break;
			}

			devices[i] = dev;

			devname = p;
		}
		devices[i] = 0;

		if (!i)
			continue;

		fprintf(stderr, "md: Loading md%s%d: %s\n",
			partitioned ? "_d" : "", dev_minor,
			md_setup_args[ent].device_names);

		fd = open(name, 0, 0);
		if (fd < 0) {
			fprintf(stderr, "md: open failed - cannot start "
				"array %s\n", name);
			continue;
		}
		if (ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
			fprintf(stderr,
				"md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
				dev_minor);
			close(fd);
			continue;
		}

		if (md_setup_args[ent].level != LEVEL_NONE) {
			/* non-persistent */
			mdu_array_info_t ainfo;
			ainfo.level = md_setup_args[ent].level;
			ainfo.size = 0;
			ainfo.nr_disks = 0;
			ainfo.raid_disks = 0;
			while (devices[ainfo.raid_disks])
				ainfo.raid_disks++;
			ainfo.md_minor = dev_minor;
			ainfo.not_persistent = 1;

			ainfo.state = (1 << MD_SB_CLEAN);
			ainfo.layout = 0;
			ainfo.chunk_size = md_setup_args[ent].chunk;
			err = ioctl(fd, SET_ARRAY_INFO, &ainfo);
			for (i = 0; !err && i <= MD_SB_DISKS; i++) {
				dev = devices[i];
				if (!dev)
					break;
				dinfo.number = i;
				dinfo.raid_disk = i;
				dinfo.state =
				    (1 << MD_DISK_ACTIVE) | (1 << MD_DISK_SYNC);
				dinfo.major = major(dev);
				dinfo.minor = minor(dev);
				err = ioctl(fd, ADD_NEW_DISK, &dinfo);
			}
		} else {
			/* persistent */
			for (i = 0; i <= MD_SB_DISKS; i++) {
				dev = devices[i];
				if (!dev)
					break;
				dinfo.major = major(dev);
				dinfo.minor = minor(dev);
				ioctl(fd, ADD_NEW_DISK, &dinfo);
			}
		}
		if (!err)
			err = ioctl(fd, RUN_ARRAY, 0);
		if (err)
			fprintf(stderr, "md: starting md%d failed\n",
				dev_minor);
		else {
			/* reread the partition table.
			 * I (neilb) and not sure why this is needed, but I cannot
			 * boot a kernel with devfs compiled in from partitioned md
			 * array without it
			 */
			close(fd);
			fd = open(name, 0, 0);
			ioctl(fd, BLKRRPART, 0);
		}
		close(fd);
	}
}

static int raid_setup(char *str)
{
	int len, pos;

	len = strlen(str) + 1;
	pos = 0;

	while (pos < len) {
		char *comma = strchr(str + pos, ',');
		int wlen;
		if (comma)
			wlen = (comma - str) - pos;
		else
			wlen = (len - 1) - pos;

		if (!strncmp(str, "noautodetect", wlen))
			raid_noautodetect = 1;
		if (strncmp(str, "partitionable", wlen) == 0)
			raid_autopart = 1;
		if (strncmp(str, "part", wlen) == 0)
			raid_autopart = 1;
		pos += wlen + 1;
	}
	return 1;
}

static void md_run_setup(void)
{
	create_dev("/dev/md0", makedev(MD_MAJOR, 0));
	if (raid_noautodetect)
		fprintf(stderr,
			"md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
	else {
		int fd = open("/dev/md0", 0, 0);
		if (fd >= 0) {
			ioctl(fd, RAID_AUTORUN,
			      (void *)(intptr_t) raid_autopart);
			close(fd);
		}
	}
	md_setup_drive();
}

void md_run(int argc, char *argv[])
{
	char **pp, *p;

	for (pp = argv; (p = *pp); pp++) {
		if (!strncmp(p, "raid=", 5))
			raid_setup(p + 5);
		else if (!strncmp(p, "md=", 3))
			md_setup(p + 3);
	}

	md_run_setup();
}
