]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-intel.c
mdmon: allow prepare_update to report failure.
[thirdparty/mdadm.git] / super-intel.c
index 0106b4f699ff661f04274c8349601fa44bd18212..2547b4a4b6aebc9944a05a6d09ab43fb8a026468 100644 (file)
@@ -8607,8 +8607,8 @@ static void imsm_process_update(struct supertype *st,
 
 static struct mdinfo *get_spares_for_grow(struct supertype *st);
 
-static void imsm_prepare_update(struct supertype *st,
-                               struct metadata_update *update)
+static int imsm_prepare_update(struct supertype *st,
+                              struct metadata_update *update)
 {
        /**
         * Allocate space to hold new disk entries, raid-device entries or a new
@@ -8828,6 +8828,7 @@ static void imsm_prepare_update(struct supertype *st,
                else
                        super->next_buf = NULL;
        }
+       return 1;
 }
 
 /* must be called while manager is quiesced */
@@ -9716,8 +9717,8 @@ static void imsm_update_metadata_locally(struct supertype *st,
        mu.space = NULL;
        mu.space_list = NULL;
        mu.next = NULL;
-       imsm_prepare_update(st, &mu);
-       imsm_process_update(st, &mu);
+       if (imsm_prepare_update(st, &mu))
+               imsm_process_update(st, &mu);
 
        while (mu.space_list) {
                void **space = mu.space_list;
@@ -10484,6 +10485,48 @@ abort:
 
        return ret_val;
 }
+
+/*******************************************************************************
+ * Function:   validate_container_imsm
+ * Description: This routine validates container after assemble,
+ *             eg. if devices in container are under the same controller.
+ *
+ * Parameters:
+ *     info    : linked list with info about devices used in array
+ * Returns:
+ *     1 : HBA mismatch
+ *     0 : Success
+ ******************************************************************************/
+int validate_container_imsm(struct mdinfo *info)
+{
+       if (!check_env("IMSM_NO_PLATFORM")) {
+               struct sys_dev *idev;
+               struct mdinfo *dev;
+               char *hba_path = NULL;
+               char *dev_path = devt_to_devpath(makedev(info->disk.major,
+                                                                               info->disk.minor));
+
+               for (idev = find_intel_devices(); idev; idev = idev->next) {
+                       if (strstr(dev_path, idev->path)) {
+                               hba_path = idev->path;
+                               break;
+                       }
+               }
+               free(dev_path);
+
+               if (hba_path) {
+                       for (dev = info->next; dev; dev = dev->next) {
+                               if (!devt_attached_to_hba(makedev(dev->disk.major,
+                                               dev->disk.minor), hba_path)) {
+                                       pr_err("WARNING - IMSM container assembled with disks under different HBAs!\n"
+                                               "       This operation is not supported and can lead to data loss.\n");
+                                       return 1;
+                               }
+                       }
+               }
+       }
+       return 0;
+}
 #endif /* MDASSEMBLE */
 
 struct superswitch super_imsm = {
@@ -10527,6 +10570,7 @@ struct superswitch super_imsm = {
        .free_super     = free_super_imsm,
        .match_metadata_desc = match_metadata_desc_imsm,
        .container_content = container_content_imsm,
+       .validate_container = validate_container_imsm,
 
        .external       = 1,
        .name = "imsm",