diff options
author | Anna Czarnowska <anna.czarnowska@intel.com> | 2011-01-05 14:34:32 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-01-05 14:34:32 +1100 |
commit | d52bb542d406071d7be6c180703d981a07eb8aed (patch) | |
tree | 39eda94f9caca4e59c34227e0912f0bcb82adb23 /Manage.c | |
parent | 326727d9c985b8f58fd53d6efcc4bd6e1721bfb5 (diff) | |
download | mdadm-d52bb542d406071d7be6c180703d981a07eb8aed.tar.gz |
move_spare function modified and moved to Manage.c
It will also be needed for Incremental.
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Manage.c')
-rw-r--r-- | Manage.c | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -1096,4 +1096,48 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident return rv; } + +/* Move spare from one array to another + * If adding to destination array fails + * add back to original array + * Returns 1 on success, 0 on failure */ +int move_spare(char *from_devname, char *to_devname, dev_t devid) +{ + struct mddev_dev devlist; + char devname[20]; + + /* try to remove and add */ + int fd1 = open(to_devname, O_RDONLY); + int fd2 = open(from_devname, O_RDONLY); + + if (fd1 < 0 || fd2 < 0) { + if (fd1>=0) close(fd1); + if (fd2>=0) close(fd2); + return 0; + } + + devlist.next = NULL; + devlist.used = 0; + devlist.re_add = 0; + devlist.writemostly = 0; + devlist.devname = devname; + sprintf(devname, "%d:%d", major(devid), minor(devid)); + + devlist.disposition = 'r'; + if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL) == 0) { + devlist.disposition = 'a'; + if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, NULL) == 0) { + /* make sure manager is aware of changes */ + ping_manager(to_devname); + ping_manager(from_devname); + close(fd1); + close(fd2); + return 1; + } + else Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL); + } + close(fd1); + close(fd2); + return 0; +} #endif |