1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-28 02:50:41 +03:00

Add lvchange --forcesync.

This commit is contained in:
Alasdair Kergon 2006-10-23 23:03:55 +00:00
parent 2bdc8e1252
commit 04e023be19
5 changed files with 178 additions and 7 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.13 -
===================================
Add lvchange --forcesync.
Perform high-level free space check before each allocation attempt.
Don't allow a node to remove an LV that's exclusively active on anther node.
Cope if same PV is included more than once in cmdline PE range list.

View File

@ -7,6 +7,7 @@ lvchange \- change attributes of a logical volume
[\-A/\-\-autobackup y/n] [\-a/\-\-available y/n/ey/en/ly/ln]
[\-\-alloc AllocationPolicy]
[\-C/\-\-contiguous y/n] [\-d/\-\-debug] [\-\-deltag Tag]
[\-\-forcesync]
[\-h/\-?/\-\-help]
[\-\-ignorelockingfailure]
[\-\-monitor {y|n}]
@ -40,6 +41,14 @@ logical volumes. It's only possible to change a non-contiguous
logical volume's allocation policy to contiguous, if all of the
allocated physical extents are already contiguous.
.TP
.I \-\-forcesync
This option only make sense if the logical volume being operated
on is a mirrored logical volume. This option is used to
resynchronize the devices in a mirrored logical volume. Since
resynchronization can take considerable time and resources, you
should consider using this option only if you have reason to
believe that the devices in your mirror are no longer the same.
.TP
.I \-\-minor minor
Set the minor number.
.TP

View File

@ -46,6 +46,7 @@ arg(alloc_ARG, '\0', "alloc", alloc_arg)
arg(separator_ARG, '\0', "separator", string_arg)
arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL)
arg(nosync_ARG, '\0', "nosync", NULL)
arg(forcesync_ARG, '\0', "forcesync", NULL)
arg(corelog_ARG, '\0', "corelog", NULL)
arg(monitor_ARG, '\0', "monitor", yes_no_arg)
arg(config_ARG, '\0', "config", string_arg)

View File

