139
139
char *backup_file, int invalid_backup,
140
140
int readonly, int runstop,
141
141
char *update, char *homehost, int require_homehost,
142
int verbose, int force)
142
int verbose, int force, int freeze_reshape)
145
145
* The task of Assemble is to find a collection of
441
445
content = content->next) {
443
/* do not assemble arrays that might have bad blocks */
444
if (content->array.state & (1<<MD_SB_BBM_ERRORS)) {
445
fprintf(stderr, Name ": BBM log found in metadata. "
446
"Cannot activate array(s).\n");
450
447
if (!ident_matches(ident, content, tst,
451
448
homehost, update,
452
449
report_missmatch ? devname : NULL))
456
453
fprintf(stderr, Name ": member %s in %s is already assembled\n",
457
454
content->text_version,
456
} else if (content->array.state & (1<<MD_SB_BLOCK_VOLUME)) {
457
/* do not assemble arrays with unsupported configurations */
458
fprintf(stderr, Name ": Cannot activate member %s in %s.\n",
459
content->text_version,
699
701
err = assemble_container_content(st, mdfd, content, runstop,
700
702
chosen_name, verbose,
703
backup_file, freeze_reshape);
706
709
/* Ok, no bad inconsistancy, we can try updating etc */
708
content->update_private = NULL;
709
710
devices = malloc(num_devs * sizeof(*devices));
710
711
devmap = calloc(num_devs * content->array.raid_disks, 1);
711
712
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
1345
1344
#ifndef MDASSEMBLE
1346
1345
if (content->reshape_active &&
1347
content->delta_disks <= 0)
1348
rv = Grow_continue(mdfd, st, content, backup_file);
1346
content->delta_disks <= 0) {
1347
rv = sysfs_set_str(content, NULL,
1348
"array_state", "readonly");
1350
rv = Grow_continue(mdfd, st, content,
1351
1355
rv = ioctl(mdfd, RUN_ARRAY, NULL);
1512
1517
int assemble_container_content(struct supertype *st, int mdfd,
1513
1518
struct mdinfo *content, int runstop,
1514
1519
char *chosen_name, int verbose,
1520
char *backup_file, int freeze_reshape)
1517
1522
struct mdinfo *dev, *sra;
1518
1523
int working = 0, preexist = 0;
1525
1530
sra = sysfs_read(mdfd, 0, GET_VERSION);
1526
1531
if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0)
1527
if (sysfs_set_array(content, md_get_version(mdfd)) != 0)
1532
if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
1530
if (content->reshape_active)
1538
if (st->ss->external && content->recovery_blocked)
1531
1539
block_subarray(content);
1553
1561
(working + preexist + expansion) >=
1554
1562
content->array.working_disks) {
1557
if (content->reshape_active) {
1566
/* There are two types of reshape: container wide or sub-array specific
1567
* Check if metadata requests blocking container wide reshapes
1569
start_reshape = (content->reshape_active &&
1570
!((content->reshape_active == CONTAINER_RESHAPE) &&
1571
(content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))));
1572
if (start_reshape) {
1558
1573
int spare = content->array.raid_disks + expansion;
1560
int *fdlist = malloc(sizeof(int) *
1561
(working + expansion
1562
+ content->array.raid_disks));
1563
for (i=0; i<spare; i++)
1565
for (dev = content->devs; dev; dev = dev->next) {
1568
sprintf(buf, "%d:%d",
1571
fd = dev_open(buf, O_RDWR);
1573
if (dev->disk.raid_disk >= 0)
1574
fdlist[dev->disk.raid_disk] = fd;
1576
fdlist[spare++] = fd;
1578
if (st->ss->external && st->ss->recover_backup)
1579
err = st->ss->recover_backup(st, content);
1581
err = Grow_restart(st, content, fdlist, spare,
1582
backup_file, verbose > 0);
1585
if (fdlist[spare] >= 0)
1586
close(fdlist[spare]);
1589
fprintf(stderr, Name ": Failed to restore critical"
1590
" section for reshape - sorry.\n");
1592
fprintf(stderr, Name ": Possibly you need"
1593
" to specify a --backup-file\n");
1597
err = Grow_continue(mdfd, st, content, backup_file);
1574
if (restore_backup(st, content,
1576
spare, backup_file, verbose) == 1)
1579
err = sysfs_set_str(content, NULL,
1580
"array_state", "readonly");
1584
if (st->ss->external) {
1585
if (!mdmon_running(st->container_dev))
1586
start_mdmon(st->container_dev);
1587
ping_monitor_by_id(st->container_dev);
1588
if (mdmon_running(st->container_dev) &&
1589
st->update_tail == NULL)
1590
st->update_tail = &st->updates;
1593
err = Grow_continue(mdfd, st, content, backup_file,
1598
1595
} else switch(content->array.level) {
1599
1596
case LEVEL_LINEAR:
1600
1597
case LEVEL_MULTIPATH:
1618
1615
if (verbose >= 0) {
1620
1617
fprintf(stderr, Name
1621
": array %s now has %d devices",
1622
chosen_name, working + preexist);
1618
": array %s now has %d device%s",
1619
chosen_name, working + preexist,
1620
working + preexist == 1 ? "":"s");
1624
1622
fprintf(stderr, Name
1625
": Started %s with %d devices",
1626
chosen_name, working + preexist);
1623
": Started %s with %d device%s",
1624
chosen_name, working + preexist,
1625
working + preexist == 1 ? "":"s");
1628
1627
fprintf(stderr, " (%d new)", working);
1637
1636
/* FIXME should have an O_EXCL and wait for read-auto */
1640
1639
fprintf(stderr, Name
1641
": %s assembled with %d devices but "
1643
chosen_name, working);
1640
": %s assembled with %d device%s",
1641
chosen_name, preexist + working,
1642
preexist + working == 1 ? "":"s");
1644
fprintf(stderr, " (%d new)", working);
1645
fprintf(stderr, " but not started\n");