[PATCH 23/35] Monitor: link container-volumes in statelist

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 2d059753de6282ad5f9f4e82e631f98015a2e1e6 Mon Sep 17 00:00:00 2001
From: Anna Czarnowska <anna.czarnowska@xxxxxxxxx>
Date: Fri, 23 Jul 2010 22:44:14 +0100
Subject: [PATCH 23/35] Monitor: link container-volumes in statelist

To avoid repeated retrieving parent container when looking for spares.

Signed-off-by: Marcin Labun <marcin.labun@xxxxxxxxx>
---
 Monitor.c |  118 ++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 94 insertions(+), 24 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index 088d511..91a8b69 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -38,6 +38,37 @@ static void alert(char *event, char *dev, char *disc, char *mailaddr, char *mail
  * At least it isn't MD_SB_DISKS.
  */
 #define MaxDisks 384
+struct state {
+	char *devname;
+	int devnum;	/* to sync with mdstat info */
+	long utime;
+	int err;
+	int active, working, failed, spare, raid, total;
+	int expected_spares;
+	int devstate[MaxDisks];
+	int devid[MaxDisks];
+	int percent;
+	char *metadata_version;
+	struct state *volumes; /* for a container it is a link its all volumes */
+	struct state *parent;  /* for volumes it is a link to its container */
+	struct state *next;
+};
+
+
+
+static void add_to_cont(struct state *cont, struct state *vol)
+{
+	struct state *last = NULL, *iter = NULL;
+
+	vol->parent = cont;
+	iter = last = cont;
+	while (iter != vol && (iter = iter->volumes) != NULL)
+		last = iter;
+	/* don't duplicate volume entries on the list */
+	if (iter != vol)
+		last->volumes = vol;
+}
+
 int Monitor(mddev_dev_t devlist,
 	    char *mailaddr, char *alert_cmd,
 	    int period, int daemonise, int scan, int oneshot,
@@ -80,21 +111,10 @@ int Monitor(mddev_dev_t devlist,
 	 * that appears in /proc/mdstat
 	 */
 
-	struct state {
-		char *devname;
-		int devnum;	/* to sync with mdstat info */
-		long utime;
-		int err;
-		int active, working, failed, spare, raid;
-		int expected_spares;
-		int devstate[MaxDisks];
-		int devid[MaxDisks];
-		int percent;
-		struct state *next;
-	} *statelist = NULL;
 	int finished = 0;
 	struct mdstat_ent *mdstat = NULL;
 	char *mailfrom = NULL;
+	struct state *statelist = NULL;
 
 	if (!mailaddr) {
 		mailaddr = conf_get_mailaddr();
@@ -197,6 +217,10 @@ int Monitor(mddev_dev_t devlist,
 			st->devnum = INT_MAX;
 			st->percent = -2;
 			st->expected_spares = mdlist->spare_disks;
+			st->metadata_version = NULL;
+			st->parent = NULL;
+			st->volumes = NULL;
+			st->total = 0;
 			statelist = st;
 		}
 	} else {
@@ -213,6 +237,10 @@ int Monitor(mddev_dev_t devlist,
 			st->devnum = INT_MAX;
 			st->percent = -2;
 			st->expected_spares = -1;
+			st->metadata_version = NULL;
+			st->parent = NULL;
+			st->volumes = NULL;
+			st->total = 0;
 			if (mdlist) {
 				st->expected_spares = mdlist->spare_disks;
 			}
@@ -237,6 +265,8 @@ int Monitor(mddev_dev_t devlist,
 			int fd;
 			unsigned int i;
 
+			st->parent = NULL;
+			st->volumes = NULL;
 			if (test)
 				alert("TestMessage", dev, NULL, mailaddr, mailfrom, alert_cmd, dosyslog);
 			fd = open(dev, O_RDONLY);
@@ -299,17 +329,22 @@ int Monitor(mddev_dev_t devlist,
 				/* external arrays don't update utime */
 				array.utime = time(0);
 
-			if (st->utime == array.utime &&
-			    st->failed == array.failed_disks &&
-			    st->working == array.working_disks &&
-			    st->spare == array.spare_disks &&
-			    (mse == NULL  || (
-				    mse->percent == st->percent
-				    ))) {
+			/* utime cannot  be trusted for external
+			 * metadata, so treat utime for external
+			 * metadata as different
+			 */
+			if ((st->utime == array.utime &&
+			   ((st->metadata_version == NULL) ||
+			     !is_external(st->metadata_version))) &&
+			     st->failed == array.failed_disks &&
+			     st->working == array.working_disks &&
+			     st->spare == array.spare_disks &&
+			    (mse == NULL  || (mse->percent == st->percent))) {
 				close(fd);
 				st->err = 0;
 				continue;
 			}
+
 			if (st->utime == 0 && /* new array */
 			    mse->pattern && strchr(mse->pattern, '_') /* degraded */
 				)
@@ -424,17 +459,28 @@ int Monitor(mddev_dev_t devlist,
 			st->failed = array.failed_disks;
 			st->utime = array.utime;
 			st->raid = array.raid_disks;
+			st->total = array.raid_disks + array.nr_disks;
 			st->err = 0;
+			if (mse->metadata_version) {
+				if (!st->metadata_version)
+					st->metadata_version = strdup(mse->metadata_version);
+				else if (strcmp(st->metadata_version,
+						mse->metadata_version) != 0) {
+					free(st->metadata_version);
+					st->metadata_version = strdup(mse->metadata_version);
+				}
+			}
+
 		}
+
 		/* now check if there are any new devices found in mdstat */
 		if (scan) {
 			struct mdstat_ent *mse;
 			for (mse=mdstat; mse; mse=mse->next)
 				if (mse->devnum != INT_MAX &&
-				    mse->level &&
-				    (strcmp(mse->level, "raid0")!=0 &&
-				     strcmp(mse->level, "linear")!=0)
-					) {
+				   (!mse->level  || /* retrieve containers */
+				    (strcmp(mse->level, "raid0") != 0 &&
+				     strcmp(mse->level, "linear") != 0))) {
 					struct state *st = malloc(sizeof *st);
 					mdu_array_info_t array;
 					int fd;
@@ -456,6 +502,10 @@ int Monitor(mddev_dev_t devlist,
 					st->err = 1;
 					st->devnum = mse->devnum;
 					st->percent = -2;
+					st->metadata_version = NULL;
+					st->parent = NULL;
+					st->volumes = NULL;
+					st->total = 0;
 					st->expected_spares = -1;
 					statelist = st;
 					if (test)
@@ -465,6 +515,27 @@ int Monitor(mddev_dev_t devlist,
 				}
 		}
 
+		/* search the statelist to connect external
+		 * metadata volumes with their containers
+		 */
+		for (st = statelist; st; st = st->next) {
+			if (st->metadata_version &&
+			    is_external(st->metadata_version) &&
+			    is_subarray(st->metadata_version+9)) {
+				struct state *cont = NULL;
+
+				for (cont = statelist; cont; cont = cont->next) {
+					if (!cont->err &&
+					    cont->parent == NULL &&
+					    cont->metadata_version &&
+					    devname2devnum(st->metadata_version+10)
+					    == cont->devnum) {
+						add_to_cont(cont, st);
+						break;
+					}
+				}
+			}
+		}
 		if (!new_found) {
 			if (oneshot)
 				break;
@@ -478,7 +549,6 @@ int Monitor(mddev_dev_t devlist,
 	return 0;
 }
 
-
 static void alert(char *event, char *dev, char *disc, char *mailaddr, char *mailfrom, char *cmd,
 		  int dosyslog)
 {
-- 
1.6.4.2

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
z siedziba w Gdansku
ul. Slowackiego 173
80-298 Gdansk

Sad Rejonowy Gdansk Polnoc w Gdansku, 
VII Wydzial Gospodarczy Krajowego Rejestru Sadowego, 
numer KRS 101882

NIP 957-07-52-316
Kapital zakladowy 200.000 zl

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux