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:
parent
ee9488488f
commit
a125a3bb50
@ -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,13 +6647,17 @@ 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 "
|
||||
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)) {
|
||||
/* Handles both cachepool & cachevol based cached LVs.
|
||||
@ -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",
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user