1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-27 05:44:18 +03:00

Compare commits

..

32 Commits

Author SHA1 Message Date
David Teigland
5ffedbcec1 generate man pages 2017-02-10 11:08:32 -06:00
David Teigland
417c3dece8 args: use arg parsing function for region size
Consolidate the validation of the region size arg
in a new arg parsing function.
2017-02-10 11:07:41 -06:00
David Teigland
311d3c7e8f lvconvert: remove code for changing region size
from the generic raid type conversion code.
2017-02-10 11:07:41 -06:00
David Teigland
c025c8b46f lvconvert: add command to change region size of a raid LV 2017-02-10 11:07:41 -06:00
David Teigland
2baabc823f vgchange: fix uint32 parsing of logicalvolume arg 2017-02-10 11:07:41 -06:00
David Teigland
d48dd64e35 commands: recognize raid variations 2017-02-10 11:07:41 -06:00
David Teigland
eee727883b lvconvert: remove unused code
For "split" which is not an alias for splitmirrors.
2017-02-10 11:07:20 -06:00
David Teigland
fa3a14df14 args: split is a synonym for splitcache
also tidy the other synonyms
2017-02-10 11:06:43 -06:00
David Teigland
43480f222f man: lvmthin updates
Some minor changes to some of the command syntaxes
to use more standard forms.
2017-02-10 11:06:43 -06:00
David Teigland
d7651132a7 ccmd: split into multiple files 2017-02-10 11:06:43 -06:00
David Teigland
61e4fbca11 command struct: remove command name refs
Change run time access to the command_name struct
cmd->cname instead of indirectly through
cmd->command->cname. This removes the two run time
fields from struct command.
2017-02-10 11:06:43 -06:00
David Teigland
13818a4630 command.h comment tidying 2017-02-10 11:06:43 -06:00
David Teigland
003437673d lvm shell: clear argv for each command 2017-02-10 11:06:43 -06:00
David Teigland
d4784802de help: accept positional args
lvm help <commandname> ...
2017-02-10 11:06:42 -06:00
David Teigland
24b93c6e35 fix lvmcmdline warning
declaration of ‘usage’ shadows a globa
2017-02-10 11:06:42 -06:00
David Teigland
98f007034e man lvm: remove options
all options are now included in commands
2017-02-10 11:06:42 -06:00
David Teigland
d5ac07f818 args: add man page descriptions 2017-02-10 11:06:42 -06:00
David Teigland
bd8965194f args: use uint32 arg for maxphysicalvolumes 2017-02-10 11:06:42 -06:00
David Teigland
1eaad64ded lvconvert: remove unused code 2017-02-10 11:06:42 -06:00
David Teigland
f16abdce55 lvconvert: use command defs for raid/mirror types
All lvconvert functionality has been moved out of the
previous monolithic lvconvert code, except conversions
related to raid/mirror/striped/linear.  This switches
that remaining code to be based on command defs, and
standard process_each_lv arg processing.  This final
switch results in quite a bit of dead code that is
also removed.
2017-02-10 11:06:42 -06:00
David Teigland
44058693d5 tests: use swapmetadata
and some other pool/cache/thin related changes
2017-02-10 11:06:41 -06:00
David Teigland
715c959983 lvconvert: use command defs for mergemirrors
and route the generic --merge to one of the
specific merge functions
2017-02-10 11:06:41 -06:00
David Teigland
7a6a99a488 toollib: find VG name in option values when needed 2017-02-10 11:06:41 -06:00
David Teigland
7ef774e2c2 lvconvert: use command defs for thin/cache/pool creation
Everything related to thin and cache.
2017-02-10 11:06:41 -06:00
David Teigland
88db11bece lvconvert: add startpoll command using command def
This is a new explicit version of 'lvconvert LV'
which has been an obscure way of triggering polling
to be restarted on an LV that was previously converted.
2017-02-10 11:06:41 -06:00
David Teigland
1c5014eda9 lvconvert: snapshot: use command definitions
Lift all the snapshot utilities (merge, split, combine)
out of the monolithic lvconvert implementation, using
the command definitions.  The old code associated with
these commands is now unused and will be removed separately.
2017-02-10 11:06:41 -06:00
David Teigland
0c5cd2ae9f lvconvert: remove unused calls for repair and replace
repair and replace are no longer called from the
monolithic lvconvert code, so remove the unused code.
2017-02-10 11:06:40 -06:00
David Teigland
96227b575d lvconvert: repair and replace: use command definitions
This lifts the lvconvert --repair and --replace commands
out of the monolithic lvconvert implementation.  The
previous calls into repair/replace can no longer be
reached and will be removed in a separate commit.
2017-02-10 11:06:40 -06:00
David Teigland
29da4255b2 lvchange: make use of command definitions
Reorganize the lvchange code to take advantage of
the command definition, and remove the validation
that is done by the command definintion rules.
2017-02-10 11:06:40 -06:00
David Teigland
106ef06c2c process_each_lv: add check_single_lv function
The new check_single_lv() function is called prior to the
existing process_single_lv().  If the check function returns 0,
the LV will not be processed.

The check_single_lv function is meant to be a standard method
to validate the combination of specific command + specific LV,
and decide if the combination is allowed.  The check_single
function can be used by anything that calls process_each_lv.

As commands are migrated to take advantage of command
definitions, each command definition gets its own entry
point which calls process_each for itself, passing a
pair of check_single/process_single functions which can
be specific to the narrowly defined command def.
2017-02-10 11:06:40 -06:00
David Teigland
6467dea0db commands: new method for defining commands
. Define a prototype for every lvm command.
. Match every user command with one definition.
. Generate help text and man pages from them.

The new file command-lines.in defines a prototype for every
unique lvm command.  A unique lvm command is a unique
combination of: command name + required option args +
required positional args.  Each of these prototypes also
includes the optional option args and optional positional
args that the command will accept, a description, and a
unique string ID for the definition.  Any valid command
will match one of the prototypes.

Here's an example of the lvresize command definitions from
command-lines.in, there are three unique lvresize commands:

lvresize --size SizeMB LV
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync, --reportformat String, --resizefs,
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB
OP: PV ...
ID: lvresize_by_size
DESC: Resize an LV by a specified size.

lvresize LV PV ...
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync,
--reportformat String, --resizefs, --stripes Number, --stripesize SizeKB
ID: lvresize_by_pv
DESC: Resize an LV by specified PV extents.
FLAGS: SECONDARY_SYNTAX

lvresize --poolmetadatasize SizeMB LV_thinpool
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync,
--reportformat String, --stripes Number, --stripesize SizeKB
OP: PV ...
ID: lvresize_pool_metadata_by_size
DESC: Resize a pool metadata SubLV by a specified size.

The three commands have separate definitions because they have
different required parameters.  Required parameters are specified
on the first line of the definition.  Optional options are
listed after OO, and optional positional args are listed after OP.

This data is used to generate corresponding command definition
structures for lvm in command-lines.h.  usage/help output is also
auto generated, so it is always in sync with the definitions.

Every user-entered command is compared against the set of
command structures, and matched with one.  An error is
reported if an entered command does not have the required
parameters for any definition.  The closest match is printed
as a suggestion, and running lvresize --help will display
the usage for each possible lvresize command.

The prototype syntax used for help/man output includes
required --option and positional args on the first line,
and optional --option and positional args enclosed in [ ]
on subsequent lines.

  command_name <required_opt_args> <required_pos_args>
          [ <optional_opt_args> ]
          [ <optional_pos_args> ]

Command definitions that are not to be advertised/suggested
have the flag SECONDARY_SYNTAX.  These commands will not be
printed in the normal help output.

Man page prototypes are also generated from the same original
command definitions, and are always in sync with the code
and help text.

Very early in command execution, a matching command definition
is found.  lvm then knows the operation being done, and that
the provided args conform to the definition.  This will allow
lots of ad hoc checking/validation to be removed throughout
the code.

Each command definition can also be routed to a specific
function to implement it.  The function is associated with
an enum value for the command definition (generated from
the ID string.)  These per-command-definition implementation
functions have not yet been created, so all commands
currently fall back to the existing per-command-name
implementation functions.

Using per-command-definition functions will allow lots of
code to be removed which tries to figure out what the
command is meant to do.  This is currently based on ad hoc
and complicated option analysis.  When using the new
functions, what the command is doing is already known
from the associated command definition.
2017-02-10 11:06:32 -06:00
David Teigland
2da7b10988 lvmlockd: test mode doesn't work
The --test option is not yet compatible with shared VGs
because changes are made in lvmlockd that cannot be
reversed or faked.
2017-02-07 10:36:18 -06:00
55 changed files with 294 additions and 829 deletions

View File

@@ -1,7 +1,5 @@
Version 2.02.169 -
=====================================
Support striped/raid0* <-> raid10_near conversions
Support shrinking of RaidLvs
Support region size changes on existing RaidLVs
Avoid parallel usage of cpg_mcast_joined() in clvmd with corosync.
Support raid6_{ls,rs,la,ra}_6 segment types and conversions from/to it.

View File

@@ -1,7 +1,5 @@
Version 1.02.138 -
=====================================
Avoids immediate resume when preloaded device is smaller.
Do not suppress kernel key description in dmsetup table output.
Support configurable command executed from dmeventd thin plugin.
Support new R|r human readable units output format.
Thin dmeventd plugin reacts faster on lvextend failure path with umount.

View File

