]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-ddf.c
teach imsm and ddf what st->subarray means at load_super time
[thirdparty/mdadm.git] / super-ddf.c
index 8725eabddf5c5def8c9509c8d3101f7cfbf748d5..517a586420ae44130d46822bf2a03139803af115 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * mdadm - manage Linux "md" devices aka RAID arrays.
  *
- * Copyright (C) 2006-2007 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2006-2009 Neil Brown <neilb@suse.de>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
@@ -643,6 +643,7 @@ static int load_ddf_local(int fd, struct ddf_super *super,
        struct stat stb;
        char *conf;
        int i;
+       int confsec;
        int vnum;
        int max_virt_disks = __be16_to_cpu(super->active->max_vd_entries);
        unsigned long long dsize;
@@ -693,11 +694,11 @@ static int load_ddf_local(int fd, struct ddf_super *super,
                            0);
 
        vnum = 0;
-       for (i = 0;
-            i < __be32_to_cpu(super->active->config_section_length);
-            i += super->conf_rec_len) {
+       for (confsec = 0;
+            confsec < __be32_to_cpu(super->active->config_section_length);
+            confsec += super->conf_rec_len) {
                struct vd_config *vd =
-                       (struct vd_config *)((char*)conf + i*512);
+                       (struct vd_config *)((char*)conf + confsec*512);
                struct vcl *vcl;
 
                if (vd->magic == DDF_SPARE_ASSIGN_MAGIC) {
@@ -781,22 +782,20 @@ static int load_super_ddf(struct supertype *st, int fd,
 
        /* 32M is a lower bound */
        if (dsize <= 32*1024*1024) {
-               if (devname) {
+               if (devname)
                        fprintf(stderr,
                                Name ": %s is too small for ddf: "
                                "size is %llu sectors.\n",
                                devname, dsize>>9);
-                       return 1;
-               }
+               return 1;
        }
        if (dsize & 511) {
-               if (devname) {
+               if (devname)
                        fprintf(stderr,
                                Name ": %s is an odd size for ddf: "
                                "size is %llu bytes.\n",
                                devname, dsize);
-                       return 1;
-               }
+               return 1;
        }
 
        if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) {
@@ -836,6 +835,18 @@ static int load_super_ddf(struct supertype *st, int fd,
                return rv;
        }
 
+       if (st->subarray[0]) {
+               struct vcl *v;
+
+               for (v = super->conflist; v; v = v->next)
+                       if (v->vcnum == atoi(st->subarray))
+                               super->currentconf = v;
+               if (!super->currentconf) {
+                       free(super);
+                       return 1;
+               }
+       }
+
        /* Should possibly check the sections .... */
 
        st->sb = super;
@@ -1062,9 +1073,9 @@ static void examine_vd(int n, struct ddf_super *sb, char *guid)
                               map_num(ddf_sec_level, vc->srl) ?: "-unknown-");
                }
                printf("  Device Size[%d] : %llu\n", n,
-                      __be64_to_cpu(vc->blocks)/2);
+                      (unsigned long long)__be64_to_cpu(vc->blocks)/2);
                printf("   Array Size[%d] : %llu\n", n,
-                      __be64_to_cpu(vc->array_blocks)/2);
+                      (unsigned long long)__be64_to_cpu(vc->array_blocks)/2);
        }
 }
 
@@ -1100,7 +1111,7 @@ static void examine_pds(struct ddf_super *sb)
        int i;
        struct dl *dl;
        printf(" Physical Disks : %d\n", cnt);
