From: Mike T. <mik...@us...> - 2006-05-16 20:50:28
|
Update of /cvsroot/evms/evms2/engine/plugins/md In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv2589 Modified Files: raid5_mgr.c Log Message: Sync up CVS with MD patches for 2.5.5: - Fix memory leak in raid5_create_conf() - Allow "remove spare" for active degraded raid5 array which is very unlikely scenario. This will only happen if the kernel refuses to pick up the spare to start the recovery. An EVMS user reported this problem using Slackware and 2.4.26 kernel. Index: raid5_mgr.c =================================================================== RCS file: /cvsroot/evms/evms2/engine/plugins/md/raid5_mgr.c,v retrieving revision 1.113 retrieving revision 1.114 diff -u -d -r1.113 -r1.114 --- raid5_mgr.c 2 May 2006 16:48:21 -0000 1.113 +++ raid5_mgr.c 16 May 2006 20:50:23 -0000 1.114 @@ -121,8 +121,10 @@ conf_disks = (info.raid_disks > info.nr_disks) ? info.raid_disks : info.nr_disks; /* - * If a spare is added to fix a degrade array, - * its index will be out nr_disks range. + * If a spare is added to fix a degrade array and recovery is running, + * its index could be greater than nr_disks. + * We should take this into account when allocating memory for disks. + * * Check disk index of each member and adjust conf_disks if necessary. */ LIST_FOR_EACH(vol->members, iter, member) { @@ -135,6 +137,7 @@ } conf->disks = EngFncs->engine_alloc(sizeof(disk_info_t) * conf_disks); + conf->stripe.nr_disks = conf_disks; conf->stripe.chunks = EngFncs->engine_alloc(sizeof(chunk_t) * conf_disks); /* Set the volume to which the stripe belongs. */ @@ -3408,15 +3411,9 @@ /* Clear out the spare_disks list. */ EngFncs->delete_all_elements(spare_disks); - /* - * If there is only one spare and the array is in degrade mode, then - * the spare cannot be removed. - */ - if (vol->spare_disks <= 1) { - if (vol->flags & MD_DEGRADED) { - LOG_EXIT_INT(0); - return 0; - } + if ((vol->flags & MD_DEGRADED) && (vol->spare_disks > 0)) { + LOG_WARNING("%s is degraded, but there are %d spare disk(s).\n", + vol->name, vol->spare_disks); } LIST_FOR_EACH(vol->members, iter, member) { @@ -4336,7 +4333,9 @@ * least one spare is available. */ if (count && - (conf->active_disks < conf->raid_disks)) { + (volume->flags & MD_DEGRADED) && + (volume->spare_disks == 1) && + (!(volume->region->flags & SOFLAG_ACTIVE)) ) { MESSAGE(_("At least one spare object must be left for recovering degraded array %s.\n"), volume->region->name); @@ -5682,10 +5681,13 @@ LOG_EXIT_INT(rc); return rc; } - if (vol->flags & MD_DEGRADED) { - LOG_ERROR("Array %s is running in degrade mode. " - "At least one spare must be left for the array to recover.\n", + if ((vol->flags & MD_DEGRADED) && + (!(vol->region->flags & SOFLAG_ACTIVE)) ) { + MESSAGE(_("Array %s is running in degrade mode. " + "At least one spare must be left for the array to recover.\n"), vol->region->name); + LOG_EXIT_INT(EINVAL); + return EINVAL; } break; |