Add mdstat_by_component
This allows finding the array which contains a given component. Components are named using the kernel-internal string name such as "sda1" or "hdb". Don't return member arrays, only the contain that contains them. Also tidy up the parsing of 'inactive' arrays in /proc/mdstat. If we see 'inactive' we need to set 'in_devs' immediately as there is no level coming. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
7e6140e6c6
commit
3b57c4661a
5
mdadm.h
5
mdadm.h
|
@ -355,6 +355,10 @@ struct mdstat_ent {
|
|||
int raid_disks;
|
||||
int chunk_size;
|
||||
char * metadata_version;
|
||||
struct dev_member {
|
||||
char *name;
|
||||
struct dev_member *next;
|
||||
} *members;
|
||||
struct mdstat_ent *next;
|
||||
};
|
||||
|
||||
|
@ -363,6 +367,7 @@ extern void free_mdstat(struct mdstat_ent *ms);
|
|||
extern void mdstat_wait(int seconds);
|
||||
extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
|
||||
extern int mddev_busy(int devnum);
|
||||
extern struct mdstat_ent *mdstat_by_component(char *name);
|
||||
|
||||
struct map_ent {
|
||||
struct map_ent *next;
|
||||
|
|
64
mdstat.c
64
mdstat.c
|
@ -83,14 +83,41 @@
|
|||
#include <sys/select.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static void free_member_devnames(struct dev_member *m)
|
||||
{
|
||||
while(m) {
|
||||
struct dev_member *t = m;
|
||||
|
||||
m = m->next;
|
||||
free(t->name);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_member_devname(struct dev_member **m, char *name)
|
||||
{
|
||||
struct dev_member *new;
|
||||
char *t;
|
||||
|
||||
if ((t = strchr(name, '[')) == NULL)
|
||||
/* not a device */
|
||||
return;
|
||||
|
||||
new = malloc(sizeof(*new));
|
||||
new->name = strndup(name, t - name);
|
||||
new->next = *m;
|
||||
*m = new;
|
||||
}
|
||||
|
||||
void free_mdstat(struct mdstat_ent *ms)
|
||||
{
|
||||
while (ms) {
|
||||
struct mdstat_ent *t;
|
||||
if (ms->dev) free(ms->dev);
|
||||
if (ms->level) free(ms->level);
|
||||
if (ms->pattern) free(ms->pattern);
|
||||
if (ms->metadata_version) free(ms->metadata_version);
|
||||
free(ms->dev);
|
||||
free(ms->level);
|
||||
free(ms->pattern);
|
||||
free(ms->metadata_version);
|
||||
free_member_devnames(ms->members);
|
||||
t = ms;
|
||||
ms = ms->next;
|
||||
free(t);
|
||||
|
@ -159,6 +186,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
|
|||
ent->raid_disks = 0;
|
||||
ent->chunk_size = 0;
|
||||
ent->devcnt = 0;
|
||||
ent->members = NULL;
|
||||
|
||||
ent->dev = strdup(line);
|
||||
ent->devnum = devnum;
|
||||
|
@ -180,6 +208,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
|
|||
in_devs = 0;
|
||||
else if (in_devs) {
|
||||
ent->devcnt++;
|
||||
add_member_devname(&ent->members, w);
|
||||
if (strncmp(w, "md", 2)==0) {
|
||||
/* This has an md device as a component.
|
||||
* If that device is already in the
|
||||
|
@ -311,3 +340,30 @@ int mddev_busy(int devnum)
|
|||
free_mdstat(mdstat);
|
||||
return me != NULL;
|
||||
}
|
||||
|
||||
struct mdstat_ent *mdstat_by_component(char *name)
|
||||
{
|
||||
struct mdstat_ent *mdstat = mdstat_read(0, 0);
|
||||
|
||||
while (mdstat) {
|
||||
struct dev_member *m;
|
||||
struct mdstat_ent *ent;
|
||||
if (mdstat->metadata_version &&
|
||||
strncmp(mdstat->metadata_version, "external:", 9) == 0 &&
|
||||
is_subarray(mdstat->metadata_version+9))
|
||||
/* don't return subarrays, only containers */
|
||||
;
|
||||
else for (m = mdstat->members; m; m = m->next) {
|
||||
if (strcmp(m->name, name) == 0) {
|
||||
free_mdstat(mdstat->next);
|
||||
mdstat->next = NULL;
|
||||
return mdstat;
|
||||
}
|
||||
}
|
||||
ent = mdstat;
|
||||
mdstat = mdstat->next;
|
||||
ent->next = NULL;
|
||||
free_mdstat(ent);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue