]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdadm: test_and_add device policies implementation
authorMariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Thu, 29 Feb 2024 11:52:11 +0000 (12:52 +0100)
committerMariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Mon, 11 Mar 2024 10:08:20 +0000 (11:08 +0100)
Add support for three scenarios:
- obtaining array wide policies via fd,
- obtaining array wide policies via struct mdinfo,
- getting policies for particular drive from the request.

Add proper functions and make them extern. These functions are used
in next patches.

Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
mdadm.h
policy.c

diff --git a/mdadm.h b/mdadm.h
index 889f4a0f1ecf3adf8616313d1171eb5ed885dc46..af2bc714bacb96878e2ede6f7a7bd6ba8f2ee29b 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -1452,6 +1452,13 @@ extern void dev_policy_free(struct dev_policy *p);
 extern void pol_add(struct dev_policy **pol, char *name, char *val, char *metadata);
 extern struct dev_policy *pol_find(struct dev_policy *pol, char *name);
 
+extern mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols,
+                                                 int fd, const int verbose);
+extern mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+                                                       struct mdinfo *mdi, const int verbose);
+extern mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+                                                       int array_fd, const int verbose);
+
 enum policy_action {
        act_default,
        act_include,
index eee9ef63adda741eb89ae71e879a5dcde5ae05ae..4b85f62d967564172e09ce69d5302d48a91bbd07 100644 (file)
--- a/policy.c
+++ b/policy.c
@@ -397,6 +397,99 @@ struct dev_policy *path_policy(char **paths, char *type)
        return pol;
 }
 
+/**
+ * drive_test_and_add_policies() - get policies for drive and add them to pols.
+ * @st: supertype.
+ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL.
+ * @fd: device descriptor.
+ * @verbose: verbose flag.
+ *
+ * If supertype doesn't support this functionality return success. Use metadata handler to get
+ * policies.
+ */
+mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols, int fd,
+                                          const int verbose)
+{
+       if (!st->ss->test_and_add_drive_policies)
+               return MDADM_STATUS_SUCCESS;
+
+       if (st->ss->test_and_add_drive_policies(pols, fd, verbose) == MDADM_STATUS_SUCCESS) {
+               /* After successful call list cannot be empty */
+               assert(*pols);
+               return MDADM_STATUS_SUCCESS;
+       }
+
+       return MDADM_STATUS_ERROR;
+}
+
+/**
+ * sysfs_test_and_add_policies() - get policies for mddev and add them to pols.
+ * @st: supertype.
+ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL.
+ * @mdi: mdinfo describes the MD array, must have GET_DISKS option.
+ * @verbose: verbose flag.
+ *
+ * If supertype doesn't support this functionality return success. To get policies, all disks
+ * connected to mddev are analyzed.
+ */
+mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+                                                struct mdinfo *mdi, const int verbose)
+{
+       struct mdinfo *sd;
+
+       if (!st->ss->test_and_add_drive_policies)
+               return MDADM_STATUS_SUCCESS;
+
+       for (sd = mdi->devs; sd; sd = sd->next) {
+               char *devpath = map_dev(sd->disk.major, sd->disk.minor, 0);
+               int fd = dev_open(devpath, O_RDONLY);
+               int rv;
+
+               if (!is_fd_valid(fd)) {
+                       pr_err("Cannot open fd for %s\n", devpath);
+                       return MDADM_STATUS_ERROR;
+               }
+
+               rv = drive_test_and_add_policies(st, pols, fd, verbose);
+               close(fd);
+
+               if (rv)
+                       return MDADM_STATUS_ERROR;
+       }
+
+       return MDADM_STATUS_SUCCESS;
+}
+
+/**
+ * mddev_test_and_add_policies() - get policies for mddev and add them to pols.
+ * @st: supertype.
+ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL.
+ * @array_fd: MD device descriptor.
+ * @verbose: verbose flag.
+ *
+ * If supertype doesn't support this functionality return success. Use fd to extract disks.
+ */
+mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+                                                int array_fd, const int verbose)
+{
+       struct mdinfo *sra;
+       int ret;
+
+       if (!st->ss->test_and_add_drive_policies)
+               return MDADM_STATUS_SUCCESS;
+
+       sra = sysfs_read(array_fd, NULL, GET_DEVS);
+       if (!sra) {
+               pr_err("Cannot load sysfs for %s\n", fd2devnm(array_fd));
+               return MDADM_STATUS_ERROR;
+       }
+
+       ret = sysfs_test_and_add_drive_policies(st, pols, sra, verbose);
+
+       sysfs_free(sra);
+       return ret;
+}
+
 void pol_add(struct dev_policy **pol,
                    char *name, char *val,
                    char *metadata)