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

Use lvconvert --repair instead of vgreduce in mirror dmeventd DSO (mornfall)

Introduce lvconvert --use_policies (mornfall)
This commit is contained in:
Milan Broz 2009-06-04 12:01:15 +00:00
parent 896fc66e32
commit c26488d348
9 changed files with 91 additions and 32 deletions

View File

@ -1,5 +1,7 @@
Version 2.02.48 -
===============================
Use lvconvert --repair instead of vgreduce in mirror dmeventd DSO.
Introduce lvconvert --use_policies (repair policy according to lvm.conf).
Fix clvmd-corosync to match new corosync API.
Fix makefile to build also shared libraries when running plain make.
Fix rename of active snapshot with virtual origin.

View File

@ -152,7 +152,7 @@ static int _remove_failed_devices(const char *device)
}
/* FIXME Is any sanity-checking required on %s? */
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing --force %s", vg)) {
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "lvconvert --config devices{ignore_suspended_devices=1} --repair --use-policies %s/%s", vg, lv)) {
/* this error should be caught above, but doesn't hurt to check again */
syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */

View File

@ -317,8 +317,10 @@ activation {
# A disk log ensures that a mirror does not need to be re-synced
# (all copies made the same) every time a machine reboots or crashes.
#
# In the event of a failure, the specified policy will be used to
# determine what happens:
# In the event of a failure, the specified policy will be used to determine
# what happens. This applies to automatic repairs (when the mirror is being
# monitored by dmeventd) and to manual lvconvert --repair when
# --use-policies is given.
#
# "remove" - Simply remove the faulty device and run without it. If
# the log device fails, the mirror would convert to using
@ -338,20 +340,13 @@ activation {
# will preserve the mirror characteristic of the device.
# This policy acts like "remove" if no suitable device and
# space can be allocated for the replacement.
# Currently this is not implemented properly and behaves
# similarly to:
#
# "allocate_anywhere" - Operates like "allocate", but it does not
# require that the new space being allocated be on a
# device is not part of the mirror. For a log device
# failure, this could mean that the log is allocated on
# the same device as a mirror device. For a mirror
# device, this could mean that the mirror device is
# allocated on the same device as another mirror device.
# This policy would not be wise for mirror devices
# because it would break the redundant nature of the
# mirror. This policy acts like "remove" if no suitable
# device and space can be allocated for the replacement.
# "allocate_anywhere" - Not yet implemented. Useful to place the log device
# temporarily on same physical volume as one of the mirror
# images. This policy is not recommended for mirror devices
# since it would break the redundant nature of the mirror. This
# policy acts like "remove" if no suitable device and space can
# be allocated for the replacement.
mirror_log_fault_policy = "allocate"
mirror_device_fault_policy = "remove"

View File

@ -126,4 +126,7 @@
#define DEFAULT_SEGS_SORT "vg_name,lv_name,seg_start"
#define DEFAULT_PVSEGS_SORT "pv_name,pvseg_start"
#define DEFAULT_MIRROR_DEVICE_FAULT_POLICY "remove"
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
#endif /* _LVM_DEFAULTS_H */

View File

@ -63,8 +63,14 @@ Report progress as a percentage at regular intervals.
.TP
.I \-\-repair
Repair a mirror that has suffered a disk failure. The mirror will be brought
back into a consistent state, and if possible, the original number of
mirrors will be restored.
back into a consistent state, and if possible, the original number of mirrors
will be restored, if so desired. By default, lvconvert will prompt you whether
to perform the replacement. If you instead wish to unconditionally replace
missing devices, you may specify \-y on the commandline and if you instead want
no replacement to happen at all, you may provide \-f. Additionally, you may use
"--use-policies" - this option will use the device replacement policy specified
in lvm.conf, specifically "activation/mirror_log_fault_policy" and
"activation/mirror_device_fault_policy".
.br
.TP
.I \-s, \-\-snapshot

View File

@ -22,19 +22,19 @@ disable_dev $dev1
lvchange --partial -a y $vg/mirror
not vgreduce -v --removemissing $vg
lvconvert -i 1 --repair $vg/mirror
lvconvert -y -i 1 --repair $vg/mirror
vgreduce --removemissing $vg
enable_dev $dev1
vgextend $vg $dev1
disable_dev $dev2
lvconvert -i 1 --repair $vg/mirror
lvconvert -y -i 1 --repair $vg/mirror
vgreduce --removemissing $vg
enable_dev $dev2
vgextend $vg $dev2
disable_dev $dev3
lvconvert -i 1 --repair $vg/mirror
lvconvert -y -i 1 --repair $vg/mirror
vgreduce --removemissing $vg
enable_dev $dev3
@ -42,5 +42,5 @@ vgextend $vg $dev3
lvcreate -m 2 -l 1 -n mirror2 $vg $dev1 $dev2 $dev3 $dev4
vgchange -a n $vg
pvremove -ff -y $dev4
echo 'y' | not lvconvert -i 1 --repair $vg/mirror2
echo 'y' | not lvconvert -y -i 1 --repair $vg/mirror2
vgs

View File

@ -50,6 +50,7 @@ arg(resync_ARG, '\0', "resync", NULL, 0)
arg(corelog_ARG, '\0', "corelog", NULL, 0)
arg(mirrorlog_ARG, '\0', "mirrorlog", string_arg, 0)
arg(repair_ARG, '\0', "repair", NULL, 0)
arg(use_policies_ARG, '\0', "use-policies", NULL, 0)
arg(monitor_ARG, '\0', "monitor", yes_no_arg, 0)
arg(config_ARG, '\0', "config", string_arg, 0)
arg(trustcache_ARG, '\0', "trustcache", NULL, 0)

View File

@ -94,7 +94,7 @@ xx(lvconvert,
0,
"lvconvert "
"[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
"\t[--repair]\n"
"\t[--repair [--use-policies]]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
@ -117,7 +117,7 @@ xx(lvconvert,
alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG,
mirrorlog_ARG, mirrors_ARG, regionsize_ARG, repair_ARG, snapshot_ARG,
test_ARG, zero_ARG)
test_ARG, use_policies_ARG, yes_ARG, force_ARG, zero_ARG)
xx(lvcreate,
"Create a logical volume",

View File

@ -457,6 +457,49 @@ static struct logical_volume *_original_lv(struct logical_volume *lv)
return next_lv;
}
static void _lvconvert_mirrors_repair_ask(struct cmd_context *cmd,
int failed_log, int failed_mirrors,
int *replace_log, int *replace_mirrors)
{
const char *leg_policy = NULL, *log_policy = NULL;
int force = arg_count(cmd, force_ARG);
int yes = arg_count(cmd, yes_ARG);
*replace_log = *replace_mirrors = 1;
if (arg_count(cmd, use_policies_ARG)) {
leg_policy = find_config_tree_str(cmd,
"activation/mirror_device_fault_policy",
DEFAULT_MIRROR_DEVICE_FAULT_POLICY);
log_policy = find_config_tree_str(cmd,
"activation/mirror_log_fault_policy",
DEFAULT_MIRROR_LOG_FAULT_POLICY);
*replace_mirrors = strcmp(leg_policy, "remove");
*replace_log = strcmp(log_policy, "remove");
return;
}
if (yes)
return;
if (force != PROMPT) {
*replace_log = *replace_mirrors = 0;
return;
}
if (failed_log &&
yes_no_prompt("Attempt to replace failed mirror log? [y/n]: ") == 'n') {
*replace_log = 0;
}
if (failed_mirrors &&
yes_no_prompt("Attempt to replace failed mirror images "
"(requires full device resync)? [y/n]: ") == 'n') {
*replace_mirrors = 0;
}
}
static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@ -470,18 +513,21 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
int failed_mirrors = 0, failed_log = 0;
struct dm_list *old_pvh = NULL, *remove_pvs = NULL;
int repair = arg_count(cmd, repair_ARG);
int replace_log = 1, replace_mirrors = 1;
seg = first_seg(lv);
existing_mirrors = lv_mirror_count(lv);
/* If called with no argument, try collapsing the resync layers */
if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG) &&
!arg_count(cmd, corelog_ARG) && !arg_count(cmd, regionsize_ARG) &&
!arg_count(cmd, repair_ARG)) {
!repair) {
lp->need_polling = 1;
return 1;
}
if (arg_count(cmd, mirrors_ARG) && arg_count(cmd, repair_ARG)) {
if (arg_count(cmd, mirrors_ARG) && repair) {
log_error("You can only use one of -m, --repair.");
return 0;
}
@ -503,7 +549,7 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
else
lp->mirrors += 1;
if (arg_count(cmd,repair_ARG)) {
if (repair) {
cmd->handles_missing_pvs = 1;
cmd->partial_activation = 1;
lp->need_polling = 0;
@ -514,7 +560,7 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
if ((failed_mirrors = _failed_mirrors_count(lv)) < 0)
return_0;
lp->mirrors -= failed_mirrors;
log_error("Mirror status: %d/%d legs failed.",
log_error("Mirror status: %d/%d images failed.",
failed_mirrors, existing_mirrors);
old_pvh = lp->pvh;
if (!(lp->pvh = _failed_pv_list(lv->vg)))
@ -577,6 +623,10 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
return 0;
}
if (repair)
_lvconvert_mirrors_repair_ask(cmd, failed_log, failed_mirrors,
&replace_log, &replace_mirrors);
restart:
/*
* Converting from mirror to linear
@ -594,7 +644,7 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
*/
if (lp->mirrors < existing_mirrors) {
/* Reduce number of mirrors */
if (arg_count(cmd, repair_ARG) || lp->pv_count)
if (repair || lp->pv_count)
remove_pvs = lp->pvh;
if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
(corelog || lp->mirrors == 1) ? 1U : 0U,
@ -727,13 +777,15 @@ static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv
if (failed_log || failed_mirrors) {
lp->pvh = old_pvh;
if (failed_log)
if (failed_log && replace_log)
failed_log = corelog = 0;
lp->mirrors += failed_mirrors;
if (replace_mirrors)
lp->mirrors += failed_mirrors;
failed_mirrors = 0;
existing_mirrors = lv_mirror_count(lv);
/* Now replace missing devices. */
goto restart;
if (replace_log || replace_mirrors)
goto restart;
}
if (!lp->need_polling)