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 raid_disks;
|
||||||
int chunk_size;
|
int chunk_size;
|
||||||
char * metadata_version;
|
char * metadata_version;
|
||||||
|
struct dev_member {
|
||||||
|
char *name;
|
||||||
|
struct dev_member *next;
|
||||||
|
} *members;
|
||||||
struct mdstat_ent *next;
|
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(int seconds);
|
||||||
extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
|
extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
|
||||||
extern int mddev_busy(int devnum);
|
extern int mddev_busy(int devnum);
|
||||||
|
extern struct mdstat_ent *mdstat_by_component(char *name);
|
||||||
|
|
||||||
struct map_ent {
|
struct map_ent {
|
||||||
struct map_ent *next;
|
struct map_ent *next;
|
||||||
|
|
64
mdstat.c
64
mdstat.c
|
@ -83,14 +83,41 @@
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <ctype.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)
|
void free_mdstat(struct mdstat_ent *ms)
|
||||||
{
|
{
|
||||||
while (ms) {
|
while (ms) {
|
||||||
struct mdstat_ent *t;
|
struct mdstat_ent *t;
|
||||||
if (ms->dev) free(ms->dev);
|
free(ms->dev);
|
||||||
if (ms->level) free(ms->level);
|
free(ms->level);
|
||||||
if (ms->pattern) free(ms->pattern);
|
free(ms->pattern);
|
||||||
if (ms->metadata_version) free(ms->metadata_version);
|
free(ms->metadata_version);
|
||||||
|
free_member_devnames(ms->members);
|
||||||
t = ms;
|
t = ms;
|
||||||
ms = ms->next;
|
ms = ms->next;
|
||||||
free(t);
|
free(t);
|
||||||
|
@ -159,6 +186,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
|
||||||
ent->raid_disks = 0;
|
ent->raid_disks = 0;
|
||||||
ent->chunk_size = 0;
|
ent->chunk_size = 0;
|
||||||
ent->devcnt = 0;
|
ent->devcnt = 0;
|
||||||
|
ent->members = NULL;
|
||||||
|
|
||||||
ent->dev = strdup(line);
|
ent->dev = strdup(line);
|
||||||
ent->devnum = devnum;
|
ent->devnum = devnum;
|
||||||
|
@ -180,6 +208,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
|
||||||
in_devs = 0;
|
in_devs = 0;
|
||||||
else if (in_devs) {
|
else if (in_devs) {
|
||||||
ent->devcnt++;
|
ent->devcnt++;
|
||||||
|
add_member_devname(&ent->members, w);
|
||||||
if (strncmp(w, "md", 2)==0) {
|
if (strncmp(w, "md", 2)==0) {
|
||||||
/* This has an md device as a component.
|
/* This has an md device as a component.
|
||||||
* If that device is already in the
|
* If that device is already in the
|
||||||
|
@ -311,3 +340,30 @@ int mddev_busy(int devnum)
|
||||||
free_mdstat(mdstat);
|
free_mdstat(mdstat);
|
||||||
return me != NULL;
|
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