Exemple #1
0
char *build_dm_uuid(struct dm_pool *mem, const struct logical_volume *lv,
		    const char *layer)
{
	const char *lvid = lv->lvid.s;
	char *dlid;

	if (!layer) {
		/*
		 * Mark internal LVs with layer suffix
		 * so tools like blkid may immeditelly see it's
		 * an internal LV they should not scan.
		 * Should also make internal detection simpler.
		 */
		/* Suffixes used here MUST match lib/activate/dev_manager.c */
		layer = lv_is_cache_origin(lv) ? "real" :
			(lv_is_cache(lv) && lv_is_pending_delete(lv)) ? "real" :
			lv_is_cache_pool_data(lv) ? "cdata" :
			lv_is_cache_pool_metadata(lv) ? "cmeta" :
			// FIXME: dm-tree needs fixes for mirrors/raids
			//lv_is_mirror_image(lv) ? "mimage" :
			//lv_is_mirror_log(lv) ? "mlog" :
			//lv_is_raid_image(lv) ? "rimage" :
			//lv_is_raid_metadata(lv) ? "rmeta" :
			lv_is_thin_pool(lv) ? "pool" :
			lv_is_thin_pool_data(lv) ? "tdata" :
			lv_is_thin_pool_metadata(lv) ? "tmeta" :
			NULL;
	}

	if (!(dlid = dm_build_dm_uuid(mem, UUID_PREFIX, lvid, layer)))
		log_error("Failed to build LVM dlid for %s.",
			  display_lvname(lv));

	return dlid;
}
Exemple #2
0
char *build_dm_uuid(struct dm_pool *mem, const struct logical_volume *lv,
		    const char *layer)
{
	const char *lvid = lv->lvid.s;

	if (!layer) {
		/*
		 * Mark internal LVs with layer suffix
		 * so tools like blkid may immeditelly see it's
		 * an internal LV they should not scan.
		 * Should also make internal detection simpler.
		 */
		layer = lv_is_cache_pool_data(lv) ? "cdata" :
			lv_is_cache_pool_metadata(lv) ? "cmeta" :
			// FIXME: dm-tree needs fixes for mirrors/raids
			//lv_is_mirror_image(lv) ? "mimage" :
			//lv_is_mirror_log(lv) ? "mlog" :
			//lv_is_raid_image(lv) ? "rimage" :
			//lv_is_raid_metadata(lv) ? "rmeta" :
			lv_is_thin_pool(lv) ? "pool" :
			lv_is_thin_pool_data(lv) ? "tdata" :
			lv_is_thin_pool_metadata(lv) ? "tmeta" :
			NULL;
	}

	return dm_build_dm_uuid(mem, UUID_PREFIX, lvid, layer);
}
Exemple #3
0
static dm_percent_t _metadata_percent(const struct logical_volume *lv)
{
	dm_percent_t percent;
	struct lv_status_cache *status;

	if (lv_is_cache(lv) || lv_is_cache_pool(lv)) {
		if (!lv_cache_status(lv, &status)) {
			stack;
			return DM_PERCENT_INVALID;
		}
		percent = status->dirty_usage;
		dm_pool_destroy(status->mem);
		return percent;
	}

	if (lv_is_thin_pool(lv))
		return lv_thin_pool_percent(lv, 1, &percent) ? percent : DM_PERCENT_INVALID;

	return DM_PERCENT_INVALID;
}
Exemple #4
0
static int lvchange_monitoring(struct cmd_context *cmd,
			       struct logical_volume *lv)
{
	struct lvinfo info;

	if (!lv_info(cmd, lv, lv_is_thin_pool(lv) ? 1 : 0,
		     &info, 0, 0) || !info.exists) {
		log_error("Logical volume, %s, is not active", lv->name);
		return 0;
	}

	/* do not monitor pvmove lv's */
	if (lv->status & PVMOVE)
		return 1;

	if ((dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) &&
	    !monitor_dev_for_events(cmd, lv, 0, dmeventd_monitor_mode()))
		return_0;

	return 1;
}
Exemple #5
0
static int lvchange_pool_update(struct cmd_context *cmd,
				struct logical_volume *lv)
{
	int r = 0;
	int update = 0;
	unsigned val;
	thin_discards_t discards;

	if (!lv_is_thin_pool(lv)) {
		log_error("Logical volume \"%s\" is not a thin pool.", lv->name);
		return 0;
	}

