mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +03:00
Added displayable_lvs_in_vg and lv_is_displayable functions to deal with
the counts of visible LVs from user's perspective consistently throughout the code.
This commit is contained in:
parent
9d9589d173
commit
b47952641a
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.44 -
|
Version 2.02.44 -
|
||||||
====================================
|
====================================
|
||||||
|
Use displayable_lvs_in_vg and lv_is_displayable for consistency throughout.
|
||||||
Fix race in vgcreate that would result in second caller overwriting first.
|
Fix race in vgcreate that would result in second caller overwriting first.
|
||||||
Fix uninitialised lv_count in vgdisplay -c.
|
Fix uninitialised lv_count in vgdisplay -c.
|
||||||
Don't skip updating pvid hash when lvmcache_info struct got swapped.
|
Don't skip updating pvid hash when lvmcache_info struct got swapped.
|
||||||
|
@ -666,7 +666,7 @@ int lvs_in_vg_opened(const struct volume_group *vg)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||||
if (lvl->lv->status & VISIBLE_LV)
|
if (lv_is_displayable(lvl->lv))
|
||||||
count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
|
count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,8 +574,6 @@ void vgdisplay_full(const struct volume_group *vg)
|
|||||||
{
|
{
|
||||||
uint32_t access_str;
|
uint32_t access_str;
|
||||||
uint32_t active_pvs;
|
uint32_t active_pvs;
|
||||||
uint32_t lv_count = 0;
|
|
||||||
struct lv_list *lvl;
|
|
||||||
char uuid[64] __attribute((aligned(8)));
|
char uuid[64] __attribute((aligned(8)));
|
||||||
|
|
||||||
active_pvs = vg->pv_count - vg_missing_pv_count(vg);
|
active_pvs = vg->pv_count - vg_missing_pv_count(vg);
|
||||||
@ -607,12 +605,8 @@ void vgdisplay_full(const struct volume_group *vg)
|
|||||||
vg->status & SHARED ? "yes" : "no");
|
vg->status & SHARED ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_list_iterate_items(lvl, &vg->lvs)
|
|
||||||
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
|
|
||||||
lv_count++;
|
|
||||||
|
|
||||||
log_print("MAX LV %u", vg->max_lv);
|
log_print("MAX LV %u", vg->max_lv);
|
||||||
log_print("Cur LV %u", lv_count);
|
log_print("Cur LV %u", displayable_lvs_in_vg(vg));
|
||||||
log_print("Open LV %u", lvs_in_vg_opened(vg));
|
log_print("Open LV %u", lvs_in_vg_opened(vg));
|
||||||
/****** FIXME Max LV Size
|
/****** FIXME Max LV Size
|
||||||
log_print ( "MAX LV Size %s",
|
log_print ( "MAX LV Size %s",
|
||||||
@ -656,17 +650,11 @@ void vgdisplay_full(const struct volume_group *vg)
|
|||||||
void vgdisplay_colons(const struct volume_group *vg)
|
void vgdisplay_colons(const struct volume_group *vg)
|
||||||
{
|
{
|
||||||
uint32_t active_pvs;
|
uint32_t active_pvs;
|
||||||
uint32_t lv_count = 0;
|
|
||||||
struct lv_list *lvl;
|
|
||||||
const char *access_str;
|
const char *access_str;
|
||||||
char uuid[64] __attribute((aligned(8)));
|
char uuid[64] __attribute((aligned(8)));
|
||||||
|
|
||||||
active_pvs = vg->pv_count - vg_missing_pv_count(vg);
|
active_pvs = vg->pv_count - vg_missing_pv_count(vg);
|
||||||
|
|
||||||
dm_list_iterate_items(lvl, &vg->lvs)
|
|
||||||
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
|
|
||||||
lv_count++;
|
|
||||||
|
|
||||||
switch (vg->status & (LVM_READ | LVM_WRITE)) {
|
switch (vg->status & (LVM_READ | LVM_WRITE)) {
|
||||||
case LVM_READ | LVM_WRITE:
|
case LVM_READ | LVM_WRITE:
|
||||||
access_str = "r/w";
|
access_str = "r/w";
|
||||||
@ -693,7 +681,7 @@ void vgdisplay_colons(const struct volume_group *vg)
|
|||||||
vg->status,
|
vg->status,
|
||||||
/* internal volume group number; obsolete */
|
/* internal volume group number; obsolete */
|
||||||
vg->max_lv,
|
vg->max_lv,
|
||||||
vg->lv_count,
|
displayable_lvs_in_vg(vg),
|
||||||
lvs_in_vg_opened(vg),
|
lvs_in_vg_opened(vg),
|
||||||
/* FIXME: maximum logical volume size */
|
/* FIXME: maximum logical volume size */
|
||||||
vg->max_pv,
|
vg->max_pv,
|
||||||
|
@ -592,14 +592,14 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
|
|||||||
* Write visible LVs first
|
* Write visible LVs first
|
||||||
*/
|
*/
|
||||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||||
if (!(lvl->lv->status & VISIBLE_LV))
|
if (!(lv_is_displayable(lvl->lv)))
|
||||||
continue;
|
continue;
|
||||||
if (!_print_lv(f, lvl->lv))
|
if (!_print_lv(f, lvl->lv))
|
||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||||
if ((lvl->lv->status & VISIBLE_LV))
|
if ((lv_is_displayable(lvl->lv)))
|
||||||
continue;
|
continue;
|
||||||
if (!_print_lv(f, lvl->lv))
|
if (!_print_lv(f, lvl->lv))
|
||||||
return_0;
|
return_0;
|
||||||
|
@ -1715,7 +1715,7 @@ int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
struct lv_names lv_names;
|
struct lv_names lv_names;
|
||||||
|
|
||||||
/* rename is not allowed on sub LVs */
|
/* rename is not allowed on sub LVs */
|
||||||
if (!lv_is_visible(lv)) {
|
if (!lv_is_displayable(lv)) {
|
||||||
log_error("Cannot rename internal LV \"%s\".", lv->name);
|
log_error("Cannot rename internal LV \"%s\".", lv->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -483,6 +483,9 @@ int lv_is_origin(const struct logical_volume *lv);
|
|||||||
int lv_is_cow(const struct logical_volume *lv);
|
int lv_is_cow(const struct logical_volume *lv);
|
||||||
int lv_is_visible(const struct logical_volume *lv);
|
int lv_is_visible(const struct logical_volume *lv);
|
||||||
|
|
||||||
|
/* Test if given LV is visible from user's perspective */
|
||||||
|
int lv_is_displayable(const struct logical_volume *lv);
|
||||||
|
|
||||||
int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
|
int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
|
||||||
|
|
||||||
/* Given a cow LV, return return the snapshot lv_segment that uses it */
|
/* Given a cow LV, return return the snapshot lv_segment that uses it */
|
||||||
|
@ -337,6 +337,7 @@ int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
|
|||||||
{
|
{
|
||||||
struct physical_volume *pv;
|
struct physical_volume *pv;
|
||||||
struct pv_list *pvl;
|
struct pv_list *pvl;
|
||||||
|
unsigned lv_count;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
if (!vg || !consistent || vg_missing_pv_count(vg)) {
|
if (!vg || !consistent || vg_missing_pv_count(vg)) {
|
||||||
@ -350,22 +351,26 @@ int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
|
|||||||
if (!vg_check_status(vg, EXPORTED_VG))
|
if (!vg_check_status(vg, EXPORTED_VG))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (vg->lv_count) {
|
lv_count = displayable_lvs_in_vg(vg);
|
||||||
|
|
||||||
|
if (lv_count) {
|
||||||
if ((force == PROMPT) &&
|
if ((force == PROMPT) &&
|
||||||
(yes_no_prompt("Do you really want to remove volume "
|
(yes_no_prompt("Do you really want to remove volume "
|
||||||
"group \"%s\" containing %d "
|
"group \"%s\" containing %u "
|
||||||
"logical volumes? [y/n]: ",
|
"logical volumes? [y/n]: ",
|
||||||
vg_name, vg->lv_count) == 'n')) {
|
vg_name, lv_count) == 'n')) {
|
||||||
log_print("Volume group \"%s\" not removed", vg_name);
|
log_print("Volume group \"%s\" not removed", vg_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!remove_lvs_in_vg(cmd, vg, force))
|
if (!remove_lvs_in_vg(cmd, vg, force))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv_count = displayable_lvs_in_vg(vg);
|
||||||
|
|
||||||
if (vg->lv_count) {
|
if (lv_count) {
|
||||||
log_error("Volume group \"%s\" still contains %d "
|
log_error("Volume group \"%s\" still contains %u "
|
||||||
"logical volume(s)", vg_name, vg->lv_count);
|
"logical volume(s)", vg_name, lv_count);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,6 +1103,18 @@ int vg_remove(struct volume_group *vg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned displayable_lvs_in_vg(const struct volume_group *vg)
|
||||||
|
{
|
||||||
|
struct lv_list *lvl;
|
||||||
|
unsigned lv_count = 0;
|
||||||
|
|
||||||
|
dm_list_iterate_items(lvl, &vg->lvs)
|
||||||
|
if (lv_is_displayable(lvl->lv))
|
||||||
|
lv_count++;
|
||||||
|
|
||||||
|
return lv_count;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine whether two vgs are compatible for merging.
|
* Determine whether two vgs are compatible for merging.
|
||||||
*/
|
*/
|
||||||
|
@ -320,6 +320,11 @@ int add_seg_to_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *
|
|||||||
int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
|
int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
|
||||||
struct lv_segment *get_only_segment_using_this_lv(struct logical_volume *lv);
|
struct lv_segment *get_only_segment_using_this_lv(struct logical_volume *lv);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count LVs that are visible from user's perspective.
|
||||||
|
*/
|
||||||
|
unsigned displayable_lvs_in_vg(const struct volume_group *vg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For internal metadata caching.
|
* For internal metadata caching.
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +36,14 @@ int lv_is_visible(const struct logical_volume *lv)
|
|||||||
return lv->status & VISIBLE_LV ? 1 : 0;
|
return lv->status & VISIBLE_LV ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lv_is_displayable(const struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
if (lv->status & SNAPSHOT)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (lv->status & VISIBLE_LV) || lv_is_cow(lv) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Given a cow LV, return the snapshot lv_segment that uses it */
|
/* Given a cow LV, return the snapshot lv_segment that uses it */
|
||||||
struct lv_segment *find_cow(const struct logical_volume *lv)
|
struct lv_segment *find_cow(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
|
@ -511,7 +511,7 @@ static int _lvname_disp(struct dm_report *rh, struct dm_pool *mem,
|
|||||||
char *repstr, *lvname;
|
char *repstr, *lvname;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (lv_is_visible(lv)) {
|
if (lv_is_displayable(lv)) {
|
||||||
repstr = lv->name;
|
repstr = lv->name;
|
||||||
return dm_report_field_string(rh, field, (const char **) &repstr);
|
return dm_report_field_string(rh, field, (const char **) &repstr);
|
||||||
}
|
}
|
||||||
@ -911,12 +911,9 @@ static int _lvcount_disp(struct dm_report *rh, struct dm_pool *mem,
|
|||||||
const void *data, void *private)
|
const void *data, void *private)
|
||||||
{
|
{
|
||||||
const struct volume_group *vg = (const struct volume_group *) data;
|
const struct volume_group *vg = (const struct volume_group *) data;
|
||||||
struct lv_list *lvl;
|
uint32_t count;
|
||||||
uint32_t count = 0;
|
|
||||||
|
|
||||||
dm_list_iterate_items(lvl, &vg->lvs)
|
count = displayable_lvs_in_vg(vg);
|
||||||
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
|
|
||||||
count++;
|
|
||||||
|
|
||||||
return _uint32_disp(rh, mem, field, &count, private);
|
return _uint32_disp(rh, mem, field, &count, private);
|
||||||
}
|
}
|
||||||
|
@ -590,7 +590,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(lv->status & VISIBLE_LV)) {
|
if (!(lv_is_displayable(lv))) {
|
||||||
log_error("Unable to change internal LV %s directly",
|
log_error("Unable to change internal LV %s directly",
|
||||||
lv->name);
|
lv->name);
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
static int _lvdisplay_single(struct cmd_context *cmd, struct logical_volume *lv,
|
static int _lvdisplay_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
void *handle)
|
void *handle)
|
||||||
{
|
{
|
||||||
if (!arg_count(cmd, all_ARG) && !lv_is_visible(lv))
|
if (!arg_count(cmd, all_ARG) && !lv_is_displayable(lv))
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
|
|
||||||
if (arg_count(cmd, colon_ARG))
|
if (arg_count(cmd, colon_ARG))
|
||||||
|
@ -27,7 +27,7 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
|
|
||||||
const char *active_str, *snapshot_str;
|
const char *active_str, *snapshot_str;
|
||||||
|
|
||||||
if (!arg_count(cmd, all_ARG) && !lv_is_visible(lv))
|
if (!arg_count(cmd, all_ARG) && !lv_is_displayable(lv))
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
|
|
||||||
inkernel = lv_info(cmd, lv, &info, 1, 0) && info.exists;
|
inkernel = lv_info(cmd, lv, &info, 1, 0) && info.exists;
|
||||||
|
@ -36,7 +36,7 @@ static int _vgs_single(struct cmd_context *cmd __attribute((unused)),
|
|||||||
static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
|
static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
void *handle)
|
void *handle)
|
||||||
{
|
{
|
||||||
if (!arg_count(cmd, all_ARG) && !lv_is_visible(lv))
|
if (!arg_count(cmd, all_ARG) && !lv_is_displayable(lv))
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
|
|
||||||
if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL))
|
if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL))
|
||||||
@ -102,7 +102,7 @@ static int _pvsegs_sub_single(struct cmd_context *cmd __attribute((unused)),
|
|||||||
static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv,
|
static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
void *handle)
|
void *handle)
|
||||||
{
|
{
|
||||||
if (!arg_count(cmd, all_ARG) && !lv_is_visible(lv))
|
if (!arg_count(cmd, all_ARG) && !lv_is_displayable(lv))
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
|
|
||||||
return process_each_segment_in_lv(cmd, lv, handle, _segs_single);
|
return process_each_segment_in_lv(cmd, lv, handle, _segs_single);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user