@@ -897,9 +897,8 @@ static uint32_t _round_to_stripe_boundary(struct volume_group *vg, uint32_t exte
/* Round up extents to stripe divisible amount */
if ((size_rest = extents % stripes)) {
new_extents += extend ? stripes - size_rest : -size_rest;
log_print_unless_silent("Rounding size %s (%u extents) %s to stripe boundary size %s(%u extents).",
log_print_unless_silent("Rounding size %s (%u extents) up to stripe boundary size %s (%u extents).",
display_size(vg->cmd, (uint64_t) extents * vg->extent_size), extents,
new_extents < extents ? "down" : "up",
display_size(vg->cmd, (uint64_t) new_extents * vg->extent_size), new_extents);
}
@@ -974,37 +973,6 @@ struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
return seg;
}
/*
* Temporary helper to return number of data copies for
* RAID segment @seg until seg->data_copies got added
*/
static uint32_t _raid_data_copies(struct lv_segment *seg)
{
/*
* FIXME: needs to change once more than 2 are supported.
* I.e. use seg->data_copies then
*/
if (seg_is_raid10(seg))
return 2;
else if (seg_is_raid1(seg))
return seg->area_count;
return seg->segtype->parity_devs + 1;
}
/* Data image count for RAID segment @seg */
static uint32_t _raid_stripes_count(struct lv_segment *seg)
{
/*
* FIXME: raid10 needs to change once more than
* 2 data_copies and odd # of legs supported.
*/
if (seg_is_raid10(seg))
return seg->area_count / _raid_data_copies(seg);
return seg->area_count - seg->segtype->parity_devs;
}
static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t s,
uint32_t area_reduction, int with_discard)
{
@@ -1045,40 +1013,32 @@ static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t
}
if (lv_is_raid_image(lv)) {
/* Calculate the amount of extents to reduce per rmate/rimage LV */
uint32_t rimage_extents;
/* FIXME: avoid extra seg_is_*() conditonals */
area_reduction =_round_to_stripe_boundary(lv->vg, area_reduction,
(seg_is_raid1(seg) || seg_is_any_raid0(seg)) ? 0 : _raid_stripes_count(seg), 0);
rimage_extents = raid_rimage_extents(seg->segtype, area_reduction, seg_is_any_raid0(seg) ? 0 : _raid_stripes_count(seg),
seg_is_raid10(seg) ? 1 :_raid_data_copies(seg));
if (!rimage_extents)
/*
* FIXME: Use lv_reduce not lv_remove
* We use lv_remove for now, because I haven't figured out
* why lv_reduce won't remove the LV.
lv_reduce(lv, area_reduction);
*/
if (area_reduction != seg->area_len) {
log_error("Unable to reduce RAID LV - operation not implemented.");
return 0;
if (seg->meta_areas) {
uint32_t meta_area_reduction;
struct logical_volume *mlv;
struct volume_group *vg = lv->vg;
if (seg_metatype(seg, s) != AREA_LV ||
!(mlv = seg_metalv(seg, s)))
} else {
if (!lv_remove(lv)) {
log_error("Failed to remove RAID image %s.",
display_lvname(lv));
return 0;
meta_area_reduction = raid_rmeta_extents_delta(vg->cmd, lv->le_count, lv->le_count - rimage_extents,
seg->region_size, vg->extent_size);
/* Limit for raid0_meta not having region size set */
if (meta_area_reduction > mlv->le_count ||
!(lv->le_count - rimage_extents))
meta_area_reduction = mlv->le_count;
if (meta_area_reduction &&
!lv_reduce(mlv, meta_area_reduction))
return_0; /* FIXME: any upper level reporting */
}
}
if (!lv_reduce(lv, rimage_extents))
return_0; /* FIXME: any upper level reporting */
/* Remove metadata area if image has been removed */
if (seg->meta_areas && seg_metalv(seg, s) && (area_reduction == seg->area_len)) {
if (!lv_reduce(seg_metalv(seg, s),
seg_metalv(seg, s)->le_count)) {
log_error("Failed to remove RAID meta-device %s.",
display_lvname(seg_metalv(seg, s)));
return 0;
}
}
return 1;
}
@@ -1485,13 +1445,6 @@ int lv_refresh_suspend_resume(const struct logical_volume *lv)
*/
int lv_reduce(struct logical_volume *lv, uint32_t extents)
{
struct lv_segment *seg = first_seg(lv);
/* Ensure stipe boundary extents on RAID LVs */
if (lv_is_raid(lv) && extents != lv->le_count)
extents =_round_to_stripe_boundary(lv->vg, extents,
seg_is_raid1(seg) ? 0 : _raid_stripes_count(seg), 0);
return _lv_reduce(lv, extents, 1);
}
@@ -3355,24 +3308,19 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
if (segtype_is_raid(segtype)) {
if (metadata_area_count) {
uint32_t cur_rimage_extents, new_rimage_extents;
if (metadata_area_count != area_count)
log_error(INTERNAL_ERROR
"Bad metadata_area_count");
ah->metadata_area_count = area_count;
ah->alloc_and_split_meta = 1;
ah->log_len = RAID_METADATA_AREA_LEN;
/* Calculate log_len (i.e. length of each rmeta device) for RAID */
cur_rimage_extents = raid_rimage_extents(segtype, existing_extents, stripes, mirrors);
new_rimage_extents = raid_rimage_extents(segtype, existing_extents + new_extents, stripes, mirrors),
ah->log_len = raid_rmeta_extents_delta(cmd, cur_rimage_extents, new_rimage_extents,
region_size, extent_size);
ah->metadata_area_count = metadata_area_count;
ah->alloc_and_split_meta = !!ah->log_len;
/*
* We need 'log_len' extents for each
* RAID device's metadata_area
*/
total_extents += ah->log_len * (segtype_is_raid1(segtype) ? 1 : ah->area_multiple);
total_extents += (ah->log_len * ah->area_multiple);
} else {
ah->log_area_count = 0;
ah->log_len = 0;
@@ -4069,6 +4017,19 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
if (!_setup_lv_size(lv, lv->le_count + extents))
return_0;
/*
* The MD bitmap is limited to being able to track 2^21 regions.
* The region_size must be adjusted to meet that criteria
* unless raid0/raid0_meta, which doesn't have a bitmap.
*/
if (seg_is_raid(seg) && !seg_is_any_raid0(seg))
while (seg->region_size < (lv->size / (1 << 21))) {
seg->region_size *= 2;
log_very_verbose("Adjusting RAID region_size from %uS to %uS"
" to support large LV size",
seg->region_size/2, seg->region_size);
}
return 1;
}
@@ -4116,22 +4077,6 @@ int lv_extend(struct logical_volume *lv,
}
/* FIXME log_count should be 1 for mirrors */
if (segtype_is_raid(segtype) && !segtype_is_any_raid0(segtype)) {
uint64_t lv_size = ((uint64_t) lv->le_count + extents) * lv->vg->extent_size;
/*
* The MD bitmap is limited to being able to track 2^21 regions.
* The region_size must be adjusted to meet that criteria
* unless raid0/raid0_meta, which doesn't have a bitmap.
*/
region_size = raid_ensure_min_region_size(lv, lv_size, region_size);
if (first_seg(lv))
first_seg(lv)->region_size = region_size;
}
if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors,
log_count, region_size, extents,
allocatable_pvs, alloc, approx_alloc, NULL)))
@@ -4712,11 +4657,6 @@ static uint32_t lvseg_get_stripes(struct lv_segment *seg, uint32_t *stripesize)
return seg->area_count;
}
if (seg_is_raid(seg)) {
*stripesize = seg->stripe_size;
return _raid_stripes_count(seg);
}
*stripesize = 0;
return 0;
}
@@ -5382,7 +5322,6 @@ int lv_resize(struct logical_volume *lv,
struct logical_volume *lock_lv = (struct logical_volume*) lv_lock_holder(lv);
struct logical_volume *aux_lv = NULL; /* Note: aux_lv never resizes fs */
struct lvresize_params aux_lp;
struct lv_segment *seg = first_seg(lv);
int activated = 0;
int ret = 0;
int status;
@@ -5424,11 +5363,6 @@ int lv_resize(struct logical_volume *lv,
}
}
/* Ensure stripe boundary extents! */
if (!lp->percent && lv_is_raid(lv))
lp->extents =_round_to_stripe_boundary(lv->vg, lp->extents,
seg_is_raid1(seg) ? 0 : _raid_stripes_count(seg),
lp->resize == LV_REDUCE ? 0 : 1);
if (aux_lv && !_lvresize_prepare(&aux_lv, &aux_lp, pvh))
return_0;

View File

@@ -1224,12 +1224,6 @@ int lv_raid_replace(struct logical_volume *lv, int force,
struct dm_list *remove_pvs, struct dm_list *allocate_pvs);
int lv_raid_remove_missing(struct logical_volume *lv);
int partial_raid_lv_supports_degraded_activation(const struct logical_volume *lv);
uint32_t raid_rmeta_extents_delta(struct cmd_context *cmd,
uint32_t rimage_extents_cur, uint32_t rimage_extents_new,
uint32_t region_size, uint32_t extent_size);
uint32_t raid_rimage_extents(const struct segment_type *segtype,
uint32_t extents, uint32_t stripes, uint32_t data_copies);
uint32_t raid_ensure_min_region_size(const struct logical_volume *lv, uint64_t lv_size, uint32_t region_size);
int lv_raid_change_region_size(struct logical_volume *lv,
int yes, int force, uint32_t new_region_size);
/* -- metadata/raid_manip.c */

View File

