[PATCH 21/33] Monitor: link containers and volumes in statelist

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

 



From: Czarnowska, Anna 
Sent: Monday, July 05, 2010 11:35 AM
To: Neil Brown
Cc: linux-raid@xxxxxxxxxxxxxxx; Czarnowska, Anna; Hawrylewicz Czarnowski, Przemyslaw; Labun, Marcin; Neubauer, Wojciech; Williams, Dan J; Ciechanowski, Ed; dledford@xxxxxxxxxx
Subject: [PATCH 21/33] Monitor: link containers and volumes in statelist

To avoid repeated retrieving of parent container or volumes list.
Simplifies finding unused disk in a container.
Function check_disk_is_free will be used for spare sharing.

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

diff --git a/Monitor.c b/Monitor.c
index 8e82797..e16af2d 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -38,6 +38,24 @@ 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;
+     char *spare_group;
+     int active, working, failed, spare, raid, total;
+     int expected_spares;
+     int devstate[MaxDisks];
+     int devid[MaxDisks];
+     int percent;
+     char *metadata_version;
+     struct state *next;
+     struct state *volumes;
+     struct state *parent;
+     struct state *missing;
+};
+
 int Monitor(mddev_dev_t devlist,
          char *mailaddr, char *alert_cmd,
          int period, int daemonise, int scan, int oneshot, @@ -85,22 +103,11 @@ 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;
-           char *spare_group;
-           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;
+     struct state *missing_parent_list = NULL;
 
      if (!mailaddr) {
            mailaddr = conf_get_mailaddr();
@@ -173,6 +180,11 @@ int Monitor(mddev_dev_t devlist,
                  st->devnum = INT_MAX;
                  st->percent = -2;
                  st->expected_spares = mdlist->spare_disks;
+                 st->metadata_version = NULL;
+                 st->missing = NULL;
+                 st->parent = NULL;
+                 st->volumes = NULL;
+                 st->total = 0;
                  if (mdlist->spare_group)
                        st->spare_group = strdup(mdlist->spare_group);
                  else
@@ -194,6 +206,11 @@ int Monitor(mddev_dev_t devlist,
                  st->percent = -2;
                  st->expected_spares = -1;
                  st->spare_group = NULL;
+                 st->metadata_version = NULL;
+                 st->missing = NULL;
+                 st->parent = NULL;
+                 st->volumes = NULL;
+                 st->total = 0;
                  if (mdlist) {
                        st->expected_spares = mdlist->spare_disks;
                        if (mdlist->spare_group)
@@ -281,11 +298,9 @@ int Monitor(mddev_dev_t devlist,
                      st->spare == array.spare_disks &&
                      (mse == NULL  || (
                            mse->percent == st->percent
-                           ))) {
-                       close(fd);
+                           )))
                        st->err = 0;
-                       continue;
-                 }
+
                  if (st->utime == 0 && /* new array */
                      mse &&  /* is in /proc/mdstat */
                      mse->pattern && strchr(mse->pattern, '_') /* degraded */ @@ -407,17 +422,53 @@ 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 && (mse->metadata_version))  {
+                       st->metadata_version = strdup(mse->metadata_version);
+                       st->parent = NULL;
+                       st->volumes = NULL;
+                       if (is_external(st->metadata_version) &&
+                       is_subarray(st->metadata_version+9)) {
+                             if (missing_parent_list)
+                                   st->missing = missing_parent_list;
+                             else
+                                   st->missing = NULL;
+                             missing_parent_list = st;
+                       }
+                 }
+           }
+           /* create parent list */
+           while (missing_parent_list) {
+                 struct state *last = NULL, *st2 = NULL;
+                 struct state *st;
+                 st = missing_parent_list;
+                 missing_parent_list = missing_parent_list->missing;
+                 st->missing = NULL;
+
+                 for (st2 = statelist; st2; st2 = st2->next) {
+                       if ((st2->parent == NULL) &&
+                       (st2->metadata_version) &&
+                       (st2->devnum != INT_MAX) &&
+                       (devname2devnum(st->metadata_version+10)
+                                   == st2->devnum)) {
+                             st->parent = st2;
+                             last = st2;
+                             while ((st2 = st2->volumes) != NULL)
+                                   last = st2;
+                             last->volumes = st;
+                             break;
+                       }
+                 }
            }
            /* 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;
@@ -430,6 +481,8 @@ int Monitor(mddev_dev_t devlist,
                                    if (fd >=0) close(fd);
                                    put_md_name(st->devname);
                                    free(st->devname);
+                                   if (st->metadata_version)
+                                         free(st->metadata_version);
                                    free(st);
                                    continue;
                              }
@@ -440,6 +493,11 @@ int Monitor(mddev_dev_t devlist,
                              st->devnum = mse->devnum;
                              st->percent = -2;
                              st->spare_group = NULL;
+                             st->metadata_version = NULL;
+                             st->missing = NULL;
+                             st->parent = NULL;
+                             st->volumes = NULL;
+                             st->total = 0;
                              st->expected_spares = -1;
                              statelist = st;
                              if (test)
@@ -519,6 +577,29 @@ int Monitor(mddev_dev_t devlist,
      return 0;
 }
 
+/* check if disk is used in donor array (native) or any volume in donor 
+container (external)*/ int check_disk_is_free(struct state *donor, int 
+disk_idx, int ext) {
+     struct state *vol = NULL;
+     int vol_disk;
+
+     if (!donor || disk_idx < 0 || donor->devid[disk_idx] == 0)
+           return INT_MAX;
+
+     /* native */
+     if (!ext)
+           return (donor->devid[disk_idx] > 0 && donor->devstate[disk_idx] == 0) 
+? disk_idx : INT_MAX;
+
+     /* external */
+     if (!donor->volumes)
+           return disk_idx;
+     for (vol = donor->volumes; vol; vol = vol->volumes)
+           for (vol_disk = 0; vol_disk < vol->total; vol_disk++)
+                 if (donor->devid[disk_idx] == vol->devid[vol_disk])
+                       return (vol->devstate[vol_disk]  == 0) ? disk_idx : INT_MAX;
+
+     return disk_idx;
+}
 
 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