1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-27 01:55:10 +03:00

Always insert an intermediate layer for mirrors.

Suppress hidden LVs from reports unless --all is given.
Use square brackets for hidden LVs in reports.
Centralise restrictions on LV names.
This commit is contained in:
Alasdair Kergon 2005-06-03 14:49:51 +00:00
parent 60f13f01d2
commit 8211a13ce0
24 changed files with 325 additions and 44 deletions

View File

@ -1,5 +1,9 @@
Version 2.01.11 -
==============================
Centralise restrictions on LV names.
Always insert an intermediate layer for mirrors.
Suppress hidden LVs from reports unless --all is given.
Use square brackets for hidden LVs in reports.
Allow the creation of mirrors with contiguous extents.
Always perform sanity checks against metadata before committing it to disk.
Split lv_extend into two steps: choosing extents + allocation to LV(s).

View File

@ -534,7 +534,6 @@ int lvs_in_vg_activated(struct volume_group *vg)
int lvs_in_vg_opened(struct volume_group *vg)
{
struct lv_list *lvl;
struct logical_volume *lv;
int count = 0;
if (!activation())

View File

@ -52,6 +52,7 @@ static struct flag _lv_flags[] = {
{VISIBLE_LV, "VISIBLE"},
{PVMOVE, "PVMOVE"},
{LOCKED, "LOCKED"},
{MIRROR_IMAGE, NULL},
{MIRROR_LOG, NULL},
{MIRRORED, NULL},
{VIRTUAL, NULL},

View File

@ -323,7 +323,8 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
}
int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
const struct config_node *cn, struct hash_table *pv_hash)
const struct config_node *cn, struct hash_table *pv_hash,
uint32_t flags)
{
unsigned int s;
struct config_value *cv;
@ -368,7 +369,8 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
*/
seg->lv->vg->free_count -= seg->area_len;
} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
set_lv_segment_area_lv(seg, s, lv1, cv->next->v.i);
set_lv_segment_area_lv(seg, s, lv1, cv->next->v.i,
flags);
} else {
log_error("Couldn't find volume '%s' "
"for segment '%s'.",

View File

@ -20,6 +20,7 @@ struct lv_segment;
struct config_node;
int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
const struct config_node *cn, struct hash_table *pv_hash);
const struct config_node *cn, struct hash_table *pv_hash,
uint32_t flags);
#endif

View File