@ -61,6 +61,7 @@ xx(lvchange,
"\t[-d|--debug]\n"
"\t[--deltag Tag]\n"
"\t[-f|--force]\n"
"\t[--forcesync]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
"\t[--monitor {y|n}]\n"
@ -71,13 +72,14 @@ xx(lvchange,
"\t[--refresh]\n"
"\t[-t|--test]\n"
"\t[-v|--verbose]\n"
"\t[-y|--yes]\n"
"\t[--version]" "\n"
"\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
alloc_ARG, autobackup_ARG, available_ARG, contiguous_ARG, force_ARG,
ignorelockingfailure_ARG, major_ARG, minor_ARG, monitor_ARG,
forcesync_ARG, ignorelockingfailure_ARG, major_ARG, minor_ARG, monitor_ARG,
partial_ARG, permission_ARG, persistent_ARG, readahead_ARG,
refresh_ARG, addtag_ARG, deltag_ARG, test_ARG)
refresh_ARG, addtag_ARG, deltag_ARG, test_ARG, yes_ARG)
xx(lvconvert,
"Change logical volume layout",
@ -274,6 +276,7 @@ xx(lvreduce,
"\t[-r|--resizefs]\n"
"\t[-t|--test]\n"
"\t[-v|--verbose]\n"
"\t[-y|--yes]\n"
"\t[--version]" "\n"
"\tLogicalVolume[Path]\n",

View File

@ -127,10 +127,10 @@ static int lvchange_availability(struct cmd_context *cmd,
}
} else {
if (lockingfailed() && (lv->vg->status & CLUSTERED)) {
log_verbose("Locking failed: ignoring clustered "
log_verbose("Locking failed: ignoring clustered "
"logical volume %s", lv->name);
return 0;
}
return 0;
}
if (lv_is_origin(lv) || (activate == CHANGE_AE)) {
log_verbose("Activating logical volume \"%s\" "
@ -175,6 +175,158 @@ static int lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv)
return 1;
}
static int lvchange_forcesync(struct cmd_context *cmd,
struct logical_volume *lv)
{
int active = 0;
struct lvinfo info;
struct logical_volume *log_lv;
if (!(lv->status & MIRRORED)) {
log_error("Unable to resync %s because it is not mirrored.",
lv->name);
return 1;
}
if (lv->status & PVMOVE) {
log_error("Unable to resync pvmove volume %s", lv->name);
return 0;
}
if (lv->status & LOCKED) {
log_error("Unable to resync locked volume %s", lv->name);
return 0;
}
if (lv_info(cmd, lv, &info, 1)) {
if (info.open_count) {
log_error("Can't resync open logical volume \"%s\"",
lv->name);
return ECMD_FAILED;
}
if (info.exists && !arg_count(cmd, yes_ARG)) {
if (yes_no_prompt("Do you really want to deactivate "
"logical volume %s to resync it? [y/n]: ",
lv->name) == 'n') {
log_print("Logical volume \"%s\" not resynced",
lv->name);
return ECMD_FAILED;
}
}
active = 1;
}
if ((lv->vg->status & CLUSTERED) && !activate_lv_excl(cmd, lv)) {
log_error("Can't get exclusive access to clustered volume %s",
lv->name);
return ECMD_FAILED;
}
if (!deactivate_lv(cmd, lv)) {
log_error("Unable to deactivate %s for resync", lv->name);
return 0;
}
log_lv = first_seg(lv)->log_lv;
log_very_verbose("Starting resync of %s%s%s mirror \"%s\"",
(active) ? "active " : "",
(lv->vg->status & CLUSTERED) ? "clustered " : "",
(log_lv) ? "disk-logged" : "core-logged",
lv->name);
/*
* If this mirror has a core log (i.e. !log_lv),
* then simply deactivating/activating will cause
* it to reset the sync status. We only need to
* worry about persistent logs.
*/
if (!log_lv && !(lv->status & MIRROR_NOTSYNCED)) {
if (active && !activate_lv(cmd, lv)) {
log_error("Failed to reactivate %s to resynchronize "
"mirror", lv->name);
return 0;
}
return 1;
}
lv->status &= ~MIRROR_NOTSYNCED;
if (log_lv) {
/* Separate mirror log so we can clear it */
first_seg(lv)->log_lv = NULL;
log_lv->status &= ~MIRROR_LOG;
log_lv->status |= VISIBLE_LV;
if (!vg_write(lv->vg)) {
log_error("Failed to write intermediate VG metadata.");
if (active) {
first_seg(lv)->log_lv = log_lv;
log_lv->status |= MIRROR_LOG;
log_lv->status &= ~VISIBLE_LV;
if (!activate_lv(cmd, lv))
stack;
}
return 0;
}
backup(lv->vg);
if (!vg_commit(lv->vg)) {
log_error("Failed to commit intermediate VG metadata.");
if (active) {
first_seg(lv)->log_lv = log_lv;
log_lv->status |= MIRROR_LOG;
log_lv->status &= ~VISIBLE_LV;
if (!activate_lv(cmd, lv))
stack;
}
return 0;
}
if (!activate_lv(cmd, log_lv)) {
log_error("Unable to activate %s for mirror log resync",
log_lv->name);
return 0;
}
log_very_verbose("Clearing log device %s", log_lv->name);
if (!set_lv(cmd, log_lv, 0)) {
log_error("Unable to reset sync status for %s", lv->name);
if (!deactivate_lv(cmd, log_lv))
log_error("Failed to deactivate log LV after "
"wiping failed");
return 0;
}
if (!deactivate_lv(cmd, log_lv)) {
log_error("Unable to deactivate log LV %s after wiping "
"for resync", log_lv->name);
return 0;
}
/* Put mirror log back in place */
first_seg(lv)->log_lv = log_lv;
log_lv->status |= MIRROR_LOG;
log_lv->status &= ~VISIBLE_LV;
}
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
if (!vg_write(lv->vg) || !vg_commit(lv->vg)) {
log_error("Failed to update metadata on disk.");
return 0;
}
if (active && !activate_lv(cmd, lv)) {
log_error("Failed to reactivate %s after resync", lv->name);
return 0;
}
return 1;
}
static int lvchange_alloc(struct cmd_context *cmd, struct logical_volume *lv)
{
int want_contiguous = 0;
@ -495,6 +647,10 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
if (doit)
log_print("Logical volume \"%s\" changed", lv->name);
if (arg_count(cmd, forcesync_ARG))
if (!lvchange_forcesync(cmd, lv))
return ECMD_FAILED;
/* availability change */
if (arg_count(cmd, available_ARG)) {
if (!lvchange_availability(cmd, lv))
@ -522,9 +678,10 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
&& !arg_count(cmd, minor_ARG) && !arg_count(cmd, major_ARG)
&& !arg_count(cmd, persistent_ARG) && !arg_count(cmd, addtag_ARG)
&& !arg_count(cmd, deltag_ARG) && !arg_count(cmd, refresh_ARG)
&& !arg_count(cmd, alloc_ARG) && !arg_count(cmd, monitor_ARG)) {
&& !arg_count(cmd, alloc_ARG) && !arg_count(cmd, monitor_ARG)
&& !arg_count(cmd, forcesync_ARG)) {
log_error("Need 1 or more of -a, -C, -j, -m, -M, -p, -r, "
"--refresh, --alloc, --addtag, --deltag "
"--forcesync, --refresh, --alloc, --addtag, --deltag "
"or --monitor");
return EINVALID_CMD_LINE;
}