summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-09-18 16:21:08 +1000
committerNeilBrown <neilb@suse.de>2008-09-18 16:21:08 +1000
commitdbb44303d7d3ad8fffb9e25c8ed6fd57afa57b95 (patch)
tree659ac563f499c3f397aa9947d37ce332fe025784
parent35ddc76dcbcb7ef5f1ca57e557bfa4c3cdf6a6eb (diff)
downloadmdadm-dbb44303d7d3ad8fffb9e25c8ed6fd57afa57b95.tar.gz
mdadm-dbb44303d7d3ad8fffb9e25c8ed6fd57afa57b95.tar.xz
mdadm-dbb44303d7d3ad8fffb9e25c8ed6fd57afa57b95.zip
Add support for assembling specific subarrays.
This normally isn't needed as --incremental does all the work. But it is needed to recognise member= and container= in mdadm.conf
-rw-r--r--Incremental.c49
-rw-r--r--config.c6
-rw-r--r--mdadm.h6
3 files changed, 58 insertions, 3 deletions
diff --git a/Incremental.c b/Incremental.c
index 6474e79..6223113 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -793,6 +793,7 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
struct map_ent *mp, *map = NULL;
char nbuf[64];
char *name_to_use;
+ struct mddev_ident_s *match = NULL;
if ((autof&7) == 3 || (autof&7) == 5)
usepart = 0;
@@ -806,10 +807,51 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
)
name_to_use = fname_from_uuid(st, ra, nbuf, '-');
- if (mp)
+ if (!mp) {
+
+ /* Check in mdadm.conf for devices == devname and
+ * member == ra->text_version after second slash.
+ */
+ char *sub = strchr(ra->text_version+1, '/');
+ struct mddev_ident_s *array_list;
+ if (sub) {
+ sub++;
+ array_list = conf_get_ident(NULL);
+ } else
+ array_list = NULL;
+ for(; array_list ; array_list = array_list->next) {
+ int fd;
+ char *dn;
+ if (array_list->member == NULL ||
+ array_list->container == NULL)
+ continue;
+ if (strcmp(array_list->member, sub) != 0)
+ continue;
+ fd = open(array_list->container, O_RDONLY);
+ if (fd < 0)
+ continue;
+ dn = devnum2devname(fd2devnum(fd));
+ close(fd);
+ if (strncmp(dn, ra->text_version+1,
+ strlen(dn)) != 0 ||
+ ra->text_version[strlen(dn)+1] != '/') {
+ free(dn);
+ continue;
+ }
+ free(dn);
+ /* we have a match */
+ match = array_list;
+ break;
+ }
+ }
+
+ if (match && is_standard(match->devname, &devnum))
+ /* we have devnum now */;
+ else if (mp)
devnum = mp->devnum;
+ else if (is_standard(name_to_use, &devnum))
+ /* have devnum */;
else {
-
n = name_to_use;
if (*n == 'd')
n++;
@@ -851,7 +893,8 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
else
devnum = find_free_devnum(usepart);
}
- mdfd = open_mddev_devnum(mp ? mp->path : NULL, devnum, name_to_use,
+ mdfd = open_mddev_devnum(mp ? mp->path : match ? match->devname : NULL,
+ devnum, name_to_use,
chosen_name, autof>>3);
if (mdfd < 0) {
diff --git a/config.c b/config.c
index 121b337..f471cf3 100644
--- a/config.c
+++ b/config.c
@@ -516,6 +516,12 @@ void arrayline(char *line)
} else if (strncasecmp(w, "auto=", 5) == 0 ) {
/* whether to create device special files as needed */
mis.autof = parse_auto(w+5, "auto type", 0);
+ } else if (strncasecmp(w, "member=", 7) == 0) {
+ /* subarray within a container */
+ mis.member = strdup(w+7);
+ } else if (strncasecmp(w, "container=", 10) == 0) {
+ /* the container holding this subarray */
+ mis.container = strdup(w+10);
} else {
fprintf(stderr, Name ": unrecognised word on ARRAY line: %s\n",
w);
diff --git a/mdadm.h b/mdadm.h
index f327020..8b6baa6 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -259,6 +259,12 @@ typedef struct mddev_ident_s {
char *bitmap_file;
int bitmap_fd;
+ char *container; /* /dev/whatever name of container. You
+ * would expect this to be the 'devname'
+ * of some other entry.
+ */
+ char *member; /* subarray within a container */
+
struct mddev_ident_s *next;
} *mddev_ident_t;