[AUTOREBUILD 4/8] Monitor: link container-volumes in statelist

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

 



>From 41468ed8a496f48a2cf88f193436ed0c472e0c1b Mon Sep 17 00:00:00 2001
From: Anna Czarnowska <anna.czarnowska@xxxxxxxxx>
Date: Tue, 28 Sep 2010 05:49:38 +0200
Subject: [AUTOREBUILD 4/8] Monitor: link container-volumes in statelist
 To avoid repeated retrieving parent container when looking for spares.

Signed-off-by: Marcin Labun <marcin.labun@xxxxxxxxx>
Signed-off-by: Anna Czarnowska <anna.czarnowska@xxxxxxxxx>
---
 Monitor.c |  119 ++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 95 insertions(+), 24 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index 2adea36..93dd15d 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];
+	unsigned 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,
@@ -81,21 +112,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];
-		unsigned 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();
@@ -198,6 +218,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 {
@@ -214,6 +238,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;
 			}
@@ -238,6 +266,8 @@ int Monitor(mddev_dev_t devlist,
 			int fd;
 			int i;
 
+			st->parent = NULL;
+			st->volumes = NULL;
 			if (test)
 				alert("TestMessage", dev, NULL, mailaddr, mailfrom, alert_cmd, dosyslog);
 			fd = open(dev, O_RDONLY);
@@ -300,17 +330,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 */
 				)
@@ -425,17 +460,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;
@@ -457,6 +503,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,28 @@ int Monitor(mddev_dev_t devlist,
 					new_found = 1;
 				}
 		}
+
+		/* 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 +550,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

--
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