Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Feb 2011 10:17:51 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r218212 - projects/graid/head/sys/geom
Message-ID:  <201102031017.p13AHpU2042095@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Feb  3 10:17:51 2011
New Revision: 218212
URL: http://svn.freebsd.org/changeset/base/218212

Log:
  Introduce new type of BIO_GETATTR -- GEOM::setstate, used to inform lower
  GEOM about state of it's providers from the point of upper layers.
  Make geom_disk use led(4) subsystem to illuminate states in such fashion:
  FAILED - "1" (on), REBUILD - "f5" (slow blink), RESYNC - "f1" (fast blink),
  ACTIVE - "0" (off).
  LED name should be set for each disk via kern.geom.disk.%s.led sysctl.
  Later disk API could be extended to allow disk driver to report this info
  in custom way via it's own facilities.

Modified:
  projects/graid/head/sys/geom/geom.h
  projects/graid/head/sys/geom/geom_disk.c

Modified: projects/graid/head/sys/geom/geom.h
==============================================================================
--- projects/graid/head/sys/geom/geom.h	Thu Feb  3 10:05:30 2011	(r218211)
+++ projects/graid/head/sys/geom/geom.h	Thu Feb  3 10:17:51 2011	(r218212)
@@ -208,6 +208,12 @@ struct g_classifier_hook {
 	void			*arg;
 };
 
+/* BIO_GETATTR("GEOM::setstate") argument values. */
+#define G_STATE_FAILED		0
+#define G_STATE_REBUILD		1
+#define G_STATE_RESYNC		2
+#define G_STATE_ACTIVE		3
+
 /* geom_dev.c */
 struct cdev;
 void g_dev_print(void);

Modified: projects/graid/head/sys/geom/geom_disk.c
==============================================================================
--- projects/graid/head/sys/geom/geom_disk.c	Thu Feb  3 10:05:30 2011	(r218211)
+++ projects/graid/head/sys/geom/geom_disk.c	Thu Feb  3 10:17:51 2011	(r218212)
@@ -56,6 +56,16 @@ __FBSDID("$FreeBSD$");
 #include <geom/geom_disk.h>
 #include <geom/geom_int.h>
 
+#include <dev/led/led.h>
+
+struct g_disk_softc {
+	struct disk		*dp;
+	struct sysctl_ctx_list	sysctl_ctx;
+	struct sysctl_oid	*sysctl_tree;
+	char			led[64];
+	uint32_t		state;
+};
+
 static struct mtx g_disk_done_mtx;
 
 static g_access_t g_disk_access;
@@ -76,6 +86,9 @@ static struct g_class g_disk_class = {
 	.dumpconf = g_disk_dumpconf,
 };
 
+SYSCTL_DECL(_kern_geom);
+SYSCTL_NODE(_kern_geom, OID_AUTO, disk, CTLFLAG_RW, 0, "GEOM_DISK stuff");
+
 static void
 g_disk_init(struct g_class *mp __unused)
 {
@@ -110,13 +123,15 @@ static int
 g_disk_access(struct g_provider *pp, int r, int w, int e)
 {
 	struct disk *dp;
+	struct g_disk_softc *sc;
 	int error;
 
 	g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)",
 	    pp->name, r, w, e);
 	g_topology_assert();
 	dp = pp->geom->softc;
