From 71d60c480ac37a20b0b7a896a818a5f0c9c55f1a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 28 Oct 2008 10:55:31 -0700 Subject: [PATCH] Preliminary -As support for container member arrays Given an mdadm.conf like the following allow /dev/imsm and /dev/md/r1 to be created by "mdadm -As". DEVICES partitions ARRAY /dev/imsm metadata=imsm auto=md UUID=b98f5dbe-aa859e7b-0e369b89-a80986d4 ARRAY /dev/md/r1 container=/dev/imsm member=0 auto=mdp UUID=3538e39c-b397c2e9-1aa031f9-2bc0eca4 spares=1 Signed-off-by: Dan Williams --- Assemble.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ Incremental.c | 6 ++++++ config.c | 2 ++ mdadm.h | 1 + mdmon.c | 9 --------- util.c | 9 +++++++++ 6 files changed, 64 insertions(+), 9 deletions(-) diff --git a/Assemble.c b/Assemble.c index 34f06a7a..526b1d5a 100644 --- a/Assemble.c +++ b/Assemble.c @@ -181,6 +181,52 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, mddev ? mddev : "further assembly"); return 1; } + + /* if the configuration specifies a container then we use that to + * determine the devices and retrieve the array configuration + */ +#ifndef MDASSEMBLE + if (ident->container && ident->member) { + int cfd = open(ident->container, O_RDWR); + struct mdinfo *mdi; + struct supertype container; + + if (verbose>0) + fprintf(stderr, Name ": looking to assemble member array %s" + " inside container %s\n", ident->member, ident->container); + if (cfd < 0) { + if (verbose>0) + fprintf(stderr, Name ": unable to open container %s: %s\n", + ident->container, strerror(errno)); + return 1; + } + + mdi = sysfs_read(cfd, fd2devnum(cfd), GET_VERSION); + if (!mdi) { + close(cfd); + if (verbose>0) + fprintf(stderr, Name ": unable to read container %s\n", + ident->container); + return 1; + } + container.ss = find_metadata_methods(mdi->text_version); + sysfs_free(mdi); + if (!container.ss) { + close(cfd); + fprintf(stderr, Name ": %s uses unknown metadata: %s\n", + ident->container, mdi->text_version); + return 1; + } + if (container.ss->load_super(&container, cfd, ident->container)) { + fprintf(stderr, Name ": Cannot load metadata for container %s\n", + ident->container); + return 1; + } + + return Incremental_container(&container, ident->container, + verbose, runstop, ident->autof); + } +#endif if (devlist == NULL) devlist = conf_get_devs(); else if (mdfd >= 0) diff --git a/Incremental.c b/Incremental.c index c9ba1eaf..80a0a07f 100644 --- a/Incremental.c +++ b/Incremental.c @@ -827,6 +827,9 @@ int Incremental_container(struct supertype *st, char *devname, int verbose, continue; if (strcmp(array_list->member, sub) != 0) continue; + if (array_list->uuid_set && + !same_uuid(ra->uuid, array_list->uuid, st->ss->swapuuid)) + continue; fd = open(array_list->container, O_RDONLY); if (fd < 0) continue; @@ -841,6 +844,9 @@ int Incremental_container(struct supertype *st, char *devname, int verbose, free(dn); /* we have a match */ match = array_list; + if (verbose>0) + fprintf(stderr, Name ": match found for member %s\n", + array_list->member); break; } } diff --git a/config.c b/config.c index 9aa8be4c..02ab3e00 100644 --- a/config.c +++ b/config.c @@ -434,6 +434,8 @@ void arrayline(char *line) mis.bitmap_fd = -1; mis.bitmap_file = NULL; mis.name[0] = 0; + mis.container = NULL; + mis.member = NULL; for (w=dl_next(line); w!=line; w=dl_next(w)) { if (w[0] == '/') { diff --git a/mdadm.h b/mdadm.h index 5604a671..4b006fb6 100644 --- a/mdadm.h +++ b/mdadm.h @@ -783,6 +783,7 @@ extern unsigned long long calc_array_size(int level, int raid_disks, int layout, int chunksize, unsigned long long devsize); extern int flush_metadata_updates(struct supertype *st); extern void append_metadata_update(struct supertype *st, void *buf, int len); +extern struct superswitch *find_metadata_methods(char *vers); extern int add_disk(int mdfd, struct supertype *st, struct mdinfo *sra, struct mdinfo *info); diff --git a/mdmon.c b/mdmon.c index 0c2c3f2d..bfad18a7 100644 --- a/mdmon.c +++ b/mdmon.c @@ -92,15 +92,6 @@ int clone_monitor(struct supertype *container) return mon_tid; } -static struct superswitch *find_metadata_methods(char *vers) -{ - if (strcmp(vers, "ddf") == 0) - return &super_ddf; - if (strcmp(vers, "imsm") == 0) - return &super_imsm; - return NULL; -} - int make_pidfile(char *devname, int o_excl) { diff --git a/util.c b/util.c index 379403d0..dee04971 100644 --- a/util.c +++ b/util.c @@ -1278,6 +1278,15 @@ void append_metadata_update(struct supertype *st, void *buf, int len) *st->update_tail = mu; st->update_tail = &mu->next; } + +struct superswitch *find_metadata_methods(char *vers) +{ + if (strcmp(vers, "ddf") == 0) + return &super_ddf; + if (strcmp(vers, "imsm") == 0) + return &super_imsm; + return NULL; +} #endif /* MDASSEMBLE */ #ifdef __TINYC__ -- 2.39.2