@ -35,7 +35,8 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
struct physical_volume *pv, uint32_t pe);
void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
struct logical_volume *lv, uint32_t le);
struct logical_volume *lv, uint32_t le,
uint32_t flags);
struct alloc_handle;
struct alloc_handle *allocate_extents(struct volume_group *vg,
@ -64,6 +65,14 @@ int lv_add_segment(struct alloc_handle *ah,
int lv_add_log_segment(struct alloc_handle *ah, struct logical_volume *log_lv);
int lv_add_virtual_segment(struct logical_volume *lv, uint32_t status,
uint32_t extents, struct segment_type *segtype);
int lv_add_mirror_segment(struct alloc_handle *ah,
struct logical_volume *lv,
struct logical_volume **sub_lvs,
uint32_t mirrors,
struct segment_type *segtype,
uint32_t status,
uint32_t region_size,
struct logical_volume *log_lv);
void alloc_destroy(struct alloc_handle *ah);

View File

@ -74,6 +74,11 @@ struct lv_segment *alloc_lv_segment(struct pool *mem,
return NULL;
}
if (!segtype) {
log_error("alloc_lv_segment: Missing segtype.");
return NULL;
}
seg->segtype = segtype;
seg->lv = lv;
seg->le = le;
@ -142,11 +147,13 @@ int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
* Link one LV segment to another. Assumes sizes already match.
*/
void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
struct logical_volume *lv, uint32_t le)
struct logical_volume *lv, uint32_t le,
uint32_t flags)
{
seg->area[area_num].type = AREA_LV;
seg_lv(seg, area_num) = lv;
seg_le(seg, area_num) = le;
lv->status |= flags;
}
/*
@ -170,12 +177,12 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
seg->len -= reduction;
seg->area_len -= area_reduction;
seg->lv->vg->free_count += area_reduction * seg->area_count;
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_PV)
continue;
release_pv_segment(seg_pvseg(seg, s), area_reduction);
seg->lv->vg->free_count += area_reduction;
}
return 1;
@ -271,6 +278,7 @@ struct alloc_handle {
uint32_t area_count; /* Number of parallel areas */
uint32_t area_multiple; /* seg->len = area_len * area_multiple */
uint32_t log_count; /* Number of parallel 1-extent logs */
uint32_t total_area_len; /* Total number of parallel extents */
struct alloced_area log_area; /* Extent used for log */
struct list alloced_areas[0]; /* Lists of areas in each stripe */
@ -465,6 +473,8 @@ static int _alloc_parallel_area(struct alloc_handle *ah, uint32_t needed,
list_add(&ah->alloced_areas[s], &aa[s].list);
}
ah->total_area_len += area_len;
for (s = 0; s < ah->area_count; s++)
consume_pv_area(areas[s], area_len);
@ -831,6 +841,11 @@ int lv_add_segment(struct alloc_handle *ah,
uint32_t region_size,
struct logical_volume *log_lv)
{
if (!segtype) {
log_error("Missing segtype in lv_add_segment().");
return 0;
}
if (segtype_is_virtual(segtype)) {
log_error("lv_add_segment cannot handle virtual segments");
return 0;
@ -901,6 +916,53 @@ int lv_add_log_segment(struct alloc_handle *ah, struct logical_volume *log_lv)
return 1;
}
/*
* Add a mirror segment
*/
int lv_add_mirror_segment(struct alloc_handle *ah,
struct logical_volume *lv,
struct logical_volume **sub_lvs,
uint32_t mirrors,
struct segment_type *segtype,
uint32_t status,
uint32_t region_size,
struct logical_volume *log_lv)
{
struct lv_segment *seg;
uint32_t m;
if (list_empty(&log_lv->segments)) {
log_error("Log LV %s is empty.", log_lv->name);
return 0;
}
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem,
get_segtype_from_string(lv->vg->cmd,
"mirror"),
lv, lv->le_count, ah->total_area_len, 0,
0, log_lv, mirrors, ah->total_area_len, 0,
region_size, 0))) {
log_error("Couldn't allocate new mirror segment.");
return 0;
}
for (m = 0; m < mirrors; m++)
set_lv_segment_area_lv(seg, m, sub_lvs[m], 0, MIRROR_IMAGE);
list_add(&lv->segments, &seg->list);
lv->le_count += ah->total_area_len;
lv->size += (uint64_t) lv->le_count *lv->vg->extent_size;
if (lv->vg->fid->fmt->ops->lv_setup &&
!lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) {
stack;
return 0;
}
return 1;
}
/*
* Entry point for single-step LV allocation + extension.
*/
@ -936,8 +998,8 @@ int lv_extend(struct logical_volume *lv,
return r;
}
static char *_generate_lv_name(struct volume_group *vg, const char *format,
char *buffer, size_t len)
char *generate_lv_name(struct volume_group *vg, const char *format,
char *buffer, size_t len)
{
struct lv_list *lvl;
int high = -1, i;
@ -961,7 +1023,6 @@ static char *_generate_lv_name(struct volume_group *vg, const char *format,
*/
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
const char *name_format,
union lvid *lvid,
uint32_t status,
alloc_policy_t alloc,
@ -979,8 +1040,8 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
return NULL;
}
if (!name && !(name = _generate_lv_name(vg, name_format, dname,
sizeof(dname)))) {
if (strstr(name, "%d") &&
!(name = generate_lv_name(vg, name, dname, sizeof(dname)))) {
log_error("Failed to generate unique name for the new "
"logical volume");
return NULL;

View File

@ -56,6 +56,7 @@
#define MIRRORED 0x00008000 /* LV - internal use only */
#define VIRTUAL 0x00010000 /* LV - internal use only */
#define MIRROR_LOG 0x00020000 /* LV */
#define MIRROR_IMAGE 0x00040000 /* LV */
#define LVM_READ 0x00000100 /* LV VG */
#define LVM_WRITE 0x00000200 /* LV VG */
@ -436,7 +437,6 @@ int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
/* Manipulate LVs */
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
const char *name_format,
union lvid *lvid,
uint32_t status,
alloc_policy_t alloc,
@ -534,9 +534,19 @@ int vg_add_snapshot(struct format_instance *fid, const char *name,
int vg_remove_snapshot(struct logical_volume *cow);
/*
* Mirroring functions
*/
struct alloc_handle;
int create_mirror_layers(struct alloc_handle *ah,
uint32_t first_area,
uint32_t num_mirrors,
struct logical_volume *lv,
struct segment_type *segtype,
uint32_t status,
uint32_t region_size,
struct logical_volume *log_lv);
int insert_pvmove_mirrors(struct cmd_context *cmd,
struct logical_volume *lv_mirr,
struct list *source_pvl,
@ -559,6 +569,8 @@ struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv);
uint32_t find_free_lvnum(struct logical_volume *lv);
char *generate_lv_name(struct volume_group *vg, const char *format,
char *buffer, size_t len);
static inline int validate_name(const char *n)
{

View File

@ -20,6 +20,70 @@
#include "display.h"
#include "activate.h"
#include "lv_alloc.h"
#include "lvm-string.h"
int create_mirror_layers(struct alloc_handle *ah,
uint32_t first_area,
uint32_t num_mirrors,
struct logical_volume *lv,
struct segment_type *segtype,
uint32_t status,
uint32_t region_size,
struct logical_volume *log_lv)
{
uint32_t m;
struct logical_volume **img_lvs;
char *img_name;
size_t len;
if (!(img_lvs = alloca(sizeof(*img_lvs) * num_mirrors))) {
log_error("img_lvs allocation failed. "
"Remove new LV and retry.");
return 0;
}
len = strlen(lv->name) + 32;
if (!(img_name = alloca(len))) {
log_error("img_name allocation failed. "
"Remove new LV and retry.");
return 0;
}
if (lvm_snprintf(img_name, len, "%s_mimage_%%d", lv->name) < 0) {
log_error("img_name allocation failed. "
"Remove new LV and retry.");
return 0;
}
for (m = 0; m < num_mirrors; m++) {
if (!(img_lvs[m] = lv_create_empty(lv->vg->fid, img_name,
NULL, LVM_READ | LVM_WRITE,
ALLOC_INHERIT, 0, lv->vg))) {\
log_error("Aborting. Failed to create submirror LV. "
"Remove new LV and retry.");
return 0;
}
if (!lv_add_segment(ah, m, 1, img_lvs[m],
get_segtype_from_string(lv->vg->cmd,
"striped"),
0, NULL, 0, 0, 0, NULL)) {
log_error("Aborting. Failed to add submirror segment "
"to %s. Remove new LV and retry.",
img_lvs[m]->name);
return 0;
}
}
if (!lv_add_mirror_segment(ah, lv, img_lvs, num_mirrors, segtype,
0, region_size, log_lv)) {
log_error("Aborting. Failed to add mirror segment. "
"Remove new LV and retry.");
return 0;
}
return 1;
}
/*
* Replace any LV segments on given PV with temporary mirror.
@ -153,7 +217,7 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
"temporary LV for pvmove.");
return 0;
}
set_lv_segment_area_lv(seg, s, lv_mirr, start_le);
set_lv_segment_area_lv(seg, s, lv_mirr, start_le, 0);
extent_count += seg->area_len;

View File

@ -50,7 +50,7 @@ int vg_add_snapshot(struct format_instance *fid, const char *name,
return 0;
}
if (!(snap = lv_create_empty(fid, name, name ? NULL : "snapshot%d",
if (!(snap = lv_create_empty(fid, name ? name : "snapshot%d",
lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
ALLOC_INHERIT, 1, origin->vg))) {
stack;

View File

@ -129,7 +129,7 @@ static int _text_import(struct lv_segment *seg, const struct config_node *sn,
return 0;
}
return text_import_areas(seg, sn, cn, pv_hash);
return text_import_areas(seg, sn, cn, pv_hash, MIRROR_IMAGE);
}
static int _text_export(const struct lv_segment *seg, struct formatter *f)

View File

@ -19,7 +19,7 @@
/* *INDENT-OFF* */
FIELD(LVS, lv, STR, "LV UUID", lvid.id[1], 38, uuid, "lv_uuid")
FIELD(LVS, lv, STR, "LV", name, 4, string, "lv_name")
FIELD(LVS, lv, STR, "LV", lvid, 4, lvname, "lv_name")
FIELD(LVS, lv, STR, "Attr", lvid, 4, lvstatus, "lv_attr")
FIELD(LVS, lv, NUM, "Maj", major, 3, int32, "lv_major")
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, "lv_minor")

View File

@ -337,6 +337,8 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
repstr[0] = 'p';
else if (lv->status & MIRRORED)
repstr[0] = 'm';
else if (lv->status & MIRROR_IMAGE)
repstr[0] = 'i';
else if (lv->status & MIRROR_LOG)
repstr[0] = 'l';
else if (lv->status & VIRTUAL)
@ -510,6 +512,39 @@ static int _loglv_disp(struct report_handle *rh, struct field *field,
return 1;
}
static int _lvname_disp(struct report_handle *rh, struct field *field,
const void *data)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
char *repstr;
size_t len;
if (lv->status & VISIBLE_LV) {
repstr = lv->name;
return _string_disp(rh, field, &repstr);
}
len = strlen(lv->name) + 3;
if (!(repstr = pool_zalloc(rh->mem, len))) {
log_error("pool_alloc failed");
return 0;
}
if (lvm_snprintf(repstr, len, "[%s]", lv->name) < 0) {
log_error("lvname snprintf failed");
return 0;
}
field->report_string = repstr;
if (!(field->sort_value = pool_strdup(rh->mem, lv->name))) {
log_error("pool_strdup failed");
return 0;
}
return 1;
}
static int _movepv_disp(struct report_handle *rh, struct field *field,
const void *data)
{

View File

@ -82,7 +82,7 @@ static int _text_import(struct lv_segment *seg, const struct config_node *sn,
seg->area_len /= seg->area_count;
return text_import_areas(seg, sn, cn, pv_hash);
return text_import_areas(seg, sn, cn, pv_hash, 0);
}
static int _text_export(const struct lv_segment *seg, struct formatter *f)

View File

@ -131,6 +131,7 @@ xx(lvcreate,
xx(lvdisplay,
"Display information about a logical volume",
"lvdisplay\n"
"\t[-a|--all]\n"
"\t[-c|--colon]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
@ -145,6 +146,7 @@ xx(lvdisplay,
"\n"
"lvdisplay --columns|-C\n"
"\t[--aligned]\n"
"\t[-a|--all]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@ -161,9 +163,10 @@ xx(lvdisplay,
"\t[--version]" "\n"
"\t[LogicalVolume[Path] [LogicalVolume[Path]...]]\n",
aligned_ARG, colon_ARG, columns_ARG, disk_ARG, ignorelockingfailure_ARG,
maps_ARG, noheadings_ARG, nosuffix_ARG, options_ARG, sort_ARG,
partial_ARG, segments_ARG, separator_ARG, unbuffered_ARG, units_ARG)
aligned_ARG, all_ARG, colon_ARG, columns_ARG, disk_ARG,
ignorelockingfailure_ARG, maps_ARG, noheadings_ARG, nosuffix_ARG,
options_ARG, sort_ARG, partial_ARG, segments_ARG, separator_ARG,
unbuffered_ARG, units_ARG)
xx(lvextend,
"Add space to a logical volume",
@ -300,6 +303,7 @@ xx(lvresize,
xx(lvs,
"Display information about logical volumes",
"lvs" "\n"
"\t[-a|--all]\n"
"\t[--aligned]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
@ -317,9 +321,9 @@ xx(lvs,
"\t[--version]" "\n"
"\t[LogicalVolume[Path] [LogicalVolume[Path]...]]\n",
aligned_ARG, ignorelockingfailure_ARG, noheadings_ARG, nolocking_ARG,
nosuffix_ARG, options_ARG, partial_ARG, segments_ARG, separator_ARG,
sort_ARG, unbuffered_ARG, units_ARG)
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, segments_ARG,
separator_ARG, sort_ARG, unbuffered_ARG, units_ARG)
xx(lvscan,
"List all logical volumes in all volume groups",
@ -775,6 +779,7 @@ xx(vgs,
"Display information about volume groups",
"vgs" "\n"
"\t[--aligned]\n"
"\t[-a|--all]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@ -790,9 +795,9 @@ xx(vgs,
"\t[--version]\n"
"\t[VolumeGroupName [VolumeGroupName...]]\n",
aligned_ARG, ignorelockingfailure_ARG, noheadings_ARG, nolocking_ARG,
nosuffix_ARG, options_ARG, partial_ARG, separator_ARG, sort_ARG,
unbuffered_ARG, units_ARG)
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, separator_ARG,
sort_ARG, unbuffered_ARG, units_ARG)
xx(vgscan,
"Search for all volume groups",

View File

@ -405,12 +405,23 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_FAILED;
}
/* FIXME Test for VISIBLE instead? */
if (lv->status & MIRROR_LOG) {
log_error("Unable to change mirror log LV %s directly", lv->name);
return ECMD_FAILED;
}
if (lv->status & MIRROR_IMAGE) {
log_error("Unable to change mirror image LV %s directly",
lv->name);
return ECMD_FAILED;
}
if (!(lv->status & VISIBLE_LV)) {
log_error("Unable to change internal LV %s directly",
lv->name);
return ECMD_FAILED;
}
/* access permission change */
if (arg_count(cmd, permission_ARG)) {
if (!archive(lv->vg))

View File

@ -137,10 +137,8 @@ static int _read_name_params(struct lvcreate_params *lp,
if ((ptr = strrchr(lp->lv_name, '/')))
lp->lv_name = ptr + 1;
/* FIXME Remove this restriction eventually */
if (!strncmp(lp->lv_name, "snapshot", 8)) {
log_error("Names starting \"snapshot\" are reserved. "
"Please choose a different LV name.");
if (!apply_lvname_restrictions(lp->lv_name)) {
stack;
return 0;
}
@ -469,6 +467,9 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
const char *tag;
int consistent = 1;
struct alloc_handle *ah = NULL;
char *log_name, lv_name_buf[128];
const char *lv_name;
size_t len;
status |= lp->permission | VISIBLE_LV;
@ -597,6 +598,16 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
if (!archive(vg))
return 0;
if (lp->lv_name)
lv_name = lp->lv_name;
else {
if (!generate_lv_name(vg, "lvol%d", lv_name_buf, sizeof(lv_name_buf))) {
log_error("Failed to generate LV name.");
return 0;
}
lv_name = &lv_name_buf[0];
}
if (lp->mirrors > 1) {
/* FIXME Adjust lp->region_size if necessary */
region_max = (1 << (ffs(lp->extents) - 1)) * vg->extent_size;
@ -609,7 +620,29 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
/* FIXME Calculate how many extents needed for the log */
if (!(log_lv = lv_create_empty(vg->fid, NULL, "mirrorlog%d", NULL,
len = strlen(lv_name) + 32;
if (!(log_name = alloca(len))) {
log_error("log_name allocation failed. "
"Remove new LV and retry.");
return 0;
}
if (lvm_snprintf(log_name, len, "%s_mlog", lv_name) < 0) {
log_error("log_name allocation failed. "
"Remove new LV and retry.");
return 0;
}
if (find_lv_in_vg(vg, log_name)) {
if (lvm_snprintf(log_name, len, "%s_mlog_%%d",
lv_name) < 0) {
log_error("log_name allocation failed. "
"Remove new LV and retry.");
return 0;
}
}
if (!(log_lv = lv_create_empty(vg->fid, log_name, NULL,
VISIBLE_LV | LVM_READ | LVM_WRITE,
lp->alloc, 0, vg))) {
stack;
@ -662,7 +695,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
log_lv->status &= ~VISIBLE_LV;
}
if (!(lv = lv_create_empty(vg->fid, lp->lv_name, "lvol%d", NULL,
if (!(lv = lv_create_empty(vg->fid, lv_name ? lv_name : "lvol%d", NULL,
status, lp->alloc, 0, vg))) {
stack;
goto error;
@ -701,11 +734,10 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
}
if (lp->mirrors > 1) {
if (!lv_add_segment(ah, 0, lp->mirrors, lv, lp->segtype,
lp->stripe_size, NULL, 0, 0,
lp->region_size, log_lv)) {
log_error("Aborting. Failed to add mirror segment. "
"Remove new LV and retry.");
if (!create_mirror_layers(ah, 0, lp->mirrors, lv,
lp->segtype, 0,
lp->region_size, log_lv)) {
stack;
goto error;
}

View File

@ -18,6 +18,9 @@
static int _lvdisplay_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
return ECMD_PROCESSED;
if (arg_count(cmd, colon_ARG))
lvdisplay_colons(lv);
else {

View File

@ -34,6 +34,12 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_FAILED;
}
if (lv->status & MIRROR_IMAGE) {
log_error("Can't remove logical volume %s used by a mirror",
lv->name);
return ECMD_FAILED;
}
if (lv->status & MIRROR_LOG) {
log_error("Can't remove logical volume %s used as mirror log",
lv->name);

View File

@ -83,10 +83,8 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
/* FIXME Remove this restriction eventually */
if (!strncmp(lv_name_new, "snapshot", 8)) {
log_error("Names starting \"snapshot\" are reserved. "
"Please choose a different LV name.");
if (!apply_lvname_restrictions(lv_name_new)) {
stack;
return ECMD_FAILED;
}

View File

@ -140,7 +140,7 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
struct lv_list *lvl;
/* FIXME Cope with non-contiguous => splitting existing segments */
if (!(lv_mirr = lv_create_empty(vg->fid, NULL, "pvmove%d", NULL,
if (!(lv_mirr = lv_create_empty(vg->fid, "pvmove%d", NULL,
LVM_READ | LVM_WRITE,
ALLOC_CONTIGUOUS, 0, vg))) {
log_error("Creation of temporary pvmove LV failed");

View File

@ -35,6 +35,9 @@ static int _vgs_single(struct cmd_context *cmd, const char *vg_name,
static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
return ECMD_PROCESSED;
if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL))
return ECMD_FAILED;
@ -78,6 +81,9 @@ static int _pvsegs_sub_single(struct cmd_context *cmd, struct volume_group *vg,
static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
return ECMD_PROCESSED;
return process_each_segment_in_lv(cmd, lv, handle, _segs_single);
}

View File

@ -1012,3 +1012,33 @@ int exec_cmd(const char *command, const char *fscmd, const char *lv_path,
return 1;
}
int apply_lvname_restrictions(const char *name)
{
if (!strncmp(name, "snapshot", 8)) {
log_error("Names starting \"snapshot\" are reserved. "
"Please choose a different LV name.");
return 0;
}
if (!strncmp(name, "pvmove", 6)) {
log_error("Names starting \"pvmove\" are reserved. "
"Please choose a different LV name.");
return 0;
}
if (strstr(name, "_mlog")) {
log_error("Names including \"_mlog\" are reserved. "
"Please choose a different LV name.");
return 0;
}
if (strstr(name, "_mimage")) {
log_error("Names including \"_mimage\" are reserved. "
"Please choose a different LV name.");
return 0;
}
return 1;
}

View File

@ -90,4 +90,6 @@ struct list *clone_pv_list(struct pool *mem, struct list *pvs);
int exec_cmd(const char *command, const char *fscmd, const char *lv_path,
const char *size);
int apply_lvname_restrictions(const char *name);
#endif