Create a container member
authorNeil Brown <neilb@suse.de>
Thu, 15 May 2008 06:48:21 +0000 (16:48 +1000)
committerNeil Brown <neilb@suse.de>
Thu, 15 May 2008 06:48:21 +0000 (16:48 +1000)
From: Neil Brown <neilb@suse.de>

Create.c
mdadm.h
super-ddf.c
sysfs.c
util.c

index 0bc4738..c1d607f 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -537,7 +537,15 @@ int Create(struct supertype *st, char *mddev, int mdfd,
 
        if (st->ss->external) {
                char ver[100];
-               strcat(strcpy(ver, "external:"), st->ss->text_version);
+               if (st->ss->external == 1)
+                       /* container */
+                       strcat(strcpy(ver, "external:"), st->ss->text_version);
+               else {
+                       /* member */
+                       sprintf(ver, "external:/%s/%d",
+                               devnum2devname(st->container_dev),
+                               st->container_member);
+               }
                if ((vers % 100) < 2 ||
                    sra == NULL ||
                    sysfs_set_str(sra, NULL, "metadata_version",
diff --git a/mdadm.h b/mdadm.h
index 4c0e9e1..dae73cc 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -397,6 +397,8 @@ struct supertype {
        struct superswitch *ss;
        int minor_version;
        int max_devs;
+       int container_dev;    /* devnum of container */
+       int container_member; /* numerical position in container */
        void *sb;
        void *info;
 };
@@ -563,6 +565,8 @@ extern int open_mddev_devnum(char *devname, int devnum, char *name,
                             char *chosen_name, int parts);
 extern int open_container(int fd);
 
+extern char *devnum2devname(int num);
+extern int fd2devnum(int fd);
 
 #define        LEVEL_MULTIPATH         (-4)
 #define        LEVEL_LINEAR            (-1)
index b494647..69ca320 100644 (file)
@@ -416,7 +416,7 @@ struct ddf_super {
 #define offsetof(t,f) ((size_t)&(((t*)0)->f))
 #endif
 
-struct superswitch super_ddf_container, super_ddf_bvd;
+extern struct superswitch super_ddf_container, super_ddf_bvd;
 
 static int calc_crc(void *buf, int len)
 {
@@ -1657,6 +1657,7 @@ static int init_super_ddf_bvd(struct supertype *st,
                return 0;
        }
        ve = &ddf->virt->entries[venum];
+       st->container_member = venum;
 
        /* A Virtual Disk GUID contains the T10 Vendor ID, controller type,
         * timestamp, random number
@@ -2023,6 +2024,8 @@ int validate_geometry_ddf(struct supertype *st,
                st->ss = &super_ddf_bvd;
                if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL, 1) == 0) {
                        st->sb = ddf;
+                       st->container_dev = fd2devnum(cfd);
+                       st->container_member = 27; // FIXME
                        close(cfd);
                        return st->ss->validate_geometry(st, level, layout,
                                                         raiddisks, chunk, size,
diff --git a/sysfs.c b/sysfs.c
index 6fa76fd..8b5a6ff 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -34,7 +34,7 @@ int load_sys(char *path, char *buf)
                return -1;
        n = read(fd, buf, 1024);
        close(fd);
-       if (n <=0 || n >= 1024)
+       if (n <0 || n >= 1024)
                return -1;
        buf[n] = 0;
        if (buf[n-1] == '\n')
@@ -316,6 +316,7 @@ int sysfs_set_array(struct mdinfo *sra,
 {
        int rv = 0;
        sra->array = info->array;
+
        if (info->array.level < 0)
                return 0; /* FIXME */
        rv |= sysfs_set_str(sra, NULL, "level",
diff --git a/util.c b/util.c
index 7b43ee2..8ea3069 100644 (file)
--- a/util.c
+++ b/util.c
@@ -978,6 +978,29 @@ int open_container(int fd)
        return -1;
 }
 
+char *devnum2devname(int num)
+{
+       char name[100];
+       if (num > 0)
+               sprintf(name, "md%d", num);
+       else
+               sprintf(name, "md_d%d", -1-num);
+       return strdup(name);
+}
+
+int fd2devnum(int fd)
+{
+       struct stat stb;
+       if (fstat(fd, &stb) == 0 &&
+           (S_IFMT&stb.st_mode)==S_IFBLK) {
+               if (major(stb.st_rdev) == MD_MAJOR)
+                       return minor(stb.st_rdev);
+               else
+                       return -1- (minor(stb.st_rdev)>>6);
+       }
+       return -1;
+}
+
 #ifdef __TINYC__
 /* tinyc doesn't optimize this check in ioctl.h out ... */
 unsigned int __invalid_size_argument_for_IOC = 0;