summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2008-05-15 16:48:13 +1000
committerNeil Brown <neilb@suse.de>2008-05-15 16:48:13 +1000
commitd03373f1deea242eaacfab6b2b0c4afc6d7702d2 (patch)
treead9fb200b3da1e8b6a536bce6634e2d056c33884
parent111d01fcc76d2e7d0b05f78fae67e89cdf6856ad (diff)
downloadmdadm-d03373f1deea242eaacfab6b2b0c4afc6d7702d2.tar.gz
mdadm-d03373f1deea242eaacfab6b2b0c4afc6d7702d2.tar.xz
mdadm-d03373f1deea242eaacfab6b2b0c4afc6d7702d2.zip
Some support for external metadata.
Allow specifying metadata type when creating arrays etc.
-rw-r--r--Create.c33
-rw-r--r--mdadm.h2
-rw-r--r--util.c4
3 files changed, 33 insertions, 6 deletions
diff --git a/Create.c b/Create.c
index 19793fa..6e58b53 100644
--- a/Create.c
+++ b/Create.c
@@ -71,6 +71,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
int rv;
int bitmap_fd;
unsigned long long bitmapsize;
+ struct mdinfo *sra;
struct mdinfo info;
int major_num = BITMAP_MAJOR_HI;
@@ -485,8 +486,21 @@ int Create(struct supertype *st, char *mddev, int mdfd,
}
+ sra = sysfs_read(mdfd, 0, 0);
- if ((vers % 100) >= 1) { /* can use different versions */
+ if (st->ss->external) {
+ char ver[100];
+ strcat(strcpy(ver, "external:"), st->ss->text_version);
+ if ((vers % 100) < 2 ||
+ sra == NULL ||
+ sysfs_set_str(sra, NULL, "metadata_version",
+ ver) < 0) {
+ fprintf(stderr, Name ": This kernel does not "
+ "support external metadata.\n");
+ return 1;
+ }
+ rv = 0;
+ } else if ((vers % 100) >= 1) { /* can use different versions */
mdu_array_info_t inf;
memset(&inf, 0, sizeof(inf));
inf.major_version = st->ss->major;
@@ -524,7 +538,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
}
-
for (pass=1; pass <=2 ; pass++) {
mddev_dev_t moved_disk = NULL; /* the disk that was moved out of the insert point */
@@ -570,13 +583,23 @@ int Create(struct supertype *st, char *mddev, int mdfd,
case 2:
close(fd);
- if (ioctl(mdfd, ADD_NEW_DISK, &info.disk)) {
- fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n",
+ if (st->ss->external) {
+ char dv[100];
+ sprintf(dv, "%d:%d\n",
+ info.disk.major,
+ info.disk.minor);
+ sysfs_set_str(sra, NULL, "new_dev", dv);
+ /* FIXME check error */
+ /*FIXME find that device and set it up*/
+ } else if (ioctl(mdfd, ADD_NEW_DISK,
+ &info.disk)) {
+ fprintf(stderr,
+ Name ": ADD_NEW_DISK for %s "
+ "failed: %s\n",
dv->devname, strerror(errno));
st->ss->free_super(st);
return 1;
}
-
break;
}
if (dv == moved_disk && dnum != insert_point) break;
diff --git a/mdadm.h b/mdadm.h
index 7190376..82f6cd9 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -377,7 +377,9 @@ extern struct superswitch {
int chunk, unsigned long long size,
char *subdev, unsigned long long *freesize);
int major;
+ char *text_version;
int swapuuid; /* true if uuid is bigending rather than hostendian */
+ int external;
} super0, super1, *superlist[];
struct supertype {
diff --git a/util.c b/util.c
index 75f3706..733a466 100644
--- a/util.c
+++ b/util.c
@@ -813,7 +813,9 @@ struct supertype *dup_super(struct supertype *st)
if (!st)
return st;
- if (st->minor_version == -1)
+ if (st->ss->text_version)
+ strcpy(version, st->ss->text_version);
+ else if (st->minor_version == -1)
sprintf(version, "%d", st->ss->major);
else
sprintf(version, "%d.%d", st->ss->major, st->minor_version);