"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "Assemble.c" between
mdadm-4.2-rc1.tar.xz and mdadm-4.2-rc2.tar.xz

About: mdadm is a tool for creating, managing and monitoring device arrays using the "md" driver in Linux, also known as Software RAID arrays.

Assemble.c  (mdadm-4.2-rc1.tar.xz):Assemble.c  (mdadm-4.2-rc2.tar.xz)
skipping to change at line 28 skipping to change at line 28
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Author: Neil Brown * Author: Neil Brown
* Email: <neilb@suse.de> * Email: <neilb@suse.de>
*/ */
#include "mdadm.h" #include "mdadm.h"
#include <ctype.h> #include <ctype.h>
mapping_t assemble_statuses[] = {
{ "but cannot be started", INCR_NO },
{ "but not safe to start", INCR_UNSAFE },
{ "and started", INCR_YES },
{ NULL, INCR_ALREADY }
};
/**
* struct assembly_array_info - General, meaningful information for assembly.
* @name: Array name.
* @new_cnt: Count of drives known to be members, recently added.
* @preexist_cnt: Count of member drives in pre-assembled array.
* @exp_cnt: Count of known expansion targets.
*
* FIXME: @exp_new_cnt for recently added expansion targets.
*/
struct assembly_array_info {
char *name;
int new_cnt;
int preexist_cnt;
int exp_cnt;
};
/**
* set_array_assembly_status() - generate status of assembly for an array.
* @c: Global settings.
* @result: Pointer to status mask.
* @status: Status to be set/printed.
* @arr: Array information.
*
* Print status message to user or set it in @result if it is not NULL.
*/
static void set_array_assembly_status(struct context *c,
int *result, int status,
struct assembly_array_info *arr)
{
int raid_disks = arr->preexist_cnt + arr->new_cnt;
char *status_msg = map_num(assemble_statuses, status);
if (c->export && result)
*result |= status;
if (c->export || c->verbose < 0)
return;
pr_err("%s has been assembled with %d device%s", arr->name,
raid_disks, raid_disks == 1 ? "":"s");
if (arr->preexist_cnt > 0)
fprintf(stderr, " (%d new)", arr->new_cnt);
if (arr->exp_cnt)
fprintf(stderr, " ( + %d for expansion)", arr->exp_cnt);
if (status_msg)
fprintf(stderr, " %s", status_msg);
fprintf(stderr, ".\n");
}
static int name_matches(char *found, char *required, char *homehost, int require _homehost) static int name_matches(char *found, char *required, char *homehost, int require _homehost)
{ {
/* See if the name found matches the required name, possibly /* See if the name found matches the required name, possibly
* prefixed with 'homehost' * prefixed with 'homehost'
*/ */
char *sep; char *sep;
unsigned int l; unsigned int l;
if (strcmp(found, required)==0) if (strcmp(found, required)==0)
return 1; return 1;
skipping to change at line 277 skipping to change at line 333
if (dfd >= 0) close(dfd); if (dfd >= 0) close(dfd);
if (tmpdev->used == 2) { if (tmpdev->used == 2) {
if (auto_assem || !inargv) if (auto_assem || !inargv)
/* Ignore unrecognised devices during auto-assemb ly */ /* Ignore unrecognised devices during auto-assemb ly */
goto loop; goto loop;
if (ident->name[0] || if (ident->name[0] ||
ident->super_minor != UnSet) ident->super_minor != UnSet)
/* Ignore unrecognised device if looking for /* Ignore unrecognised device if looking for
* specific array */ * specific array */
goto loop; goto loop;
if (ident->uuid_set)
/* ignore unrecognized device if looking for
* specific uuid
*/
goto loop;
pr_err("%s has no superblock - assembly aborted\n", pr_err("%s has no superblock - assembly aborted\n",
devname); devname);
if (st) if (st)
st->ss->free_super(st); st->ss->free_super(st);
dev_policy_free(pol); dev_policy_free(pol);
domain_free(domains); domain_free(domains);
if (tst) if (tst)
tst->ss->free_super(tst); tst->ss->free_super(tst);
return -1; return -1;
skipping to change at line 1914 skipping to change at line 1975
return 1; return 1;
} }
return rv == 2 ? 0 : rv; return rv == 2 ? 0 : rv;
} }
int assemble_container_content(struct supertype *st, int mdfd, int assemble_container_content(struct supertype *st, int mdfd,
struct mdinfo *content, struct context *c, struct mdinfo *content, struct context *c,
char *chosen_name, int *result) char *chosen_name, int *result)
{ {
struct mdinfo *dev, *sra, *dev2; struct mdinfo *dev, *sra, *dev2;
int working = 0, preexist = 0; struct assembly_array_info array = {chosen_name, 0, 0, 0};
int expansion = 0;
int old_raid_disks; int old_raid_disks;
int start_reshape; int start_reshape;
char *avail; char *avail;
int err; int err;
int is_raid456, is_clean, all_disks;
if (sysfs_init(content, mdfd, NULL)) { if (sysfs_init(content, mdfd, NULL)) {
pr_err("Unable to initialize sysfs\n"); pr_err("Unable to initialize sysfs\n");
return 1; return 1;
} }
sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS); sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS);
if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) { if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) {
if (content->array.major_version == -1 && if (content->array.major_version == -1 &&
content->array.minor_version == -2 && content->array.minor_version == -2 &&
skipping to change at line 1976 skipping to change at line 2037
sysfs_set_str(sra, dev2, "state", "remove"); sysfs_set_str(sra, dev2, "state", "remove");
} }
old_raid_disks = content->array.raid_disks - content->delta_disks; old_raid_disks = content->array.raid_disks - content->delta_disks;
avail = xcalloc(content->array.raid_disks, 1); avail = xcalloc(content->array.raid_disks, 1);
for (dev = content->devs; dev; dev = dev->next) { for (dev = content->devs; dev; dev = dev->next) {
if (dev->disk.raid_disk >= 0) if (dev->disk.raid_disk >= 0)
avail[dev->disk.raid_disk] = 1; avail[dev->disk.raid_disk] = 1;
if (sysfs_add_disk(content, dev, 1) == 0) { if (sysfs_add_disk(content, dev, 1) == 0) {
if (dev->disk.raid_disk >= old_raid_disks && if (dev->disk.raid_disk >= old_raid_disks &&
content->reshape_active) content->reshape_active)
expansion++; array.exp_cnt++;
else else
working++; array.new_cnt++;
} else if (errno == EEXIST) } else if (errno == EEXIST)
preexist++; array.preexist_cnt++;
} }
sysfs_free(sra); sysfs_free(sra);
if (working + expansion == 0 && c->runstop <= 0) {
free(avail); all_disks = array.new_cnt + array.exp_cnt + array.preexist_cnt;
return 1;/* Nothing new, don't try to start */
}
map_update(NULL, fd2devnm(mdfd), content->text_version, map_update(NULL, fd2devnm(mdfd), content->text_version,
content->uuid, chosen_name); content->uuid, chosen_name);
if (content->consistency_policy == CONSISTENCY_POLICY_PPL && if (content->consistency_policy == CONSISTENCY_POLICY_PPL &&
st->ss->validate_ppl) { st->ss->validate_ppl) {
content->array.state |= 1; content->array.state |= 1;
err = 0; err = 0;
for (dev = content->devs; dev; dev = dev->next) { for (dev = content->devs; dev; dev = dev->next) {
int dfd; int dfd;
skipping to change at line 2048 skipping to change at line 2108
/* Set the array as 'clean' so that we can proceed with starting /* Set the array as 'clean' so that we can proceed with starting
* it even if we don't have all devices. Mdmon doesn't care * it even if we don't have all devices. Mdmon doesn't care
* if the dirty flag is set in metadata, it will start managing * if the dirty flag is set in metadata, it will start managing
* it anyway. * it anyway.
* This is really important for raid456 (RWH case), other levels * This is really important for raid456 (RWH case), other levels
* are started anyway. * are started anyway.
*/ */
content->array.state |= 1; content->array.state |= 1;
} }
is_raid456 = (content->array.level >= 4 && content->array.level <= 6);
is_clean = content->array.state & 1;
if (enough(content->array.level, content->array.raid_disks, if (enough(content->array.level, content->array.raid_disks,
content->array.layout, content->array.state & 1, avail) == 0) content->array.layout, is_clean, avail) == 0) {
{ set_array_assembly_status(c, result, INCR_NO, &array);
if (c->export && result)
*result |= INCR_NO; if (c->verbose >= 0 && is_raid456 && !is_clean)
else if (c->verbose >= 0) { pr_err("Consider --force to start dirty degraded array\n"
pr_err("%s assembled with %d device%s", );
chosen_name, preexist + working,
preexist + working == 1 ? "":"s");
if (preexist)
fprintf(stderr, " (%d new)", working);
fprintf(stderr, " but not started\n");
}
free(avail); free(avail);
return 1; return 1;
} }
free(avail); free(avail);
if ((working + preexist + expansion) < content->array.working_disks) { if (c->runstop <= 0 && all_disks < content->array.working_disks) {
if (c->runstop <= 0) {
if (c->export && result) set_array_assembly_status(c, result, INCR_UNSAFE, &array);
*result |= INCR_UNSAFE;
else if (c->verbose >= 0) { if (c->verbose >= 0 && c->force)
pr_err("%s assembled with %d device%s", pr_err("Consider --run to start array as degraded.\n");
chosen_name, preexist + working, return 1;
preexist + working == 1 ? "":"s"); }
if (preexist)
fprintf(stderr, " (%d new)", working); if (is_raid456 && content->resync_start != MaxSector && c->force &&
fprintf(stderr, " but not safe to start\n"); all_disks < content->array.raid_disks) {
if (c->force)
pr_err("Consider --run to start array as content->resync_start = MaxSector;
degraded.\n"); err = sysfs_set_num(content, NULL, "resync_start", MaxSector);
} if (err)
return 1; return 1;
} else if (content->array.level >= 4 &&
content->array.level <= 6 && pr_err("%s array state forced to clean. It may cause data corrupt
content->resync_start != MaxSector && ion.\n",
c->force) { chosen_name);
/* Don't inform the kernel that the array is not
* clean and requires resync.
*/
content->resync_start = MaxSector;
err = sysfs_set_num(content, NULL, "resync_start",
MaxSector);
if (err)
return 1;
pr_err("%s array state forced to clean. It may cause data
corruption.\n",
chosen_name);
}
} }
/* /*
* Before activating the array, perform extra steps required * Before activating the array, perform extra steps required
* to configure the internal write-intent bitmap. * to configure the internal write-intent bitmap.
*/ */
if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP && if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP &&
st->ss->set_bitmap) st->ss->set_bitmap)
st->ss->set_bitmap(st, content); st->ss->set_bitmap(st, content);
if (start_reshape) { if (start_reshape) {
int spare = content->array.raid_disks + expansion; int spare = content->array.raid_disks + array.exp_cnt;
if (restore_backup(st, content, if (restore_backup(st, content,
working, array.new_cnt,
spare, &c->backup_file, c->verbose) == 1) spare, &c->backup_file, c->verbose) == 1)
return 1; return 1;
if (content->reshape_progress == 0) { if (content->reshape_progress == 0) {
/* If reshape progress is 0 - we are assembling the /* If reshape progress is 0 - we are assembling the
* array that was stopped, before reshape has started. * array that was stopped, before reshape has started.
* Array needs to be started as active, Grow_continue() * Array needs to be started as active, Grow_continue()
* will start the reshape. * will start the reshape.
*/ */
sysfs_set_num(content, NULL, "reshape_position", sysfs_set_num(content, NULL, "reshape_position",
skipping to change at line 2171 skipping to change at line 2218
sysfs_set_safemode(content, content->safe_mode_delay); sysfs_set_safemode(content, content->safe_mode_delay);
/* Block subarray here if it is not reshaped now /* Block subarray here if it is not reshaped now
* It has be blocked a little later to allow mdmon to switch in * It has be blocked a little later to allow mdmon to switch in
* in to R/W state * in to R/W state
*/ */
if (st->ss->external && content->recovery_blocked && if (st->ss->external && content->recovery_blocked &&
!start_reshape) !start_reshape)
block_subarray(content); block_subarray(content);
if (c->export && result) { if (err)
if (err) set_array_assembly_status(c, result, INCR_NO, &array);
*result |= INCR_NO; else {
else set_array_assembly_status(c, result, INCR_YES, &array);
*result |= INCR_YES;
} else if (c->verbose >= 0) {
if (err)
pr_err("array %s now has %d device%s",
chosen_name, working + preexist,
working + preexist == 1 ? "":"s");
else {
sysfs_rules_apply(chosen_name, content);
pr_err("Started %s with %d device%s",
chosen_name, working + preexist,
working + preexist == 1 ? "":"s");
}
if (preexist)
fprintf(stderr, " (%d new)", working);
if (expansion)
fprintf(stderr, " ( + %d for expansion)",
expansion);
fprintf(stderr, "\n");
}
if (!err)
wait_for(chosen_name, mdfd); wait_for(chosen_name, mdfd);
sysfs_rules_apply(chosen_name, content);
}
return err; return err;
/* FIXME should have an O_EXCL and wait for read-auto */ /* FIXME should have an O_EXCL and wait for read-auto */
} }
 End of changes. 16 change blocks. 
78 lines changed or deleted 107 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)