summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2016-03-01 15:31:48 +0100
committerPeter Rajnoha <prajnoha@redhat.com>2016-03-03 13:09:01 +0100
commitf354f4c77097eb001f9163000704a5aab9257271 (patch)
tree6f07439ce334ca0baab0ace7090dc5cd45b0df7d
parentec957225a11cc071581b3d6c999fb17cb1cf21b9 (diff)
downloadlvm2-f354f4c77097eb001f9163000704a5aab9257271.tar.gz
metadata: also look at historical LVs when checking LV name availability
Live LVs and historical LVs are in one namespace and the name needs to be unique in whole VG.
-rw-r--r--lib/metadata/lv_manip.c39
-rw-r--r--lib/metadata/metadata-exported.h2
-rw-r--r--lib/metadata/metadata.c19
-rw-r--r--lib/metadata/mirror.c8
-rw-r--r--lib/metadata/pool_manip.c2
-rw-r--r--lib/metadata/raid_manip.c14
-rw-r--r--liblvm/lvm_vg.c6
7 files changed, 67 insertions, 23 deletions
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 85f61a1c7..136d232ff 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4028,10 +4028,12 @@ out:
static int _rename_single_lv(struct logical_volume *lv, char *new_name)
{
struct volume_group *vg = lv->vg;
+ int historical;
- if (find_lv_in_vg(vg, new_name)) {
- log_error("Logical volume \"%s\" already exists in "
- "volume group \"%s\"", new_name, vg->name);
+ if (lv_name_is_used_in_vg(vg, new_name, &historical)) {
+ log_error("%sLogical Volume \"%s\" already exists in "
+ "volume group \"%s\"", historical ? "historical " : "",
+ new_name, vg->name);
return 0;
}
@@ -4194,6 +4196,7 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
{
struct volume_group *vg = lv->vg;
struct lv_names lv_names = { .old = lv->name };
+ int historical;
/*
* rename is not allowed on sub LVs except for pools
@@ -4205,9 +4208,10 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
- if (find_lv_in_vg(vg, new_name)) {
- log_error("Logical volume \"%s\" already exists in "
- "volume group \"%s\"", new_name, vg->name);
+ if (lv_name_is_used_in_vg(vg, new_name, &historical)) {
+ log_error("%sLogical Volume \"%s\" already exists in "
+ "volume group \"%s\"", historical ? "historical " : "",
+ new_name, vg->name);
return 0;
}
@@ -5365,6 +5369,7 @@ char *generate_lv_name(struct volume_group *vg, const char *format,
char *buffer, size_t len)
{
struct lv_list *lvl;
+ struct glv_list *glvl;
int high = -1, i;
dm_list_iterate_items(lvl, &vg->lvs) {
@@ -5375,6 +5380,14 @@ char *generate_lv_name(struct volume_group *vg, const char *format,
high = i;
}
+ dm_list_iterate_items(glvl, &vg->historical_lvs) {
+ if (sscanf(glvl->glv->historical->name, format, &i) != 1)
+ continue;
+
+ if (i > high)
+ high = i;
+ }
+
if (dm_snprintf(buffer, len, format, high + 1) < 0)
return NULL;
@@ -5506,6 +5519,7 @@ struct logical_volume *lv_create_empty(const char *name,
struct format_instance *fi = vg->fid;
struct logical_volume *lv;
char dname[NAME_LEN];
+ int historical;
if (vg_max_lv_reached(vg))
stack;
@@ -5515,9 +5529,10 @@ struct logical_volume *lv_create_empty(const char *name,
log_error("Failed to generate unique name for the new "
"logical volume");
return NULL;
- } else if (find_lv_in_vg(vg, name)) {
+ } else if (lv_name_is_used_in_vg(vg, name, &historical)) {
log_error("Unable to create LV %s in Volume Group %s: "
- "name already in use.", name, vg->name);
+ "name already in use%s.", name, vg->name,
+ historical ? " by historical LV" : "");
return NULL;
}
@@ -7010,10 +7025,12 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
struct logical_volume *tmp_lv;
struct lv_segment *seg, *pool_seg;
int thin_pool_was_active = -1; /* not scanned, inactive, active */
+ int historical;
- if (new_lv_name && find_lv_in_vg(vg, new_lv_name)) {
- log_error("Logical volume \"%s\" already exists in "
- "volume group \"%s\"", new_lv_name, vg->name);
+ if (new_lv_name && lv_name_is_used_in_vg(vg, new_lv_name, &historical)) {
+ log_error("%sLogical Volume \"%s\" already exists in "
+ "volume group \"%s\"", historical ? "historical " : "",
+ new_lv_name, vg->name);
return NULL;
}
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index dc95995bf..ecca418cc 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1035,6 +1035,8 @@ struct generic_logical_volume *find_historical_glv(const struct volume_group *vg
int check_removed_list,
struct glv_list **glvl_found);
+int lv_name_is_used_in_vg(const struct volume_group *vg, const char *name, int *historical);
+
struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
const char *pv_name,
int allow_orphan, int allow_unformatted);
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index a5cb15ad7..5ab6f8e4b 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2149,6 +2149,25 @@ struct generic_logical_volume *find_historical_glv(const struct volume_group *vg
return NULL;
}
+int lv_name_is_used_in_vg(const struct volume_group *vg, const char *name, int *historical)
+{
+ struct generic_logical_volume *historical_lv;
+ struct logical_volume *lv;
+ int found = 0;
+
+ if ((lv = find_lv(vg, name))) {
+ found = 1;
+ if (historical)
+ *historical = 0;
+ } else if ((historical_lv = find_historical_glv(vg, name, 0, NULL))) {
+ found = 1;
+ if (historical)
+ *historical = 1;
+ }
+
+ return found;
+}
+
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev)
{
struct pv_list *pvl;
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 2a72209f8..da7be6c30 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -2213,10 +2213,12 @@ int lv_split_mirror_images(struct logical_volume *lv, const char *split_name,
uint32_t split_count, struct dm_list *removable_pvs)
{
int r;
+ int historical;
- if (find_lv_in_vg(lv->vg, split_name)) {
- log_error("Logical Volume \"%s\" already exists in "
- "volume group \"%s\"", split_name, lv->vg->name);
+ if (lv_name_is_used_in_vg(lv->vg, split_name, &historical)) {
+ log_error("%sLogical Volume \"%s\" already exists in "
+ "volume group \"%s\"", historical ? "historical " : "",
+ split_name, lv->vg->name);
return 0;
}
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index d2856ae02..87ca99255 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -867,7 +867,7 @@ int vg_remove_pool_metadata_spare(struct volume_group *vg)
*c = 0;
/* If the name is in use, generate new lvol%d */
- if (find_lv_in_vg(vg, new_name) &&
+ if (lv_name_is_used_in_vg(vg, new_name, NULL) &&
!generate_lv_name(vg, "lvol%d", new_name, sizeof(new_name))) {
log_error("Failed to generate unique name for "
"pool metadata spare logical volume.");
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index e66b53323..3b9f81c2e 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -339,6 +339,7 @@ static char *_generate_raid_name(struct logical_volume *lv,
const char *format = (count >= 0) ? "%s_%s_%u" : "%s_%s";
size_t len = strlen(lv->name) + strlen(suffix) + ((count >= 0) ? 5 : 2);
char *name;
+ int historical;
if (!(name = dm_pool_alloc(lv->vg->vgmem, len))) {
log_error("Failed to allocate new name.");
@@ -353,9 +354,9 @@ static char *_generate_raid_name(struct logical_volume *lv,
return NULL;
}
- if (find_lv_in_vg(lv->vg, name)) {
- log_error("Logical volume %s already exists in volume group %s.",
- name, lv->vg->name);
+ if (lv_name_is_used_in_vg(lv->vg, name, &historical)) {
+ log_error("%sLogical Volume %s already exists in volume group %s.",
+ historical ? "historical " : "", name, lv->vg->name);
return NULL;
}
@@ -1093,6 +1094,7 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
uint32_t old_count = lv_raid_image_count(lv);
struct logical_volume *tracking;
struct dm_list tracking_pvs;
+ int historical;
dm_list_init(&removal_list);
dm_list_init(&data_list);
@@ -1116,9 +1118,9 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
return 0;
}
- if (find_lv_in_vg(lv->vg, split_name)) {
- log_error("Logical Volume \"%s\" already exists in %s",
- split_name, lv->vg->name);
+ if (lv_name_is_used_in_vg(lv->vg, split_name, &historical)) {
+ log_error("%sLogical Volume \"%s\" already exists in %s",
+ historical ? "historical " : "", split_name, lv->vg->name);
return 0;
}
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index 7e48df033..8b3fc91c0 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -523,6 +523,7 @@ int lvm_lv_name_validate(const vg_t vg, const char *name)
{
int rc = -1;
name_error_t name_error;
+ int historical;
struct saved_env e = store_user_env(vg->cmd);
@@ -530,10 +531,11 @@ int lvm_lv_name_validate(const vg_t vg, const char *name)
if (NAME_VALID == name_error) {
if (apply_lvname_restrictions(name)) {
- if (!find_lv_in_vg(vg, name)) {
+ if (!lv_name_is_used_in_vg(vg, name, &historical)) {
rc = 0;
} else {
- log_errno(EINVAL, "LV name exists in VG");
+ log_errno(EINVAL, "%sLV name exists in VG",
+ historical ? "historical " : "");
}
}
} else {