/*
 * usr/kinit/do_mounts_md.c
 *
 * 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 <alloca.h>
#include <inttypes.h>
#include <sys/sysmacros.h>
#include <sys/md.h>
#include <linux/major.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, level, factor, fault, partitioned = 0;
	char *pername = "";
	char *str1;
	int ent;

	if (*str == 'd') {
		partitioned = 1;
		str++;
	}
	if (get_option(&str, &minor) != 2) {	/* MD Number */
		fprintf(stderr, "md: Too few arguments supplied to md=.\n");
		return 0;
	}
	str1 = str;
	if (minor >= MAX_MD_DEVS) {
		fprintf(stderr, "md: md=%d, Minor device number too high.\n",
			minor);
		return 0;
	}
	for (ent = 0; ent < md_setup_ents; ent++)
		if (md_setup_args[ent].minor == minor &&
		    md_setup_args[ent].partitioned == partitioned) {
			fprintf(stderr,
				"md: md=%s%d, Specified more than once. "
				"Replacing previous definition.\n",
				partitioned ? "d" : "", minor);
			break;
		}
	if (ent >= MAX_MD_DEVS) {
		fprintf(stderr, "md: md=%s%d - too many md initialisations\n",
			partitioned ? "d" : "", minor);
		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%d (%s) from %s, below.\n",
		minor, pername, str);
	md_setup_args[ent].device_names = str;
	md_setup_args[ent].partitioned = partitioned;
	md_setup_args[ent].minor = minor;

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

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