summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2008-07-12 20:27:38 +1000
committerNeil Brown <neilb@suse.de>2008-07-12 20:27:38 +1000
commitf7e7067b47d2ca9994f9222dfa5833ac84ce3b22 (patch)
tree9519e435af3001dd2ccb2ee01d114067213aa615
parent6adfd3affda071d1083497d150a1150ade0e3fdb (diff)
downloadmdadm-f7e7067b47d2ca9994f9222dfa5833ac84ce3b22.tar.gz
mdadm-f7e7067b47d2ca9994f9222dfa5833ac84ce3b22.tar.xz
mdadm-f7e7067b47d2ca9994f9222dfa5833ac84ce3b22.zip
Add subarray field to supertype.
When loading the metadata for a subarray (super_by_fd), we set ->subarray to be the name read from md/metadata_version so that getinfo_super can return info about the correct array. With this we can differentiate between a container and an array within the container by looking at ->subarray[0].
-rw-r--r--Create.c6
-rw-r--r--Manage.c4
-rw-r--r--mdadm.h2
-rw-r--r--super-ddf.c12
-rw-r--r--super-intel.c6
-rw-r--r--super0.c3
-rw-r--r--super1.c3
-rw-r--r--util.c37
8 files changed, 59 insertions, 14 deletions
diff --git a/Create.c b/Create.c
index eb67968..495cf39 100644
--- a/Create.c
+++ b/Create.c
@@ -550,7 +550,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
char ver[100];
strcat(strcpy(ver, "external:"),
info.text_version);
- if (st->ss->external == 2) {
+ if (st->ss->external && st->subarray[0]) {
/* member */
/* When creating a member, we need to be careful
@@ -651,7 +651,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
strcasecmp(dv->devname, "missing")==0)
continue;
- if (st->ss->external == 2)
+ if (st->ss->external && st->subarray[0])
fd = open(dv->devname, O_RDWR, 0);
else
fd = open(dv->devname, O_RDWR|O_EXCL,0);
@@ -732,7 +732,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
}
if (verbose >= 0)
fprintf(stderr, Name ": array %s started.\n", mddev);
- if (st->ss->external == 2) {
+ if (st->ss->external && st->subarray[0]) {
if (need_mdmon) {
int dn = st->container_dev;
int i;
diff --git a/Manage.c b/Manage.c
index 003d815..9197eea 100644
--- a/Manage.c
+++ b/Manage.c
@@ -354,7 +354,7 @@ int Manage_subdevs(char *devname, int fd,
return 1;
case 'a':
/* add the device */
- if (tst == &supertype_container_member) {
+ if (tst->subarray[0]) {
fprintf(stderr, Name ": Cannot add disks to a"
" \'member\' array, perform this"
" operation on the parent container\n");
@@ -551,7 +551,7 @@ int Manage_subdevs(char *devname, int fd,
case 'r':
/* hot remove */
- if (tst == &supertype_container_member) {
+ if (tst->subarray[0]) {
fprintf(stderr, Name ": Cannot remove disks from a"
" \'member\' array, perform this"
" operation on the parent container\n");
diff --git a/mdadm.h b/mdadm.h
index 97569fa..c728bad 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -563,6 +563,7 @@ struct supertype {
int minor_version;
int max_devs;
int container_dev; /* devnum of container */
+ char subarray[32]; /* name of array inside container */
void *sb;
void *info;
@@ -582,7 +583,6 @@ struct supertype {
};
-extern struct supertype supertype_container_member;
extern struct supertype *super_by_fd(int fd);
extern struct supertype *guess_super(int fd);
extern struct supertype *dup_super(struct supertype *st);
diff --git a/super-ddf.c b/super-ddf.c
index 5644aea..378a5d2 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -733,6 +733,8 @@ static int load_super_ddf(struct supertype *st, int fd,
if (load_super_ddf_all(st, fd, &st->sb, devname, 1) == 0)
return 0;
#endif
+ if (st->subarray[0])
+ return 1; /* FIXME Is this correct */
if (get_dev_size(fd, devname, &dsize) == 0)
return 1;
@@ -1826,6 +1828,7 @@ static int init_super_ddf_bvd(struct supertype *st,
vcl = malloc(offsetof(struct vcl, conf) + ddf->conf_rec_len * 512);
vcl->lba_offset = (__u64*) &vcl->conf.phys_refnum[ddf->mppe];
vcl->vcnum = venum;
+ sprintf(st->subarray, "%d", venum);
vcl->block_sizes = NULL; /* FIXME not for CONCAT */
vc = &vcl->conf;
@@ -2449,6 +2452,15 @@ static int load_super_ddf_all(struct supertype *st, int fd,
seq = load_ddf_local(dfd, super, NULL, keep_fd);
if (!keep_fd) close(dfd);
}
+ if (st->subarray[0]) {
+ struct vcl *v;
+
+ for (v = super->conflist; v; v = v->next)
+ if (v->vcnum == atoi(st->subarray))
+ super->newconf = v;
+ if (!super->newconf)
+ return 1;
+ }
*sbp = super;
if (st->ss == NULL) {
st->ss = &super_ddf_container;
diff --git a/super-intel.c b/super-intel.c
index 3324529..30b2962 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -980,6 +980,10 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
close(dfd);
}
+ if (st->subarray[0]) {
+ /* FIXME */
+ }
+
*sbp = super;
if (st->ss == NULL) {
st->ss = &super_imsm_container;
@@ -1001,6 +1005,8 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
if (load_super_imsm_all(st, fd, &st->sb, devname, 1) == 0)
return 0;
#endif
+ if (st->subarray[0])
+ return 1; /* FIXME */
super = alloc_super(0);
if (!super) {
diff --git a/super0.c b/super0.c
index 6bb5a7e..9984712 100644
--- a/super0.c
+++ b/super0.c
@@ -783,6 +783,9 @@ static int load_super0(struct supertype *st, int fd, char *devname)
free_super0(st);
+ if (st->subarray[0])
+ return 1;
+
if (!get_dev_size(fd, devname, &dsize))
return 1;
diff --git a/super1.c b/super1.c
index ae6c8a3..a6a308a 100644
--- a/super1.c
+++ b/super1.c
@@ -1065,6 +1065,9 @@ static int load_super1(struct supertype *st, int fd, char *devname)
free_super1(st);
+ if (st->subarray[0])
+ return 1;
+
if (st->ss == NULL || st->minor_version == -1) {
int bestvers = -1;
struct supertype tst;
diff --git a/util.c b/util.c
index 08c6bb0..3a5daa2 100644
--- a/util.c
+++ b/util.c
@@ -788,8 +788,6 @@ struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, N
#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
-struct supertype supertype_container_member;
-
struct supertype *super_by_fd(int fd)
{
mdu_array_info_t array;
@@ -800,6 +798,7 @@ struct supertype *super_by_fd(int fd)
char *verstr;
char version[20];
int i;
+ char *subarray = NULL;
sra = sysfs_read(fd, 0, GET_VERSION);
@@ -819,16 +818,37 @@ struct supertype *super_by_fd(int fd)
sprintf(version, "%d.%d", vers, minor);
verstr = version;
}
- if (minor == -2 && verstr[0] == '/')
- st = &supertype_container_member;
- else
- for (i = 0; st == NULL && superlist[i] ; i++)
- st = superlist[i]->match_metadata_desc(verstr);
+ if (minor == -2 && verstr[0] == '/') {
+ char *dev = verstr+1;
+ subarray = strchr(dev, '/');
+ int devnum;
+ if (subarray)
+ *subarray++ = '\0';
+ if (strncmp(dev, "md_d", 4) == 0)
+ devnum = -1-atoi(dev+4);
+ else
+ devnum = atoi(dev+2);
+ subarray = strdup(subarray);
+ if (sra)
+ sysfs_free(sra);
+ sra = sysfs_read(-1, devnum, GET_VERSION);
+ verstr = sra->text_version ? : "-no-metadata-";
+ }
+
+ for (i = 0; st == NULL && superlist[i] ; i++)
+ st = superlist[i]->match_metadata_desc(verstr);
if (sra)
sysfs_free(sra);
- if (st)
+ if (st) {
st->sb = NULL;
+ if (subarray) {
+ strncpy(st->subarray, subarray, 32);
+ st->subarray[31] = 0;
+ free(subarray);
+ } else
+ st->subarray[0] = 0;
+ }
return st;
}
#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
@@ -845,6 +865,7 @@ struct supertype *dup_super(struct supertype *orig)
st->ss = orig->ss;
st->max_devs = orig->max_devs;
st->minor_version = orig->minor_version;
+ strcpy(st->subarray, orig->subarray);
st->sb = NULL;
st->info = NULL;
return st;