Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Feb 2011 12:34:27 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r218519 - in projects/graid/head: sbin/geom/class/raid sys/geom/raid
Message-ID:  <201102101234.p1ACYRS7022195@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Feb 10 12:34:27 2011
New Revision: 218519
URL: http://svn.freebsd.org/changeset/base/218519

Log:
  Add checks for number of disks in each configuration, supported by Intel
  RAID BIOS. Add "-f" flag to `graid label` and `graid add` allowing to
  bypass these checks.

Modified:
  projects/graid/head/sbin/geom/class/raid/geom_raid.c
  projects/graid/head/sbin/geom/class/raid/graid.8
  projects/graid/head/sys/geom/raid/md_intel.c

Modified: projects/graid/head/sbin/geom/class/raid/geom_raid.c
==============================================================================
--- projects/graid/head/sbin/geom/class/raid/geom_raid.c	Thu Feb 10 11:27:31 2011	(r218518)
+++ projects/graid/head/sbin/geom/class/raid/geom_raid.c	Thu Feb 10 12:34:27 2011	(r218519)
@@ -47,19 +47,21 @@ uint32_t version = G_RAID_VERSION;
 struct g_command class_commands[] = {
 	{ "label", G_FLAG_VERBOSE, NULL,
 	    {
+		{ 'f', "force", NULL, G_TYPE_BOOL },
 		{ 'S', "size", G_VAL_OPTIONAL, G_TYPE_NUMBER },
 		{ 's', "strip", G_VAL_OPTIONAL, G_TYPE_NUMBER },
 		G_OPT_SENTINEL
 	    },
-	    "[-S size] [-s stripsize] format label level prov ..."
+	    "[-fv] [-S size] [-s stripsize] format label level prov ..."
 	},
 	{ "add", G_FLAG_VERBOSE, NULL,
 	    {
+		{ 'f', "force", NULL, G_TYPE_BOOL },
 		{ 'S', "size", G_VAL_OPTIONAL, G_TYPE_NUMBER },
 		{ 's', "strip", G_VAL_OPTIONAL, G_TYPE_NUMBER },
 		G_OPT_SENTINEL
 	    },
-	    "[-S size] [-s stripsize] name label level"
+	    "[-fv] [-S size] [-s stripsize] name label level"
 	},
 	{ "delete", G_FLAG_VERBOSE, NULL,
 	    {

Modified: projects/graid/head/sbin/geom/class/raid/graid.8
==============================================================================
--- projects/graid/head/sbin/geom/class/raid/graid.8	Thu Feb 10 11:27:31 2011	(r218518)
+++ projects/graid/head/sbin/geom/class/raid/graid.8	Thu Feb 10 12:34:27 2011	(r218519)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 5, 2011
+.Dd February 10, 2011
 .Dt GRAID 8
 .Os
 .Sh NAME
@@ -33,6 +33,7 @@
 .Sh SYNOPSIS
 .Nm
 .Cm label
+.Op Fl f
 .Op Fl S Ar size
 .Op Fl s Ar strip
 .Ar format
@@ -41,6 +42,7 @@
 .Ar prov ...
 .Nm
 .Cm add
+.Op Fl f
 .Op Fl S Ar size
 .Op Fl s Ar strip
 .Ar name
@@ -114,6 +116,9 @@ and metadata format.
 .Pp
 Additional options include:
 .Bl -tag -width ".Fl s Ar strip"
+.It Fl f
+Enforce specified configuration creation if it is officially unsupported,
+but technically can be created.
 .It Fl S Ar size
 Use
 .Ar size
@@ -200,6 +205,8 @@ The format used by Intel RAID BIOS.
 Supports up to two volumes per array.
 Supports configurations: RAID0 (2+ disks), RAID1 (2 disks),
 RAID5 (3+ disks), RAID10 (4 disks).
+Configurations not supported by Intel RAID BIOS, but enforsable on your own
+risk: RAID1 (3+ disks), RAID1E (3+ disks), RAID10 (6+ disks).
 .El
 .Sh SUPPORTED RAID LEVELS
 The GEOM RAID class follows a modular design, allowing different RAID levels

Modified: projects/graid/head/sys/geom/raid/md_intel.c
==============================================================================
--- projects/graid/head/sys/geom/raid/md_intel.c	Thu Feb 10 11:27:31 2011	(r218518)
+++ projects/graid/head/sys/geom/raid/md_intel.c	Thu Feb 10 12:34:27 2011	(r218519)
@@ -568,6 +568,43 @@ g_raid_md_intel_get_disk(struct g_raid_s
 	return (disk);
 }
 
+static int
+g_raid_md_intel_supported(int level, int qual, int disks, int force)
+{
+
+	switch (level) {
+	case G_RAID_VOLUME_RL_RAID0:
+		if (disks < 1)
+			return (0);
+		if (!force && (disks < 2 || disks > 6))
+			return (0);
+		break;
+	case G_RAID_VOLUME_RL_RAID1:
+		if (disks < 1)
+			return (0);
+		if (!force && (disks != 2))
+			return (0);
+		break;
+	case G_RAID_VOLUME_RL_RAID1E:
+		if (disks < 3)
+			return (0);
+		if (!force && (disks != 4))
+			return (0);
+		break;
+	case G_RAID_VOLUME_RL_RAID5:
+		if (disks < 3)
+			return (0);
+		if (!force && disks > 6)
+			return (0);
+		break;
+	default:
+		return (0);
+	}
+	if (qual != G_RAID_VOLUME_RLQ_NONE)
+		return (0);
+	return (1);
+}
+
 static struct g_raid_volume *
 g_raid_md_intel_get_volume(struct g_raid_softc *sc, int id)
 {
@@ -1359,16 +1396,17 @@ g_raid_md_ctl_intel(struct g_raid_md_obj
 			gctl_error(req, "Unknown RAID level '%s'.", levelname);
 			return (-4);
 		}
-		if (level != G_RAID_VOLUME_RL_RAID0 &&
-		    level != G_RAID_VOLUME_RL_RAID1 &&
-		    level != G_RAID_VOLUME_RL_RAID5 &&
-		    level != G_RAID_VOLUME_RL_RAID1E) {
-			gctl_error(req, "Unsupported RAID level.");
+		numdisks = *nargs - 3;
+		force = gctl_get_paraml(req, "force", sizeof(*force));
+		if (!g_raid_md_intel_supported(level, qual, numdisks,
+		    force ? *force : 0)) {
+			gctl_error(req, "Unsupported RAID level "
+			    "(0x%02x/0x%02x), or number of disks (%d).",
+			    level, qual, numdisks);
 			return (-5);
 		}
 
 		/* Search for disks, connect them and probe. */
-		numdisks = *nargs - 3;
 		size = 0x7fffffffffffffffllu;
 		sectorsize = 0;
 		for (i = 0; i < numdisks; i++) {
@@ -1584,13 +1622,6 @@ makedisk:
 			gctl_error(req, "Unknown RAID level '%s'.", levelname);
 			return (-4);
 		}
-		if (level != G_RAID_VOLUME_RL_RAID0 &&
-		    level != G_RAID_VOLUME_RL_RAID1 &&
-		    level != G_RAID_VOLUME_RL_RAID5 &&
-		    level != G_RAID_VOLUME_RL_RAID1E) {
-			gctl_error(req, "Unsupported RAID level.");
-			return (-5);
-		}
 
 		/* Look for existing volumes. */
 		i = 0;
@@ -1608,10 +1639,19 @@ makedisk:
 			return (-7);
 		}
 
+		numdisks = vol1->v_disks_count;
+		force = gctl_get_paraml(req, "force", sizeof(*force));
+		if (!g_raid_md_intel_supported(level, qual, numdisks,
+		    force ? *force : 0)) {
+			gctl_error(req, "Unsupported RAID level "
+			    "(0x%02x/0x%02x), or number of disks (%d).",
+			    level, qual, numdisks);
+			return (-5);
+		}
+
 		/* Collect info about present disks. */
 		size = 0x7fffffffffffffffllu;
 		sectorsize = 512;
-		numdisks = vol1->v_disks_count;
 		for (i = 0; i < numdisks; i++) {
 			disk = vol1->v_subdisks[i].sd_disk;
 			pd = (struct g_raid_md_intel_perdisk *)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102101234.p1ACYRS7022195>