Exemple #1
0
/*
 * lv_cache_create
 * @pool
 * @origin
 *
 * Given a cache_pool and an origin, link the two and create a
 * cached LV.
 *
 * Returns: cache LV on success, NULL on failure
 */
struct logical_volume *lv_cache_create(struct logical_volume *pool,
				       struct logical_volume *origin)
{
	const struct segment_type *segtype;
	struct cmd_context *cmd = pool->vg->cmd;
	struct logical_volume *cache_lv;
	struct lv_segment *seg;

	if (!lv_is_cache_pool(pool)) {
		log_error(INTERNAL_ERROR
			  "%s is not a cache_pool LV", pool->name);
		return NULL;
	}

	if (!dm_list_empty(&pool->segs_using_this_lv)) {
		seg = get_only_segment_using_this_lv(pool);
		log_error("%s is already in use by %s",
			  pool->name, seg ? seg->lv->name : "another LV");
		return NULL;
	}

	if (lv_is_cache_type(origin)) {
		/*
		 * FIXME: We can layer caches, insert_layer_for_lv() would
		 * have to do a better job renaming the LVs in the stack
		 * first so that there isn't a name collision with <name>_corig.
		 * The origin under the origin would become *_corig_corig
		 * before renaming the origin above to *_corig.
		 */
		log_error(INTERNAL_ERROR
			  "The origin, %s, cannot be of cache type",
			  origin->name);
		return NULL;
	}

	if (!(segtype = get_segtype_from_string(cmd, "cache")))
		return_NULL;

	cache_lv = origin;
	if (!(origin = insert_layer_for_lv(cmd, cache_lv, CACHE, "_corig")))
		return_NULL;

	seg = first_seg(cache_lv);
	seg->segtype = segtype;

	if (!attach_pool_lv(seg, pool, NULL, NULL))
		return_NULL;

	return cache_lv;
}
Exemple #2
0
/* Check if given LV is usable as snapshot origin LV */
int validate_snapshot_origin(const struct logical_volume *origin_lv)
{
	const char *err = NULL; /* For error string */

	if (lv_is_cow(origin_lv))
		err = "snapshots";
	else if (lv_is_locked(origin_lv))
		err = "locked volumes";
	else if (lv_is_pvmove(origin_lv))
		err = "pvmoved volumes";
	else if (!lv_is_visible(origin_lv))
		err = "hidden volumes";
	else if (lv_is_merging_origin(origin_lv))
		err = "an origin that has a merging snapshot";
	else if (lv_is_cache_type(origin_lv) && !lv_is_cache(origin_lv))
		err = "cache type volumes";
	else if (lv_is_thin_type(origin_lv) && !lv_is_thin_volume(origin_lv))
		err = "thin pool type volumes";
	else if (lv_is_mirror_type(origin_lv)) {
		if (!lv_is_mirror(origin_lv))
			err = "mirror subvolumes";
		else {
			log_warn("WARNING: Snapshots of mirrors can deadlock under rare device failures.");
			log_warn("WARNING: Consider using the raid1 mirror type to avoid this.");
			log_warn("WARNING: See global/mirror_segtype_default in lvm.conf.");
		}
	} else if (lv_is_raid_type(origin_lv) && !lv_is_raid(origin_lv))
		err = "raid subvolumes";

	if (err) {
		log_error("Snapshots of %s are not supported.", err);
		return 0;
	}

	if (vg_is_clustered(origin_lv->vg) && lv_is_active(origin_lv) &&
	    !lv_is_active_exclusive_locally(origin_lv)) {
		log_error("Snapshot origin must be active exclusively.");
		return 0;
	}

	return 1;
}