mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Fix creation and conversion of mirrors with tags.
This commit is contained in:
parent
851002b87d
commit
5d06515c0b
@ -1,5 +1,6 @@
|
||||
Version 2.02.25 -
|
||||
=================================
|
||||
Fix creation and conversion of mirrors with tags.
|
||||
Fix vgsplit for lvm1 format (set and validate VG name in PVs metadata).
|
||||
Split metadata areas in vgsplit properly.
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "activate.h"
|
||||
#include "lv_alloc.h"
|
||||
#include "lvm-string.h"
|
||||
#include "str_list.h"
|
||||
#include "locking.h" /* FIXME Should not be used in this file */
|
||||
|
||||
#include "defaults.h" /* FIXME: should this be defaults.h? */
|
||||
@ -77,6 +78,42 @@ static void _move_lv_segments(struct logical_volume *lv_to, struct logical_volum
|
||||
lv_from->size = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Delete independent/orphan LV, it must acquire lock.
|
||||
*/
|
||||
static int _delete_lv(struct lv_segment *mirrored_seg, struct logical_volume *lv)
|
||||
{
|
||||
struct cmd_context *cmd = mirrored_seg->lv->vg->cmd;
|
||||
struct str_list *sl;
|
||||
|
||||
/* Inherit tags - maybe needed for activation */
|
||||
if (!str_list_match_list(&mirrored_seg->lv->tags, &lv->tags)) {
|
||||
list_iterate_items(sl, &mirrored_seg->lv->tags)
|
||||
if (!str_list_add(cmd->mem, &lv->tags, sl->str)) {
|
||||
log_error("Aborting. Unable to tag.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!vg_write(mirrored_seg->lv->vg) ||
|
||||
!vg_commit(mirrored_seg->lv->vg)) {
|
||||
log_error("Intermediate VG commit for orphan volume failed.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!activate_lv(cmd, lv))
|
||||
return_0;
|
||||
|
||||
if (!deactivate_lv(cmd, lv))
|
||||
return_0;
|
||||
|
||||
if (!lv_remove(lv))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reduce mirrored_seg to num_mirrors images.
|
||||
*/
|
||||
@ -205,57 +242,15 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
}
|
||||
|
||||
/* Delete the 'orphan' LVs */
|
||||
for (m = num_mirrors; m < old_area_count; m++) {
|
||||
/* LV is now independent of the mirror so must acquire lock. */
|
||||
if (!activate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
|
||||
stack;
|
||||
for (m = num_mirrors; m < old_area_count; m++)
|
||||
if (!_delete_lv(mirrored_seg, seg_lv(mirrored_seg, m)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (lv1 && !_delete_lv(mirrored_seg, lv1))
|
||||
return 0;
|
||||
|
||||
if (!lv_remove(seg_lv(mirrored_seg, m))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (lv1) {
|
||||
if (!activate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lv_remove(lv1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (log_lv) {
|
||||
if (!activate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lv_remove(log_lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (log_lv && !_delete_lv(mirrored_seg, log_lv))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
||||
if (!(log_lv = create_mirror_log(cmd, lv->vg, ah,
|
||||
lp->alloc, lv->name,
|
||||
(sync_percent >= 100.0) ?
|
||||
1 : 0))) {
|
||||
1 : 0, &lv->tags))) {
|
||||
log_error("Failed to create mirror log.");
|
||||
return 0;
|
||||
}
|
||||
@ -385,7 +385,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
||||
if (!arg_count(cmd, corelog_ARG) &&
|
||||
!(log_lv = create_mirror_log(cmd, lv->vg, ah,
|
||||
lp->alloc,
|
||||
lv->name, 0))) {
|
||||
lv->name, 0, &lv->tags))) {
|
||||
log_error("Failed to create mirror log.");
|
||||
return 0;
|
||||
}
|
||||
|
@ -476,8 +476,8 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
|
||||
uint64_t tmp_size;
|
||||
struct volume_group *vg;
|
||||
struct logical_volume *lv, *org = NULL, *log_lv = NULL;
|
||||
struct list *pvh;
|
||||
const char *tag;
|
||||
struct list *pvh, tags;
|
||||
const char *tag = NULL;
|
||||
int consistent = 1;
|
||||
struct alloc_handle *ah = NULL;
|
||||
char lv_name_buf[128];
|
||||
@ -675,6 +675,19 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
|
||||
lv_name = &lv_name_buf[0];
|
||||
}
|
||||
|
||||
if (arg_count(cmd, addtag_ARG)) {
|
||||
if (!(tag = arg_str_value(cmd, addtag_ARG, NULL))) {
|
||||
log_error("Failed to get tag");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(vg->fid->fmt->features & FMT_TAGS)) {
|
||||
log_error("Volume group %s does not support tags",
|
||||
vg->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (lp->mirrors > 1) {
|
||||
/* FIXME Calculate how many extents needed for the log */
|
||||
|
||||
@ -698,9 +711,13 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
|
||||
status |= MIRROR_NOTSYNCED;
|
||||
}
|
||||
|
||||
list_init(&tags);
|
||||
if (tag)
|
||||
str_list_add(cmd->mem, &tags, tag);
|
||||
|
||||
if (!lp->corelog &&
|
||||
!(log_lv = create_mirror_log(cmd, vg, ah, lp->alloc,
|
||||
lv_name, lp->nosync))) {
|
||||
lv_name, lp->nosync, &tags))) {
|
||||
log_error("Failed to create mirror log.");
|
||||
return 0;
|
||||
}
|
||||
@ -725,23 +742,10 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
|
||||
lv->minor);
|
||||
}
|
||||
|
||||
if (arg_count(cmd, addtag_ARG)) {
|
||||
if (!(tag = arg_str_value(cmd, addtag_ARG, NULL))) {
|
||||
log_error("Failed to get tag");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(lv->vg->fid->fmt->features & FMT_TAGS)) {
|
||||
log_error("Volume group %s does not support tags",
|
||||
lv->vg->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!str_list_add(cmd->mem, &lv->tags, tag)) {
|
||||
log_error("Failed to add tag %s to %s/%s",
|
||||
tag, lv->vg->name, lv->name);
|
||||
goto error;
|
||||
}
|
||||
if (tag && !str_list_add(cmd->mem, &lv->tags, tag)) {
|
||||
log_error("Failed to add tag %s to %s/%s",
|
||||
tag, lv->vg->name, lv->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (lp->mirrors > 1) {
|
||||
|
@ -1310,11 +1310,13 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
|
||||
struct alloc_handle *ah,
|
||||
alloc_policy_t alloc,
|
||||
const char *lv_name,
|
||||
int in_sync)
|
||||
int in_sync,
|
||||
struct list *tags)
|
||||
{
|
||||
struct logical_volume *log_lv;
|
||||
char *log_name;
|
||||
size_t len;
|
||||
struct str_list *sl;
|
||||
|
||||
len = strlen(lv_name) + 32;
|
||||
if (!(log_name = alloca(len)) ||
|
||||
@ -1336,6 +1338,13 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Temporary tag mirror log */
|
||||
list_iterate_items(sl, tags)
|
||||
if (!str_list_add(cmd->mem, &log_lv->tags, sl->str)) {
|
||||
log_error("Aborting. Unable to tag mirror log.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* store mirror log on disk(s) */
|
||||
if (!vg_write(vg)) {
|
||||
stack;
|
||||
@ -1361,6 +1370,11 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
|
||||
goto error;
|
||||
}
|
||||
|
||||
list_iterate_items(sl, tags)
|
||||
if (!str_list_del(&log_lv->tags, sl->str))
|
||||
log_error("Failed to remove tag %s from mirror log.",
|
||||
sl->str);
|
||||
|
||||
if (activation() && !set_lv(cmd, log_lv, log_lv->size,
|
||||
in_sync ? -1 : 0)) {
|
||||
log_error("Aborting. Failed to wipe mirror log. "
|
||||
|
@ -100,7 +100,8 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
|
||||
struct alloc_handle *ah,
|
||||
alloc_policy_t alloc,
|
||||
const char *lv_name,
|
||||
int in_sync);
|
||||
int in_sync,
|
||||
struct list *tags);
|
||||
|
||||
int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
uint64_t sectors, int value);
|
||||
|
Loading…
Reference in New Issue
Block a user