mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
activation: add base lv component function
Introduce: lv_is_component() check is LV is actually a component device. lv_component_is_active() checking if any component device is active. lv_holder_is_active() is any component holding device is active.
This commit is contained in:
parent
6481471c9d
commit
ca9cbd92c4
@ -1,5 +1,6 @@
|
||||
Version 2.02.178 -
|
||||
=====================================
|
||||
Extend internal library to recognize and work with component LV.
|
||||
Skip duplicate check for active LV when prompting for its removal.
|
||||
Activate correct lock holding LV when it is cached.
|
||||
Do not modify archived metadata when removing striped raid.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@ -2860,3 +2860,112 @@ void activation_exit(void)
|
||||
dev_manager_exit();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _component_cb(struct logical_volume *lv, void *data)
|
||||
{
|
||||
struct logical_volume **component_lv = (struct logical_volume **) data;
|
||||
|
||||
if (lv_is_locked(lv) || lv_is_pvmove(lv) ||/* ignoring */
|
||||
/* thin-pool is special and it's using layered device */
|
||||
(lv_is_thin_pool(lv) && pool_is_active(lv)))
|
||||
return -1;
|
||||
|
||||
if (lv_is_active(lv)) {
|
||||
if (!lv_is_component(lv) || lv_is_visible(lv))
|
||||
return -1; /* skip whole subtree */
|
||||
|
||||
log_debug_activation("Found active component LV %s.", display_lvname(lv));
|
||||
*component_lv = lv;
|
||||
return 0; /* break any further processing */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds out for any LV if any of its component LVs are active.
|
||||
* Function first checks if an existing LV is visible and active eventually
|
||||
* it's lock holding LV is already active. In such case sub LV cannot be
|
||||
* actived alone and no further checking is needed.
|
||||
*
|
||||
* Returns active component LV if there is such.
|
||||
*/
|
||||
const struct logical_volume *lv_component_is_active(const struct logical_volume *lv)
|
||||
{
|
||||
const struct logical_volume *component_lv = NULL;
|
||||
const struct logical_volume *holder_lv = lv_lock_holder(lv);
|
||||
|
||||
if ((holder_lv != lv) && lv_is_active(holder_lv))
|
||||
return NULL; /* Lock holding LV is active, do not check components */
|
||||
|
||||
if (_component_cb((struct logical_volume *) lv, &holder_lv) == 1)
|
||||
(void) for_each_sub_lv((struct logical_volume *) lv, _component_cb,
|
||||
(void*) &component_lv);
|
||||
|
||||
return component_lv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds out if any LV above is active, as stacked device tree can be composed of
|
||||
* chained set of LVs.
|
||||
*
|
||||
* Returns active holder LV if there is such.
|
||||
*/
|
||||
const struct logical_volume *lv_holder_is_active(const struct logical_volume *lv)
|
||||
{
|
||||
const struct logical_volume *holder;
|
||||
const struct seg_list *sl;
|
||||
|
||||
if (lv_is_locked(lv) || lv_is_pvmove(lv))
|
||||
return NULL; /* Skip pvmove/locked LV tracking */
|
||||
|
||||
dm_list_iterate_items(sl, &lv->segs_using_this_lv) {
|
||||
/* Recursive call for upper-stack holder */
|
||||
if ((holder = lv_holder_is_active(sl->seg->lv)))
|
||||
return holder;
|
||||
|
||||
if (lv_is_active(sl->seg->lv)) {
|
||||
log_debug_activation("Found active holder LV %s.", display_lvname(sl->seg->lv));
|
||||
return sl->seg->lv;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _deactivate_sub_lv_cb(struct logical_volume *lv, void *data)
|
||||
{
|
||||
struct logical_volume **slv = data;
|
||||
|
||||
if (lv_is_thin_pool(lv) || lv_is_external_origin(lv))
|
||||
return -1;
|
||||
|
||||
if (!deactivate_lv(lv->vg->cmd, lv)) {
|
||||
*slv = lv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deactivates LV toghether with explicit deactivation call made also for all its component LVs.
|
||||
*/
|
||||
int deactivate_lv_with_sub_lv(const struct logical_volume *lv)
|
||||
{
|
||||
struct logical_volume *flv;
|
||||
|
||||
if (!deactivate_lv(lv->vg->cmd, lv)) {
|
||||
log_error("Cannot deactivate logical volume %s.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!for_each_sub_lv((struct logical_volume *)lv, _deactivate_sub_lv_cb, &flv)) {
|
||||
log_error("Cannot deactivate subvolume %s of logical volume %s.",
|
||||
display_lvname(flv), display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@ -198,6 +198,11 @@ int lv_is_active_exclusive(const struct logical_volume *lv);
|
||||
int lv_is_active_exclusive_locally(const struct logical_volume *lv);
|
||||
int lv_is_active_exclusive_remotely(const struct logical_volume *lv);
|
||||
|
||||
/* Check is any component LV is active */
|
||||
const struct logical_volume *lv_component_is_active(const struct logical_volume *lv);
|
||||
const struct logical_volume *lv_holder_is_active(const struct logical_volume *lv);
|
||||
int deactivate_lv_with_sub_lv(const struct logical_volume *lv);
|
||||
|
||||
int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
const char *layer, const char *target_type);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
|
@ -253,6 +253,17 @@
|
||||
|
||||
#define lv_is_removed(lv) (((lv)->status & LV_REMOVED) ? 1 : 0)
|
||||
|
||||
/* Recognize component LV (matching lib/misc/lvm-string.c _lvname_has_reserved_component_string()) */
|
||||
#define lv_is_component(lv) (lv_is_cache_origin(lv) || ((lv)->status & (\
|
||||
CACHE_POOL_DATA |\
|
||||
CACHE_POOL_METADATA |\
|
||||
MIRROR_IMAGE |\
|
||||
MIRROR_LOG |\
|
||||
RAID_IMAGE |\
|
||||
RAID_META |\
|
||||
THIN_POOL_DATA |\
|
||||
THIN_POOL_METADATA)) ? 1 : 0)
|
||||
|
||||
int lv_layout_and_role(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
struct dm_list **layout, struct dm_list **role);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user