close(d->state_fd);
}
- close(aa->action_fd);
- close(aa->info.state_fd);
- close(aa->resync_start_fd);
- close(aa->metadata_fd);
- close(aa->sync_completed_fd);
+ if (aa->action_fd >= 0)
+ close(aa->action_fd);
+ if (aa->info.state_fd >= 0)
+ close(aa->info.state_fd);
+ if (aa->resync_start_fd >= 0)
+ close(aa->resync_start_fd);
+ if (aa->metadata_fd >= 0)
+ close(aa->metadata_fd);
+ if (aa->sync_completed_fd >= 0)
+ close(aa->sync_completed_fd);
}
static void free_aa(struct active_array *aa)
static struct active_array *duplicate_aa(struct active_array *aa)
{
- struct active_array *newa = malloc(sizeof(*newa));
+ struct active_array *newa = xmalloc(sizeof(*newa));
struct mdinfo **dp1, **dp2;
*newa = *aa;
if ((*dp1)->state_fd < 0)
continue;
- d = malloc(sizeof(*d));
+ d = xmalloc(sizeof(*d));
*d = **dp1;
*dp2 = d;
dp2 = & d->next;
di->disk.minor == cd->disk.minor)
break;
if (!cd) {
- struct mdinfo *newd = malloc(sizeof(*newd));
+ struct mdinfo *newd = xmalloc(sizeof(*newd));
- if (!newd) {
- container->devcnt = -1;
- continue;
- }
*newd = *di;
add_disk_to_container(container, newd);
}
*disk = *clone;
disk->recovery_fd = sysfs_open(aa->devnum, disk->sys_name, "recovery_start");
+ if (disk->recovery_fd < 0)
+ return -1;
disk->state_fd = sysfs_open(aa->devnum, disk->sys_name, "state");
+ if (disk->state_fd < 0) {
+ close(disk->recovery_fd);
+ return -1;
+ }
disk->prev_state = read_dev_state(disk->state_fd);
disk->curr_state = disk->prev_state;
disk->next = aa->info.devs;
if (mdstat->level) {
int level = map_name(pers, mdstat->level);
if (level == 0 || level == LEVEL_LINEAR) {
- a->container = NULL;
+ a->to_remove = 1;
+ wakeup_monitor();
return;
}
else if (a->info.array.level != level && level > 0) {
}
}
+ /* we are after monitor kick,
+ * so container field can be cleared - check it again
+ */
+ if (a->container == NULL)
+ return;
+
/* We don't check the array while any update is pending, as it
* might container a change (such as a spare assignment) which
* could affect our decisions.
newa = duplicate_aa(a);
if (!newa)
goto out;
- /* Cool, we can add a device or several. */
+ /* prevent the kernel from activating the disk(s) before we
+ * finish adding them
+ */
+ sysfs_set_str(&a->info, NULL, "sync_action", "frozen");
/* Add device to array and set offset/size/slot.
* and open files for each newdev */
for (d = newdev; d ; d = d->next) {
struct mdinfo *newd;
- newd = malloc(sizeof(*newd));
- if (!newd)
- continue;
+ newd = xmalloc(sizeof(*newd));
if (sysfs_add_disk(&newa->info, d, 0) < 0) {
free(newd);
continue;
if (!newa)
break;
}
- newd = malloc(sizeof(*newd));
- if (!newd)
- continue;
+ newd = xmalloc(sizeof(*newd));
disk_init_and_add(newd, d, newa);
}
if (sysfs_get_ll(info, NULL, "array_size", &array_size) == 0
GET_LEVEL|GET_CHUNK|GET_DISKS|GET_COMPONENT|
GET_DEGRADED|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE);
- new = malloc(sizeof(*new));
- if (!new || !mdi) {
- if (mdi)
- sysfs_free(mdi);
- if (new)
- free(new);
+ if (!mdi)
return;
- }
- memset(new, 0, sizeof(*new));
+ new = xcalloc(1, sizeof(*new));
new->devnum = mdstat->devnum;
strcpy(new->info.sys_name, devnum2devname(new->devnum));
new->info.component_size = mdi->component_size;
for (i = 0; i < new->info.array.raid_disks; i++) {
- struct mdinfo *newd = malloc(sizeof(*newd));
+ struct mdinfo *newd = xmalloc(sizeof(*newd));
for (di = mdi->devs; di; di = di->next)
if (i == di->disk.raid_disk)
/* Looks like a member of this container */
for (a = container->arrays; a; a = a->next) {
if (mdstat->devnum == a->devnum) {
- if (a->container)
+ if (a->container && a->to_remove == 0)
manage_member(mdstat, a);
break;
}
manage(mdstat, container);
free_mdstat(mdstat);
} else if (!sigterm) {
- mu = malloc(sizeof(*mu));
+ mu = xmalloc(sizeof(*mu));
mu->len = msg->len;
mu->buf = msg->buf;
msg->buf = NULL;