@@ -50,26 +50,24 @@ static int _check_num_areas_in_lv_segments(struct logical_volume *lv, unsigned n
return 1;
}
/*
* Ensure region size exceeds the minimum for @lv because
* MD's bitmap is limited to tracking 2^21 regions.
*
* Pass in @lv_size, because funcion can be called with an empty @lv.
*/
uint32_t raid_ensure_min_region_size(const struct logical_volume *lv, uint64_t lv_size, uint32_t region_size)
/* Ensure region size exceeds the minimum for lv */
static void _ensure_min_region_size(const struct logical_volume *lv)
{
uint32_t min_region_size = lv_size / (1 << 21);
uint32_t region_size_sav = region_size;
struct lv_segment *seg = first_seg(lv);
uint32_t min_region_size, region_size;
/* MD's bitmap is limited to tracking 2^21 regions */
min_region_size = lv->size / (1 << 21);
region_size = seg->region_size;
while (region_size < min_region_size)
region_size *= 2;
if (region_size != region_size_sav)
log_very_verbose("Adjusting region_size from %s to %s for %s.",
display_size(lv->vg->cmd, region_size_sav),
display_size(lv->vg->cmd, region_size),
display_lvname(lv));
return region_size;
if (seg->region_size != region_size) {
log_very_verbose("Setting region_size to %u for %s.",
seg->region_size, display_lvname(lv));
seg->region_size = region_size;
}
}
/*
@@ -108,7 +106,8 @@ static void _check_and_adjust_region_size(const struct logical_volume *lv)
struct lv_segment *seg = first_seg(lv);
seg->region_size = seg->region_size ? : get_default_region_size(lv->vg->cmd);
seg->region_size = raid_ensure_min_region_size(lv, lv->size, seg->region_size);
return _ensure_min_region_size(lv);
}
/* Strip any raid suffix off LV name */
@@ -481,161 +480,6 @@ out:
return r;
}
/* raid0* <-> raid10_near area reorder helper: swap 2 LV segment areas @a1 and @a2 */
static void _swap_areas(struct lv_segment_area *a1, struct lv_segment_area *a2)
{
struct lv_segment_area tmp;
tmp = *a1;
*a1 = *a2;
*a2 = tmp;
}
/*
* Reorder the areas in the first segment of @seg to suit raid10_{near,far}/raid0 layout.
*
* raid10_{near,far} can only be reordered to raid0 if !mod(#total_devs, #mirrors)
*
* Examples with 6 disks indexed 0..5 with 3 stripes:
* raid0 (012345) -> raid10_{near,far} (031425) order
* idx 024135
* raid10_{near,far} (012345) -> raid0 (024135/135024) order depending on mirror leg selection (TBD)
* idx 031425
* _or_ (variations possible)
* idx 304152
*
* Examples 3 stripes with 9 disks indexed 0..8 to create a 3 striped raid0 with 3 data_copies per leg:
* vvv
* raid0 (012345678) -> raid10 (034156278) order
* v v v
* raid10 (012345678) -> raid0 (036124578) order depending on mirror leg selection (TBD)
*
*/
enum raid0_raid10_conversion { reorder_to_raid10_near, reorder_from_raid10_near };
static int _reorder_raid10_near_seg_areas(struct lv_segment *seg, enum raid0_raid10_conversion conv)
{
unsigned dc, idx1, idx1_sav, idx2, s, ss, str, xchg;
uint32_t data_copies = 2; /* seg->data_copies */
uint32_t *idx, stripes = seg->area_count;
unsigned i = 0;
/* Internal sanity checks... */
if (!(conv == reorder_to_raid10_near || conv == reorder_from_raid10_near))
return_0;
if ((conv == reorder_to_raid10_near && !(seg_is_striped(seg) || seg_is_any_raid0(seg))) ||
(conv == reorder_from_raid10_near && !seg_is_raid10_near(seg)))
return_0;
/* FIXME: once more data copies supported with raid10 */
if (seg_is_raid10_near(seg) && (stripes % data_copies)) {
log_error("Can't convert %s LV %s with number of stripes not divisable by number of data copies",
lvseg_name(seg), display_lvname(seg->lv));
return 0;
}
/* FIXME: once more data copies supported with raid10 */
stripes /= data_copies;
if (!(idx = dm_pool_zalloc(seg_lv(seg, 0)->vg->vgmem, seg->area_count * sizeof(*idx))))
return 0;
/* Set up positional index array */
switch (conv) {
case reorder_to_raid10_near:
/*
* raid0 (012 345) with 3 stripes/2 data copies -> raid10 (031425)
*
* _reorder_raid10_near_seg_areas 2137 idx[0]=0
* _reorder_raid10_near_seg_areas 2137 idx[1]=2
* _reorder_raid10_near_seg_areas 2137 idx[2]=4
* _reorder_raid10_near_seg_areas 2137 idx[3]=1
* _reorder_raid10_near_seg_areas 2137 idx[4]=3
* _reorder_raid10_near_seg_areas 2137 idx[5]=5
*
* raid0 (012 345 678) with 3 stripes/3 data copies -> raid10 (036147258)
*
* _reorder_raid10_near_seg_areas 2137 idx[0]=0
* _reorder_raid10_near_seg_areas 2137 idx[1]=3
* _reorder_raid10_near_seg_areas 2137 idx[2]=6
*
* _reorder_raid10_near_seg_areas 2137 idx[3]=1
* _reorder_raid10_near_seg_areas 2137 idx[4]=4
* _reorder_raid10_near_seg_areas 2137 idx[5]=7
* _reorder_raid10_near_seg_areas 2137 idx[6]=2
* _reorder_raid10_near_seg_areas 2137 idx[7]=5
* _reorder_raid10_near_seg_areas 2137 idx[8]=8
*/
/* idx[from] = to */
for (s = ss = 0; s < seg->area_count; s++)
if (s < stripes)
idx[s] = s * data_copies;
else {
uint32_t factor = s % stripes;
if (!factor)
ss++;
idx[s] = ss + factor * data_copies;
}
break;
case reorder_from_raid10_near:
/*
* Order depending on mirror leg selection (TBD)
*
* raid10 (012345) with 3 stripes/2 data copies -> raid0 (024135/135024)
* raid10 (012345678) with 3 stripes/3 data copies -> raid0 (036147258/147036258/...)
*/
/* idx[from] = to */
for (s = 0; s < seg->area_count; s++)
idx[s] = -1; /* = unused */
idx1 = 0;
idx2 = stripes;
for (str = 0; str < stripes; str++) {
idx1_sav = idx1;
for (dc = 0; dc < data_copies; dc++) {
struct logical_volume *slv;
s = str * data_copies + dc;
slv = seg_lv(seg, s);
idx[s] = ((slv->status & PARTIAL_LV) || idx1 != idx1_sav) ? idx2++ : idx1++;
}
if (idx1 == idx1_sav) {
log_error("Failed to find a valid mirror in stripe %u!", str);
return 0;
}
}
break;
default:
return 0;
}
/* Sort areas */
do {
xchg = seg->area_count;
for (s = 0; s < seg->area_count ; s++)
if (idx[s] == s)
xchg--;
else {
_swap_areas(seg->areas + s, seg->areas + idx[s]);
_swap_areas(seg->meta_areas + s, seg->meta_areas + idx[s]);
ss = idx[idx[s]];
idx[idx[s]] = idx[s];
idx[s] = ss;
}
i++;
} while (xchg);
return 1;
}
/*
* _shift_and_rename_image_components
* @seg: Top-level RAID segment
@@ -828,7 +672,7 @@ static int _alloc_image_components(struct logical_volume *lv,
return_0;
if (seg_is_linear(seg))
region_size = seg->region_size ? : get_default_region_size(lv->vg->cmd);
region_size = get_default_region_size(lv->vg->cmd);
else
region_size = seg->region_size;
@@ -913,7 +757,7 @@ static uint32_t _raid_rmeta_extents(struct cmd_context *cmd, uint32_t rimage_ext
uint64_t bytes, regions, sectors;
region_size = region_size ?: get_default_region_size(cmd);
regions = ((uint64_t) rimage_extents) * extent_size / region_size;
regions = (uint64_t) rimage_extents * extent_size / region_size;
/* raid and bitmap superblocks + region bytes */
bytes = 2 * 4096 + dm_div_up(regions, 8);
@@ -922,53 +766,6 @@ static uint32_t _raid_rmeta_extents(struct cmd_context *cmd, uint32_t rimage_ext
return dm_div_up(sectors, extent_size);
}
/*
* Returns raid metadata device size _change_ in extents, algorithm from dm-raid ("raid" target) kernel code.
*/
uint32_t raid_rmeta_extents_delta(struct cmd_context *cmd,
uint32_t rimage_extents_cur, uint32_t rimage_extents_new,
uint32_t region_size, uint32_t extent_size)
{
uint32_t rmeta_extents_cur = _raid_rmeta_extents(cmd, rimage_extents_cur, region_size, extent_size);
uint32_t rmeta_extents_new = _raid_rmeta_extents(cmd, rimage_extents_new, region_size, extent_size);
/* Need minimum size on LV creation */
if (!rimage_extents_cur)
return rmeta_extents_new;
/* Need current size on LV deletion */
if (!rimage_extents_new)
return rmeta_extents_cur;
if (rmeta_extents_new == rmeta_extents_cur)
return 0;
/* Extending/reducing... */
return rmeta_extents_new > rmeta_extents_cur ?
rmeta_extents_new - rmeta_extents_cur :
rmeta_extents_cur - rmeta_extents_new;
}
/* Calculate raid rimage extents required based on total @extents for @segtype, @stripes and @data_copies */
uint32_t raid_rimage_extents(const struct segment_type *segtype,
uint32_t extents, uint32_t stripes, uint32_t data_copies)
{
uint64_t r;
if (!extents ||
segtype_is_mirror(segtype) ||
segtype_is_raid1(segtype))
return extents;
r = extents;
if (segtype_is_any_raid10(segtype))
r *= (data_copies ?: 1); /* Caller should ensure data_copies > 0 */
r = dm_div_up(r, stripes ?: 1); /* Caller should ensure stripes > 0 */
return r > UINT_MAX ? 0 : (uint32_t) r;
}
/*
* _alloc_rmeta_for_lv
* @lv
@@ -1009,8 +806,7 @@ static int _alloc_rmeta_for_lv(struct logical_volume *data_lv,
if (!(ah = allocate_extents(data_lv->vg, NULL, seg->segtype, 0, 1, 0,
seg->region_size,
raid_rmeta_extents_delta(data_lv->vg->cmd, 0, data_lv->le_count,
seg->region_size, data_lv->vg->extent_size),
1 /*RAID_METADATA_AREA_LEN*/,
allocate_pvs, data_lv->alloc, 0, NULL)))
return_0;
@@ -1070,11 +866,6 @@ static int _raid_add_images_without_commit(struct logical_volume *lv,
/* A complete resync will be done, no need to mark each sub-lv */
status_mask = ~(LV_REBUILD);
/* FIXME: allow setting region size on upconvert from linear */
seg->region_size = get_default_region_size(lv->vg->cmd);
/* MD's bitmap is limited to tracking 2^21 regions */
seg->region_size = raid_ensure_min_region_size(lv, lv->size, seg->region_size);
if (!(lvl = dm_pool_alloc(lv->vg->vgmem, sizeof(*lvl)))) {
log_error("Memory allocation failed.");
return 0;
@@ -1121,9 +912,7 @@ static int _raid_add_images_without_commit(struct logical_volume *lv,
goto fail;
if (seg_is_linear(seg)) {
uint32_t region_size = seg->region_size;
seg->status |= RAID_IMAGE;
first_seg(lv)->status |= RAID_IMAGE;
if (!insert_layer_for_lv(lv->vg->cmd, lv,
RAID | LVM_READ | LVM_WRITE,
"_rimage_0"))
@@ -1131,8 +920,15 @@ static int _raid_add_images_without_commit(struct logical_volume *lv,
lv->status |= RAID;
seg = first_seg(lv);
seg->region_size = region_size;
seg_lv(seg, 0)->status |= RAID_IMAGE | LVM_READ | LVM_WRITE;
seg->region_size = get_default_region_size(lv->vg->cmd);
/* MD's bitmap is limited to tracking 2^21 regions */
while (seg->region_size < (lv->size / (1 << 21))) {
seg->region_size *= 2;
log_very_verbose("Setting RAID1 region_size to %uS.",
seg->region_size);
}
if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_RAID1)))
return_0;
}
@@ -2400,6 +2196,7 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv,
lv->status &= ~MIRROR;
lv->status &= ~MIRRORED;
lv->status |= RAID;
seg->status |= SEG_RAID;
if (!lv_update_and_reload(lv))
return_0;
@@ -2763,7 +2560,6 @@ static struct lv_segment *_convert_striped_to_raid0(struct logical_volume *lv,
#define ALLOW_NONE 0x0
#define ALLOW_STRIPES 0x2
#define ALLOW_STRIPE_SIZE 0x4
#define ALLOW_REGION_SIZE 0x8
struct possible_takeover_reshape_type {
/* First 2 have to stay... */
@@ -2780,77 +2576,58 @@ struct possible_type {
};
static struct possible_takeover_reshape_type _possible_takeover_reshape_types[] = {
/* striped -> raid1 */
/* striped -> */
{ .current_types = SEG_STRIPED_TARGET, /* linear, i.e. seg->area_count = 1 */
.possible_types = SEG_RAID1,
.current_areas = 1,
.options = ALLOW_REGION_SIZE },
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
{ .current_types = SEG_STRIPED_TARGET, /* linear, i.e. seg->area_count = 1 */
.possible_types = SEG_RAID0|SEG_RAID0_META,
.current_areas = 1,
.options = ALLOW_STRIPE_SIZE },
/* raid0* -> raid1 */
/* raid0* -> */
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count = 1 */
.possible_types = SEG_RAID1,
.current_areas = 1,
.options = ALLOW_REGION_SIZE },
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
/* striped,raid0* <-> striped,raid0* */
{ .current_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
.possible_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
/* striped,raid0*,raid4,raid5_n,raid6_n_6 <-> striped,raid0*,raid4,raid5_n,raid6_n_6 */
{ .current_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META|SEG_RAID4|SEG_RAID5_N|SEG_RAID6_N_6,
.possible_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META|SEG_RAID4|SEG_RAID5_N|SEG_RAID6_N_6,
.current_areas = ~0U,
.options = ALLOW_NONE },
/* striped,raid0* -> raid4,raid5_n,raid6_n_6,raid10_near */
{ .current_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
.possible_types = SEG_RAID4|SEG_RAID5_N|SEG_RAID6_N_6|SEG_RAID10_NEAR,
.current_areas = ~0U,
.options = ALLOW_REGION_SIZE },
/* raid4,raid5_n,raid6_n_6,raid10_near -> striped/raid0* */
{ .current_types = SEG_RAID4|SEG_RAID5_N|SEG_RAID6_N_6|SEG_RAID10_NEAR,
.possible_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
.current_areas = ~0U,
.options = ALLOW_NONE },
/* raid4,raid5_n,raid6_n_6 <-> raid4,raid5_n,raid6_n_6 */
{ .current_types = SEG_RAID4|SEG_RAID5_N|SEG_RAID6_N_6,
.possible_types = SEG_RAID4|SEG_RAID5_N|SEG_RAID6_N_6,
.current_areas = ~0U,
.options = ALLOW_REGION_SIZE },
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
/* raid5_ls <-> raid6_ls_6 */
{ .current_types = SEG_RAID5_LS|SEG_RAID6_LS_6,
.possible_types = SEG_RAID5_LS|SEG_RAID6_LS_6,
.current_areas = ~0U,
.options = ALLOW_REGION_SIZE },
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
/* raid5_rs -> raid6_rs_6 */
{ .current_types = SEG_RAID5_RS|SEG_RAID6_RS_6,
.possible_types = SEG_RAID5_RS|SEG_RAID6_RS_6,
.current_areas = ~0U,
.options = ALLOW_REGION_SIZE },
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
/* raid5_ls -> raid6_la_6 */
{ .current_types = SEG_RAID5_LA|SEG_RAID6_LA_6,
.possible_types = SEG_RAID5_LA|SEG_RAID6_LA_6,
.current_areas = ~0U,
.options = ALLOW_REGION_SIZE },
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
/* raid5_ls -> raid6_ra_6 */
{ .current_types = SEG_RAID5_RA|SEG_RAID6_RA_6,
.possible_types = SEG_RAID5_RA|SEG_RAID6_RA_6,
.current_areas = ~0U,
.options = ALLOW_REGION_SIZE },
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
/* mirror <-> raid1 with arbitrary number of legs */
{ .current_types = SEG_MIRROR|SEG_RAID1,
.possible_types = SEG_MIRROR|SEG_RAID1,
.current_areas = ~0U,
.options = ALLOW_REGION_SIZE },
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
/* END */
{ .current_types = 0 }
@@ -3137,6 +2914,8 @@ static int _raid1_to_mirrored_wrapper(TAKEOVER_FN_ARGS)
display_lvname(lv), SEG_TYPE_NAME_MIRROR);
return 0;
}
if (sigint_caught())
return_0;
/* Archive metadata */
if (!archive(lv->vg))
@@ -3326,7 +3105,7 @@ static int _shift_parity_dev(struct lv_segment *seg)
/* raid456 -> raid0* / striped */
static int _raid45_to_raid54_wrapper(TAKEOVER_FN_ARGS);
static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
{
int rename_sublvs = 0;
struct lv_segment *seg = first_seg(lv);
@@ -3350,6 +3129,8 @@ static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
display_lvname(lv), new_segtype->name);
return 0;
}
if (sigint_caught())
return_0;
/* Archive metadata */
if (!archive(lv->vg))
@@ -3371,10 +3152,6 @@ static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
log_error("Failed to rename %s LV %s MetaLVs.", lvseg_name(seg), display_lvname(lv));
return 0;
}
} else if (seg_is_raid10_near(seg)) {
log_debug_metadata("Reordering areas for raid10 -> raid0 takeover");
if (!_reorder_raid10_near_seg_areas(seg, reorder_from_raid10_near))
return 0;
}
/* Remove meta and data LVs requested */
@@ -3527,6 +3304,9 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
dm_list_init(&removal_lvs);
if (seg_is_raid10(seg))
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
if (new_data_copies > new_image_count) {
log_error("N number of data_copies \"--mirrors N-1\" may not be larger than number of stripes.");
return 0;
@@ -3585,10 +3365,6 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
!_rename_area_lvs(lv, "_"))) {
log_error("Can't convert %s to %s.", display_lvname(lv), new_segtype->name);
return 0;
} else if (segtype_is_raid10_near(new_segtype)) {
log_debug_metadata("Reordering areas for raid0 -> raid10 takeover");
if (!_reorder_raid10_near_seg_areas(seg, reorder_to_raid10_near))
return 0;
}
seg->segtype = new_segtype;
@@ -3694,9 +3470,7 @@ static int _takeover_from_raid0_to_raid1(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_to_raid10(TAKEOVER_FN_ARGS)
{
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
first_seg(lv)->area_count * 2 /* new_image_count */,
2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
static int _takeover_from_raid0_to_raid45(TAKEOVER_FN_ARGS)
@@ -3746,9 +3520,7 @@ static int _takeover_from_raid0_meta_to_raid1(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_meta_to_raid10(TAKEOVER_FN_ARGS)
{
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
first_seg(lv)->area_count * 2 /* new_image_count */,
2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
static int _takeover_from_raid0_meta_to_raid45(TAKEOVER_FN_ARGS)
@@ -3825,12 +3597,12 @@ static int _takeover_from_raid45_to_mirrored(TAKEOVER_FN_ARGS)
static int _takeover_from_raid45_to_raid0(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid45_to_raid0_meta(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid45_to_raid1(TAKEOVER_FN_ARGS)
@@ -3861,30 +3633,30 @@ static int _takeover_from_raid45_to_raid6(TAKEOVER_FN_ARGS)
static int _takeover_from_raid45_to_striped(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid6_to_raid0(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid6_to_raid0_meta(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid6_to_raid45(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1,
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1,
2 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid6_to_striped(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
2 /* data_copies */, 0, 0, 0, allocate_pvs);
}
@@ -3911,9 +3683,7 @@ static int _takeover_from_striped_to_raid0_meta(TAKEOVER_FN_ARGS)
static int _takeover_from_striped_to_raid10(TAKEOVER_FN_ARGS)
{
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
first_seg(lv)->area_count * 2 /* new_image_count */,
2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
static int _takeover_from_striped_to_raid45(TAKEOVER_FN_ARGS)
@@ -3930,8 +3700,6 @@ static int _takeover_from_striped_to_raid6(TAKEOVER_FN_ARGS)
}
/*
* Only if we decide to support raid01 at all.
static int _takeover_from_raid01_to_raid01(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
@@ -3946,7 +3714,6 @@ static int _takeover_from_raid01_to_striped(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
*/
static int _takeover_from_raid10_to_linear(TAKEOVER_FN_ARGS)
{
@@ -3960,22 +3727,17 @@ static int _takeover_from_raid10_to_mirrored(TAKEOVER_FN_ARGS)
static int _takeover_from_raid10_to_raid0(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count / 2,
1 /* data_copies */, 0, 0, 0, allocate_pvs);
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
/*
* Only if we decide to support raid01 at all.
static int _takeover_from_raid10_to_raid01(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
*/
static int _takeover_from_raid10_to_raid0_meta(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count / 2,
1 /* data_copies */, 0, 0, 0, allocate_pvs);
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
static int _takeover_from_raid10_to_raid1(TAKEOVER_FN_ARGS)
@@ -3983,20 +3745,16 @@ static int _takeover_from_raid10_to_raid1(TAKEOVER_FN_ARGS)
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
/*
* This'd be a reshape, not a takeover.
*
static int _takeover_from_raid10_to_raid10(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
*/
static int _takeover_from_raid10_to_striped(TAKEOVER_FN_ARGS)
{
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count / 2,
1 /* data_copies */, 0, 0, 0, allocate_pvs);
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
*/
/*
* Import takeover matrix.
@@ -4122,7 +3880,7 @@ replaced:
* Change region size on raid @lv to @region_size if
* different from current region_size and adjusted region size
*/
static int _region_size_change_requested(struct logical_volume *lv, int yes, const uint32_t region_size)
static int _region_size_change_requested(struct logical_volume *lv, int yes, uint32_t region_size)
{
uint32_t old_region_size;
const char *seg_region_size_str;
@@ -4132,14 +3890,14 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, con
if (!region_size)
return_0;
/* CLI validation provides the check but be caucious... */
/* CLI validation prvides the check but be caucious... */
if (seg_is_any_raid0(seg))
return_0;
if (region_size == seg->region_size) {
log_print_unless_silent("Region size wouldn't change on %s LV %s.",
lvseg_name(seg), display_lvname(lv));
return 1;
log_warn("Region size wouldn't change on %s LV %s.",
lvseg_name(seg), display_lvname(lv));
return 0;
}
if (region_size * 8 > lv->size) {
@@ -4149,7 +3907,7 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, con
}
if (region_size < seg->stripe_size) {
log_error("Requested region size for LV %s is smaller than stripe size.",
log_error("Region size for LV %s is smaller than stripe size.",
display_lvname(lv));
return 0;
}
@@ -4161,16 +3919,8 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, con
}
old_region_size = seg->region_size;
seg_region_size_str = display_size(lv->vg->cmd, region_size);
if (!yes && yes_no_prompt("Do you really want to change the region_size %s of LV %s to %s? [y/n]: ",
display_size(lv->vg->cmd, old_region_size),
display_lvname(lv), seg_region_size_str) == 'n') {
log_error("Logical volume %s NOT converted", display_lvname(lv));
return 0;
}
seg->region_size = region_size;
seg_region_size_str = display_size(lv->vg->cmd, seg->region_size);
_check_and_adjust_region_size(lv);
if (seg->region_size == old_region_size) {
@@ -4179,6 +3929,15 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, con
return 1;
}
if (!yes && yes_no_prompt("Do you really want to change the region_size %s of LV %s to %s? [y/n]: ",
display_size(lv->vg->cmd, old_region_size),
display_lvname(lv), seg_region_size_str) == 'n') {
log_error("Logical volume %s NOT converted", display_lvname(lv));
return 0;
}
if (sigint_caught())
return_0;
/* Check for new region size causing bitmap to still fit metadata image LV */
if (seg->meta_areas && seg_metatype(seg, 0) == AREA_LV && seg_metalv(seg, 0)->le_count <
_raid_rmeta_extents(lv->vg->cmd, lv->le_count, seg->region_size, lv->vg->extent_size)) {
@@ -4199,7 +3958,7 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, con
static int _conversion_options_allowed(const struct lv_segment *seg_from,
const struct segment_type **segtype_to,
uint32_t new_image_count,
int new_data_copies, int new_region_size,
int new_data_copies, int region_size,
int stripes, unsigned new_stripe_size_supplied)
{
int r = 1;
@@ -4226,12 +3985,6 @@ static int _conversion_options_allowed(const struct lv_segment *seg_from,
r = 0;
}
if (new_region_size && !(opts & ALLOW_REGION_SIZE)) {
if (!_log_prohibited_option(seg_from, *segtype_to, "-R/--regionsize"))
stack;
r = 0;
}
return r;
}
@@ -4252,13 +4005,13 @@ int lv_raid_convert(struct logical_volume *lv,
const unsigned new_stripes,
const unsigned new_stripe_size_supplied,
const unsigned new_stripe_size,
const uint32_t new_region_size,
/* FIXME: workaround with volatile new_region_size until cli validation patches got merged */
uint32_t new_region_size,
struct dm_list *allocate_pvs)
{
struct lv_segment *seg = first_seg(lv);
uint32_t stripes, stripe_size;
uint32_t new_image_count = seg->area_count;
uint32_t region_size = new_region_size;
takeover_fn_t takeover_fn;
if (!new_segtype) {
@@ -4280,7 +4033,7 @@ int lv_raid_convert(struct logical_volume *lv,
/* Change RAID region size */
/*
* FIXME: workaround with new_region_size until the
* FIXME: workaround with volatile new_region_size until the
* cli validation patches got merged when we'll change
* the API to have new_region_size_supplied to check for.
*/
@@ -4290,7 +4043,7 @@ int lv_raid_convert(struct logical_volume *lv,
seg_is_raid(seg) && !seg_is_any_raid0(seg))
return _region_size_change_requested(lv, yes, new_region_size);
} else
region_size = seg->region_size ? : get_default_region_size(lv->vg->cmd);
new_region_size = seg->region_size ? : get_default_region_size(lv->vg->cmd);
/*
* Check acceptible options mirrors, region_size,
@@ -4305,7 +4058,7 @@ int lv_raid_convert(struct logical_volume *lv,
/* Exit without doing activation checks if the combination isn't possible */
if (_takeover_not_possible(takeover_fn))
return takeover_fn(lv, new_segtype, yes, force, new_image_count, 0, new_stripes, stripe_size,
region_size, allocate_pvs);
new_region_size, allocate_pvs);
log_verbose("Converting %s from %s to %s.",
display_lvname(lv), lvseg_name(first_seg(lv)),
@@ -4336,7 +4089,7 @@ int lv_raid_convert(struct logical_volume *lv,
}
return takeover_fn(lv, new_segtype, yes, force, new_image_count, 0, new_stripes, stripe_size,
region_size, allocate_pvs);
new_region_size, allocate_pvs);
}
int lv_raid_change_region_size(struct logical_volume *lv,

View File

@@ -50,8 +50,7 @@ struct dev_manager;
#define SEG_RAID0 0x0000000000040000ULL
#define SEG_RAID0_META 0x0000000000080000ULL
#define SEG_RAID1 0x0000000000100000ULL
#define SEG_RAID10_NEAR 0x0000000000200000ULL
#define SEG_RAID10 SEG_RAID10_NEAR
#define SEG_RAID10 0x0000000000200000ULL
#define SEG_RAID4 0x0000000000400000ULL
#define SEG_RAID5_N 0x0000000000800000ULL
#define SEG_RAID5_LA 0x0000000001000000ULL

View File

@@ -112,7 +112,7 @@ static takeover_fn_t _takeover_fns[][11] = {
/* raid1 */ { r1__lin, r1__str, r1__mir, r1__r0, r1__r0m, r1__r1, r1__r45, X , r1__r10, X , X },
/* raid4/5 */ { r45_lin, r45_str, r45_mir, r45_r0, r45_r0m, r45_r1, r45_r54, r45_r6, X , X , X },
/* raid6 */ { X , r6__str, X , r6__r0, r6__r0m, X , r6__r45, X , X , X , X },
/* raid10 */ { r10_lin, r10_str, r10_mir, r10_r0, r10_r0m, r10_r1, X , X , X , X , X },
/* raid10 */ // { r10_lin, r10_str, r10_mir, r10_r0, r10_r0m, r10_r1, X , X , r10_r10, r10_r01, X },
/* raid01 */ // { X , r01_str, X , X , X , X , X , X , r01_r10, r01_r01, X },
/* other */ { X , X , X , X , X , X , X , X , X , X , X },
};

View File

@@ -2874,8 +2874,8 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
else if (child->props.size_changed < 0)
dnode->props.size_changed = -1;
/* No resume for a device without parents or with unchanged or smaller size */
if (!dm_tree_node_num_children(child, 1) || (child->props.size_changed <= 0))
/* Resume device immediately if it has parents and its size changed */
if (!dm_tree_node_num_children(child, 1) || !child->props.size_changed)
continue;
if (!node_created && (dm_list_size(&child->props.segs) == 1)) {

View File

@@ -144,12 +144,10 @@ Makefile: Makefile.in
man-generator:
$(CC) -DMAN_PAGE_GENERATOR -I$(top_builddir)/tools $(CFLAGS) $(top_srcdir)/tools/command.c -o $@
- ./man-generator lvmconfig > test.gen
if [ ! -s test.gen ] ; then cp genfiles/*.gen $(top_builddir)/man; fi;
$(MAN8GEN): man-generator
echo "Generating $@" ;
if [ ! -e $@.gen ]; then ./man-generator $(basename $@) $(top_srcdir)/man/$@.des > $@.gen; fi
./man-generator $(basename $@) > $@.gen
if [ -f $(top_srcdir)/man/$@.end ]; then cat $(top_srcdir)/man/$@.end >> $@.gen; fi;
cat $(top_srcdir)/man/see_also.end >> $@.gen
$(SED) -e "s+#VERSION#+$(LVM_VERSION)+;s+#DEFAULT_SYS_DIR#+$(DEFAULT_SYS_DIR)+;s+#DEFAULT_ARCHIVE_DIR#+$(DEFAULT_ARCHIVE_DIR)+;s+#DEFAULT_BACKUP_DIR#+$(DEFAULT_BACKUP_DIR)+;s+#DEFAULT_PROFILE_DIR#+$(DEFAULT_PROFILE_DIR)+;s+#DEFAULT_CACHE_DIR#+$(DEFAULT_CACHE_DIR)+;s+#DEFAULT_LOCK_DIR#+$(DEFAULT_LOCK_DIR)+;s+#CLVMD_PATH#+@CLVMD_PATH@+;s+#LVM_PATH#+@LVM_PATH@+;s+#DEFAULT_RUN_DIR#+@DEFAULT_RUN_DIR@+;s+#DEFAULT_PID_DIR#+@DEFAULT_PID_DIR@+;s+#SYSTEMD_GENERATOR_DIR#+$(SYSTEMD_GENERATOR_DIR)+;s+#DEFAULT_MANGLING#+$(DEFAULT_MANGLING)+;" $@.gen > $@

View File

@@ -820,10 +820,8 @@ Outputs the current table for the device in a format that can be fed
back in using the create or load commands.
With \fB\-\-target\fP, only information relating to the specified target type
is displayed.
Real encryption keys are suppressed in the table output for the crypt
target unless the \fB\-\-showkeys\fP parameter is supplied. Kernel key
references prefixed with \fB:\fP are not affected by the parameter and get
displayed always.
Encryption keys are suppressed in the table output for the crypt
target unless the \fB\-\-showkeys\fP parameter is supplied.
.
.HP
.CMD_TARGETS

View File

@@ -1,4 +1,4 @@
.SH EXAMPLES
.EXAMPLES
Change LV permission to read-only:
.sp

View File

@@ -7,6 +7,21 @@ To display the current LV type, run the command:
.B lvs \-o name,segtype
.I LV
A command to change the LV type uses the general pattern:
.B lvconvert \-\-type
.I NewType LV
LVs with the following types can be modified by lvconvert:
.B striped,
.B snapshot,
.B mirror,
.B raid*,
.B thin,
.B cache,
.B thin\-pool,
.B cache\-pool.
The
.B linear
type is equivalent to the

View File

@@ -1,64 +1,64 @@
.SH EXAMPLES
Convert a linear LV to a two-way mirror LV.
Convert a linear LV to a two-way mirror LV:
.br
.B lvconvert \-\-type mirror \-\-mirrors 1 vg/lvol1
Convert a linear LV to a two-way RAID1 LV.
Convert a linear LV to a two-way RAID1 LV:
.br
.B lvconvert \-\-type raid1 \-\-mirrors 1 vg/lvol1
Convert a mirror LV to use an in\-memory log.
Convert a mirror LV to use an in\-memory log:
.br
.B lvconvert \-\-mirrorlog core vg/lvol1
Convert a mirror LV to use a disk log.
Convert a mirror LV to use a disk log:
.br
.B lvconvert \-\-mirrorlog disk vg/lvol1
Convert a mirror or raid1 LV to a linear LV.
Convert a mirror or raid1 LV to a linear LV:
.br
.B lvconvert --type linear vg/lvol1
Convert a mirror LV to a raid1 LV with the same number of images.
Convert a mirror LV to a raid1 LV with the same number of images:
.br
.B lvconvert \-\-type raid1 vg/lvol1
Convert a linear LV to a two-way mirror LV, allocating new extents from specific
PV ranges.
PV ranges:
.br
.B lvconvert \-\-mirrors 1 vg/lvol1 /dev/sda:0\-15 /dev/sdb:0\-15
Convert a mirror LV to a linear LV, freeing physical extents from a specific PV.
Convert a mirror LV to a linear LV, freeing physical extents from a specific PV:
.br
.B lvconvert \-\-type linear vg/lvol1 /dev/sda
Split one image from a mirror or raid1 LV, making it a new LV.
Split one image from a mirror or raid1 LV, making it a new LV:
.br
.B lvconvert \-\-splitmirrors 1 \-\-name lv_split vg/lvol1
Split one image from a raid1 LV, and track changes made to the raid1 LV
while the split image remains detached.
while the split image remains detached:
.br
.B lvconvert \-\-splitmirrors 1 \-\-trackchanges vg/lvol1
Merge an image (that was previously created with \-\-splitmirrors and
\-\-trackchanges) back into the original raid1 LV.
\-\-trackchanges) back into the original raid1 LV:
.br
.B lvconvert \-\-mergemirrors vg/lvol1_rimage_1
Replace PV /dev/sdb1 with PV /dev/sdf1 in a raid1/4/5/6/10 LV.
Replace PV /dev/sdb1 with PV /dev/sdf1 in a raid1/4/5/6/10 LV:
.br
.B lvconvert \-\-replace /dev/sdb1 vg/lvol1 /dev/sdf1
Replace 3 PVs /dev/sd[b-d]1 with PVs /dev/sd[f-h]1 in a raid1 LV.
Replace 3 PVs /dev/sd[b-d]1 with PVs /dev/sd[f-h]1 in a raid1 LV:
.br
.B lvconvert \-\-replace /dev/sdb1 \-\-replace /dev/sdc1 \-\-replace /dev/sdd1
.RS
.B vg/lvol1 /dev/sd[fgh]1
.RE
Replace the maximum of 2 PVs /dev/sd[bc]1 with PVs /dev/sd[gh]1 in a raid6 LV.
Replace the maximum of 2 PVs /dev/sd[bc]1 with PVs /dev/sd[gh]1 in a raid6 LV:
.br
.B lvconvert \-\-replace /dev/sdb1 \-\-replace /dev/sdc1 vg/lvol1 /dev/sd[gh]1
@@ -69,7 +69,7 @@ is used as an external read\-only origin for the new thin LV.
Convert an LV into a thin LV in the specified thin pool. The existing LV
is used as an external read\-only origin for the new thin LV, and is
renamed "external".
renamed "external":
.br
.B lvconvert \-\-type thin \-\-thinpool vg/tpool1
.RS
@@ -77,19 +77,19 @@ renamed "external".
.RE
Convert an LV to a cache pool LV using another specified LV for cache pool
metadata.
metadata:
.br
.B lvconvert \-\-type cache-pool \-\-poolmetadata vg/poolmeta1 vg/lvol1
Convert an LV to a cache LV using the specified cache pool and chunk size.
Convert an LV to a cache LV using the specified cache pool and chunk size:
.br
.B lvconvert \-\-type cache \-\-cachepool vg/cpool1 \-c 128 vg/lvol1
Detach and keep the cache pool from a cache LV.
Detach and keep the cache pool from a cache LV:
.br
.B lvconvert \-\-splitcache vg/lvol1
Detach and remove the cache pool from a cache LV.
Detach and remove the cache pool from a cache LV:
.br
.B lvconvert \-\-uncache vg/lvol1

View File

@@ -1,5 +1,6 @@
.SH NOTES
.IP \[bu] 3
To find the name of the pvmove LV that was created by an original
\fBpvmove /dev/name\fP command, use the command:
.br
@@ -7,27 +8,27 @@ To find the name of the pvmove LV that was created by an original
.SH EXAMPLES
Continue polling a pvmove operation.
Continue polling a pvmove operation:
.br
.B lvm lvpoll --polloperation pvmove vg00/pvmove0
Abort a pvmove operation.
Abort a pvmove operation:
.br
.B lvm lvpoll --polloperation pvmove --abort vg00/pvmove0
Continue polling a mirror conversion.
Continue polling a mirror conversion:
.br
.B lvm lvpoll --polloperation convert vg00/lvmirror
Continue mirror repair.
Continue mirror repair:
.br
.B lvm lvpoll --polloperation convert vg/damaged_mirror --handlemissingpvs
Continue snapshot merge.
Continue snapshot merge:
.br
.B lvm lvpoll --polloperation merge vg/snapshot_old
Continue thin snapshot merge.
Continue thin snapshot merge:
.br
.B lvm lvpoll --polloperation merge_thin vg/thin_snapshot

View File

@@ -1,3 +0,0 @@
lvmsadc is not currently supported in LVM. The device-mapper statistics
facility provides similar performance metrics using the \fBdmstats(8)\fP
command.

View File

@@ -1,3 +0,0 @@
lvmsar is not currently supported in LVM. The device-mapper statistics
facility provides similar performance metrics using the \fBdmstats(8)\fP
command.

View File

@@ -1,61 +0,0 @@
pvmove moves the allocated physical extents (PEs) on a source PV to one or
more destination PVs. You can optionally specify a source LV in which
case only extents used by that LV will be moved to free (or specified)
extents on the destination PV. If no destination PV is specified, the
normal allocation rules for the VG are used.
If pvmove is interrupted for any reason (e.g. the machine crashes) then
run pvmove again without any PV arguments to restart any operations that
were in progress from the last checkpoint. Alternatively, use the abort
option at any time to abort the operation. The resulting location of LVs
after an abort depends on whether the atomic option was used.
More than one pvmove can run concurrently if they are moving data from
different source PVs, but additional pvmoves will ignore any LVs already
in the process of being changed, so some data might not get moved.
pvmove works as follows:
1. A temporary 'pvmove' LV is created to store details of all the data
movements required.
2. Every LV in the VG is searched for contiguous data that need moving
according to the command line arguments.
For each piece of data found, a new segment is added to the end of the
pvmove LV.
This segment takes the form of a temporary mirror to copy the data
from the original location to a newly allocated location.
The original LV is updated to use the new temporary mirror segment
in the pvmove LV instead of accessing the data directly.
3. The VG metadata is updated on disk.
4. The first segment of the pvmove LV is activated and starts to mirror
the first part of the data. Only one segment is mirrored at once as this
is usually more efficient.
5. A daemon repeatedly checks progress at the specified time interval.
When it detects that the first temporary mirror is in sync, it breaks that
mirror so that only the new location for that data gets used and writes a
checkpoint into the VG metadata on disk. Then it activates the mirror for
the next segment of the pvmove LV.
6. When there are no more segments left to be mirrored, the temporary LV
is removed and the VG metadata is updated so that the LVs reflect the new
data locations.
Note that this new process cannot support the original LVM1
type of on-disk metadata. Metadata can be converted using
\fBvgconvert\fP(8).
If the \fB\-\-atomic\fP option is used, a slightly different approach is
used for the move. Again, a temporary 'pvmove' LV is created to store the
details of all the data movements required. This temporary LV contains
all the segments of the various LVs that need to be moved. However, in
this case, an identical LV is allocated that contains the same number of
segments and a mirror is created to copy the contents from the first
temporary LV to the second. After a complete copy is made, the temporary
LVs are removed, leaving behind the segments on the destination PV. If an
abort is issued during the move, all LVs being moved will remain on the
source PV.

View File

@@ -1,3 +1,50 @@
.SH NOTES
.
\fBpvmove\fP works as follows:
1. A temporary 'pvmove' LV is created to store details of all the data
movements required.
2. Every LV in the VG is searched for contiguous data that need moving
according to the command line arguments.
For each piece of data found, a new segment is added to the end of the
pvmove LV.
This segment takes the form of a temporary mirror to copy the data
from the original location to a newly allocated location.
The original LV is updated to use the new temporary mirror segment
in the pvmove LV instead of accessing the data directly.
3. The VG metadata is updated on disk.
4. The first segment of the pvmove LV is activated and starts to mirror
the first part of the data. Only one segment is mirrored at once as this
is usually more efficient.
5. A daemon repeatedly checks progress at the specified time interval.
When it detects that the first temporary mirror is in sync, it breaks that
mirror so that only the new location for that data gets used and writes a
checkpoint into the VG metadata on disk. Then it activates the mirror for
the next segment of the pvmove LV.
6. When there are no more segments left to be mirrored, the temporary LV
is removed and the VG metadata is updated so that the LVs reflect the new
data locations.
Note that this new process cannot support the original LVM1
type of on-disk metadata. Metadata can be converted using
\fBvgconvert\fP(8).
If the \fB\-\-atomic\fP option is used, a slightly different approach is
used for the move. Again, a temporary 'pvmove' LV is created to store the
details of all the data movements required. This temporary LV contains
all the segments of the various LVs that need to be moved. However, in
this case, an identical LV is allocated that contains the same number of
segments and a mirror is created to copy the contents from the first
temporary LV to the second. After a complete copy is made, the temporary
LVs are removed, leaving behind the segments on the destination PV. If an
abort is issued during the move, all LVs being moved will remain on the
source PV.
.SH EXAMPLES
Move all physical extents that are used by simple LVs on the specified PV to

View File

@@ -1,2 +0,0 @@
pvremove wipes the label on a device so that LVM will no longer recognise
it as a PV.

View File

@@ -1,2 +0,0 @@
pvresize resizes a PV. The PV may already be in a VG and may have active
LVs allocated on it.

View File

@@ -1,5 +1,6 @@
.SH NOTES
.IP \[bu] 3
pvresize will refuse to shrink a PV if it has allocated extents beyond the
new end.

View File

@@ -1 +0,0 @@
pvs produces formatted output about PVs.

View File

@@ -1,6 +1,6 @@
pvscan scans all supported LVM block devices in the system for PVs.
.SH NOTES
\fBScanning with lvmetad\fP
.SS Scanning with lvmetad
pvscan operates differently when used with the
.BR lvmetad (8)
@@ -64,9 +64,7 @@ be temporarily disabled if they are seen.
To notify lvmetad about a device that is no longer present, the major and
minor numbers must be given, not the path.
.P
\fBAutomatic activation\fP
.SS Automatic activation
When event-driven system services detect a new LVM device, the first step
is to automatically scan and cache the metadata from the device. This is

View File

@@ -1,16 +0,0 @@
vgcfgbackup creates back up files containing metadata of VGs.
If no VGs are named, back up files are created for all VGs.
See \fBvgcfgrestore\fP for information on using the back up
files.
In a default installation, each VG is backed up into a separate file
bearing the name of the VG in the directory \fI#DEFAULT_BACKUP_DIR#\fP.
To use an alternative back up file, use \fB\-f\fP. In this case, when
backing up multiple VGs, the file name is treated as a template, with %s
replaced by the VG name.
NB. This DOES NOT back up the data content of LVs.
It may also be useful to regularly back up the files in
\fI#DEFAULT_SYS_DIR#\fP.

View File

@@ -1,8 +0,0 @@
vgcfgrestore restores the metadata of a VG from a text back up file
produced by \fBvgcfgbackup\fP. This writes VG metadata onto the devices
specifed in back up file.
A back up file can be specified with \fB\-\-file\fP. If no backup file is
specified, the most recent one is used. Use \fB\-\-list\fP for a list of
the available back up and archive files of a VG.

View File

@@ -1,9 +1,11 @@
.SH NOTES
.IP \[bu] 3
To replace PVs, \fBvgdisplay \-\-partial \-\-verbose\fP will show the
UUIDs and sizes of any PVs that are no longer present. If a PV in the VG
is lost and you wish to substitute another of the same size, use
\fBpvcreate \-\-restorefile filename \-\-uuid uuid\fP (plus additional
arguments as appropriate) to initialise it with the same UUID as the
missing PV. Repeat for all other missing PVs in the VG. Then use
\fBvgcfgrestore \-\-file filename\fP to restore the VG's metadata.
\fBvgcfgrestore \-\-file filename\fP to restore the volume group's
metadata.

View File

@@ -1,2 +0,0 @@
vgchange changes VG attributes, changes LV activation in the kernel, and
includes other utilities for VG maintenance.

View File

@@ -1,10 +1,4 @@
.SH NOTES
If vgchange recognizes COW snapshot LVs that were dropped because they ran
out of space, it displays a message informing the administrator that the
snapshots should be removed.
.SH EXAMPLES
.EXAMPLES
Activate all LVs in all VGs on all existing devices.
.br

View File

@@ -1 +0,0 @@
vgck checks LVM metadata for consistency.

View File

@@ -1,7 +0,0 @@
vgconvert converts VG metadata from one format to another. The new
metadata format must be able to fit into the space provided by the old
format.
Because the LVM1 format should no longer be used, this command is no
longer needed in general.

View File

@@ -1,4 +0,0 @@
vgcreate creates a new VG on block devices. If the devices were not
previously intialized as PVs with \fBpvcreate\fP(8), vgcreate will
inititialize them, making them PVs. The pvcreate options for initializing
devices are also available with vgcreate.

View File

@@ -1,4 +1,4 @@
.SH EXAMPLES
.EXAMPLES
Create a VG with two PVs, using the default physical extent size.
.br

View File

@@ -1,4 +0,0 @@
vgdisplay shows the attributes of VGs, and the associated PVs and LVs.
\fBvgs\fP(8) is a preferred alternative that shows the same information
and more, using a more compact and configurable output format.

View File

@@ -1,8 +1,14 @@
vgexport makes inactive VGs unknown to the system. In this state, all the
PVs in the VG can be moved to a different system, from which
.SH NOTES
.
.IP \[bu] 3
vgexport can make inactive VG(s) unknown to the system. In this state,
all the PVs in the VG can be moved to a different system, from which
\fBvgimport\fP can then be run.
.IP \[bu] 3
Most LVM tools ignore exported VGs.
.IP \[bu] 3
vgexport clears the VG system ID, and vgimport sets the VG system ID to
match the host running vgimport (if the host has a system ID).

View File

@@ -1,11 +0,0 @@
vgextend adds one or more PVs to a VG. This increases the space available
for LVs in the VG.
Also, PVs that have gone missing and then returned, e.g. due to a
transient device failure, can be added back to the VG without
re-initializing them (see \-\-restoremissing).
If the specified PVs have not yet been initialized with pvcreate, vgextend
will initialize them. In this case pvcreate options can be used, e.g.
\-\-labelsector, \-\-metadatasize, \-\-metadataignore,
\-\-pvmetadatacopies, \-\-dataalignment, \-\-dataalignmentoffset.

View File

@@ -1,3 +1,10 @@
.SH NOTES
If the specified PVs have not yet been initialized with pvcreate,
vgextend will initialize them. In this case the PV options apply,
e.g. \-\-labelsector, \-\-metadatasize, \-\-metadataignore,
\-\-pvmetadatacopies, \-\-dataalignment, \-\-dataalignmentoffset.
.SH EXAMPLES
Add two PVs to a VG.

View File

@@ -1,5 +0,0 @@
vgimport makes exported VGs known to the system again, perhaps after
moving the PVs from a different system.
vgexport clears the VG system ID, and vgimport sets the VG system ID to
match the host running vgimport (if the host has a system ID).

9
man/vgimport.8.end Normal file
View File

@@ -0,0 +1,9 @@
.SH NOTES
.
.IP \[bu] 3
vgimport makes exported VG(s) known to the system again, perhaps
after moving the PVs from a different system.
.IP \[bu] 3
vgexport clears the VG system ID, and vgimport sets the VG system ID
to match the host running vgimport (if the host has a system ID).

View File

@@ -1,6 +0,0 @@
vgimportclone imports a VG from duplicated PVs, e.g. created by a hardware
snapshot of existing PVs.
A duplicated VG cannot used until it is made to coexist with the original
VG. vgimportclone renames the VG associated with the specified PVs and
changes the associated VG and PV UUIDs.

View File

@@ -1,3 +1,14 @@
.SH NOTES
.IP \[bu] 3
vgimportclone can be used to import a VG from duplicated PVs (e.g. created
by a hardware snapshot of the PV devices).
.IP \[bu] 3
A duplicated VG cannot used until it is made to coexist with the original
VG. vgimportclone renames the VG associated with the specified PVs and
changes the associated VG and PV UUIDs.
.SH EXAMPLES
An original VG "vg00" has PVs "/dev/sda" and "/dev/sdb".

View File

@@ -1,3 +0,0 @@
vgmerge merges two existing VGs. The inactive source VG is merged into the
destination VG if physical extent sizes are equal and PV and LV summaries
of both VGs fit into the destination VG's limits.

View File

@@ -1,5 +0,0 @@
vgmknodes checks the LVM device nodes in /dev that are needed for active
LVs and creates any that are missing and removes unused ones.
This command should not usually be needed if all the system components are
interoperating correctly.

View File

@@ -1 +0,0 @@
vgreduce removes one or more unused PVs from a VG.

View File

@@ -1,6 +0,0 @@
vgremove removes one or more VGs. If LVs exist in the VG, a prompt is used
to confirm LV removal.
If one or more PVs in the VG are lost, consider
\fBvgreduce \-\-removemissing\fP to make the VG
metadata consistent again.

View File

@@ -1,9 +0,0 @@
vgrename renames a VG.
All VGs visible to a system need to have different names, otherwise many
LVM commands will refuse to run or give warning messages. VGs with the
same name can occur when disks are moved between machines, or filters are
changed. If a newly connected disk has a VG with the same name as the VG
containing the root filesystem, the machine may not boot correctly. When
two VGs have the same name, the VG UUID can be used in place of the source
VG name.

View File

@@ -1 +0,0 @@
vgs produces formatted output about VGs.

View File

@@ -1 +0,0 @@
vgscan scans all supported LVM block devices in the system for VGs.

View File

@@ -1,13 +1,18 @@
vgsplit moves one or more PVs from a source VG to a destination VG. The
.SH NOTES
.
.IP \[bu] 3
vgsplit moves one or more PVs from a source VG to a destination VG. The
PVs can be specified explicitly or implicitly by naming an LV, in which
case on PVs underlying the LV are moved.
.IP \[bu] 3
If the destination VG does not exist, a new VG is created (command options
can be used to specify properties of the new VG, also see
\fBvgcreate\fP(8).)
can be used to specify properties of the new VG.)
.IP \[bu] 3
LVs cannot be split between VGs; each LV must be entirely on the PVs in
the source or destination VG.
vgsplit can only move complete PVs. (See \fBpvmove\fP(8) for moving part
of a PV.)
.IP \[bu] 3
vgsplit can only move complete PVs. (See pvmove for moving part of a PV.)

View File

@@ -1413,10 +1413,10 @@ have_raid() {
}
have_raid4 () {
local r=0
local r=1
have_raid 1 8 0 && r=1
have_raid 1 9 1 && r=0
have_raid 1 8 0 && r=0
have_raid 1 9 1 && r=1
return $r
}

View File

@@ -1,72 +0,0 @@
#!/bin/sh
# Copyright (C) 2017 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# unrelated to lvm2 daemons
SKIP_WITH_LVMLOCKD=1
SKIP_WITH_LVMPOLLD=1
SKIP_WITH_CLVMD=1
SKIP_WITH_LVMETAD=1
. lib/inittest
CIPHER=aes-xts-plain64
HEXKEY_32=0102030405060708090a0102030405060102030405060708090a010203040506
HIDENKEY_32=0000000000000000000000000000000000000000000000000000000000000000
KEY_NAME="$PREFIX:keydesc"
function _teardown() {
keyctl unlink %:$PREFIX-keyring
aux teardown_devs_prefixed $PREFIX
}
aux target_at_least dm-zero 1 0 0 || skip "missing dm-zero target"
aux target_at_least dm-crypt 1 15 0 || skip "dm-crypt doesn't support keys in kernel keyring service"
which keyctl || skip "test requires keyctl utility"
keyctl newring $PREFIX-keyring @u
keyctl timeout %:$PREFIX-keyring 60
trap '_teardown' EXIT
keyctl add logon $KEY_NAME ${HEXKEY_32:0:32} %:$PREFIX-keyring
dmsetup create $PREFIX-zero --table "0 1 zero"
# put key in kernel keyring for active table
dmsetup create $PREFIX-crypt --table "0 1 crypt $CIPHER :32:logon:$KEY_NAME 0 $TESTDIR/dev$prefix/mapper/$PREFIX-zero 0"
# put hexbyte key in dm-crypt directly in inactive table
dmsetup load $PREFIX-crypt --table "0 1 crypt $CIPHER $HEXKEY_32 0 $TESTDIR/dev$prefix/mapper/$PREFIX-zero 0"
# test dmsetup doesn't hide key descriptions...
str=`dmsetup table $PREFIX-crypt | cut -d ' ' -f 5`
test $str = :32:logon:$KEY_NAME || die
str=`dmsetup table --showkeys $PREFIX-crypt | cut -d ' ' -f 5`
test $str = :32:logon:$KEY_NAME || die
# ...but it hides hexbyte representation of keys...
str=`dmsetup table --inactive $PREFIX-crypt | cut -d ' ' -f 5`
test $str = $HIDENKEY_32 || die
#...unless --showkeys explictly requested
str=`dmsetup table --showkeys --inactive $PREFIX-crypt | cut -d ' ' -f 5`
test $str = $HEXKEY_32 || die
# let's swap the tables
dmsetup resume $PREFIX-crypt
dmsetup load $PREFIX-crypt --table "0 1 crypt $CIPHER :32:logon:$KEY_NAME 0 $TESTDIR/dev$prefix/mapper/$PREFIX-zero 0"
str=`dmsetup table --inactive $PREFIX-crypt | cut -d ' ' -f 5`
test $str = :32:logon:$KEY_NAME || die
str=`dmsetup table --showkeys --inactive $PREFIX-crypt | cut -d ' ' -f 5`
test $str = :32:logon:$KEY_NAME || die
str=`dmsetup table $PREFIX-crypt | cut -d ' ' -f 5`
test $str = $HIDENKEY_32 || die
str=`dmsetup table --showkeys $PREFIX-crypt | cut -d ' ' -f 5`
test $str = $HEXKEY_32 || die

View File

@@ -19,7 +19,7 @@ aux have_raid 1 9 0 || skip
correct_raid4_layout=0
aux have_raid 1 9 1 && correct_raid4_layout=1
aux prepare_vg 8 80
aux prepare_vg 6 80
function _lvcreate
{
@@ -163,7 +163,6 @@ _lvcreate raid4 3 4 64M $vg $lv1
aux wait_for_sync $vg $lv1
# Convert raid4 -> striped
not _lvconvert striped striped 3 $vg $lv1 512k
_lvconvert striped striped 3 $vg $lv1
# Convert striped -> raid4
@@ -196,7 +195,6 @@ _lvconvert raid0_meta raid0_meta 3 $vg $lv1
_lvconvert raid5 raid5_n 4 $vg $lv1
# Convert raid4 -> raid0_meta
not _lvconvert raid0_meta raid0_meta 3 $vg $lv1 256k
_lvconvert raid0_meta raid0_meta 3 $vg $lv1
# Convert raid0_meta -> raid4
@@ -244,30 +242,6 @@ _lvconvert raid0_meta raid0_meta 3 $vg $lv1
# Convert raid0_meta -> raid6_n_6
_lvconvert raid6 raid6_n_6 5 $vg $lv1
# Convert raid6_n_6 -> striped
not _lvconvert striped striped 3 $vg $lv1 128k
_lvconvert striped striped 3 $vg $lv1
# Convert striped -> raid10
_lvconvert raid10 raid10 6 $vg $lv1
# Convert raid10 -> raid0
not _lvconvert raid0 raid0 3 $vg $lv1 64k
_lvconvert raid0 raid0 3 $vg $lv1
# Convert raid0 -> raid10
_lvconvert raid10 raid10 6 $vg $lv1
# Convert raid10 -> raid0
_lvconvert raid0_meta raid0_meta 3 $vg $lv1
# Convert raid0_meta -> raid10
_lvconvert raid10 raid10 6 $vg $lv1
# Convert raid10 -> striped
not _lvconvert striped striped 3 $vg $lv1 256k
_lvconvert striped striped 3 $vg $lv1
# Clean up
lvremove -y $vg

View File

@@ -20,7 +20,7 @@ aux raid456_replace_works || skip
aux lvmconf 'allocation/maximise_cling = 0' \
'allocation/mirror_logs_require_separate_pvs = 1'
aux prepare_vg 8 80
aux prepare_vg 8
function delay
{

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (C) 2012,2017 Red Hat, Inc. All rights reserved.
# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
@@ -16,11 +16,10 @@ SKIP_WITH_LVMPOLLD=1
aux have_raid 1 3 0 || skip
levels="5 6 10"
aux have_raid4 && levels="4 $levels"
aux have_raid 1 7 0 && levels="0 0_meta $levels"
levels="5 6"
aux have_raid4 && levels="4 5 6"
aux prepare_pvs 6
aux prepare_pvs 6 80
vgcreate -s 256K $vg $(cat DEVICES)
@@ -40,10 +39,9 @@ for deactivate in true false; do
#check raid_images_contiguous $vg $lv1
# Extend and reduce 3-striped RAID 4/5/6/10
# Extend and reduce 3-striped RAID 4/5/6
for i in $levels ; do
lvcreate --type raid$i -i 3 -l 3 -n $lv2 $vg
check lv_field $vg/$lv2 "seg_size" "768.00k"
test $deactivate && {
aux wait_for_sync $vg $lv2
@@ -51,12 +49,10 @@ for deactivate in true false; do
}
lvresize -l +3 $vg/$lv2
check lv_field $vg/$lv2 "seg_size" "1.50m"
#check raid_images_contiguous $vg $lv1
should lvresize -y -l -3 $vg/$lv2
should check lv_field $vg/$lv2 "seg_size" "768.00k"
#check raid_images_contiguous $vg $lv1

View File

@@ -19,7 +19,6 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@@ -1317,12 +1316,6 @@ int define_commands(void)
return 0;
}
/*
* FIXME: when running one specific command name,
* we can optimize by not parsing command defs
* that don't start with that command name.
*/
cmd = &commands[cmd_count];
cmd->command_index = cmd_count;
cmd_count++;
@@ -2527,27 +2520,7 @@ static char *upper_command_name(char *str)
return str_upper;
}
static void include_description_file(char *name, char *des_file)
{
char buf[1024 * 1024];
int fd;
memset(buf, 0, sizeof(buf));
fd = open(des_file, O_RDONLY);
if (fd < 0)
return;
read(fd, buf, sizeof(buf) - 1);
printf(".SH DESCRIPTION\n");
printf("%s\n", buf);
close(fd);
}
void print_man(char *name, char *des_file, int include_primary, int include_secondary)
void print_man(char *name, int include_primary, int include_secondary)
{
struct command_name *cname;
struct command *cmd, *prev_cmd = NULL;
@@ -2596,8 +2569,8 @@ void print_man(char *name, char *des_file, int include_primary, int include_seco
printf("%s \\- %s\n", lvmname, cname->desc);
else
printf("%s\n", lvmname);
printf(".br\n");
printf(".P\n");
printf(".\n");
printf(".SH SYNOPSIS\n");
printf(".br\n");
@@ -2641,11 +2614,6 @@ void print_man(char *name, char *des_file, int include_primary, int include_seco
printf("\n");
}
if (des_file) {
include_description_file(lvmname, des_file);
printf(".P\n");
}
printf(".SH USAGE\n");
printf(".br\n");
printf(".P\n");
@@ -2681,13 +2649,13 @@ int main(int argc, char *argv[])
memset(&commands, 0, sizeof(commands));
if (argc < 2) {
log_error("Usage: %s <command> [/path/to/description-file]", argv[0]);
log_error("Usage: %s <command>", argv[0]);
exit(EXIT_FAILURE);
}
define_commands();
print_man(argv[1], (argc > 2) ? argv[2] : NULL, 1, 1);
print_man(argv[1], 1, 1);
return 0;
}

View File

@@ -2197,15 +2197,8 @@ static int _status(CMD_ARGS)
c++;
if (*c)
c++;
/*
* Do not suppress kernel key references prefixed
* with colon ':'. Displaying those references is
* harmless. crypt target supports kernel keys
* starting with v1.15.0 (merged in kernel 4.10)
*/
if (*c != ':')
while (*c && *c != ' ')
*c++ = '0';
while (*c && *c != ' ')
*c++ = '0';
}
printf(FMTu64 " " FMTu64 " %s %s",
start, length, target_type, params);