svn commit: r216525 - in projects/graid/head: etc/mtree include sbin/geom/class sbin/geom/class/raid sys/conf sys/geom/raid sys/modules/geom sys/modules/geom/geom_raid

Alexander Motin mav at FreeBSD.org
Sat Dec 18 19:04:21 UTC 2010


Author: mav
Date: Sat Dec 18 19:04:21 2010
New Revision: 216525
URL: http://svn.freebsd.org/changeset/base/216525

Log:
  Initial commit of the geom_raid module, intended to replace ataraid(4)
  at GEOM level. At this moment code is able to read and write existing
  RAID0 and RAID1 Intel MatrixRAID volumes, but not yet able to create
  volumes or do any error handling/recovery/rebuilding/...
  
  Basic design description can be found here:
  http://people.freebsd.org/~mav/graid_design.h
  
  Sponsored by:	Cisco Systems, Inc.

Added:
  projects/graid/head/sbin/geom/class/raid/
  projects/graid/head/sbin/geom/class/raid/Makefile   (contents, props changed)
  projects/graid/head/sbin/geom/class/raid/geom_raid.c   (contents, props changed)
  projects/graid/head/sbin/geom/class/raid/graid.8   (contents, props changed)
  projects/graid/head/sys/geom/raid/
  projects/graid/head/sys/geom/raid/g_raid.c   (contents, props changed)
  projects/graid/head/sys/geom/raid/g_raid.h   (contents, props changed)
  projects/graid/head/sys/geom/raid/g_raid_ctl.c   (contents, props changed)
  projects/graid/head/sys/geom/raid/g_raid_md_if.m   (contents, props changed)
  projects/graid/head/sys/geom/raid/g_raid_tr_if.m   (contents, props changed)
  projects/graid/head/sys/geom/raid/md_intel.c   (contents, props changed)
  projects/graid/head/sys/geom/raid/tr_raid0.c   (contents, props changed)
  projects/graid/head/sys/geom/raid/tr_raid1.c   (contents, props changed)
  projects/graid/head/sys/modules/geom/geom_raid/
  projects/graid/head/sys/modules/geom/geom_raid/Makefile   (contents, props changed)
Modified:
  projects/graid/head/etc/mtree/BSD.include.dist
  projects/graid/head/include/Makefile
  projects/graid/head/sbin/geom/class/Makefile
  projects/graid/head/sys/conf/NOTES
  projects/graid/head/sys/conf/files
  projects/graid/head/sys/conf/options
  projects/graid/head/sys/modules/geom/Makefile

Modified: projects/graid/head/etc/mtree/BSD.include.dist
==============================================================================
--- projects/graid/head/etc/mtree/BSD.include.dist	Sat Dec 18 16:41:11 2010	(r216524)
+++ projects/graid/head/etc/mtree/BSD.include.dist	Sat Dec 18 19:04:21 2010	(r216525)
@@ -188,6 +188,8 @@
         ..
         nop
         ..
+        raid
+        ..
         raid3
         ..
         shsec

Modified: projects/graid/head/include/Makefile
==============================================================================
--- projects/graid/head/include/Makefile	Sat Dec 18 16:41:11 2010	(r216524)
+++ projects/graid/head/include/Makefile	Sat Dec 18 19:04:21 2010	(r216525)
@@ -47,7 +47,7 @@ LSUBDIRS=	cam/ata cam/scsi \
 	${_fs_nwfs} fs/portalfs fs/procfs fs/smbfs fs/udf fs/unionfs \
 	geom/cache geom/concat geom/eli geom/gate geom/journal geom/label \
 	geom/mirror geom/mountver geom/multipath geom/nop \
-	geom/raid3 geom/shsec geom/stripe geom/virstor \
+	geom/raid geom/raid3 geom/shsec geom/stripe geom/virstor \
 	netgraph/atm netgraph/netflow \
 	security/audit \
 	security/mac_biba security/mac_bsdextended security/mac_lomac \

Modified: projects/graid/head/sbin/geom/class/Makefile
==============================================================================
--- projects/graid/head/sbin/geom/class/Makefile	Sat Dec 18 16:41:11 2010	(r216524)
+++ projects/graid/head/sbin/geom/class/Makefile	Sat Dec 18 19:04:21 2010	(r216525)
@@ -14,6 +14,7 @@ SUBDIR+=mountver
 SUBDIR+=multipath
 SUBDIR+=nop
 SUBDIR+=part
+SUBDIR+=raid
 SUBDIR+=raid3
 SUBDIR+=sched
 SUBDIR+=shsec

