Beispiel #1
0
static int detach_metadata_devices(struct lv_segment *seg, struct dm_list *list)
{
	uint32_t s;
	uint32_t num_meta_lvs;
	struct cmd_context *cmd = seg->lv->vg->cmd;
	struct lv_list *lvl;

	num_meta_lvs = seg_is_raid(seg) ? seg->area_count : !!seg->log_lv;

	if (!num_meta_lvs)
		return_0;

	if (!(lvl = dm_pool_alloc(cmd->mem, sizeof(*lvl) * num_meta_lvs)))
		return_0;

	if (seg_is_raid(seg)) {
		for (s = 0; s < seg->area_count; s++) {
			if (!seg_metalv(seg, s))
				return_0; /* Trap this future possibility */

			lvl[s].lv = seg_metalv(seg, s);
			lv_set_visible(lvl[s].lv);

			dm_list_add(list, &lvl[s].list);
		}
		return 1;
	}

	lvl[0].lv = detach_mirror_log(seg);
	dm_list_add(list, &lvl[0].list);

	return 1;
}
Beispiel #2
0
static int lvchange_resync(struct cmd_context *cmd,
			      struct logical_volume *lv)
{
	int active = 0;
	int monitored;
	struct lvinfo info;
	struct logical_volume *log_lv;

	if (!(lv->status & MIRRORED)) {
		log_error("Unable to resync %s because it is not mirrored.",
			  lv->name);
		return 1;
	}

	if (lv->status & PVMOVE) {
		log_error("Unable to resync pvmove volume %s", lv->name);
		return 0;
	}

	if (lv->status & LOCKED) {
		log_error("Unable to resync locked volume %s", lv->name);
		return 0;
	}

	if (lv_info(cmd, lv, 0, &info, 1, 0)) {
		if (info.open_count) {
			log_error("Can't resync open logical volume \"%s\"",
				  lv->name);
			return 0;
		}

		if (info.exists) {
			if (!arg_count(cmd, yes_ARG) &&
			    yes_no_prompt("Do you really want to deactivate "
					  "logical volume %s to resync it? [y/n]: ",
					  lv->name) == 'n') {
				log_error("Logical volume \"%s\" not resynced",
					  lv->name);
				return 0;
			}

			if (sigint_caught())
				return 0;

			active = 1;
		}
	}

	/* Activate exclusively to ensure no nodes still have LV active */
	monitored = dmeventd_monitor_mode();
	init_dmeventd_monitor(0);

	if (!deactivate_lv(cmd, lv)) {
		log_error("Unable to deactivate %s for resync", lv->name);
		return 0;
	}

	if (vg_is_clustered(lv->vg) && lv_is_active(lv)) {
		log_error("Can't get exclusive access to clustered volume %s",
			  lv->name);
		return 0;
	}

	init_dmeventd_monitor(monitored);

	log_lv = first_seg(lv)->log_lv;

	log_very_verbose("Starting resync of %s%s%s mirror \"%s\"",
			 (active) ? "active " : "",
			 vg_is_clustered(lv->vg) ? "clustered " : "",
			 (log_lv) ? "disk-logged" : "core-logged",
			 lv->name);

	/*
	 * If this mirror has a core log (i.e. !log_lv),
	 * then simply deactivating/activating will cause
	 * it to reset the sync status.  We only need to
	 * worry about persistent logs.
	 */
	if (!log_lv && !(lv->status & LV_NOTSYNCED)) {
		if (active && !activate_lv(cmd, lv)) {
			log_error("Failed to reactivate %s to resynchronize "
				  "mirror", lv->name);
			return 0;
		}
		return 1;
	}

	lv->status &= ~LV_NOTSYNCED;

	if (log_lv) {
		/* Separate mirror log so we can clear it */
		detach_mirror_log(first_seg(lv));

		if (!vg_write(lv->vg)) {
			log_error("Failed to write intermediate VG metadata.");
			if (!attach_mirror_log(first_seg(lv), log_lv))
				stack;
			if (active && !activate_lv(cmd, lv))
				stack;
			return 0;
		}

		if (!vg_commit(lv->vg)) {
			log_error("Failed to commit intermediate VG metadata.");
			if (!attach_mirror_log(first_seg(lv), log_lv))
				stack;
			if (active && !activate_lv(cmd, lv))
				stack;
			return 0;
		}

		backup(lv->vg);

		if (!activate_lv(cmd, log_lv)) {
			log_error("Unable to activate %s for mirror log resync",
				  log_lv->name);
			return 0;
		}

		log_very_verbose("Clearing log device %s", log_lv->name);
		if (!set_lv(cmd, log_lv, log_lv->size, 0)) {
			log_error("Unable to reset sync status for %s", lv->name);
			if (!deactivate_lv(cmd, log_lv))
				log_error("Failed to deactivate log LV after "
					  "wiping failed");
			return 0;
		}

		if (!deactivate_lv(cmd, log_lv)) {
			log_error("Unable to deactivate log LV %s after wiping "
				  "for resync", log_lv->name);
			return 0;
		}

		/* Put mirror log back in place */
		if (!attach_mirror_log(first_seg(lv), log_lv))
			stack;
	}

	log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
	if (!vg_write(lv->vg) || !vg_commit(lv->vg)) {
		log_error("Failed to update metadata on disk.");
		return 0;
	}

	if (active && !activate_lv(cmd, lv)) {
		log_error("Failed to reactivate %s after resync", lv->name);
		return 0;
	}

	return 1;
}