1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-29 06:57:46 +03:00

Compare commits

..

137 Commits

Author SHA1 Message Date
Heinz Mauelshagen
8ab0725077 lvchange: reject writemostly/writebehind on raid1 during resync
The MD kernel raid1 personality does no use any writemostly leg as the primary.

In case a previous linear LV holding data gets upconverted to
raid1 it becomes the primary leg of the new raid1 LV and a full
resynchronization is started to update the new legs.

No writemostly and/or writebehind setting may be allowed during
this initial, full synchronization period of this new raid1 LV
(using the lvchange(8) command), because that would change the
primary (i.e the previous linear LV) thus causing data loss.

lvchange has a bug not preventing this scenario.

Fix rejects setting writemostly and/or writebehind on resychronizing raid1 LVs.

Once we have status in the lvm2 metadata about the linear -> raid upconversion,
we may relax this constraint for other types of resynchronization
(e.g. for user requested "lvchange --resync ").

New lvchange-raid1-writemostly.sh test is added to the test suite.

Resolves: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=855895
2017-02-23 15:09:29 +01:00
David Teigland
3f4ecaf8c2 man/help: improve the style of units indicator
We use --foo Number[k|Units] to indicate that
the default units of the number is k, but other
units listed below are also accepted.

Capitalize and underline Units so it is consistent
with other variables, and reference it at the end.

Technically, the k should be bold, but this
tends to make the text visually hard to read
because of the excessive highlights scattered
everywhere.  So it's left normal text for now
(it's unlikely to confuse anyone.)
2017-02-22 16:50:30 -06:00
David Teigland
da634bfc89 man: indicate repeatable options
Print ... after a repeatable option in the OPTIONS section.
An alternative would be to just mention in the text description
that the option is repeatable.
2017-02-22 16:38:54 -06:00
David Teigland
1eb1869626 man: improve writemostly PV arg 2017-02-22 15:20:44 -06:00
Zdenek Kabelac
aa72caca5a tests: support zero_dev
When the test would need to try to write some large amount of data
we can give it 'zero' segments - for obvious reason such written data
can't be verified but in some test cases it doesn't really matter.

Usage follows  'error_dev' style.

For now test suite is not supporting any combination of
error/delay/zero segments so only 1 type could be used per PV.
2017-02-22 15:40:59 +01:00
Zdenek Kabelac
f44e69f9fc tests: not slowing work with metadata
Slows only data extents on a PV.
2017-02-22 15:40:28 +01:00
Zdenek Kabelac
9712995edd snapshot: improve removal of active origin volume
Previously when lvremove tried to remove 'active' origin,
it had been asking for every 'snapshot' LV separately
and doing individual single snapshot removals first.

To be faster it now deactivates origin before removal
all connected snapshots.

This avoids multiple reloads of dm table for origin volume
which were unnecessary as origin was meant to be removed as well.
2017-02-22 15:35:04 +01:00
Zdenek Kabelac
6716f5a2f4 WHATS_NEW: add entry 2017-02-22 15:20:52 +01:00
David Teigland
263050bc07 man/help: enclose each option in brackets
Placing [] around each individual option is the most
common style, and it improves the readability.
2017-02-21 14:59:52 -06:00
David Teigland
c1ce371b59 man/help: use separate common option lists
There are two kinds of common options:
1. options common to all variants of a given command name
2. options common to all lvm commands

Previously, both kinds of common options were listed together
under "Common options".  Now the first are printed under
"Common options for command" (when needed), and the second
are printed under "Common options for lvm" (always).
2017-02-21 14:32:54 -06:00
David Teigland
b7ae57c6a6 man: teaking output format 2017-02-21 12:27:51 -06:00
David Teigland
21fc35dd1b commands: adjust default help output
Remove the "usage notes" which should just
live in the man pages.

When there are 3 or more variants of a command,
print all the options produces a lot of output,
so require --longhelp to print all the options
in these cases.
2017-02-21 12:27:51 -06:00
David Teigland
7e411b111f man lvm: update see also list
add several missing references
remove references to lvmdiskscan lvmchange
2017-02-21 12:27:51 -06:00
David Teigland
f80d373753 man: expand type option description 2017-02-21 12:27:51 -06:00
Alasdair G Kergon
d2dbe71fb3 dmsetup: Indicate device repetition in usage summaries. 2017-02-21 11:25:18 +00:00
Zdenek Kabelac
1c1ce2739e tests: some debug code
Checking if --deferred would make it any faster - but it's as slow
as without this new optional flag anyway (4.10).
2017-02-21 09:40:21 +01:00
Zdenek Kabelac
2a65e2d49e tests: ensure first call is version test
Check 'dmsetup version'  is called before starting any more
advanced logic in $DM_DEV_DIR.

Call also replaces mkdir as it creates needed path with control node.
2017-02-21 09:38:49 +01:00
Zdenek Kabelac
7c14004f69 tests: make sure which PV is used for allocation 2017-02-21 09:38:04 +01:00
Zdenek Kabelac
d409fec079 tests: paralelize creation and teardown
To speedup initial construction and destruction of test devices
(mainly in case more then 1 is needed)  call dmsetup
in parallel.
2017-02-21 00:52:05 +01:00
Zdenek Kabelac
921d5972e8 tests: use exclusive activation for mirror
Test suite does not support clustered mirroring.
2017-02-21 00:52:05 +01:00
David Teigland
86a660be7b man: use .HP instead of .TP 2017-02-20 17:10:11 -06:00
David Teigland
e13639053b man/help: print general raid type as "raid"
Instead of printing "raid*".  There are already
notes mentioning that "raid" refers to "raid<N>"
2017-02-20 15:41:24 -06:00
David Teigland
d22cccdf63 man vgchange/lvchange: note special option usage 2017-02-20 15:36:30 -06:00
David Teigland
a2d2cd8777 man lvcreate: add special option notes at the start
The --name, --size, --extents options deserve a special
note at the start of the man page, before appearing in
the usage section.
2017-02-20 15:36:30 -06:00
David Teigland
2396c50689 man: add variables descriptions
Add a section describing variables.

In the full options list, include common
options in the alphabetical listing instead
of at the end.
2017-02-20 15:36:10 -06:00
David Teigland
4d29d9afb2 lvresize/lvextend: accept type option
The --type option has previously been accepted for
lvresize/lvextend.  Using it did not affect the operation
of the command.  The value was simply verified as matching
the current seg type of the LV.
2017-02-20 11:23:46 -06:00
Zdenek Kabelac
5f2639d01d tests: update lvresize testing
Add missing tests for some lvresize acceptable options.
2017-02-20 00:44:12 +01:00
Zdenek Kabelac
13dd1ca757 cleanup: simplier code
Already know string is 'lvm-' so use name[3].
2017-02-20 00:43:40 +01:00
Zdenek Kabelac
2260c6d1e6 cleanup: same sign for compare 2017-02-20 00:43:40 +01:00
Zdenek Kabelac
d8514b24e1 cleanup: use multiline string 2017-02-20 00:43:40 +01:00
Zdenek Kabelac
aff62c74b7 cleanup: use const 2017-02-20 00:43:40 +01:00
Zdenek Kabelac
f16ad760cb man: thin dmeventd plugin update
Document new dmeventd/thin_command lvm.conf configurable.
2017-02-20 00:43:12 +01:00
Zdenek Kabelac
cd24e6de89 man: dmstats update
Fixing colorization bugs
2017-02-19 22:59:43 +01:00
Zdenek Kabelac
665479b818 man: dmsetup update 2017-02-19 22:59:43 +01:00
Zdenek Kabelac
2a21a19d90 commands: fix memleak
Keep all allocations 'mempool' allocated for simple cleanup.
2017-02-19 22:59:43 +01:00
Zdenek Kabelac
87c89ac279 lvresize: fix regressiong on accepting args
Commit f45b689406 caused regression
of lvresize -m and --type  parameter

After fix this sequence may work when we also fix syntax description:

lvcreate -l1 -m1 -n lv1 vg
lvextend --type mirror -m1 -l+1 vg/lv1
2017-02-19 22:59:43 +01:00
David Teigland
13944738d4 man/help: fix description of r|R unit 2017-02-17 15:44:26 -06:00
David Teigland
fab0d63121 man: print space before built-in name
print 'lvm config' not 'lvm-config'
2017-02-17 15:33:35 -06:00
David Teigland
87fe9328d3 man pvmove: move details to notes 2017-02-17 15:28:00 -06:00
David Teigland
6064b0359a man: mention force behavior in various places 2017-02-17 15:11:19 -06:00
David Teigland
50e0345f9d man lvmconfig: refer to typeconfig option name 2017-02-17 14:46:10 -06:00
David Teigland
10cb8e0ec0 man/help: show recently added r|R unit 2017-02-17 14:44:11 -06:00
David Teigland
3cf3943898 args: in yes option mention qq for auto-no 2017-02-17 14:44:11 -06:00
David Teigland
f88ce5fb99 lvconvert: include swap behavior in generic pool syntax
For this syntax:
lvconvert --thinpool LV1 --poolmetadata LV2
lvconvert --cachepool LV1 --poolmetadata LV2

Restore the metadata swapping behavior in addition to
the pool creation behavior.  When LV1 is already a pool,
the metadata LV will be swapped with LV2.
When LV1 is not a pool, it will be converted to a
pool using the specified LV for metadata.

This syntax is no longer advertised because of the
ambiguous behavior.  The primary syntaxes for pool
creation and metadata swapping will be the advertised
methods.
2017-02-17 13:20:15 -06:00
Zdenek Kabelac
56deed9d54 commands: compensate --uuid
As we now user binary search - it's nondeterministict
which of the same 'args' will be give - so duplicates
need 'extra' care.

So provide same hack for output for --uuidstr_ARG as
for input.

Solves 'pvscan -u'.
2017-02-17 13:57:59 +01:00
Zdenek Kabelac
00f299b932 commands: some more dm wrappers
As man-generator is not liked with libdm as of now - some more wrappers.
2017-02-17 13:36:57 +01:00
Zdenek Kabelac
238a79aac4 cleanup: unused uninit vars 2017-02-17 13:20:55 +01:00
Zdenek Kabelac
995f7aa92f cleanup: use strchr for 1-byte lookup 2017-02-17 13:20:55 +01:00
Zdenek Kabelac
46d6c7d3ad cleanup: add comment for longer macro 2017-02-17 13:20:55 +01:00
Zdenek Kabelac
772834e40a commands: optimize binary search
Since there is a lot of options and lot of searches,
use binary search to keep strcmp at minimum.

The interesting part is - alphabetically sorted array contains
duplicates and some of them are not the 'right anwer', so
after we find matching string but not matching long_ARG,
we may need to check if the surrouding strings are the right matching
one.

The single loops is used also for strictly define --foo_long
(i.e. --stripes)  and just differs at final part.

TODO1: replace strstr call with some flag (just like short_opt).
TODO2: drop '--' from being stored and tests by strcmp.
2017-02-17 13:20:55 +01:00
Zdenek Kabelac
582a272b3f commands: use dm_strncpy
Easier code using dm_strncpy() an dm_snprintf().
2017-02-17 13:11:33 +01:00
Zdenek Kabelac
80b717af0c commands: cheap optimisation for parser
Some low-hanging fruits to cut of signification number of strcmp calls.
2017-02-17 13:00:05 +01:00
David Teigland
298b11aed1 commands: track errors in command def parsing
When parsing command defs, track and report all
errors that are found.  Add an error return case
from define_commands so the standard error exit
path is used.
2017-02-16 15:26:42 -06:00
David Teigland
1cb95fa5a0 commands: initialize commands[] once
When using liblvm2cmd, a process can do multiple
init/exit calls, i.e.

lvm2_init(); lvm2_run(); lvm2_exit();
lvm2_init(); lvm2_run(); lvm2_exit();
...

define_commands() needs to set up the global commands[]
definitions only the first time.
2017-02-16 13:59:52 -06:00
David Teigland
15f51bc421 commands: avoid factoring options until needed 2017-02-16 09:37:28 -06:00
David Teigland
22bee4fbdb help/man: remove commas from list of options
Using commas between options does not seem to
be done anywhere else, so remove them.
2017-02-15 15:51:46 -06:00
David Teigland
81c0ed9fc6 commands: use dm wrappers for malloc/free 2017-02-15 15:49:18 -06:00
David Teigland
6a5c9ba349 commands: use existing vg/lv name parsing functions
inside the new lv arg parsing function.

This includes getting the VG name from the env var,
and some added checks on the format of the vg/lv string.
2017-02-15 15:28:54 -06:00
David Teigland
2556498ee1 lvcreate: fix LVM_VG_NAME detection
Commit d3af0e7528 was
not quite right in testing if the env var was set.
2017-02-15 14:10:46 -06:00
David Teigland
4a30f5f9b0 toollib: skip dev prefix from lv names
_get_arg_lvnames_using_options() was missing skip_dev_dir()
2017-02-15 13:42:35 -06:00
David Teigland
286d39ee3c lvconvert: handle old arg quirk when combining snapshot
The old ad hoc arg parsing when combining a split snapshot
allowed the first lv to have a vgname, but not the second.
Since lvconvert now uses the standard arg parsing in
process_each_lv(), the old one-off behavior requires a
work around.
2017-02-15 12:40:35 -06:00
David Teigland
d3af0e7528 lvcreate: LVM_VG_NAME applies even without name arg
There was a small flaw in the logic regarding when LVM_VG_NAME
can replace a VG position arg.
2017-02-15 12:07:51 -06:00
David Teigland
7417c8acfa Revert "lvconvert: enable previous syntax to swap metadata"
This reverts commit 717363bb94.

These alternate forms for swapping metadata cannot be
distinguished from the command for creating a pool.
If we were to add these alternate forms for swapping
metadata, we would need to overload the pool creation
command defs, making those definitions ambiguous.
2017-02-14 16:02:54 -06:00
David Teigland
d2c5bb5c70 coverity cleanups 2017-02-14 15:53:29 -06:00
David Teigland
1236e0ed29 man-generator: fix compiler warnings 2017-02-14 10:28:52 -06:00
David Teigland
1dddb068c9 man/help: use separator in units list
h|H|b|B|... instead of hHbB...
2017-02-14 10:21:39 -06:00
David Teigland
c0f2a59993 commands: skip parsing command defs for other command names
The base command name can be used to skip parsing
command defs that will not be needed.
2017-02-14 10:16:13 -06:00
David Teigland
f46b28bdb6 commands: improve help/usage output
Replace --help --help with --long-help.
Some blank lines were needed.
Add 'lvm help all' to print help for all commands.
2017-02-14 09:52:09 -06:00
Alasdair G Kergon
c868562a79 Makefile: all_man also requires man-generator now 2017-02-14 13:24:31 +00:00
Zdenek Kabelac
22457ed4d9 makefiles: missing deps 2017-02-14 10:24:56 +01:00
Zdenek Kabelac
fc0e49297d makefiles: use configure vars
Use binaries found in configure.
2017-02-14 10:24:56 +01:00
Zdenek Kabelac
3350eb67cc libdm: move code for _stats_resize_group
Code is only needed when "fiemap.h" so keep it under single #ifdef.
2017-02-14 10:24:56 +01:00
Zdenek Kabelac
6118b0fb93 configure: update 2017-02-14 00:05:04 +01:00
Zdenek Kabelac
65b82a8072 activation: trust 'pending' status reported by dmeventd
Only usleep when dmeventd reports 'pending' otherwise trust reported
state.
2017-02-14 00:04:26 +01:00
Zdenek Kabelac
05dd566a52 dmeventd: unify error handling
Always make sure the 'status' is release on 'error' path (thin pluging missed)
Make code looking same across all plugins.
2017-02-14 00:03:34 +01:00
David Teigland
5a87d8667d coverity cleanups for recent command defs commits 2017-02-13 16:11:04 -06:00
David Teigland
5ab051df7a WHATS_NEW: changes for recent command defs 2017-02-13 15:36:17 -06:00
David Teigland
c816e8b636 WHATS_NEW: items from command definitions patch set 2017-02-13 15:22:26 -06:00
David Teigland
717363bb94 lvconvert: enable previous syntax to swap metadata 2017-02-13 14:41:54 -06:00
David Teigland
b2fd5b31d3 commands: suggest --help if command doesn't match 2017-02-13 13:46:17 -06:00
David Teigland
698abdde16 generate man pages 2017-02-13 10:31:23 -06:00
David Teigland
13a6368522 args: use arg parsing function for region size
Consolidate the validation of the region size arg
in a new arg parsing function.
2017-02-13 08:21:58 -06:00
David Teigland
a1386dcca0 lvconvert: remove code for changing region size
from the generic raid type conversion code.
2017-02-13 08:21:58 -06:00
David Teigland
46abc28a48 lvconvert: add command to change region size of a raid LV 2017-02-13 08:21:58 -06:00
David Teigland
8152e4a99e vgchange: fix uint32 parsing of logicalvolume arg 2017-02-13 08:20:10 -06:00
David Teigland
2224b6a701 commands: recognize raid variations 2017-02-13 08:20:10 -06:00
David Teigland
c3faa5816d commands: move command def parsing into lvm binary
It was previously done at build time by the ccmd binary.
2017-02-13 08:20:10 -06:00
David Teigland
942dc07402 lvconvert: remove unused code
For "split" which is not an alias for splitmirrors.
2017-02-13 08:20:10 -06:00
David Teigland
f067c0ad78 args: split is a synonym for splitcache
also tidy the other synonyms
2017-02-13 08:20:10 -06:00
David Teigland
c3e1838382 man: lvmthin updates
Some minor changes to some of the command syntaxes
to use more standard forms.
2017-02-13 08:20:10 -06:00
David Teigland
15d9f2850e ccmd: split into multiple files 2017-02-13 08:20:10 -06:00
David Teigland
013c080756 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-13 08:20:10 -06:00
David Teigland
d9d5b8414b command.h comment tidying 2017-02-13 08:20:10 -06:00
David Teigland
9a0f0c70bf lvm shell: clear argv for each command 2017-02-13 08:20:10 -06:00
David Teigland
23a1ced439 help: accept positional args
lvm help <commandname> ...
2017-02-13 08:20:10 -06:00
David Teigland
3642deb4f3 fix lvmcmdline warning
declaration of ‘usage’ shadows a globa
2017-02-13 08:20:10 -06:00
David Teigland
4d2c3502e7 man lvm: remove options
all options are now included in commands
2017-02-13 08:20:10 -06:00
David Teigland
5c779b3231 args: add man page descriptions 2017-02-13 08:20:10 -06:00
David Teigland
db26a82f2f args: use uint32 arg for maxphysicalvolumes 2017-02-13 08:20:10 -06:00
David Teigland
041c2fef88 lvconvert: remove unused code 2017-02-13 08:20:10 -06:00
David Teigland
46b2599d5c 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-13 08:20:10 -06:00
David Teigland
a801b92b2c tests: use swapmetadata
and some other pool/cache/thin related changes
2017-02-13 08:20:10 -06:00
David Teigland
86d8ab493b lvconvert: use command defs for mergemirrors
and route the generic --merge to one of the
specific merge functions
2017-02-13 08:20:10 -06:00
David Teigland
95e38607ec toollib: find VG name in option values when needed 2017-02-13 08:20:10 -06:00
David Teigland
0e3e611a13 lvconvert: use command defs for thin/cache/pool creation
Everything related to thin and cache.
2017-02-13 08:20:10 -06:00
David Teigland
d71aaca07b 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-13 08:20:10 -06:00
David Teigland
fa2a728a39 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-13 08:20:10 -06:00
David Teigland
254bffb95d 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-13 08:20:10 -06:00
David Teigland
35b9d4d6e9 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-13 08:20:10 -06:00
David Teigland
52c60b7e7b 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-13 08:20:10 -06:00
David Teigland
9c6c55c314 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-13 08:20:10 -06:00
David Teigland
1e2420bca8 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-13 08:20:10 -06:00
David Teigland
19267fa6aa 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-13 08:20:10 -06:00
Zdenek Kabelac
2923d9e47d tests: update 2017-02-13 10:06:19 +01:00
Zdenek Kabelac
c3b1f1a07a tests: fix dev path
Use proper device path for test devices.
Use mkfs.ext4 and drop  'echo y|' to it.
Use smaller device size to consume less memory and CPU time.
2017-02-13 10:06:19 +01:00
Zdenek Kabelac
a3579aafc5 cleanup: use matching signed number comparation 2017-02-13 10:06:19 +01:00
Zdenek Kabelac
7cbee8f31a cleanup: use matching const type 2017-02-13 10:06:18 +01:00
Zdenek Kabelac
b6301aa977 cleanup: use fall through
gcc gets 'selective' on having commented fall through case.
2017-02-13 10:06:18 +01:00
Zdenek Kabelac
a39c828c01 cleanup: fix warning about shadowed declaration
Avoid shadowing lv_size as lv_size() is already defined function in lv.h
2017-02-13 10:06:18 +01:00
Zdenek Kabelac
717d0c6b94 cleanup: use proper printf specifier 2017-02-13 10:06:18 +01:00
Zdenek Kabelac
b185a3e333 config: update doc 2017-02-13 10:06:07 +01:00
Zdenek Kabelac
aa0c735e2c dmeventd: limit thin_command usage
Require usable command string to begining with '/'
So 'thin_command = "/some/path/command"' is the only supported variant
to internal 'lvm' command.
2017-02-13 09:43:53 +01:00
Zdenek Kabelac
416f951283 coverity: fix double free
Do not try to free hist_arg twice.
2017-02-12 17:28:44 +01:00
Zdenek Kabelac
a7d2ee4bc2 coverity: fix mem leak on error path in dm stats
Free allocated resouces on error path.
2017-02-12 17:28:13 +01:00
Zdenek Kabelac
0844b20f98 coverity: remove unneeded header files 2017-02-11 21:17:27 +01:00
Zdenek Kabelac
375e38709c cleanup: drop double const specifier
Remove duplicated 'const' specifier.
Reindent.
2017-02-11 20:30:16 +01:00
Zdenek Kabelac
2a9eda1229 mem: add extra mem pages for pthread stack
Some archs can use even 64K pages and then lvm2 runs into trouble if
the stack is 'too small' to fit extra page capturing stack overwrite.

So when lvm2 limits stack - add extra mem page - be it 4K or 64K.

Relates to ppc64le bug: https://bugzilla.redhat.com/1387279
2017-02-11 18:23:15 +01:00
Heinz Mauelshagen
8296b99a89 lvconvert: remove test code
Remove allocate_pvs from raid_manip.c:_region_size_change_request() API
and lv_extend() using it added for temporary test purpose.

Related: rhbz1366296
2017-02-10 23:44:27 +01:00
Heinz Mauelshagen
28ea66d46d lvconvert: add region size checks
Add:
- region size checks to raid_manip.c types array and supporting functions
- tests to lvconvert-raid-takeover.sh to check bogus
  "lvconvert --type  --regionsize N " requests

Related: rhbz1366296
2017-02-10 23:37:08 +01:00
Heinz Mauelshagen
caa2094e33 test: lvresize-raid.sh missing conditional
Test missed to check for raid0 present in the kernel.

Related: rhbz1366296
2017-02-10 21:22:38 +01:00
Zdenek Kabelac
c908a8b131 libdm: avoid resume if preloaded device is smaller
When we preload device with smaller size, we avoid its resume,
so later suspend/resume of full device tree my process all
existing in flight bios.

Also update comment and avoid using confusing opposite meaning.
2017-02-10 20:29:11 +01:00
Ondrej Kozina
035c614c19 dmsetup: do not suppress kernel key descriptions in tables
Kernel 4.10 (dm-crypt v1.15.0) and later supports loading device
tables with crypt segment having key in kernel keyring retention
service.

dmsetup hid key section of tables output. With this patch dmsetup
no longer hides key section if it detects kernel key description
instead of hex byte representation of key itself.
2017-02-10 19:18:49 +01:00
Heinz Mauelshagen
baba3f8e2a lvconvert: add conversion from/to raid10
Add:
- conversion support from striped/raid0/raid0_meta to/from raid10;
  raid10 goes by the near format (same as used in creation of
  raid10 LVs), which groups data copies together with their original
  blocks (e.g. 3-way striped, 2 data copies resulting in 112233 in the
  first stripe followed by 445566 in the second etc.) and is limited
  to even numbers of legs for now
- related tests to lvconvert-raid-takeover.sh
- typo

Related: rhbz1366296
2017-02-10 19:13:02 +01:00
Bryn M. Reeves
68ec6940e6 man: mention dmstats in lvmsar and lvmsadc man pages 2017-02-10 17:09:17 +00:00
Heinz Mauelshagen
55eaabd118 lvreduce/lvresize: add ability to reduce the size of a RaidLV
- support shrinking of raid0/1/4/5/6/10 LVs
- enhance lvresize-raid.sh tests: add raid0* and raid10
- fix have_raid4 in aux.sh to allow lv_resize-raid.sh
  and other scripts to test raid4

Resolves: rhbz1394048
2017-02-09 22:42:03 +01:00
Heinz Mauelshagen
79f31008fa lvconvert: add support to change RAID region size (fixup)
Commit cfb6ef654d introduced
support to change RAID region size.

Fix:
- don't change region_size until after prompting the user
- use log_print_unless_silent() instead of log_warn()
- avoid superfluous sigint() calls which are already
  covered in yes_no_prompt()
- typo

Related: rhbz1392947
2017-02-07 19:05:01 +01:00
Heinz Mauelshagen
69fe8729f3 lvconvert: avoid setting segment flag
Fix:
- don't set SEG_RAID in _convert_mirror_to_raid1() errounously

Related: rhbz1366296
2017-02-07 17:48:17 +01:00
108 changed files with 2582 additions and 1094 deletions

View File

@@ -59,6 +59,8 @@ liblvm: lib
daemons: lib libdaemon tools
tools: lib libdaemon device-mapper
po: tools daemons
man: tools
all_man: tools
scripts: liblvm libdm
lib.device-mapper: include.device-mapper

View File

@@ -1,5 +1,22 @@
Version 2.02.169 -
=====================================
Reject writemostly/writebehind in lvchange during resynchronization.
Deactivate active origin first before removal for improved workflow.
Fix regression of accepting options --type and -m with lvresize (2.02.158).
Add lvconvert --swapmetadata, new specific way to swap pool metadata LVs.
Add lvconvert --startpoll, new specific way to start polling conversions.
Add lvconvert --mergethin, new specific way to merge thin snapshots.
Add lvconvert --mergemirrors, new specific way to merge split mirrors.
Add lvconvert --mergesnapshot, new specific way to combine cow LVs.
Split up lvconvert code based on command definitions.
Split up lvchange code based on command definitions.
Generate help output and man pages from command definitions.
Verify all command line items against command definition.
Match every command run to one command definition.
Specify every allowed command definition/syntax in command-lines.in.
Add extra memory page when limiting pthread stack size in clvmd.
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,5 +1,8 @@
Version 1.02.138 -
=====================================
Add extra memory page when limiting pthread stack size in dmeventd.
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

@@ -2054,6 +2054,7 @@ dmeventd {
# or metadata volume gets above 50%.
# Command which starts with 'lvm ' prefix is internal lvm command.
# You can write your own handler to customise behaviour in more details.
# User handler is specified with the full path starting with '/'.
# This configuration option has an automatic default value.
# thin_command = "lvm lvextend --use-policies"

198
configure vendored
View File

@@ -821,6 +821,8 @@ HAVE_PIE
POW_LIB
LIBOBJS
ALLOCA
SORT
WC
CHMOD
CSCOPE_CMD
CFLOW_CMD
@@ -5234,6 +5236,202 @@ else
CHMOD="$ac_cv_path_CHMOD"
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}wc", so it can be a program name with args.
set dummy ${ac_tool_prefix}wc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_WC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $WC in
[\\/]* | ?:[\\/]*)
ac_cv_path_WC="$WC" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_WC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
WC=$ac_cv_path_WC
if test -n "$WC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $WC" >&5
$as_echo "$WC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_path_WC"; then
ac_pt_WC=$WC
# Extract the first word of "wc", so it can be a program name with args.
set dummy wc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_WC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_WC in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_WC="$ac_pt_WC" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_WC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ac_pt_WC=$ac_cv_path_ac_pt_WC
if test -n "$ac_pt_WC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_WC" >&5
$as_echo "$ac_pt_WC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_pt_WC" = x; then
WC=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
WC=$ac_pt_WC
fi
else
WC="$ac_cv_path_WC"
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}sort", so it can be a program name with args.
set dummy ${ac_tool_prefix}sort; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_SORT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $SORT in
[\\/]* | ?:[\\/]*)
ac_cv_path_SORT="$SORT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_SORT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
SORT=$ac_cv_path_SORT
if test -n "$SORT"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SORT" >&5
$as_echo "$SORT" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_path_SORT"; then
ac_pt_SORT=$SORT
# Extract the first word of "sort", so it can be a program name with args.
set dummy sort; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_SORT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_SORT in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_SORT="$ac_pt_SORT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_SORT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ac_pt_SORT=$ac_cv_path_ac_pt_SORT
if test -n "$ac_pt_SORT"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_SORT" >&5
$as_echo "$ac_pt_SORT" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_pt_SORT" = x; then
SORT=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
SORT=$ac_pt_SORT
fi
else
SORT="$ac_cv_path_SORT"
fi
################################################################################
ac_header_dirent=no