	if (arg_count(cmd, discards_ARG)) {
		discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_IGNORE);
		if (discards != first_seg(lv)->discards) {
			if ((discards != THIN_DISCARDS_IGNORE) &&
				 (first_seg(lv)->chunk_size &
				  (first_seg(lv)->chunk_size - 1)))
				log_error("Cannot change discards state for "
					  "logical volume \"%s\" "
					  "with non power of 2 chunk size.", lv->name);
			else if (((discards == THIN_DISCARDS_IGNORE) ||
			     (first_seg(lv)->discards == THIN_DISCARDS_IGNORE)) &&
			    lv_is_active(lv))
				log_error("Cannot change discards state for active "
					  "logical volume \"%s\".", lv->name);
			else {
				first_seg(lv)->discards = discards;
				update++;
			}
		} else
			log_error("Logical volume \"%s\" already uses --discards %s.",
				  lv->name, get_pool_discards_name(discards));
	}

	if (arg_count(cmd, zero_ARG)) {
		val = arg_uint_value(cmd, zero_ARG, 1);
		if (val != first_seg(lv)->zero_new_blocks) {
			first_seg(lv)->zero_new_blocks = val;
			update++;
		} else
			log_error("Logical volume \"%s\" already %szero new blocks.",
				  lv->name, val ? "" : "does not ");
	}

	if (!update)
		return 0;

	log_very_verbose("Updating logical volume \"%s\" on disk(s).", lv->name);
	if (!vg_write(lv->vg))
		return_0;

	if (!suspend_lv_origin(cmd, lv)) {
		log_error("Failed to update active %s/%s (deactivation is needed).",
			  lv->vg->name, lv->name);
		vg_revert(lv->vg);
		goto out;
	}

	if (!vg_commit(lv->vg)) {
		if (!resume_lv_origin(cmd, lv))
			stack;
		goto_out;
	}

	if (!resume_lv_origin(cmd, lv)) {
		log_error("Problem reactivating %s.", lv->name);
		goto out;
	}

	r = 1;
out:
	backup(lv->vg);
	return r;
}
Exemple #6
0
static int lvchange_permission(struct cmd_context *cmd,
			       struct logical_volume *lv)
{
	uint32_t lv_access;
	struct lvinfo info;
	int r = 0;

	lv_access = arg_uint_value(cmd, permission_ARG, 0);

	if ((lv_access & LVM_WRITE) && (lv->status & LVM_WRITE)) {
		log_error("Logical volume \"%s\" is already writable",
			  lv->name);
		return 0;
	}

	if (!(lv_access & LVM_WRITE) && !(lv->status & LVM_WRITE)) {
		log_error("Logical volume \"%s\" is already read only",
			  lv->name);
		return 0;
	}

	if ((lv->status & MIRRORED) && (vg_is_clustered(lv->vg)) &&
	    lv_info(cmd, lv, 0, &info, 0, 0) && info.exists) {
		log_error("Cannot change permissions of mirror \"%s\" "
			  "while active.", lv->name);
		return 0;
	}

	/* Not allowed to change permissions on RAID sub-LVs directly */
	if ((lv->status & RAID_META) || (lv->status & RAID_IMAGE)) {
		log_error("Cannot change permissions of RAID %s \"%s\"",
			  (lv->status & RAID_IMAGE) ? "image" :
			  "metadata area", lv->name);
		return 0;
	}

	if (!(lv_access & LVM_WRITE) && lv_is_thin_pool(lv)) {
		log_error("Change permissions of thin pool \"%s\" not "
			  "yes supported.", lv->name);
		return 0;
	}

	if (lv_access & LVM_WRITE) {
		lv->status |= LVM_WRITE;
		log_verbose("Setting logical volume \"%s\" read/write",
			    lv->name);
	} else {
		lv->status &= ~LVM_WRITE;
		log_verbose("Setting logical volume \"%s\" read-only",
			    lv->name);
	}

	log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
	if (!vg_write(lv->vg))
		return_0;

	if (!suspend_lv(cmd, lv)) {
		log_error("Failed to lock %s", lv->name);
		vg_revert(lv->vg);
		goto out;
	}

	if (!vg_commit(lv->vg)) {
		if (!resume_lv(cmd, lv))
			stack;
		goto_out;
	}

	log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name);
	if (!resume_lv(cmd, lv)) {
		log_error("Problem reactivating %s", lv->name);
		goto out;
	}

	r = 1;
out:
	backup(lv->vg);
	return r;
}