summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2006-01-31 00:39:50 +0000
committerNeil Brown <neilb@suse.de>2006-01-31 00:39:50 +0000
commit22a88995861f93110802ee49c5d7bc28250b46ce (patch)
tree16e1f93459d27b51e614d5a81a73252f120e39f9
parent576d6d83af3e684bda417493cf64aab3ce235ab2 (diff)
downloadmdadm-22a88995861f93110802ee49c5d7bc28250b46ce.tar.gz
mdadm-22a88995861f93110802ee49c5d7bc28250b46ce.tar.xz
mdadm-22a88995861f93110802ee49c5d7bc28250b46ce.zip
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 <neilb@suse.de>
-rw-r--r--Detail.c2
-rw-r--r--Monitor.c2
-rw-r--r--mdadm.c4
-rw-r--r--mdadm.h2
-rw-r--r--mdopen.c2
-rw-r--r--mdstat.c53
6 files changed, 52 insertions, 13 deletions
diff --git a/Detail.c b/Detail.c
index 2986a6e..774a750 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 1ad57be..2ea0bc8 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 925c01f..7b6c3d0 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 d93117f..5df6eee 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 81cf725..0656ce2 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 9a73279..7ef4443 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)