View File

@@ -86,6 +86,8 @@ AC_PROG_RANLIB
AC_PATH_TOOL(CFLOW_CMD, cflow)
AC_PATH_TOOL(CSCOPE_CMD, cscope)
AC_PATH_TOOL(CHMOD, chmod)
AC_PATH_TOOL(WC, wc)
AC_PATH_TOOL(SORT, sort)
################################################################################
dnl -- Check for header files.

View File

@@ -517,7 +517,7 @@ int main(int argc, char *argv[])
/* Initialise the LVM thread variables */
dm_list_init(&lvm_cmd_head);
if (pthread_attr_init(&stack_attr) ||
pthread_attr_setstacksize(&stack_attr, STACK_SIZE)) {
pthread_attr_setstacksize(&stack_attr, STACK_SIZE + getpagesize())) {
log_sys_error("pthread_attr_init", "");
exit(1);
}

View File

@@ -468,7 +468,7 @@ static int _pthread_create_smallstack(pthread_t *t, void *(*fun)(void *), void *
/*
* We use a smaller stack since it gets preallocated in its entirety
*/
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE + getpagesize());
/*
* If no-one will be waiting, we need to detach.

View File

@@ -184,16 +184,12 @@ int register_device(const char *device,
goto_bad;
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
"lvscan --cache", device)) {
dmeventd_lvm2_exit_with_pool(state);
"lvscan --cache", device))
goto_bad;
}
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --repair --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
"lvconvert --repair --use-policies", device))
goto_bad;
}
*user = state;
@@ -203,6 +199,9 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor mirror %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -140,10 +140,8 @@ int register_device(const char *device,
"lvscan --cache", device) ||
!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
"--repair --use-policies", device))
goto_bad;
}
*user = state;
@@ -153,6 +151,9 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor RAID %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -254,10 +254,8 @@ int register_device(const char *device,
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvextend,
sizeof(state->cmd_lvextend),
"lvextend --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
"lvextend --use-policies", device))
goto_bad;
}
state->percent_check = CHECK_MINIMUM;
*user = state;
@@ -268,6 +266,9 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor snapshot %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -18,7 +18,6 @@
#include <sys/wait.h>
#include <stdarg.h>
#include <pthread.h>
/* TODO - move this mountinfo code into library to be reusable */
#ifdef __linux__
@@ -59,8 +58,8 @@ struct dso_state {
int restore_sigset;
sigset_t old_sigset;
pid_t pid;
char **argv;
char cmd_str[1024];
char *argv[3];
char *cmd_str;
};
DM_EVENT_LOG_FN("thin")
@@ -86,7 +85,7 @@ static int _run_command(struct dso_state *state)
} else {
/* For an error event it's for a user to check status and decide */
env[1] = NULL;
log_debug("Error event processing");
log_debug("Error event processing.");
}
log_verbose("Executing command: %s", state->cmd_str);
@@ -116,7 +115,7 @@ static int _use_policy(struct dm_task *dmt, struct dso_state *state)
#if THIN_DEBUG
log_debug("dmeventd executes: %s.", state->cmd_str);
#endif
if (state->argv)
if (state->argv[0])
return _run_command(state);
if (!dmeventd_lvm2_run_with_lock(state->cmd_str)) {
@@ -353,34 +352,41 @@ int register_device(const char *device,
void **user)
{
struct dso_state *state;
int maxcmd;
char *str;
char cmd_str[PATH_MAX + 128 + 2]; /* cmd ' ' vg/lv \0 */
if (!dmeventd_lvm2_init_with_pool("thin_pool_state", state))
goto_bad;
if (!dmeventd_lvm2_command(state->mem, state->cmd_str,
sizeof(state->cmd_str),
"_dmeventd_thin_command", device)) {
dmeventd_lvm2_exit_with_pool(state);
if (!dmeventd_lvm2_command(state->mem, cmd_str, sizeof(cmd_str),
"_dmeventd_thin_command", device))
goto_bad;
}
if (strncmp(state->cmd_str, "lvm ", 4)) {
maxcmd = 2; /* space for last NULL element */
for (str = state->cmd_str; *str; str++)
if (*str == ' ')
maxcmd++;
if (!(str = dm_pool_strdup(state->mem, state->cmd_str)) ||
!(state->argv = dm_pool_zalloc(state->mem, maxcmd * sizeof(char *)))) {
log_error("Failed to allocate memory for command.");
if (strncmp(cmd_str, "lvm ", 4) == 0) {
if (!(state->cmd_str = dm_pool_strdup(state->mem, cmd_str + 4))) {
log_error("Failed to copy lvm command.");
goto bad;
}
} else if (cmd_str[0] == '/') {
if (!(state->cmd_str = dm_pool_strdup(state->mem, cmd_str))) {
log_error("Failed to copy thin command.");
goto bad;
}
dm_split_words(str, maxcmd - 1, 0, state->argv);
/* Find last space before 'vg/lv' */
if (!(str = strrchr(state->cmd_str, ' ')))
goto inval;
if (!(state->argv[0] = dm_pool_strndup(state->mem, state->cmd_str,
str - state->cmd_str))) {
log_error("Failed to copy command.");
goto bad;
}
state->argv[1] = str + 1; /* 1 argument - vg/lv */
_init_thread_signals(state);
} else
memmove(state->cmd_str, state->cmd_str + 4, strlen(state->cmd_str + 4) + 1);
} else /* Unuspported command format */
goto inval;
state->pid = -1;
*user = state;
@@ -388,9 +394,14 @@ int register_device(const char *device,
log_info("Monitoring thin pool %s.", device);
return 1;
inval:
log_error("Invalid command for monitoring: %s.", cmd_str);
bad:
log_error("Failed to monitor thin pool %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -19,10 +19,12 @@
#define MIN_ARGV_SIZE 8
static const char *const const polling_ops[] = { [PVMOVE] = LVMPD_REQ_PVMOVE,
[CONVERT] = LVMPD_REQ_CONVERT,
[MERGE] = LVMPD_REQ_MERGE,
[MERGE_THIN] = LVMPD_REQ_MERGE_THIN };
static const char *const polling_ops[] = {
[PVMOVE] = LVMPD_REQ_PVMOVE,
[CONVERT] = LVMPD_REQ_CONVERT,
[MERGE] = LVMPD_REQ_MERGE,
[MERGE_THIN] = LVMPD_REQ_MERGE_THIN
};
const char *polling_op(enum poll_type type)
{

View File

@@ -1948,16 +1948,13 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
/* Check [un]monitor results */
/* Try a couple times if pending, but not forever... */
for (i = 0; i < 40; i++) {
for (i = 0;; i++) {
pending = 0;
monitored = seg->segtype->ops->target_monitored(seg, &pending);
if (pending ||
(!monitored && monitor) ||
(monitored && !monitor))
log_very_verbose("%s %smonitoring still pending: waiting...",
display_lvname(lv), monitor ? "" : "un");
else
if (!pending || i >= 40)
break;
log_very_verbose("%s %smonitoring still pending: waiting...",
display_lvname(lv), monitor ? "" : "un");
usleep(10000 * i);
}

View File

@@ -1864,7 +1864,9 @@ cfg(dmeventd_thin_command_CFG, "thin_command", dmeventd_CFG_SECTION, CFG_DEFAULT
"The plugin runs command with each 5% increment when thin-pool data volume\n"
"or metadata volume gets above 50%.\n"
"Command which starts with 'lvm ' prefix is internal lvm command.\n"
"You can write your own handler to customise behaviour in more details.\n")
"You can write your own handler to customise behaviour in more details.\n"
"User handler is specified with the full path starting with '/'.\n")
/* TODO: systemd service handler */
cfg(dmeventd_executable_CFG, "executable", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_PATH, vsn(2, 2, 73), "@DMEVENTD_PATH@", 0, NULL,
"The full path to the dmeventd binary.\n")

View File

@@ -897,8 +897,9 @@ 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) up to stripe boundary size %s (%u extents).",
log_print_unless_silent("Rounding size %s (%u extents) %s 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);
}
@@ -973,6 +974,37 @@ 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)
{
@@ -1013,32 +1045,40 @@ static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t
}
if (lv_is_raid_image(lv)) {
/*
* 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.");
/* 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)
return 0;
} else {
if (!lv_remove(lv)) {
log_error("Failed to remove RAID image %s.",
display_lvname(lv));
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)))
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 */
}
/* 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;
}
}
if (!lv_reduce(lv, rimage_extents))
return_0; /* FIXME: any upper level reporting */
return 1;
}
@@ -1445,6 +1485,13 @@ 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);
}
@@ -3308,19 +3355,24 @@ 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 * ah->area_multiple);
total_extents += ah->log_len * (segtype_is_raid1(segtype) ? 1 : ah->area_multiple);
} else {
ah->log_area_count = 0;
ah->log_len = 0;
@@ -4017,19 +4069,6 @@ 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;
}
@@ -4056,6 +4095,7 @@ int lv_extend(struct logical_volume *lv,
uint32_t sub_lv_count;
uint32_t old_extents;
uint32_t new_extents; /* Total logical size after extension. */
uint64_t raid_size;
log_very_verbose("Adding segment of type %s to LV %s.", segtype->name, lv->name);
@@ -4077,6 +4117,22 @@ 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)) {
raid_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, raid_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)))
@@ -4657,6 +4713,11 @@ 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;
}
@@ -5322,6 +5383,7 @@ 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;
@@ -5363,6 +5425,11 @@ 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;
@@ -6162,12 +6229,21 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
/* Remove snapshot LVs first */
if ((force == PROMPT) &&
/* Active snapshot already needs to confirm each active LV */
!lv_is_active(lv) &&
yes_no_prompt("Removing origin %s will also remove %u "
"snapshots(s). Proceed? [y/n]: ",
lv->name, lv->origin_count) == 'n')
(yes_no_prompt("Do you really want to remove%s "
"%sorigin logical volume %s with %u snapshot(s)? [y/n]: ",
lv_is_active(lv) ? " active" : "",
vg_is_clustered(lv->vg) ? "clustered " : "",
display_lvname(lv),
lv->origin_count) == 'n'))
goto no_remove;
if (!deactivate_lv(cmd, lv)) {
stack;
goto no_remove;
}
log_verbose("Removing origin logical volume %s with %u snapshots(s).",
display_lvname(lv), lv->origin_count);
dm_list_iterate_safe(snh, snht, &lv->snapshot_segs)
if (!lv_remove_with_dependencies(cmd, dm_list_struct_base(snh, struct lv_segment,
origin_list)->cow,

View File

@@ -1224,8 +1224,15 @@ 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 raid_size, uint32_t region_size);
int lv_raid_change_region_size(struct logical_volume *lv,
int yes, int force, uint32_t new_region_size);
int lv_raid_in_sync(const struct logical_volume *lv);
/* -- metadata/raid_manip.c */
/* ++ metadata/cache_manip.c */

View File

@@ -1256,7 +1256,7 @@ uint32_t extents_from_percent_size(struct volume_group *vg, const struct dm_list
}
break;
}
/* Fall back to use all PVs in VG like %FREE */
/* fall through to use all PVs in VG like %FREE */
case PERCENT_FREE:
if (!(extents = vg->free_count)) {
log_error("No free extents in Volume group %s.", vg->name);
@@ -6388,7 +6388,7 @@ int vg_strip_outdated_historical_lvs(struct volume_group *vg) {
* Removal time in the future? Not likely,
* but skip this item in any case.
*/
if ((current_time) < glvl->glv->historical->timestamp_removed)
if (current_time < (time_t) glvl->glv->historical->timestamp_removed)
continue;
if ((current_time - glvl->glv->historical->timestamp_removed) > threshold) {

View File

@@ -21,7 +21,6 @@
#include "activate.h"
#include "lv_alloc.h"
#include "lvm-string.h"
#include "lvm-signal.h"
static int _check_restriping(uint32_t new_stripes, struct logical_volume *lv)
{
@@ -50,24 +49,26 @@ static int _check_num_areas_in_lv_segments(struct logical_volume *lv, unsigned n
return 1;
}
/* Ensure region size exceeds the minimum for lv */
static void _ensure_min_region_size(const struct logical_volume *lv)
/*
* 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 raid_size, uint32_t 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;
uint32_t min_region_size = raid_size / (1 << 21);
uint32_t region_size_sav = region_size;
while (region_size < min_region_size)
region_size *= 2;
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;
}
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;
}
/*
@@ -106,8 +107,7 @@ 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);
return _ensure_min_region_size(lv);
seg->region_size = raid_ensure_min_region_size(lv, lv->size, seg->region_size);
}
/* Strip any raid suffix off LV name */
@@ -238,7 +238,7 @@ static int _deactivate_and_remove_lvs(struct volume_group *vg, struct dm_list *r
* Returns: 1 if in-sync, 0 otherwise.
*/
#define _RAID_IN_SYNC_RETRIES 6
static int _raid_in_sync(struct logical_volume *lv)
static int _raid_in_sync(const struct logical_volume *lv)
{
int retries = _RAID_IN_SYNC_RETRIES;
dm_percent_t sync_percent;
@@ -269,6 +269,12 @@ static int _raid_in_sync(struct logical_volume *lv)
return (sync_percent == DM_PERCENT_100) ? 1 : 0;
}
/* External interface to raid in-sync check */
int lv_raid_in_sync(const struct logical_volume *lv)
{
return _raid_in_sync(lv);
}
/* Check if RaidLV @lv is synced or any raid legs of @lv are not synced */
static int _raid_devs_sync_healthy(struct logical_volume *lv)
{
@@ -480,6 +486,161 @@ 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
@@ -672,7 +833,7 @@ static int _alloc_image_components(struct logical_volume *lv,
return_0;
if (seg_is_linear(seg))
region_size = get_default_region_size(lv->vg->cmd);
region_size = seg->region_size ? : get_default_region_size(lv->vg->cmd);
else
region_size = seg->region_size;
@@ -757,7 +918,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);
@@ -766,6 +927,53 @@ 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
@@ -806,7 +1014,8 @@ 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,
1 /*RAID_METADATA_AREA_LEN*/,
raid_rmeta_extents_delta(data_lv->vg->cmd, 0, data_lv->le_count,
seg->region_size, data_lv->vg->extent_size),
allocate_pvs, data_lv->alloc, 0, NULL)))
return_0;
@@ -866,6 +1075,11 @@ 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;
@@ -912,7 +1126,9 @@ static int _raid_add_images_without_commit(struct logical_volume *lv,
goto fail;
if (seg_is_linear(seg)) {
first_seg(lv)->status |= RAID_IMAGE;
uint32_t region_size = seg->region_size;
seg->status |= RAID_IMAGE;
if (!insert_layer_for_lv(lv->vg->cmd, lv,
RAID | LVM_READ | LVM_WRITE,
"_rimage_0"))
@@ -920,15 +1136,8 @@ 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;
}
@@ -2196,7 +2405,6 @@ 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;
@@ -2560,6 +2768,7 @@ 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... */
@@ -2576,58 +2785,77 @@ struct possible_type {
};
static struct possible_takeover_reshape_type _possible_takeover_reshape_types[] = {
/* striped -> */
/* striped -> raid1 */
{ .current_types = SEG_STRIPED_TARGET, /* linear, i.e. seg->area_count = 1 */
.possible_types = SEG_RAID1,
.current_areas = 1,
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
.options = 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* -> */
/* raid0* -> raid1 */
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count = 1 */
.possible_types = SEG_RAID1,
.current_areas = 1,
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
.options = ALLOW_REGION_SIZE },
/* 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,
/* striped,raid0* <-> striped,raid0* */
{ .current_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
.possible_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
.current_areas = ~0U,
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
.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 },
/* 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_NONE }, /* FIXME: ALLOW_REGION_SIZE */
.options = 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_NONE }, /* FIXME: ALLOW_REGION_SIZE */
.options = 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_NONE }, /* FIXME: ALLOW_REGION_SIZE */
.options = 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_NONE }, /* FIXME: ALLOW_REGION_SIZE */
.options = 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_NONE }, /* FIXME: ALLOW_REGION_SIZE */
.options = ALLOW_REGION_SIZE },
/* END */
{ .current_types = 0 }
@@ -2914,8 +3142,6 @@ 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))
@@ -3105,7 +3331,7 @@ static int _shift_parity_dev(struct lv_segment *seg)
/* raid456 -> raid0* / striped */
static int _raid45_to_raid54_wrapper(TAKEOVER_FN_ARGS);
static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
{
int rename_sublvs = 0;
struct lv_segment *seg = first_seg(lv);
@@ -3129,8 +3355,6 @@ static int _raid456_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))
@@ -3152,6 +3376,10 @@ static int _raid456_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 */
@@ -3304,9 +3532,6 @@ 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;
@@ -3365,6 +3590,10 @@ 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;
@@ -3470,7 +3699,9 @@ static int _takeover_from_raid0_to_raid1(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_to_raid10(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
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);
}
static int _takeover_from_raid0_to_raid45(TAKEOVER_FN_ARGS)
@@ -3520,7 +3751,9 @@ static int _takeover_from_raid0_meta_to_raid1(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_meta_to_raid10(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
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);
}
static int _takeover_from_raid0_meta_to_raid45(TAKEOVER_FN_ARGS)
@@ -3597,12 +3830,12 @@ static int _takeover_from_raid45_to_mirrored(TAKEOVER_FN_ARGS)
static int _takeover_from_raid45_to_raid0(TAKEOVER_FN_ARGS)
{
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);
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);
}
static int _takeover_from_raid45_to_raid0_meta(TAKEOVER_FN_ARGS)
{
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);
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);
}
static int _takeover_from_raid45_to_raid1(TAKEOVER_FN_ARGS)
@@ -3633,30 +3866,30 @@ static int _takeover_from_raid45_to_raid6(TAKEOVER_FN_ARGS)
static int _takeover_from_raid45_to_striped(TAKEOVER_FN_ARGS)
{
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);
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);
}
static int _takeover_from_raid6_to_raid0(TAKEOVER_FN_ARGS)
{
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
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);
}
static int _takeover_from_raid6_to_raid0_meta(TAKEOVER_FN_ARGS)
{
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
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);
}
static int _takeover_from_raid6_to_raid45(TAKEOVER_FN_ARGS)
{
return _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1,
return _raid45610_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 _raid456_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
2 /* data_copies */, 0, 0, 0, allocate_pvs);
}
@@ -3683,7 +3916,9 @@ static int _takeover_from_striped_to_raid0_meta(TAKEOVER_FN_ARGS)
static int _takeover_from_striped_to_raid10(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
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);
}
static int _takeover_from_striped_to_raid45(TAKEOVER_FN_ARGS)
@@ -3700,6 +3935,8 @@ 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);
@@ -3714,6 +3951,7 @@ 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)
{
@@ -3727,17 +3965,22 @@ static int _takeover_from_raid10_to_mirrored(TAKEOVER_FN_ARGS)
static int _takeover_from_raid10_to_raid0(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
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);
}
/*
* 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 _takeover_unsupported_yet(lv, new_stripes, new_segtype);
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);
}
static int _takeover_from_raid10_to_raid1(TAKEOVER_FN_ARGS)
@@ -3745,16 +3988,20 @@ 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 _takeover_unsupported_yet(lv, new_stripes, new_segtype);
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);
}
*/
/*
* Import takeover matrix.
@@ -3880,7 +4127,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, uint32_t region_size)
static int _region_size_change_requested(struct logical_volume *lv, int yes, const uint32_t region_size)
{
uint32_t old_region_size;
const char *seg_region_size_str;
@@ -3890,14 +4137,14 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, uin
if (!region_size)
return_0;
/* CLI validation prvides the check but be caucious... */
/* CLI validation provides the check but be caucious... */
if (seg_is_any_raid0(seg))
return_0;
if (region_size == seg->region_size) {
log_warn("Region size wouldn't change on %s LV %s.",
lvseg_name(seg), display_lvname(lv));
return 0;
log_print_unless_silent("Region size wouldn't change on %s LV %s.",
lvseg_name(seg), display_lvname(lv));
return 1;
}
if (region_size * 8 > lv->size) {
@@ -3907,7 +4154,7 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, uin
}
if (region_size < seg->stripe_size) {
log_error("Region size for LV %s is smaller than stripe size.",
log_error("Requested region size for LV %s is smaller than stripe size.",
display_lvname(lv));
return 0;
}
@@ -3919,15 +4166,7 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, uin
}
old_region_size = seg->region_size;
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) {
log_warn("Region size on %s did not change due to adjustment.",
display_lvname(lv));
return 1;
}
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),
@@ -3935,8 +4174,15 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, uin
log_error("Logical volume %s NOT converted", display_lvname(lv));
return 0;
}
if (sigint_caught())
return_0;
seg->region_size = region_size;
_check_and_adjust_region_size(lv);
if (seg->region_size == old_region_size) {
log_warn("Region size on %s did not change due to adjustment.",
display_lvname(lv));
return 1;
}
/* 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 <
@@ -3958,7 +4204,7 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, uin
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 region_size,
int new_data_copies, int new_region_size,
int stripes, unsigned new_stripe_size_supplied)
{
int r = 1;
@@ -3985,6 +4231,12 @@ 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;
}
@@ -4005,13 +4257,13 @@ int lv_raid_convert(struct logical_volume *lv,
const unsigned new_stripes,
const unsigned new_stripe_size_supplied,
const unsigned new_stripe_size,
/* FIXME: workaround with volatile new_region_size until cli validation patches got merged */
uint32_t new_region_size,
const 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) {
@@ -4033,7 +4285,7 @@ int lv_raid_convert(struct logical_volume *lv,
/* Change RAID region size */
/*
* FIXME: workaround with volatile new_region_size until the
* FIXME: workaround with 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.
*/
@@ -4043,7 +4295,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
new_region_size = seg->region_size ? : get_default_region_size(lv->vg->cmd);
region_size = seg->region_size ? : get_default_region_size(lv->vg->cmd);
/*
* Check acceptible options mirrors, region_size,
@@ -4058,7 +4310,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,
new_region_size, allocate_pvs);
region_size, allocate_pvs);
log_verbose("Converting %s from %s to %s.",
display_lvname(lv), lvseg_name(first_seg(lv)),
@@ -4089,7 +4341,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,
new_region_size, allocate_pvs);
region_size, allocate_pvs);
}
int lv_raid_change_region_size(struct logical_volume *lv,

View File

@@ -50,7 +50,8 @@ struct dev_manager;
#define SEG_RAID0 0x0000000000040000ULL
#define SEG_RAID0_META 0x0000000000080000ULL
#define SEG_RAID1 0x0000000000100000ULL
#define SEG_RAID10 0x0000000000200000ULL
#define SEG_RAID10_NEAR 0x0000000000200000ULL
#define SEG_RAID10 SEG_RAID10_NEAR
#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 , r10_r10, r10_r01, X },
/* raid10 */ { r10_lin, r10_str, r10_mir, r10_r0, r10_r0m, r10_r1, X , X , X , X , 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

@@ -15,7 +15,6 @@
#include "lib.h"
#include "config.h"
#include "lvm-file.h"
#include "lvm-flock.h"
#include "lvm-signal.h"
#include "locking.h"

View File

@@ -42,7 +42,7 @@ static int _pthread_create(pthread_t *t, void *(*fun)(void *), void *arg, int st
/*
* We use a smaller stack since it gets preallocated in its entirety
*/
pthread_attr_setstacksize(&attr, stacksize);
pthread_attr_setstacksize(&attr, stacksize + getpagesize());
return pthread_create(t, &attr, fun, arg);
}
#endif

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;
/* Resume device immediately if it has parents and its size changed */
if (!dm_tree_node_num_children(child, 1) || !child->props.size_changed)
/* 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))
continue;
if (!node_created && (dm_list_size(&child->props.segs) == 1)) {

View File

@@ -3062,26 +3062,31 @@ static void _get_final_time(time_range_t range, struct tm *tm,
tm_up.tm_sec += 1;
break;
}
/* fall through */
case RANGE_MINUTE:
if (tm_up.tm_min < 59) {
tm_up.tm_min += 1;
break;
}
/* fall through */
case RANGE_HOUR:
if (tm_up.tm_hour < 23) {
tm_up.tm_hour += 1;
break;
}
/* fall through */
case RANGE_DAY:
if (tm_up.tm_mday < _get_days_in_month(tm_up.tm_mon, tm_up.tm_year)) {
tm_up.tm_mday += 1;
break;
}
/* fall through */
case RANGE_MONTH:
if (tm_up.tm_mon < 11) {
tm_up.tm_mon += 1;
break;
}
/* fall through */
case RANGE_YEAR:
tm_up.tm_year += 1;
break;
@@ -4204,7 +4209,7 @@ static void _recalculate_fields(struct dm_report *rh)
{
struct row *row;
struct dm_report_field *field;
size_t len;
int len;
dm_list_iterate_items(row, &rh->rows) {
dm_list_iterate_items(field, &row->fields) {

View File

@@ -402,7 +402,7 @@ static int _stats_bound(const struct dm_stats *dms)
if (dms->bind_major > 0 || dms->bind_name || dms->bind_uuid)
return 1;
/* %p format specifier expects a void pointer. */
log_debug("Stats handle at %p is not bound.", (void *) dms);
log_debug("Stats handle at %p is not bound.", dms);
return 0;
}
@@ -3294,7 +3294,7 @@ static void _sum_histogram_bins(const struct dm_stats *dms,
struct dm_stats_region *region;
struct dm_histogram_bin *bins;
struct dm_histogram *dmh_cur;
uint64_t bin;
int bin;
region = &dms->regions[region_id];
dmh_cur = region->counters[area_id].histogram;
@@ -3857,9 +3857,9 @@ struct _extent {
*/
static int _extent_start_compare(const void *p1, const void *p2)
{
struct _extent *r1, *r2;
r1 = (struct _extent *) p1;
r2 = (struct _extent *) p2;
const struct _extent *r1, *r2;
r1 = (const struct _extent *) p1;
r2 = (const struct _extent *) p2;
if (r1->start < r2->start)
return -1;
@@ -3868,37 +3868,6 @@ static int _extent_start_compare(const void *p1, const void *p2)
return 1;
}
/*
* Resize the group bitmap corresponding to group_id so that it can
* contain at least num_regions members.
*/
static int _stats_resize_group(struct dm_stats_group *group, int num_regions)
{
int last_bit = dm_bit_get_last(group->regions);
dm_bitset_t new, old;
if (last_bit >= num_regions) {
log_error("Cannot resize group bitmap to %d with bit %d set.",
num_regions, last_bit);
return 0;
}
log_very_verbose("Resizing group bitmap from %d to %d (last_bit: %d).",
group->regions[0], num_regions, last_bit);
new = dm_bitset_create(NULL, num_regions);
if (!new) {
log_error("Could not allocate memory for new group bitmap.");
return 0;
}
old = group->regions;
dm_bit_copy(new, old);
group->regions = new;
dm_bitset_destroy(old);
return 1;
}
static int _stats_create_group(struct dm_stats *dms, dm_bitset_t regions,
const char *alias, uint64_t *group_id)
{
@@ -4003,7 +3972,7 @@ merge:
static void _stats_copy_histogram_bounds(struct dm_histogram *to,
struct dm_histogram *from)
{
uint64_t i;
int i;
to->nr_bins = from->nr_bins;
@@ -4019,7 +3988,7 @@ static void _stats_copy_histogram_bounds(struct dm_histogram *to,
static int _stats_check_histogram_bounds(struct dm_histogram *h1,
struct dm_histogram *h2)
{
uint64_t i;
int i;
if (!h1 || !h2)
return 0;
@@ -4202,6 +4171,37 @@ int dm_stats_get_group_descriptor(const struct dm_stats *dms,
}
#ifdef HAVE_LINUX_FIEMAP_H
/*
* Resize the group bitmap corresponding to group_id so that it can
* contain at least num_regions members.
*/
static int _stats_resize_group(struct dm_stats_group *group, int num_regions)
{
int last_bit = dm_bit_get_last(group->regions);
dm_bitset_t new, old;
if (last_bit >= num_regions) {
log_error("Cannot resize group bitmap to %d with bit %d set.",
num_regions, last_bit);
return 0;
}
log_very_verbose("Resizing group bitmap from %d to %d (last_bit: %d).",
group->regions[0], num_regions, last_bit);
new = dm_bitset_create(NULL, num_regions);
if (!new) {
log_error("Could not allocate memory for new group bitmap.");
return 0;
}
old = group->regions;
dm_bit_copy(new, old);
group->regions = new;
dm_bitset_destroy(old);
return 1;
}
/*
* Group a table of region_ids corresponding to the extents of a file.
*/
@@ -4557,7 +4557,7 @@ static int _stats_unmap_regions(struct dm_stats *dms, uint64_t group_id,
log_error("Could not finalize region extent table.");
goto out;
}
log_very_verbose("Kept %ld of %ld old extents",
log_very_verbose("Kept " FMTi64 " of " FMTi64 " old extents",
nr_kept, nr_old);
log_very_verbose("Found " FMTu64 " new extents",
*count - nr_kept);
@@ -4725,7 +4725,7 @@ static uint64_t *_stats_map_file_regions(struct dm_stats *dms, int fd,
dm_pool_free(extent_mem, extents);
dm_pool_destroy(extent_mem);
dm_free(hist_arg);
return regions;
out_remove:
@@ -4842,7 +4842,7 @@ uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
if (!bounds) {
log_error("Could not allocate memory for group "
"histogram bounds.");
return NULL;
goto out;
}
_stats_copy_histogram_bounds(bounds,
dms->regions[group_id].bounds);
@@ -4869,6 +4869,8 @@ uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
bad:
_stats_cleanup_region_ids(dms, regions, count);
dm_free(bounds);
dm_free(regions);
out:
dm_free((char *) alias);
return NULL;
}

View File

@@ -626,7 +626,7 @@ uint64_t dm_units_to_factor(const char *units, char *unit_type,
uint64_t multiplier;
if (endptr)
*endptr = (char *) units;
*endptr = units;
if (isdigit(*units)) {
custom_value = strtod(units, &ptr);
@@ -709,7 +709,7 @@ uint64_t dm_units_to_factor(const char *units, char *unit_type,
}
if (endptr)
*endptr = (char *) units + 1;
*endptr = units + 1;
if (_close_enough(custom_value, 0.))
return v * multiplier; /* Use integer arithmetic */

View File

@@ -40,6 +40,11 @@ SED = @SED@
CFLOW_CMD = @CFLOW_CMD@
AWK = @AWK@
CHMOD = @CHMOD@
EGREP = @EGREP@
GREP = @GREP@
SORT = @SORT@
WC = @WC@
PYTHON2 = @PYTHON2@
PYTHON3 = @PYTHON3@
PYCOMPILE = $(top_srcdir)/autoconf/py-compile
@@ -512,9 +517,9 @@ ifeq (,$(firstword $(EXPORTED_SYMBOLS)))
) > $@
else
set -e;\
R=$$(sort $^ | uniq -u);\
R=$$($(SORT) $^ | uniq -u);\
test -z "$$R" || { echo "Mismatch between symbols in shared library and lists in .exported_symbols.* files: $$R"; false; } ;\
( for i in $$(echo $(EXPORTED_SYMBOLS) | tr ' ' '\n' | sort -rnt_ -k5 ); do\
( for i in $$(echo $(EXPORTED_SYMBOLS) | tr ' ' '\n' | $(SORT) -rnt_ -k5 ); do\
echo "$${i##*.} {"; echo " global:";\
$(SED) "s/^/ /;s/$$/;/" $$i;\
echo "};";\

View File

@@ -144,10 +144,12 @@ 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 $@" ;
./man-generator $(basename $@) > $@.gen
if [ ! -e $@.gen ]; then ./man-generator $(basename $@) $(top_srcdir)/man/$@.des > $@.gen; fi
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

@@ -23,40 +23,6 @@ dmeventd is the event monitoring daemon for device-mapper devices.
Library plugins can register and carry out actions triggered when
particular events occur.
.
.SH LVM PLUGINS
.
.HP
.IR Mirror
.br
Attempts to handle device failure automatically. See
.BR lvm.conf (5).
.
.HP
.IR Raid
.br
Attempts to handle device failure automatically. See
.BR lvm.conf (5).
.
.HP
.IR Snapshot
.br
Monitors how full a snapshot is becoming and emits a warning to
syslog when it exceeds 80% full.
The warning is repeated when 85%, 90% and 95% of the snapshot is filled.
See
.BR lvm.conf (5).
Snapshot which runs out of space gets invalid and when it is mounted,
it gets umounted if possible.
.
.HP
.IR Thin
.br
Monitors how full a thin pool data and metadata is becoming and emits
a warning to syslog when it exceeds 80% full.
The warning is repeated when 85%, 90% and 95% of the thin pool is filled.
See
.BR lvm.conf (5).
If the thin-pool runs out of space, thin volumes are umounted if possible.
.
.SH OPTIONS
.
@@ -104,6 +70,80 @@ events to monitor from the currently running daemon.
.br
Show version of dmeventd.
.
.SH LVM PLUGINS
.
.HP
.BR Mirror
.br
Attempts to handle device failure automatically. See
.BR lvm.conf (5).
.
.HP
.BR Raid
.br
Attempts to handle device failure automatically. See
.BR lvm.conf (5).
.
.HP
.BR Snapshot
.br
Monitors how full a snapshot is becoming and emits a warning to
syslog when it exceeds 80% full.
The warning is repeated when 85%, 90% and 95% of the snapshot is filled.
See
.BR lvm.conf (5).
Snapshot which runs out of space gets invalid and when it is mounted,
it gets umounted if possible.
.
.HP
.BR Thin
.br
Monitors how full a thin pool data and metadata is becoming and emits
a warning to syslog when it exceeds 80% full.
The warning is repeated when more then 85%, 90% and 95%
of the thin pool is filled. See
.BR lvm.conf (5).
When a thin pool fills over 50% (data or metadata) thin plugin calls
configured \fIdmeventd/thin_command\fP with every 5% increase.
With default setting it calls internal
\fBlvm lvextend --use-policies\fP to resize thin pool
when it's been filled above configured threshold
\fIactivation/thin_pool_autoextend_threshold\fP.
If the command fails, dmeventd thin plugin will keep
retrying execution with increasing time delay between
retries upto 42 minutes.
User may also configure external command to support more advanced
maintenance operations of a thin pool.
Such external command can e.g. remove some unneeded snapshots,
use \fBfstrim\fP(8) to free recover space in a thin pool,
but also can use \fBlvextend --use-policies\fP if other actions
have not released enough space.
Command is executed with environmental variable
\fBLVM_RUN_BY_DMEVENTD=1\fP so any lvm2 command executed
in this environment will not try to interact with dmeventd.
To see the fullness of a thin pool command may check these
two environmental variables
\fBDMEVENTD_THIN_POOL_DATA\fP and \fBDMEVENTD_THIN_POOL_DATA\fP.
Command can also read status with tools like \fBlvs\fP(8).
.
.SH ENVIRONMENT VARIABLES
.
.TP
.B DMEVENTD_THIN_POOL_DATA
Variable is set by thin plugin and is available to executed program. Value present
actual usage of thin pool data volume. Variable is not set when error event
is processed.
.TP
.B DMEVENTD_THIN_POOL_DATA
Variable is set by thin plugin and is available to executed program. Value present
actual usage of thin pool metadata volume. Variable is not set when error event
is processed.
.TP
.B LVM_RUN_BY_DMEVENTD
Variable is set by thin plugin to prohibit recursive interation
with dmeventd by any executed lvm2 command from
a thin_command environment.
.
.SH SEE ALSO
.
.BR lvm (8),

View File

@@ -27,9 +27,9 @@ dmsetup \(em low level logical volume management
. IR uuid ]
. RB \%[ \-\-addnodeoncreate | \-\-addnodeonresume ]
. RB \%[ \-n | \-\-notable | \-\-table
. RI \%{ table | table_file }]
. IR \%table | table_file ]
. RB [ \-\-readahead
. RB \%{[ + ] \fIsectors | auto | none }]
. RB \%[ + ] \fIsectors | auto | none ]
. ad b
..
.CMD_CREATE
@@ -41,7 +41,7 @@ dmsetup \(em low level logical volume management
. BR deps
. RB [ \-o
. IR options ]
. RI [ device_name ]
. RI [ device_name ...]
. ad b
..
.CMD_DEPS
@@ -58,7 +58,7 @@ dmsetup \(em low level logical volume management
.B dmsetup
.de CMD_INFO
. BR info
. RI [ device_name ]
. RI [ device_name ...]
..
.CMD_INFO
.
@@ -92,7 +92,7 @@ dmsetup \(em low level logical volume management
. BR load
. IR device_name
. RB [ \-\-table
. RI { table | table_file }]
. IR table | table_file ]
. ad b
..
.CMD_LOAD
@@ -117,7 +117,7 @@ dmsetup \(em low level logical volume management
.B dmsetup
.de CMD_MANGLE
. BR mangle
. RI [ device_name ]
. RI [ device_name ...]
..
.CMD_MANGLE
.
@@ -135,7 +135,7 @@ dmsetup \(em low level logical volume management
.B dmsetup
.de CMD_MKNODES
. BR mknodes
. RI [ device_name ]
. RI [ device_name ...]
..
.CMD_MKNODES
.
@@ -146,7 +146,7 @@ dmsetup \(em low level logical volume management
. BR reload
. IR device_name
. RB [ \-\-table
. RI { table | table_file }]
. IR table | table_file ]
. ad b
..
.CMD_RELOAD
@@ -159,7 +159,7 @@ dmsetup \(em low level logical volume management
. RB [ \-f | \-\-force ]
. RB [ \-\-retry ]
. RB [ \-\-deferred ]
. IR device_name
. IR device_name ...
. ad b
..
.CMD_REMOVE
@@ -197,12 +197,12 @@ dmsetup \(em low level logical volume management
.de CMD_RESUME
. ad l
. BR resume
. IR device_name
. IR device_name ...
. RB [ \-\-addnodeoncreate | \-\-addnodeonresume ]
. RB [ \-\-noflush ]
. RB [ \-\-nolockfs ]
. RB \%[ \-\-readahead
. RB \%{[ + ] \fIsectors | auto | none }]
. RB \%[ + ] \fIsectors | auto | none ]
. ad b
..
.CMD_RESUME
@@ -247,7 +247,7 @@ dmsetup \(em low level logical volume management
. RB [ \-\-target
. IR target_type ]
. RB [ \-\-noflush ]
. RI [ device_name ]
. RI [ device_name ...]
. ad b
..
.CMD_STATUS
@@ -259,7 +259,7 @@ dmsetup \(em low level logical volume management
. BR suspend
. RB [ \-\-nolockfs ]
. RB [ \-\-noflush ]
. IR device_name
. IR device_name ...
. ad b
..
.CMD_SUSPEND
@@ -272,7 +272,7 @@ dmsetup \(em low level logical volume management
. RB [ \-\-target
. IR target_type ]
. RB [ \-\-showkeys ]
. RI [ device_name ]
. RI [ device_name ...]
. ad b
..
.CMD_TABLE
@@ -354,7 +354,7 @@ dmsetup \(em low level logical volume management
.de CMD_WIPE_TABLE
. ad l
. BR wipe_table
. IR device_name
. IR device_name ...
. RB [ \-f | \-\-force ]
. RB [ \-\-noflush ]
. RB [ \-\-nolockfs ]
@@ -447,7 +447,7 @@ The default interval is one second.
.
.HP
.BR \-\-manglename
.RB { auto | hex | none }
.BR auto | hex | none
.br
Mangle any character not on a whitelist using mangling_mode when
processing device-mapper device names and UUIDs. The names and UUIDs
@@ -529,7 +529,7 @@ Specify which fields to display.
.
.HP
.BR \-\-readahead
.RB {[ + ] \fIsectors | auto | none }
.RB [ + ] \fIsectors | auto | none
.br
Specify read ahead size in units of sectors.
The default value is \fBauto\fP which allows the kernel to choose
@@ -820,8 +820,10 @@ 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.
Encryption keys are suppressed in the table output for the crypt
target unless the \fB\-\-showkeys\fP parameter is supplied.
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.
.
.HP
.CMD_TARGETS

View File

@@ -44,7 +44,7 @@ dmstats \(em device-mapper statistics management
.B dmsetup
.B stats
.I command
.RB [ options ]
[OPTIONS]
.sp
.
.PD 0
@@ -53,13 +53,13 @@ dmstats \(em device-mapper statistics management
.de CMD_COMMAND
. ad l
. IR command
. RI [ device_name |
. RB [ \-u | \-\-uuid
. IR uuid ]
. RB | [ \-\-major
. IR device_name " |"
. BR \-\-major
. IR major
. BR \-\-minor
. IR minor ]
. IR minor " |"
. BR \-u | \-\-uuid
. IR uuid
. RB \%[ \-v | \-\-verbose]
. ad b
..
@@ -82,9 +82,7 @@ dmstats \(em device-mapper statistics management
.de CMD_CREATE
. ad l
. BR create
. RB [ device_name...
. RB | file_path...
. RB | [ \-\-alldevices ]]
. IR device_name... | file_path... | \fB\-\-alldevices
. RB [ \-\-areas
. IR nr_areas | \fB\-\-areasize
. IR area_size ]
@@ -110,8 +108,7 @@ dmstats \(em device-mapper statistics management
.de CMD_DELETE
. ad l
. BR delete
. RI [ device_name ]
. RB [ \-\-alldevices ]
. IR device_name | \fB\-\-alldevices
. OPT_PROGRAMS
. OPT_REGIONS
. ad b
@@ -123,10 +120,9 @@ dmstats \(em device-mapper statistics management
.de CMD_GROUP
. ad l
. BR group
. RI [ device_name ]
. RI [ device_name | \fB\-\-alldevices ]
. RB [ \-\-alias
. IR name ]
. RB [ \-\-alldevices ]
. RB [ \-\-regions
. IR regions ]
. ad b
@@ -205,8 +201,7 @@ dmstats \(em device-mapper statistics management
.de CMD_UNGROUP
. ad l
. BR ungroup
. RI [ device_name ]
. RB [ \-\-alldevices ]
. RI [ device_name | \fB\-\-alldevices ]
. RB [ \-\-groupid
. IR id ]
. ad b
@@ -217,7 +212,7 @@ dmstats \(em device-mapper statistics management
.de CMD_UPDATE_FILEMAP
. ad l
. BR update_filemap
. RI file_path
. IR file_path
. RB [ \-\-groupid
. IR id ]
. ad b

View File

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

View File

@@ -7,21 +7,6 @@ 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
@@ -35,12 +20,6 @@ type is deprecated and the
.B raid1
type should be used. They are both implementations of mirroring.
The
.B raid*
type refers to one of many raid levels, e.g.
.B raid1,
.B raid5.
In some cases, an LV is a single device mapper (dm) layer above physical
devices. In other cases, hidden LVs (dm devices) are layered between the
visible LV and physical devices. LVs in the middle layers are called sub LVs.

View File

@@ -1,64 +1,85 @@
.SH NOTES
This previous command syntax would perform two different operations:
.br
\fBlvconvert --thinpool\fP \fILV1\fP \fB--poolmetadata\fP \fILV2\fP
.br
If LV1 was not a thin pool, the command would convert LV1 to
a thin pool, optionally using a specified LV for metadata.
But, if LV1 was already a thin pool, the command would swap
the current metadata LV with LV2 (for repair purposes.)
In the same way, this previous command syntax would perform two different
operations:
.br
\fBlvconvert --cachepool\fP \fILV1\fP \fB--poolmetadata\fP \fILV2\fP
.br
If LV1 was not a cache pool, the command would convert LV1 to
a cache pool, optionally using a specified LV for metadata.
But, if LV1 was already a cache pool, the command would swap
the current metadata LV with LV2 (for repair purposes.)
.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 +90,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 +98,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

@@ -26,3 +26,14 @@ virtual size rather than a physical size. A cache LV is the combination of
a standard LV with a cache pool, used to cache active portions of the LV
to improve performance.
.SS Usage notes
In the usage section below, \fB--size\fP \fINumber\fP can be replaced
in each case with \fB--extents\fP \fINumberExtents\fP. Also see both
descriptions the options section.
In the usage section below, \fB--name\fP is omitted from the required
options, even though it is typically used. When the name is not
specified, a new LV name is generated with the "lvol" prefix and a unique
numeric suffix. Also see the description in the options section.

5
man/lvm-config.8.des Normal file
View File

@@ -0,0 +1,5 @@
This command is the same as \fBlvmconfig\fP(8).
lvm config produces formatted output from the LVM configuration tree. The
sources of the configuration data include \fBlvm.conf\fP(5) and command
line settings from \-\-config.

5
man/lvm-dumpconfig.8.des Normal file
View File

@@ -0,0 +1,5 @@
This command is the same as \fBlvmconfig\fP(8).
lvm dumpconfig produces formatted output from the LVM configuration tree. The
sources of the configuration data include \fBlvm.conf\fP(5) and command
line settings from \-\-config.

View File

@@ -1,6 +1,5 @@
.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
@@ -8,27 +7,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

@@ -484,48 +484,70 @@ directly.
.SH SEE ALSO
.
.nh
.BR lvm.conf (5),
.BR lvmcache (7),
.BR lvmreport(7),
.BR lvmthin (7),
.BR clvmd (8),
.BR lvm (8)
.BR lvm.conf (5)
.BR lvmconfig (8)
.BR pvchange (8)
.BR pvck (8)
.BR pvcreate (8)
.BR pvdisplay (8)
.BR pvmove (8)
.BR pvremove (8)
.BR pvresize (8)
.BR pvs (8)
.BR pvscan (8)
.BR vgcfgbackup (8)
.BR vgcfgrestore (8)
.BR vgchange (8)
.BR vgck (8)
.BR vgcreate (8)
.BR vgconvert (8)
.BR vgdisplay (8)
.BR vgexport (8)
.BR vgextend (8)
.BR vgimport (8)
.BR vgimportclone (8)
.BR vgmerge (8)
.BR vgmknodes (8)
.BR vgreduce (8)
.BR vgremove (8)
.BR vgrename (8)
.BR vgs (8)
.BR vgscan (8)
.BR vgsplit (8)
.BR lvcreate (8)
.BR lvchange (8)
.BR lvconvert (8)
.BR lvdisplay (8)
.BR lvextend (8)
.BR lvreduce (8)
.BR lvremove (8)
.BR lvrename (8)
.BR lvresize (8)
.BR lvs (8)
.BR lvscan (8)
.BR lvm2-activation-generator (8)
.BR blkdeactivate (8)
.BR lvmdump (8)
.BR dmeventd (8)
.BR lvmetad (8)
.BR lvmpolld (8)
.BR lvmlockd (8)
.BR lvmlockctl (8)
.BR clvmd (8)
.BR cmirrord (8)
.BR lvmdbusd (8)
.BR lvmsystemid (7)
.BR lvmreport (7)
.BR lvmraid (7)
.BR lvmthin (7)
.BR lvmcache (7)
.BR dmsetup (8),
.BR lvchange (8),
.BR lvcreate (8),
.BR lvdisplay (8),
.BR lvextend (8),
.BR lvmchange (8),
.BR lvmconfig (8),
.BR lvmdiskscan (8),
.BR lvreduce (8),
.BR lvremove (8),
.BR lvrename (8),
.BR lvresize (8),
.BR lvs (8),
.BR lvscan (8),
.BR pvchange (8),
.BR pvck (8),
.BR pvcreate (8),
.BR pvdisplay (8),
.BR pvmove (8),
.BR pvremove (8),
.BR pvs (8),
.BR pvscan (8),
.BR vgcfgbackup (8),
.BR vgchange (8),
.BR vgck (8),
.BR vgconvert (8),
.BR vgcreate (8),
.BR vgdisplay (8),
.BR vgextend (8),
.BR vgimport (8),
.BR vgimportclone (8),
.BR vgmerge (8),
.BR vgmknodes (8),
.BR vgreduce (8),
.BR vgremove (8),
.BR vgrename (8),
.BR vgs (8),
.BR vgscan (8),
.BR vgsplit (8),
.BR readline (3)

3
man/lvmsadc.8.des Normal file
View File

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

3
man/lvmsar.8.des Normal file
View File

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

View File

@@ -278,22 +278,6 @@ or vgchange to activate thin snapshots with the "k" attribute.
\&
.SS Alternate syntax for specifying type thin\-pool
\&
The fully specified syntax for creating a thin pool LV shown above is:
.B lvconvert \-\-type thin-pool \-\-poolmetadata VG/ThinMetaLV VG/ThinDataLV
An alternate syntax may be used for the same operation:
.B lvconvert \-\-thinpool VG/ThinDataLV \-\-poolmetadata VG/ThinMetaLV
The thin-pool type is inferred by lvm; the \-\-thinpool option is not an
alias for \-\-type thin\-pool.
.SS Automatic pool metadata LV
\&

View File

@@ -6,6 +6,11 @@ removal. LVs cannot be deactivated or removed while they are open (e.g.
if they contain a mounted filesystem). Removing an origin LV will also
remove all dependent snapshots.
When a single force option is used, LVs are removed without confirmation,
and the command will try to deactivate unused LVs.
To remove damaged LVs, two force options may be required (\fB-ff\fP).
\fBHistorical LVs\fP
If the configuration setting \fBmetadata/record_lvs_history\fP is enabled

View File

@@ -16,3 +16,6 @@ data on that disk. This can be done by zeroing the first sector with:
Use \fBvgcreate\fP(8) to create a new VG on the PV, or \fBvgextend\fP(8)
to add the PV to existing VG.
The force option will create a PV without confirmation. Repeating the
force option (\fB-ff\fP) will forcibly create a PV, overriding checks that
normally prevent it, e.g. if the PV is already in a VG.

16
man/pvmove.8.des Normal file
View File

@@ -0,0 +1,16 @@
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.

View File

@@ -1,6 +1,6 @@
.SH NOTES
.
\fBpvmove\fP works as follows:
pvmove works as follows:
1. A temporary 'pvmove' LV is created to store details of all the data
movements required.
@@ -9,7 +9,7 @@ movements required.
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
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.

7
man/pvremove.8.des Normal file
View File

@@ -0,0 +1,7 @@
pvremove wipes the label on a device so that LVM will no longer recognise
it as a PV.
A PV cannot be removed from a VG while it is used by an active LV.
Repeat the force option (\fB-ff\fP) to forcibly remove a PV belonging to
an existing VG. Normally, \fBvgreduce\fP(8) should be used instead.

2
man/pvresize.8.des Normal file
View File

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

View File

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

1
man/pvs.8.des Normal file
View File

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

View File

@@ -1,6 +1,6 @@
.SH NOTES
pvscan scans all supported LVM block devices in the system for PVs.
.SS Scanning with lvmetad
\fBScanning with lvmetad\fP
pvscan operates differently when used with the
.BR lvmetad (8)
@@ -64,7 +64,9 @@ 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.
.SS Automatic activation
.P
\fBAutomatic activation\fP
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

16
man/vgcfgbackup.8.des Normal file
View File

@@ -0,0 +1,16 @@
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.

11
man/vgcfgrestore.8.des Normal file
View File

@@ -0,0 +1,11 @@
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.
WARNING: When a VG contains thin pools, changes to thin metadata cannot be
reverted, and data loss may occur if thin metadata has changed. The force
option is required to restore in this case.

View File

@@ -1,11 +1,9 @@
.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 volume group's
metadata.
\fBvgcfgrestore \-\-file filename\fP to restore the VG's metadata.

2
man/vgchange.8.des Normal file
View File

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

View File

@@ -1,4 +1,10 @@
.EXAMPLES
.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
Activate all LVs in all VGs on all existing devices.
.br

1
man/vgck.8.des Normal file
View File

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

7
man/vgconvert.8.des Normal file
View File

@@ -0,0 +1,7 @@
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.

4
man/vgcreate.8.des Normal file
View File

@@ -0,0 +1,4 @@
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 @@
.EXAMPLES
.SH EXAMPLES
Create a VG with two PVs, using the default physical extent size.
.br

4
man/vgdisplay.8.des Normal file
View File

@@ -0,0 +1,4 @@
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,14 +1,8 @@
.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
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
\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).

11
man/vgextend.8.des Normal file
View File

@@ -0,0 +1,11 @@
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,10 +1,3 @@
.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.

5
man/vgimport.8.des Normal file
View File

@@ -0,0 +1,5 @@
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).

View File

@@ -1,9 +0,0 @@
.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).

6
man/vgimportclone.8.des Normal file
View File

@@ -0,0 +1,6 @@
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,14 +1,3 @@
.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".

3
man/vgmerge.8.des Normal file
View File

@@ -0,0 +1,3 @@
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.

5
man/vgmknodes.8.des Normal file
View File

@@ -0,0 +1,5 @@
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.

1
man/vgreduce.8.des Normal file
View File

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

9
man/vgremove.8.des Normal file
View File

@@ -0,0 +1,9 @@
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.
Repeat the force option (\fB-ff\fP) to forcibly remove LVs in the VG
without confirmation.

9
man/vgrename.8.des Normal file
View File

@@ -0,0 +1,9 @@
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.

1
man/vgs.8.des Normal file
View File

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

1
man/vgscan.8.des Normal file
View File

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

View File

@@ -1,18 +1,13 @@
.SH NOTES
.
.IP \[bu] 3
vgsplit moves one or more PVs from a source VG to a destination VG. The
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.)
can be used to specify properties of the new VG, also see
\fBvgcreate\fP(8).)
.IP \[bu] 3
LVs cannot be split between VGs; each LV must be entirely on the PVs in
the source or destination VG.
.IP \[bu] 3
vgsplit can only move complete PVs. (See pvmove for moving part of a PV.)
vgsplit can only move complete PVs. (See \fBpvmove\fP(8) for moving part
of a PV.)

View File

@@ -39,7 +39,7 @@ S ?= @ # never match anything by default
VERBOSE ?= 0
ALL := $(shell find -L $(srcdir) \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) | sort)
comma = ,
RUN := $(shell find -L $(srcdir) -regextype posix-egrep \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) -and -regex "$(srcdir)/.*($(subst $(comma),|,$(T))).*" -and -not -regex "$(srcdir)/.*($(subst $(comma),|,$(S))).*" | sort)
RUN := $(shell find -L $(srcdir) -regextype posix-egrep \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) -and -regex "$(srcdir)/.*($(subst $(comma),|,$(T))).*" -and -not -regex "$(srcdir)/.*($(subst $(comma),|,$(S))).*" | ($SORT))
RUN_BASE = $(subst $(srcdir)/,,$(RUN))
ifeq ("@BUILD_LVMETAD@", "yes")
@@ -267,7 +267,7 @@ lib/%: lib/%.o .lib-dir-stamp
lib/%: $(srcdir)/lib/%.sh .lib-dir-stamp
cp $< $@
chmod +x $@
$(CHMOD) +x $@
lib/flavour-%: $(srcdir)/lib/flavour-%.sh .lib-dir-stamp
cp $< $@

View File

@@ -405,23 +405,28 @@ teardown_devs_prefixed() {
fi
# Remove devices, start with closed (sorted by open count)
local remfail=no
# Run 'dmsetup remove' in parallel
local need_udev_wait=0
rm -f REMOVE_FAILED
#local listdevs=( $(dm_info name,open --sort open,name | grep "$prefix.*:0") )
#dmsetup remove --deferred ${listdevs[@]%%:0} || touch REMOVE_FAILED
init_udev_transaction
for dm in $(dm_info name --sort open | grep "$prefix"); do
dmsetup remove "$dm" &>/dev/null || remfail=yes
for dm in $(dm_info name --sort open,name | grep "$prefix"); do
dmsetup remove "$dm" &>/dev/null || touch REMOVE_FAILED &
need_udev_wait=1
done
wait
finish_udev_transaction
test $need_udev_wait -eq 0 || udev_wait
if test $remfail = yes; then
if test -f REMOVE_FAILED; then
local num_devs
local num_remaining_devs=999
while num_devs=$(dm_table | grep "$prefix" | wc -l) && \
test $num_devs -lt $num_remaining_devs -a $num_devs -ne 0; do
test "$stray" -eq 0 || echo "Removing $num_devs stray mapped devices with names beginning with $prefix: "
# HACK: sort also by minors - so we try to close 'possibly later' created device first
# HACK: sort also by minors - so we try to close 'possibly later' created device first
for dm in $(dm_info name --sort open,-minor | grep "$prefix") ; do
dmsetup remove -f "$dm" || true
done
@@ -794,6 +799,7 @@ prepare_devs() {
local size=$(($devsize*2048)) # sectors
local count=0
rm -f CREATE_FAILED
init_udev_transaction
for i in $(seq 1 $n); do
local name="${PREFIX}$pvname$i"
@@ -801,17 +807,19 @@ prepare_devs() {
DEVICES[$count]=$dev
count=$(( $count + 1 ))
echo 0 $size linear "$BACKING_DEV" $((($i-1)*$size + $shift)) > "$name.table"
if not dmsetup create -u "TEST-$name" "$name" "$name.table" &&
test -n "$LVM_TEST_BACKING_DEVICE";
then # maybe the backing device is too small for this test
LVM_TEST_BACKING_DEVICE=
rm -f BACKING_DEV
prepare_devs "$@"
return $?
fi
dmsetup create -u "TEST-$name" "$name" "$name.table" || touch CREATE_FAILED &
test -f CREATE_FAILED && break;
done
wait
finish_udev_transaction
if test -f CREATE_FAILED -a -n "$LVM_TEST_BACKING_DEVICE"; then
LVM_TEST_BACKING_DEVICE=
rm -f BACKING_DEV CREATE_FAILED
prepare_devs "$@"
return $?
fi
# non-ephemeral devices need to be cleared between tests
test -f LOOP || for d in ${DEVICES[@]}; do
blkdiscard "$d" 2>/dev/null || true
@@ -833,9 +841,11 @@ prepare_devs() {
# ( IFS=$'\n'; echo "${DEVICES[*]}" ) >DEVICES
echo "ok"
for dev in "${DEVICES[@]}"; do
notify_lvmetad "$dev"
done
if test -e LOCAL_LVMETAD; then
for dev in "${DEVICES[@]}"; do
notify_lvmetad "$dev"
done
fi
}
@@ -856,7 +866,7 @@ common_dev_() {
else
test -z "${offsets[@]}" && offsets="0:"
fi ;;
error) offsets=${@:3}
error|zero) offsets=${@:3}
test -z "${offsets[@]}" && offsets="0:" ;;
esac
@@ -883,8 +893,8 @@ common_dev_() {
case "$tgtype" in
delay)
echo "$from $len delay $pvdev $(($pos + $offset)) $read_ms $pvdev $(($pos + $offset)) $write_ms" ;;
error)
echo "$from $len error" ;;
error|zero)
echo "$from $len $tgtype" ;;
esac
pos=$(($pos + $len))
done > "$name.devtable"
@@ -1003,12 +1013,23 @@ restore_from_devtable() {
#
# Convert device to device with errors
# Takes the list of pairs of error segment from:len
# Original device table is replace with multiple lines
# Combination with zero or delay is unsupported
# Original device table is replaced with multiple lines
# i.e. error_dev "$dev1" 8:32 96:8
error_dev() {
common_dev_ error "$@"
}
#
# Convert existing device to a device with zero segments
# Takes the list of pairs of zero segment from:len
# Combination with error or delay is unsupported
# Original device table is replaced with multiple lines
# i.e. zero_dev "$dev1" 8:32 96:8
zero_dev() {
common_dev_ zero "$@"
}
backup_dev() {
local dev
@@ -1413,10 +1434,10 @@ have_raid() {
}
have_raid4 () {
local r=1
local r=0
have_raid 1 8 0 && r=0
have_raid 1 9 1 && r=1
have_raid 1 8 0 && r=1
have_raid 1 9 1 && r=0
return $r
}

View File

@@ -77,6 +77,11 @@ find "$TESTOLDPWD/lib" ! \( -name '*.sh' -o -name '*.[cdo]' \
DM_DEFAULT_NAME_MANGLING_MODE=none
DM_DEV_DIR="$TESTDIR/dev"
LVM_SYSTEM_DIR="$TESTDIR/etc"
# abort on the internal dm errors in the tests (allowing test user override)
DM_ABORT_ON_INTERNAL_ERRORS=${DM_ABORT_ON_INTERNAL_ERRORS:-1}
export DM_DEFAULT_NAME_MANGLING_MODE DM_DEV_DIR LVM_SYSTEM_DIR DM_ABORT_ON_INTERNAL_ERRORS
mkdir "$LVM_SYSTEM_DIR" "$DM_DEV_DIR"
if test -n "$LVM_TEST_DEVDIR" ; then
test -d "$LVM_TEST_DEVDIR" || die "Test device directory LVM_TEST_DEVDIR=\"$LVM_TEST_DEVDIR\" is not valid."
@@ -85,14 +90,11 @@ else
mknod "$DM_DEV_DIR/testnull" c 1 3 || die "mknod failed"
echo >"$DM_DEV_DIR/testnull" || \
die "Filesystem does support devices in $DM_DEV_DIR (mounted with nodev?)"
mkdir "$DM_DEV_DIR/mapper"
# dmsetup makes here needed control entry if still missing
dmsetup version || \
die "Dmsetup in $DM_DEV_DIR can't report version?"
fi
# abort on the internal dm errors in the tests (allowing test user override)
DM_ABORT_ON_INTERNAL_ERRORS=${DM_ABORT_ON_INTERNAL_ERRORS:-1}
export DM_DEFAULT_NAME_MANGLING_MODE DM_DEV_DIR LVM_SYSTEM_DIR DM_ABORT_ON_INTERNAL_ERRORS
echo "$TESTNAME" >TESTNAME
echo "Kernel is $(uname -a)"

View File

@@ -0,0 +1,72 @@
#!/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

@@ -0,0 +1,41 @@
#!/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, MA2110-1301 USA
SKIP_WITH_LVMLOCKD=1
SKIP_WITH_LVMPOLLD=1
. lib/inittest
which mkfs.ext4 || skip
aux have_raid 1 3 5 || skip
aux prepare_vg 4
for d in $dev1 $dev2 $dev3 $dev4
do
aux delay_dev $d 1
done
#
# Test writemostly prohibited on resyncrhonizing raid1
#
# Create 4-way striped LV
lvcreate -aey --ty raid1 -m 3 -L 32M -n $lv1 $vg
not lvchange -y --writemostly $dev1 $vg/$lv1
check lv_field $vg/$lv1 segtype "raid1"
check lv_field $vg/$lv1 stripes 4
check lv_attr_bit health $vg/${lv1}_rimage_0 "-"
aux wait_for_sync $vg $lv1
lvchange -y --writemostly $dev1 $vg/$lv1
check lv_attr_bit health $vg/${lv1}_rimage_0 "w"
vgremove -ff $vg

View File

@@ -14,6 +14,7 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
which mkfs.ext4 || skip
aux have_raid 1 9 0 || skip
aux prepare_vg 6
@@ -29,7 +30,7 @@ function _test_regionsize
lvconvert --yes -R $regionsize $vg/$lv
[ $? -ne 0 ] && return 1
check lv_field $vg/$lv regionsize "$regionsize_str"
fsck -fn /dev/mapper/$vg-$lv
fsck -fn "$DM_DEV_DIR/$vg/$lv"
}
function _test_regionsizes
@@ -47,13 +48,13 @@ function _test_regionsizes
}
# Create 3-way raid1
lvcreate --yes -aey --type raid1 -m 2 -R64K -L 64M -n $lv1 $vg
lvcreate --yes -aey --type raid1 -m 2 -R64K -L8M -n $lv1 $vg
check lv_field $vg/$lv1 segtype "raid1"
check lv_field $vg/$lv1 stripes 3
check lv_field $vg/$lv1 regionsize "64.00k"
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv1
mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
aux wait_for_sync $vg $lv1
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
_test_regionsizes raid1
@@ -61,14 +62,14 @@ _test_regionsizes raid1
lvremove --yes $vg
# Create 5-way raid6
lvcreate --yes -aey --type raid6 -i 3 --stripesize 128K -R 256K -L 64M -n $lv1 $vg
lvcreate --yes -aey --type raid6 -i 3 --stripesize 128K -R 256K -L8M -n $lv1 $vg
check lv_field $vg/$lv1 segtype "raid6"
check lv_field $vg/$lv1 stripes 5
check lv_field $vg/$lv1 stripesize "128.00k"
check lv_field $vg/$lv1 regionsize "256.00k"
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv1
mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
aux wait_for_sync $vg $lv1
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
_test_regionsizes raid6
@@ -76,14 +77,14 @@ _test_regionsizes raid6
lvremove --yes $vg
# Create 6-way raid01
lvcreate --yes -aey --type raid10 -i 3 -m 1 --stripesize 128K -R 256K -L 64M -n $lv1 $vg
lvcreate --yes -aey --type raid10 -i 3 -m 1 --stripesize 128K -R 256K -L8M -n $lv1 $vg
check lv_field $vg/$lv1 segtype "raid10"
check lv_field $vg/$lv1 stripes 6
check lv_field $vg/$lv1 stripesize "128.00k"
check lv_field $vg/$lv1 regionsize "256.00k"
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv1
mkfs.ext4 -t ext4 "$DM_DEV_DIR/$vg/$lv1"
aux wait_for_sync $vg $lv1
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
_test_regionsizes raid10

View File

@@ -14,12 +14,13 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
which mkfs.ext4 || skip
aux have_raid 1 9 0 || skip
correct_raid4_layout=0
aux have_raid 1 9 1 && correct_raid4_layout=1
aux prepare_vg 6 80
aux prepare_vg 8
function _lvcreate
{
@@ -33,8 +34,8 @@ function _lvcreate
lvcreate -y -aey --type $level -i $req_stripes -L $size -n $lv $vg
check lv_field $vg/$lv segtype "$level"
check lv_field $vg/$lv stripes $stripes
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv
fsck -fn /dev/mapper/$vg-$lv
mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
fsck -fn "$DM_DEV_DIR/$vg/$lv"
}
function _lvconvert
@@ -52,17 +53,16 @@ function _lvconvert
[ "${level:0:7}" = "striped" ] && wait_and_check=0
[ "${level:0:5}" = "raid0" ] && wait_and_check=0
lvconvert -y --ty $req_level $R $vg/$lv
[ $? -ne 0 ] && return $?
check lv_field $vg/$lv segtype "$level"
check lv_field $vg/$lv stripes $stripes
if [ "$wait_and_check" -eq 1 ]
then
fsck -fn /dev/mapper/$vg-$lv
fsck -fn "$DM_DEV_DIR/$vg/$lv"
aux wait_for_sync $vg $lv
fi
fsck -fn /dev/mapper/$vg-$lv
fsck -fn "$DM_DEV_DIR/$vg/$lv"
}
function _invalid_raid5_conversions
@@ -90,28 +90,28 @@ function _invalid_raid5_conversions
# aux delay_dev "$dev1" 1
# Create 3-way mirror
lvcreate --yes -aey --type mirror -R 64K -m 2 -L 64M -n $lv1 $vg
lvcreate --yes -aey --type mirror -R 64K -m 2 -L8M -n $lv1 $vg
check lv_field $vg/$lv1 segtype "mirror"
check lv_field $vg/$lv1 stripes 3
check lv_field $vg/$lv1 regionsize "64.00k"
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv1
mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
aux wait_for_sync $vg $lv1
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
# Convert 3-way to 4-way mirror
lvconvert -m 3 $vg/$lv1
check lv_field $vg/$lv1 segtype "mirror"
check lv_field $vg/$lv1 stripes 4
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
aux wait_for_sync $vg $lv1
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
# Takeover 4-way mirror to raid1
lvconvert --yes --type raid1 -R 64k $vg/$lv1
check lv_field $vg/$lv1 segtype "raid1"
check lv_field $vg/$lv1 stripes 4
check lv_field $vg/$lv1 regionsize "64.00k"
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
## Convert 4-way raid1 to 5-way
lvconvert -m 4 -R 128K $vg/$lv1
@@ -119,9 +119,9 @@ check lv_field $vg/$lv1 segtype "raid1"
check lv_field $vg/$lv1 stripes 5
# FIXME: once lv_raid_chanage_image_count() supports region_size changes
not check lv_field $vg/$lv1 regionsize "128.00k"
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
aux wait_for_sync $vg $lv1
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
# FIXME: enable once lvconvert rejects early
## Try converting 4-way raid1 to 9-way
@@ -136,7 +136,7 @@ dmsetup status $vg-$lv1
dmsetup table $vg-$lv1
check lv_field $vg/$lv1 segtype "raid1"
check lv_field $vg/$lv1 stripes 2
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
# Convert 2-way raid1 to mirror
lvconvert --yes --type mirror -R 32K $vg/$lv1
@@ -144,7 +144,7 @@ check lv_field $vg/$lv1 segtype "mirror"
check lv_field $vg/$lv1 stripes 2
check lv_field $vg/$lv1 regionsize "32.00k"
aux wait_for_sync $vg $lv1
fsck -fn /dev/mapper/$vg-$lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
aux wait_for_sync $vg $lv1
# Clean up
@@ -159,10 +159,11 @@ then
#
# Create 3-way striped raid4 (4 legs total)
_lvcreate raid4 3 4 64M $vg $lv1
_lvcreate raid4 3 4 8M $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
@@ -195,6 +196,7 @@ _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
@@ -242,11 +244,35 @@ _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
# Create + convert 4-way raid5 variations
_lvcreate raid5 4 5 64M $vg $lv1
_lvcreate raid5 4 5 8M $vg $lv1
aux wait_for_sync $vg $lv1
_invalid_raid5_conversions $vg $lv1
not _lvconvert raid6_rs_6 raid6_rs_6 6 $vg $lv1
@@ -256,7 +282,7 @@ _lvconvert raid6_ls_6 raid6_ls_6 6 $vg $lv1
_lvconvert raid5_ls raid5_ls 5 $vg $lv1
lvremove -y $vg
_lvcreate raid5_ls 4 5 64M $vg $lv1
_lvcreate raid5_ls 4 5 8M $vg $lv1
aux wait_for_sync $vg $lv1
_invalid_raid5_conversions $vg $lv1
not _lvconvert raid6_rs_6 raid6_rs_6 6 $vg $lv1
@@ -266,7 +292,7 @@ _lvconvert raid6_ls_6 raid6_ls_6 6 $vg $lv1
_lvconvert raid5_ls raid5_ls 5 $vg $lv1
lvremove -y $vg
_lvcreate raid5_rs 4 5 64M $vg $lv1
_lvcreate raid5_rs 4 5 8M $vg $lv1
aux wait_for_sync $vg $lv1
_invalid_raid5_conversions $vg $lv1
not _lvconvert raid6_ra_6 raid6_ra_6 6 $vg $lv1
@@ -276,7 +302,7 @@ _lvconvert raid6_rs_6 raid6_rs_6 6 $vg $lv1
_lvconvert raid5_rs raid5_rs 5 $vg $lv1
lvremove -y $vg
_lvcreate raid5_la 4 5 64M $vg $lv1
_lvcreate raid5_la 4 5 8M $vg $lv1
aux wait_for_sync $vg $lv1
_invalid_raid5_conversions $vg $lv1
not _lvconvert raid6_ls_6 raid6_ls_6 6 $vg $lv1
@@ -286,7 +312,7 @@ _lvconvert raid6_la_6 raid6_la_6 6 $vg $lv1
_lvconvert raid5_la raid5_la 5 $vg $lv1
lvremove -y $vg
_lvcreate raid5_ra 4 5 64M $vg $lv1
_lvcreate raid5_ra 4 5 8M $vg $lv1
aux wait_for_sync $vg $lv1
_invalid_raid5_conversions $vg $lv1
not _lvconvert raid6_ls_6 raid6_ls_6 6 $vg $lv1
@@ -298,7 +324,7 @@ lvremove -y $vg
else
not lvcreate -y -aey --type raid4 -i 3 -L 64M -n $lv4 $vg
not lvcreate -y -aey --type raid4 -i 3 -L8M -n $lv4 $vg
not lvconvert -y --ty raid4 $vg/$lv1
not lvconvert -y --ty raid4 $vg/$lv2

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
aux prepare_vg 8 80
function delay
{

View File

@@ -28,7 +28,7 @@ grep "$dev1" out
# check for RHBZ 1080189 -- SEGV in lvremove/vgremove
pvcreate -ff -y --metadatatype 1 "$dev1" "$dev2"
vgcreate --metadatatype 1 $vg1 "$dev1" "$dev2"
lvcreate -l1 $vg1
lvcreate -l1 $vg1 "$dev1"
pvremove -ff -y "$dev2"
vgchange -an $vg1
not lvremove $vg1

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
# Copyright (C) 2012,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
@@ -16,10 +16,11 @@ SKIP_WITH_LVMPOLLD=1
aux have_raid 1 3 0 || skip
levels="5 6"
aux have_raid4 && levels="4 5 6"
levels="5 6 10"
aux have_raid4 && levels="4 $levels"
aux have_raid 1 7 0 && levels="0 0_meta $levels"
aux prepare_pvs 6 80
aux prepare_pvs 6
vgcreate -s 256K $vg $(cat DEVICES)
@@ -39,9 +40,10 @@ for deactivate in true false; do
#check raid_images_contiguous $vg $lv1
# Extend and reduce 3-striped RAID 4/5/6
# Extend and reduce 3-striped RAID 4/5/6/10
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
@@ -49,10 +51,12 @@ 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

@@ -34,9 +34,26 @@ lvremove -ff $vg
lvcreate -L 10M -n lv $vg "$dev1"
lvextend -L +10M $vg/lv "$dev2"
lvextend --type striped -m0 -L +10M $vg/lv "$dev2"
# Attempt to reduce with lvextend and vice versa:
not lvextend -L 16M $vg/lv
not lvreduce -L 32M $vg/lv
lvremove -ff $vg
lvcreate --type mirror -aey -L 4 -n $lv1 $vg
# Incorrent name for resized LV
not lvextend --type mirror -L 10 -n $lv1 $vg
# Same size
not lvextend --type mirror -L 4 $vg/$lv1
# Cannot use any '-' or '+' sign for --mirror arg
not lvextend --type mirror -L+2 -m-1 $vg/$lv1
not lvextend --type mirror -L+2 -m+1 $vg/$lv1
lvextend --type mirror -L+4 -m1 $vg/$lv1
lvs -a $vg
check lv_field $vg/$lv1 size "8.00m"
lvremove -ff $vg

View File

@@ -33,9 +33,9 @@ test_pvmove_resume() {
# next LV on same VG and differetnt PV (we want to test 2 pvmoves per VG)
lvcreate -an -Zn -l30 -n $lv2 $vg "$dev3"
aux delay_dev "$dev4" 0 250
aux delay_dev "$dev4" 0 250 $(get first_extent_sector "$dev4"):
test -e HAVE_DM_DELAY || { lvremove -f $vg; return 0; }
aux delay_dev "$dev5" 0 250
aux delay_dev "$dev5" 0 250 $(get first_extent_sector "$dev5"):
pvmove -i5 "$dev1" "$dev4" &
PVMOVE=$!

View File

@@ -42,8 +42,6 @@ export MKE2FS_CONFIG="$TESTDIR/lib/mke2fs.conf"
aux have_thin 1 0 0 || skip
aux lvmconf "dmeventd/thin_command = \"$PWD/testcmd.sh\""
# Simple implementation of umount when lvextend fails
cat <<- EOF >testcmd.sh
#!/bin/sh
@@ -54,27 +52,27 @@ echo "Metadata: \$DMEVENTD_THIN_POOL_METADATA"
$TESTDIR/lib/lvextend --use-policies \$1 || {
umount "$mntdir" || true
umount "$mntusedir" || true
return 1
return 0
}
test \$($TESTDIR/lib/lvs -o selected -S "data_percent>95||metadata_percent>95" --noheadings \$1) -eq 0 || {
umount "$mntdir" || true
umount "$mntusedir" || true
return 1
return 0
}
EOF
chmod +x testcmd.sh
# Show prepared script
cat testcmd.sh
aux prepare_dmeventd
# Use autoextend percent 0 - so extension fails and triggers umount...
aux lvmconf "activation/thin_pool_autoextend_percent = 0" \
"activation/thin_pool_autoextend_threshold = 70"
"activation/thin_pool_autoextend_threshold = 70" \
"dmeventd/thin_command = \"/$PWD/testcmd.sh\""
aux prepare_dmeventd
aux prepare_vg 2
lvcreate -L8M -V8M -n $lv1 -T $vg/pool
lvcreate -V8M -n $lv2 -T $vg/pool
@@ -85,8 +83,8 @@ lvchange --monitor y $vg/pool
mkdir "$mntdir" "$mntusedir"
trap 'cleanup_mounted_and_teardown' EXIT
mount "$DM_DEV_DIR/mapper/$vg-$lv1" "$mntdir"
mount "$DM_DEV_DIR/mapper/$vg-$lv2" "$mntusedir"
mount "$DM_DEV_DIR/$vg/$lv1" "$mntdir"
mount "$DM_DEV_DIR/$vg/$lv2" "$mntusedir"
# Check both LVs are opened (~mounted)
is_lv_opened_ "$vg/$lv1"

View File

@@ -173,14 +173,7 @@ liblvm2cmd.$(LIB_SUFFIX).$(LIB_VERSION): liblvm2cmd.$(LIB_SUFFIX)
.commands: $(srcdir)/commands.h $(srcdir)/cmdnames.h Makefile
$(CC) -E -P $(srcdir)/cmdnames.h 2> /dev/null | \
egrep -v '^ *(|#.*|config|devtypes|dumpconfig|formats|fullreport|help|lastlog|lvpoll|pvdata|segtypes|systemid|tags|version) *$$' > .commands
.DELETE_ON_ERROR:
# move properly to configure
WC = /usr/bin/wc
GREP = /bin/grep
SORT = /bin/sort
$(EGREP) -v '^ *(|#.*|config|devtypes|dumpconfig|formats|fullreport|help|lastlog|lvpoll|pvdata|segtypes|systemid|tags|version) *$$' > .commands
command-count.h: $(srcdir)/command-lines.in Makefile
set -o pipefail && \
@@ -204,11 +197,12 @@ command-lines-input.h: $(srcdir)/command-lines.in Makefile
( cat $(top_srcdir)/doc/license.txt && \
echo "/* Do not edit. This file is generated by the Makefile. */" && \
echo -en "const char _command_input[] =\n\n\"" && \
$(GREP) -Ev '^#|\-\-\-|^$$' $(srcdir)/command-lines.in | $(AWK) 'BEGIN {ORS = "\\n\"\n\""} //' && \
$(EGREP) -v '^#|\-\-\-|^$$' $(srcdir)/command-lines.in | $(AWK) 'BEGIN {ORS = "\\n\"\n\""} //' && \
echo "\\n\";" \
) > $@
$(SOURCES:%.c=%.d) $(SOURCES2:%.c=%.d): command-lines-input.h command-count.h cmds.h
$(SOURCES:%.c=%.o) $(SOURCES2:%.c=%.o): command-lines-input.h command-count.h cmds.h
ifneq ("$(CFLOW_CMD)", "")
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))

View File

@@ -244,6 +244,9 @@ arg(locktype_ARG, '\0', "locktype", locktype_VAL, 0, 0,
arg(logonly_ARG, '\0', "logonly", 0, 0, 0,
"Suppress command report and display only log report.\n")
arg(longhelp_ARG, '\0', "longhelp", 0, 0, 0,
"Display long help text.\n")
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", sizekb_VAL, 0, 0,
"Sets the maximum recovery rate for a RAID LV. The rate value\n"
"is an amount of data per second for each device in the array.\n"
@@ -543,7 +546,7 @@ arg(shared_ARG, '\0', "shared", 0, 0, 0,
arg(sinceversion_ARG, '\0', "sinceversion", string_VAL, 0, 0,
"Specify an LVM version in x.y.z format where x is the major version,\n"
"the y is the minor version and z is the patchlevel (e.g. 2.2.106).\n"
"This option is currently applicable only with --type new\n"
"This option is currently applicable only with --typeconfig new\n"
"to display all configuration settings introduced since given version.\n")
arg(splitcache_ARG, '\0', "splitcache", 0, 0, 0,
@@ -586,9 +589,12 @@ arg(stripes_long_ARG, '\0', "stripes", number_VAL, 0, 0,
"existing allocated space, only newly allocated space can be striped.\n")
arg(swapmetadata_ARG, '\0', "swapmetadata", 0, 0, 0,
"Remove the metadata LV in a pool and replace it with another specified LV.\n"
"The removed LV is preserved and given the name of the LV that replaced it.\n"
"Used for repair only.\n")
"Extracts the metadata LV from a pool and replaces it with another specified LV.\n"
"The extracted LV is preserved and given the name of the LV that replaced it.\n"
"Use for repair only. When the metadata LV is swapped out of the pool, it can\n"
"be activated directly and used with thin provisioning tools:\n"
"\\fBcache_dump\\fP(8), \\fBcache_repair\\fP(8), \\fBcache_restore\\fP(8),\n"
"\\fBthin_dump\\fP(8), \\fBthin_repair\\fP(8), \\fBthin_restore\\fP(8).\n")
arg(syncaction_ARG, '\0', "syncaction", syncaction_VAL, 0, 0,
"Initiate different types of RAID synchronization.\n"
@@ -640,7 +646,16 @@ arg(trustcache_ARG, '\0', "trustcache", 0, 0, 0,
"Avoids certain device scanning during command processing. Do not use.\n")
arg(type_ARG, '\0', "type", segtype_VAL, 0, 0,
"Specifies an LV type, or \"segment type\".\n")
"Specifies an LV type, or \"segment type\".\n"
"See usage definitions for specific ways to use these types.\n"
"For more information about redundancy and performance (\\fBraid\\fP<N>, \\fBmirror\\fP, \\fBstriped\\fP, \\fBlinear\\fP) see \\fBlvmraid\\fP(7).\n"
"For thin provisioning (\\fBthin\\fP, \\fBthin-pool\\fP) see \\fBlvmthin\\fP(7).\n"
"For performance caching (\\fBcache\\fP, \\fBcache-pool\\fP) see \\fBlvmcache\\fP(7).\n"
"For copy-on-write snapshots (\\fBsnapshot\\fP) see usage definitions.\n"
"Several commands omit an explicit type option because the type\n"
"is inferred from other options or shortcuts\n"
"(e.g. --stripes, --mirrors, --snapshot, --virtualsize, --thin, --cache).\n"
"Use inferred types with care because it can lead to unexpected results.\n")
arg(unbuffered_ARG, '\0', "unbuffered", 0, 0, 0,
"Produce output immediately without sorting or aligning the columns properly.\n")
@@ -666,10 +681,12 @@ arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0,
"Internal option used for generating config file during build.\n")
arg(units_ARG, '\0', "units", units_VAL, 0, 0,
"All sizes are output in these units: (h)uman-readable, (b)ytes, (s)ectors,\n"
"(k)ilobytes, (m)egabytes, (g)igabytes, (t)erabytes, (p)etabytes, (e)xabytes.\n"
"Capitalise to use multiples of 1000 (S.I.) instead of 1024. Can also specify\n"
"custom units e.g. --units 3M.\n")
"All sizes are output in these units:\n"
"human-(r)eadable with '<' rounding indicator,\n"
"(h)uman-readable, (b)ytes, (s)ectors, (k)ilobytes, (m)egabytes,\n"
"(g)igabytes, (t)erabytes, (p)etabytes, (e)xabytes.\n"
"Capitalise to use multiples of 1000 (S.I.) instead of 1024.\n"
"Custom units can be specified, e.g. --units 3M.\n")
arg(unquoted_ARG, '\0', "unquoted", 0, 0, 0,
"When used with --nameprefixes, output values in the field=value\n"
@@ -920,8 +937,8 @@ arg(force_ARG, 'f', "force", 0, ARG_COUNTABLE, 0,
/* Not used. */
arg(full_ARG, 'f', "full", 0, 0, 0, NULL)
arg(help_ARG, 'h', "help", 0, ARG_COUNTABLE, 0,
"Display help text. Repeat this option for more information.\n")
arg(help_ARG, 'h', "help", 0, 0, 0,
"Display help text.\n")
arg(cache_ARG, 'H', "cache", 0, 0, 0,
"Specifies the command is handling a cache LV or cache pool.\n"
@@ -1015,7 +1032,7 @@ arg(list_ARG, 'l', "list", 0, 0, 0,
"#dumpconfig\n"
"#config\n"
"List config settings with summarizing comment. This is the same as using\n"
"options --type list --withsummary.\n"
"options --typeconfig list --withsummary.\n"
"#vgcfgrestore\n"
"List metadata backup and archive files pertaining to the VG.\n"
"May be used with --file. Does not restore the VG.\n"
@@ -1363,7 +1380,8 @@ arg(resizeable_ARG, 'x', "resizeable", bool_VAL, 0, 0,
arg(yes_ARG, 'y', "yes", 0, 0, 0,
"Do not prompt for confirmation interactively but always assume the\n"
"answer yes. Use with extreme caution.\n")
"answer yes. Use with extreme caution.\n"
"(For automatic no, see -qq.)\n")
arg(zero_ARG, 'Z', "zero", bool_VAL, 0, 0,
"#lvchange\n"

View File

@@ -187,23 +187,9 @@
# OO_ALL is included in every command automatically.
#
OO_ALL: --commandprofile String, --config String, --debug,
--driverloaded Bool, --help, --profile String, --quiet,
--driverloaded Bool, --help, --longhelp, --profile String, --quiet,
--verbose, --version, --yes, --test
#
# This list only applies to printing the usage text.
# These common options are displayed once at the end of
# a given command's usage. This is done to avoid excessive
# repetition of common options, which may obscure the more
# interesting and relevant parts of a common prototype.
# This definition is *only* used when generating the command
# usage strings, and is the basis for the division between
# the "usage" and "usage_common" strings. This OO defn does
# not relate to which optional opts are accepted by commands,
# which is defined by the OO line.
#
OO_USAGE_COMMON: OO_ALL, --force, --noudevsync
#
# options for pvs, lvs, vgs, fullreport
#
@@ -250,7 +236,9 @@ OO_LVCHANGE_META: --addtag Tag, --deltag Tag,
lvchange OO_LVCHANGE_META VG|LV|Tag|Select ...
OO: --activate Active, OO_LVCHANGE
ID: lvchange_properties
DESC: Change a general LV property.
DESC: Change a general LV attribute.
DESC: For options listed in parentheses, any one is
DESC: required, after which the others are optional.
RULE: all not lv_is_pvmove lv_is_mirror_log lv_is_mirror_image
RULE: all and lv_is_vg_writable
RULE: --contiguous not --alloc
@@ -454,17 +442,36 @@ DESC: Convert LV to type thin-pool.
RULE: all and lv_is_visible
RULE: all not lv_is_locked lv_is_origin lv_is_merging_origin lv_is_external_origin lv_is_virtual
# alternate form of lvconvert --type thin-pool
# deprecated because of non-standard syntax (missing positional arg)
# Commands in this form are converted to standard form so that
# the validation of LV types and rules specified above will apply.
lvconvert --thinpool LV_linear_striped_raid_cache
# This command syntax has two different meanings depending on
# whether the LV pos arg is already a thin pool or not.
#
# 1. When the LV arg is not a pool, this command converts
# the LV into a pool, optionally using a specified meta LV.
# This is an alternate form of the primary command:
# lvconvert --type thin-pool LV
#
# 2. When the LV is is already a pool and a meta LV is specified,
# the meta LV is swapped. Swapping a meta LV is a very specialized
# operation that users should never use.
# This is an alternate form of the primary command:
# lvconvert --swapmetadata --poolmetadata LV LV
#
# The command def cannot include --poolmetadata as a required
# option, otherwise 1 would not pass, so the validation of
# this option cannot be done by the command defs, but has to
# be done ad hoc in the lvconvert implementation.
#
# This command syntax is deprecated, and the primary forms
# of creating a pool or swapping metadata should be used.
lvconvert --thinpool LV_linear_striped_raid_cache_thinpool
OO: --type thin-pool, --stripes_long Number, --stripesize SizeKB,
--discards Discards, --zero Bool, OO_LVCONVERT_POOL, OO_LVCONVERT
OP: PV ...
ID: lvconvert_to_thinpool_noarg
ID: lvconvert_to_thinpool_or_swap_metadata
DESC: Convert LV to type thin-pool (variant, use --type thin-pool).
FLAGS: SECONDARY_SYNTAX
DESC: Swap metadata LV in a thin pool (variant, use --swapmetadata).
FLAGS: PREVIOUS_SYNTAX
---
@@ -475,17 +482,36 @@ OP: PV ...
ID: lvconvert_to_cachepool
DESC: Convert LV to type cache-pool.
# alternate form of lvconvert --type cache-pool
# deprecated because of non-standard syntax (missing positional arg)
# Commands in this form are converted to standard form so that
# the validation of LV types and rules specified above will apply.
lvconvert --cachepool LV_linear_striped_raid
# This command syntax has two different meanings depending on
# whether the LV pos arg is already a cache pool or not.
#
# 1. When the LV arg is not a pool, this command converts
# the LV into a pool, optionally using a specified meta LV.
# This is an alternate form of the primary command:
# lvconvert --type cache-pool LV
#
# 2. When the LV is is already a pool and a meta LV is specified,
# the meta LV is swapped. Swapping a meta LV is a very specialized
# operation that users should never use.
# This is an alternate form of the primary command:
# lvconvert --swapmetadata --poolmetadata LV LV
#
# The command def cannot include --poolmetadata as a required
# option, otherwise 1 would not pass, so the validation of
# this option cannot be done by the command defs, but has to
# be done ad hoc in the lvconvert implementation.
#
# This command syntax is deprecated, and the primary forms
# of creating a pool or swapping metadata should be used.
lvconvert --cachepool LV_linear_striped_raid_cachepool
OO: --type cache-pool, OO_LVCONVERT_POOL, OO_LVCONVERT,
--cachemode CacheMode, --cachepolicy String, --cachesettings String
OP: PV ...
ID: lvconvert_to_cachepool_noarg
ID: lvconvert_to_cachepool_or_swap_metadata
DESC: Convert LV to type cache-pool (variant, use --type cache-pool).
FLAGS: SECONDARY_SYNTAX
DESC: Swap metadata LV in a cache pool (variant, use --swapmetadata).
FLAGS: PREVIOUS_SYNTAX
---
@@ -1088,12 +1114,17 @@ ID: lvdisplay_general
---
# --type is an option in lvextend/lvresize only so that the specified type
# value can be checked to match the existing type; using it doesn't
# currently enable any different behavior.
# --extents is not specified; it's an automatic alternative for --size
lvextend --size SizeMB LV
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
--nofsck, --nosync, --noudevsync, --reportformat ReportFmt, --resizefs,
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB,
--type SegType
OP: PV ...
ID: lvextend_by_size
DESC: Extend an LV by a specified size.
@@ -1101,7 +1132,8 @@ DESC: Extend an LV by a specified size.
lvextend LV PV ...
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
--nofsck, --nosync, --noudevsync,
--reportformat ReportFmt, --resizefs, --stripes Number, --stripesize SizeKB
--reportformat ReportFmt, --resizefs, --stripes Number, --stripesize SizeKB,
--type SegType
ID: lvextend_by_pv
DESC: Extend an LV by specified PV extents.
FLAGS: SECONDARY_SYNTAX
@@ -1109,7 +1141,8 @@ FLAGS: SECONDARY_SYNTAX
lvextend --poolmetadatasize SizeMB LV_thinpool
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
--nofsck, --nosync, --noudevsync,
--reportformat ReportFmt, --stripes Number, --stripesize SizeKB
--reportformat ReportFmt, --stripes Number, --stripesize SizeKB,
--type SegType
OP: PV ...
ID: lvextend_pool_metadata_by_size
DESC: Extend a pool metadata SubLV by a specified size.
@@ -1117,7 +1150,8 @@ DESC: Extend a pool metadata SubLV by a specified size.
lvextend --usepolicies LV_thinpool_snapshot
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
--nofsck, --nosync, --noudevsync,
--reportformat ReportFmt, --resizefs
--reportformat ReportFmt, --resizefs,
--type SegType
OP: PV ...
ID: lvextend_by_policy
DESC: Extend an LV according to a predefined policy.
@@ -1155,10 +1189,15 @@ ID: lvrename_lv_lv
---
# --type is an option in lvextend/lvresize only so that the specified type
# value can be checked to match the existing type; using it doesn't
# currently enable any different behavior.
lvresize --size SizeMB LV
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync, --reportformat ReportFmt, --resizefs,
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB,
--type SegType
OP: PV ...
ID: lvresize_by_size
DESC: Resize an LV by a specified size.
@@ -1166,7 +1205,8 @@ DESC: Resize an LV by a specified size.
lvresize LV PV ...
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync,
--reportformat ReportFmt, --resizefs, --stripes Number, --stripesize SizeKB
--reportformat ReportFmt, --resizefs, --stripes Number, --stripesize SizeKB,
--type SegType
ID: lvresize_by_pv
DESC: Resize an LV by specified PV extents.
FLAGS: SECONDARY_SYNTAX
@@ -1174,7 +1214,8 @@ FLAGS: SECONDARY_SYNTAX
lvresize --poolmetadatasize SizeMB LV_thinpool
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync,
--reportformat ReportFmt, --stripes Number, --stripesize SizeKB
--reportformat ReportFmt, --stripes Number, --stripesize SizeKB,
--type SegType
OP: PV ...
ID: lvresize_pool_metadata_by_size
DESC: Resize a pool metadata SubLV by a specified size.
@@ -1355,7 +1396,9 @@ vgchange OO_VGCHANGE_META
OO: OO_VGCHANGE
OP: VG|Tag|Select ...
ID: vgchange_properties
DESC: Change a general VG property.
DESC: Change a general VG attribute.
DESC: For options listed in parentheses, any one is
DESC: required, after which the others are optional.
vgchange --monitor Bool
OO: --sysinit, --ignorelockingfailure, --poll Bool, OO_VGCHANGE

File diff suppressed because it is too large Load Diff

View File

@@ -69,7 +69,7 @@ struct command_name {
static inline int val_bit_is_set(uint64_t val_bits, int val_enum)
{
return (val_bits & (1 << val_enum)) ? 1 : 0;
return (val_bits & (1ULL << val_enum)) ? 1 : 0;
}
static inline uint64_t val_enum_to_bit(int val_enum)
@@ -79,7 +79,7 @@ static inline uint64_t val_enum_to_bit(int val_enum)
static inline int lvp_bit_is_set(uint64_t lvp_bits, int lvp_enum)
{
return (lvp_bits & (1 << lvp_enum)) ? 1 : 0;
return (lvp_bits & (1ULL << lvp_enum)) ? 1 : 0;
}
static inline uint64_t lvp_enum_to_bit(int lvp_enum)
@@ -89,7 +89,7 @@ static inline uint64_t lvp_enum_to_bit(int lvp_enum)
static inline int lvt_bit_is_set(uint64_t lvt_bits, int lvt_enum)
{
return (lvt_bits & (1 << lvt_enum)) ? 1 : 0;
return (lvt_bits & (1ULL << lvt_enum)) ? 1 : 0;
}
static inline uint64_t lvt_enum_to_bit(int lvt_enum)
@@ -166,6 +166,8 @@ struct cmd_rule {
*/
#define CMD_FLAG_ONE_REQUIRED_OPT 1 /* lvchange/vgchage require one item from required_opt_args */
#define CMD_FLAG_SECONDARY_SYNTAX 2 /* allows syntax variants to be suppressed in certain output */
#define CMD_FLAG_PREVIOUS_SYNTAX 4 /* allows syntax variants to not be advertised in output */
#define CMD_FLAG_PARSE_ERROR 8 /* error parsing command-lines.in def */
/* a register of the lvm commands */
struct command {
@@ -175,7 +177,7 @@ struct command {
int command_enum; /* <command_id>_CMD */
int command_index; /* position in commands[] */
struct command_function *functions; /* new style */
const struct command_function *functions; /* new style */
command_fn fn; /* old style */
unsigned int cmd_flags; /* CMD_FLAG_ */
@@ -209,9 +211,11 @@ struct command {
int pos_count; /* temp counter used by create-command */
};
int define_commands(void);
int define_commands(char *run_name);
int command_id_to_enum(const char *str);
void print_usage(struct command *cmd);
void print_usage_common(struct command_name *cname, struct command *cmd);
void print_usage(struct command *cmd, int longhelp);
void print_usage_common_cmd(struct command_name *cname, struct command *cmd);
void print_usage_common_lvm(struct command_name *cname, struct command *cmd);
void factor_common_options(void);
#endif

View File

@@ -2197,8 +2197,15 @@ static int _status(CMD_ARGS)
c++;
if (*c)
c++;
while (*c && *c != ' ')
*c++ = '0';
/*
* 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';
}
printf(FMTu64 " " FMTu64 " %s %s",
start, length, target_type, params);
@@ -5719,32 +5726,32 @@ static int _stats_help(CMD_ARGS);
* dmsetup stats <cmd> [options] [device_name]
* dmstats <cmd> [options] [device_name]
*
* clear [--allregions|--regionid id] [--alldevices|<device...>]
* clear [--allregions|--regionid id] [--alldevices|<device>...]
* create [--start <start> [--length <len>]
* [--areas <nr_areas>] [--areasize <size>]
* [--programid <id>] [--userdata <data> ]
* [--bounds histogram_boundaries] [--precise]
* [--alldevices|<device...>]
* [--alldevices|<device>...]
* create --filemap [--nogroup]
* [--programid <id>] [--userdata <data> ]
* [--bounds histogram_boundaries] [--precise] [<file_path>]
* delete [--allprograms|--programid id]
* [--allregions|--regionid id]
* [--alldevices|<device...>]
* [--alldevices|<device>...]
* group [--alias NAME] --regions <regions>
* [--allprograms|--programid id] [--alldevices|<device...>]
* [--allprograms|--programid id] [--alldevices|<device>...]
* list [--allprograms|--programid id] [--allregions|--regionid id]
* print [--clear] [--allprograms|--programid id]
* [--allregions|--regionid id]
* [--alldevices|<device...>]
* [--alldevices|<device>...]
* report [--interval <seconds>] [--count <cnt>]
* [--units <u>] [--programid <id>] [--regionid <id>]
* [-o <fields>] [-O|--sort <sort_fields>]
* [-S|--select <selection>] [--nameprefixes]
* [--noheadings] [--separator <separator>]
* [--allprograms|--programid id] [<device...>]
* [--allprograms|--programid id] [<device>...]
* ungroup --groupid <id> [--allprograms|--programid id]
* [--alldevices|<device...>]
* [--alldevices|<device>...]
*/
#define INDENT "\n\t "
@@ -5759,7 +5766,7 @@ static int _stats_help(CMD_ARGS);
#define EXTRA_OPTS HIST_OPTS PRECISE_OPTS
#define ALL_PROGS_OPT "[--allprograms|--programid id] "
#define ALL_REGIONS_OPT "[--allregions|--regionid id] "
#define ALL_DEVICES_OPT "[--alldevices|<device...>] "
#define ALL_DEVICES_OPT "[--alldevices|<device>...] "
#define ALL_PROGS_REGIONS_DEVICES ALL_PROGS_OPT INDENT ALL_REGIONS_OPT INDENT ALL_DEVICES_OPT
#define FIELD_OPTS "[-o <fields>] [-O|--sort <sort_fields>]"
#define DM_REPORT_OPTS FIELD_OPTS INDENT "[-S|--select <selection>] [--nameprefixes]" INDENT \
@@ -5788,7 +5795,7 @@ static struct command _stats_subcommands[] = {
{"group", GROUP_OPTS, 1, -1, 1, 0, _stats_group},
{"list", ALL_PROGS_OPT ALL_REGIONS_OPT, 0, -1, 1, 0, _stats_report},
{"print", PRINT_OPTS, 0, -1, 1, 0, _stats_print},
{"report", REPORT_OPTS "[<device...>]", 0, -1, 1, 0, _stats_report},
{"report", REPORT_OPTS "[<device>...]", 0, -1, 1, 0, _stats_report},
{"ungroup", "--groupid <id> " UNGROUP_OPTS, 1, -1, 1, 0, _stats_ungroup},
{"update_filemap", "--groupid <id> <file_path>", 1, 1, 0, 0, _stats_update_file},
{"version", "", 0, -1, 1, 0, _version},
@@ -5825,27 +5832,27 @@ static struct command _dmsetup_commands[] = {
"\t [-u|uuid <uuid>] [--addnodeonresume|--addnodeoncreate]\n"
"\t [--readahead {[+]<sectors>|auto|none}]\n"
"\t [-n|--notable|--table {<table>|<table_file>}]", 1, 2, 0, 0, _create},
{"remove", "[--deferred] [-f|--force] [--retry] <device>", 0, -1, 1, 0, _remove},
{"remove", "[--deferred] [-f|--force] [--retry] <device>...", 0, -1, 1, 0, _remove},
{"remove_all", "[-f|--force]", 0, 0, 0, 0, _remove_all},
{"suspend", "[--noflush] [--nolockfs] <device>", 0, -1, 1, 0, _suspend},
{"resume", "[--noflush] [--nolockfs] <device>\n"
{"suspend", "[--noflush] [--nolockfs] <device>...", 0, -1, 1, 0, _suspend},
{"resume", "[--noflush] [--nolockfs] <device>...\n"
"\t [--addnodeonresume|--addnodeoncreate]\n"
"\t [--readahead {[+]<sectors>|auto|none}]", 0, -1, 1, 0, _resume},
{"load", "<device> [<table>|<table_file>]", 0, 2, 0, 0, _load},
{"clear", "<device>", 0, -1, 1, 0, _clear},
{"reload", "<device> [<table>|<table_file>]", 0, 2, 0, 0, _load},
{"wipe_table", "[-f|--force] [--noflush] [--nolockfs] <device>", 1, -1, 1, 0, _error_device},
{"wipe_table", "[-f|--force] [--noflush] [--nolockfs] <device>...", 1, -1, 1, 0, _error_device},
{"rename", "<device> [--setuuid] <new_name_or_uuid>", 1, 2, 0, 0, _rename},
{"message", "<device> <sector> <message>", 2, -1, 0, 0, _message},
{"ls", "[--target <target_type>] [--exec <command>] [-o <options>] [--tree]", 0, 0, 0, 0, _ls},
{"info", "[<device>]", 0, -1, 1, 0, _info},
{"deps", "[-o <options>] [<device>]", 0, -1, 1, 0, _deps},
{"stats", "<command> [<options>] [<devices>]", 1, -1, 1, 1, _stats},
{"status", "[<device>] [--noflush] [--target <target_type>]", 0, -1, 1, 0, _status},
{"table", "[<device>] [--target <target_type>] [--showkeys]", 0, -1, 1, 0, _status},
{"info", "[<device>...]", 0, -1, 1, 0, _info},
{"deps", "[-o <options>] [<device>...]", 0, -1, 1, 0, _deps},
{"stats", "<command> [<options>] [<device>...]", 1, -1, 1, 1, _stats},
{"status", "[<device>...] [--noflush] [--target <target_type>]", 0, -1, 1, 0, _status},
{"table", "[<device>...] [--target <target_type>] [--showkeys]", 0, -1, 1, 0, _status},
{"wait", "<device> [<event_nr>] [--noflush]", 0, 2, 0, 0, _wait},
{"mknodes", "[<device>]", 0, -1, 1, 0, _mknodes},
{"mangle", "[<device>]", 0, -1, 1, 0, _mangle},
{"mknodes", "[<device>...]", 0, -1, 1, 0, _mknodes},
{"mangle", "[<device>...]", 0, -1, 1, 0, _mangle},
{"udevcreatecookie", "", 0, 0, 0, 0, _udevcreatecookie},
{"udevreleasecookie", "[<cookie>]", 0, 1, 0, 0, _udevreleasecookie},
{"udevflags", "<cookie>", 1, 1, 0, 0, _udevflags},
@@ -5887,8 +5894,7 @@ static void _stats_usage(FILE *out)
for (i = 0; _stats_subcommands[i].name; i++)
fprintf(out, "\t%s %s\n", _stats_subcommands[i].name, _stats_subcommands[i].help);
fprintf(out, "\n<device> may be device name or -u <uuid> or "
"-j <major> -m <minor>\n");
fprintf(out, "\n<device> may be device name or (if only one) -u <uuid> or -j <major> -m <minor>\n");
fprintf(out, "<fields> are comma-separated. Use 'help -c' for list.\n");
fprintf(out, "\n");
}
@@ -5913,7 +5919,7 @@ static void _dmsetup_usage(FILE *out)
for (i = 0; _dmsetup_commands[i].name; i++)
fprintf(out, "\t%s %s\n", _dmsetup_commands[i].name, _dmsetup_commands[i].help);
fprintf(out, "\n<device> may be device name or -u <uuid> or "
fprintf(out, "\n<device> may be device name or (if only one) -u <uuid> or "
"-j <major> -m <minor>\n");
fprintf(out, "<mangling_mode> is one of 'none', 'auto' and 'hex'.\n");
fprintf(out, "<fields> are comma-separated. Use 'help -c' for list.\n");

View File

@@ -739,6 +739,21 @@ static int _lvchange_writemostly(struct logical_volume *lv)
struct cmd_context *cmd = lv->vg->cmd;
struct lv_segment *raid_seg = first_seg(lv);
/*
* Prohibit writebehind and writebehind during synchronization.
*
* FIXME: we can do better once we can distingush between
* an initial sync after a linear -> raid1 upconversion
* and any later additions of legs, requested resyncs
* via lvchange or leg repairs/replacements.
*/
if (!lv_raid_in_sync(lv)) {
log_error("Unable to change write%s on %s while it is not in-sync.",
arg_is_set(cmd, writemostly_ARG) ? "mostly" : "behind",
display_lvname(lv));
return 0;
}
if (arg_is_set(cmd, writebehind_ARG))
raid_seg->writebehind = arg_uint_value(cmd, writebehind_ARG, 0);

View File

@@ -3649,6 +3649,43 @@ static int _lvconvert_combine_split_snapshot_single(struct cmd_context *cmd,
int lvconvert_combine_split_snapshot_cmd(struct cmd_context *cmd, int argc, char **argv)
{
const char *vgname = NULL;
const char *lvname1;
const char *lvname2;
char *vglv;
int vglv_sz;
/*
* Hack to accomodate an old parsing quirk that allowed the
* the VG name to be attached to only the LV in arg pos 1,
* i.e. lvconvert -s vgname/lvname lvname
*
* The LV name in arg pos 2 is the one that is processed
* by process_each_lv(). If that LV has no VG name, but
* the first LV does, then copy the VG name from arg pos 1
* and add it to the LV name in arg pos 2 so that the
* standard arg parsing in process_each_lv will find it.
*
* This is the only instance in all commands.
*/
lvname1 = cmd->position_argv[0];
lvname2 = cmd->position_argv[1];
if (strstr("/", lvname1) && !strstr("/", lvname2) && !getenv("LVM_VG_NAME")) {
if (!validate_lvname_param(cmd, &vgname, &lvname1))
return_ECMD_FAILED;
vglv_sz = strlen(vgname) + strlen(lvname2) + 2;
if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
dm_snprintf(vglv, vglv_sz, "%s/%s", vgname, lvname2) < 0) {
log_error("vg/lv string alloc failed.");
return_ECMD_FAILED;
}
cmd->position_argv[1] = vglv;
}
return process_each_lv(cmd, 1, cmd->position_argv + 1, NULL, NULL, READ_FOR_UPDATE,
NULL, NULL, &_lvconvert_combine_split_snapshot_single);
}
@@ -3753,51 +3790,6 @@ int lvconvert_to_pool_cmd(struct cmd_context *cmd, int argc, char **argv)
NULL, NULL, &_lvconvert_to_pool_single);
}
/*
* Reformats non-standard command form into standard command form.
*
* In the command variants with no position LV arg, the LV arg is taken from
* the --thinpool/--cachepool arg, and the position args are modified to match
* the standard command form.
*/
int lvconvert_to_pool_noarg_cmd(struct cmd_context *cmd, int argc, char **argv)
{
struct command *new_command;
char *pool_data_name;
int i, p;
switch (cmd->command->command_enum) {
case lvconvert_to_thinpool_noarg_CMD:
pool_data_name = (char *)arg_str_value(cmd, thinpool_ARG, NULL);
new_command = get_command(lvconvert_to_thinpool_CMD);
break;
case lvconvert_to_cachepool_noarg_CMD:
pool_data_name = (char *)arg_str_value(cmd, cachepool_ARG, NULL);
new_command = get_command(lvconvert_to_cachepool_CMD);
break;
default:
log_error(INTERNAL_ERROR "Unknown pool conversion.");
return 0;
};
log_debug("Changing command %d:%s to standard form %d:%s",
cmd->command->command_index, cmd->command->command_id,
new_command->command_index, new_command->command_id);
/* Make the LV the first position arg. */
p = cmd->position_argc;
for (i = 0; i < cmd->position_argc; i++)
cmd->position_argv[p] = cmd->position_argv[p-1];
cmd->position_argv[0] = pool_data_name;
cmd->position_argc++;
cmd->command = new_command;
return lvconvert_to_pool_cmd(cmd, argc, argv);
}
static int _lvconvert_to_cache_vol_single(struct cmd_context *cmd,
struct logical_volume *lv,
struct processing_handle *handle)
@@ -4040,39 +4032,96 @@ int lvconvert_swap_pool_metadata_cmd(struct cmd_context *cmd, int argc, char **a
NULL, NULL, &_lvconvert_swap_pool_metadata_single);
}
#if 0
int lvconvert_swap_pool_metadata_noarg_cmd(struct cmd_context *cmd, int argc, char **argv)
static int _lvconvert_to_pool_or_swap_metadata_single(struct cmd_context *cmd,
struct logical_volume *lv,
struct processing_handle *handle)
{
struct command *new_command;
char *pool_name;
struct dm_list *use_pvh = NULL;
int to_thinpool = 0;
int to_cachepool = 0;
switch (cmd->command->command_enum) {
case lvconvert_swap_thinpool_metadata_CMD:
pool_name = (char *)arg_str_value(cmd, thinpool_ARG, NULL);
case lvconvert_to_thinpool_or_swap_metadata_CMD:
to_thinpool = 1;
break;
case lvconvert_swap_cachepool_metadata_CMD:
pool_name = (char *)arg_str_value(cmd, cachepool_ARG, NULL);
case lvconvert_to_cachepool_or_swap_metadata_CMD:
to_cachepool = 1;
break;
default:
log_error(INTERNAL_ERROR "Invalid lvconvert pool command");
return 0;
};
if (cmd->position_argc > 1) {
/* First pos arg is required LV, remaining are optional PVs. */
if (!(use_pvh = create_pv_list(cmd->mem, lv->vg, cmd->position_argc - 1, cmd->position_argv + 1, 0)))
return_ECMD_FAILED;
} else
use_pvh = &lv->vg->pvs;
/*
* We can finally determine if this command is supposed to create
* a pool or swap the metadata in an existing pool.
*
* This allows the ambiguous command:
* 'lvconvert --thinpool LV1 --poolmetadata LV2' to mean either:
* 1. convert LV2 to a pool using the specified meta LV2
* 2. swap the meta lv in LV1 with LV2
*
* In case 2, the poolmetadata option is required, but in case 1
* it is optional. So, the command def is not able to validate
* the required/optional option, and we have to check here
* for missing poolmetadata in case 2.
*/
if (lv_is_pool(lv)) {
if (!arg_is_set(cmd, poolmetadata_ARG)) {
log_error("The --poolmetadata option is required to swap metadata.");
return ECMD_FAILED;
}
return _lvconvert_swap_pool_metadata_single(cmd, lv, handle);
}
if (!_lvconvert_to_pool(cmd, lv, to_thinpool, to_cachepool, use_pvh))
return_ECMD_FAILED;
return ECMD_PROCESSED;
}
/*
* In the command variants with no position LV arg, the LV arg is taken from
* the --thinpool/--cachepool arg, and the position args are modified to match
* the standard command form.
*/
int lvconvert_to_pool_or_swap_metadata_cmd(struct cmd_context *cmd, int argc, char **argv)
{
char *pool_data_name;
int i, p;
switch (cmd->command->command_enum) {
case lvconvert_to_thinpool_or_swap_metadata_CMD:
pool_data_name = (char *)arg_str_value(cmd, thinpool_ARG, NULL);
break;
case lvconvert_to_cachepool_or_swap_metadata_CMD:
pool_data_name = (char *)arg_str_value(cmd, cachepool_ARG, NULL);
break;
default:
log_error(INTERNAL_ERROR "Unknown pool conversion.");
return 0;
};
new_command = get_command(lvconvert_swap_pool_metadata_CMD);
log_debug("Changing command %d:%s to standard form %d:%s",
cmd->command->command_index, cmd->command->command_id,
new_command->command_index, new_command->command_id);
/* Make the LV the first position arg. */
cmd->position_argv[0] = pool_name;
cmd->position_argc++;
cmd->command = new_command;
p = cmd->position_argc;
for (i = 0; i < cmd->position_argc; i++)
cmd->position_argv[p] = cmd->position_argv[p-1];
return lvconvert_swap_pool_metadata_cmd(cmd, argc, argv);
cmd->position_argv[0] = pool_data_name;
cmd->position_argc++;
return process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
NULL, NULL, &_lvconvert_to_pool_or_swap_metadata_single);
}
#endif
static int _lvconvert_merge_thin_single(struct cmd_context *cmd,
struct logical_volume *lv,

View File

@@ -32,7 +32,7 @@ void *cmdlib_lvm2_init(unsigned static_compile);
void lvm_fin(struct cmd_context *cmd);
struct cmd_context *init_lvm(unsigned set_connections, unsigned set_filters);
void lvm_register_commands(void);
int lvm_register_commands(char *name);
int lvm_split(char *str, int *argc, char **argv, int max);
int lvm_run_command(struct cmd_context *cmd, int argc, char **argv);
int lvm_return_code(int ret);

View File

@@ -34,7 +34,8 @@ void *cmdlib_lvm2_init(unsigned static_compile)
if (!(cmd = init_lvm(1, 1)))
return NULL;
lvm_register_commands();
if (!lvm_register_commands(NULL))
return NULL;
return (void *) cmd;
}

Some files were not shown because too many files have changed in this diff Show More