]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-intel.c
Retry writing 'inactive' state during stopping array
[thirdparty/mdadm.git] / super-intel.c
index d5d01661f1461d0e19d6bfd87ca6d96e1e18945f..44c100b5e97bf22a375cf687fcd5b1b5fe19f435 100644 (file)
@@ -476,6 +476,9 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname)
 #endif /* MDASSEMBLE */
 
 
+static int find_intel_hba_capability(int fd, struct intel_super *super,
+                                    char *devname);
+
 static struct supertype *match_metadata_desc_imsm(char *arg)
 {
        struct supertype *st;
@@ -1700,8 +1703,6 @@ static __u64 blocks_per_migr_unit(struct imsm_dev *dev)
                migr_chunk = migr_strip_blocks_resync(dev);
                disks = imsm_num_data_members(dev, 0);
                blocks_per_unit = stripes_per_unit * migr_chunk * disks;
-               if (migr_type(dev) == MIGR_GEN_MIGR)
-                       return blocks_per_unit;
                stripe = __le32_to_cpu(map->blocks_per_strip) * disks;
                segment = blocks_per_unit / stripe;
                block_rel = blocks_per_unit - segment * stripe;
@@ -1852,6 +1853,12 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
                        int used_disks;
 
                        info->reshape_progress = blocks_per_unit * units;
+
+                       /* checkpoint is written per disks unit
+                        * recalculate it to reshape position
+                        */
+                       used_disks = imsm_num_data_members(dev, 0);
+                       info->reshape_progress *= used_disks;
                        dprintf("IMSM: General Migration checkpoint : %llu "
                               "(%llu) -> read reshape progress : %llu\n",
                                units, blocks_per_unit, info->reshape_progress);
@@ -2626,7 +2633,7 @@ struct bbm_log *__get_imsm_bbm_log(struct imsm_super *mpb)
 static void __free_imsm(struct intel_super *super, int free_disks);
 
 /* load_imsm_mpb - read matrix metadata
- * allocates super->mpb to be freed by free_super
+ * allocates super->mpb to be freed by free_imsm
  */
 static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
 {
@@ -2678,6 +2685,10 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
        }
 
        __free_imsm(super, 0);
+       /*  reload capability and hba */
+
+       /* capability and hba must be updated with new super allocation */
+       find_intel_hba_capability(fd, super, devname);
        super->len = ROUND_UP(anchor->mpb_size, 512);
        if (posix_memalign(&super->buf, 512, super->len) != 0) {
                if (devname)
@@ -2801,6 +2812,8 @@ static void __free_imsm(struct intel_super *super, int free_disks)
                free(super->buf);
                super->buf = NULL;
        }
+       /* unlink capability description */
+       super->orom = NULL;
        if (free_disks)
                free_imsm_disks(super);
        free_devlist(super);
@@ -2840,54 +2853,45 @@ static struct intel_super *alloc_super(void)
                memset(super, 0, sizeof(*super));
                super->current_vol = -1;
                super->create_offset = ~((__u32 ) 0);
-               if (!check_env("IMSM_NO_PLATFORM"))
-                       super->orom = find_imsm_orom();
        }
-
        return super;
 }
 
-
 /*
  * find and allocate hba and OROM/EFI based on valid fd of RAID component device
  */
