mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +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:
parent
60f13f01d2
commit
8211a13ce0
@ -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).
|
||||
|
@ -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())
|
||||
|
@ -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},
|
||||
|
@ -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'.",
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user