Version 2.02.00 -
===================================
+ Add mirror_seg pointer to lv_segment struct.
Only keep a device open if it's known to belong to a locked VG.
Fix lvdisplay to show all mirror destinations.
Replacement suspend code using libdevmapper dependency tree.
static int _action_activate(struct dev_manager *dm, struct logical_volume *lv)
{
+ // Replace with deptree code for lv + known deps only.
if (!_scan_existing_devices(dm)) {
stack;
return 0;
seg->region_size = region_size;
seg->extents_copied = extents_copied;
seg->log_lv = log_lv;
+ seg->mirror_seg = NULL;
list_init(&seg->tags);
- if (log_lv)
+ if (log_lv) {
log_lv->status |= MIRROR_LOG;
+ find_seg_by_le(log_lv, 0)->mirror_seg = seg;
+ }
return seg;
}
area_multiple = segtype_is_striped(segtype) ? area_count : 1;
+ /* FIXME Shouldn't log_lv always be NULL here? */
+ /* (As we set up log segments elsewhere) */
+
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
lv->le_count,
aa[0].len * area_multiple,
return 0;
}
- for (m = 0; m < mirrors; m++)
+ for (m = 0; m < mirrors; m++) {
set_lv_segment_area_lv(seg, m, sub_lvs[m], 0, MIRROR_IMAGE);
+ find_seg_by_le(sub_lvs[m], 0)->mirror_seg = seg;
+ }
list_add(&lv->segments, &seg->list);
lv->le_count += ah->total_area_len;
r = 0;
}
+ if (seg->log_lv) {
+ if (!seg_is_mirrored(seg)) {
+ log_error("LV %s: segment %u has log LV but "
+ "is not mirrored",
+ lv->name, seg_count);
+ r = 0;
+ }
+
+ if (!(seg->log_lv->status & MIRROR_LOG)) {
+ log_error("LV %s: segment %u log LV %s is not "
+ "a mirror log",
+ lv->name, seg_count, seg->log_lv->name);
+ r = 0;
+ }
+
+ if (!find_seg_by_le(seg->log_lv, 0) ||
+ find_seg_by_le(seg->log_lv, 0)->mirror_seg != seg) {
+ log_error("LV %s: segment %u log LV does not "
+ "point back to mirror segment",
+ lv->name, seg_count);
+ r = 0;
+ }
+ }
+
+ if (seg->status & MIRROR_IMAGE) {
+ if (!seg->mirror_seg ||
+ !seg_is_mirrored(seg->mirror_seg)) {
+ log_error("LV %s: segment %u mirror image "
+ "is not mirrored",
+ lv->name, seg_count);
+ r = 0;
+ }
+ }
+
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) == AREA_UNASSIGNED) {
log_error("LV %s: segment %u has unassigned "
lv->name, seg_count, s);
r = 0;
}
+
+ if (seg_lv(seg, s) &&
+ (seg_lv(seg, s)->status & MIRROR_IMAGE) &&
+ (find_seg_by_le(seg_lv(seg, s),
+ seg_le(seg, s))->mirror_seg
+ != seg)) {
+ log_error("LV %s: segment %u mirror "
+ "image %u missing mirror ptr",
+ lv->name, seg_count, s);
+ r = 0;
+ }
+
/* FIXME I don't think this ever holds?
if (seg_le(seg, s) != le) {
log_error("LV %s: segment %u has "
uint32_t region_size; /* For mirrors - in sectors */
uint32_t extents_copied;
struct logical_volume *log_lv;
+ struct lv_segment *mirror_seg;
struct list tags;
struct logical_volume *log_lv);
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors);
int remove_all_mirror_images(struct logical_volume *lv);
+/*
+ * Given mirror image or mirror log segment, find corresponding mirror segment
+ */
+struct lv_segment *find_mirror_seg(struct lv_segment *seg);
int insert_pvmove_mirrors(struct cmd_context *cmd,
struct logical_volume *lv_mirr,
#include "lv_alloc.h"
#include "lvm-string.h"
+struct lv_segment *find_mirror_seg(struct lv_segment *seg)
+{
+ return seg->mirror_seg;
+}
+
/*
* Ensure region size is compatible with volume size.
*/
for (m = 0; m < num_mirrors; m++) {
if (!(img_lvs[m] = lv_create_empty(lv->vg->fid, img_name,
NULL, LVM_READ | LVM_WRITE,
- ALLOC_INHERIT, 0, lv->vg))) {\
- log_error("Aborting. Failed to create submirror LV. "
+ ALLOC_INHERIT, 0, lv->vg))) {
+ log_error("Aborting. Failed to create mirror image LV. "
"Remove new LV and retry.");
return 0;
}
get_segtype_from_string(lv->vg->cmd,
"striped"),
0, NULL, 0, 0, 0, NULL)) {
- log_error("Aborting. Failed to add submirror segment "
+ log_error("Aborting. Failed to add mirror image segment "
"to %s. Remove new LV and retry.",
img_lvs[m]->name);
return 0;