-       printf("      Number    RefNo    Size       Device    Type/State\n");
+       printf("      Number    RefNo      Size       Device      Type/State\n");
 
        for (i=0 ; i<cnt ; i++) {
                struct phys_disk_entry *pd = &sb->phys->entries[i];
@@ -1111,18 +1122,19 @@ static void examine_pds(struct ddf_super *sb)
                //printf("\n");
                printf("       %3d    %08x  ", i,
                       __be32_to_cpu(pd->refnum));
-               printf("%lluK ",  __be64_to_cpu(pd->config_size)>>1);
+               printf("%8lluK ", 
+                      (unsigned long long)__be64_to_cpu(pd->config_size)>>1);
                for (dl = sb->dlist; dl ; dl = dl->next) {
                        if (dl->disk.refnum == pd->refnum) {
                                char *dv = map_dev(dl->major, dl->minor, 0);
                                if (dv) {
-                                       printf("%-10s", dv);
+                                       printf("%-15s", dv);
                                        break;
                                }
                        }
                }
                if (!dl)
-                       printf("%10s","");
+                       printf("%15s","");
                printf(" %s%s%s%s%s",
                       (type&2) ? "active":"",
                       (type&4) ? "Global-Spare":"",
@@ -1162,7 +1174,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info);
 
 static void uuid_from_super_ddf(struct supertype *st, int uuid[4]);
 
-static void brief_examine_super_ddf(struct supertype *st)
+static void brief_examine_super_ddf(struct supertype *st, int verbose)
 {
        /* We just write a generic DDF ARRAY entry
         */
@@ -1172,7 +1184,6 @@ static void brief_examine_super_ddf(struct supertype *st)
        char nbuf[64];
        getinfo_super_ddf(st, &info);
        fname_from_uuid(st, &info, nbuf, ':');
-       printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
 
        for (i=0; i<__be16_to_cpu(ddf->virt->max_vdes); i++) {
                struct virtual_entry *ve = &ddf->virt->entries[i];
@@ -1187,6 +1198,7 @@ static void brief_examine_super_ddf(struct supertype *st)
                printf("ARRAY container=%s member=%d UUID=%s\n",
                       nbuf+5, i, nbuf1+5);
        }
+       printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
 }
 
 static void export_examine_super_ddf(struct supertype *st)
@@ -1335,6 +1347,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
                info->component_size = ddf->dlist->size - info->data_offset;
        } else {
                info->disk.number = -1;
+               info->disk.raid_disk = -1;
 //             info->disk.raid_disk = find refnum in the table and use index;
        }
        info->disk.state = (1 << MD_DISK_SYNC);
@@ -1373,6 +1386,7 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info)
                __be32_to_cpu(*(__u32*)(vc->conf.guid+16));
        info->array.utime         = DECADE + __be32_to_cpu(vc->conf.timestamp);
        info->array.chunk_size    = 512 << vc->conf.chunk_shift;
+       info->custom_array_size   = 0;
 
        if (cd >= 0 && cd < ddf->mppe) {
                info->data_offset         = __be64_to_cpu(vc->lba_offset[cd]);
@@ -1493,10 +1507,20 @@ static int update_super_ddf(struct supertype *st, struct mdinfo *info,
        return rv;
 }
 
+__u32 random32(void)
+{
+       __u32 rv;
+       int rfd = open("/dev/urandom", O_RDONLY);
+       if (rfd < 0 || read(rfd, &rv, 4) != 4)
+               rv = random();
+       if (rfd >= 0)
+               close(rfd);
+       return rv;
+}
+
 static void make_header_guid(char *guid)
 {
        __u32 stamp;
-       int rfd;
        /* Create a DDF Header of Virtual Disk GUID */
 
        /* 24 bytes of fiction required.
@@ -1511,11 +1535,8 @@ static void make_header_guid(char *guid)
        memcpy(guid+12, &stamp, 4);
        stamp = __cpu_to_be32(time(0) - DECADE);
        memcpy(guid+16, &stamp, 4);
-       rfd = open("/dev/urandom", O_RDONLY);
-       if (rfd < 0 || read(rfd, &stamp, 4) != 4)
-               stamp = random();
+       stamp = random32();
        memcpy(guid+20, &stamp, 4);
-       if (rfd >= 0) close(rfd);
 }
 
 static int init_super_ddf_bvd(struct supertype *st,
@@ -2148,12 +2169,12 @@ static int add_to_super_ddf(struct supertype *st,
        tm = localtime(&now);
        sprintf(dd->disk.guid, "%8s%04d%02d%02d",
                T10, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
-       *(__u32*)(dd->disk.guid + 16) = random();
-       *(__u32*)(dd->disk.guid + 20) = random();
+       *(__u32*)(dd->disk.guid + 16) = random32();
+       *(__u32*)(dd->disk.guid + 20) = random32();
 
        do {
                /* Cannot be bothered finding a CRC of some irrelevant details*/
-               dd->disk.refnum = random();
+               dd->disk.refnum = random32();
                for (i = __be16_to_cpu(ddf->active->max_pd_entries) - 1;
                     i >= 0; i--)
                        if (ddf->phys->entries[i].refnum == dd->disk.refnum)
@@ -2645,6 +2666,8 @@ validate_geometry_ddf_container(struct supertype *st,
        close(fd);
 
        *freesize = avail_size_ddf(st, ldsize >> 9);
+       if (*freesize == 0)
+               return 0;
 
        return 1;
 }
@@ -2915,7 +2938,8 @@ static struct mdinfo *container_content_ddf(struct supertype *st)
                                if (d->disk.refnum == vc->conf.phys_refnum[i])
                                        break;
                        if (d == NULL)
-                               break;
+                               /* Haven't found that one yet, maybe there are others */
+                               continue;
 
                        dev = malloc(sizeof(*dev));
                        memset(dev, 0, sizeof(*dev));