diff options
author | Xiao Ni <xni@redhat.com> | 2016-06-16 03:41:02 +0200 |
---|---|---|
committer | Jes Sorensen <Jes.Sorensen@redhat.com> | 2016-06-16 19:53:45 +0200 |
commit | 8800f85381d0cd9689dee62bbbdafdb359100389 (patch) | |
tree | 1c712dcc645e60a3a38f1ae137882524baf1ffa7 /Grow.c | |
parent | The sys_name array in the mdinfo structure is 20 bytes of storage. (diff) | |
download | mdadm-8800f85381d0cd9689dee62bbbdafdb359100389.tar.xz mdadm-8800f85381d0cd9689dee62bbbdafdb359100389.zip |
MDADM:Check mdinfo->reshape_active more times before calling Grow_continue
When reshaping a 3 drives raid5 to 4 drives raid5, there is a chance that
it can't start the reshape. If the disks are not enough to have spaces for
relocating the data_offset, it needs to call start_reshape and then run
mdadm --grow --continue by systemd. But mdadm --grow --continue fails
because it checkes that info->reshape_active is 0.
The info->reshape_active is got from the superblock of underlying devices.
Function start_reshape write reshape to /sys/../sync_action. Before writing
latest superblock to underlying devices, mdadm --grow --continue is called.
There is a chance info->reshape_active is 0. We should wait for superblock
updating more time before calling Grow_continue.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Diffstat (limited to 'Grow.c')
-rwxr-xr-x | Grow.c | 67 |
1 files changed, 37 insertions, 30 deletions
@@ -4788,6 +4788,7 @@ int Grow_continue_command(char *devname, int fd, dprintf("Grow continue is run for "); if (st->ss->external == 0) { int d; + int cnt = 5; dprintf_cont("native array (%s)\n", devname); if (ioctl(fd, GET_ARRAY_INFO, &array.array) < 0) { pr_err("%s is not an active md array - aborting\n", devname); @@ -4799,36 +4800,42 @@ int Grow_continue_command(char *devname, int fd, * FIXME we should really get what we need from * sysfs */ - for (d = 0; d < MAX_DISKS; d++) { - mdu_disk_info_t disk; - char *dv; - int err; - disk.number = d; - if (ioctl(fd, GET_DISK_INFO, &disk) < 0) - continue; - if (disk.major == 0 && disk.minor == 0) - continue; - if ((disk.state & (1 << MD_DISK_ACTIVE)) == 0) - continue; - dv = map_dev(disk.major, disk.minor, 1); - if (!dv) - continue; - fd2 = dev_open(dv, O_RDONLY); - if (fd2 < 0) - continue; - err = st->ss->load_super(st, fd2, NULL); - close(fd2); - if (err) - continue; - break; - } - if (d == MAX_DISKS) { - pr_err("Unable to load metadata for %s\n", - devname); - ret_val = 1; - goto Grow_continue_command_exit; - } - st->ss->getinfo_super(st, content, NULL); + do { + for (d = 0; d < MAX_DISKS; d++) { + mdu_disk_info_t disk; + char *dv; + int err; + disk.number = d; + if (ioctl(fd, GET_DISK_INFO, &disk) < 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; + if ((disk.state & (1 << MD_DISK_ACTIVE)) == 0) + continue; + dv = map_dev(disk.major, disk.minor, 1); + if (!dv) + continue; + fd2 = dev_open(dv, O_RDONLY); + if (fd2 < 0) + continue; + err = st->ss->load_super(st, fd2, NULL); + close(fd2); + if (err) + continue; + break; + } + if (d == MAX_DISKS) { + pr_err("Unable to load metadata for %s\n", + devname); + ret_val = 1; + goto Grow_continue_command_exit; + } + st->ss->getinfo_super(st, content, NULL); + if (!content->reshape_active) + sleep(3); + else + break; + } while (cnt-- > 0); } else { char *container; |