+
+int devname_matches(char *name, char *match)
+{
+ /* See if the given array name matches the
+ * given match from config file.
+ *
+ * First strip and /dev/md/ or /dev/, then
+ * see if there might be a numeric match of
+ * mdNN with NN
+ * then just strcmp
+ */
+ if (strncmp(name, "/dev/md/", 8) == 0)
+ name += 8;
+ else if (strncmp(name, "/dev/", 5) == 0)
+ name += 5;
+
+ if (strncmp(match, "/dev/md/", 8) == 0)
+ match += 8;
+ else if (strncmp(match, "/dev/", 5) == 0)
+ match += 5;
+
+
+ if (strncmp(name, "md", 2) == 0 &&
+ isdigit(name[2]))
+ name += 2;
+ if (strncmp(match, "md", 2) == 0 &&
+ isdigit(match[2]))
+ match += 2;
+
+ return (strcmp(name, match) == 0);
+}
+
+int conf_name_is_free(char *name)
+{
+ /* Check if this name is already take by an ARRAY entry in
+ * the config file.
+ * It can be taken either by a match on devname, name, or
+ * even super-minor.
+ */
+ mddev_ident_t dev;
+
+ load_conffile();
+ for (dev = mddevlist; dev; dev = dev->next) {
+ char nbuf[100];
+ if (dev->devname && devname_matches(name, dev->devname))
+ return 0;
+ if (dev->name[0] && devname_matches(name, dev->name))
+ return 0;
+ sprintf(nbuf, "%d", dev->super_minor);
+ if (dev->super_minor != UnSet &&
+ devname_matches(name, nbuf))
+ return 0;
+ }
+ return 1;
+}
+
+struct mddev_ident_s *conf_match(struct mdinfo *info, struct supertype *st)
+{
+ struct mddev_ident_s *array_list, *match;
+ int verbose = 0;
+ char *devname = NULL;
+ array_list = conf_get_ident(NULL);
+ match = NULL;
+ for (; array_list; array_list = array_list->next) {
+ if (array_list->uuid_set &&
+ same_uuid(array_list->uuid, info->uuid, st->ss->swapuuid)
+ == 0) {
+ if (verbose >= 2 && array_list->devname)
+ fprintf(stderr, Name
+ ": UUID differs from %s.\n",
+ array_list->devname);
+ continue;
+ }
+ if (array_list->name[0] &&
+ strcasecmp(array_list->name, info->name) != 0) {
+ if (verbose >= 2 && array_list->devname)
+ fprintf(stderr, Name
+ ": Name differs from %s.\n",
+ array_list->devname);
+ continue;
+ }
+ if (array_list->devices && devname &&
+ !match_oneof(array_list->devices, devname)) {
+ if (verbose >= 2 && array_list->devname)
+ fprintf(stderr, Name
+ ": Not a listed device for %s.\n",
+ array_list->devname);
+ continue;
+ }
+ if (array_list->super_minor != UnSet &&
+ array_list->super_minor != info->array.md_minor) {
+ if (verbose >= 2 && array_list->devname)
+ fprintf(stderr, Name
+ ": Different super-minor to %s.\n",
+ array_list->devname);
+ continue;
+ }
+ if (!array_list->uuid_set &&
+ !array_list->name[0] &&
+ !array_list->devices &&
+ array_list->super_minor == UnSet) {
+ if (verbose >= 2 && array_list->devname)
+ fprintf(stderr, Name
+ ": %s doesn't have any identifying information.\n",
+ array_list->devname);
+ continue;
+ }
+ /* FIXME, should I check raid_disks and level too?? */
+
+ if (match) {
+ if (verbose >= 0) {
+ if (match->devname && array_list->devname)
+ fprintf(stderr, Name
+ ": we match both %s and %s - cannot decide which to use.\n",
+ match->devname, array_list->devname);
+ else
+ fprintf(stderr, Name
+ ": multiple lines in mdadm.conf match\n");
+ }
+ return NULL;
+ }
+ match = array_list;
+ }
+ return match;
+}