Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Dec 2010 16:33:40 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r216666 - in projects/graid/head: sbin/geom/class/raid sys/geom/raid
Message-ID:  <201012221633.oBMGXelm026819@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Wed Dec 22 16:33:40 2010
New Revision: 216666
URL: http://svn.freebsd.org/changeset/base/216666

Log:
  Implement `graid stop`, and common part of `graid label`. Pass "label"
  and all further commands to metadata module via special method call.

Modified:
  projects/graid/head/sbin/geom/class/raid/geom_raid.c
  projects/graid/head/sys/geom/raid/g_raid.c
  projects/graid/head/sys/geom/raid/g_raid.h
  projects/graid/head/sys/geom/raid/g_raid_ctl.c
  projects/graid/head/sys/geom/raid/g_raid_md_if.m
  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	Wed Dec 22 15:44:25 2010	(r216665)
+++ projects/graid/head/sbin/geom/class/raid/geom_raid.c	Wed Dec 22 16:33:40 2010	(r216666)
@@ -49,71 +49,11 @@ uint32_t version = G_RAID_VERSION;
 #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
+//static void raid_main(struct gctl_req *req, unsigned flags);
 
 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 ..."
+	{ "label", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
+	    "format name level prov ..."
 	},
 	{ "stop", G_FLAG_VERBOSE, NULL,
 	    {
@@ -125,6 +65,7 @@ struct g_command class_commands[] = {
 	G_CMD_SENTINEL
 };
 
+#if 0
 static int verbose = 0;
 
 static void
@@ -140,7 +81,6 @@ raid_main(struct gctl_req *req, unsigned
 		gctl_error(req, "No '%s' argument.", "verb");
 		return;
 	}
-#if 0
 	if (strcmp(name, "label") == 0)
 		raid_label(req);
 	else if (strcmp(name, "clear") == 0)
@@ -150,236 +90,7 @@ raid_main(struct gctl_req *req, unsigned
 	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
+

Modified: projects/graid/head/sys/geom/raid/g_raid.c
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid.c	Wed Dec 22 15:44:25 2010	(r216665)
+++ projects/graid/head/sys/geom/raid/g_raid.c	Wed Dec 22 16:33:40 2010	(r216666)
@@ -92,7 +92,7 @@ static void g_raid_fini(struct g_class *
 struct g_class g_raid_class = {
 	.name = G_RAID_CLASS_NAME,
 	.version = G_VERSION,
-	.ctlreq = g_raid_config,
+	.ctlreq = g_raid_ctl,
 	.taste = g_raid_taste,
 	.destroy_geom = g_raid_destroy_geom,
 	.init = g_raid_init,
@@ -219,7 +219,7 @@ g_raid_volume_event2str(int event)
 	}
 }
 
-static const char *
+const char *
 g_raid_volume_level2str(int level, int qual)
 {
 
@@ -253,6 +253,41 @@ g_raid_volume_level2str(int level, int q
 	}
 }
 
+int
+g_raid_volume_str2level(const char *str, int *level, int *qual)
+{
+
+	*level = G_RAID_VOLUME_RL_UNKNOWN;
+	*qual = G_RAID_VOLUME_RLQ_NONE;
+	if (strcasecmp(str, "RAID0") == 0)
+		*level = G_RAID_VOLUME_RL_RAID0;
+	else if (strcasecmp(str, "RAID1") == 0)
+		*level = G_RAID_VOLUME_RL_RAID1;
+	else if (strcasecmp(str, "RAID3") == 0)
+		*level = G_RAID_VOLUME_RL_RAID3;
+	else if (strcasecmp(str, "RAID4") == 0)
+		*level = G_RAID_VOLUME_RL_RAID4;
+	else if (strcasecmp(str, "RAID5") == 0)
+		*level = G_RAID_VOLUME_RL_RAID5;
+	else if (strcasecmp(str, "RAID6") == 0)
+		*level = G_RAID_VOLUME_RL_RAID6;
+	else if (strcasecmp(str, "RAID10") == 0)
+		*level = G_RAID_VOLUME_RL_RAID10;
+	else if (strcasecmp(str, "RAID1E") == 0)
+		*level = G_RAID_VOLUME_RL_RAID1E;
+	else if (strcasecmp(str, "SINGLE") == 0)
+		*level = G_RAID_VOLUME_RL_SINGLE;
+	else if (strcasecmp(str, "CONCAT") == 0)
+		*level = G_RAID_VOLUME_RL_CONCAT;
+	else if (strcasecmp(str, "RAID5E") == 0)
+		*level = G_RAID_VOLUME_RL_RAID5E;
+	else if (strcasecmp(str, "RAID5EE") == 0)
+		*level = G_RAID_VOLUME_RL_RAID5EE;
+	else
+		return (0);
+	return (1);
+}
+
 static const char *
 g_raid_get_diskname(struct g_raid_disk *disk)
 {
@@ -1233,12 +1268,15 @@ g_raid_destroy_node(struct g_raid_softc 
 		kobj_delete((kobj_t)sc->sc_md, M_RAID);
 		sc->sc_md = NULL;
 	}
-	G_RAID_DEBUG(1, "Destroying node %s.", sc->sc_name);
-	g_topology_lock();
-	sc->sc_geom->softc = NULL;
-	g_wither_geom(sc->sc_geom, ENXIO);
-	g_topology_unlock();
-	sc->sc_geom = NULL;
+	if (sc->sc_geom != NULL) {
+		G_RAID_DEBUG(1, "Destroying node %s.", sc->sc_name);
+		g_topology_lock();
+		sc->sc_geom->softc = NULL;
+		g_wither_geom(sc->sc_geom, ENXIO);
+		g_topology_unlock();
+		sc->sc_geom = NULL;
+	} else
+		G_RAID_DEBUG(1, "Destroying node.");
 	if (worker) {
 		mtx_destroy(&sc->sc_queue_mtx);
 		sx_xunlock(&sc->sc_lock);
@@ -1423,6 +1461,31 @@ g_raid_taste(struct g_class *mp, struct 
 	return (geom);
 }
 
+int
+g_raid_create_node_format(const char *format, struct g_geom **gp)
+{
+	struct g_raid_md_class *class;
+	struct g_raid_md_object *obj;
+	int status;
+
+	G_RAID_DEBUG(2, "Creating node for %s metadata.", format);
+	LIST_FOREACH(class, &g_raid_md_classes, mdc_list) {
+		if (strcasecmp(class->name, format) == 0)
+			break;
+	}
+	if (class == NULL) {
+		G_RAID_DEBUG(2, "Creating node for %s metadata.", format);
+		return (G_RAID_MD_TASTE_FAIL);
+	}
+	obj = (void *)kobj_create((kobj_class_t)class, M_RAID,
+	    M_WAITOK);
+	obj->mdo_class = class;
+	status = G_RAID_MD_CREATE(obj, &g_raid_class, gp);
+	if (status != G_RAID_MD_TASTE_NEW)
+		kobj_delete((kobj_t)obj, M_RAID);
+	return (status);
+}
+
 static int
 g_raid_destroy_geom(struct gctl_req *req __unused,
     struct g_class *mp __unused, struct g_geom *gp)

Modified: projects/graid/head/sys/geom/raid/g_raid.h
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid.h	Wed Dec 22 15:44:25 2010	(r216665)
+++ projects/graid/head/sys/geom/raid/g_raid.h	Wed Dec 22 16:33:40 2010	(r216666)
@@ -278,8 +278,12 @@ int g_raid_tr_modevent(module_t, int, vo
     };								\
     DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_ANY)
 
+const char * g_raid_volume_level2str(int level, int qual);
+int g_raid_volume_str2level(const char *str, int *level, int *qual);
+
 struct g_raid_softc * g_raid_create_node(struct g_class *mp,
     const char *name, struct g_raid_md_object *md);
+int g_raid_create_node_format(const char *format, struct g_geom **gp);
 struct g_raid_volume * g_raid_create_volume(struct g_raid_softc *sc,
     const char *name);
 struct g_raid_disk * g_raid_create_disk(struct g_raid_softc *sc);
@@ -307,7 +311,7 @@ u_int g_raid_nsubdisks(struct g_raid_vol
 int g_raid_destroy(struct g_raid_softc *sc, int how);
 int g_raid_event_send(void *arg, int event, int flags);
 
-g_ctl_req_t g_raid_config;
+g_ctl_req_t g_raid_ctl;
 #endif	/* _KERNEL */
 
 #endif	/* !_G_RAID_H_ */

Modified: projects/graid/head/sys/geom/raid/g_raid_ctl.c
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid_ctl.c	Wed Dec 22 15:44:25 2010	(r216665)
+++ projects/graid/head/sys/geom/raid/g_raid_ctl.c	Wed Dec 22 16:33:40 2010	(r216666)
@@ -43,547 +43,149 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/kthread.h>
 #include <geom/raid/g_raid.h>
+#include "g_raid_md_if.h"
 
 
-#if 0
 static struct g_raid_softc *
-g_raid_find_device(struct g_class *mp, const char *name)
+g_raid_find_node(struct g_class *mp, const char *name)
 {
 	struct g_raid_softc *sc;
 	struct g_geom *gp;
 
-	g_topology_lock();
 	LIST_FOREACH(gp, &mp->geom, geom) {
 		sc = gp->softc;
 		if (sc == NULL)
 			continue;
 		if (sc->sc_stopping != 0)
 			continue;
-		if (strcmp(gp->name, name) == 0 ||
-		    strcmp(sc->sc_name, name) == 0) {
-			g_topology_unlock();
-			sx_xlock(&sc->sc_lock);
+		if (strcasecmp(sc->sc_name, name) == 0)
 			return (sc);
-		}
-	}
-	g_topology_unlock();
-	return (NULL);
-}
-
-static struct g_raid_disk *
-g_raid_find_disk(struct g_raid_softc *sc, const char *name)
-{
-	struct g_raid_disk *disk;
-
-	sx_assert(&sc->sc_lock, SX_XLOCKED);
-	if (strncmp(name, "/dev/", 5) == 0)
-		name += 5;
-	LIST_FOREACH(disk, &sc->sc_disks, d_next) {
-		if (disk->d_consumer == NULL)
-			continue;
-		if (disk->d_consumer->provider == NULL)
-			continue;
-		if (strcmp(disk->d_consumer->provider->name, name) == 0)
-			return (disk);
 	}
 	return (NULL);
 }
 
 static void
-g_raid_ctl_configure(struct gctl_req *req, struct g_class *mp)
+g_raid_ctl_label(struct gctl_req *req, struct g_class *mp)
 {
+	struct g_geom *geom;
 	struct g_raid_softc *sc;
-	struct g_raid_disk *disk;
-	const char *name, *balancep, *prov;
-	intmax_t *slicep, *priority;
-	uint32_t slice;
-	uint8_t balance;
-	int *autosync, *noautosync, *failsync, *nofailsync, *hardcode, *dynamic;
-	int *nargs, do_sync = 0, dirty = 1, do_priority = 0;
+	const char *format;
+	int *nargs;
+	int crstatus, ctlstatus;
 
 	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
 	if (nargs == NULL) {
 		gctl_error(req, "No '%s' argument.", "nargs");
 		return;
 	}
-	if (*nargs != 1 && *nargs != 2) {
-		gctl_error(req, "Invalid number of arguments.");
-		return;
-	}
-	name = gctl_get_asciiparam(req, "arg0");
-	if (name == NULL) {
-		gctl_error(req, "No 'arg%u' argument.", 0);
-		return;
-	}
-	balancep = gctl_get_asciiparam(req, "balance");
-	if (balancep == NULL) {
-		gctl_error(req, "No '%s' argument.", "balance");
-		return;
-	}
-	autosync = gctl_get_paraml(req, "autosync", sizeof(*autosync));
-	if (autosync == NULL) {
-		gctl_error(req, "No '%s' argument.", "autosync");
-		return;
-	}
-	noautosync = gctl_get_paraml(req, "noautosync", sizeof(*noautosync));
-	if (noautosync == NULL) {
-		gctl_error(req, "No '%s' argument.", "noautosync");
-		return;
-	}
-	failsync = gctl_get_paraml(req, "failsync", sizeof(*failsync));
-	if (failsync == NULL) {
-		gctl_error(req, "No '%s' argument.", "failsync");
-		return;
-	}
-	nofailsync = gctl_get_paraml(req, "nofailsync", sizeof(*nofailsync));
-	if (nofailsync == NULL) {
-		gctl_error(req, "No '%s' argument.", "nofailsync");
-		return;
-	}
-	hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
-	if (hardcode == NULL) {
-		gctl_error(req, "No '%s' argument.", "hardcode");
-		return;
-	}
-	dynamic = gctl_get_paraml(req, "dynamic", sizeof(*dynamic));
-	if (dynamic == NULL) {
-		gctl_error(req, "No '%s' argument.", "dynamic");
-		return;
-	}
-	priority = gctl_get_paraml(req, "priority", sizeof(*priority));
-	if (priority == NULL) {
-		gctl_error(req, "No '%s' argument.", "priority");
-		return;
-	}
-	if (*priority < -1 || *priority > 255) {
-		gctl_error(req, "Priority range is 0 to 255, %jd given",
-		    *priority);
-		return;
-	}
-	/* 
-	 * Since we have a priority, we also need a provider now.
-	 * Note: be WARNS safe, by always assigning prov and only throw an
-	 * error if *priority != -1.
-	 */
-	prov = gctl_get_asciiparam(req, "arg1");
-	if (*priority > -1) {
-		if (prov == NULL) {
-			gctl_error(req, "Priority needs a disk name");
-			return;
-		}
-		do_priority = 1;
-	}
-	if (*autosync && *noautosync) {
-		gctl_error(req, "'%s' and '%s' specified.", "autosync",
-		    "noautosync");
-		return;
-	}
-	if (*failsync && *nofailsync) {
-		gctl_error(req, "'%s' and '%s' specified.", "failsync",
-		    "nofailsync");
-		return;
-	}
-	if (*hardcode && *dynamic) {
-		gctl_error(req, "'%s' and '%s' specified.", "hardcode",
-		    "dynamic");
-		return;
-	}
-	sc = g_raid_find_device(mp, name);
-	if (sc == NULL) {
-		gctl_error(req, "No such device: %s.", name);
-		return;
-	}
-	if (*balancep == '\0')
-		balance = sc->sc_balance;
-	else {
-		if (balance_id(balancep) == -1) {
-			gctl_error(req, "Invalid balance algorithm.");
-			sx_xunlock(&sc->sc_lock);
-			return;
-		}
-		balance = balance_id(balancep);
-	}
-	slicep = gctl_get_paraml(req, "slice", sizeof(*slicep));
-	if (slicep == NULL) {
-		gctl_error(req, "No '%s' argument.", "slice");
-		sx_xunlock(&sc->sc_lock);
-		return;
-	}
-	if (*slicep == -1)
-		slice = sc->sc_slice;
-	else
-		slice = *slicep;
-	/* Enforce usage() of -p not allowing any other options. */
-	if (do_priority && (*autosync || *noautosync || *failsync ||
-	    *nofailsync || *hardcode || *dynamic || *slicep != -1 ||
-	    *balancep != '\0')) {
-		sx_xunlock(&sc->sc_lock);
-		gctl_error(req, "only -p accepted when setting priority");
-		return;
-	}
-	if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync &&
-	    !*noautosync && !*failsync && !*nofailsync && !*hardcode &&
-	    !*dynamic && !do_priority) {
-		sx_xunlock(&sc->sc_lock);
-		gctl_error(req, "Nothing has changed.");
-		return;
-	}
-	if ((!do_priority && *nargs != 1) || (do_priority && *nargs != 2)) {
-		sx_xunlock(&sc->sc_lock);
+	if (*nargs < 4) {
 		gctl_error(req, "Invalid number of arguments.");
 		return;
 	}
-	if (g_raid_ndisks(sc, -1) < sc->sc_ndisks) {
-		sx_xunlock(&sc->sc_lock);
-		gctl_error(req, "Not all disks connected. Try 'forget' command "
-		    "first.");
-		return;
-	}
-	sc->sc_balance = balance;
-	sc->sc_slice = slice;
-	if ((sc->sc_flags & G_RAID_DEVICE_FLAG_NOAUTOSYNC) != 0) {
-		if (*autosync) {
-			sc->sc_flags &= ~G_RAID_DEVICE_FLAG_NOAUTOSYNC;
-			do_sync = 1;
-		}
-	} else {
-		if (*noautosync)
-			sc->sc_flags |= G_RAID_DEVICE_FLAG_NOAUTOSYNC;
-	}
-	if ((sc->sc_flags & G_RAID_DEVICE_FLAG_NOFAILSYNC) != 0) {
-		if (*failsync)
-			sc->sc_flags &= ~G_RAID_DEVICE_FLAG_NOFAILSYNC;
-	} else {
-		if (*nofailsync) {
-			sc->sc_flags |= G_RAID_DEVICE_FLAG_NOFAILSYNC;
-			dirty = 0;
-		}
-	}
-	LIST_FOREACH(disk, &sc->sc_disks, d_next) {
-		/*
-		 * Handle priority first, since we only need one disk, do one
-		 * operation on it and then we're done. No need to check other
-		 * flags, as usage doesn't allow it.
-		 */
-		if (do_priority) {
-			if (strcmp(disk->d_consumer->provider->name, prov) == 0) {
-				if (disk->d_priority == *priority)
-					gctl_error(req, "Nothing has changed.");
-				else {
-					disk->d_priority = *priority;
-					g_raid_update_metadata(disk);
-				}
-				break;
-			}
-			continue;
-		}
-		if (do_sync) {
-			if (disk->d_state == G_RAID_DISK_STATE_SYNCHRONIZING)
-				disk->d_flags &= ~G_RAID_DISK_FLAG_FORCE_SYNC;
-		}
-		if (!dirty)
-			disk->d_flags &= ~G_RAID_DISK_FLAG_DIRTY;
-		g_raid_update_metadata(disk);
-		if (do_sync) {
-			if (disk->d_state == G_RAID_DISK_STATE_STALE) {
-				g_raid_event_send(disk,
-				    G_RAID_DISK_STATE_DISCONNECTED,
-				    G_RAID_EVENT_DISK);
-			}
-		}
-	}
-	sx_xunlock(&sc->sc_lock);
-}
-
-static void
-g_raid_ctl_rebuild(struct gctl_req *req, struct g_class *mp)
-{
-	struct g_raid_metadata md;
-	struct g_raid_softc *sc;
-	struct g_raid_disk *disk;
-	struct g_provider *pp;
-	const char *name;
-	char param[16];
-	int error, *nargs;
-	u_int i;
-
-	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
-	if (nargs == NULL) {
-		gctl_error(req, "No '%s' argument.", "nargs");
-		return;
-	}
-	if (*nargs < 2) {
-		gctl_error(req, "Too few arguments.");
-		return;
-	}
-	name = gctl_get_asciiparam(req, "arg0");
-	if (name == NULL) {
-		gctl_error(req, "No 'arg%u' argument.", 0);
+	format = gctl_get_asciiparam(req, "arg0");
+	if (format == NULL) {
+		gctl_error(req, "No format recieved.");
 		return;
 	}
-	sc = g_raid_find_device(mp, name);
-	if (sc == NULL) {
-		gctl_error(req, "No such device: %s.", name);
+	crstatus = g_raid_create_node_format(format, &geom);
+	if (crstatus == G_RAID_MD_TASTE_FAIL) {
+		gctl_error(req, "Failed to create node with format '%s'.",
+		    format);
 		return;
 	}
-	for (i = 1; i < (u_int)*nargs; i++) {
-		snprintf(param, sizeof(param), "arg%u", i);
-		name = gctl_get_asciiparam(req, param);
-		if (name == NULL) {
-			gctl_error(req, "No 'arg%u' argument.", i);
-			continue;
-		}
-		disk = g_raid_find_disk(sc, name);
-		if (disk == NULL) {
-			gctl_error(req, "No such provider: %s.", name);
-			continue;
-		}
-		if (g_raid_ndisks(sc, G_RAID_DISK_STATE_ACTIVE) == 1 &&
-		    disk->d_state == G_RAID_DISK_STATE_ACTIVE) {
-			/*
-			 * This is the last active disk. There will be nothing
-			 * to rebuild it from, so deny this request.
-			 */
-			gctl_error(req,
-			    "Provider %s is the last active provider in %s.",
-			    name, sc->sc_geom->name);
-			break;
-		}
-		/*
-		 * Do rebuild by resetting syncid, disconnecting the disk and
-		 * connecting it again.
-		 */
-		if ((sc->sc_flags & G_RAID_DEVICE_FLAG_NOAUTOSYNC) != 0)
-			disk->d_flags |= G_RAID_DISK_FLAG_FORCE_SYNC;
-		g_raid_update_metadata(disk);
-		pp = disk->d_consumer->provider;
-		g_topology_lock();
-		error = g_raid_read_metadata(disk->d_consumer, &md);
-		g_topology_unlock();
-		g_raid_event_send(disk, G_RAID_DISK_STATE_DISCONNECTED,
-		    G_RAID_EVENT_WAIT);
-		if (error != 0) {
-			gctl_error(req, "Cannot read metadata from %s.",
-			    pp->name);
-			continue;
-		}
-		error = g_raid_add_disk(sc, pp, &md);
-		if (error != 0) {
-			gctl_error(req, "Cannot reconnect component %s.",
-			    pp->name);
-			continue;
-		}
+	sc = (struct g_raid_softc *)geom->softc;
+	g_topology_unlock();
+	sx_xlock(&sc->sc_lock);
+	ctlstatus = G_RAID_MD_CTL(sc->sc_md, req);
+	if (ctlstatus < 0) {
+		gctl_error(req, "Command failed: %d.", ctlstatus);
+		if (crstatus == G_RAID_MD_TASTE_NEW)
+			g_raid_destroy_node(sc, 0);
 	}
 	sx_xunlock(&sc->sc_lock);
+	g_topology_lock();
 }
 
 static void
-g_raid_ctl_remove(struct gctl_req *req, struct g_class *mp)
+g_raid_ctl_stop(struct gctl_req *req, struct g_class *mp)
 {
 	struct g_raid_softc *sc;
-	struct g_raid_disk *disk;
-	const char *name;
-	char param[16];
-	int *nargs;
-	u_int i;
+	const char *nodename;
+	int *nargs, *force;
+	int error, how;
 
 	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
 	if (nargs == NULL) {
 		gctl_error(req, "No '%s' argument.", "nargs");
 		return;
 	}
-	if (*nargs < 2) {
-		gctl_error(req, "Too few arguments.");
+	if (*nargs < 1) {
+		gctl_error(req, "Invalid number of arguments.");
 		return;
 	}
-	name = gctl_get_asciiparam(req, "arg0");
-	if (name == NULL) {
-		gctl_error(req, "No 'arg%u' argument.", 0);
+	nodename = gctl_get_asciiparam(req, "arg0");
+	if (nodename == NULL) {
+		gctl_error(req, "No node name recieved.");
 		return;
 	}
-	sc = g_raid_find_device(mp, name);
+	sc = g_raid_find_node(mp, nodename);
 	if (sc == NULL) {
-		gctl_error(req, "No such device: %s.", name);
+		gctl_error(req, "Node '%s' not found.", nodename);
 		return;
 	}
-	if (g_raid_ndisks(sc, -1) < sc->sc_ndisks) {
+	force = gctl_get_paraml(req, "force", sizeof(*force));
+	if (force != NULL && *force)
+		how = G_RAID_DESTROY_HARD;
+	else
+		how = G_RAID_DESTROY_SOFT;
+	g_topology_unlock();
+	sx_xlock(&sc->sc_lock);
+	error = g_raid_destroy(sc, how);
+	if (error != 0)
 		sx_xunlock(&sc->sc_lock);
-		gctl_error(req, "Not all disks connected. Try 'forget' command "
-		    "first.");
-		return;
-	}
-	for (i = 1; i < (u_int)*nargs; i++) {
-		snprintf(param, sizeof(param), "arg%u", i);
-		name = gctl_get_asciiparam(req, param);
-		if (name == NULL) {
-			gctl_error(req, "No 'arg%u' argument.", i);
-			continue;
-		}
-		disk = g_raid_find_disk(sc, name);
-		if (disk == NULL) {
-			gctl_error(req, "No such provider: %s.", name);
-			continue;
-		}
-		g_raid_event_send(disk, G_RAID_DISK_STATE_DESTROY,
-		    G_RAID_EVENT_DISK);
-	}
-	sx_xunlock(&sc->sc_lock);
+	g_topology_lock();
 }
 
 static void
-g_raid_ctl_deactivate(struct gctl_req *req, struct g_class *mp)
+g_raid_ctl_other(struct gctl_req *req, struct g_class *mp)
 {
 	struct g_raid_softc *sc;
-	struct g_raid_disk *disk;
-	const char *name;
-	char param[16];
+	const char *nodename;
 	int *nargs;
-	u_int i;
+	int ctlstatus;
 
 	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
 	if (nargs == NULL) {
 		gctl_error(req, "No '%s' argument.", "nargs");
 		return;
 	}
-	if (*nargs < 2) {
-		gctl_error(req, "Too few arguments.");
+	if (*nargs < 1) {
+		gctl_error(req, "Invalid number of arguments.");
 		return;
 	}
-	name = gctl_get_asciiparam(req, "arg0");
-	if (name == NULL) {
-		gctl_error(req, "No 'arg%u' argument.", 0);
+	nodename = gctl_get_asciiparam(req, "arg0");
+	if (nodename == NULL) {
+		gctl_error(req, "No node name recieved.");
 		return;
 	}
-	sc = g_raid_find_device(mp, name);
+	sc = g_raid_find_node(mp, nodename);
 	if (sc == NULL) {
-		gctl_error(req, "No such device: %s.", name);
+		gctl_error(req, "Node '%s' not found.", nodename);
 		return;
 	}
-	for (i = 1; i < (u_int)*nargs; i++) {
-		snprintf(param, sizeof(param), "arg%u", i);
-		name = gctl_get_asciiparam(req, param);
-		if (name == NULL) {
-			gctl_error(req, "No 'arg%u' argument.", i);
-			continue;
-		}
-		disk = g_raid_find_disk(sc, name);
-		if (disk == NULL) {
-			gctl_error(req, "No such provider: %s.", name);
-			continue;
-		}
-		disk->d_flags |= G_RAID_DISK_FLAG_INACTIVE;
-		disk->d_flags &= ~G_RAID_DISK_FLAG_FORCE_SYNC;
-		g_raid_update_metadata(disk);
-		sc->sc_bump_id |= G_RAID_BUMP_SYNCID;
-		g_raid_event_send(disk, G_RAID_DISK_STATE_DISCONNECTED,
-		    G_RAID_EVENT_DISK);
+	g_topology_unlock();
+	sx_xlock(&sc->sc_lock);
+	if (sc->sc_md != NULL) {
+		ctlstatus = G_RAID_MD_CTL(sc->sc_md, req);
+		if (ctlstatus < 0)
+			gctl_error(req, "Command failed: %d.", ctlstatus);
 	}
 	sx_xunlock(&sc->sc_lock);
+	g_topology_lock();
 }
 
-static void
-g_raid_ctl_forget(struct gctl_req *req, struct g_class *mp)
-{
-	struct g_raid_softc *sc;
-	struct g_raid_disk *disk;
-	const char *name;
-	char param[16];
-	int *nargs;
-	u_int i;
-
-	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
-	if (nargs == NULL) {
-		gctl_error(req, "No '%s' argument.", "nargs");
-		return;
-	}
-	if (*nargs < 1) {
-		gctl_error(req, "Missing device(s).");
-		return;
-	}
-
-	for (i = 0; i < (u_int)*nargs; i++) {
-		snprintf(param, sizeof(param), "arg%u", i);

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



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