563
* _alloc_rmeta_for_lv
566
* Allocate a RAID metadata device for the given LV (which is or will
567
* be the associated RAID data device). The new metadata device must
568
* be allocated from the same PV(s) as the data device.
570
static int _alloc_rmeta_for_lv(struct logical_volume *data_lv,
571
struct logical_volume **meta_lv)
573
struct dm_list allocatable_pvs;
574
struct alloc_handle *ah;
575
struct lv_segment *seg = first_seg(data_lv);
576
char *p, base_name[strlen(data_lv->name) + 1];
578
dm_list_init(&allocatable_pvs);
580
if (!seg_is_linear(seg)) {
581
log_error(INTERNAL_ERROR "Unable to allocate RAID metadata "
582
"area for non-linear LV, %s", data_lv->name);
586
sprintf(base_name, "%s", data_lv->name);
587
if ((p = strstr(base_name, "_mimage_")))
590
if (!_get_pv_list_for_lv(data_lv, &allocatable_pvs)) {
591
log_error("Failed to build list of PVs for %s/%s",
592
data_lv->vg->name, data_lv->name);
596
if (!(ah = allocate_extents(data_lv->vg, NULL, seg->segtype, 0, 1, 0,
598
1 /*RAID_METADATA_AREA_LEN*/,
599
&allocatable_pvs, data_lv->alloc, NULL)))
602
if (!_alloc_image_component(data_lv, base_name, ah, 0,
455
610
static int _raid_add_images(struct logical_volume *lv,
456
611
uint32_t new_count, struct dm_list *pvs)
613
int rebuild_flag_cleared = 0;
459
615
uint32_t old_count = lv_raid_image_count(lv);
460
616
uint32_t count = new_count - old_count;
617
uint64_t status_mask = -1;
461
618
struct cmd_context *cmd = lv->vg->cmd;
462
619
struct lv_segment *seg = first_seg(lv);
463
620
struct dm_list meta_lvs, data_lvs;
1102
1371
vg->name, lv->name);
1375
static int _convert_mirror_to_raid1(struct logical_volume *lv,
1376
const struct segment_type *new_segtype)
1379
struct lv_segment *seg = first_seg(lv);
1380
struct lv_list lvl_array[seg->area_count], *lvl;
1381
struct dm_list meta_lvs;
1382
struct lv_segment_area *meta_areas;
1384
dm_list_init(&meta_lvs);
1386
if (!_raid_in_sync(lv)) {
1387
log_error("Unable to convert %s/%s while it is not in-sync",
1388
lv->vg->name, lv->name);
1392
meta_areas = dm_pool_zalloc(lv->vg->vgmem,
1393
lv_mirror_count(lv) * sizeof(*meta_areas));
1395
log_error("Failed to allocate memory");
1399
for (s = 0; s < seg->area_count; s++) {
1400
log_debug("Allocating new metadata LV for %s",
1401
seg_lv(seg, s)->name);
1402
if (!_alloc_rmeta_for_lv(seg_lv(seg, s), &(lvl_array[s].lv))) {
1403
log_error("Failed to allocate metadata LV for %s in %s",
1404
seg_lv(seg, s)->name, lv->name);
1407
dm_list_add(&meta_lvs, &(lvl_array[s].list));
1410
log_debug("Clearing newly allocated metadata LVs");
1411
if (!_clear_lvs(&meta_lvs)) {
1412
log_error("Failed to initialize metadata LVs");
1417
log_debug("Removing mirror log, %s", seg->log_lv->name);
1418
if (!remove_mirror_log(lv->vg->cmd, lv, NULL, 0)) {
1419
log_error("Failed to remove mirror log");
1424
seg->meta_areas = meta_areas;
1427
dm_list_iterate_items(lvl, &meta_lvs) {
1428
log_debug("Adding %s to %s", lvl->lv->name, lv->name);
1430
/* Images are known to be in-sync */
1431
lvl->lv->status &= ~LV_REBUILD;
1432
first_seg(lvl->lv)->status &= ~LV_REBUILD;
1433
lv_set_hidden(lvl->lv);
1435
if (!set_lv_segment_area_lv(seg, s, lvl->lv, 0,
1437
log_error("Failed to add %s to %s",
1438
lvl->lv->name, lv->name);
1444
for (s = 0; s < seg->area_count; s++) {
1447
new_name = dm_pool_zalloc(lv->vg->vgmem,
1449
strlen("_rimage_XXn"));
1451
log_error("Failed to rename mirror images");
1455
sprintf(new_name, "%s_rimage_%u", lv->name, s);
1456
log_debug("Renaming %s to %s", seg_lv(seg, s)->name, new_name);
1457
seg_lv(seg, s)->name = new_name;
1458
seg_lv(seg, s)->status &= ~MIRROR_IMAGE;
1459
seg_lv(seg, s)->status |= RAID_IMAGE;
1461
init_mirror_in_sync(1);
1463
log_debug("Setting new segtype for %s", lv->name);
1464
seg->segtype = new_segtype;
1465
lv->status &= ~MIRRORED;
1467
seg->status |= RAID;
1469
if (!vg_write(lv->vg)) {
1470
log_error("Failed to write changes to %s in %s",
1471
lv->name, lv->vg->name);
1475
if (!suspend_lv(lv->vg->cmd, lv)) {
1476
log_error("Failed to suspend %s/%s before committing changes",
1477
lv->vg->name, lv->name);
1481
if (!vg_commit(lv->vg)) {
1482
log_error("Failed to commit changes to %s in %s",
1483
lv->name, lv->vg->name);
1487
if (!resume_lv(lv->vg->cmd, lv)) {
1488
log_error("Failed to resume %s/%s after committing changes",
1489
lv->vg->name, lv->name);
1501
* Convert an LV from one RAID type (or 'mirror' segtype) to another.
1503
* Returns: 1 on success, 0 on failure
1505
int lv_raid_reshape(struct logical_volume *lv,
1506
const struct segment_type *new_segtype)
1508
struct lv_segment *seg = first_seg(lv);
1511
log_error(INTERNAL_ERROR "New segtype not specified");
1515
if (!strcmp(seg->segtype->name, "mirror") &&
1516
(!strcmp(new_segtype->name, "raid1")))
1517
return _convert_mirror_to_raid1(lv, new_segtype);
1519
log_error("Converting the segment type for %s/%s from %s to %s"
1520
" is not yet supported.", lv->vg->name, lv->name,
1521
seg->segtype->name, new_segtype->name);
1531
* Replace the specified PVs.
1533
int lv_raid_replace(struct logical_volume *lv,
1534
struct dm_list *remove_pvs,
1535
struct dm_list *allocate_pvs)
1537
uint32_t s, sd, match_count = 0;
1538
struct dm_list old_meta_lvs, old_data_lvs;
1539
struct dm_list new_meta_lvs, new_data_lvs;
1540
struct lv_segment *raid_seg = first_seg(lv);
1541
struct lv_list *lvl;
1542
char *tmp_names[raid_seg->area_count * 2];
1544
dm_list_init(&old_meta_lvs);
1545
dm_list_init(&old_data_lvs);
1546
dm_list_init(&new_meta_lvs);
1547
dm_list_init(&new_data_lvs);
1550
* How many sub-LVs are being removed?
1552
for (s = 0; s < raid_seg->area_count; s++) {
1553
if ((seg_type(raid_seg, s) == AREA_UNASSIGNED) ||
1554
(seg_metatype(raid_seg, s) == AREA_UNASSIGNED)) {
1555
log_error("Unable to replace RAID images while the "
1556
"array has unassigned areas");
1560
if (_lv_is_on_pvs(seg_lv(raid_seg, s), remove_pvs) ||
1561
_lv_is_on_pvs(seg_metalv(raid_seg, s), remove_pvs))
1566
log_verbose("%s/%s does not contain devices specified"
1567
" for replacement", lv->vg->name, lv->name);
1569
} else if (match_count == raid_seg->area_count) {
1570
log_error("Unable to remove all PVs from %s/%s at once.",
1571
lv->vg->name, lv->name);
1573
} else if (raid_seg->segtype->parity_devs &&
1574
(match_count > raid_seg->segtype->parity_devs)) {
1575
log_error("Unable to replace more than %u PVs from (%s) %s/%s",
1576
raid_seg->segtype->parity_devs,
1577
raid_seg->segtype->name, lv->vg->name, lv->name);
1582
* Allocate the new image components first
1583
* - This makes it easy to avoid all currently used devs
1584
* - We can immediately tell if there is enough space
1586
* - We need to change the LV names when we insert them.
1588
if (!_alloc_image_components(lv, allocate_pvs, match_count,
1589
&new_meta_lvs, &new_data_lvs)) {
1590
log_error("Failed to allocate replacement images for %s/%s",
1591
lv->vg->name, lv->name);
1596
* Remove the old images
1597
* - If we did this before the allocate, we wouldn't have to rename
1598
* the allocated images, but it'd be much harder to avoid the right
1599
* PVs during allocation.
1601
if (!_raid_extract_images(lv, raid_seg->area_count - match_count,
1603
&old_meta_lvs, &old_data_lvs)) {
1604
log_error("Failed to remove the specified images from %s/%s",
1605
lv->vg->name, lv->name);
1610
* Skip metadata operation normally done to clear the metadata sub-LVs.
1612
* The LV_REBUILD flag is set on the new sub-LVs,
1613
* so they will be rebuilt and we don't need to clear the metadata dev.
1616
for (s = 0; s < raid_seg->area_count; s++) {
1617
tmp_names[s] = NULL;
1618
sd = s + raid_seg->area_count;
1619
tmp_names[sd] = NULL;
1621
if ((seg_type(raid_seg, s) == AREA_UNASSIGNED) &&
1622
(seg_metatype(raid_seg, s) == AREA_UNASSIGNED)) {
1623
/* Adjust the new metadata LV name */
1624
lvl = dm_list_item(dm_list_first(&new_meta_lvs),
1626
dm_list_del(&lvl->list);
1627
tmp_names[s] = dm_pool_alloc(lv->vg->vgmem,
1628
strlen(lvl->lv->name) + 1);
1631
if (dm_snprintf(tmp_names[s], strlen(lvl->lv->name) + 1,
1632
"%s_rmeta_%u", lv->name, s) < 0)
1634
if (!set_lv_segment_area_lv(raid_seg, s, lvl->lv, 0,
1636
log_error("Failed to add %s to %s",
1637
lvl->lv->name, lv->name);
1640
lv_set_hidden(lvl->lv);
1642
/* Adjust the new data LV name */
1643
lvl = dm_list_item(dm_list_first(&new_data_lvs),
1645
dm_list_del(&lvl->list);
1646
tmp_names[sd] = dm_pool_alloc(lv->vg->vgmem,
1647
strlen(lvl->lv->name) + 1);
1650
if (dm_snprintf(tmp_names[sd], strlen(lvl->lv->name) + 1,
1651
"%s_rimage_%u", lv->name, s) < 0)
1653
if (!set_lv_segment_area_lv(raid_seg, s, lvl->lv, 0,
1655
log_error("Failed to add %s to %s",
1656
lvl->lv->name, lv->name);
1659
lv_set_hidden(lvl->lv);
1663
if (!vg_write(lv->vg)) {
1664
log_error("Failed to write changes to %s in %s",
1665
lv->name, lv->vg->name);
1669
if (!suspend_lv(lv->vg->cmd, lv)) {
1670
log_error("Failed to suspend %s/%s before committing changes",
1671
lv->vg->name, lv->name);
1675
if (!vg_commit(lv->vg)) {
1676
log_error("Failed to commit changes to %s in %s",
1677
lv->name, lv->vg->name);
1681
if (!resume_lv(lv->vg->cmd, lv)) {
1682
log_error("Failed to resume %s/%s after committing changes",
1683
lv->vg->name, lv->name);
1687
dm_list_iterate_items(lvl, &old_meta_lvs) {
1688
if (!deactivate_lv(lv->vg->cmd, lvl->lv))
1690
if (!lv_remove(lvl->lv))
1693
dm_list_iterate_items(lvl, &old_data_lvs) {
1694
if (!deactivate_lv(lv->vg->cmd, lvl->lv))
1696
if (!lv_remove(lvl->lv))
1700
/* Update new sub-LVs to correct name and clear REBUILD flag */
1701
for (s = 0; s < raid_seg->area_count; s++) {
1702
sd = s + raid_seg->area_count;
1703
if (tmp_names[s] && tmp_names[sd]) {
1704
seg_metalv(raid_seg, s)->name = tmp_names[s];
1705
seg_lv(raid_seg, s)->name = tmp_names[sd];
1706
seg_metalv(raid_seg, s)->status &= ~LV_REBUILD;
1707
seg_lv(raid_seg, s)->status &= ~LV_REBUILD;
1711
if (!vg_write(lv->vg)) {
1712
log_error("Failed to write changes to %s in %s",
1713
lv->name, lv->vg->name);
1717
if (!suspend_lv(lv->vg->cmd, lv)) {
1718
log_error("Failed to suspend %s/%s before committing changes",
1719
lv->vg->name, lv->name);
1723
if (!vg_commit(lv->vg)) {
1724
log_error("Failed to commit changes to %s in %s",
1725
lv->name, lv->vg->name);
1729
if (!resume_lv(lv->vg->cmd, lv)) {
1730
log_error("Failed to resume %s/%s after committing changes",
1731
lv->vg->name, lv->name);