summaryrefslogtreecommitdiff
path: root/mdstat.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-11-01 16:14:01 +1100
committerNeilBrown <neilb@suse.de>2013-02-21 17:05:23 +1100
commit4dd2df0966ec2e43ea404df5de7adf9f0e1a8e40 (patch)
treeeeda21aab0004ea6544cb00e2c36ce29f02943dc /mdstat.c
parentfdcad551e9a54c4aa8c4b63160b76e2c539a0441 (diff)
Discard devnum in favour of devnm
We widely use a "devnum" which is 0 or +ve for md%d devices and -ve for md_d%d devices. But I want to be able to use md_%s device names. So get rid of devnum (a number) and use devnm (a 32char string). eg. md0 md_d2 md_home Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'mdstat.c')
-rw-r--r--mdstat.c69
1 files changed, 30 insertions, 39 deletions
diff --git a/mdstat.c b/mdstat.c
index 5f690e5d..9ebfc075 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -152,9 +152,8 @@ struct mdstat_ent *mdstat_read(int hold, int start)
for (; (line = conf_line(f)) ; free_line(line)) {
struct mdstat_ent *ent;
char *w;
- int devnum;
+ char devnm[32];
int in_devs = 0;
- char *ep;
if (strcmp(line, "Personalities")==0)
continue;
@@ -164,18 +163,10 @@ struct mdstat_ent *mdstat_read(int hold, int start)
continue;
insert_here = NULL;
/* Better be an md line.. */
- if (strncmp(line, "md", 2)!= 0)
+ if (strncmp(line, "md", 2)!= 0 || strlen(line) >= 32
+ || (line[2] != '_' && !isdigit(line[2])))
continue;
- if (strncmp(line, "md_d", 4) == 0)
- devnum = -1-strtoul(line+4, &ep, 10);
- else if (strncmp(line, "md", 2) == 0)
- devnum = strtoul(line+2, &ep, 10);
- else
- continue;
- if (ep == NULL || *ep ) {
- /* pr_err("bad /proc/mdstat line starts: %s\n", line); */
- continue;
- }
+ strcpy(devnm, line);
ent = xmalloc(sizeof(*ent));
ent->dev = ent->level = ent->pattern= NULL;
@@ -189,7 +180,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
ent->members = NULL;
ent->dev = xstrdup(line);
- ent->devnum = devnum;
+ strcpy(ent->devnm, devnm);
for (w=dl_next(line); w!= line ; w=dl_next(w)) {
int l = strlen(w);
@@ -207,19 +198,20 @@ struct mdstat_ent *mdstat_read(int hold, int start)
} else if (in_devs && strcmp(w, "blocks")==0)
in_devs = 0;
else if (in_devs) {
+ char *ep = strchr(w, '[');
ent->devcnt +=
add_member_devname(&ent->members, w);
- if (strncmp(w, "md", 2)==0) {
+ if (ep && 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 = devname2devnum(w);
ih = &all;
while (ih != insert_here && *ih &&
- (*ih)->devnum != dn2)
+ ((int)strlen((*ih)->devnm) != ep-w
+ || strncmp((*ih)->devnm, w, ep-w) != 0))
ih = & (*ih)->next;
insert_here = ih;
}
@@ -345,13 +337,13 @@ void mdstat_wait_fd(int fd, const sigset_t *sigmask)
NULL, sigmask);
}
-int mddev_busy(int devnum)
+int mddev_busy(char *devnm)
{
struct mdstat_ent *mdstat = mdstat_read(0, 0);
struct mdstat_ent *me;
for (me = mdstat ; me ; me = me->next)
- if (me->devnum == devnum)
+ if (strcmp(me->devnm, devnm) == 0)
break;
free_mdstat(mdstat);
return me != NULL;
@@ -384,35 +376,34 @@ struct mdstat_ent *mdstat_by_component(char *name)
return NULL;
}
-struct mdstat_ent *mdstat_by_subdev(char *subdev, int container)
+struct mdstat_ent *mdstat_by_subdev(char *subdev, char *container)
{
struct mdstat_ent *mdstat = mdstat_read(0, 0);
+ struct mdstat_ent *ent = NULL;
while (mdstat) {
- struct mdstat_ent *ent;
- char *pos;
/* metadata version must match:
- * external:[/-]md%d/%s
- * where %d is 'container' and %s is 'subdev'
+ * external:[/-]%s/%s
+ * where first %s is 'container' and second %s is 'subdev'
*/
- if (mdstat->metadata_version &&
- strncmp(mdstat->metadata_version, "external:", 9) == 0 &&
- strchr("/-", mdstat->metadata_version[9]) != NULL &&
- strncmp(mdstat->metadata_version+10, "md", 2) == 0 &&
- strtoul(mdstat->metadata_version+12, &pos, 10)
- == (unsigned)container &&
- pos > mdstat->metadata_version+12 &&
- *pos == '/' &&
- strcmp(pos+1, subdev) == 0
- ) {
- free_mdstat(mdstat->next);
- mdstat->next = NULL;
- return mdstat;
- }
+ if (ent)
+ free_mdstat(ent);
ent = mdstat;
mdstat = mdstat->next;
ent->next = NULL;
- free_mdstat(ent);
+
+ if (ent->metadata_version == NULL ||
+ strncmp(ent->metadata_version, "external:", 9) != 0)
+ continue;
+
+ if (!metadata_container_matches(ent->metadata_version+9,
+ container) ||
+ !metadata_subdev_matches(ent->metadata_version+9,
+ subdev))
+ continue;
+
+ free_mdstat(mdstat);
+ return ent;
}
return NULL;
}