From 63b4aae33ebf00d443378daf313622630f2336c0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 29 Apr 2010 10:50:29 -0700 Subject: mdmon: fix missing open of md//recovery_start When activating a spare we neglect to open recovery_start and as such do not see checkpoint events. Move disk initialization to common routine to mitigate recurrence. Reported-by: Adam Kwolek Signed-off-by: Dan Williams --- managemon.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/managemon.c b/managemon.c index 037406f..454c39d 100644 --- a/managemon.c +++ b/managemon.c @@ -361,6 +361,23 @@ static void manage_container(struct mdstat_ent *mdstat, } } +static int disk_init_and_add(struct mdinfo *disk, struct mdinfo *clone, + struct active_array *aa) +{ + if (!disk || !clone) + return -1; + + *disk = *clone; + disk->recovery_fd = sysfs_open(aa->devnum, disk->sys_name, "recovery_start"); + disk->state_fd = sysfs_open(aa->devnum, disk->sys_name, "state"); + disk->prev_state = read_dev_state(disk->state_fd); + disk->curr_state = disk->prev_state; + disk->next = aa->info.devs; + aa->info.devs = disk; + + return 0; +} + static void manage_member(struct mdstat_ent *mdstat, struct active_array *a) { @@ -414,14 +431,7 @@ static void manage_member(struct mdstat_ent *mdstat, free(newd); continue; } - *newd = *d; - newd->next = newa->info.devs; - newa->info.devs = newd; - - newd->state_fd = sysfs_open(a->devnum, newd->sys_name, - "state"); - newd->prev_state = read_dev_state(newd->state_fd); - newd->curr_state = newd->prev_state; + disk_init_and_add(newd, d, newa); } queue_metadata_update(updates); updates = NULL; @@ -513,19 +523,7 @@ static void manage_new(struct mdstat_ent *mdstat, if (i == di->disk.raid_disk) break; - if (di && newd) { - memcpy(newd, di, sizeof(*newd)); - - newd->state_fd = sysfs_open(new->devnum, - newd->sys_name, - "state"); - newd->recovery_fd = sysfs_open(new->devnum, - newd->sys_name, - "recovery_start"); - - newd->prev_state = read_dev_state(newd->state_fd); - newd->curr_state = newd->prev_state; - } else { + if (disk_init_and_add(newd, di, new) != 0) { if (newd) free(newd); @@ -535,11 +533,7 @@ static void manage_new(struct mdstat_ent *mdstat, new->container = NULL; break; } - continue; } - sprintf(newd->sys_name, "rd%d", i); - newd->next = new->info.devs; - new->info.devs = newd; } new->action_fd = sysfs_open(new->devnum, NULL, "sync_action"); -- cgit From 10013317ce51c6b619f9782b55e9b6b9f536f0a8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Hawrylewicz Czarnowski Date: Thu, 22 Apr 2010 23:10:32 +0100 Subject: fix: memory leak in mdmon_pid() devnum2devname() returns pointer to memory allocated with strdup. It must be released to prevent memory leak. Signed-off-by: Przemyslaw Czarnowski Signed-off-by: Dan Williams --- util.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util.c b/util.c index 25f1e56..8315200 100644 --- a/util.c +++ b/util.c @@ -1532,7 +1532,11 @@ int mdmon_pid(int devnum) char pid[10]; int fd; int n; - sprintf(path, "%s/%s.pid", pid_dir, devnum2devname(devnum)); + char *devname = devnum2devname(devnum); + + sprintf(path, "%s/%s.pid", pid_dir, devname); + free(devname); + fd = open(path, O_RDONLY | O_NOATIME, 0); if (fd < 0) -- cgit From 4363fd80bcc9f85ed824228dee5e6350a8d73e18 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 13:33:43 -0700 Subject: imsm: robustify recovery-start detection update_recovery_start() assumed that the out-of-sync disk would always be marked as IMSM_ORD_REBUILD in the disk_ord_tbl, but the segmentation fault reported by Andy proves otherwise. This might also be explained by an interrupted rebuild and the disk has not yet been marked missing. https://bugzilla.redhat.com/show_bug.cgi?id=592030 Reported-by: Andy Lutomirski Signed-off-by: Dan Williams --- super-intel.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/super-intel.c b/super-intel.c index bdd7a96..dd9699d 100644 --- a/super-intel.c +++ b/super-intel.c @@ -4044,6 +4044,15 @@ static void update_recovery_start(struct imsm_dev *dev, struct mdinfo *array) rebuild = d; } + if (!rebuild) { + /* (?) none of the disks are marked with + * IMSM_ORD_REBUILD, so assume they are missing and the + * disk_ord_tbl was not correctly updated + */ + dprintf("%s: failed to locate out-of-sync disk\n", __func__); + return; + } + units = __le32_to_cpu(dev->vol.curr_migr_unit); rebuild->recovery_start = units * blocks_per_migr_unit(dev); } -- cgit