]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
Disk removal support for Raid10->Raid0 takeover
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index ad2ec923bf8559d476573e404f0c807b64793e5b..fde58ebbeffa6271c93e01abae14c5880221e0f6 100644 (file)
--- a/util.c
+++ b/util.c
@@ -160,6 +160,31 @@ int get_linux_version()
        return (a*1000000)+(b*1000)+c;
 }
 
+int mdadm_version(char *version)
+{
+       int a, b, c;
+       char *cp;
+
+       if (!version)
+               version = Version;
+
+       cp = strchr(version, '-');
+       if (!cp || *(cp+1) != ' ' || *(cp+2) != 'v')
+               return -1;
+       cp += 3;
+       a = strtoul(cp, &cp, 10);
+       if (*cp != '.')
+               return -1;
+       b = strtoul(cp+1, &cp, 10);
+       if (*cp == '.')
+               c = strtoul(cp+1, &cp, 10);
+       else
+               c = 0;
+       if (*cp != ' ' && *cp != '-')
+               return -1;
+       return (a*1000000)+(b*1000)+c;
+}
+
 #ifndef MDASSEMBLE
 long long parse_size(char *size)
 {
@@ -1043,6 +1068,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
        char version[20];
        int i;
        char *subarray = NULL;
+       int container = NoMdDev;
 
        sra = sysfs_read(fd, 0, GET_VERSION);
 
@@ -1064,15 +1090,15 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
        }
        if (minor == -2 && is_subarray(verstr)) {
                char *dev = verstr+1;
+
                subarray = strchr(dev, '/');
-               int devnum;
                if (subarray)
                        *subarray++ = '\0';
-               devnum = devname2devnum(dev);
                subarray = strdup(subarray);
+               container = devname2devnum(dev);
                if (sra)
                        sysfs_free(sra);
-               sra = sysfs_read(-1, devnum, GET_VERSION);
+               sra = sysfs_read(-1, container, GET_VERSION);
                if (sra && sra->text_version[0])
                        verstr = sra->text_version;
                else
@@ -1088,13 +1114,16 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
                st->sb = NULL;
                if (subarrayp)
                        *subarrayp = subarray;
+               st->container_dev = container;
+               st->devnum = fd2devnum(fd);
        } else
                free(subarray);
+
        return st;
 }
 #endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
 
-int dev_size_from_id(unsigned int id, unsigned long long *size)
+int dev_size_from_id(dev_t id, unsigned long long *size)
 {
        char buf[20];
        int fd;
@@ -1597,6 +1626,21 @@ int add_disk(int mdfd, struct supertype *st,
        return rv;
 }
 
+int remove_disk(int mdfd, struct supertype *st,
+               struct mdinfo *sra, struct mdinfo *info)
+{
+       int rv;
+       /* Remove the disk given by 'info' from the array */
+#ifndef MDASSEMBLE
+       if (st->ss->external)
+               rv = sysfs_set_str(sra, info, "slot", "none");
+       else
+#endif
+               rv = ioctl(mdfd, HOT_REMOVE_DISK, makedev(info->disk.major,
+                                                         info->disk.minor));
+       return rv;
+}
+
 int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
 {
        /* Initialise kernel's knowledge of array.