-static int find_intel_hba_capability(int fd, struct intel_super *super, int verbose)
+static int find_intel_hba_capability(int fd, struct intel_super *super, char *devname)
 {
        struct sys_dev *hba_name;
        int rv = 0;
 
        if ((fd < 0) || check_env("IMSM_NO_PLATFORM")) {
+               super->orom = NULL;
                super->hba = NULL;
                return 0;
        }
        hba_name = find_disk_attached_hba(fd, NULL);
        if (!hba_name) {
-               if (verbose) {
-                       char str[256];
-
-                       fd2devname(fd, str);
+               if (devname)
                        fprintf(stderr,
                                Name ": %s is not attached to Intel(R) RAID controller.\n",
-                               str);
-               }
+                               devname);
                return 1;
        }
        rv = attach_hba_to_super(super, hba_name);
        if (rv == 2) {
-               if (verbose) {
-                       char str[256];
+               if (devname) {
+                       struct intel_hba *hba = super->hba;
 
-                       fd2devname(fd, str);
                        fprintf(stderr, Name ": %s is attached to Intel(R) %s RAID "
                                "controller (%s),\n"
                                "    but the container is assigned to Intel(R) "
                                "%s RAID controller (",
-                               str,
+                               devname,
                                hba_name->path,
                                hba_name->pci_id ? : "Err!",
                                get_sys_dev_type(hba_name->type));
 
-                       struct intel_hba *hba = super->hba;
                        while (hba) {
                                fprintf(stderr, "%s", hba->pci_id ? : "Err!");
                                if (hba->next)
@@ -2902,11 +2906,13 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, int verb
                free_sys_dev(&hba_name);
                return 2;
        }
+       super->orom = find_imsm_capability(hba_name->type);
        free_sys_dev(&hba_name);
+       if (!super->orom)
+               return 3;
        return 0;
 }
 
-
 #ifndef MDASSEMBLE
 /* find_missing - helper routine for load_super_imsm_all that identifies
  * disks that have disappeared from the system.  This routine relies on
@@ -3287,6 +3293,7 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
                struct intel_super *s = alloc_super();
                char nm[32];
                int dfd;
+               int rv;
 
                err = 1;
                if (!s)
@@ -3300,6 +3307,11 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
                if (dfd < 0)
                        goto error;
 
+               rv = find_intel_hba_capability(dfd, s, devname);
+               /* no orom/efi or non-intel hba of the disk */
+               if (rv != 0)
+                       goto error;
+
                err = load_and_parse_mpb(dfd, s, NULL, 1);
 
                /* retry the load if we might have raced against mdmon */
@@ -3374,6 +3386,15 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
                        sizeof(*super));
                return 1;
        }
+       rv = find_intel_hba_capability(fd, super, devname);
+       /* no orom/efi or non-intel hba of the disk */
+       if (rv != 0) {
+               if (devname)
+                       fprintf(stderr,
+                               Name ": No OROM/EFI properties for %s\n", devname);
+               free_imsm(super);
+               return 2;
+       }
 
        rv = load_and_parse_mpb(fd, super, devname, 0);
 
@@ -3767,8 +3788,8 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
         * We do not need to test disks attachment for container based additions,
         * they shall be already tested when container was created/assembled.
         */
-       rv = find_intel_hba_capability(fd, super, 1);
-       /* no intel hba of the disk */
+       rv = find_intel_hba_capability(fd, super, devname);
+       /* no orom/efi or non-intel hba of the disk */
        if (rv != 0) {
                dprintf("capability: %p fd: %d ret: %d\n",
                        super->orom, fd, rv);
@@ -4104,25 +4125,14 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
 {
        int fd;
        unsigned long long ldsize;
-       const struct imsm_orom *orom;
+       struct intel_super *super=NULL;
+       int rv = 0;
 
        if (level != LEVEL_CONTAINER)
                return 0;
        if (!dev)
                return 1;
 
-       if (check_env("IMSM_NO_PLATFORM"))
-               orom = NULL;
-       else
-               orom = find_imsm_orom();
-       if (orom && raiddisks > orom->tds) {
-               if (verbose)
-                       fprintf(stderr, Name ": %d exceeds maximum number of"
-                               " platform supported disks: %d\n",
-                               raiddisks, orom->tds);
-               return 0;
-       }
-
        fd = open(dev, O_RDONLY|O_EXCL, 0);
        if (fd < 0) {
                if (verbose)
@@ -4134,9 +4144,45 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
                close(fd);
                return 0;
        }
+
+       /* capabilities retrieve could be possible
+        * note that there is no fd for the disks in array.
+        */
+       super = alloc_super();
+       if (!super) {
+               fprintf(stderr,
+                       Name ": malloc of %zu failed.\n",
+                       sizeof(*super));
+               close(fd);
+               return 0;
+       }
+
+       rv = find_intel_hba_capability(fd, super, verbose ? dev : NULL);
+       if (rv != 0) {
+#if DEBUG
+               char str[256];
+               fd2devname(fd, str);
+               dprintf("validate_geometry_imsm_container: fd: %d %s orom: %p rv: %d raiddisk: %d\n",
+                       fd, str, super->orom, rv, raiddisks);
+#endif
+               /* no orom/efi or non-intel hba of the disk */
+               close(fd);
+               free_imsm(super);
+               return 0;
+       }
        close(fd);
+       if (super->orom && raiddisks > super->orom->tds) {
+               if (verbose)
+                       fprintf(stderr, Name ": %d exceeds maximum number of"
+                               " platform supported disks: %d\n",
+                               raiddisks, super->orom->tds);
+
+               free_imsm(super);
+               return 0;
+       }
 
        *freesize = avail_size_imsm(st, ldsize >> 9);
+       free_imsm(super);
 
        return 1;
 }