]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
split name/number maps into separate file.
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index 38750b248892e5eef8dcc1e38e42521ba5a64553..45e6873980f55b0ea96f3da7cc9bed6bea53a0eb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -160,6 +160,7 @@ int get_linux_version()
        return (a*1000000)+(b*1000)+c;
 }
 
+#ifndef MDASSEMBLE
 int mdadm_version(char *version)
 {
        int a, b, c;
@@ -185,7 +186,6 @@ int mdadm_version(char *version)
        return (a*1000000)+(b*1000)+c;
 }
 
-#ifndef MDASSEMBLE
 long long parse_size(char *size)
 {
        /* parse 'size' which should be a number optionally
@@ -566,27 +566,6 @@ int ask(char *mesg)
 }
 #endif /* MDASSEMBLE */
 
-char *map_num(mapping_t *map, int num)
-{
-       while (map->name) {
-               if (map->num == num)
-                       return map->name;
-               map++;
-       }
-       return NULL;
-}
-
-int map_name(mapping_t *map, char *name)
-{
-       while (map->name) {
-               if (strcmp(map->name, name)==0)
-                       return map->num;
-               map++;
-       }
-       return UnSet;
-}
-
-
 int is_standard(char *dev, int *nump)
 {
        /* tests if dev is a "standard" md dev name.
@@ -998,24 +977,34 @@ int dev_open(char *dev, int flags)
        return fd;
 }
 
-int open_dev(int devnum)
+int open_dev_flags(int devnum, int flags)
 {
        char buf[20];
 
        sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
-       return dev_open(buf, O_RDWR);
+       return dev_open(buf, flags);
+}
+
+int open_dev(int devnum)
+{
+       return open_dev_flags(devnum, O_RDONLY);
 }
 
 int open_dev_excl(int devnum)
 {
        char buf[20];
        int i;
+       int flags = O_RDWR;
 
        sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
        for (i=0 ; i<25 ; i++) {
-               int fd = dev_open(buf, O_RDWR|O_EXCL);
+               int fd = dev_open(buf, flags|O_EXCL);
                if (fd >= 0)
                        return fd;
+               if (errno == EACCES && flags == O_RDWR) {
+                       flags = O_RDONLY;
+                       continue;
+               }
                if (errno != EBUSY)
                        return fd;
                usleep(200000);
@@ -1191,6 +1180,7 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type)
                if (guess_type == guess_partitions && ss->add_to_super != NULL)
                        continue;
                memset(st, 0, sizeof(*st));
+               st->ignore_hw_compat = 1;
                rv = ss->load_super(st, fd, NULL);
                if (rv == 0) {
                        struct mdinfo info;
@@ -1206,9 +1196,11 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type)
        if (bestsuper != -1) {
                int rv;
                memset(st, 0, sizeof(*st));
+               st->ignore_hw_compat = 1;
                rv = superlist[bestsuper]->load_super(st, fd, NULL);
                if (rv == 0) {
                        superlist[bestsuper]->free_super(st);
+                       st->ignore_hw_compat = 0;
                        return st;
                }
        }
@@ -1370,7 +1362,8 @@ static int get_last_partition_end(int fd, unsigned long long *endofpart)
        return retval;
 }
 
-int check_partitions(int fd, char *dname, unsigned long long freesize)
+int check_partitions(int fd, char *dname, unsigned long long freesize,
+                       unsigned long long size)
 {
        /*
         * Check where the last partition ends
@@ -1393,6 +1386,12 @@ int check_partitions(int fd, char *dname, unsigned long long freesize)
                                Name ": metadata will over-write last partition on %s.\n",
                                dname);
                        return 1;
+               } else if (size && endofpart > size) {
+                       /* partitions will be truncated in new device */
+                       fprintf(stderr,
+                               Name ": array size is too small to cover all partitions on %s.\n",
+                               dname);
+                       return 1;
                }
        }
        return 0;
@@ -1490,8 +1489,7 @@ int is_subarray_active(char *subarray, char *container)
 
        for (ent = mdstat; ent; ent = ent->next)
                if (is_container_member(ent, container))
-                       if (!subarray ||
-                           strcmp(to_subarray(ent, container), subarray) == 0)
+                       if (strcmp(to_subarray(ent, container), subarray) == 0)
                                break;
 
        free_mdstat(mdstat);
@@ -1499,11 +1497,6 @@ int is_subarray_active(char *subarray, char *container)
        return ent != NULL;
 }
 
-int is_container_active(char *container)
-{
-       return is_subarray_active(NULL, container);
-}
-
 /* open_subarray - opens a subarray in a container
  * @dev: container device name
  * @st: empty supertype
@@ -1962,7 +1955,7 @@ struct mdinfo *container_choose_spares(struct supertype *st,
                                if (spare_group)
                                        pol_add(&pol, pol_domain,
                                                spare_group, NULL);
-                               if (!domain_test(domlist, pol, metadata))
+                               if (domain_test(domlist, pol, metadata) != 1)
                                        found = 0;
                                dev_policy_free(pol);
                        }