]> 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 c22bb3bdc3148dd00fe7bdd167a901d5879b427c..45e6873980f55b0ea96f3da7cc9bed6bea53a0eb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -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_RDONLY);
+       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;