示例#1
0
/*
 * Test whether two segments could be merged by the current merging code
 */
static int _striped_segments_compatible(struct lv_segment *first,
				struct lv_segment *second)
{
	uint32_t width;
	unsigned s;

	if ((first->area_count != second->area_count) ||
	    (first->stripe_size != second->stripe_size))
		return 0;

	for (s = 0; s < first->area_count; s++) {

		/* FIXME Relax this to first area type != second area type */
		/*       plus the additional AREA_LV checks needed */
		if ((seg_type(first, s) != AREA_PV) ||
		    (seg_type(second, s) != AREA_PV))
			return 0;

		width = first->area_len;

		if ((seg_pv(first, s) !=
		     seg_pv(second, s)) ||
		    (seg_pe(first, s) + width !=
		     seg_pe(second, s)))
			return 0;
	}

	if (!str_list_lists_equal(&first->tags, &second->tags))
		return 0;

	return 1;
}
示例#2
0
static int _detach_pvmove_mirror(struct cmd_context *cmd,
				 struct logical_volume *lv_mirr)
{
	uint32_t mimage_to_remove = 0;
	struct dm_list lvs_completed;
	struct lv_list *lvl;

	/* Update metadata to remove mirror segments and break dependencies */
	dm_list_init(&lvs_completed);

	if (arg_is_set(cmd, abort_ARG) &&
	    (seg_type(first_seg(lv_mirr), 0) == AREA_LV))
		mimage_to_remove = 1; /* remove the second mirror leg */

	if (!lv_remove_mirrors(cmd, lv_mirr, 1, 0, _is_pvmove_image_removable, &mimage_to_remove, PVMOVE) ||
	    !remove_layers_for_segments_all(cmd, lv_mirr, PVMOVE,
					    &lvs_completed)) {
		return 0;
	}

	dm_list_iterate_items(lvl, &lvs_completed)
		/* FIXME Assumes only one pvmove at a time! */
		lvl->lv->status &= ~LOCKED;

	return 1;
}
示例#3
0
static int _is_pvmove_image_removable(struct logical_volume *mimage_lv,
				      void *baton)
{
	uint32_t mimage_to_remove = *((uint32_t *)baton);
	struct lv_segment *mirror_seg;

	if (!(mirror_seg = get_only_segment_using_this_lv(mimage_lv))) {
		log_error(INTERNAL_ERROR "%s is not a proper mirror image",
			  mimage_lv->name);
		return 0;
	}

	if (seg_type(mirror_seg, 0) != AREA_LV) {
		log_error(INTERNAL_ERROR "%s is not a pvmove mirror of LV-type",
			  mirror_seg->lv->name);
		return 0;
	}

	if (mimage_to_remove > mirror_seg->area_count) {
		log_error(INTERNAL_ERROR "Mirror image %" PRIu32 " not found in segment",
			  mimage_to_remove);
		return 0;
	}

	if (seg_lv(mirror_seg, mimage_to_remove) == mimage_lv)
		return 1;

	return 0;
}
示例#4
0
static int _is_converting(struct logical_volume *lv)
{
    struct lv_segment *seg;

    if (lv->status & MIRRORED) {
        seg = first_seg(lv);
        /* Can't use is_temporary_mirror() because the metadata for
         * seg_lv may not be read in and flags may not be set yet. */
        if (seg_type(seg, 0) == AREA_LV &&
                strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER))
            return 1;
    }

    return 0;
}
示例#5
0
static int _striped_merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
{
	uint32_t s;

	if (!_striped_segments_compatible(seg1, seg2))
		return 0;

	seg1->len += seg2->len;
	seg1->area_len += seg2->area_len;

	for (s = 0; s < seg1->area_count; s++)
		if (seg_type(seg1, s) == AREA_PV)
			merge_pv_segments(seg_pvseg(seg1, s),
					  seg_pvseg(seg2, s));

	return 1;
}
示例#6
0
/*
 * Check all pv_segments in VG for consistency
 */
int check_pv_segments(struct volume_group *vg)
{
        struct physical_volume *pv;
        struct pv_list *pvl;
        struct pv_segment *peg;
        unsigned s, segno;
        uint32_t start_pe, alloced;
        uint32_t pv_count = 0, free_count = 0, extent_count = 0;
        int ret = 1;

        //list_iterate_items(pvl, &vg->pvs) {
        list_iterate_items(pvl, struct pv_list, &vg->pvs) {
                pv = pvl->pv;
                segno = 0;
                start_pe = 0;
                alloced = 0;
                pv_count++;

                //list_iterate_items(peg, &pv->segments) {
                list_iterate_items(peg, struct pv_segment, &pv->segments) {
                        s = peg->lv_area;

                        /* FIXME Remove this next line eventually */
                        log_debug("%s %u: %6u %6u: %s(%u:%u)",
                                  dev_name(pv->dev), segno++, peg->pe, peg->len,
                                  peg->lvseg ? peg->lvseg->lv->name : "NULL",
                                  peg->lvseg ? peg->lvseg->le : 0, s);
                        /* FIXME Add details here on failure instead */
                        if (start_pe != peg->pe) {
                                log_error("Gap in pvsegs: %u, %u",
                                          start_pe, peg->pe);
                                ret = 0;
                        }
                        if (peg->lvseg) {
                                if (seg_type(peg->lvseg, s) != AREA_PV) {
                                        log_error("Wrong lvseg area type");
                                        ret = 0;
                                }
                                if (seg_pvseg(peg->lvseg, s) != peg) {
                                        log_error("Inconsistent pvseg pointers");
                                        ret = 0;
                                }
                                if (peg->lvseg->area_len != peg->len) {
                                        log_error("Inconsistent length: %u %u",
                                                  peg->len,
                                                  peg->lvseg->area_len);
                                        ret = 0;
                                }
                                alloced += peg->len;
                        }
                        start_pe += peg->len;
                }

                if (start_pe != pv->pe_count) {
                        log_error("PV segment pe_count mismatch: %u != %u",
                                  start_pe, pv->pe_count);
                        ret = 0;
                }

                if (alloced != pv->pe_alloc_count) {
                        log_error("PV segment pe_alloc_count mismatch: "
                                  "%u != %u", alloced, pv->pe_alloc_count);
                        ret = 0;
                }

                extent_count += start_pe;
                free_count += (start_pe - alloced);
        }

        if (pv_count != vg->pv_count) {
                log_error("PV segment VG pv_count mismatch: %u != %u",
                          pv_count, vg->pv_count);
                ret = 0;
        }

        if (free_count != vg->free_count) {
                log_error("PV segment VG free_count mismatch: %u != %u",
                          free_count, vg->free_count);
                ret = 0;
        }

        if (extent_count != vg->extent_count) {
                log_error("PV segment VG extent_count mismatch: %u != %u",
                          extent_count, vg->extent_count);
                ret = 0;
        }

        return ret;
}