From 22a88995861f93110802ee49c5d7bc28250b46ce Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Tue, 31 Jan 2006 00:39:50 +0000 Subject: [PATCH] Sort mdstat entries so that composites are well-ordered. This means that "-Ds" lists arrays in an approprate order for assembly. Signed-off-by: Neil Brown --- Detail.c | 2 +- Monitor.c | 2 +- mdadm.c | 4 ++-- mdadm.h | 2 +- mdopen.c | 2 +- mdstat.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++------- 6 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Detail.c b/Detail.c index 2986a6eb..774a7509 100644 --- a/Detail.c +++ b/Detail.c @@ -135,7 +135,7 @@ int Detail(char *dev, int brief, int test) mdu_bitmap_file_t bmf; unsigned long array_size; unsigned long long larray_size; - struct mdstat_ent *ms = mdstat_read(0); + struct mdstat_ent *ms = mdstat_read(0, 0); struct mdstat_ent *e; int devnum = array.md_minor; if (major(stb.st_rdev) != MD_MAJOR) diff --git a/Monitor.c b/Monitor.c index 1ad57beb..2ea0bc8f 100644 --- a/Monitor.c +++ b/Monitor.c @@ -204,7 +204,7 @@ int Monitor(mddev_dev_t devlist, if (mdstat) free_mdstat(mdstat); - mdstat = mdstat_read(oneshot?0:1); + mdstat = mdstat_read(oneshot?0:1, 0); for (st=statelist; st; st=st->next) { mdu_array_info_t array; diff --git a/mdadm.c b/mdadm.c index 925c01fe..7b6c3d01 100644 --- a/mdadm.c +++ b/mdadm.c @@ -1030,7 +1030,7 @@ int main(int argc, char *argv[]) if (devlist == NULL) { if (devmode=='D' && scan) { /* apply --detail to all devices in /proc/mdstat */ - struct mdstat_ent *ms = mdstat_read(0); + struct mdstat_ent *ms = mdstat_read(0, 1); struct mdstat_ent *e; for (e=ms ; e ; e=e->next) { char *name = get_md_name(e->devnum); @@ -1051,7 +1051,7 @@ int main(int argc, char *argv[]) int progress=1, err; int last = 0; do { - struct mdstat_ent *ms = mdstat_read(0); + struct mdstat_ent *ms = mdstat_read(0, 0); struct mdstat_ent *e; if (!progress) last = 1; diff --git a/mdadm.h b/mdadm.h index d93117f1..5df6eeed 100644 --- a/mdadm.h +++ b/mdadm.h @@ -160,7 +160,7 @@ struct mdstat_ent { struct mdstat_ent *next; }; -extern struct mdstat_ent *mdstat_read(int); +extern struct mdstat_ent *mdstat_read(int hold, int start); extern void free_mdstat(struct mdstat_ent *ms); extern void mdstat_wait(int seconds); diff --git a/mdopen.c b/mdopen.c index 81cf725b..0656ce26 100644 --- a/mdopen.c +++ b/mdopen.c @@ -158,7 +158,7 @@ int open_mddev(char *dev, int autof) major = get_mdp_major(); break; case 0: /* not standard, pick an unused number */ - mdlist = mdstat_read(0); + mdlist = mdstat_read(0, 0); for (num= (autof>0)?-1:0 ; ; num+= (autof>2)?-1:1) { struct mdstat_ent *me; for (me=mdlist; me; me=me->next) diff --git a/mdstat.c b/mdstat.c index 9a732798..7ef4443d 100644 --- a/mdstat.c +++ b/mdstat.c @@ -101,10 +101,10 @@ void free_mdstat(struct mdstat_ent *ms) } static int mdstat_fd = -1; -struct mdstat_ent *mdstat_read(int hold) +struct mdstat_ent *mdstat_read(int hold, int start) { FILE *f; - struct mdstat_ent *all, **end; + struct mdstat_ent *all, *rv, **end, **insert_here; char *line; if (hold && mdstat_fd != -1) { @@ -121,6 +121,7 @@ struct mdstat_ent *mdstat_read(int hold) struct mdstat_ent *ent; char *w; int devnum; + int in_devs = 0; char *ep; if (strcmp(line, "Personalities")==0) @@ -129,6 +130,7 @@ struct mdstat_ent *mdstat_read(int hold) continue; if (strcmp(line, "unused")==0) continue; + insert_here = NULL; /* Better be an md line.. */ if (strncmp(line, "md", 2)!= 0) continue; @@ -167,9 +169,28 @@ struct mdstat_ent *mdstat_read(int hold) ent->active = 0; else if (ent->active >=0 && ent->level == NULL && - w[0] != '(' /*readonly*/) + w[0] != '(' /*readonly*/) { ent->level = strdup(w); - else if (!ent->pattern && + in_devs = 1; + } else if (in_devs && strcmp(w, "blocks")==0) + in_devs = 0; + else if (in_devs && strncmp(w, "md", 2)==0) { + /* This has an md device as a component. + * If that device is already in the list, + * make sure we insert before there. + */ + struct mdstat_ent **ih; + int dn2; + if (strncmp(w, "md_d", 4)==0) + dn2 = -1-strtoul(w+4, &ep, 10); + else + dn2 = strtoul(w+2, &ep, 10); + ih = &all; + while (ih != insert_here && *ih && + (*ih)->devnum != dn2) + ih = & (*ih)->next; + insert_here = ih; + } else if (!ent->pattern && w[0] == '[' && (w[1] == 'U' || w[1] == '_')) { ent->pattern = strdup(w+1); @@ -192,13 +213,31 @@ struct mdstat_ent *mdstat_read(int hold) ent->percent = atoi(w); } } - *end = ent; - end = &ent->next; + if (insert_here && (*insert_here)) { + ent->next = *insert_here; + *insert_here = ent; + } else { + *end = ent; + end = &ent->next; + } } if (hold && mdstat_fd == -1) mdstat_fd = dup(fileno(f)); fclose(f); - return all; + + /* If we might want to start array, + * reverse the order, so that components comes before composites + */ + if (start) { + rv = NULL; + while (all) { + struct mdstat_ent *e = all; + all = all->next; + e->next = rv; + rv = e; + } + } else rv = all; + return rv; } void mdstat_wait(int seconds) -- 2.39.2