1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

lv_remove: reduce commits for removed LVs

This patch postpones update of lvm metadata for each removed
LV for later moment depending on LV type.

It also queues messages to be printed after such write & commit.

As such there is some change in the behavior - although before
prompt we do make  write&commit happens automatically in some
other error case we rather keep 'existing' state - so there
could be difference in amount of removed & commited LVs.

IMHO introduce logic is slightly better and more save.

But some cases still need the early commit - i.e. thin-removal
and fixing this needs some more thinking.

TODO: improve removal at least with the case of the whole thin-pool.
i.e. we can simply recognize removal of 'all LVs/whole VG'.
This commit is contained in:
Zdenek Kabelac 2021-03-05 16:21:50 +01:00
parent ee9488488f
commit a125a3bb50
5 changed files with 46 additions and 12 deletions

View File

@ -6538,6 +6538,7 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
int ask_discard;
struct seg_list *sl;
struct lv_segment *seg = first_seg(lv);
char msg[NAME_LEN + 300], *msg_dup;
vg = lv->vg;
@ -6609,6 +6610,8 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
if ((force == PROMPT) &&
!lv_is_pending_delete(lv) &&
lv_is_visible(lv)) {
if (vg->needs_write_and_commit && (!vg_write(vg) || !vg_commit(vg)))
return 0;
if (yes_no_prompt("Do you really want to remove%s active "
"%slogical volume %s? [y/n]: ",
ask_discard ? " and DISCARD" : "",
@ -6644,12 +6647,16 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
}
}
if (!lv_is_historical(lv) && (force == PROMPT) && ask_discard &&
yes_no_prompt("Do you really want to remove and DISCARD "
"logical volume %s? [y/n]: ",
display_lvname(lv)) == 'n') {
log_error("Logical volume %s not removed.", display_lvname(lv));
return 0;
if (!lv_is_historical(lv) && (force == PROMPT) && ask_discard) {
/* try to store on disks already confirmed removals */
if (vg->needs_write_and_commit && (!vg_write(vg) || !vg_commit(vg)))
return 0;
if (yes_no_prompt("Do you really want to remove and DISCARD "
"logical volume %s? [y/n]: ",
display_lvname(lv)) == 'n') {
log_error("Logical volume %s not removed.", display_lvname(lv));
return 0;
}
}
if (lv_is_cache(lv) && !lv_is_pending_delete(lv)) {
@ -6765,8 +6772,11 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
/* store it on disks */
if (!vg_write(vg) || !vg_commit(vg))
if (!pool_lv && (!strcmp(cmd->name, "lvremove") || !strcmp(cmd->name, "vgremove"))) {
/* With lvremove & vgremove try to postpone commit after last such LV */
vg->needs_write_and_commit = 1;
log_debug_metadata("Postponing write and commit.");
} else if (!vg_write(vg) || !vg_commit(vg)) /* store it on disks */
return_0;
/* Release unneeded blocks in thin pool */
@ -6785,10 +6795,18 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
lockd_lv(cmd, lock_lv, "un", LDLV_PERSISTENT);
lockd_free_lv(cmd, vg, lv->name, &lv->lvid.id[1], lv->lock_args);
if (!suppress_remove_message && (visible || historical))
log_print_unless_silent("%sogical volume \"%s\" successfully removed",
historical ? "Historical l" : "L",
historical ? lv->this_glv->historical->name : lv->name);
if (!suppress_remove_message && (visible || historical)) {
(void) dm_snprintf(msg, sizeof(msg),
"%sogical volume \"%s\" successfully removed",
historical ? "Historical l" : "L",
historical ? lv->this_glv->historical->name : lv->name);
if (!vg->needs_write_and_commit)
log_print_unless_silent("%s", msg);
/* Keep print message for later display with next vg_write() and vg_commit() */
else if (!(msg_dup = dm_pool_strdup(vg->vgmem, msg)) ||
!str_list_add_no_dup_check(vg->vgmem, &vg->msg_list, msg_dup))
return_0;
}
return 1;
}

View File

@ -3173,6 +3173,7 @@ static int _vg_commit_mdas(struct volume_group *vg)
int vg_commit(struct volume_group *vg)
{
struct pv_list *pvl;
struct dm_str_list *sl;
int ret;
ret = _vg_commit_mdas(vg);
@ -3190,6 +3191,14 @@ int vg_commit(struct volume_group *vg)
/* This *is* the original now that it's commited. */
_vg_move_cached_precommitted_to_committed(vg);
if (vg->needs_write_and_commit){
/* Print buffered messages that have been finished with this commit. */
dm_list_iterate_items(sl, &vg->msg_list)
log_print_unless_silent("%s", sl->str);
dm_list_init(&vg->msg_list);
vg->needs_write_and_commit = 0;
}
}
/* If at least one mda commit succeeded, it was committed */

View File

@ -60,6 +60,7 @@ struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
dm_list_init(&vg->removed_lvs);
dm_list_init(&vg->removed_historical_lvs);
dm_list_init(&vg->removed_pvs);
dm_list_init(&vg->msg_list);
log_debug_mem("Allocated VG %s at %p.", vg->name ? : "<no name>", (void *)vg);

View File

@ -43,6 +43,7 @@ struct volume_group {
uint32_t seqno; /* Metadata sequence number */
unsigned skip_validate_lock_args : 1;
unsigned needs_backup : 1;
unsigned needs_write_and_commit : 1;
uint32_t write_count; /* count the number of vg_write calls */
/*
@ -129,6 +130,7 @@ struct volume_group {
struct dm_hash_table *hostnames; /* map of creation hostnames */
struct logical_volume *pool_metadata_spare_lv; /* one per VG */
struct logical_volume *sanlock_lv; /* one per VG */
struct dm_list msg_list;
};
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,

View File

@ -3216,6 +3216,10 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
log_set_report_object_name_and_id(NULL, NULL);
}
if (vg->needs_write_and_commit && (ret_max == ECMD_PROCESSED) &&
(!vg_write(vg) || !vg_commit(vg)))
return_0;
if (vg->needs_backup)
backup(vg);