summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2008-04-09 12:56:34 +0000
committerAlasdair Kergon <agk@redhat.com>2008-04-09 12:56:34 +0000
commiteb273c7c65a067081af4b08ee9e18f45fc2370ef (patch)
treee6b479dcec137c51dcd4e33158b5d15f15d900bc
parent178e1df257026b25a099930cf33711b85bace271 (diff)
downloadlvm2-eb273c7c65a067081af4b08ee9e18f45fc2370ef.tar.gz
lvm2-eb273c7c65a067081af4b08ee9e18f45fc2370ef.tar.xz
lvm2-eb273c7c65a067081af4b08ee9e18f45fc2370ef.zip
Use clustered mirror log with pvmove in clustered VGs, if available.
-rw-r--r--WHATS_NEW1
-rw-r--r--lib/locking/locking.c10
-rw-r--r--lib/locking/locking.h2
-rw-r--r--tools/lvconvert.c2
-rw-r--r--tools/polldaemon.h2
-rw-r--r--tools/pvmove.c72
6 files changed, 63 insertions, 26 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 0f131474..437950ea 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.34 -
===================================
+ Use clustered mirror log with pvmove in clustered VGs, if available.
Fix some pvmove error status codes.
Fix vgsplit error paths to release vg_to lock.
Indicate whether or not VG is clustered in vgcreate log message.
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 770269bb..d97c564b 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -412,19 +412,23 @@ int suspend_lvs(struct cmd_context *cmd, struct list *lvs)
}
/* Lock a list of LVs */
-int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs)
+int activate_lvs(struct cmd_context *cmd, struct list *lvs, unsigned exclusive)
{
struct list *lvh;
struct lv_list *lvl;
list_iterate_items(lvl, lvs) {
- if (!activate_lv_excl(cmd, lvl->lv)) {
+ if (!exclusive) {
+ if (!activate_lv(cmd, lvl->lv)) {
+ log_error("Failed to activate %s", lvl->lv->name);
+ return 0;
+ }
+ } else if (!activate_lv_excl(cmd, lvl->lv)) {
log_error("Failed to activate %s", lvl->lv->name);
list_uniterate(lvh, lvs, &lvl->list) {
lvl = list_item(lvh, struct lv_list);
activate_lv(cmd, lvl->lv);
}
-
return 0;
}
}
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index 475a2d0a..6c292f7d 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -120,7 +120,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/* Process list of LVs */
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
int resume_lvs(struct cmd_context *cmd, struct list *lvs);
-int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs);
+int activate_lvs(struct cmd_context *cmd, struct list *lvs, unsigned exclusive);
/* Interrupt handling */
void sigint_clear(void);
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 43447e62..1f1173f1 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -258,7 +258,7 @@ static int _update_lvconvert_mirror(struct cmd_context *cmd __attribute((unused)
struct volume_group *vg __attribute((unused)),
struct logical_volume *lv __attribute((unused)),
struct list *lvs_changed __attribute((unused)),
- int first_time __attribute((unused)))
+ unsigned flags __attribute((unused)))
{
/* lvconvert mirror doesn't require periodical metadata update */
return 1;
diff --git a/tools/polldaemon.h b/tools/polldaemon.h
index 197f02f2..1c18bf6d 100644
--- a/tools/polldaemon.h
+++ b/tools/polldaemon.h
@@ -29,7 +29,7 @@ struct poll_functions {
int (*update_metadata) (struct cmd_context *cmd,
struct volume_group *vg,
struct logical_volume *lv_mirr,
- struct list *lvs_changed, int first_time);
+ struct list *lvs_changed, unsigned flags);
int (*finish_copy) (struct cmd_context *cmd,
struct volume_group *vg,
struct logical_volume *lv_mirr,
diff --git a/tools/pvmove.c b/tools/pvmove.c
index e5ee697f..fbf0e272 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -17,28 +17,43 @@
#include "polldaemon.h"
#include "display.h"
-static int pvmove_target_present(struct cmd_context *cmd, int clustered)
+#define PVMOVE_FIRST_TIME 0x00000001 /* Called for first time */
+
+static int _pvmove_target_present(struct cmd_context *cmd, int clustered)
{
const struct segment_type *segtype;
unsigned attr = 0;
+ int found = 1;
+ static int _clustered_found = -1;
+
+ if (clustered && _clustered_found >= 0)
+ return _clustered_found;
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
return_0;
if (activation() && segtype->ops->target_present &&
- !segtype->ops->target_present(NULL, clustered ? &attr : NULL)) {
- log_error("%s: Required device-mapper target(s) not "
- "detected in your kernel", segtype->name);
- return 0;
- }
+ !segtype->ops->target_present(NULL, clustered ? &attr : NULL))
+ found = 0;
- if (clustered && !(attr & MIRROR_LOG_CLUSTERED)) {
- log_error("%s: Required device-mapper clustered log "
- "module not detected in your kernel", segtype->name);
- return 0;
+ if (activation() && clustered) {
+ if (found && (attr & MIRROR_LOG_CLUSTERED))
+ _clustered_found = found = 1;
+ else
+ _clustered_found = found = 0;
}
- return 1;
+ return found;
+}
+
+static unsigned _pvmove_is_exclusive(struct cmd_context *cmd,
+ struct volume_group *vg)
+{
+ if (vg_status(vg) & CLUSTERED)
+ if (!_pvmove_target_present(cmd, 1))
+ return 1;
+
+ return 0;
}
/* Allow /dev/vgname/lvname, vgname/lvname or lvname */
@@ -250,10 +265,22 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
return lv_mirr;
}
+static int _activate_lv(struct cmd_context *cmd, struct logical_volume *lv_mirr,
+ unsigned exclusive)
+{
+ if (exclusive)
+ return activate_lv_excl(cmd, lv_mirr);
+
+ return activate_lv(cmd, lv_mirr);
+}
+
static int _update_metadata(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv_mirr,
- struct list *lvs_changed, int first_time)
+ struct list *lvs_changed, unsigned flags)
{
+ unsigned exclusive = _pvmove_is_exclusive(cmd, vg);
+ unsigned first_time = (flags & PVMOVE_FIRST_TIME) ? 1 : 0;
+
log_verbose("Updating volume group metadata");
if (!vg_write(vg)) {
log_error("ABORTING: Volume group metadata update failed.");
@@ -289,7 +316,7 @@ static int _update_metadata(struct cmd_context *cmd, struct volume_group *vg,
/* Only the first mirror segment gets activated as a mirror */
/* FIXME: Add option to use a log */
if (first_time) {
- if (!activate_lv_excl(cmd, lv_mirr)) {
+ if (!_activate_lv(cmd, lv_mirr, exclusive)) {
if (!test_mode())
log_error("ABORTING: Temporary mirror "
"activation failed. "
@@ -326,7 +353,8 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
struct list *lvs_changed;
struct physical_volume *pv;
struct logical_volume *lv_mirr;
- int first_time = 1;
+ unsigned first_time = 1;
+ unsigned exclusive;
pv_name_arg = argv[0];
argc--;
@@ -359,6 +387,8 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
return ECMD_FAILED;
}
+ exclusive = _pvmove_is_exclusive(cmd, vg);
+
if ((lv_mirr = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) {
log_print("Detected pvmove in progress for %s", pv_name);
if (argc || lv_name)
@@ -372,7 +402,7 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
}
/* Ensure mirror LV is active */
- if (!activate_lv_excl(cmd, lv_mirr)) {
+ if (!_activate_lv(cmd, lv_mirr, exclusive)) {
log_error
("ABORTING: Temporary mirror activation failed.");
unlock_vg(cmd, pv_vg_name(pv));
@@ -416,8 +446,8 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
}
}
- /* Lock lvs_changed for exclusive use and activate (with old metadata) */
- if (!activate_lvs_excl(cmd, lvs_changed)) {
+ /* Lock lvs_changed and activate (with old metadata) */
+ if (!activate_lvs(cmd, lvs_changed, exclusive)) {
stack;
unlock_vg(cmd, pv_vg_name(pv));
return ECMD_FAILED;
@@ -429,7 +459,7 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
if (first_time) {
if (!_update_metadata
- (cmd, vg, lv_mirr, lvs_changed, first_time)) {
+ (cmd, vg, lv_mirr, lvs_changed, PVMOVE_FIRST_TIME)) {
stack;
unlock_vg(cmd, pv_vg_name(pv));
return ECMD_FAILED;
@@ -565,8 +595,10 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv)
char *colon;
int ret;
- if (!pvmove_target_present(cmd, 0)) {
- stack;
+ /* dm raid1 target must be present in every case */
+ if (!_pvmove_target_present(cmd, 0)) {
+ log_error("Required device-mapper target(s) not "
+ "detected in your kernel");
return ECMD_FAILED;
}