]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-ddf.c
Fix parsing of inactive arrays in /proc/mdstat
[thirdparty/mdadm.git] / super-ddf.c
index c28d8040895950c01c7adf9a5dedb96d05a8813e..b01c68d5a40b4472b74595c7693d705871e82f04 100644 (file)
@@ -783,6 +783,10 @@ static int load_super_ddf(struct supertype *st, int fd,
        if (get_dev_size(fd, devname, &dsize) == 0)
                return 1;
 
+       if (test_partition(fd))
+               /* DDF is not allowed on partitions */
+               return 1;
+
        /* 32M is a lower bound */
        if (dsize <= 32*1024*1024) {
                if (devname)
@@ -1180,6 +1184,18 @@ 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, int verbose)
+{
+       /* We just write a generic DDF ARRAY entry
+        */
+       struct mdinfo info;
+       char nbuf[64];
+       getinfo_super_ddf(st, &info);
+       fname_from_uuid(st, &info, nbuf, ':');
+
+       printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
+}
+
+static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
 {
        /* We just write a generic DDF ARRAY entry
         */
@@ -1203,7 +1219,6 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose)
                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)
@@ -1249,7 +1264,11 @@ static int match_home_ddf(struct supertype *st, char *homehost)
         * the hostname
         */
        struct ddf_super *ddf = st->sb;
-       int len = strlen(homehost);
+       int len;
+
+       if (!homehost)
+               return 0;
+       len = strlen(homehost);
 
        return (memcmp(ddf->controller.guid, T10, 8) == 0 &&
                len < sizeof(ddf->controller.vendor_data) &&
@@ -1338,6 +1357,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
                                                         (ddf->anchor.guid+16));
        info->array.utime         = 0;
        info->array.chunk_size    = 0;
+       info->container_enough    = 0;
 
 
        info->disk.major = 0;
@@ -1355,9 +1375,10 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
                info->disk.raid_disk = -1;
 //             info->disk.raid_disk = find refnum in the table and use index;
        }
-       info->disk.state = (1 << MD_DISK_SYNC);
+       info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
 
 
+       info->recovery_start = MaxSector;
        info->reshape_active = 0;
        info->name[0] = 0;
 
@@ -1416,13 +1437,15 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info)
 
        info->container_member = ddf->currentconf->vcnum;
 
+       info->recovery_start = MaxSector;
        info->resync_start = 0;
+       info->reshape_active = 0;
        if (!(ddf->virt->entries[info->container_member].state
              & DDF_state_inconsistent)  &&
            (ddf->virt->entries[info->container_member].init_state
             & DDF_initstate_mask)
            == DDF_init_full)
-               info->resync_start = ~0ULL;
+               info->resync_start = MaxSector;
 
        uuid_from_super_ddf(st, info->uuid);
 
@@ -1578,13 +1601,8 @@ static int init_super_ddf(struct supertype *st,
        struct phys_disk *pd;
        struct virtual_disk *vd;
 
-       if (!info) {
-               st->sb = NULL;
-               return 0;
-       }
        if (st->sb)
-               return init_super_ddf_bvd(st, info, size, name, homehost,
-                                         uuid);
+               return init_super_ddf_bvd(st, info, size, name, homehost, uuid);
 
        if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
                fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
@@ -1593,6 +1611,12 @@ static int init_super_ddf(struct supertype *st,
        memset(ddf, 0, sizeof(*ddf));
        ddf->dlist = NULL; /* no physical disks yet */
        ddf->conflist = NULL; /* No virtual disks yet */
+       st->sb = ddf;
+
+       if (info == NULL) {
+               /* zeroing superblock */
+               return 0;
+       }
 
        /* At least 32MB *must* be reserved for the ddf.  So let's just
         * start 32MB from the end, and put the primary header there.
@@ -1727,7 +1751,7 @@ static int init_super_ddf(struct supertype *st,
 
        memset(pd, 0xff, pdsize);
        memset(pd, 0, sizeof(*pd));
-       pd->magic = DDF_PHYS_DATA_MAGIC;
+       pd->magic = DDF_PHYS_RECORDS_MAGIC;
        pd->used_pdes = __cpu_to_be16(0);
        pd->max_pdes = __cpu_to_be16(max_phys_disks);
        memset(pd->pad, 0xff, 52);
@@ -2394,8 +2418,12 @@ static int write_init_super_ddf(struct supertype *st)
 
                /* FIXME I need to close the fds! */
                return 0;
-       } else 
+       } else {        
+               struct dl *d;
+               for (d = ddf->dlist; d; d=d->next)
+                       while (Kill(d->devname, NULL, 0, 1, 1) == 0);
                return __write_init_super_ddf(st, 1);
+       }
 }
 
 #endif