-	if (dp == NULL || dp->d_destroyed) {
+	sc = pp->private;
+	if (dp == NULL || dp->d_destroyed || sc == NULL) {
 		/*
 		 * Allow decreasing access count even if disk is not
 		 * avaliable anymore.
@@ -155,6 +170,9 @@ g_disk_access(struct g_provider *pp, int
 				    pp->name, error);
 			g_disk_unlock_giant(dp);
 		}
+		sc->state = G_STATE_ACTIVE;
+		if (sc->led[0] != 0)
+			led_set(sc->led, "0");
 		dp->d_flags &= ~DISKFLAG_OPEN;
 	}
 	return (error);
@@ -162,7 +180,7 @@ g_disk_access(struct g_provider *pp, int
 
 static void
 g_disk_kerneldump(struct bio *bp, struct disk *dp)
-{ 
+{
 	struct g_kerneldump *gkd;
 	struct g_geom *gp;
 
@@ -186,6 +204,36 @@ g_disk_kerneldump(struct bio *bp, struct
 }
 
 static void
+g_disk_setstate(struct bio *bp, struct disk *dp)
+{
+	struct g_disk_softc *sc;
+	const char *cmd;
+
+	sc = bp->bio_to->private;
+	if (sc != NULL) {
+		memcpy(&sc->state, bp->bio_data, sizeof(sc->state));
+		if (sc->led[0] != 0) {
+			switch (sc->state) {
+			case G_STATE_FAILED:
+				cmd = "1";
+				break;
+			case G_STATE_REBUILD:
+				cmd = "f5";
+				break;
+			case G_STATE_RESYNC:
+				cmd = "f1";
+				break;
+			default:
+				cmd = "0";
+				break;
+			}
+			led_set(sc->led, cmd);
+		}
+	}
+	g_io_deliver(bp, 0);
+}
+
+static void
 g_disk_done(struct bio *bp)
 {
 	struct bio *bp2;
@@ -319,6 +367,8 @@ g_disk_start(struct bio *bp)
 			break;
 		else if (!strcmp(bp->bio_attribute, "GEOM::kerneldump"))
 			g_disk_kerneldump(bp, dp);
+		else if (!strcmp(bp->bio_attribute, "GEOM::setstate"))
+			g_disk_setstate(bp, dp);
 		else 
 			error = ENOIOCTL;
 		break;
@@ -376,6 +426,8 @@ g_disk_create(void *arg, int flag)
 	struct g_geom *gp;
 	struct g_provider *pp;
 	struct disk *dp;
+	struct g_disk_softc *sc;
+	char tmpstr[80];
 
 	if (flag == EV_CANCEL)
 		return;
@@ -392,6 +444,23 @@ g_disk_create(void *arg, int flag)
 	pp->stripesize = dp->d_stripesize;
 	if (bootverbose)
 		printf("GEOM: new disk %s\n", gp->name);
+	sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO);
+	sc->dp = dp;
+	sysctl_ctx_init(&sc->sysctl_ctx);
+	snprintf(tmpstr, sizeof(tmpstr), "GEOM disk %s", gp->name);
+	sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
+		SYSCTL_STATIC_CHILDREN(_kern_geom_disk), OID_AUTO, gp->name,
+		CTLFLAG_RD, 0, tmpstr);
+	if (sc->sysctl_tree != NULL) {
+		snprintf(tmpstr, sizeof(tmpstr),
+		    "kern.geom.disk.%s.led", gp->name);
+		TUNABLE_STR_FETCH(tmpstr, sc->led, sizeof(sc->led));
+		SYSCTL_ADD_STRING(&sc->sysctl_ctx,
+		    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, "led",
+		    CTLFLAG_RW | CTLFLAG_TUN, sc->led, sizeof(sc->led),
+		    "LED name");
+	}
+	pp->private = sc;
 	dp->d_geom = gp;
 	g_error_provider(pp, 0);
 }
@@ -401,11 +470,21 @@ g_disk_destroy(void *ptr, int flag)
 {
 	struct disk *dp;
 	struct g_geom *gp;
+	struct g_disk_softc *sc;
 
 	g_topology_assert();
 	dp = ptr;
 	gp = dp->d_geom;
 	if (gp != NULL) {
+		sc = LIST_FIRST(&gp->provider)->private;
+		if (sc->sysctl_tree != NULL) {
+			sysctl_ctx_free(&sc->sysctl_ctx);
+			sc->sysctl_tree = NULL;
+		}
+		if (sc->led[0] != 0)
+			led_set(sc->led, "0");
+		g_free(sc);
+		LIST_FIRST(&gp->provider)->private = NULL;
 		gp->softc = NULL;
 		g_wither_geom(gp, ENXIO);
 	}



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