Added: projects/graid/head/sbin/geom/class/raid/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/graid/head/sbin/geom/class/raid/Makefile	Sat Dec 18 19:04:21 2010	(r216525)
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+.PATH:	${.CURDIR}/../../misc
+
+CLASS=	raid
+
+DPADD=	${LIBMD}
+LDADD=	-lmd
+
+.include <bsd.lib.mk>

Added: projects/graid/head/sbin/geom/class/raid/geom_raid.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/graid/head/sbin/geom/class/raid/geom_raid.c	Sat Dec 18 19:04:21 2010	(r216525)
@@ -0,0 +1,385 @@
+/*-
+ * Copyright (c) 2004-2009 Pawel Jakub Dawidek <pjd at FreeBSD.org>
+ * Copyright (c) 2010 Alexander Motin <mav at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <errno.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <strings.h>
+#include <assert.h>
+#include <libgeom.h>
+#include <geom/raid/g_raid.h>
+#include <core/geom.h>
+#include <misc/subr.h>
+
+uint32_t lib_version = G_LIB_VERSION;
+uint32_t version = G_RAID_VERSION;
+
+#define	GRAID_BALANCE		"load"
+#define	GRAID_SLICE		"4096"
+#define	GRAID_PRIORITY	"0"
+
+static void raid_main(struct gctl_req *req, unsigned flags);
+#if 0
+static void raid_activate(struct gctl_req *req);
+static void raid_clear(struct gctl_req *req);
+static void raid_dump(struct gctl_req *req);
+static void raid_label(struct gctl_req *req);
+#endif
+
+struct g_command class_commands[] = {
+	{ "activate", G_FLAG_VERBOSE, raid_main, G_NULL_OPTS,
+	    "[-v] name prov ..."
+	},
+	{ "clear", G_FLAG_VERBOSE, raid_main, G_NULL_OPTS,
+	    "[-v] prov ..."
+	},
+	{ "configure", G_FLAG_VERBOSE, NULL,
+	    {
+		{ 'a', "autosync", NULL, G_TYPE_BOOL },
+		{ 'b', "balance", "", G_TYPE_STRING },
+		{ 'd', "dynamic", NULL, G_TYPE_BOOL },
+		{ 'f', "failsync", NULL, G_TYPE_BOOL },
+		{ 'F', "nofailsync", NULL, G_TYPE_BOOL },
+		{ 'h', "hardcode", NULL, G_TYPE_BOOL },
+		{ 'n', "noautosync", NULL, G_TYPE_BOOL },
+		{ 'p', "priority", "-1", G_TYPE_NUMBER },
+		{ 's', "slice", "-1", G_TYPE_NUMBER },
+		G_OPT_SENTINEL
+	    },
+	    "[-adfFhnv] [-b balance] [-s slice] name\n"
+	    "[-v] -p priority name prov"
+	},
+	{ "deactivate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
+	    "[-v] name prov ..."
+	},
+	{ "dump", 0, raid_main, G_NULL_OPTS,
+	    "prov ..."
+	},
+	{ "forget", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
+	    "name ..."
+	},
+	{ "label", G_FLAG_VERBOSE, raid_main,
+	    {
+		{ 'b', "balance", GRAID_BALANCE, G_TYPE_STRING },
+		{ 'F', "nofailsync", NULL, G_TYPE_BOOL },
+		{ 'h', "hardcode", NULL, G_TYPE_BOOL },
+		{ 'n', "noautosync", NULL, G_TYPE_BOOL },
+		{ 's', "slice", GRAID_SLICE, G_TYPE_NUMBER },
+		G_OPT_SENTINEL
+	    },
+	    "[-Fhnv] [-b balance] [-s slice] name prov ..."
+	},
+	{ "insert", G_FLAG_VERBOSE, NULL,
+	    {
+		{ 'h', "hardcode", NULL, G_TYPE_BOOL },
+		{ 'i', "inactive", NULL, G_TYPE_BOOL },
+		{ 'p', "priority", GRAID_PRIORITY, G_TYPE_NUMBER },
+		G_OPT_SENTINEL
+	    },
+	    "[-hiv] [-p priority] name prov ..."
+	},
+	{ "rebuild", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
+	    "[-v] name prov ..."
+	},
+	{ "remove", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
+	    "[-v] name prov ..."
+	},
+	{ "stop", G_FLAG_VERBOSE, NULL,
+	    {
+		{ 'f', "force", NULL, G_TYPE_BOOL },
+		G_OPT_SENTINEL
+	    },
+	    "[-fv] name ..."
+	},
+	G_CMD_SENTINEL
+};
+
+static int verbose = 0;
+
+static void
+raid_main(struct gctl_req *req, unsigned flags)
+{
+	const char *name;
+
+	if ((flags & G_FLAG_VERBOSE) != 0)
+		verbose = 1;
+
+	name = gctl_get_ascii(req, "verb");
+	if (name == NULL) {
+		gctl_error(req, "No '%s' argument.", "verb");
+		return;
+	}
+#if 0
+	if (strcmp(name, "label") == 0)
+		raid_label(req);
+	else if (strcmp(name, "clear") == 0)
+		raid_clear(req);
+	else if (strcmp(name, "dump") == 0)
+		raid_dump(req);
+	else if (strcmp(name, "activate") == 0)
+		raid_activate(req);
+	else
+#endif
+		gctl_error(req, "Unknown command: %s.", name);
+}
+
+#if 0
+static void
+raid_label(struct gctl_req *req)
+{
+	struct g_raid_metadata md;
+	u_char sector[512];
+	const char *str;
+	unsigned sectorsize;
+	off_t mediasize;
+	intmax_t val;
+	int error, i, nargs, bal, hardcode;
+
+	nargs = gctl_get_int(req, "nargs");
+	if (nargs < 2) {
+		gctl_error(req, "Too few arguments.");
+		return;
+	}
+
+	strlcpy(md.md_magic, G_RAID_MAGIC, sizeof(md.md_magic));
+	md.md_version = G_RAID_VERSION;
+	str = gctl_get_ascii(req, "arg0");
+	strlcpy(md.md_name, str, sizeof(md.md_name));
+	md.md_mid = arc4random();
+	md.md_all = nargs - 1;
+	md.md_mflags = 0;
+	md.md_dflags = 0;
+	md.md_genid = 0;
+	md.md_syncid = 1;
+	md.md_sync_offset = 0;
+	val = gctl_get_intmax(req, "slice");
+	md.md_slice = val;
+	str = gctl_get_ascii(req, "balance");
+	bal = balance_id(str);
+	if (bal == -1) {
+		gctl_error(req, "Invalid balance algorithm.");
+		return;
+	}
+	md.md_balance = bal;
+	if (gctl_get_int(req, "noautosync"))
+		md.md_mflags |= G_RAID_DEVICE_FLAG_NOAUTOSYNC;
+	if (gctl_get_int(req, "nofailsync"))
+		md.md_mflags |= G_RAID_DEVICE_FLAG_NOFAILSYNC;
+	hardcode = gctl_get_int(req, "hardcode");
+
+	/*
+	 * Calculate sectorsize by finding least common multiple from
+	 * sectorsizes of every disk and find the smallest mediasize.
+	 */
+	mediasize = 0;
+	sectorsize = 0;
+	for (i = 1; i < nargs; i++) {
+		unsigned ssize;
+		off_t msize;
+
+		str = gctl_get_ascii(req, "arg%d", i);
+		msize = g_get_mediasize(str);
+		ssize = g_get_sectorsize(str);
+		if (msize == 0 || ssize == 0) {
+			gctl_error(req, "Can't get informations about %s: %s.",
+			    str, strerror(errno));
+			return;
+		}
+		msize -= ssize;
+		if (mediasize == 0 || (mediasize > 0 && msize < mediasize))
+			mediasize = msize;
+		if (sectorsize == 0)
+			sectorsize = ssize;
+		else
+			sectorsize = g_lcm(sectorsize, ssize);
+	}
+	md.md_mediasize = mediasize;
+	md.md_sectorsize = sectorsize;
+	md.md_mediasize -= (md.md_mediasize % md.md_sectorsize);
+
+	/*
+	 * Clear last sector first, to spoil all components if device exists.
+	 */
+	for (i = 1; i < nargs; i++) {
+		str = gctl_get_ascii(req, "arg%d", i);
+		error = g_metadata_clear(str, NULL);
+		if (error != 0) {
+			gctl_error(req, "Can't store metadata on %s: %s.", str,
+			    strerror(error));
+			return;
+		}
+	}
+
+	/*
+	 * Ok, store metadata (use disk number as priority).
+	 */
+	for (i = 1; i < nargs; i++) {
+		str = gctl_get_ascii(req, "arg%d", i);
+		md.md_did = arc4random();
+		md.md_priority = i - 1;
+		md.md_provsize = g_get_mediasize(str);
+		assert(md.md_provsize != 0);
+		if (!hardcode)
+			bzero(md.md_provider, sizeof(md.md_provider));
+		else {
+			if (strncmp(str, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+				str += sizeof(_PATH_DEV) - 1;
+			strlcpy(md.md_provider, str, sizeof(md.md_provider));
+		}
+		raid_metadata_encode(&md, sector);
+		error = g_metadata_store(str, sector, sizeof(sector));
+		if (error != 0) {
+			fprintf(stderr, "Can't store metadata on %s: %s.\n",
+			    str, strerror(error));
+			gctl_error(req, "Not fully done.");
+			continue;
+		}
+		if (verbose)
+			printf("Metadata value stored on %s.\n", str);
+	}
+}
+
+static void
+raid_clear(struct gctl_req *req)
+{
+	const char *name;
+	int error, i, nargs;
+
+	nargs = gctl_get_int(req, "nargs");
+	if (nargs < 1) {
+		gctl_error(req, "Too few arguments.");
+		return;
+	}
+
+	for (i = 0; i < nargs; i++) {
+		name = gctl_get_ascii(req, "arg%d", i);
+		error = g_metadata_clear(name, G_RAID_MAGIC);
+		if (error != 0) {
+			fprintf(stderr, "Can't clear metadata on %s: %s.\n",
+			    name, strerror(error));
+			gctl_error(req, "Not fully done.");
+			continue;
+		}
+		if (verbose)
+			printf("Metadata cleared on %s.\n", name);
+	}
+}
+
+static void
+raid_dump(struct gctl_req *req)
+{
+	struct g_raid_metadata md, tmpmd;
+	const char *name;
+	int error, i, nargs;
+
+	nargs = gctl_get_int(req, "nargs");
+	if (nargs < 1) {
+		gctl_error(req, "Too few arguments.");
+		return;
+	}
+
+	for (i = 0; i < nargs; i++) {
+		name = gctl_get_ascii(req, "arg%d", i);
+		error = g_metadata_read(name, (u_char *)&tmpmd, sizeof(tmpmd),
+		    G_RAID_MAGIC);
+		if (error != 0) {
+			fprintf(stderr, "Can't read metadata from %s: %s.\n",
+			    name, strerror(error));
+			gctl_error(req, "Not fully done.");
+			continue;
+		}
+		if (raid_metadata_decode((u_char *)&tmpmd, &md) != 0) {
+			fprintf(stderr, "MD5 hash mismatch for %s, skipping.\n",
+			    name);
+			gctl_error(req, "Not fully done.");
+			continue;
+		}
+		printf("Metadata on %s:\n", name);
+		raid_metadata_dump(&md);
+		printf("\n");
+	}
+}
+
+static void
+raid_activate(struct gctl_req *req)
+{
+	struct g_raid_metadata md, tmpmd;
+	const char *name, *path;
+	int error, i, nargs;
+
+	nargs = gctl_get_int(req, "nargs");
+	if (nargs < 2) {
+		gctl_error(req, "Too few arguments.");
+		return;
+	}
+	name = gctl_get_ascii(req, "arg0");
+
+	for (i = 1; i < nargs; i++) {
+		path = gctl_get_ascii(req, "arg%d", i);
+		error = g_metadata_read(path, (u_char *)&tmpmd, sizeof(tmpmd),
+		    G_RAID_MAGIC);
+		if (error != 0) {
+			fprintf(stderr, "Cannot read metadata from %s: %s.\n",
+			    path, strerror(error));
+			gctl_error(req, "Not fully done.");
+			continue;
+		}
+		if (raid_metadata_decode((u_char *)&tmpmd, &md) != 0) {
+			fprintf(stderr,
+			    "MD5 hash mismatch for provider %s, skipping.\n",
+			    path);
+			gctl_error(req, "Not fully done.");
+			continue;
+		}
+		if (strcmp(md.md_name, name) != 0) {
+			fprintf(stderr,
+			    "Provider %s is not the raid %s component.\n",
+			    path, name);
+			gctl_error(req, "Not fully done.");
+			continue;
+		}
+		md.md_dflags &= ~G_RAID_DISK_FLAG_INACTIVE;
+		raid_metadata_encode(&md, (u_char *)&tmpmd);
+		error = g_metadata_store(path, (u_char *)&tmpmd, sizeof(tmpmd));
+		if (error != 0) {
+			fprintf(stderr, "Cannot write metadata from %s: %s.\n",
+			    path, strerror(error));
+			gctl_error(req, "Not fully done.");
+			continue;
+		}
+		if (verbose)
+			printf("Provider %s activated.\n", path);
+	}
+}
+#endif

Added: projects/graid/head/sbin/geom/class/raid/graid.8
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/graid/head/sbin/geom/class/raid/graid.8	Sat Dec 18 19:04:21 2010	(r216525)
@@ -0,0 +1,263 @@
+.\" Copyright (c) 2010 Alexander Motin <mav at FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 18, 2010
+.Dt GRAID 8
+.Os
+.Sh NAME
+.Nm graid
+.Nd "control utility for software RAID devices"
+.Sh SYNOPSIS
+.Nm
+.Cm label
+.Op Fl Fhnv
+.Op Fl b Ar balance
+.Op Fl s Ar slice
+.Ar name
+.Ar prov ...
+.Nm
+.Cm clear
+.Op Fl v
+.Ar prov ...
+.Nm
+.Cm configure
+.Op Fl adfFhnv
+.Op Fl b Ar balance
+.Op Fl s Ar slice
+.Ar name
+.Nm
+.Cm configure
+.Op Fl v
+.Fl p Ar priority
+.Ar name
+.Ar prov
+.Nm
+.Cm rebuild
+.Op Fl v
+.Ar name
+.Ar prov ...
+.Nm
+.Cm insert
+.Op Fl hiv
+.Op Fl p Ar priority
+.Ar name
+.Ar prov ...
+.Nm
+.Cm remove
+.Op Fl v
+.Ar name
+.Ar prov ...
+.Nm
+.Cm activate
+.Op Fl v
+.Ar name
+.Ar prov ...
+.Nm
+.Cm deactivate
+.Op Fl v
+.Ar name
+.Ar prov ...
+.Nm
+.Cm forget
+.Op Fl v
+.Ar name ...
+.Nm
+.Cm stop
+.Op Fl fv
+.Ar name ...
+.Nm
+.Cm dump
+.Ar prov ...
+.Nm
+.Cm list
+.Nm
+.Cm status
+.Nm
+.Cm load
+.Nm
+.Cm unload
+.Sh DESCRIPTION
+The
+.Nm
+utility is used for software RAID configurations.
+After a RAID's creation, all components are detected and configured
+automatically.
+All operations like failure detection, stale component detection, rebuild
+of stale components, etc.\& are also done automatically.
+The
+.Nm
+utility uses on-disk metadata to store all needed information.
+.Pp
+The first argument to
+.Nm
+indicates an action to be performed:
+.Bl -tag -width ".Cm deactivate"
+.It Cm label
+Create a mirror.
+The order of components is important, because a component's priority is based on its position
+(starting from 0 to 255).
+The component with the biggest priority is used by the
+.Cm prefer
+balance algorithm
+and is also used as a master component when resynchronization is needed,
+e.g.\& after a power failure when the device was open for writing.
+.Pp
+Additional options include:
+.Bl -tag -width ".Fl b Ar balance"
+.It Fl b Ar balance
+Specifies balance algorithm to use, one of:
+.Bl -tag -width ".Cm round-robin"
+.It Cm load
+Read from the component with the lowest load.
+This is the default balance algorithm.
+.It Cm prefer
+Read from the component with the biggest priority.
+.It Cm round-robin
+Use round-robin algorithm when choosing component to read.
+.It Cm split
+Split read requests, which are bigger than or equal to slice size on N pieces,
+where N is the number of active components.
+.El
+.It Fl F
+Do not synchronize after a power failure or system crash.
+Assumes device is in consistent state.
+.It Fl h
+Hardcode providers' names in metadata.
+.It Fl n
+Turn off autosynchronization of stale components.
+.It Fl s Ar slice
+When using the
+.Cm split
+balance algorithm and an I/O READ request is bigger than or equal to this value,
+the I/O request will be split into N pieces, where N is the number of active
+components.
+Defaults to 4096 bytes.
+.El
+.It Cm clear
+Clear metadata on the given providers.
+.It Cm configure
+Configure the given device.
+.Pp
+Additional options include:
+.Bl -tag -width ".Fl p Ar priority"
+.It Fl a
+Turn on autosynchronization of stale components.
+.It Fl b Ar balance
+Specifies balance algorithm to use.
+.It Fl d
+Do not hardcode providers' names in metadata.
+.It Fl f
+Synchronize device after a power failure or system crash.
+.It Fl F
+Do not synchronize after a power failure or system crash.
+Assumes device is in consistent state.
+.It Fl h
+Hardcode providers' names in metadata.
+.It Fl n
+Turn off autosynchronization of stale components.
+.It Fl p Ar priority
+Specifies priority for the given component
+.Ar prov .
+.It Fl s Ar slice
+Specifies slice size for
+.Cm split
+balance algorithm.
+.El
+.It Cm rebuild
+Rebuild the given mirror components forcibly.
+If autosynchronization was not turned off for the given device, this command
+should be unnecessary.
+.It Cm insert
+Add the given component(s) to the existing mirror.
+.Pp
+Additional options include:
+.Bl -tag -width ".Fl p Ar priority"
+.It Fl h
+Hardcode providers' names in metadata.
+.It Fl i
+Mark component(s) as inactive immediately after insertion.
+.It Fl p Ar priority
+Specifies priority of the given component(s).
+.El
+.It Cm remove
+Remove the given component(s) from the mirror and clear metadata on it.
+.It Cm activate
+Activate the given component(s), which were marked as inactive before.
+.It Cm deactivate
+Mark the given component(s) as inactive, so it will not be automatically
+connected to the mirror.
+.It Cm forget
+Forget about components which are not connected.
+This command is useful when a disk has failed and cannot be reconnected, preventing the
+.Cm remove
+command from being used to remove it.
+.It Cm stop
+Stop the given mirror.
+.Pp
+Additional options include:
+.Bl -tag -width ".Fl f"
+.It Fl f
+Stop the given mirror even if it is opened.
+.El
+.It Cm dump
+Dump metadata stored on the given providers.
+.It Cm list
+See
+.Xr geom 8 .
+.It Cm status
+See
+.Xr geom 8 .
+.It Cm load
+See
+.Xr geom 8 .
+.It Cm unload
+See
+.Xr geom 8 .
+.El
+.Pp
+Additional options include:
+.Bl -tag -width ".Fl v"
+.It Fl v
+Be more verbose.
+.El
+.Sh EXIT STATUS
+Exit status is 0 on success, and 1 if the command fails.
+.Sh SEE ALSO
+.Xr geom 4 ,
+.Xr dumpon 8 ,
+.Xr geom 8 ,
+.Xr mount 8 ,
+.Xr newfs 8 ,
+.Xr savecore 8 ,
+.Xr umount 8 ,
+.Xr vinum 8
+.Sh HISTORY
+The
+.Nm
+utility appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+.An Alexander Motin Aq mav at FreeBSD.org

Modified: projects/graid/head/sys/conf/NOTES
==============================================================================
--- projects/graid/head/sys/conf/NOTES	Sat Dec 18 16:41:11 2010	(r216524)
+++ projects/graid/head/sys/conf/NOTES	Sat Dec 18 19:04:21 2010	(r216525)
@@ -163,6 +163,7 @@ options 	GEOM_PART_MBR		# MBR partitioni
 options 	GEOM_PART_PC98		# PC-9800 disk partitioning
 options 	GEOM_PART_VTOC8		# SMI VTOC8 disk label
 options 	GEOM_PC98		# NEC PC9800 partitioning
+options 	GEOM_RAID		# Soft RAID functionality.
 options 	GEOM_RAID3		# RAID3 functionality.
 options 	GEOM_SHSEC		# Shared secret.
 options 	GEOM_STRIPE		# Disk striping.

Modified: projects/graid/head/sys/conf/files
==============================================================================
--- projects/graid/head/sys/conf/files	Sat Dec 18 16:41:11 2010	(r216524)
+++ projects/graid/head/sys/conf/files	Sat Dec 18 19:04:21 2010	(r216525)
@@ -2067,6 +2067,13 @@ geom/part/g_part_gpt.c		optional geom_pa
 geom/part/g_part_mbr.c		optional geom_part_mbr
 geom/part/g_part_pc98.c		optional geom_part_pc98
 geom/part/g_part_vtoc8.c	optional geom_part_vtoc8
+geom/raid/g_raid.c		optional geom_raid
+geom/raid/g_raid_ctl.c		optional geom_raid
+geom/raid/g_raid_md_if.m	optional geom_raid
+geom/raid/g_raid_tr_if.m	optional geom_raid
+geom/raid/md_intel.c		optional geom_raid
+geom/raid/tr_raid0.c		optional geom_raid
+geom/raid/tr_raid1.c		optional geom_raid
 geom/raid3/g_raid3.c		optional geom_raid3
 geom/raid3/g_raid3_ctl.c	optional geom_raid3
 geom/shsec/g_shsec.c		optional geom_shsec

Modified: projects/graid/head/sys/conf/options
==============================================================================
--- projects/graid/head/sys/conf/options	Sat Dec 18 16:41:11 2010	(r216524)
+++ projects/graid/head/sys/conf/options	Sat Dec 18 19:04:21 2010	(r216525)
@@ -101,6 +101,7 @@ GEOM_PART_MBR	opt_geom.h
 GEOM_PART_PC98	opt_geom.h
 GEOM_PART_VTOC8	opt_geom.h
 GEOM_PC98	opt_geom.h
+GEOM_RAID	opt_geom.h
 GEOM_RAID3	opt_geom.h
 GEOM_SHSEC	opt_geom.h
 GEOM_STRIPE	opt_geom.h

Added: projects/graid/head/sys/geom/raid/g_raid.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/graid/head/sys/geom/raid/g_raid.c	Sat Dec 18 19:04:21 2010	(r216525)
@@ -0,0 +1,1656 @@
+/*-
+ * Copyright (c) 2010 Alexander Motin <mav at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/bio.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/eventhandler.h>
+#include <vm/uma.h>
+#include <geom/geom.h>
+#include <sys/proc.h>
+#include <sys/kthread.h>
+#include <sys/sched.h>
+#include <geom/raid/g_raid.h>
+#include "g_raid_md_if.h"
+#include "g_raid_tr_if.h"
+
+static MALLOC_DEFINE(M_RAID, "raid_data", "GEOM_RAID Data");
+
+SYSCTL_DECL(_kern_geom);
+SYSCTL_NODE(_kern_geom, OID_AUTO, raid, CTLFLAG_RW, 0, "GEOM_RAID stuff");
+u_int g_raid_debug = 1000;
+TUNABLE_INT("kern.geom.raid.debug", &g_raid_debug);
+SYSCTL_UINT(_kern_geom_raid, OID_AUTO, debug, CTLFLAG_RW, &g_raid_debug, 0,
+    "Debug level");
+static u_int g_raid_start_timeout = 4;
+TUNABLE_INT("kern.geom.raid.start_timeout", &g_raid_start_timeout);
+SYSCTL_UINT(_kern_geom_raid, OID_AUTO, timeout, CTLFLAG_RW, &g_raid_start_timeout,
+    0, "Time to wait on all mirror components");
+static u_int g_raid_idletime = 5;
+TUNABLE_INT("kern.geom.raid.idletime", &g_raid_idletime);
+SYSCTL_UINT(_kern_geom_raid, OID_AUTO, idletime, CTLFLAG_RW,
+    &g_raid_idletime, 0, "Mark components as clean when idling");
+static u_int g_raid_disconnect_on_failure = 1;
+TUNABLE_INT("kern.geom.raid.disconnect_on_failure",
+    &g_raid_disconnect_on_failure);
+SYSCTL_UINT(_kern_geom_raid, OID_AUTO, disconnect_on_failure, CTLFLAG_RW,
+    &g_raid_disconnect_on_failure, 0, "Disconnect component on I/O failure.");
+
+#define	MSLEEP(ident, mtx, priority, wmesg, timeout)	do {		\
+	G_RAID_DEBUG(4, "%s: Sleeping %p.", __func__, (ident));		\
+	msleep((ident), (mtx), (priority), (wmesg), (timeout));		\
+	G_RAID_DEBUG(4, "%s: Woken up %p.", __func__, (ident));		\
+} while (0)
+
+LIST_HEAD(, g_raid_md_class) g_raid_md_classes =
+    LIST_HEAD_INITIALIZER(g_raid_md_classes);
+
+LIST_HEAD(, g_raid_tr_class) g_raid_tr_classes =
+    LIST_HEAD_INITIALIZER(g_raid_tr_classes);
+
+//static eventhandler_tag g_raid_pre_sync = NULL;
+
+static int g_raid_destroy_geom(struct gctl_req *req, struct g_class *mp,
+    struct g_geom *gp);
+static g_taste_t g_raid_taste;
+static void g_raid_init(struct g_class *mp);
+static void g_raid_fini(struct g_class *mp);
+
+struct g_class g_raid_class = {
+	.name = G_RAID_CLASS_NAME,
+	.version = G_VERSION,
+	.ctlreq = g_raid_config,
+	.taste = g_raid_taste,
+	.destroy_geom = g_raid_destroy_geom,
+	.init = g_raid_init,
+	.fini = g_raid_fini
+};
+
+
+static void g_raid_destroy_provider(struct g_raid_volume *vol);
+static int g_raid_update_disk(struct g_raid_disk *disk, u_int state);
+static int g_raid_update_subdisk(struct g_raid_subdisk *subdisk, u_int state);
+static int g_raid_update_volume(struct g_raid_volume *vol, u_int state);
+static void g_raid_dumpconf(struct sbuf *sb, const char *indent,
+    struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp);
+static void g_raid_start_request(struct bio *bp);
+static void g_raid_disk_done(struct bio *bp);
+
+static const char *
+g_raid_disk_state2str(int state)
+{
+
+	switch (state) {
+	case G_RAID_DISK_S_NONE:
+		return ("NONE");
+	case G_RAID_DISK_S_ACTIVE:
+		return ("ACTIVE");
+	case G_RAID_DISK_S_SPARE:
+		return ("SPARE");
+	case G_RAID_DISK_S_OFFLINE:
+		return ("OFFLINE");
+	default:
+		return ("INVALID");
+	}
+}
+
+static const char *
+g_raid_disk_event2str(int event)
+{
+
+	switch (event) {
+	case G_RAID_DISK_E_DISCONNECTED:
+		return ("DISCONNECTED");
+	default:
+		return ("INVALID");
+	}
+}
+
+static const char *
+g_raid_subdisk_state2str(int state)
+{
+
+	switch (state) {
+	case G_RAID_SUBDISK_S_NONE:
+		return ("NONE");
+	case G_RAID_SUBDISK_S_NEW:
+		return ("NEW");
+	case G_RAID_SUBDISK_S_ACTIVE:
+		return ("ACTIVE");
+	case G_RAID_SUBDISK_S_STALE:
+		return ("STALE");
+	case G_RAID_SUBDISK_S_SYNCHRONIZING:
+		return ("SYNCHRONIZING");
+	case G_RAID_SUBDISK_S_DISCONNECTED:
+		return ("DISCONNECTED");
+	case G_RAID_SUBDISK_S_DESTROY:
+		return ("DESTROY");
+	default:
+		return ("INVALID");
+	}
+}
+
+static const char *
+g_raid_subdisk_event2str(int event)
+{
+
+	switch (event) {
+	case G_RAID_SUBDISK_E_NEW:
+		return ("NEW");
+	case G_RAID_SUBDISK_E_DISCONNECTED:
+		return ("DISCONNECTED");
+	default:
+		return ("INVALID");
+	}
+}
+
+static const char *
+g_raid_volume_state2str(int state)
+{
+
+	switch (state) {
+	case G_RAID_VOLUME_S_STARTING:
+		return ("STARTING");
+	case G_RAID_VOLUME_S_BROKEN:
+		return ("BROKEN");
+	case G_RAID_VOLUME_S_DEGRADED:
+		return ("DEGRADED");
+	case G_RAID_VOLUME_S_SUBOPTIMAL:
+		return ("SUBOPTIMAL");
+	case G_RAID_VOLUME_S_OPTIMAL:
+		return ("OPTIMAL");
+	case G_RAID_VOLUME_S_UNSUPPORTED:
+		return ("UNSUPPORTED");
+	case G_RAID_VOLUME_S_STOPPED:
+		return ("STOPPED");
+	default:
+		return ("INVALID");
+	}
+}
+
+static const char *
+g_raid_volume_event2str(int event)
+{
+
+	switch (event) {
+	case G_RAID_VOLUME_E_UP:
+		return ("UP");
+	case G_RAID_VOLUME_E_DOWN:
+		return ("DOWN");
+	case G_RAID_VOLUME_E_START:
+		return ("START");
+	default:
+		return ("INVALID");
+	}
+}
+
+static const char *
+g_raid_volume_level2str(int level, int qual)
+{
+
+	switch (level) {
+	case G_RAID_VOLUME_RL_RAID0:
+		return ("RAID0");
+	case G_RAID_VOLUME_RL_RAID1:
+		return ("RAID1");
+	case G_RAID_VOLUME_RL_RAID3:
+		return ("RAID3");
+	case G_RAID_VOLUME_RL_RAID4:
+		return ("RAID4");
+	case G_RAID_VOLUME_RL_RAID5:
+		return ("RAID5");
+	case G_RAID_VOLUME_RL_RAID6:
+		return ("RAID6");
+	case G_RAID_VOLUME_RL_RAID10:
+		return ("RAID10");
+	case G_RAID_VOLUME_RL_RAID1E:
+		return ("RAID1E");
+	case G_RAID_VOLUME_RL_SINGLE:
+		return ("SINGLE");
+	case G_RAID_VOLUME_RL_CONCAT:
+		return ("CONCAT");
+	case G_RAID_VOLUME_RL_RAID5E:
+		return ("RAID5E");
+	case G_RAID_VOLUME_RL_RAID5EE:
+		return ("RAID5EE");
+	default:
+		return ("UNKNOWN");
+	}
+}
+
+static const char *
+g_raid_get_diskname(struct g_raid_disk *disk)
+{
+
+	if (disk->d_consumer == NULL || disk->d_consumer->provider == NULL)
+		return ("[unknown]");
+	return (disk->d_consumer->provider->name);
+}
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list