@@ -2543,8 +2571,12 @@ static int validate_geometry_ddf(struct supertype *st,
                for (i=0; ddf_level_num[i].num1 != MAXINT; i++)
                        if (ddf_level_num[i].num2 == level)
                                break;
-               if (ddf_level_num[i].num1 == MAXINT)
+               if (ddf_level_num[i].num1 == MAXINT) {
+                       if (verbose)
+                               fprintf(stderr, Name ": DDF does not support level %d arrays\n",
+                                       level);
                        return 0;
+               }
                /* Should check layout? etc */
 
                if (st->sb && freesize) {
@@ -2592,7 +2624,7 @@ static int validate_geometry_ddf(struct supertype *st,
                if (verbose)
                        fprintf(stderr,
                                Name ": ddf: Cannot create this array "
-                               "on device %s\n",
+                               "on device %s - a container is required.\n",
                                dev);
                return 0;
        }
@@ -2684,8 +2716,11 @@ static int validate_geometry_ddf_bvd(struct supertype *st,
        struct extent *e;
        int i;
        /* ddf/bvd supports lots of things, but not containers */
-       if (level == LEVEL_CONTAINER)
+       if (level == LEVEL_CONTAINER) {
+               if (verbose)
+                       fprintf(stderr, Name ": DDF cannot create a container within an container\n");
                return 0;
+       }
        /* We must have the container info already read in. */
        if (!ddf)
                return 0;
@@ -2902,7 +2937,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st)
                        this->resync_start = 0;
                } else {
                        this->array.state = 1;
-                       this->resync_start = ~0ULL;
+                       this->resync_start = MaxSector;
                }
                memcpy(this->name, ddf->virt->entries[i].name, 16);
                this->name[16]=0;
@@ -2949,6 +2984,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st)
                        dev->disk.minor = d->minor;
                        dev->disk.raid_disk = i;
                        dev->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
+                       dev->recovery_start = MaxSector;
 
                        dev->events = __be32_to_cpu(ddf->primary.seq);
                        dev->data_offset = __be64_to_cpu(vc->lba_offset[i]);
@@ -2960,12 +2996,22 @@ static struct mdinfo *container_content_ddf(struct supertype *st)
        return rest;
 }
 
-static int store_zero_ddf(struct supertype *st, int fd)
+static int store_super_ddf(struct supertype *st, int fd)
 {
+       struct ddf_super *ddf = st->sb;
        unsigned long long dsize;
        void *buf;
        int rc;
 
+       if (!ddf)
+               return 1;
+
+       /* ->dlist and ->conflist will be set for updates, currently not
+        * supported
+        */
+       if (ddf->dlist || ddf->conflist)
+               return 1;
+
        if (!get_dev_size(fd, NULL, &dsize))
                return 1;
 
@@ -3037,7 +3083,7 @@ static int ddf_set_array_state(struct active_array *a, int consistent)
        if (consistent == 2) {
                /* Should check if a recovery should be started FIXME */
                consistent = 1;
-               if (!is_resync_complete(a))
+               if (!is_resync_complete(&a->info))
                        consistent = 0;
        }
        if (consistent)
@@ -3049,9 +3095,9 @@ static int ddf_set_array_state(struct active_array *a, int consistent)
 
        old = ddf->virt->entries[inst].init_state;
        ddf->virt->entries[inst].init_state &= ~DDF_initstate_mask;
-       if (is_resync_complete(a))
+       if (is_resync_complete(&a->info))
                ddf->virt->entries[inst].init_state |= DDF_init_full;
-       else if (a->resync_start == 0)
+       else if (a->info.resync_start == 0)
                ddf->virt->entries[inst].init_state |= DDF_init_not;
        else
                ddf->virt->entries[inst].init_state |= DDF_init_quick;
@@ -3059,7 +3105,7 @@ static int ddf_set_array_state(struct active_array *a, int consistent)
                ddf->updates_pending = 1;
 
        dprintf("ddf mark %d %s %llu\n", inst, consistent?"clean":"dirty",
-               a->resync_start);
+               a->info.resync_start);
        return consistent;
 }
 
@@ -3518,6 +3564,7 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
                        di->disk.major = dl->major;
                        di->disk.minor = dl->minor;
                        di->disk.state = 0;
+                       di->recovery_start = 0;
                        di->data_offset = pos;
                        di->component_size = a->info.component_size;
                        di->container_member = dl->pdnum;
@@ -3597,6 +3644,7 @@ struct superswitch super_ddf = {
 #ifndef        MDASSEMBLE
        .examine_super  = examine_super_ddf,
        .brief_examine_super = brief_examine_super_ddf,
+       .brief_examine_subarrays = brief_examine_subarrays_ddf,
        .export_examine_super = export_examine_super_ddf,
        .detail_super   = detail_super_ddf,
        .brief_detail_super = brief_detail_super_ddf,
@@ -3615,7 +3663,7 @@ struct superswitch super_ddf = {
 
        .load_super     = load_super_ddf,
        .init_super     = init_super_ddf,
-       .store_super    = store_zero_ddf,
+       .store_super    = store_super_ddf,
        .free_super     = free_super_ddf,
        .match_metadata_desc = match_metadata_desc_ddf,
        .container_content = container_content_ddf,