mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Use clustered mirror log with pvmove in clustered VGs, if available.
This commit is contained in:
parent
178e1df257
commit
eb273c7c65
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.34 -
|
Version 2.02.34 -
|
||||||
===================================
|
===================================
|
||||||
|
Use clustered mirror log with pvmove in clustered VGs, if available.
|
||||||
Fix some pvmove error status codes.
|
Fix some pvmove error status codes.
|
||||||
Fix vgsplit error paths to release vg_to lock.
|
Fix vgsplit error paths to release vg_to lock.
|
||||||
Indicate whether or not VG is clustered in vgcreate log message.
|
Indicate whether or not VG is clustered in vgcreate log message.
|
||||||
|
@ -412,19 +412,23 @@ int suspend_lvs(struct cmd_context *cmd, struct list *lvs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Lock a list of 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 list *lvh;
|
||||||
struct lv_list *lvl;
|
struct lv_list *lvl;
|
||||||
|
|
||||||
list_iterate_items(lvl, lvs) {
|
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);
|
log_error("Failed to activate %s", lvl->lv->name);
|
||||||
list_uniterate(lvh, lvs, &lvl->list) {
|
list_uniterate(lvh, lvs, &lvl->list) {
|
||||||
lvl = list_item(lvh, struct lv_list);
|
lvl = list_item(lvh, struct lv_list);
|
||||||
activate_lv(cmd, lvl->lv);
|
activate_lv(cmd, lvl->lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
|||||||
/* Process list of LVs */
|
/* Process list of LVs */
|
||||||
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
|
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
|
||||||
int resume_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 */
|
/* Interrupt handling */
|
||||||
void sigint_clear(void);
|
void sigint_clear(void);
|
||||||
|
@ -258,7 +258,7 @@ static int _update_lvconvert_mirror(struct cmd_context *cmd __attribute((unused)
|
|||||||
struct volume_group *vg __attribute((unused)),
|
struct volume_group *vg __attribute((unused)),
|
||||||
struct logical_volume *lv __attribute((unused)),
|
struct logical_volume *lv __attribute((unused)),
|
||||||
struct list *lvs_changed __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 */
|
/* lvconvert mirror doesn't require periodical metadata update */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -29,7 +29,7 @@ struct poll_functions {
|
|||||||
int (*update_metadata) (struct cmd_context *cmd,
|
int (*update_metadata) (struct cmd_context *cmd,
|
||||||
struct volume_group *vg,
|
struct volume_group *vg,
|
||||||
struct logical_volume *lv_mirr,
|
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,
|
int (*finish_copy) (struct cmd_context *cmd,
|
||||||
struct volume_group *vg,
|
struct volume_group *vg,
|
||||||
struct logical_volume *lv_mirr,
|
struct logical_volume *lv_mirr,
|
||||||
|
@ -17,28 +17,43 @@
|
|||||||
#include "polldaemon.h"
|
#include "polldaemon.h"
|
||||||
#include "display.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;
|
const struct segment_type *segtype;
|
||||||
unsigned attr = 0;
|
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")))
|
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (activation() && segtype->ops->target_present &&
|
if (activation() && segtype->ops->target_present &&
|
||||||
!segtype->ops->target_present(NULL, clustered ? &attr : NULL)) {
|
!segtype->ops->target_present(NULL, clustered ? &attr : NULL))
|
||||||
log_error("%s: Required device-mapper target(s) not "
|
found = 0;
|
||||||
"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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clustered && !(attr & MIRROR_LOG_CLUSTERED)) {
|
return found;
|
||||||
log_error("%s: Required device-mapper clustered log "
|
}
|
||||||
"module not detected in your kernel", segtype->name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allow /dev/vgname/lvname, vgname/lvname or lvname */
|
/* 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;
|
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,
|
static int _update_metadata(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
struct logical_volume *lv_mirr,
|
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");
|
log_verbose("Updating volume group metadata");
|
||||||
if (!vg_write(vg)) {
|
if (!vg_write(vg)) {
|
||||||
log_error("ABORTING: Volume group metadata update failed.");
|
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 */
|
/* Only the first mirror segment gets activated as a mirror */
|
||||||
/* FIXME: Add option to use a log */
|
/* FIXME: Add option to use a log */
|
||||||
if (first_time) {
|
if (first_time) {
|
||||||
if (!activate_lv_excl(cmd, lv_mirr)) {
|
if (!_activate_lv(cmd, lv_mirr, exclusive)) {
|
||||||
if (!test_mode())
|
if (!test_mode())
|
||||||
log_error("ABORTING: Temporary mirror "
|
log_error("ABORTING: Temporary mirror "
|
||||||
"activation failed. "
|
"activation failed. "
|
||||||
@ -326,7 +353,8 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
|
|||||||
struct list *lvs_changed;
|
struct list *lvs_changed;
|
||||||
struct physical_volume *pv;
|
struct physical_volume *pv;
|
||||||
struct logical_volume *lv_mirr;
|
struct logical_volume *lv_mirr;
|
||||||
int first_time = 1;
|
unsigned first_time = 1;
|
||||||
|
unsigned exclusive;
|
||||||
|
|
||||||
pv_name_arg = argv[0];
|
pv_name_arg = argv[0];
|
||||||
argc--;
|
argc--;
|
||||||
@ -359,6 +387,8 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
|
|||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exclusive = _pvmove_is_exclusive(cmd, vg);
|
||||||
|
|
||||||
if ((lv_mirr = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) {
|
if ((lv_mirr = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) {
|
||||||
log_print("Detected pvmove in progress for %s", pv_name);
|
log_print("Detected pvmove in progress for %s", pv_name);
|
||||||
if (argc || lv_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 */
|
/* Ensure mirror LV is active */
|
||||||
if (!activate_lv_excl(cmd, lv_mirr)) {
|
if (!_activate_lv(cmd, lv_mirr, exclusive)) {
|
||||||
log_error
|
log_error
|
||||||
("ABORTING: Temporary mirror activation failed.");
|
("ABORTING: Temporary mirror activation failed.");
|
||||||
unlock_vg(cmd, pv_vg_name(pv));
|
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) */
|
/* Lock lvs_changed and activate (with old metadata) */
|
||||||
if (!activate_lvs_excl(cmd, lvs_changed)) {
|
if (!activate_lvs(cmd, lvs_changed, exclusive)) {
|
||||||
stack;
|
stack;
|
||||||
unlock_vg(cmd, pv_vg_name(pv));
|
unlock_vg(cmd, pv_vg_name(pv));
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
@ -429,7 +459,7 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
|
|||||||
|
|
||||||
if (first_time) {
|
if (first_time) {
|
||||||
if (!_update_metadata
|
if (!_update_metadata
|
||||||
(cmd, vg, lv_mirr, lvs_changed, first_time)) {
|
(cmd, vg, lv_mirr, lvs_changed, PVMOVE_FIRST_TIME)) {
|
||||||
stack;
|
stack;
|
||||||
unlock_vg(cmd, pv_vg_name(pv));
|
unlock_vg(cmd, pv_vg_name(pv));
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
@ -565,8 +595,10 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
char *colon;
|
char *colon;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!pvmove_target_present(cmd, 0)) {
|
/* dm raid1 target must be present in every case */
|
||||||
stack;
|
if (!_pvmove_target_present(cmd, 0)) {
|
||||||
|
log_error("Required device-mapper target(s) not "
|
||||||
|
"detected in your kernel");
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user