1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-04-06 10:50:41 +03:00

Compare commits

...

511 Commits

Author SHA1 Message Date
Zdenek Kabelac
11b64b0c0c lvmcmdline: still support use of profile
Couple commands (lvcreate,lvconvert,vgcreate,lvchange,vgchange)
has the 'specific' property that within them the option --profile
behaves like --metadataprofile, while for all other commands this
option should be simply an alias for --commandprofile.

We may eventually drop this rather confusing behavior in the future
version and there will be only one use as --[command]profile

It should be noted this --commandprofile can be often used
instead of --config option for preconfiguring setting
for some group of commands - we should possibly more propagate
this usage.
2025-04-04 14:48:57 +02:00
Zdenek Kabelac
6838881956 libdm: fix missed init of regex pointer
Recent patch set for select enhancement missed to initialize
ssl struct element regex to NULL and this code might have
crashed on this code path evaluation.
2025-04-04 14:48:57 +02:00
Zdenek Kabelac
5d16beee57 WHATS_NEW: update 2025-04-01 15:37:36 +02:00
Zdenek Kabelac
26e86f9da9 make: generate 2025-04-01 15:37:36 +02:00
Zdenek Kabelac
b8b0fcfa10 cov: remove unused header 2025-04-01 15:37:36 +02:00
Zdenek Kabelac
6679438437 tests: check resize of snapshot with mounted origin 2025-04-01 15:37:36 +02:00
Zdenek Kabelac
1bf3961bbe tests: resize of mounted fs missed workaround
For older kernel, we need to suspend/resume.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
dcf37af2ca tests: preserve signess 2025-04-01 15:37:36 +02:00
Zdenek Kabelac
ebbdaccd9c tests: check unsupported vdo conversions
Validate unsupported vdo conversions are rejected.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
fafc0f76c5 tests: remove testing of old mirror with vdo
Actually mirror were never supposed to be usable with any newer
target as they are very problematic with any stacked usage.
So now it's going to be properly checked and prohibited.

Users are always supposed to use 'raid1' --type instead.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
491c6652ae command: use loop for short_opts pass
Slight refactoring of the code to take less size
as the code is used rather occasionally.

Correct some minor typographical issue.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
ea73594f07 man-generator: print LV1 also for options
We can print list of supported LV types for
options like --cachepool,--thinpool,--vdopool when
they are specifying particular LV.

TODO: while we nicely document them, the parser engine ATM
is not capable to validate and enforce these properties,
so the code needs to match them on its own.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
9ed7528d1f man-generator: add check for option overlap
Report --check error, when the option is required and optional
for the command.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
7becd29494 lvconvert: fix _lvconvert_visible_check ret code
_lvconvert_visible_check() used to validate visibility
of converted LV for changing mirrorlog, regionsize
and merging images.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
3687f7fee3 lvconvert: validate converted LV to vdopool
Although our command-line description file describes
supported types for conversion with some rules,
these are technically not yet fully implemented in
the code, thus we need explicit functionality to
validate passed LVs for conversion.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
74c178f7bf lvconvert: fix move is positional args
Properly shift args by 1 - hopefully 'argv[]' has the right size
to fit this single shift (as some option must have been there...)
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
82789f6134 lvconvert: simplify passing LV for conversion
Since command is defined to not taky any'free args',
we can actully avoid playing with positional args here
and just pass argv with a single arg.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
30fdd6b9b4 args: update name of kernel module
Use  '_' for kernel module name.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
63088e1f82 command-lines.in: matching vdopool conversion
Just use options in the same order as with --type vdo-pool
conversion.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
579054452b command-lines.in update some description
Add some explicit warning for commands that are destroying content
of converted volume.

Add thinpooldata to the list of allow LVs for caching
(as the code already support this).
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
253ef42362 command-lines.in: add info about implicity type
Short description about how the default implied type
is selected for this lvcreate command.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
54831ecabd command: update parameter from description
Parameter --profile is already 'generic' parameter,
so it's been listed twice in lvchange & vgchange.

Parameter --uuid was listed 2x in pvchange.
2025-04-01 15:37:36 +02:00
Zdenek Kabelac
a4951801fa tools: add suppport to recognize thinpooldata 2025-04-01 15:37:36 +02:00
Zdenek Kabelac
d0c9bcf6d7 validation: add check for single vdo segments
Add check for VDO LV and VDOPOOL LV having just
a single segment in LV.
Also add couple missing '.'  in error messages.
2025-04-01 15:37:36 +02:00
David Disseldorp
43a755d568 device-types: support zram
See Linux source Documentation/admin-guide/blockdev/zram.rst .
zram devices offer a good performance and efficient resource utilization
through the use of compression.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2025-04-01 15:37:36 +02:00
Bryn M. Reeves
12419e3b67 snapshot: fix lvresize when greater than max COW size
If lvresize is given a size > the maximum COW size for a given origin
the command will fail with an internal error and no error message:

  # lvresize --size 1.6g fedora/snaptest-snap
    Rounding size to boundary between physical extents: <1.59 GiB.
    Reached maximum COW size <1.01 GiB (258 extents).
    Command failed with status code 5.

  With -vvv:

  Found snapshot target v1.16.0.
  Getting target version for snapshot-origin
  dm versions   [ opencount flush ]   [2048] (*1)
  Found snapshot-origin target v1.9.0.
  Reached maximum COW size <1.01 GiB (258 extents). <<<
  Unlock: Memlock counters: prioritized:0 locked:0 critical:0 daemon:0 suspended:0
  Syncing device names
  Unlocking /run/lock/lvm/V_fedora
  _undo_flock /run/lock/lvm/V_fedora
  Freeing VG fedora at 0x55781b142890.
  Freeing VG fedora at 0x55781b136860.
  global/notify_dbus not found in config: defaulting to 1
  Destroy lvmcache content
  Completed: lvresize -vvv --debug --size 1706243072b fedora/snaptest-snap
  Internal error: Failed command did not use log_error

This happens because in this case _lvresize_adjust_extents() returns
early without setting lp->resize to either LV_EXTEND or LV_REDUCE after
capping lp->extents to the maximum COW size.

Fix this by just capping lp->extents and relying on the existing code in
_lvresize_adjust_extents() to fixup lp->resize in the case that
lp->extents == existing_logical_extents. This is consistent with the
no-op case where -l is given as the existing size:

root@localhost:~/src/git/lvm2# LD_LIBRARY_PATH="$PWD/tools" ./tools/lvm lvresize -L 1.6g fedora/snaptest-snap
  Rounding size to boundary between physical extents: 1.60 GiB.
  Reached maximum COW size <1.01 GiB (258 extents).
  New size (258 extents) matches existing size (258 extents).
  No size change.
2025-04-01 15:36:26 +02:00
Peter Rajnoha
0d17105292
libdm: report: select: remove fixme note from _create_field_selection
Let's keep the fail-safe check in for the case some combination (e.g.
after adding a new type) is not caught earlier in the _parse_selection.
2025-03-28 10:12:20 +01:00
Peter Rajnoha
1d94dd075d
libdm: report: select: add support for string list regex selection
The c065b407cb77a7a14d7c7c3c94e09fcca2fcff09..872e085030ae8039f18908f6e45bad7ba99250a7
was for device_mapper/libdm-report.c. Do the same for libdm/libdm-report.c
2025-03-25 12:17:27 +01:00
Peter Rajnoha
872e085030
WHATS_NEW: update 2025-03-25 10:25:08 +01:00
Peter Rajnoha
959f775985
tests: select-report: cover string list regex selection 2025-03-25 10:25:08 +01:00
Peter Rajnoha
0c970d8ec7
man: lvmreport: update parts about string list selection 2025-03-25 10:25:08 +01:00
Peter Rajnoha
8d41afbc1f
libdm: report: select: support string list selection based on a regex
Wire the field<-->selection comparison logic for regexes used for
string lists.
2025-03-25 10:25:08 +01:00
Peter Rajnoha
b4ebf69739
libdm: report: select: support parsing regex for a string list
Recognize regex in string list selection criterion, including grouping
items by using {} and [] together with && (or ",") and || (or "#")
logical operators:
  - [ <regex> && <regex> ... ]
  - [ <regex> || <regex> ... ]
  - { <regex> && <regex> ... ]
  - { <regex> || <regex> ... ]

Also recognize simple "<regex>" (without any grouping operators)
as a shortcut for "{ <regex> }".
2025-03-25 10:25:08 +01:00
Peter Rajnoha
8c696e463f
libdm: report: select: lower initial size for selection mempool
The selection doesn't use that much memory, adjust the size accordingly.
2025-03-25 10:25:08 +01:00
Peter Rajnoha
91c29c318f
libdm: report: selection: use separate regex mempool
Regex remembers the mempool it was given during dm_regex_create and
then it uses it for further allocation during dm_regex_match. This
could be dangerous in case we used the same mempool for any other
allocations/frees in between dm_regex_create and dm_regex_match calls
in the outer code. This patch adds separate regex mempool for the
report/select to avoid the possible issues.
2025-03-25 10:25:07 +01:00
Peter Rajnoha
d556d77363
libdm: report: select: default to subset if no grouping operator used
Previous patch made a proper difference between [...||...] and
[...&&...]. If the criterion for a string list does not use any [] or
{}, we need to make sure that proper matching function is called -
in this case not using {} or [] is the same as if {} was used
(matching subset).
2025-03-25 10:25:07 +01:00
Peter Rajnoha
649d17d221
tests: select-report: adjust test for matching [...||...] in string lists 2025-03-25 10:25:07 +01:00
Peter Rajnoha
b4a9897bd8
libdm: report: select: fix string list match for [...||...] selection
Matching a string list criterion which had [... || ... ] was not
correctly implemented - it was the same as [ ... && ... ]. This patch
makes a difference between the two:
  - [ ... || ... ] matches if all items from string list value are
    matched by ANY item from selection string list (that is, not
    all the selection string list items need to match)

  - [ ... && ... ] matches if all items from string list value are
    matched by an item from selection string list 1:1 (that is,
    all the selection string list items need to match)
2025-03-25 10:25:07 +01:00
Peter Rajnoha
523d796b15
libdm: report: select: remove superfluous struct reserved_value_wrapper param
Remove superfluous struct reserved_value_wrapper param for
_tok_value_regex function. The only thing that _tok_value did was
zeroing the reserve field within the struct. But this one is already
zero-initialied in outer _parse_selection function.
2025-03-25 10:25:07 +01:00
Peter Rajnoha
d9832565ec
libdm: report: select: make internal errors related to incorrect field types clearer 2025-03-25 10:25:07 +01:00
Peter Rajnoha
6565ce22b7
libdm: report: select: also log function name for internal errors 2025-03-25 10:25:07 +01:00
Peter Rajnoha
53ccbdab1b
libdm: report: select: add/edit comments for parser 2025-03-25 10:25:06 +01:00
Peter Rajnoha
c065b407cb
libdm: report: select: move regex handling under common value token parsing
This is a cleanup and a preparation for adding support for regex matching
in string lists in subsequent patches.
2025-03-24 14:39:11 +01:00
David Teigland
22b628924f tests: fix metadata-old with lvmlockd_test 2025-03-17 11:49:54 -05:00
Zdenek Kabelac
06baec439e make: generate 2025-03-17 13:52:03 +01:00
Zdenek Kabelac
92493361f3 WHATS_NEW: updates 2025-03-17 13:51:24 +01:00
Zdenek Kabelac
5efa388206 man: indent with command
Avoid spaces showing as the 1st. character on the man page line.
Also start with actual text and move .IP sequence to the line end.
2025-03-17 13:51:24 +01:00
Zdenek Kabelac
fe1cf7174f makefile: rebuild man when see_also changes
Missed rebuild dependency, when see_also file changes.
2025-03-17 13:48:58 +01:00
Zdenek Kabelac
6e5e7b3193 makefile: cleanup tab 2025-03-17 13:48:58 +01:00
Zdenek Kabelac
a6264f6a44 tests: don't restart lvmdbusd
Since lvmdbusd execution of lvm2 command was fixed
stop retrying to restart lvmdbuds and abort testig
when it fails.
2025-03-17 13:48:58 +01:00
Zdenek Kabelac
b2f8e744de lvm: option description only for man generator
There is no need to include option description text
within command binary itself.

It's only used only for man generating.
2025-03-17 13:48:58 +01:00
Zdenek Kabelac
01e4764c40 man: fixes in argument description
Describe missed --segments opt for lvdisplay (matches lvs).

Describe lvm-fullreport --all option - show text for lvs,vgs,pvs.

Missed '.' for --separator.
2025-03-17 13:48:58 +01:00
Zdenek Kabelac
c9ee8d8a06 lvmdbusd: ensure readout on exit 2025-03-17 13:48:58 +01:00
Zdenek Kabelac
154befd4b8 cache: ensure UUID ends with \0
Initialization of union is somewhat tricky as it initialize only
the first member + padding, but in our case this does not clear
the whole size of union so explicitly set \0 after 2 'struct id'
and make sure DM uuid is not using random characters from stack.

Also add explicit .id designators (c99).
2025-03-17 13:48:58 +01:00
David Teigland
951fd6358b metadata: replace pv status WRONG_VG with pv bit field
Avoid any special meaning associated with the status field.
2025-03-06 10:52:50 -06:00
David Teigland
8efbffe086 lvmcache: unpair wrong PV devs and improve duplicate name warnings
After detecting that a VG has wrongly claimed a PV, unpair
the pv->dev setting.  This will cause the usual "missing PV"
message to appear for that VG.  Make this message, and some
others, clearer by using the VGID rather than the VG name
when there are multiple VGs with the same name.
2025-03-06 10:02:29 -06:00
David Teigland
cff93e4d5c lvmcache: fix check for no pvid 2025-03-05 16:03:42 -06:00
David Teigland
227d3ca507 lvmcache: add WRONG_VG PV status flag
_vg_read() calls lvmcache_update_vg_from_read() which detects
that the VG metadata is incorrectly claiming the PV.  Flag this
condition in the PV status as WRONG_VG.  Later, vg_read() can
simply check the WRONG_VG flag rather than repeating the same
PV/VG checks that were already done in lvmcache_update_vg_from_read.
2025-03-05 14:28:42 -06:00
David Teigland
cc843151b4 lvmcache: ignore incorrect PV claim from old metadata
Outdated VG metadata that appears when an old device is attached
to the system can result in PVs appearing to belong to the
old/wrong VG, and commands are allowed to use (corrupt) the PVs.

- vgcreate old /dev/sda /dev/sdb /dev/sdc
- offline /dev/sda
- vgreduce --removemissing old
- vgremove old
- vgcreate new /dev/sdb /dev/sdc
- online /dev/sda

When sda is reattached, sdb and sdc will appear to be
in VG old again.  An attempt to correct the problem,
e.g. with vgremove old or vgreduce old, would modify
sdb and sdc, removing them from the new VG.

To fix this, check that sdb and sdc contain metadata for
VG old before allowing VG old to claim ownership of them.
With the fix, sdb and sdc are not displayed as part of
VG old, and commands to change VG old will fail as long
as it references incorrect PVs.

To fix VG old (sda), remove the incorrect PVs from VG old
while limiting the command to see only the correct PVs:
vgreduce --removemissing --devices /dev/sda old
2025-03-05 14:16:46 -06:00
David Teigland
7dd2f101c7 integrity: round meta size up to minimum one extent
If VG extents are larger than the required integrity metadata size,
use one extent as the size.
2025-03-03 11:31:40 -05:00
David Teigland
381b45b5a9 lvmlockd: add helpful error message for vgremove
Print a helpful error message when the lockspace is not started.
2025-03-03 11:05:04 -05:00
David Teigland
8273a6e2e1 pvresize: accept autobackup option 2025-02-27 10:05:27 -06:00
Marian Csontos
c59a8e2d56 doc: Update metadata on 2.03.31 release notes 2025-02-27 16:53:55 +01:00
Marian Csontos
a1e449dea2 post-release 2025-02-27 16:51:29 +01:00
Marian Csontos
3a6e221c56 pre-release 2.03.31 2025-02-27 16:51:29 +01:00
Marian Csontos
d80d346f4e doc: WHATS_NEW and release note update 2025-02-27 16:49:34 +01:00
Marian Csontos
54ade3a6bb doc: Apply markdown formatting 2025-02-27 16:12:52 +01:00
Eric Blake
1dcd9fbe08 misc: Typo fix s/loose/lose/
Signed-off-by: Eric Blake <eblake@redhat.com>
2025-02-26 10:32:19 +00:00
Eric Blake
a853649565 misc: Typo fix s/more then/more than/
Also a few instances of s/less then/less than/.

Signed-off-by: Eric Blake <eblake@redhat.com>
2025-02-26 10:32:19 +00:00
Zdenek Kabelac
a512bf3c62 WHATS_NEW: update 2025-02-26 01:35:12 +01:00
Zdenek Kabelac
9197880050 make: generate 2025-02-26 01:31:50 +01:00
Zdenek Kabelac
16bc80c389 test: check LVM_SUPPRESS_FD_WARNINGS
Add test for suppression messages about leaked descriptors.
2025-02-26 01:31:49 +01:00
Zdenek Kabelac
4fa6c76181 lvmlockd: drop return from void function 2025-02-26 01:31:49 +01:00
Zdenek Kabelac
b4c9f29eb3 man: update generator code
Generate pages more complaint with 'mandoc -T lint'
Remove some generated space on EOL.
Replace .ad l with .na  macro.
Remove some .br duplicates.
2025-02-26 01:30:31 +01:00
Zdenek Kabelac
8d855ff23a man: reformat args.h to fit in 80 lines
Compliance to mandoc -T lint to fit lines into 80 chars
in generated man pages.
2025-02-26 01:29:54 +01:00
Zdenek Kabelac
ba9c4368f4 man: updates
Updates for 'mandot -T lint'
Fit lines into 80 characters.
Use  .na .ad   instead of  .ad l  .ad b
Remove some misplaced  .P  & .br
Trim spaces for EOL.
2025-02-26 01:27:15 +01:00
Jack Wilsdon
1f728f370f libdaemon: fix suppressing stray fd warnings
Restore support for LVM_SUPPRESS_FD_WARNINGS as
this was seemingly lost with refactoring to
use daemon_close_stray_fds().
2025-02-26 01:21:19 +01:00
David Teigland
80ee9e45cb uncache and splitcache should restore inactive state
If an inactive LV is being cached in writeback mode, then
removing the cache does a temporary activation to flush
the cache back to the main LV.  However, it forgot to
deactivate the LV again, so the temporary activation
was left in place.
2025-02-25 15:48:28 -06:00
David Teigland
297808c269 lvmlockd: add debug line 2025-02-25 15:48:28 -06:00
David Teigland
dfb4ed13f6 lvmlockd: expand lockopt skip options
The lockopt options for skipping locks were not being used
in many places, making it impossible to override locking to
forcibly run some commands.
2025-02-25 12:40:36 -06:00
Zdenek Kabelac
be25429ea7 test: result is some for lvmpolld
Drop 'TEST WARNING' from this case - the code works the same
were for 'pvmove -b' polling as for lvmpolld.

Just keep there 'TODO' notice we want to eventually reduce amount
of 'worked' pvmove monitoring process - ATM there will be 1 per LV.
2025-02-25 01:10:04 +01:00
Salvatore Bonaccorso
36bdffb6a4 man: clarify --stripes number of device
The current manpage is unclear in the example of a raid10 type LV RAID
with --mirrors 1 --stripes 4. The number of devices in each raid1 mirror
is NumberStripes/(NumberMirrors+1). Thus the example should read:

e.g. mirrors 1 and stripes 4 will stripe data across two raid1
mirrors, where each mirror contains two devices.

Fixes: https://gitlab.com/lvmteam/lvm2/-/issues/26
Signed-off-by: Salvatore Bonaccorso <carnil@debian.org>
2025-02-25 01:10:04 +01:00
Dion Bosschieter
6f9e247285 man: fix grammar in lvmlockd.8_main
Remove redundant 'the' in 'When the another VG'.

Signed-off-by: Dion Bosschieter <dionbosschieter@gmail.com>
2025-02-25 01:10:04 +01:00
Tyler Clark
be0b2ea01a man: removing duplicate words in man pages.
This patch removes some sequentially duplicated words in a few man pages.
2025-02-25 01:10:04 +01:00
Zdenek Kabelac
d5ac344465 clang: match prototype 2025-02-25 01:10:04 +01:00
Zdenek Kabelac
4789abbcd2 cov: some missed arg_is_set changes 2025-02-25 01:10:04 +01:00
Zdenek Kabelac
a29d0c014a lvconvert: validate mirror image counting
Since _failed_mirrors_count() may eventually return -1,
add extra validation before using returned count.
2025-02-25 01:10:04 +01:00
Zdenek Kabelac
7d0acdbcb0 thin: fix checking monitor mode
Previous commit 874a8ab4d02a59c5 missed 'IGNORE' mode.
Fix it by adding rather 'explicit' test for this value,
so the code is better readable.

Also unlock memory earlier and drop unneeded <backtrace>
from return since we already logged error in this function.
2025-02-25 01:09:49 +01:00
David Teigland
5430eec2b9 lvmlockd: fix missing lvremove free_lv
Fix missing lockd_free_lv in commit
e3f0af8f1fd7 lvmlockd: fixes for lvremove
2025-02-24 16:36:01 -06:00
Zdenek Kabelac
d83f40d25a tests: reduce Exa test size
Since kernel patch 3d9a9e9a77c5ebecda43b514f2b9659644b904d0  (6.14)
it seem device size is no limitted to <8Exa bytes (so LLONG loff_t
works across whole device).

So reduce our tested size to 8191 Peta  ~ <8 Exa.
2025-02-24 18:59:58 +01:00
Zdenek Kabelac
c40bd459df test: wait for polling finish
Increase the used mirror size for longer processing.

Add more -vvvv traces to pvmove to better chase test error.

Add extra code to wait for finish of polling pvmove after it's
been aborted - so it doesn't break 'next' test.
2025-02-24 18:59:58 +01:00
Zdenek Kabelac
d016158ff9 WHATS_NEW: updates 2025-02-24 18:59:58 +01:00
Zdenek Kabelac
874a8ab4d0 cov: add value check 2025-02-24 18:59:58 +01:00
Zdenek Kabelac
0fe1613c9b cov: use arg_count for unchecked usage
Reserve usage of  'arg_is_set()' to tested use case and use
arg_count() for unchecked one.
2025-02-24 18:59:58 +01:00
Zdenek Kabelac
56398a2180 cov: explicitly ignore value 2025-02-24 18:59:58 +01:00
Bjarni Ingi Gislason
bb458e9528 man: remarks and editorial changes for dmstats
Use "groff -e ' $' -e '\\~$' <file>" to find obvious trailing spaces.
Use "mandoc -T lint  dmstats.8"
Use "test-groff -mandoc -t -ww -z dmstats.8"

-.-.

Lines containing '\c' (' \c' does not make sense):

503:.B \-\-units \c

-.-

Change '-' (\-) to '\(en' (en-dash) for a (numeric) range.
GNU gnulib has recently (2023-06-18) updated its
"build_aux/update-copyright" to recognize "\(en" in man pages.

dmstats.8:470:expressed as a hyphen separated range, for example: '1\-10'.

-.-.

Add a (no-break, "\ " or "\~") space between a number and a unit,
as these are not one entity.

1114:Create a 32M region 1G into device d0

-.-.

Add a "\&" after "e.g." and "i.e.", or use English words
(man-pages(7)).
Abbreviation points should be protected against being interpreted as
an end of sentence, if they are not, and that independent of the
current place on the line.

511:Can also specify custom units e.g. \fB\-\-units\ 3M\fP.

-.-.

Wrong distance between sentences in the input file.

  Separate the sentences and subordinate clauses; each begins on a new
line.  See man-pages(7) ("Conventions for source file layout") and
"info groff" ("Input Conventions").

  The best procedure is to always start a new sentence on a new line,
at least, if you are typing on a computer.

Remember coding: Only one command ("sentence") on each (logical) line.

-.-.

The name of a man page is typeset in bold and the section in roman
(see man-pages(7)).

798:extents). This currently includes \fBxfs(5)\fP and \fBext4(5)\fP.
801:group, and the group alias is set to the \fBbasename(3)\fP of the

-.-.

Use thousand markers to make large numbers easy to read

560:is equivalent to 10000000. Latency values with a precision of less than

-.-.

Remove quotes when there is a printable
but no space character between them
and the quotes are not for emphasis (markup),
for example as an argument to a macro.

1:.TH DMSTATS 8 "Jun 23 2016" "Linux" "MAINTENANCE COMMANDS"

-.-.

Output from "test-groff  -mandoc -t -K utf8 -rF0 -rHY=0 -rCHECKSTYLE=10 -ww -z ":

.-.

Additionally:

  Fix some arguments for '.TP'.  A single-font macro does not work with
'\c', so use a two-font macro.

-.-

  Use the pair ".na / .ad" to set no-adjustment (same result as '.ad l')
and '.ad' to restore previous adjustment.
[Replacing ".ad l" ... ".ad b"]

  Set singular '.ad b' to '.ad \*(AD' as the user should have the choice to
control the adjustment from the command line.

  Add an empty string to string 'AD' with '.as AD "\"' to avoid a warning
about an undefined string.

-.-

Generally:

Split (sometimes) lines after a punctuation mark; before a conjunction.

Updated-by: zkabelac@redhat.com
2025-02-24 18:59:58 +01:00
Bjarni Ingi Gislason
2fae69cc4b man: remarks and editorial changes for dmsetup
Checking for defects with a new version

Use test-[g|n]roff -mandoc -t -K utf8 -rF0 -rHY=0 -rCHECKSTYLE=10 -ww -z < "man page"
Use "groff -e ' $' -e '\\~$' <file>" to find obvious trailing spaces.
Use "mandoc -T lint  dmsetup.8":
Use "test-groff -mandoc -t -ww -z dmsetup.8":

-.-.

Add a (no-break, "\ " or "\~") space between a number and a unit,
as these are not one entity.

-.-.

Use "\e" to print the escape character instead of "\\" (which gets
interpreted in copy mode).

487:with its hex value (two digits) prefixed by \\x.

-.-.

Strings longer than 3/4 of a standard line length (80)
Use "\:" to split the string at the end of an output line, for example a
long URL (web address)

1030 <name>,<uuid>,\:<minor>,<flags>,\:<table>\:[,<table>+]\:[;<name>,<uuid>,\:<minor>,<flags>,<table>\:[,<table>+]]

-.-.

Add a "\&" after "e.g." and "i.e.", or use English words
(man-pages(7)).
Abbreviation points should be protected against being interpreted as
an end of sentence, if they are not, and that independent of the
current place on the line.

581:Note: Same cookie should be used for same type of operations i.e. creation of
767:Attempts to remove all device definitions i.e. reset the driver.  This also runs
946:e.g. striped 2 32 /dev/hda1 0 /dev/hdb1 0

-.-.

Wrong distance between sentences in the input file.

  Separate the sentences and subordinate clauses; each begins on a new
line.  See man-pages(7) ("Conventions for source file layout") and
"info groff" ("Input Conventions").

  The best procedure is to always start a new sentence on a new line,
at least, if you are typing on a computer.

Remember coding: Only one command ("sentence") on each (logical) line.

Mark a final abbreviation point as such by suffixing it with "\&".

Some sentences (etc.) do not begin on a new line.

Split (sometimes) lines after a punctuation mark; before a conjunction.

-.-.

Use \(en (en-dash) for a dash at the beginning (en) of a line,
or between space characters,
not a minus (\-) or a hyphen (-), except in the NAME section.

-.-.

Remove quotes when there is a printable
but no space character between them
and the quotes are not for emphasis (markup),
for example as an argument to a macro.

1:.TH DMSETUP 8 "Apr 06 2006" "Linux" "MAINTENANCE COMMANDS"

-.-.

Output from "test-groff  -mandoc -t -K utf8 -rF0 -rHY=0 -rCHECKSTYLE=10 -ww -z ":

Updated-by: <zkabelac@redhat.com>
2025-02-24 18:59:58 +01:00
Zdenek Kabelac
0d4418fe6c polldaemon: handle sigint from nanosleep
Handle interruption caught in sleep between polling and
abort() tool execution in such case.
(Although ATM we are not normally signalling the tool this way).
2025-02-24 18:59:58 +01:00
Zdenek Kabelac
bb66753a14 polldaemon: enhance error tracking
Improve error handling in polling functions where errors
were previously ignored. These errors result from serious
failures (e.g., allocation errors) and should lead to a full
command exit, as the tool cannot function in such a state.

FIXME:

However, there is a fundamental design issue worth considering:
when a command like pvmove --abort cancels an ongoing operation,
the existing polling command continues running and only terminates
once it detects that there is nothing left to poll.

Next issue is perment reopening of a VG when 'monitoring' progress.

And the last is big trouble with '--interval 0' which is able to
wait in DM ioctl() and hold the VG lock, and there is not good way
to about such operation (other then sending a signal to such process).
2025-02-24 18:59:58 +01:00
Zdenek Kabelac
c1bc0c9726 lvmpolld: easier alloc code
Share _free_lvmpolld_lv() function.
2025-02-24 18:59:58 +01:00
Zdenek Kabelac
685e704373 test: skip retry only for lvconvert
Mirror creation is creating log volumes and needs occasionally
retry loop for deactivation.
2025-02-24 18:59:58 +01:00
Zdenek Kabelac
4be1c7b6ca makefile: remove old lcov files
Remove any older lcov generated files ('*.gcda|gcno') then the currently
generated 'make.file' before creating a new lcov report.

Otherwise we may hit the problem of using some older generated files
possibly with different format.
2025-02-24 18:59:58 +01:00
Jianqi Zeng
36be0778f8 libdm: restore missing symbols
Restore missing symbols to the libdevmapper.so library.

These symbols:

dm_bitset_parse_list@@DM_1_02_138
and dm_tree_node_size_changed@Base

become 'lost' with commit: 40b277ae1799fc7a2e3f38b0abebd81a8e3d1995
which supposedly cleaned local 'symbols' from visibility,
however these missing symbols were impproperly exported.

Signed-off-by: Jianqi Zeng <zengjianqi@kylinos.cn>
2025-02-24 18:59:58 +01:00
David Teigland
6ad474385b lvmlockd: recognize error ELMERR 2025-02-20 10:18:28 -06:00
David Teigland
b02e6cd4a9 lvmlockd: disallow shared activation of LV with cow snapshot
The check for disallowing shared activation was missing
a check for this type.
2025-02-19 16:19:42 -06:00
Zdenek Kabelac
bb0bbc6d74 test: repeatedly restart lvmdbusd
It looks like occasionally supports_json() in cmdhandler.py
for some reason does not find  'fullreport' in err output
of lvm help...  let's see more traces...
2025-02-19 00:36:46 +01:00
Zdenek Kabelac
8417a6a578 revert "test: aux gives more time for lvmdbusd start"
This reverts commit 8425c1b468af0caf2e1e36d1eb1c1b399ee22489.

Seems we have different problem with lvmdbusd test start.
2025-02-19 00:36:46 +01:00
Zdenek Kabelac
79c022133b test: improve holding device open
Use 'exec' to open device and then just pass descriptor to sleep.
2025-02-19 00:36:46 +01:00
David Teigland
e3f0af8f1f lvmlockd: fixes for lvremove
The simple common case of locking the LV to remove with a
persistent lock would usually be fine, but there are a number
of special cases that were not addressed:
- no locking was done for removing cow snapshot
- direct locking to vdo pool
- dm-cache uncache using lvremove was not handled
2025-02-18 11:57:01 -06:00
David Teigland
5359737c29 lvmlockd: use lockd_lvcreate_lock for multiple LV types
Use the same lockd_lvcreate_lock() for all cases in which
creating a new LV first requires locking another associated
LV, e.g. locking the pool or origin for the new LV.
2025-02-18 11:50:52 -06:00
Zdenek Kabelac
b13b55884a test: add check for no such file 2025-02-17 15:51:03 +01:00
Zdenek Kabelac
da19ef49b1 cov: refactor code for warning
Refactor resizing loop, so Coverity no longer sees
the loop as 'infinite' and the code is also readable.
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
03b78fa666 cov: refactor code
Refactor code, so Coverity doesn't complain about over-running
an array with char*.
(IMHO this seemed like a problem in Coverity code evaluation)
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
a87cc133e2 cov: initialize arrays values 2025-02-17 15:51:03 +01:00
Zdenek Kabelac
07f23d4b81 clang: refactor code for easier alloc tracking
Refactor _get_split_name(). code to simplify detection of memory leak
in _destroy_split_name(). Now there are always just 2 pointers
instead of conditional pointer free() which is hard to follow.
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
8bdc234348 clang: call alloca with non-zero size
Make sure that some non 0 size is also for (mirrors == 0).
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
05f1e78f3e clang: pointer protection 2025-02-17 15:51:03 +01:00
Zdenek Kabelac
9f425a62fc clang: validate command before exec
Add extra check for command existence in argv before fork().
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
1e91c16112 clang: use better readable code
Here we make sure, that we always free fopen() fp.
As theoretically we may have had opened 'stdout'.
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
12efeb6d51 clang: validation 2025-02-17 15:51:03 +01:00
Zdenek Kabelac
5fd50ae192 tools: using proper header order
ARG_COUNT is generated by processing command_enums and
then it can be used by command.h.

So correct include order and later use command.h.
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
5a6d318b29 cleanup: headers self compilable
In most cases header should be self-compilable, so the
do not expect other 'header' files to be used upfront
so the header would be compilable.

No functional change.
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
924221765e cleanup: match function prototype with definition
Match variable name in function definition with
its prototype. Pick the name which better fits
the usage.

No functional change.
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
a6b2ce6299 cleanup: project headers in front
Include project headers before system header files.
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
464c30e6c3 clang: silence warning
Make the code pass through Coverity/clang.
As it didn't like theoretical access beyond
_yes[] & _no[] array elements.
2025-02-17 15:51:03 +01:00
Zdenek Kabelac
5e127fb8e9 clang: correcting imprecise prototype
These internal header were using misleading variable names
in function prototypes, but correct names were used in
function definition. Noticed with:

clang-tidy --checks=readability-inconsistent-declaration-parameter-name

No functional change.
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
f66c76e5ea clang: make pointer defined 2025-02-17 15:51:02 +01:00
Zdenek Kabelac
3a700dd2f2 clang: add known mask value
Bit flags likely should never have been 'enum' but since
we have this in a public header - it might be hard to
replace this. So at least add missing 'enum' element
we use.
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
bacd9f394d clang: check pointers 2025-02-17 15:51:02 +01:00
Zdenek Kabelac
cb0c43898a clang: pointer validation 2025-02-17 15:51:02 +01:00
Zdenek Kabelac
ff1f1188c3 clang: better visibility of non-null lock_type
clang can't see transient result, however
it would be still better to check for type string just once.
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
9cc6b15dd9 clang: ensure defined value
Although this radix_tree_simple code is not being unused ATM...
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
e737c54d8a clang: validate allocated buffer size
Validate for not using 0 size arg for allocation,
however this can never heapen for running code...
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
1d13b391f8 clang: trace rewind errno
Although rewind() return void, it's API suggest
to check for 'errno' value.
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
15b3cf1104 clang: reduce padding in struct cfg_def_item
Reorder struct members to minimize padding.
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
4ff8c706db clang: reduce padding in struct command_name
Reorder struct members to minimize padding.
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
0c3c08b95f clang: refactor code to always run inner loop
Make it more clear to analyzer the inner loop always runs.
Otherwise it may complain about *c being NULL.
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
063984afde clang: valid area is required
Do not try to check references when verifying
LV segments with missing area.
2025-02-17 15:51:02 +01:00
Zdenek Kabelac
623e98e16c clang: ensure extents is usable
Although the code was exiting only for  (update == 0),
the later code actually used requires 'extents' to exist
also for  (update != 0).

TODO: The logic here is not very clear, more testing needed.
2025-02-17 15:49:54 +01:00
Zdenek Kabelac
f0a707f6b4 clang: fix double free in error path
When prefix insertion to radix_tree would fail, the error
path might try to possible double free allocated memory.
2025-02-17 15:41:53 +01:00
Zdenek Kabelac
bea43e4faa raid: set warn print level
Since there conversion messages are not causing direct
command error, switch message level to log_warn().
2025-02-17 15:41:53 +01:00
David Teigland
c326796a89 man lvm: add tag info
Restore basic info about tags that was dropped years ago
during the reworking for man page generation.
Also some other minor random updates.
2025-02-13 12:21:51 -06:00
David Teigland
fd341c818d lvcreate: accept lockopt option
The redundant lvcreate.c implementation of accepted options needs
to be removed.
2025-02-13 11:42:24 -06:00
Zdenek Kabelac
00a3664a5c test: improve for use with older systems
Improve test, so it's also working on systems without delay_dev
and test is actually more 'race' resistant.
2025-02-13 11:05:23 +01:00
Zdenek Kabelac
625a38c855 raid: remove struct overlap with possible_takeover
After reorganizing elements in `possible_takeover_reshape_type`
(in commit 5b92ce741f6bcb9b3d3c19c0fc13b972f950c560),
it became apparent that the code relied on struct overlap,
which is somewhat unsafe. This commit removes it and ensures
proper `const` qualification for the struct usage.
2025-02-13 11:04:30 +01:00
David Teigland
04cacff3b9 lvmlockd: lockd_vg return value cleanup 2025-02-12 11:16:16 -06:00
Zdenek Kabelac
852f3c20bb lcov: ignore some errors
While building lcov files - ignore errors from 'negative' counter
(perhaps we can use -fprofile-update=atomic - but it would be another
slowdown of test runs)

Also ignore unexecuted blocks warnings with 'gcov'.

Failure of lcov goal is not supposed to error whole make build.
2025-02-12 15:12:31 +01:00
Zdenek Kabelac
8a67936e7e cleanup: match prototype 2025-02-12 15:11:56 +01:00
Zdenek Kabelac
13fcb7e428 cleanup: use full source path to header 2025-02-12 15:11:56 +01:00
Zdenek Kabelac
736db4247c test: handle lvmpolling case
When test runs with lvmpolld - we cannot check
messages from pvmove - as those are visible through
output of lvmpolld - so just skip this and
only check LVs are in expected state.
2025-02-12 15:11:56 +01:00
Zdenek Kabelac
0bb06eb99b coverity: cleanup model code 2025-02-12 14:31:37 +01:00
Zdenek Kabelac
5b92ce741f gcc: better structure padding
Since we use '.option' to assign struct member - just suffle
structure element for better padding.
2025-02-12 14:31:37 +01:00
Zdenek Kabelac
c0b725d6e6 gcc: fabsf float based operation
Use 'float' version of 'fabs()' to compare floats.
2025-02-12 14:31:37 +01:00
Zdenek Kabelac
75a39003b0 clang: just use regular final else
There is no need to compare, so just keep 'if' part as the comment.
2025-02-12 14:31:37 +01:00
Zdenek Kabelac
e9640e5178 sanlock: more variable structure part to the end
Move variable part so there is no need to use 'gnu' compiler extension.
2025-02-12 13:55:29 +01:00
Zdenek Kabelac
e410715154 mirror: make sure 0 is not clz arg
Just make sure there will be never ever used '0'
as parameter for clz().
2025-02-12 13:55:29 +01:00
Zdenek Kabelac
d6934ea31d lvmcmdline: fix printed error messages
Since long_opt was changed to char[], we were only comparing pointers
that always exist, whereas the original intention of the test was
to verify the presence of a string
(i.e., checking that the first byte is not \0).
2025-02-12 13:55:22 +01:00
David Teigland
a1017024f1 raidintegrity: support removal of partial images
vgreduce --removemissing --force replaces a partial image
with an error target.  When that image includes an integrity
layer, that layer needs to first be removed.
2025-02-10 12:10:08 -06:00
Zdenek Kabelac
e7ae3fbd10 WHATS_NEW: update 2025-02-10 11:31:53 +01:00
Zdenek Kabelac
8425c1b468 test: aux gives more time for lvmdbusd start
Try 20s delay to see whether dbus service will be alive...
2025-02-10 11:31:53 +01:00
Zdenek Kabelac
7f12b5d0dc test: split mirror with opened leg 2025-02-10 11:31:53 +01:00
Zdenek Kabelac
550ce921fa test: check layout for error and zero 2025-02-10 11:31:53 +01:00
Zdenek Kabelac
d913d776d1 test: pvmove with open temporary volumes
Test pvmove logic when various pvmove mirror volumes are opened
while pvmove is finishing.
2025-02-10 11:31:53 +01:00
Zdenek Kabelac
a9fcc3ab0c gcc: compare same signedness 2025-02-10 11:31:53 +01:00
Zdenek Kabelac
a187f02ed5 vdo: correctly size string array
Fix logging of VDO configuration info message which has acutally
printed " and," using next element..
Increase the array element size so it can store >=5 bytes
for " and" + \0.
2025-02-10 11:31:53 +01:00
Zdenek Kabelac
74a2325261 mirror: splitting handles opened devices
Similar to the pvmove update, enhance error path handling
for scenarios where legs or logs remain open and cannot be
closed during the splitting of a mirror image.

Remove the now obsolete _delete_lv() function,
as it will no longer be needed.
2025-02-10 11:31:53 +01:00
Zdenek Kabelac
be1b83a76f mirror: move status bit masking
Use bit masking in replace_lv_with_error_segment().
2025-02-10 11:31:53 +01:00
Zdenek Kabelac
87a4e7bb68 debug: update message for pvmove
Add some more consistency to message printed for pvmove.
2025-02-10 11:31:53 +01:00
Zdenek Kabelac
7858c25427 debug: use more similar skipping messages 2025-02-10 11:31:53 +01:00
Zdenek Kabelac
425ae9aaf0 debug: reinitialize debug pid after fork 2025-02-10 11:31:53 +01:00
Zdenek Kabelac
2a34723511 lv_manip: print layout for error and zero 2025-02-10 11:31:53 +01:00
Zdenek Kabelac
ed9468153e mirror: enhance error path for pvmove finish
When the pvmove operation is completing, it attempts to deactivate
the temporary mirror and remove its mirror legs. However,
if an external tool holds these volumes open, the operation would
previously abort entirely, leaving the LVM2 metadata in a partially
unusable state that required manual administrative fixes.

To improve this, the code has been enhanced to handle such scenarios
more gracefully. It will now complete the pvmove operation even
if some volumes cannot be deactivated, marking them in the metadata
with an error segment. While the command will report errors,
the metadata will remain in a usable state. The administrator
can then remove the orphaned volumes when they are no longer in use.
2025-02-10 11:31:52 +01:00
David Teigland
09e508cd43 devices file: fix backup limit
Fix the code that limited the total number of backup files.
It failed, and left excess files, when the file version
number was greated than 9999, exceeding the four digit suffix.

Now, after version 9999, the suffix intentionally grows beyond
four digits as needed, and is not a fixed width, or zero padded.
2025-02-05 20:40:59 -06:00
Zdenek Kabelac
a6408163dd lvmlockd: correct prototype for sanlock-less build 2025-02-03 10:45:09 +01:00
Zdenek Kabelac
c68af364e7 lvmlockd: compilation fixes 2025-02-02 20:06:10 +01:00
Zdenek Kabelac
d5cc65f683 gcc: std=c11 for test suite as well 2025-02-02 20:00:44 +01:00
Zdenek Kabelac
082d475ea9 debug: missed stack tracing 2025-02-02 20:00:44 +01:00
Zdenek Kabelac
29bb84f17b raid: refactor code to _raid_leg_degraded
Move common code into _raid_leg_degraded().
2025-02-02 20:00:44 +01:00
David Teigland
48d7511808 lvmlockd: fix free_lv immediately after init_lv
Fix for recent commit "lvmlockd: free resource structs for LVs"

When a vg_write() fails in lvcreate, lvmlockd sees init_lv()
followed by free_lv().  The LV lock is not acquired prior to
free_lv, and no prior resource struct exists. This wasn't being
handled.
2025-01-31 18:38:39 -06:00
David Teigland
ffeee23537 lvmlockd: log correct name in error path
fix for recent "lvmlockd: free resource structs for LVs"
2025-01-30 16:38:33 -06:00
Zdenek Kabelac
46a48f1320 vg_read: correct error path for DM cache update
New code for updating DM cache traveled through couple destination
however in this place only 'return_0' is missing unlocking in
error path.
2025-01-30 20:02:25 +01:00
Zdenek Kabelac
2c63b12bd3 tests: more info from test 2025-01-30 17:26:08 +01:00
Zdenek Kabelac
36ae51c3cb dev-type: require 4k only for some topology attrs
Previous commit 5f71cebcbecc37b5291018da35b3efe9636bf6c3 was not
correct. 4k requirement cannot be put on attribute_offset - where
it is valid to have this only 512b aligned.
The rule might get more complicated to recognized invalid values.
For this moment however add more easier requirement - we
impose 4K restriction on minimal and optimal io size if they
are bigger then 1 sector (512B).
2025-01-30 17:23:45 +01:00
Zdenek Kabelac
1e21b0a6f2 WHATS_NEW: update 2025-01-30 13:38:31 +01:00
Zdenek Kabelac
12f1472972 cov: annotate 2025-01-30 13:38:31 +01:00
Zdenek Kabelac
1719f1169f cov: ensure buffer does not underflow
Add explicit check for having always positive value.
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
d32ee0b7ab cov: avoid expression overflow
Keep max memory in MiB  (>> 20).
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
42a43c37de cov: explicitly ignore return codes 2025-01-30 13:38:31 +01:00
Zdenek Kabelac
583e5f952e cov: add validation of FID pointer
Ensure NULL theoretical NULL FID pointer is not
dereferenced.
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
fd91edfd15 cov: limit buffer size for sscanf
Limit sscanf parser buffer width for string.
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
51030c57a1 cov: use bigger buffer
Since pvck's  _check_vgname_start is actually checking
up-to (NAME_LEN + 2) bytes  (130),
use at least this size for (MAX_LINE_CHECK + 3).
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
1e21a93ead cov: limit log levels to 7
lvm2 is using 7 levels for logging.
(Which might be already probably too much...)
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
cae445443e cov: add sscanf width specifiers for lvmlockctl 2025-01-30 13:38:31 +01:00
Zdenek Kabelac
f582c7be1d cov: add space for string 0
Sscan may automatically add 0 after field width mark,
and since it's not exactlu trivial to do a macro calculation
for PATH_MAX - 1, rather make buffer for sscanf results bigger.

Also use matching FSTYPE_MAX as field width specifier.
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
09d896810b cov: add extra byte for 0
Since we use 'DM_NAME_LEN' size for sscanf - it may need to store
extra string 0, which is added automatically after 'maximum field
width' specifier.
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
07b595d0f3 gcc: updates for use with std=c11
Let gcc -std=c11 pass...
Useful i.e. to get working Coverity scan ATM.
(as gcc15 and stdbool changes makes it problematic.)
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
9fe73c8d95 debug: drop double '/' in created pathname
Our cmd->dev_dir already has '/dev/' so do not use '/dev//devname'.
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
27f0ca79cc tests: update topology test
Check lvm2 create usable VG for optimal_io_size 16776704
(which is not divisible by 4KiB).
2025-01-30 13:38:31 +01:00
Zdenek Kabelac
5f71cebcbe dev-types: ignore non-4K divisible topology values
When topology value is bigger then 1 sector (512b)
we require 4K divisibility for them.
2025-01-30 13:38:03 +01:00
Zdenek Kabelac
e907c3cf9a config: check for 0 from read
When the read returns 0, it could mean the file
was trimmed or some other type of problem.
In this case abort the potentially endless loop.
2025-01-30 13:38:03 +01:00
Zdenek Kabelac
b32c0bb9c5 vg_read: matching missed empty cache
lvm2 is caching DM nodes with the use of DM_LIST_DEVICES ioctl().
And tried to preserve the cached structure for the same list,
however there was 1 case where cache was empty, and new LIST ioctl
returned some elements - if this DM table change has happened
in the moment of 'scanning' and locking -  lvm2 has then continued
to use 'invalid' empty cache.

Fix by capturing this missed case and update cache properly.

TODO: we could possibly use plain memcmp() with previous ioctl result.
2025-01-30 13:37:19 +01:00
Zdenek Kabelac
dd09127608 vg_read: rescanning DM cache after taking lock
Since we started to use DM cache now also for basic checks
whether the DM devices is present in DM table, this cache
now needs to be actually refreshed when the LOCK is taken.
This hiddenly happend if there was enabled 'scan_lvs' however
still not at the right place.

Move this explicit cache update call right after the moment
vg_read grabs the lock.

TODO: in the optimal case, we should mark the 'cache invalid'
and later refresh this cache, when the first reader appears,
but since this would be large patch, do this little fix step patch
first and improve performance later.
2025-01-30 13:33:37 +01:00
David Teigland
76b1776367 lvmlockd: fix thin locking case for cow snapshot
The case of lvcreate creating a cow snapshot of a thin volume was
caught by the sanity check for any missed instances of thin locking.
2025-01-29 18:10:00 -06:00
David Teigland
ebb90fd2c6 lvmlockd: free resource structs for LVs
Once created, resource structs for LVs were never being freed.
If LVs are activated, then later removed or never used again,
the unused structs waste memory and cause the resource list
to grow.
2025-01-23 15:57:46 -06:00
David Teigland
7d7b5db230 lvmlockd: thin locking improvements
There was a lot of messy and inefficient locking calls sent from
a command to lvmlockd when working with thin volumes, e.g.
- requesting a lock numerous times that was already held
- releasing a lock numerous times that was already unlocked
- repeating lock/unlock/lock/unlock rather than holding the
  lock until it was no longer needed

Mistakes in the locking could easily hide among all the noise.

The mess was largely because thin-related commands involve a
lot of internal LV manipulations, and lvmlockd calls were done
at the lower level of LV activation/deactivation.  This change
adds locking code that is more specific to the thin command
being run, so it can be more intelligent in acquiring and
releasing locks where needed.
2025-01-17 14:06:21 -06:00
David Teigland
c2cf9a4cae lvmlockd: debug log message improvements 2025-01-17 14:01:17 -06:00
David Teigland
84aa248f07 lvmlockd: reject bogus lease offset values 2025-01-17 14:00:34 -06:00
Marian Csontos
6c2debf917 doc: Release Notes for 2.03.30 2025-01-14 20:57:47 +01:00
Marian Csontos
6de7c51dce post-release 2025-01-14 20:55:33 +01:00
Marian Csontos
9f81fccd65 pre-release 2.03.30 2025-01-14 20:55:33 +01:00
Marian Csontos
ffbf3a8ca2 WHATS_NEW: update 2025-01-10 17:19:16 +01:00
Marian Csontos
8247752ce1 doc: Try to test limit of release notes
This works with newer ikiwiki when building locally, but not on the
gitlab.
2025-01-10 17:06:03 +01:00
Zdenek Kabelac
8cbd417e7a memlock: skip locking unused libs
Skip memlocking libraries unused in critical section.
2025-01-09 14:16:32 +01:00
Zdenek Kabelac
a4bf6667f8 WHATS_NEW: update 2025-01-09 00:20:19 +01:00
Zdenek Kabelac
b47612cd8b configure: autoreconf 2025-01-09 00:20:19 +01:00
Zdenek Kabelac
9ad2980996 configure.ac: notify_dbus works fine with older version
Picking version 218 for notify_dbus support - maybe older works too,
but not being tested...
2025-01-09 00:20:19 +01:00
Zdenek Kabelac
ecf2cbec7f configure.ac: report 'none' when nvme_wwid is missing 2025-01-09 00:20:19 +01:00
Zdenek Kabelac
e95bc8f8c9 cov: check syscall 2025-01-09 00:20:19 +01:00
Zdenek Kabelac
970463fc46 cov: just be sure nsid is defined 2025-01-09 00:20:19 +01:00
Zdenek Kabelac
d582ee591e cov: remove unused header 2025-01-09 00:20:19 +01:00
Zdenek Kabelac
14673b2746 cov: some error path updates 2025-01-09 00:20:19 +01:00
Zdenek Kabelac
8fb58826c0 tests: cleanup typo 2025-01-09 00:20:19 +01:00
Masanari Iida
d7ffd98257 man: fix double words
This patch fixes double words found in man.

Signed-off-by: Masanari Iida <standby24x7@gmail.com>
2025-01-09 00:20:19 +01:00
Zdenek Kabelac
86574ce07a tests: test unsupported lvresize of origin vdo lv 2025-01-09 00:20:19 +01:00
Zdenek Kabelac
f392dab286 tests: check memory locking
Check reserved memory and stack is able to disable mlocking.
2025-01-09 00:20:19 +01:00
Zdenek Kabelac
9414dcae3a lvresize: vdo origin resize is unsupported
Add explicit error message for not (yet) supported resize
of origin VDO volume.
2025-01-08 23:08:30 +01:00
Zdenek Kabelac
0d3b87d19f lvmcmdline: memlock init after config parsing
Since we now support disabling memory locking by setting
reserved memory or stack to 0 - it would be useful if this would
work also with cmdline --config option.

TODO: rework creation and usage of cmdtool context so we avoid
several places in the code which do try to initialized something...
2025-01-08 23:07:26 +01:00
Zdenek Kabelac
4ef211a187 memlock: check for proper reserved size
Fix regression introduced with commit:
964012fdb924076e9ab97fabe00e759ddbf7c3bd
that effectively disabled memory locking before suspending volumes.
From merging/testing there remained wrong condition
as we really want to check for 0 memory reservation value
for both checked settings.
2025-01-08 23:06:47 +01:00
Peter Rajnoha
1576273273
WHATS_NEW: update 2025-01-06 15:35:44 +01:00
Peter Rajnoha
e86a75b4fe
tests: adjust lvresize-xfs tests for recent lvextend changes
Because now, we are doing the fsinfo check before extending an LV and if
that check fails, we do not proceed to the LV extension itself and the
lvextend command bails out immediatelly.
2025-01-06 15:31:17 +01:00
Peter Rajnoha
036e88eb85
filesystem: add new_size_bytes to struct fs_info
It seems we need new_size_bytes in places where struct fs_info is also
passed. Store the new_size_bytes inside the struct fs_info so we
can just pass that one to all the functions we call and hence make
the code a bit cleaner and easier to follow.
2025-01-06 15:31:13 +01:00
Peter Rajnoha
5f53ecda36
lv_manip: check fs resize is supported before LV extension
This avoids a situation where we would extend an LV and then we would
not do anything to the FS on it because the FS info check failed for some
reason, like the type was not supported (e.g. swap) or we could not resize
the FS unless being in some supported state (e.g. XFS to be mounted for
the xfs_growfs to work).

Before this patch (LV resized, FS not resized):

❯  lvextend --fs resize -L+4M vg/swap
  Size of logical volume vg/swap changed from 32.00 MiB (8 extents) to 36.00 MiB (9 extents).
  File system extend is not supported (swap).
  File system extend error.
  Logical volume vg/swap successfully resized.

With this patch (LV not resized, FS not resized):

❯  lvextend --fs resize -L+4M vg/swap
  File system extend is not supported (swap).
2025-01-06 15:29:43 +01:00
Zdenek Kabelac
5ef958704c WHATS_NEW: update 2024-12-19 14:57:43 +01:00
Zdenek Kabelac
e1117164a4 make: generate 2024-12-19 14:55:56 +01:00
Zdenek Kabelac
8a9bc6eed8 args: missed option all for vgdisplay 2024-12-19 14:55:25 +01:00
Zdenek Kabelac
3e641578d8 tests: check conversion of in-use volume
Thin-pool conversion fails early when trying to convert
volume which is in use  (simulated by sleep <)
2024-12-19 14:50:32 +01:00
Zdenek Kabelac
6326d00937 thin: deactivate converted volume early
Deactivate converted volume to pool early, so the conversion
exits early and does not leave some already created metadata
volumes that needed manual cleanup by user after command
aborted its conversion operation when the converted volume
was actually in-use  (i.e. when user tried to convert
a mounted LV into a thin-pool, 2 extra volumes needed removal).
2024-12-19 14:47:16 +01:00
Zdenek Kabelac
928b8e9c6e configure: autoreconf 2024-12-09 16:04:53 -06:00
Zdenek Kabelac
cb87e184bc configure.ac: add support for libnvme
Add 2 new options for linking  libnvme with lvm2.
Option  --without-libnvme, --disable-nvme-wwid
2024-12-09 16:04:53 -06:00
David Teigland
d952358636 device_id: nvme devices may use alternate wwids
Device quirks may cause sysfs wwid file to change what it
displays, from a bogus eui... string to an nvme... string.

The old wwid may be saved in system.devices, so recognizing
the device requires finding the old value from libnvme.

After matching the old bogus value using libnvme, system.devices
is updated with the current sysfs wwid value.
2024-12-09 16:03:43 -06:00
Marian Csontos
736d23ad26 doc: Fix limit for inlined release notes 2024-12-09 17:40:14 +01:00
Peter Rajnoha
32ab91e528
udev: create /dev/disk/by-diskseq/<DISKSEQ> symlink for public DM devices
All block devices have a disk sequence number assigned (an ever-increasing 64 bit
sequence number) since kernel v5.15 (February 2021). The number is exported through
/sys/block/<disk>/diskseq property and also as DISKSEQ udev event variable.
The diskseq helps with referencing a device throughout its existence in
race-free way.

By default, the /usr/lib/udev/rules.d/60-persistent-storage.rules set
/dev/disk/by-diskseq/<diskseq> symlink for each block device. However,
these rules do not apply for DM devices because we manage the symlinks
ourselves in 13-dm-disk.rules where it properly follows the
DM_UDEV_DISABLE_DISK_RULES flag, among other things.

Add a rule to 13-dm-disk.rules to create the /dev/disk/by-diskseq/<diskseq>.
2024-12-09 13:17:46 +01:00
Marian Csontos
85014fcd6d post-release 2024-12-09 12:57:57 +01:00
Marian Csontos
32cfcfd151 pre-release 2.03.29 2024-12-09 12:57:57 +01:00
Zdenek Kabelac
3c365e6c5c WHATS_NEW: update 2024-12-06 17:23:01 +01:00
Zdenek Kabelac
4a18f89736 make: generate 2024-12-06 17:23:01 +01:00
Zdenek Kabelac
2b82e882ed configure: autoreconf 2024-12-06 17:22:57 +01:00
Zdenek Kabelac
d8726b07c3 lvmlockd: utilize SD_NOTIFY_SUPPORT
Update makefile and code to better utilize SD_NOTIFY_SUPPORT var.
2024-12-06 17:16:55 +01:00
Su Yue
ee97c5c633 configure.ac: add option disable/enable-sd-notify
Since commit d106ac04ab34 ("configure.ac: use LIBSYSTEMD"),
lvmlockd is not built with SD_NOTIFY by default but depending
on LIBSYSTEMD_LIBS. There are three prerequisites of
nonempty LIBSYSTEMD_LIBS:
NOTIFYDBUS_SUPPORT, SYSTEMD_JOURNAL_SUPPORT and SYSTEMD_JOURNAL_SUPPORT.

If ./configure is called with options ' --disable-systemd-journal
--disable-app-machineid --enable-lvmlockd-sanlock
--disable-notify-dbus', the lvmlockd built is without sd_notify
support which causes hang of start lvmlockd service in notify type.

This commit adds options disable-sd-notify and enable-sd-notify.
The default value is autodetected and when the lvm2 is build with
systemd then sd-notify is enabled.
If systemd/sd-daemon.h is existed, call PKG_CHECK_MODULES libsystemd.

Signed-off-by: Su Yue <glass.su@suse.com>
Modified-by: Zdenek Kabelac <zkabelac@redhat.com>
2024-12-06 17:14:58 +01:00
David Teigland
f08d1caf47 vgdisplay: remove command def for activevolumegroups
too minor to care about separating
2024-12-06 09:18:23 -06:00
David Teigland
acd7cfbc08 pvdisplay, vgdisplay, lvdisplay: changed listed order
List the common form first, followed by the others.
2024-12-05 16:09:19 -06:00
David Teigland
6c5e8ee18b vgdisplay: add command def for activevolumegroups
This variant does not accecpt positional args like
the others.
2024-12-05 16:03:24 -06:00
David Teigland
017c668fd0 vgdisplay: split code for variants using command defs 2024-12-05 15:31:55 -06:00
David Teigland
ccde015712 pvdisplay: split code for variants using command defs
Also fix the use of --all that was mistakenly included
as an accepted option for vgdisplay and two cases of pvdisplay
in commit "tools: enhance lvdisplay vgdisplay pvdisplay"
2024-12-05 15:31:55 -06:00
David Teigland
9beea2db69 lvdisplay: split code for variants using command defs 2024-12-05 15:31:55 -06:00
Marian Csontos
275c9666b6 doc: Amend 2.03.27 and 28 release notes' date 2024-12-05 14:40:42 +01:00
Zdenek Kabelac
d791f160a8 tests: make reshape bug more easier to hit
Seems this delay_dev usage exposing some reshape window creation bug.
So make delay bigger to hit the error easier.
2024-12-04 16:14:22 +01:00
Zdenek Kabelac
75907f0e80 tests: do not use noudevsync with udev system
Remove --noudevsync option - as this breaks synchronization with
udev which is necessary when trying to i.e. create  _rmeta_3
and wipe it - as the symlinks must be present for wiping.

So if there was some other issue  (behind the comment) - we need to
check for the problem elsewhere instead of disabling udev sync.
2024-12-04 16:14:22 +01:00
Zdenek Kabelac
45344262cc debug: missing stack 2024-12-04 16:14:22 +01:00
Marian Csontos
c695c7a252 doc: Update WHATS_NEW and Release notes 2024-12-03 13:07:03 +01:00
Zdenek Kabelac
94da2c9792 configure: autoreconf 2024-11-26 14:39:09 +01:00
Zdenek Kabelac
ce8e6c8c63 configure.ac: build lvmlockd with notify
Automatically use --enable-notify-dbus when building lvmlockd
if not configured otherwise by a configure user -
as the lvmlockd.service is notify based.
2024-11-26 14:38:23 +01:00
Marian Csontos
60cd279f96 test: Prevent incorrect value propagating into test
In case dbus-send is not present previous random value of i was tested.
2024-11-26 13:25:49 +01:00
Marian Csontos
25638f6a87 spec: Remove [Build]Requires for cluster 2024-11-26 10:59:05 +01:00
David Teigland
47c4f737c9 lvmlockd: allow test mode when dlm is not built 2024-11-25 12:08:43 -06:00
David Teigland
a6e918cd48 man: lvmraid integrity updates 2024-11-25 10:22:43 -06:00
Vojtech Trefny
c77f2697ee dbus: Add function for running lconvert --repair on RAID LVs 2024-11-25 14:22:29 +00:00
Zdenek Kabelac
9259892627 tests: increase mirror size
On fast machines mirror throttling starts to react much later
so try bigger mirror size to fight with race in test.
2024-11-25 14:16:55 +01:00
Zdenek Kabelac
2c06950888 man: update display fields
The --sort option belongs to  '-C' columned output only.
Also add short commmand description for specialized
vg/pv/lvdisplay command.
2024-11-25 14:03:51 +01:00
Zdenek Kabelac
5893ca17da make: generate 2024-11-22 14:25:54 +01:00
Zdenek Kabelac
e8e4324d68 tools: enhance lvdisplay vgdisplay pvdisplay
Split description for display commands so we can better describe
it's usage and combination of individual options in man page.

Now we can separately describe:

lvdisplay, lvdisplay -c, lvdisplay -C
vgdisplay, vgdisplay -c, vgdisplay -C
pvdisplay, pvdisplay -c, pvdisplay -C

TODO: Drop validation from command code itself.
2024-11-22 14:25:54 +01:00
Zdenek Kabelac
502543ffed args: add colon and column for pv/vg/lvdisplay
Better description for --colon and --column option for
pvdisplay, vgdisplay, lvdisplay.
2024-11-22 14:25:54 +01:00
Zdenek Kabelac
03a3863804 man: clean
Both branches printed new line.
2024-11-22 14:25:54 +01:00
Zdenek Kabelac
ebadd3ccc6 man: refactor check for variant
Remove unnecessary checks and move the comment to the 1st. check.
2024-11-22 14:25:54 +01:00
Zdenek Kabelac
c4d4bddfce man: refactor printing option
When generating man pages, use a single function to print
option with its short & long name.
2024-11-22 14:25:54 +01:00
Zdenek Kabelac
efe5af819a man: enhance handling of option description
Update the _print_man_option_desc() to also handle common parts
as the initial text without any specified section and also
add support for '#\n' to be able to revert to common part.
2024-11-22 14:25:54 +01:00
Zdenek Kabelac
ca5d258376 test: shellcheck: use quotation marks 2024-11-15 14:11:30 +01:00
Zdenek Kabelac
4c31e6d56a test: shellcheck: add shell directive
Also add forgotten standard copyright message with shell reference.
2024-11-15 14:10:49 +01:00
Zdenek Kabelac
51a684ef0f shellcheck: separate declaration and assign
So the error exit code can be processed if needed...
2024-11-15 14:10:39 +01:00
Zdenek Kabelac
dfc132a514 shellcheck: validate cd success 2024-11-15 14:10:31 +01:00
Zdenek Kabelac
473e93fbff WHATS_NEW: update 2024-11-13 13:06:15 +01:00
Zdenek Kabelac
270f9306bc tests: improve tracing messages
Avoid printing lvm2 command trace, if the test finds the 'dmeventd'
was started unxpectedly during testing as the last command is hardly
ever responsible for this

Also reorder some messages when doing teardown of devices.

Do not print 'help' message from hostname command, when it does
not support option '-I'.
2024-11-13 13:00:42 +01:00
Zdenek Kabelac
7b9bdcb4d4 tests: check _tdata conversion to raid1 2024-11-13 13:00:42 +01:00
Zdenek Kabelac
c2f41c1a59 raid: fix name rotation
Since we now keep lv names valid all the time (as they are part
of radix_tree) - there is a problem with this renaming code, that
for a moment used duplicated name in vg struct.

Fix it by interating LVs backwared - which avoids breaking consitency
and also actually makes code more simple.
2024-11-13 13:00:42 +01:00
Zdenek Kabelac
cbfc31ee2b tests: aux check for leaked symlinks
Add check for 'leaked' symlinks after test and trap
the case when some 'danglink' links are present.
This might be some problem with udev synchronization
or some other strange race.

All such symlinks will be also removed so they will not
influence following tests.
2024-11-08 19:41:50 +01:00
Zdenek Kabelac
dcac774f09 tests: check vdo minimum_io_size 2024-11-08 19:41:50 +01:00
Zdenek Kabelac
e4b5f8a485 debug: remove unused define 2024-11-08 19:41:50 +01:00
Zdenek Kabelac
c3ed3f28a2 device_mapper: suppress warns about inactive query
When command prints warning about suppressing query
for inactive table, because this is not supported
by kernel - 1 printed message is just enough, no
reason to 'spam' command output all the time, message
will remain only in debug log.

Also drop 'WARNING:' from real 'error' message.
WARNIGS are supposed to be just warning and command
then exists with 'success'.
2024-11-08 19:41:50 +01:00
Zdenek Kabelac
158d3243b6 vdo: fix input units for minimim_io_size
When specifying minimum_io_size with --vdosettings,
command assumed wrong unit (sectors).

So '--vdosettings minimum_io_size=512|4096' resulted into
an error that only 512 or 4096 values are allowed, but
at the same time values  1 or 8 were accepted.

So fix by converting any number >= 512 to 'sectors' and
keep input of 1 or 8 still valid if anyone has been using
this before.

So now we take  512 or 4096  and still also  1 or 8 with the
same effect.

Also correct the 'error' message when invalid minimum_io_size
is specified.
2024-11-08 19:41:18 +01:00
Peter Rajnoha
44a04b71f8
WHATS_NEW: update 2024-11-07 07:57:34 +01:00
Peter Rajnoha
a2ca20dad9
tests: remove superfluous -a option for df used in lvresize-xfs.sh
The df -a looks at whole system and it returns an error code in case
there's an inaccessible fs which is not even part of the testing environment.
The -a for df is not actually needed here in the lvresize-xfs test, so remove it.
2024-11-07 07:57:34 +01:00
Peter Rajnoha
1d8a4c4817
lv_manip: use the same param validation for RAID 0 as for RAID 1/4/5/6
This actually reverts commit 83ae675f8df53010c984b78d0318d0d92d5ac83a.
2024-11-07 07:57:34 +01:00
Peter Rajnoha
b5249fa3c2
lv_manip: fix stripe count and size validation for RAID LVs
Fix stripe count and size parameter validation for RAID LVs and
include existing automatic setting of these parameters based
on current shape of the RAID LV in case these are not set
on command line fully.

Previously, this was done only to a certain subset given by this
condition (where the 'stripes' is the '-i|--stripes' cmd line arg
and  the 'stripe_size' is actually the '-I|--stripesize' cmd line arg):

  !(stripes == 1 || (stripes > 1 && stripe_size))

This condition is a bit harder to follow at first sight and there
are no comments around with explanation for why this one is used,
so let's analyze it a bit more.

First, let's convert this to an equivalent condition (De Morgan law)
so it's easier to read for humans:

  stripes != 1 && !(stripes > 1 && stripe_size)

Note: Both stripe and stripesize are unsigned integers, so they can't be negative.

Now, based on that condition, we were running the code to deduce the
stripe/stripesize and do the checks ("the code") only if both of these
are true:

  - stripes is different from 1

  - we don't have stripes > 1 and stripe_size defined at the same time

But this is not correct in all cases, because:

  A) if someone uses stripes = 0, then "the code" is executed
    (correct)

  B) if someone uses stripes = 1, then "the code" is not executed
    (wrong: we still need to be able to check the args against
            existing RAID LV stripes whether it matches)

  - if someone uses stripes > 1, then "the code" is:

     C) if stripe_size = 0, executed
       (correct)

     D) if stripe_size > 0, not executed
       (wrong: we still want to check against existing RAID LV stripes)

Current issues with this condition:
  The B) ends up with segfault.

    ❯ lvextend -i 1 -l+1 vg/lvol0
      Rounding size 4.00 MiB (1 extents) up to stripe boundary size 8.00 MiB (2 extents).
    Segmentation fault (core dumped)

  The D) ends up with errors like:

    ❯ lvextend -i 3 -l+1 -I128k vg/lvol0
      Rounding size 4.00 MiB (1 extents) up to stripe boundary size 8.00 MiB (2 extents).
      Rounding size (4 extents) up to stripe boundary size for segment (5 extents).
      Size of logical volume vg/lvol0 changed from 8.00 MiB (2 extents) to 20.00 MiB (5 extents).
      LV lvol0: segment 1 with len=5  has inconsistent area_len 3
      Couldn't read all logical volumes for volume group vg.
      Failed to write VG vg.

Conclusion:
  The condition needs to be removed so we always run "the code" to check
  given striping args given on command line against existing RAID LV
  striping. The reason is that we don't want to allow changing stripe
  count for RAID LVs through lvextend and we need to end up with the
  error:
    "Unable to extend <RAID segment type> segment type with different number of stripes"

  (We do support changing the striping by lvconvert's reshaping functionality only).
2024-11-07 07:57:23 +01:00
Zdenek Kabelac
a210e9d768 makefiles: flip condition
With previous commit, in this case we need to flip condition,
to make it working here as expected.
2024-11-06 12:33:24 +01:00
Zdenek Kabelac
0fc7266353 gcc: do not mix signess compare 2024-11-06 00:04:54 +01:00
Zdenek Kabelac
2a1a7a863d gcc: make older compilers happier
Use {{}} for array initializer to quite warning for older gcc.
2024-11-06 00:04:54 +01:00
Zdenek Kabelac
f7df63748a makefiles: eliminate error output
Hide error message from 'find', if the 'lib' dir has
not been create yet (in case of non-srcdir build).
2024-11-06 00:04:54 +01:00
Zdenek Kabelac
987256aaa8 makefiles: use filter 2024-11-06 00:04:54 +01:00
Zdenek Kabelac
d53c71a4f2 makefiles: fix clean rule for non srcdir builds
With commit acbeaa7a8d86acc0f0e3c04723d066d995f29fe5 we started
to use symlinks to link test suite shell scripts, however
they remained within CLEAN_TARGETS.
So when running 'make clean' within non-srcdir build dir, we
were cleaning actuall shell script in this dir.
So remove list of this script from CLEAN_TARGETS in this case.
2024-11-06 00:04:54 +01:00
Zdenek Kabelac
dfa74465e9 tests: runner better handle help messages
Postpone check for root uuid so we can print help message.
2024-11-06 00:04:54 +01:00
Zdenek Kabelac
cf6cbfb7f7 tests: check strftime result 2024-11-06 00:04:54 +01:00
Zdenek Kabelac
352b1b1817 cov: check result of sync_local_dev_names
Although ATM this function always returns 1.
(maybe should be void)
2024-11-05 14:18:50 +01:00
Zdenek Kabelac
03782806eb lvmdiskscan: use while loop
Use more readable while() loop like in other similar instancies.
2024-11-05 14:18:50 +01:00
Marian Csontos
e42ceccc6d post-release 2024-11-04 16:42:12 +01:00
Marian Csontos
f87a6ad6d6 pre-release 2.03.28 2024-11-04 16:42:12 +01:00
Zdenek Kabelac
8ada61dbed gcc: fix warning about uninitialized use
get_sizes_lockspace() may not always initilize all passed values
in case the bitfield would not trigger if() path.
So just in case keep the path initilized.

TODO: maybe add INTERNAL_ERROR to get_sizes_lockspace().
2024-11-01 17:48:28 +01:00
David Teigland
0aa585a29f lvmlockd: remove unused vg_sysid
from structs and info dump.
2024-11-01 10:48:12 -05:00
Zdenek Kabelac
fc2e4a7b70 tests: skip test on older version
Prevent crashing kernel on older systems.
2024-11-01 13:27:20 +01:00
Zdenek Kabelac
057314ff8d lvmlockd: update prototype for non-lvmlockd build
Match prototype to last updates of lockd_init_lv_args().
2024-11-01 11:27:02 +01:00
David Teigland
88a085c485 lvmlockd: optimize new lv lease search
When converting a VG to locktype sanlock, a new
lease is allocated for each existing lv.  Finding
a new lease location involved searching the lvmlock
LV from the start for an unused location, which
would be very slow with many LVs.  Improve this by
starting each search from the last used location.
2024-10-31 20:29:00 -05:00
David Teigland
4eb66fd20c lvmlockd: fix vgchange --locktype sanlock
Fix regression from commit 7f29afdb06d
"lvmlockd: configurable sanlock lease sizes on 4K disks"

That change failed to recognize that a running lockspace will not
exist in lvmlockd when converting a local VG to a sanlock VG, i.e.
vgchange --locktype sanlock vgname.  When the vgchange attempted
to initialize new lv leases for existing LVs, lvmlockd would
return an error when it found no lockspace.
2024-10-31 16:31:35 -05:00
Zdenek Kabelac
354ca52e8c WHATS_NEW: update 2024-10-31 17:56:59 +01:00
Zdenek Kabelac
c2afa7a116 vg: add radix_tree for lv uuids
When searching for committed LV by uuid, this search can
be expensive for commands like 'vgremove' - so for
this part introduce  'lv_uuids' radix_tree that is
build with first access to lv_committed().
2024-10-31 17:55:31 +01:00
Zdenek Kabelac
db0f1b799f metadata: use radix_tree for find_lv_in_vg
Since there is a group of commands that need to access 'lv_list'
while still need to search for LV by its name, make the whole
struct lv_list a member of logical_volume structure.
This makes it easy to return also 'lv_list' this list this LV
within VG.
Also the patch should not use more memory, since we were allocating
lv_list for each LV anyway when linkin LV to VG.

Since find_lv_by_name() is now using radix_tree(),
use the same 'search for /' in LV in name for both
find_lv() & find_lv_in_vg().

TODO: Possibly refactor code and use only dm_list
instead of lv_list and dereference LV with container_of()
(thus saving pointer within struct logical_volume) - but
we use 'lv_list' currently in many places...
2024-10-31 17:55:31 +01:00
Zdenek Kabelac
0e5beb92c5 config: introduce validate_metadata
Add lvm.conf  config/validate_metadata  configurable setting.
Allows to disable validation of volume_group structure before
writing to disk.
Call of vg_validate() is supposed to catch any inconsistency
of in-memory volume group structure and possibly early aborting
commnand before making any more 'damage' in case the VG struct
is found insistent after some metadata manipulation.

This is almost always useful for devel - and also for normal user
as for small metadata size this doesn't add too much overhead.

However if the volume_group size is large and operations are just
adding removing simple LVs - this validation time may add noticable
to final command running time.

So if the user seeks the highest perfomance of command and does
not do any 'complex' metadata manipulation - it's reasonably safe
to disable validation (with the use of setting "none") here.
2024-10-31 17:55:31 +01:00
Zdenek Kabelac
7bf404db3b validate_lvname: early exit
If the LV name does not any have '_' chr,
there is no point trying to call 'strstr()' to look for "_suffix".
Also we can search from _.
2024-10-31 17:55:31 +01:00
Zdenek Kabelac
ae8ba49142 cov: validate string with lock mode
Check the dev_mode string is not NULL before use.
2024-10-30 13:09:31 +01:00
Zdenek Kabelac
6ebcb0015e cov: add stacktraces
Add stacktraces for unexpected paths.
2024-10-30 13:08:56 +01:00
Zdenek Kabelac
699696b0a6 vdo: reader checks there is enough data
Validate enough of data was read from disk to parse vdo header.
TODO: there should be a loop for buffer reading.
2024-10-30 12:59:08 +01:00
Zdenek Kabelac
8095a6c14c metadata: pahole logical_volume
Shuffle some variables to remove 'extra' alignment holes
within the structure thus making it smaller.
2024-10-30 12:59:08 +01:00
Zdenek Kabelac
9e8bd57e15 metadata: lv_set_name use uniq_insert
With presence of uniq_insert, use this function also
here for extra protection and check for duplicate lv_name
when inserting a new name into radix_tree.
2024-10-30 12:59:08 +01:00
Zdenek Kabelac
b66b72b115 get_alloc_string: compare only enum
Instead of possibly checking for cling_by_tags string twice,
just compare resulting alloc number from search loop.
2024-10-30 12:57:34 +01:00
Zdenek Kabelac
30adf7e91c toolcontext: use the striped string first 2024-10-30 12:57:34 +01:00
Zdenek Kabelac
e2a5715a60 cache_manip: reset sigint handler
After processing interrupt, reset the interrupt counter,
so further code is not mislead and continues processing
in 'locked' section as expected.
2024-10-30 12:57:34 +01:00
Zdenek Kabelac
0e64d49642 tests: use longer tag
Avoid config 'grep' with actual 'randomly' generated path name
which may eventually contain 'cc' as part the path and
causing a mismatch of the grep test.
2024-10-30 12:57:34 +01:00
Zdenek Kabelac
608418e4f2 debug: missing stacktrace 2024-10-28 20:07:37 +01:00
Zdenek Kabelac
16241b2dc7 lv_manip: init major minor in alloc_lv
Move initialization of major and minor to alloc_lv().
2024-10-28 20:07:37 +01:00
Zdenek Kabelac
e2b00dd162 device_mapper: use static array for dm_size_to_string
Avoid copying this structure on stack with every call.
2024-10-28 20:07:37 +01:00
Zdenek Kabelac
b05e0df4e1 tests: add reproducer for failing raid5 activation
For now use 'should' to mark this 'known' failure.
This case needs solution.
2024-10-28 20:07:37 +01:00
Zdenek Kabelac
86dc72c28c tests: flip to use FSLASTBLOCK
It seems FSSIZE is newer then FSLASTBLOCK so use this one instead.
2024-10-28 20:07:37 +01:00
Zdenek Kabelac
a934231623 tests: correcting expected return code
Expecting success when using with '-r'.
2024-10-28 20:07:37 +01:00
Heinz Mauelshagen
708435d187 man: lvchange update about --syncaction being transient 2024-10-25 22:03:18 +02:00
Zdenek Kabelac
034b6a262c WHATS_NEW: update 2024-10-25 15:08:03 +02:00
Zdenek Kabelac
143545a08c lvmlockd: fix incorrect function definition
In commit 7f29afdb06d9f3420b3d2174d6ed4c55a58ac706 this function
was added with misplaced ';'.
2024-10-25 15:08:03 +02:00
Zdenek Kabelac
c8a8c7286f tests: add test to resize to same size
Check that 'lvresize/extend -r' resizing to the same size is
doing the fs resize.
2024-10-25 15:08:03 +02:00
Zdenek Kabelac
5a293968ec lvresize: fix regression when resizing with fs
When 'lvresize -r' is used to resize the volume, it's valid to
resize even to the same size of an LV, as the command then runs
fs-resize utility to eventually upsize the fs to the current
volume size.

Return code of such command then reflects the return value
of this fs-resize tool.

This fixes the regression introduced when the support
for option --fs was added (2.03.17).
2024-10-25 15:06:39 +02:00
Peter Rajnoha
43ce78e5c6
tests: lvresize-fs: check blkid version for lvresize with swap test 2024-10-25 13:21:57 +02:00
Peter Rajnoha
aa0200c3ff
dev-type: update comment about swap info from blkid 2024-10-25 12:53:07 +02:00
Zdenek Kabelac
40010e3eb8 clang: close file on memory alloc error path 2024-10-25 01:26:40 +02:00
Zdenek Kabelac
ebc5c0cb1d clang: check for dirfd result 2024-10-25 01:26:40 +02:00
Zdenek Kabelac
0fbcb3b308 clang: check segment lv is defined 2024-10-25 01:26:40 +02:00
Zdenek Kabelac
5ec8f744d0 clang: ensure pointer is defined
Check for new_segtype and lv is defined
before dereferencing.
2024-10-25 01:26:40 +02:00
Zdenek Kabelac
ea4daeb28e cov: use 64bit arithmentic 2024-10-25 01:26:40 +02:00
Zdenek Kabelac
1363a5ffb2 cov: ensure detached_log_lv exists before use 2024-10-25 01:26:40 +02:00
Zdenek Kabelac
5a3375f958 debug: use major:minor
Print major:minor as in other places.
2024-10-25 01:26:40 +02:00
Zdenek Kabelac
edfa4955d8 device_id: close only opened dir
After more of opendir, make sure 'dir' is closed
only when it's been opened.
2024-10-25 01:26:40 +02:00
Zdenek Kabelac
a5e3f0e6dd metadata: check for mda_device existance 2024-10-25 01:26:39 +02:00
Zdenek Kabelac
f61572eef2 dev-cache: ensure list has elements
When updating DM cache, check whether the list even has entries
before comparing it with old cached instance.
2024-10-25 01:26:39 +02:00
Zdenek Kabelac
87f68f443c metadata: fallback search without radix_tree
If we use some dummy vg struct, allow fallback
plain dm_list search.
2024-10-25 01:26:39 +02:00
Zdenek Kabelac
7d48c1f6e3 device_mapper: add omitted error message 2024-10-25 01:26:39 +02:00
Zdenek Kabelac
188dd3c357 device_mapper: check for pv before use in error msg 2024-10-25 01:26:39 +02:00
David Teigland
875012fb5d lvmlockd: enable lockopt nodelay for lockstart
Avoid the sanlock add_lockspace delay in vgchange --lockstart
by adding --lockopt nodelay.  This is for testing, and is not
safe to use in general.
2024-10-24 17:15:16 -05:00
Zdenek Kabelac
77332669d0 WHATS_NEW: update 2024-10-24 21:38:35 +02:00
long.yunjian@zte.com.cn
639fb633d3 cleanup: correct invalid function
Use proper function names in annotation

There are no fuction named print_common_options_cmd()
and print_common_options_lvm(). So, rename them to the
real function named print_usage_common_cmd() and
print_usage_common_lvm().

Signed-off-by: YunJian Long
2024-10-24 21:38:06 +02:00
Zdenek Kabelac
9295de7cea tests: do not use shell pipe for reshape_len
Tricky one - as the pipe exit codes may result into whole
test failure depending on how quick/slow command exits
are within pipeline.

So get the len without piping.
2024-10-24 21:24:26 +02:00
Zdenek Kabelac
2c5bf25187 devicesfile: move opendir after fclose
Call opendir() after new file is stored within dir,
otherwise this new file would not accounted.
2024-10-24 21:24:26 +02:00
Zdenek Kabelac
b88cbc7f17 metadata: missed lv_set_name users
Missed when introduced lv_set_name().
2024-10-24 21:24:26 +02:00
Zdenek Kabelac
c27d6695c1 lv: add lv_set_vg
To keep vg->lv_names up-to-date also for merge & split,
add function lv_set_vg() the will update also radix tree
reference for a VG.
2024-10-24 21:23:49 +02:00
Zdenek Kabelac
73c7dac1a8 WHATS_NEW: update 2024-10-24 17:38:09 +02:00
Zdenek Kabelac
21517c2bd5 metadata: use radix tree to find lv_names
Replace usage of dm_hash with radix_tree to quickly find LV name
with a vg and also index PV names with set of available PVs.
This PV index is only needed during the import, but instead
of passing 'radix_tree *' everywhere, just keep this within
a VG struct as well and once the parsing is finished, release
this PV index radix_tree.

This also makes it easier to replace this structure
in the future if needed.

lv_set_name now uses  radix_tree remove+insert to keep lv_names
tree in-sync and usable for  find_lv queries.
2024-10-24 17:38:09 +02:00
Zdenek Kabelac
1825e782cc revert "metadata: use lv_hash in segment-specific metadata parsing"
This reverts commit f42aef47064fcc3fa8f78beea9e9b7e7c028e123.

Going to replace dm_hash with radix_tree and use 'find_lv()'
to abstract lookup for LV with VG.
2024-10-24 17:38:09 +02:00
Zdenek Kabelac
956b2c568f metadata: use lv_set_name for raid and mirror
Use lv_set_name API also for raid and mirror LV manipulation.
2024-10-24 17:38:09 +02:00
Zdenek Kabelac
c681d4e61a metadata: add lv_set_name
Add function to set lv->name.
Also when creating empty LV, first add this LV
to linked list in a VG and just after that allocate lv name.
2024-10-24 17:38:09 +02:00
Zdenek Kabelac
73f24443e5 check_pv_segments: resolve pv name once 2024-10-24 17:38:09 +02:00
Zdenek Kabelac
eb4b307d0c log: postpone some initialization
Clear buffers when really logging.
2024-10-24 17:38:09 +02:00
Zdenek Kabelac
dee8bc9ae4 lv_manip: remove duplicate check for max lv
This check is always performed with call to link_lv_to_vg().
2024-10-24 17:37:30 +02:00
Zdenek Kabelac
d62170d646 flags: drop no longer needed header
After code refactoring, this header is not needed here anymore.
2024-10-24 17:35:33 +02:00
Zdenek Kabelac
668c185949 vg_validate: use uniq_insert
Enhance usage with uniq_insert and also try to better
utilize CPU cache and do a smaller loop for individual
hashing of lvname and separately lvid.

Also correcting usage of 'continue' within validation of
historical names as it should report as much errors
as it can within a loop.
2024-10-24 17:35:33 +02:00
Zdenek Kabelac
0852c3171d tests: unit test for uniq insert into radix_tree 2024-10-24 17:35:33 +02:00
Zdenek Kabelac
5b1ebed3fc radix_tree: add radix_tree_uniq_insert
When using radix_tree to identify duplicate entries we may
avoid to call an extra 'lookup()' prior the insert() operation
add radix_tree_uniq_insert/_ptr() that is able to report -1 if
there was already set a value for the given key.
2024-10-24 17:24:40 +02:00
Zdenek Kabelac
dd856edaab vgcfgrestore: validate complete VG
Avoid finding problems in vg_validate when restoring
invalid VG metadata as that would lead to internal error.
i.e. adding unsupported METADATA_FLAG to zero segtype
can trigger such thing.
2024-10-23 20:16:14 +02:00
Zdenek Kabelac
2916a8a1f3 read_lvflags: keep flag reading focused on flags
Previous update needed to add handling segtype within flag.c
which somewhat breaks API separition and also had bug in hanlding
actual flags.

So instead keep segtype code in _read_segtype_and_lvflags() within
import_vsn1.c and handle purly flags in read_lvflags() from const
string.
2024-10-23 20:16:14 +02:00
Zdenek Kabelac
1f0530919e export: typo with buffer zeroing
Lost '= 0' in cut & paste.
Also get rid of no longer needed 'goto' section.
2024-10-23 20:15:48 +02:00
Zdenek Kabelac
ea39c58127 export: add missed buffer initialization
Since we reduced emitting to single string list,
we need to make sure empty list are not producing
garbage strings.
2024-10-23 14:38:21 +02:00
Zdenek Kabelac
056ad4a8f4 WHATS_NEW: update 2024-10-23 14:10:46 +02:00
Zdenek Kabelac
e0421ee7bf export: change to read_segtype_and_lvflags
Instead of duplicating whole segtype string with flags and
using 2 calls read_segtype_lvflags() + get_segtype_from_string(),
merge the functionality into a single read_segtype_and_lvflags().
This allows to make only a local string copy (no allocs) and eventually
to not copy segtype string at all, when there are no flags.
2024-10-23 14:10:46 +02:00
Zdenek Kabelac
4929c55bc5 export: reduce emit_to_buffer calls
As the 'emit_to_buffer' uses relatively complex
vsnprintf() call inside, try to reduce number
of unnecessary calls and try replace some more
complex string build with a single call instead.
2024-10-23 14:10:46 +02:00
Zdenek Kabelac
7156b4930d dev-cache: enhance usability of dm cache
With existing code, the cache was working only to the 2nd. locking.
So i.e. when 'lvs' scans system with more then one VG, the caching
was effectively not working.

Update the code, so the label invalidate code is able to update DM
cache - so whenever we take a new lock - we will refresh the cache.

TODO: the refresh ATM does a very simple compare of old a new list
of cached DM device, and with the first spotted difference, it just
fallback to the full rebuild of DM cache - with large amount of active
devices this might not the most efficient way....
2024-10-23 14:10:35 +02:00
Zdenek Kabelac
96cea466a5 tests: skip test for too old sfdisk 2024-10-22 22:30:47 +02:00
Zdenek Kabelac
0f793fcbca check_lv_segment: correct last change
Previous commit 7c5cca600c071c9991acb3fcafb9f8a3f60e03e5
was not correctly aliging block that was checking mirrors.
2024-10-22 22:25:54 +02:00
Zdenek Kabelac
5666728b27 WHATS_NEW: update 2024-10-22 19:36:00 +02:00
Zdenek Kabelac
d121707ffa debug: drop stack 2024-10-22 19:36:00 +02:00
Zdenek Kabelac
c19dfe11a5 debug: use just LV name for debug message
Since we detect 'debug' level after calling 'log_debug()' - all
the arguments are evaluated, so in this case display_lvname() was
preparing a string that is not used in case debugging is not enabled.

So since these string are on 'hot-path' and it's already known
which VG is being worked on, in these few cases just use lv->name.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
ccd693d065 reporting: prepare id string only for json output
When processing LVs for a command we stored  '*object_id' & '*group_id'
as printable string that was however only used with json reporting.

Refactor code so we simply store there 'struct id*' that is just
converted into printable string when json reporting is really used.

Also check for 'sigint()' right before loop processing begins which
is primary purpose of this test.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
34b5d7f8bd vg_validate: use radix_tree
Replace dm_hash with radix_tree which uses less memory
and gives same performance.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
5827c9e337 config: use dm_config_parse_only_section 2024-10-22 19:36:00 +02:00
Zdenek Kabelac
5d2d3c53a4 device_mapper: add dm_config_parse_only_section
This function call is able to setup config parser so it stops
parsing 'subsection' nodes after parsing named section node.
Only nodes at 'level' 0 will be still processed. And this nodes
are found by searching for last  \n}\n sequence from the end of
buffer   (instead of trying to analyze all the text in buffer).
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
4dc0ee8e56 export: use radix_tree for write formatter
Replace use of dm_hash with radix_tree when making PV index names.

Store just the index number itself and use pv%d for outf() string.

For lookup up a PV - use just the PV pointer itself, it's faster then
converint for it's ID to UUID format.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
7c5cca600c check_lv_segment: split into incomplete complete
Split single check_lv_segments() into 2 separate
versions so they can be called independently.
This allow to 'skip' already checked segment
check after it's been imported to VG and also
avoid another repeated checking when validating
segment with complete vg.

**
check_lv_segments_incomplete_vg()

this check just basic LV segment properties and does not
validate those requiring full VG.

**
check_lv_segments_complete_vg()

Remaining check that expects complete VG is present.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
fa11ef6846 metadata: look for LV by name with find_lv
Avoid getting dm_list reference when looking for logical_volume*.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
1755ceb17c thin: check only for profiled config vars
ATM this rather save a lot of unncessary log entries as it grabs
the global autoextend_threshold (profile == NULL) just once instead
of revealing it every time with NULL profile.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
8fcfac7c89 lv: set creation uses const string
There is no need to duplicate const string we got and keep
from uname() call.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
b4156bb4de export: limit generation of comment strings
Generate comment string only for formatter with comments.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
0179f00e0c import: check fixup mirror only when needed
Track whether import has even seen segment of LV with log_lv,
and call fixup mirror only in this case.

Also avoid repeated lookup of get_segtype_from_string for
SEG_TYPE_NAME_MIRROR.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
89da9ae251 device_mapper: increase mem pool chunk size
Use bigger memory pool chunk size and reduces amount of
memory pool extensions when handling larger metadata, but do not
make it noticable bigger when handling small ones...

Use same large value also when allocating VG memory pool.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
9c9953dc3e device_mapper: join flags checks together
Just use a single bitmask flag check and OR fields together.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
fd9f7d10ca device_mapper: query for json report once
Remember _is_json_report() check for whole function.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
f59fa69507 device_mapper: use on stack allocation
Reduce number of heap allocation calls and for smaller
locally used string, use on stack allocation.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
d8996a2a12 device_mapper: store string on stack
Instead of allocating string from a pool, for shorted strings
use buffer on stack since the string after the use in _find_or_make_node()
as no longer needed.
Eventually we may enhance code also for TOK_STRING_ESCAPED and TOK_STRING,
but they appear to be unused for _section().
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
c29e3410c9 device_mapper: slight improvement of tok_match
Reduce amount of unnecessary instructions for some code paths.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
92158a24a5 device_mapper: optimize _get_token
For the most common part check for '#' when it's known it's not a space.
And also when we checked for '\n' we dont need to check again isspace().

Also help a bit more 'gcc' optimizer to grab buffer char just once and
simplify jump to next characted in the buffer when checking for token.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
2f022f5cbb device_mapper: nodes and values with strings
Avoid double dm_pool allocation call by copying string
for node name and config value directly after the end
of node/value structure.

It would be likely better to not copy these strings at all
and derefence it from the original string however that
needs futher changes in the code base.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
b185578321 crc: add newer zlib code
This code is faster when calculating crc32 checksum for larger
block areas. There is also SIMD variant present in the code,
however ATM the influence on performance of lvm2 is not that big..
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
f55c949410 crc: move static table
Move static table upward in the code so it can be shared with
another 'crc' implementation.
2024-10-22 19:36:00 +02:00
Zdenek Kabelac
d07e273aff lvmlockd: drop return 1 from void function
When compiling code without lvmlockd, the void function
lockd_free_lv_after_updatei()  should not return any value.
2024-10-22 19:15:55 +02:00
Peter Rajnoha
e96d6b7442
lv_manip: fall back to direct zeroing on any BLKZEROOUT ioctl failure
When BLKZEROOUT ioctl fails, it should not stop us from trying the direct
zeroing as a fallback action, since this is an optimization only.
We should be able to continue with new LV creation if we succeed
with that direct fallback then.

Related report: https://issues.redhat.com/browse/RHEL-58737
2024-10-18 11:44:34 +02:00
David Teigland
6ab2a22fcf lvremove: fix failed remove of all LVs in shared VG
commit a125a3bb505cc "lv_remove: reduce commits for removed LVs"
changed "lvremove <vgname>" from removing one LV at a time,
to removing all LVs in one vg write/commit.  It also changed
the behavior if some of the LVs could not be removed, from
removing those LVs that could be removed, to removing nothing
if any LV could not be removed.  This caused a regression in
shared VGs using sanlock, in which the on-disk lease was
removed for any LV that could be removed, even if the command
decided to remove nothing.  This would leave LVs without a
valid ondisk lease, and "lock failed: error -221" would be
returned for any command attempting to lock the LV.

Fix this by not freeing the on-disk leases until after the
command has decided to go ahead and remove everything, and
has written the VG metadata.

Before the fix:

node1: lvchange -ay vg/lv1
node2: lvchange -ay vg/lv2

node1: lvs
  lv1  test -wi-a----- 4.00m
  lv2  test -wi------- 4.00m
node2: lvs
  lv1  test -wi------- 4.00m
  lv2  test -wi-a----- 4.00m

node1: lvremove -y vg/lv1 vg/lv2
  LV locked by other host: vg/lv2

(lvremove removed neither of the LVs, but it freed
the lock for lv1, which could have been removed
except for the proper locking failure on lv2.)

node1: lvs
  lv1  test -wi------- 4.00m
  lv2  test -wi------- 4.00m

node1: lvremove -y vg/lv1
LV vg/lv1 lock failed: error -221

(The lock for lv1 is gone, so nothing can be done with it.)
2024-10-16 13:18:14 -05:00
Peter Rajnoha
8e3db44036
device_id: fix segfault if devices file has PVID=. 2024-10-15 10:58:16 +02:00
Peter Rajnoha
317fae4024
dev-type: detect mixed dos partition with gpt's PMBR
Detect when we have mixed dos partition with gpt's PMBR partition.

This is not a sane configuration, but detect it anyway, just in case
someone configures such partition layout manually and forcefully and
incorrectly defines one of the partition types to be the GPT's PMBR.

For example:

  ❯  fdisk -l /dev/sdc

  Device     Boot Start    End Sectors Size Id Type
  /dev/sdc1        2048  67583   65536  32M 83 Linux
  /dev/sdc2       67584 262143  194560  95M ee GPT

Before:
(The partition filter passes even though there's real existing dos
partition - the empty GPT PMBR overrides it.)

  ❯  pvcreate /dev/sdc
  WARNING: PMBR signature detected on /dev/sdc at offset 510. Wipe it? [y/n]:
  Wiping PMBR signature on /dev/sdc.
  Physical volume "/dev/sdc" successfully created.

With this patch applied:
(The GPT PMBR does not override the existence of the dos partition.)

  ❯  pvcreate /dev/sdc
    Cannot use /dev/sdc: device is partitioned
2024-10-03 09:55:36 +02:00
Marian Csontos
e2e6b08518 post-release 2024-10-02 14:21:43 +02:00
Marian Csontos
207990a877 pre-release 2024-10-02 14:21:09 +02:00
Marian Csontos
ec965dde39 WHATS_NEW and release-notes update 2024-10-02 14:18:35 +02:00
Peter Rajnoha
b77f7acac8
WHATS_NEW: update 2024-10-02 13:49:45 +02:00
Marian Csontos
ca02546649 [WIP] Disable dlm for RHEL10 2024-10-02 13:48:11 +02:00
Tobias Stoeckmann
493d8908fb lvmdbusd: Fix Python script
The thread does not contain field "damon" but "daemon".

Actually found with codespell.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-10-02 11:34:22 +00:00
Peter Rajnoha
9d6a3ee547
filesystem: add note about swap devices 2024-10-02 13:31:54 +02:00
Peter Rajnoha
bd5ca83c43
tests: also test swap devices in lvresize-fs.sh 2024-10-02 13:31:54 +02:00
Peter Rajnoha
5096335277
lv_manip: handle swap devices in fs-related checks for lvreduce/lvextend
This provides better hints when trying to resize the fs on top of an LV.
Also needs a3f6d2f593a4d278daf9ba3a1ba30bae38d8396a for proper operation.

❯  lvs -o name,size vg/swap
  lv_name lv_size
  swap     60.00m

Before:

❯  lvextend -L72m vg/swap
  Size of logical volume vg/swap changed from 60.00 MiB (15 extents) to 72.00 MiB (18 extents).
  Logical volume vg/swap successfully resized.

❯  lvreduce -L60m vg/swap
  File system swap found on vg/swap.
  File system device usage is not available from libblkid.

❯  lvreduce -L50m vg/swap
  Rounding size to boundary between physical extents: 52.00 MiB.
  File system swap found on vg/swap.
  File system device usage is not available from libblkid.

After:

❯  lvextend -L72m vg/swap
  Size of logical volume vg/swap changed from 60.00 MiB (15 extents) to 72.00 MiB (18 extents).
  Logical volume vg/swap successfully resized.

❯  lvreduce -L60m vg/swap
  File system swap found on vg/swap.
  File system size (60.00 MiB) is equal to the requested size (60.00 MiB).
  File system reduce is not needed, skipping.
  Size of logical volume vg/swap changed from 72.00 MiB (18 extents) to 60.00 MiB (15 extents).
  Logical volume vg/swap successfully resized.

❯  lvreduce -L50m vg/swap
  Rounding size to boundary between physical extents: 52.00 MiB.
  File system swap found on vg/swap.
  File system size (60.00 MiB) is larger than the requested size (52.00 MiB).
  File system reduce is required and not supported (swap).
2024-10-02 13:31:54 +02:00
Peter Rajnoha
e009becd73
dev-type: get swap device size from blkid using FSSIZE
blkid does not report FSLASTBLOCK for a swap device. However, blkid
does report FSSIZE for swap devices, so use this field (and including
the header size which is of FSBLOCKSIZE for the swap) instead to
set the "filesystem last block" which is used subsequently for
further calculations and conditions.
2024-10-02 13:31:54 +02:00
Peter Rajnoha
4524778b23
tests: add pvcreate-partition.sh 2024-10-02 12:02:35 +02:00
Peter Rajnoha
d5d2c98980
dev-type: add prefix to differentiate msdos and gpt constants 2024-10-02 12:02:34 +02:00
Peter Rajnoha
84cabd068b
filter: partitioned: also detect non-empty GPT partition table
We already detect msdos partition table. If it is empty, that is, there
is just the partition header and no actual partitions defined, then the
filter-partitioned passes, otherwise not.

Do the same for GPT partition table.
2024-10-02 11:54:01 +02:00
Zdenek Kabelac
4708a354f6 make: generate 2024-09-30 15:00:03 +02:00
Zdenek Kabelac
28e7be9f39 cov: annotate 2024-09-30 15:00:03 +02:00
Zdenek Kabelac
0e1e220c3d cov: potentially overflowing expression
Use 64bit arithmentic.
2024-09-30 15:00:03 +02:00
David Teigland
7f29afdb06 lvmlockd: configurable sanlock lease sizes on 4K disks
New config setting sanlock_align_size can be used to configure
the sanlock lease size that lvmlockd will use on 4K disks.

By default, lvmlockd and sanlock use 8MiB align_size (lease size)
on 4K disks, which supports up to 2000 hosts (and max host_id.)

This can be reduced to 1, 2 or 4 (in MiB), to reduce lease i/o.
The reduced sizes correspond to smaller max hosts/host_id:

1 MiB = 250 hosts
2 MiB = 500 hosts
4 MiB = 1000 hosts
8 MiB = 2000 hosts (default)

(Disks with 512 byte sectors always use 1MiB leases and support
2000 hosts/host_id, and are not affected by this.)
2024-09-27 17:59:03 -05:00
Zdenek Kabelac
6816366ff1 WHATS_NEW: update 2024-09-27 13:44:59 +02:00
zkabelac
7447634c26 cleanup: replace use of alloced with allocated 2024-09-27 13:42:45 +02:00
zkabelac
0862e2b150 cleanup: typos in libdm 2024-09-27 13:42:45 +02:00
zkabelac
74f607952d cleanup: more typos in WHATS_NEW 2024-09-27 13:42:45 +02:00
Tobias Stoeckmann
cb781b3e1d cleanup: fix typos
Typos found with codespell.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-27 13:42:45 +02:00
Zdenek Kabelac
964012fdb9 memlock: use value of 0 to disable memory locking
In cases user is sure he is not using his 'rootfs' or 'swap' on LVs
managed with his command - it possible to completely bypass pinning
process to RAM which may eventually slightly speedup command execution,
(however at the risk the process can be eventually delayed by swapping).
Basicaly use this only at your risk...

TODO: add some dmeventd support for this.
2024-09-27 13:42:45 +02:00
Zdenek Kabelac
7e2bb2a35e vdo: depcreate unused settings 2024-09-26 16:25:12 +02:00
David Teigland
e9413fb211 lvmlockd: use lvmlock LV size
Previously, lvmlockd detected the end of the lvmlock LV
by doing i/o to it until an i/o error was returned.
This triggered sanlock warning messages, so use the LV
size to avoid accessing beyond the end of the device.

Previously, every lvcreate would refresh the lvmlock LV
in case another machine had extended it.  This involves
a lot of unnecessary work in most cases, so now compare
the LV size and device size to detect when a refresh is
needed.
2024-09-26 08:53:09 -05:00
David Teigland
9d7c19c2ce lvmlockd: fix previous thin locking fix
Restore the original lvremove locking for non-thin LVs
that were changed in the thin locking fix.
2024-09-23 17:15:42 -05:00
David Teigland
d7a028aaad vg: remove unused hostnames hash table
The hash table of lv creation hostnames was not used for anything,
so remove it.
2024-09-23 15:04:53 -05:00
David Teigland
1c3d7dfb07 lvmlockd: fix locking for thin
lvremove of a thin lv while the pool is inactive would
leave the pool locked but inactive.

lvcreate of a thin snapshot while the pool is inactive
would leave the pool locked but inactive.

lvcreate of a thin lv could activate the pool to check
a threshold before the pool lock was acquired in lvmlockd.
2024-09-23 14:57:07 -05:00
Peter Rajnoha
86a9db05cf
tests: remove superfluous -a option for df used in lvresize-fs.sh 2024-09-19 15:12:44 +02:00
David Teigland
f42aef4706 metadata: use lv_hash in segment-specific metadata parsing
The lv_hash wasn't being passed to the seg-specific text import
functions, so they were doing many find_lv() calls which consumes
a lot of time when there are many LVs in the metadata.
2024-09-10 11:51:15 -05:00
David Teigland
1b68841605 args: readonly description update
Include reference to --permission r.
2024-09-06 08:44:06 -05:00
Peter Rajnoha
e8383073a9
WHATS_NEW_DM: update 2024-09-05 12:14:42 +02:00
Peter Rajnoha
1e48599193
libdm: do not fail if GETVAL semctl fails for udev sync inc and dec
While performing udev sync semaphore's inc/dec operation, we use the
result from GETVAL semctl just to print a debug message with current
value of that sempahore, nothing else.

If the GETVAL fails for whetever reason while the actual inc/dec
completes successfully, just log a warning message about the GETVAL
(and print the debug messages without the actual semaphore value)
and return success for the inc/dec operation as a whole.
2024-09-05 12:14:42 +02:00
Peter Rajnoha
f7f08ba881
libdm: clean up udev sync semaphore on fail path during its creation
Clean up udev sync semaphore on fail path during its creation, otherwise
the caller will have no handle returned to clean it up itself and the
semaphore will keep staying in the system. The only way to clean it up
would be to call `dmsetup udevcomplete_all` which would destroy all
udev sync semaphores, not just the failed one, which we don't want.
2024-09-05 12:14:42 +02:00
Peter Rajnoha
de196f4b60
libdm: add 'cookie create/inc/dec' log prefix if GETVAL fails for udev sync ops
The same message is printed while performing create/inc/dec operation and
the GETVAL semctl fails. Add a prefix so we know exactly in which of
these functions the issue actually happened.
2024-09-05 12:14:37 +02:00
Marian Csontos
80d7483322 scripts: Fix ConditionPathExists in unit files 2024-09-04 14:40:58 +02:00
Zdenek Kabelac
b7fef5b133 WHATS_NEW: update 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
418fb5a3b4 configure: autoreconf 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
915689f566 make generate 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
a4fa14c73b cleanup: typos in configure.ac 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
460ff472f9 cleanup: typos in test comments 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
0e52e215a8 cleanup: typos in test logging 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
26a6c69a87 cleanup: typos in doc 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
e3a2f7b8ee cleanup: typos man pages 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
7d816c6a4a cleanup: typos in WHATS_NEW 2024-08-30 16:51:15 +02:00
Zdenek Kabelac
39b7d1ba8f cleanup: typos in comments
Collection of typos in code comments.
Should have no runtime effect.
2024-08-30 16:51:15 +02:00
Zdenek Kabelac
7da47cea35 cleanup: typos in logging
Fixes various typos in printed/logged messages.
2024-08-30 16:51:15 +02:00
Zdenek Kabelac
643bc26595 cleanup: typo dirctory to directory
Rename internal lm_idm_scsi_find_block_directory() function.
2024-08-30 16:51:14 +02:00
zkabelac
6a8ba51d82 cleanup: typo premable to preamble
Correct preable, seems even unused.
2024-08-30 16:51:04 +02:00
zkabelac
1c9e619fef libdm: _DOESNT_ to _DOES_NOT_
Rename internal define DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID
to DM_NAME_LIST_FLAG_DOES_NOT_HAVE_UUID
(currently unused)
2024-08-30 16:48:48 +02:00
Zdenek Kabelac
bfd5464002 lvmlockd: retrive to retrieve
Replace retrive with retrieve for internal function.
2024-08-30 16:48:48 +02:00
Zdenek Kabelac
625c55fd6c libdaemon: daemonise to daemonize
Replace daemonise() with daemonize().
2024-08-30 16:48:48 +02:00
zkabelac
b8a4fda0f7 lvconvert: use pvmove as part of renamed LV name
LV with pvmove_ prefix is not allowed to be created by user
so bigger chance our selected name will never exist.

TODO: probably add code to get generic unused LV name...
2024-08-30 16:48:48 +02:00
Zdenek Kabelac
a8696ee72a libdm: check for queue name
Fix typo and check for queue string within sysfs kernel name.
2024-08-30 16:48:48 +02:00
Zdenek Kabelac
f301f6acbc integrity: typo interleave_sectors
Correct emitted parameter name for interleave_sectors for DM table line.
2024-08-30 16:48:48 +02:00
Peter Rajnoha
7a20ac4f61
make: generate 2024-08-30 14:24:26 +02:00
Peter Rajnoha
4313e3896c
man: lvmreport: add note about log/command_log_selection="all" 2024-08-30 14:24:26 +02:00
Peter Rajnoha
30e25d0db9
config: update description for log/command_log_selection 2024-08-30 14:20:03 +02:00
Peter Rajnoha
83ae675f8d
lvresize: ignore given stripe and stripe size args for raid0 2024-08-29 14:01:27 +02:00
Peter Rajnoha
c65d379769
toollib: do not accept duplicate device name on pvcreate input 2024-08-28 10:35:18 +02:00
Marian Csontos
8e9d7ace7b post-release 2024-08-23 16:02:19 +02:00
Marian Csontos
6de3937ac5 pre-release 2024-08-23 16:02:19 +02:00
David Teigland
7825d914e3 lvmlockd: increase dump buffer size 2024-08-22 16:23:07 -05:00
Zdenek Kabelac
e2f6af68c2 WHATS_NEW: update 2024-08-22 14:47:29 +02:00
Zdenek Kabelac
efbea49971 make: generate 2024-08-22 14:47:29 +02:00
Zdenek Kabelac
038760da4f gcc: single type initializers
Older gcc doesn't really like complex types (buffer, struct) to be
initialized without extra {} around such type.
So pick any other 'single type' var from a struct and set it to 0,
rest will do the compiler without emitting a warning.
2024-08-22 14:47:29 +02:00
Zdenek Kabelac
ff2cadbf18 cleanup: drop extra space 2024-08-22 14:38:40 +02:00
Zdenek Kabelac
7dbb362c0f tests: check pvmove on single PV 2024-08-22 14:36:28 +02:00
Zdenek Kabelac
07b6174f7c validation: support empty lv segments
Revert 373372c8ab3749bc76ced37cec04b00aae6e5979 and instead update
our validation code to handle LVs with empty segment - currently
we should need this only for pvmove operation, thus such LV should
have name  'pvmove%u'.

This fixes a problem where user tried i.e. pvmove on a VG with single
PV - as reported: https://github.com/lvmteam/lvm2/issues/148

Reported-by: bob@redhat.com
2024-08-22 14:36:28 +02:00
Peter Rajnoha
9df8dd97c3
WHATS_NEW: update 2024-08-14 15:30:30 +02:00
Peter Rajnoha
b53a2ae2a4
tools: vgscan: accept --refresh option 2024-08-14 15:12:59 +02:00
Peter Rajnoha
1ced65b6b4
tools: vgscan: accept --refresh option 2024-08-14 15:09:50 +02:00
Peter Rajnoha
9472e9c5a0
tools: args: update description for --refresh 2024-08-14 14:59:07 +02:00
Peter Rajnoha
4efed9ee99
tools: vgmknodes: use display_lvname 2024-08-14 14:20:55 +02:00
Peter Rajnoha
845a65a755
tools: vgmknodes: handle /dev/mapper content without LV refresh only if udev not running 2024-08-14 13:53:17 +02:00
Peter Rajnoha
5c6120186d
tools: vgmknodes: log error message if LV refresh fails 2024-08-14 13:50:22 +02:00
Peter Rajnoha
75f9b0c25a
tools: vgmknodes: wait for udev first with --refresh, then check /dev 2024-08-14 13:07:25 +02:00
Peter Rajnoha
bec1860531
man: vgmknodes: add note about udev and --refresh 2024-08-14 11:51:34 +02:00
Peter Rajnoha
012854b3c2
gitignore: update
The .cache and compile_commands.json is used by popular source crawling and
indexing clang tools which in turn may be integrated with source code editors.

We may reuse the .cache directory for for other caches and temporary
files.

The /doc/.ikiwiki and /public are related to the ikiwiki.
2024-08-13 11:17:57 +02:00
Zdenek Kabelac
90a845a708 make: generate 2024-08-09 16:34:22 +02:00
Zdenek Kabelac
9036862357 Revert "tests: use put_time"
This reverts commit b4af2571dbee9dab5717bb166ed63df5ae63974b.
std::put_time is a relatively new feature so breaks builds on older
systems.
2024-08-09 15:37:59 +02:00
Zdenek Kabelac
2dc6c3d236 tests: add some udev waits
Avoid possible udev race - since dmsetup create is
not using the same cookie logic as lvm2 commands,
try to avoid racing on some systems with udev scanning.
2024-08-09 15:10:24 +02:00
Zdenek Kabelac
b4af2571db tests: use put_time 2024-08-09 15:10:24 +02:00
Zdenek Kabelac
a06a49b549 tests: search for delimiter in bounded buffer 2024-08-09 15:10:24 +02:00
Zdenek Kabelac
aa75e1f0bf cov: annotate known case 2024-08-09 15:10:24 +02:00
Zdenek Kabelac
e150931fc4 cov: validate list emptiness
Emit internal error for empty list.
2024-08-09 15:10:18 +02:00
Zdenek Kabelac
d1c6da2f66 cov: validate altdev list is not empty 2024-08-09 15:10:18 +02:00
Zdenek Kabelac
22672be97d cov: check for dev_iter_create result
dev_iter_create() may fail in malloc so check
for its error code.
2024-08-09 15:10:18 +02:00
Zdenek Kabelac
76936f2832 cov: drop unused header inclusion 2024-08-09 13:20:44 +02:00
Zdenek Kabelac
426c3c7b88 cov: avoid expression overflow
Use 64bit math to multiply extent_size.
2024-08-09 13:20:44 +02:00
David Teigland
78d14a805c integrity: add --integritysettings for tuning
The option can be used in multiple ways (like --cachesettings):

--integritysettings key=val
--integritysettings 'key1=val1 key2=val2'
--integritysettings key1=val1 --integritysettings key2=val2

Use with lvcreate or lvconvert when integrity is first enabled
to configure:
journal_sectors
journal_watermark
commit_time
bitmap_flush_interval
allow_discards

Use with lvchange to configure (only while inactive):
journal_watermark
commit_time
bitmap_flush_interval
allow_discards

lvchange --integritysettings "" clears any previously configured
settings, so dm-integrity will use its own defaults.

lvs -a -o integritysettings displays configured settings.
2024-08-07 17:40:34 -05:00
David Teigland
07576f7e51 devices: fix dev_dm_uuid
If a non-dm device is passed, the dm code doesn't fail and returns
some dm uuid.
2024-08-01 11:32:56 -05:00
Peter Rajnoha
ae8d5113f4
WHATS_NEW: update 2024-07-30 10:32:25 +02:00
Peter Rajnoha
7fdba39b3f tests: add tests for autoswitching to JSON format for log messages 2024-07-24 09:50:26 +00:00
Peter Rajnoha
0e8c429e30 make: generate 2024-07-24 09:50:26 +00:00
Peter Rajnoha
14dbf6ca7b reporter: simplify checking output format setting in report_format_init 2024-07-24 09:50:26 +00:00
Peter Rajnoha
3eecdcbd64 config_settings: fix typo 2024-07-24 09:50:26 +00:00
Peter Rajnoha
8281f7c111 config: use default log/command_log_report=1 for json/json_std output format
log/command_log_report config setting defaults to 1 now if json or json_std
output format is used (either by setting report/output_format config
setting or using --reportformat cmd line arg).

This means that if we use json/json_std output format, the command log
messages are then part of the json output too, not interleaved as
unstructured text mixed with the json output.

If log/command_log_report is set explicitly in the config, then we still
respect that, no matter what output format is used currently. In this
case, users can still separate and redirect the output by using
LVM_OUT_FD, LVM_ERR_FD and LVM_REPORT_FD so that the different types
do not interleave with the json/json_std output.
2024-07-24 09:50:26 +00:00
Heinz Mauelshagen
be229b0cd1 WHATS_NEW 2024-07-19 13:28:30 +02:00
Heinz Mauelshagen
557b2850ce lv_manip: avoid unreleased memory pool(s) message on RAID extend
In case of different PV sizes in a VG, the lvm2 allocator falls short
to define extended segments resiliently asked for 100%FREE RaidLV extension
and a RAID distinct allocation check fails.  Fix is to release a memory pool
on the resulting error path.

Until the lvm2 allocator gets enhanced (WIP) to do such complex (and other)
allocations proper, a workaround is to extend a RaidLV to any free space on
its already allocated PVs by defining those PVs on the lvextend command line
then iteratively run further such lvextend commands to extend it to its
final intended size.  Mind, this may be a non-trivial extension interation.
2024-07-18 14:36:47 +02:00
Marian Csontos
c288ddd6c8 pages: Update release note tag and timestamp 2024-07-12 12:50:20 +02:00
Marian Csontos
60fbbd5f5f post-release 2024-07-12 12:42:39 +02:00
499 changed files with 12323 additions and 6108 deletions

6
.gitignore vendored
View File

@ -45,6 +45,12 @@ make.tmpl
coverity/coverity_model.xml
/.cache/
/compile_commands.json
/doc/.ikiwiki
/public
/libdm/.symver_check
daemons/clvmd

View File

@ -172,7 +172,7 @@ help:
@echo " lcov-dated Generate lcov with timedate suffix."
@echo " lcov-reset Reset lcov counters"
@echo " man Build man pages."
@echo " print-VARIABLE Resolve make variable."
@echo " print-VARIABLE Resolve make variable."
@echo " rpm Build rpm."
@echo " run-unit-test Run unit tests."
@echo " tags Generate c/etags."
@ -194,7 +194,8 @@ ifneq ("$(GENHTML)", "")
lcov:
$(RM) -rf $(LCOV_REPORTS_DIR)
$(MKDIR_P) $(LCOV_REPORTS_DIR)
$(LCOV) --capture --directory $(top_builddir) --ignore-errors source \
-find . -name '*.gc[dn][ao]' ! -newer make.tmpl -delete
-$(LCOV) --capture --directory $(top_builddir) --ignore-errors source,negative,gcov \
--output-file $(LCOV_REPORTS_DIR)/out.info
-test ! -s $(LCOV_REPORTS_DIR)/out.info || \
$(GENHTML) -o $(LCOV_REPORTS_DIR) --ignore-errors source \

View File

@ -1 +1 @@
2.03.25(2) (2024-07-12)
2.03.32(2)-git (2025-02-27)

View File

@ -1 +1 @@
1.02.199 (2024-07-12)
1.02.206-git (2025-02-27)

246
WHATS_NEW
View File

@ -1,3 +1,92 @@
Version 2.03.32 -
==================
Lvconvert vdopool conversion propperly validates acceptable LVs.
Accept thin pool data LV as cachable LV.
Allow using zram block devices (likely for testing).
Fix lvresize when resizing COW snapshots already covering origin.
Fix lvmdbusd read of executed lvm commands output.
Fix construction of DM UUID for cachevol _cdata and _cmeta devices.
Version 2.03.31 - 27th February 2025
====================================
Reduce 'mandoc -T lint' reported issues for man pages.
Restore support for LVM_SUPPRESS_FD_WARNINGS (2.03.24).
Fix uncache and split cache restoring original state of volume.
Extend use of lockopt skip to more scenarios.
Enhance error path resolving in polling code.
Disallow shared activation of LV with CoW snapshot.
Fix lvmlockd use in lvremove of CoW snapshot, VDO pool, and uncache.
Improve mirror split with opened temporary volumes.
Improve pvmove finish with opened temporary volumes.
Fix backup limit for devices file, handle over 10,000 files.
Ignore reported optimal_io_size not divisible by 4096.
Fix busy-loop in config reading when read returned 0.
Fix DM cache preserving logic (2.03.28).
Improve use of lvmlockd for usecases involving thin volumes and pools.
Version 2.03.30 - 14th January 2025
===================================
Lvresize reports origin vdo volume cannot be resized.
Support setting reserved_memory|stack of --config cmdline.
Fix support for disabling memory locking (2.03.27).
Do not extend an LV if FS resize unsupported and '--fs resize' used.
Prevent leftover temporary device when converting in use volume to a pool.
lvconvert detects early volume in use when converting it to a pool.
Handle NVMe with quirk changed WWID not matching WWID in devices file.
Version 2.03.29 - 09th December 2024
====================================
Configure --enable/disable-sd-notify to control lvmlockd build with sd-notify.
Allow test mode when lvmlockd is built without dlm support.
Add a note about RAID + integrity synchronization to lvmraid(7) man page.
Add a function for running lvconvert --repair on RAID LVs to lvmdbusd.
Improve option section of man pages for listing commands ({pv,lv,vg}{s,display}).
Fix renaming of raid sub LVs when converting a volume to raid (2.03.28).
Fix segfault/VG write error for raid LV lvextend -i|--stripes -I|--stripesize.
Revert ignore -i|--stripes, -I|--stripesize for lvextend on raid0 LV (2.03.27).
Version 2.03.28 - 04th November 2024
====================================
Use radix_tree to lookup for UUID within committed metadata.
Use radix_tree to lookup LV list entry within VG struct.
Introduce setting config/validate_metadata = full | none.
Restore fs resize call for lvresize -r on the same size LV (2.03.17).
Correct off-by-one devicesfile backup counting.
Replace use of dm_hash with radix_tree for lv names and uuids.
Refactor vg_validate with uniq_insert and better use of CPU caches.
Add radix_tree_uniq_insert.
Update DM cache when taking next VG lock instead of dropping it.
Generate json string id only for json reporting.
For vgsummary use new API call dm_config_parse_only_section().
Use radix_tree for PV names mapping.
Split check_lv_segment into separate _in/complete_vg variant.
Use find_lv instead of find_lv_in_vg when possible.
Do a mirror fixup only when mirrors with logs are imported.
Add faster crc32 calculation from zlib code for x86_64.
Fall back to direct zeroing if BLKZEROOUT fails during new LV initialization.
Version 2.03.27 - 02nd October 2024
===================================
Fix swap device size detection using blkid for lvresize/lvreduce/lvextend.
Detect GPT partition table and pass partition filter if no partitions defined.
Add global/sanlock_align_size option to configure sanlock lease size.
Disable mem locking when activation/reserved_stack or reserved_memory is 0.
Fix locking issues in lvmlockd leaving thin pool locked.
Deprecate vdo settings vdo_write_policy and vdo_write_policy.
Lots of typo fixes across lvm2 code base (codespell).
Corrected integrity parameter interleave_sectors for DM table line.
Ignore -i|--stripes, -I|--stripesize for lvextend on raid0 LV, like raid10.
Do not accept duplicate device names for pvcreate.
Version 2.03.26 - 23rd August 2024
==================================
Fix internal error reported by pvmove on a VG with single PV.
Also accept --mknodes --refresh for vgscan.
Fix vgmknodes --refresh to wait for udev before checking /dev content.
Use log/report_command_log=1 config setting by default for JSON output format.
Fix unreleased memory pools on RAID lvextend.
Add --integritysettings option to manipulate dm-integrity settings.
Version 2.03.25 - 12nd July 2024
================================
Utilize more radix_tree instead of dm_hash and btree.
@ -13,12 +102,12 @@ Version 2.03.24 - 16th May 2024
Lvconvert supports VDO options for thin-pool with vdo conversion.
Improve placement to .data.rel.ro and .rodata sections.
Fix support for -y and -W when creating thinpool with vdo.
Bettter support for runtime valgrind detection.
Better support for runtime valgrind detection.
Allow command interruption when communicating with dmeventd.
Fix resize of VDO volume used for thin pool data volume.
Use -Wl,-z,now and -Wl,--as-needed for compilation by default.
Require 3.7 as minimal version for sanlock.
Share code for closing opened desriptors on program startup.
Share code for closing opened descriptors on program startup.
Fix memleak in lvmcache.
Add configure --with-default-event-activation=ON setting.
Fix return value from reporter function when hitting internal error.
@ -62,7 +151,7 @@ Version 2.03.23 - 21st November 2023
Support PV lists with thin lvconvert.
Fix support for lvm_import_vdo with SCSI VDO volumes.
Fix locking issue leading to hanging concurrent vgchange --refresh.
Recognize lvm.conf report/headings=2 for full column names in report headings.
Recognise lvm.conf report/headings=2 for full column names in report headings.
Add --headings none|abbrev|full cmd line option to set report headings type.
Fix conversion to thin pool using lvmlockd.
Fix conversion from thick into thin volume using lvmlockd.
@ -132,6 +221,7 @@ Version 2.03.17 - 10th November 2022
Switch to use mallinfo2 and use it only with glibc.
Error out in lvm shell if using a cmd argument not supported in the shell.
Fix lvm shell's lastlog command to report previous pre-command failures.
Keep libaio locked in memory in critical section.
Extend VDO and VDOPOOL without flushing and locking fs.
Add --valuesonly option to lvmconfig to print only values without keys.
Updates configure with recent autoconf tooling.
@ -151,7 +241,7 @@ Version 2.03.16 - 18th May 2022
--deldev.
Display writecache block size with lvs -o writecache_block_size.
Improve cachesettings description in man lvmcache.
Fix lossing of delete message on thin-pool extension.
Fix losing of delete message on thin-pool extension.
Version 2.03.15 - 07th February 2022
====================================
@ -238,7 +328,7 @@ Version 2.03.12 - 07th May 2021
Fix problem with unbound variable usage within fsadm.
Fix IMSM MD RAID detection on 4k devices.
Check for presence of VDO target before starting any conversion.
Support metatadata profiles with volume VDO pool conversions.
Support metadata profiles with volume VDO pool conversions.
Support -Zn for conversion of already formatted VDO pools.
Avoid removing LVs on error path of lvconvert during creation volumes.
Fix crashing lvdisplay when thin volume was waiting for merge.
@ -269,7 +359,7 @@ Version 2.03.11 - 08th January 2021
Enhance error handling for fsadm and handle correct fsck result.
Dmeventd lvm plugin ignores higher reserved_stack lvm.conf values.
Support using BLKZEROOUT for clearing devices.
Support interruption when wipping LVs.
Support interruption when wiping LVs.
Support interruption for bcache waiting.
Fix bcache when device has too many failing writes.
Fix bcache waiting for IO completion with failing disks.
@ -396,7 +486,7 @@ Version 2.03.03 - 07th June 2019
Ignore foreign and shared PVs for pvscan online files.
Add config setting to control fields in debug file and verbose output.
Add command[pid] and timestamp to debug file and verbose output.
Fix missing growth of _pmsmare volume when extending _tmeta volume.
Fix missing growth of _pmspare volume when extending _tmeta volume.
Automatically grow thin metadata, when thin data gets too big.
Add synchronization with udev before removing cached devices.
Add support for caching VDO LVs and VDOPOOL LVs.
@ -409,14 +499,14 @@ Version 2.03.03 - 07th June 2019
Change scan_lvs default to 0 so LVs are not scanned for PVs.
Thin-pool selects power-of-2 chunk size by default.
Cache selects power-of-2 chunk size by default.
Support reszing for VDOPoolLV and VDOLV.
Support resizing for VDOPoolLV and VDOLV.
Improve -lXXX%VG modifier which improves cache segment estimation.
Ensure migration_threshold for cache is at least 8 chunks.
Restore missing man info lvcreate --zero for thin-pools.
Drop misleadning comment for metadata minimum_io_size for VDO segment.
Drop misleading comment for metadata minimum_io_size for VDO segment.
Add device hints to reduce scanning.
Introduce LVM_SUPPRESS_SYSLOG to suppress syslog usage by generator.
Fix generator quering lvmconfig unpresent config option.
Fix generator querying lvmconfig unpresent config option.
Fix memleak on bcache error path code.
Fix missing unlock on lvm2 dmeventd plugin error path initialization.
Improve Makefile dependency tracking.
@ -478,7 +568,7 @@ Version 2.02.178-rc1 - 24th May 2018
--with-cache switch for ./configure has been removed.
Include new unit-test framework and unit tests.
Extend validation of region_size for mirror segment.
Reload whole device stack when reinitilizing mirror log.
Reload whole device stack when reinitializing mirror log.
Mirrors without monitoring are WARNING and not blocking on error.
Detect too big region_size with clustered mirrors.
Fix evaluation of maximal region size for mirror log.
@ -523,7 +613,7 @@ Version 2.02.178-rc1 - 24th May 2018
Restore pvmove support for wide-clustered active volumes (2.02.177).
Avoid non-exclusive activation of exclusive segment types.
Fix trimming sibling PVs when doing a pvmove of raid subLVs.
Preserve exclusive activation during thin snaphost merge.
Preserve exclusive activation during thin snapshot merge.
Avoid exceeding array bounds in allocation tag processing.
Add --lockopt to common options and add option to skip selected locks.
@ -539,7 +629,7 @@ Version 2.02.177 - 18th December 2017
Fix lvmlockd to use pool lock when accessing _tmeta volume.
Report expected sanlock_convert errors only when retries fail.
Avoid blocking in sanlock_convert on SH to EX lock conversion.
Deactivate missing raid LV legs (_rimage_X-missing_Y_Z) on decativation.
Deactivate missing raid LV legs (_rimage_X-missing_Y_Z) on deactivation.
Skip read-modify-write when entire block is replaced.
Categorise I/O with reason annotations in debug messages.
Allow extending of raid LVs created with --nosync after a failed repair.
@ -561,7 +651,7 @@ Version 2.02.177 - 18th December 2017
Check raid reshape flags in vg_validate().
Add support for pvmove of cache and snapshot origins.
Avoid using precommitted metadata for suspending pvmove tree.
Ehnance pvmove locking.
Enhance pvmove locking.
Deactivate activated LVs on error path when pvmove activation fails.
Add "io" to log/debug_classes for logging low-level I/O.
Eliminate redundant nested VG metadata in VG struct.
@ -651,13 +741,13 @@ Version 2.02.173 - 20th July 2017
Version 2.02.172 - 28th June 2017
=================================
Add missing NULL to argv array when spliting cmdline arguments.
Add missing NULL to argv array when splitting cmdline arguments.
Add display_percent helper function for printing percent values.
lvconvert --repair handles failing raid legs (present but marked 'D'ead).
Do not lvdisplay --maps unset settings of cache pool.
Fix lvdisplay --maps for cache pool without policy settings.
Support aborting of flushing cache LV.
Reenable conversion of data and metadata thin-pool volumes to raid.
Re-enable conversion of data and metadata thin-pool volumes to raid.
Improve raid status reporting with lvs.
No longer necessary to '--force' a repair for RAID1.
Linear to RAID1 upconverts now use "recover" sync action, not "resync".
@ -725,7 +815,7 @@ Version 2.02.169 - 28th March 2017
Support cache segment with configurable metadata format.
Add allocation/cache_metadata_format profilable settings.
Use function cache_set_params() for both lvcreate and lvconvert.
Skip rounding on cache chunk size boudary when create cache LV.
Skip rounding on cache chunk size boundary when create cache LV.
Improve cache_set_params support for chunk_size selection.
Fix metadata profile allocation/cache_[mode|policy] setting.
Fix missing support for using allocation/cache_pool_chunk_size setting.
@ -775,8 +865,8 @@ Version 2.02.169 - 28th March 2017
Extend metadata validation of external origin LV use count.
Fix dm table when the last user of active external origin is removed.
Improve reported lvs status for active external origin volume.
Fix table load for splitted RAID LV and require explicit activation.
Always active splitted RAID LV exclusively locally.
Fix table load for split RAID LV and require explicit activation.
Always active split RAID LV exclusively locally.
Do not use LV RAID status bit for segment status.
Check segtype directly instead of checking RAID in segment status.
Reusing exiting code for raid image removal.
@ -839,7 +929,7 @@ Version 2.02.166 - 26th September 2016
Use --alloc normal for mirror logs even if the mimages were stricter.
Use O_DIRECT to gather metadata in lvmdump.
Ignore creation_time when checking for matching metadata for lvmetad.
Fix possible NULL pointer derefence when checking for monitoring.
Fix possible NULL pointer dereference when checking for monitoring.
Add lvmreport(7) man page.
Don't install lvmraid(7) man page when raid excluded. (2.02.165)
Report 0% as dirty (copy%) for cache without any used block.
@ -879,7 +969,7 @@ Version 2.02.164 - 15th August 2016
Version 2.02.163 - 10th August 2016
===================================
Add profile for lvmdbusd which uses lvm shell json report output.
Restrict in-command modification of some parms in lvm shell.
Restrict in-command modification of some params in lvm shell.
Apply LVM_COMMAND_PROFILE early for lvm shell.
Refactor reporting so lvm shell log report collects whole of cmd execution.
Support LVM_*_FD envvars to redirect output to file descriptors.
@ -1032,11 +1122,11 @@ Version 2.02.152 - 30th April 2016
==================================
Use any inherited tags when wiping metadata sub LVs to ensure activation.
Add str_list_wipe.
Improve support for interrupting procesing of volumes during lvchange.
Improve support for interrupting processing of volumes during lvchange.
Use failed command return code when lvchanging read-only volume.
Show creation transaction_id and zeroing state of pool with thin volume.
Stop checking for dm_cache_mq policy with cache target 1.9 (alias to smq).
Check first /sys/module/dm_* dir existance before using modprobe.
Check first /sys/module/dm_* dir existence before using modprobe.
Remove mpath from 10-dm.rules, superseded by 11-dm-mpath.rules (mpath>=0.6.0).
Version 2.02.151 - 23rd April 2016
@ -1061,7 +1151,7 @@ Version 2.02.150 - 9th April 2016
=================================
Avoid using flushing dm status ioctl when checking for usable DM device.
Check for devices without LVM- uuid prefix only with kernels < 3.X.
Reuse %FREE size aproximation with lvcreate -l%PVS thin-pool.
Reuse %FREE size approximation with lvcreate -l%PVS thin-pool.
Allow the lvmdump directory to exist already provided it is empty.
Show lvconverted percentage with 2 decimal digits.
Fix regression in suspend when repairing --type mirror (2.02.133).
@ -1138,7 +1228,7 @@ Version 2.02.143 - 21st February 2016
Fix error path when sending thin-pool message fails in update_pool_lv().
Support reporting CheckNeeded and Fail state for thin-pool and thin LV.
For failing thin-pool and thin volume correctly report percentage as INVALID.
Report -1, not 'unkown' for lv_{snapshot_invalid,merge_failed} with --binary.
Report -1, not 'unknown' for lv_{snapshot_invalid,merge_failed} with --binary.
Add configure --enable-dbus-service for an LVM D-Bus service.
Replace configure --enable-python_bindings with python2 and python3 versions.
If PV belongs to some VG and metadata missing, skip it if system ID is used.
@ -1167,7 +1257,7 @@ Version 2.02.141 - 25th January 2016
Restore support for command breaking in process_each_lv_in_vg() (2.02.118).
Use correct mempool when process_each_lv_in_vg() (2.02.118).
Fix lvm.8 man to show again prohibited suffixes.
Fix configure to set proper use_blkid_wiping if autodetected as disabled.
Fix configure to set proper use_blkid_wiping if autodetection as disabled.
Initialise udev in clvmd for use in device scanning. (2.02.116)
Add seg_le_ranges report field for common format when displaying seg devices.
Honour report/list_item_separator for seg_metadata_le_ranges report field.
@ -1317,7 +1407,7 @@ Version 2.02.129 - 26th August 2015
Fix shared library generation to stop exporting internal functions.(2.02.120)
Accept --cachemode with lvconvert.
Fix and improve reporting properties of cache-pool.
Enable usage of --cachepolicy and --cachesetting with lvconvert.
Enable usage of --cachepolicy and --cachesettings with lvconvert.
Don't allow to reduce size of thin-pool metadata.
Fix debug buffer overflows in cmirrord logging.
Add --foreground and --help to cmirrord.
@ -1474,7 +1564,7 @@ Version 2.02.119 - 2nd May 2015
Add --enable-halvm and --disable-halvm options to lvmconf script.
Add --services, --mirrorservice and --startstopservices option to lvmconf.
Use proper default value of global/use_lvmetad when processing lvmconf script.
Respect allocation/cling_tag_list during intial contiguous allocation.
Respect allocation/cling_tag_list during initial contiguous allocation.
Add A_PARTITION_BY_TAGS set when allocated areas should not share tags.
Make changes persist with python addTag/removeTag.
Set correct vgid when updating cache when writing PV metadata.
@ -1552,7 +1642,7 @@ Version 2.02.116 - 30th January 2015
Scan pools in for_each_sub_lv() and add for_each_sub_lv_except_pools().
Fix lvm2app lvm_lv_get_property return value for fields with info/status ioctl.
Fix lvm2app regression in lvm_lv_get_attr causing unknown values (2.02.115).
Set default cache_mode to writehrough when missing in metadata.
Set default cache_mode to writethrough when missing in metadata.
Preserve chunk size with repair and metadata swap of a thin pool.
Fix raid --splitmirror 1 functionality (2.02.112).
Fix tree preload to handle splitting raid images.
@ -1618,13 +1708,13 @@ Version 2.02.112 - 11th November 2014
Properly report error when taking snapshot of any cache type LV.
Add basic thread debugging messages to dmeventd.
Include threads being shutdown in dmeventd device registration responses.
Inital support for external users of thin pools based on transaction_id.
Initial support for external users of thin pools based on transaction_id.
Report some basic percentage info for cache pools.
Introduce size_mb_arg_with_percent() for advanced size arg reading.
Add extra support for '.' as decimal point in size args.
Add configure parameters for default segment type choices.
Add global/sparse_segtype_default setting to use thin for --type sparse.
Update and correct lvcreate and lvcovert man pages.
Update and correct lvcreate and lvconvert man pages.
Mark pools and snapshots as unzeroable volumes.
Check for zeroing of volume after segment type is fully detected.
Better support for persistent major and minor options with lvcreate.
@ -1677,7 +1767,7 @@ Version 2.02.112 - 11th November 2014
Support DEBUG_MEMLOCK to trap unsupported mmap usage.
Enable cache segment type by default.
Ensure only supported volume types are used with cache segments.
Fix inablility to specify cachemode when 'lvconvert'ing to cache-pool.
Fix inability to specify cachemode when 'lvconvert'ing to cache-pool.
Grab cluster lock for active LVs when setting clustered attribute.
Use va_copy to properly pass va_list through functions.
Add function to detect rotational devices.
@ -1745,7 +1835,7 @@ Version 2.02.108 - 23rd July 2014
Enhance lvconvert thin, thinpool, cache and cachepool command line support.
Display 'C' only for cache and cache-pool target types in lvs.
Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
Return proper error codes for some failing lvconvert functions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
Support lvdisplay --maps for raid.
Add --activationmode degraded to activate degraded raid volumes by default.
@ -1764,7 +1854,7 @@ Version 2.02.108 - 23rd July 2014
Support lvremove -ff to remove thin volumes from broken thin pools.
Require --yes to skip raid repair prompt.
Change makefile %.d generation to handle filename changes without make clean.
Fix use of buildir in make pofile.
Fix use of builddir in make pofile.
Enhance private volumes UUIDs with suffixed for easier detection.
Do not use reserved _[tc]meta volumes for temporary LVs.
Leave backup pool metadata with _meta%d suffix instead of reserved _tmeta%d.
@ -1869,7 +1959,7 @@ Version 2.02.106 - 10th April 2014
Include 'lvm dumpconfig --type missing' and '--type diff' output to lvmdump.
Return failure when specifying negative size for pvresize.
Fix memory corruption in cmd context refresh if clvmd leaks opened device.
Reinitialise lvmcache properly on fork to fix premature polldaemon exit.
Reinitialize lvmcache properly on fork to fix premature polldaemon exit.
Add 'lvm dumpconfig --type diff' to show differences from defaults.
Fix swap signature detection for devices smaller then 2MB.
Use dm_malloc function in clvmd.c.
@ -1896,7 +1986,7 @@ Version 2.02.106 - 10th April 2014
Don't print an error and accept empty value for global/thin_disabled_features.
Update API for internal function build_dm_uuid().
Do not try to check empty pool with scheduled messages.
Fix return value in pool_has_message() when quering for any message.
Fix return value in pool_has_message() when querying for any message.
Cleanup all client resources on clvmd exit.
Use dm_zalloc to clear members of clvmd client struct.
Use BLKID_CFLAGS when compiling with blkid support.
@ -1938,7 +2028,7 @@ Version 2.02.106 - 10th April 2014
Fix test when checking target version for available thin features.
Detect thin feature external_origin_extend and limit extend when missing.
Rename internal pool_can_resize_metadata() to thin_pool_feature_supported().
Issue error if libbblkid detects signature and fails to return offset/length.
Issue error if libblkid detects signature and fails to return offset/length.
Update autoconf config.guess/sub to 2014-01-01.
Online thin pool metadata resize requires 1.10 kernel thin pool target.
@ -2011,7 +2101,7 @@ Version 2.02.104 - 13th November 2013
=====================================
Workaround VG refresh race during autoactivation by retrying the refresh.
Handle failures in temporary mirror used when adding images to mirrors.
Fix and improve logic for implicitely exclusive activations.
Fix and improve logic for implicitly exclusive activations.
Return success when LV cannot be activated because of volume_list filter.
Return proper error state for remote exclusive activation.
Fix missing lvmetad scan for PVs found on MD partitions.
@ -2174,11 +2264,11 @@ Version 2.02.99 - 24th July 2013
Add support for persistent flagging of LVs to be skipped during activation.
Add --type profilable to lvm dumpconfig to show profilable config settings.
Add --mergedconfig to lvm dumpconfig for merged --config/--profile/lvm.conf.
Relase memory and unblock signals in lock_vol error path.
Release memory and unblock signals in lock_vol error path.
Define LVM2_* command errors in lvm2cmd.h and use in dmeventd plugins.
Move errors.h to tools dir.
Add man page entries for profile configuration and related options.
Improve error loging when user tries to interrupt commands.
Improve error logging when user tries to interrupt commands.
Rename _swap_lv to _swap_lv_identifiers and move to allow an additional user.
Rename snapshot segment returning methods from find_*_cow to find_*_snapshot.
liblvm/python API: Additions: PV create/removal/resize/listing
@ -2379,7 +2469,7 @@ Version 2.02.98 - 15th October 2012
Do not start dmeventd for lvchange --resync when monitoring is off.
Remove pvscan --cache from lvm2-lvmetad init script.
Remove ExecStartPost with pvscan --cache from lvm2-lvmetad.service.
Report invalid percentage for property snap_percent of non-snaphot LVs.
Report invalid percentage for property snap_percent of non-snapshot LVs.
Disallow conversion of thin LVs to mirrors.
Fix lvm2api data_percent reporting for thin volumes.
Do not allow RAID LVs in a clustered volume group.
@ -2429,7 +2519,7 @@ Version 2.02.98 - 15th October 2012
Version 2.02.97 - 7th August 2012
=================================
Improve documention of allocation policies in lvm.8.
Improve documentation of allocation policies in lvm.8.
Increase limit for major:minor to 4095:1048575 when using -My option.
Add make install_systemd_generators.
Add generator for lvm2 activation systemd units.
@ -2513,7 +2603,7 @@ Version 2.02.96 - 8th June 2012
Check for buffer overwrite in get_cluster_type() in clvmd.
Fix global/detect_internal_vg_cache_corruption config check.
Update lcov Makefile target to support all dmeventd plugins.
Fix initializiation of thin monitoring. (2.02.92)
Fix initialization of thin monitoring. (2.02.92)
Cope with improperly formatted device numbers in /proc/devices. (2.02.91)
Exit if LISTEN_PID environment variable incorrect in lvmetad systemd handover.
Use pvscan --cache instead of vgscan in lvmetad scripts.
@ -2526,7 +2616,7 @@ Version 2.02.96 - 8th June 2012
Add --with-thin-check configure option for path to thin_check.
Fix error message when pvmove LV activation fails with name already in use.
Better structure layout for device_info in dev_subsystem_name().
Change message severity for creation of VG over uninitialised devices.
Change message severity for creation of VG over uninitialized devices.
Fix error path for failed toolcontext creation.
Detect lvm binary path in lvmetad udev rules.
Don't unlink socket on lvmetad shutdown if instantiated from systemd.
@ -2561,7 +2651,7 @@ Version 2.02.94 - 3rd March 2012
Add some close() and dev_close() error path backtraces.
Set stdin/stdout/stderr to /dev/null for polldaemon.
Limit the max size of processed clvmd message to ~8KB.
Do not send uninitialised bytes in cluster error reply messages.
Do not send uninitialized bytes in cluster error reply messages.
Use unsigned type for bitmask instead of enum type for lvm properties.
Add missing cleanup of excl_uuid hash on some exit paths of clvmd.
Check for existence of vg_name in _format1/_pool_vg_read().
@ -2634,7 +2724,7 @@ Version 2.02.91 - 12th February 2012
Version 2.02.90 - 1st February 2012
===================================
sync_local_dev_names before (re)activating mirror log for initialisation.
sync_local_dev_names before (re)activating mirror log for initialization.
Disable partial activation for thin LVs and LVs with all missing segments.
Do not print warning for pv_min_size between 512KB and 2MB.
Clean up systemd unit ordering and requirements.
@ -2653,7 +2743,7 @@ Version 2.02.89 - 26th January 2012
Add data_percent and metadata_percent for thin pools to lvs -v.
Add data_lv & metadata_lv fields to lvs for thin pools.
Add data_percent & pool_lv fields to lvs for thin volumes.
Rename origin_only parm to use_layer for lv_info and use with thin LVs.
Rename origin_only param to use_layer for lv_info and use with thin LVs.
Add lv_thin_pool_transaction_id to read the transaction_id value.
Use {suspend,resume}_origin_only when up-converting RAID, as mirrors do.
Always add RAID metadata LVs to deptree (even when origin_only is set).
@ -2683,7 +2773,7 @@ Version 2.02.89 - 26th January 2012
Add _dev_init to initialize common struct device members.
Always zalloc struct device during initialization.
Fix missing thread list manipulation protection in dmeventd.
Do not derefence lv pointer in _percent_run() function before NULL check.
Do not dereference lv pointer in _percent_run() function before NULL check.
Allow empty strings for description and creation_host config fields.
Issue deprecation warning when removing last lvm1-format snapshot.
Reinstate support for snapshot removal with lvm1 format. (2.02.86)
@ -2754,11 +2844,11 @@ Version 2.02.89 - 26th January 2012
Change vg_revert to void and remove superfluous calls after failed vg_commit.
Use execvp for CLVMD restart to preserve environment settings.
Restart CLVMD with same cluster manager.
Fix log_error() usage in raid and unknown segtype initialisation.
Fix log_error() usage in raid and unknown segtype initialization.
Improve testing Makefile.
Fix install_ocf make target when srcdir != builddir. (2.02.80)
Support env vars LVM_CLVMD_BINARY and LVM_BINARY in clvmd.
Fix restart of clvmd (preserve exlusive locks). (2.02.64)
Fix restart of clvmd (preserve exclusive locks). (2.02.64)
Add 'Volume Type' lv_attr characters for RAID and RAID_IMAGE.
Add activation/retry_deactivation to lvm.conf to retry deactivation of an LV.
Replace open_count check with holders/mounted_fs check on lvremove path.
@ -2824,13 +2914,13 @@ Version 2.02.87 - 12th August 2011
Cache and share generated VG structs.
Fix possible format instance memory leaks and premature releases in _vg_read.
Suppress locking error messages in monitoring init scripts.
If pipe in clvmd fails return busy instead of using uninitialised descriptors.
If pipe in clvmd fails return busy instead of using uninitialized descriptors.
Add ability to reduce the number of mirrors in raid1 arrays to lvconvert.
Add dmeventd plugin for raid.
Replace free_vg with release_vg and move it to vg.c.
Remove INCONSISTENT_VG flag from the code.
Remove lock from cache in _lock_vol even if unlock fails.
Initialise clvmd locks before lvm context to avoid open descriptor leaks.
Initialize clvmd locks before lvm context to avoid open descriptor leaks.
Remove obsolete gulm clvmd cluster locking support.
Suppress low-level locking errors and warnings while using --sysinit.
Remove unused inconsistent_seqno variable in _vg_read().
@ -2903,7 +2993,7 @@ Version 2.02.85 - 29th April 2011
Issue discards on lvremove and lvreduce etc. if enabled and supported.
Add seg_pe_ranges and devices fields to liblvm.
Fix incorrect tests for dm_snprintf() failure.
Fix some unmatching sign comparation gcc warnings in the code.
Fix some unmatching sign comparison gcc warnings in the code.
Support lv_extend() on empty LVs.
Avoid regenerating cache content when exported VG buffer is unchanged.
Extend the set of memory regions that are not locked to memory.
@ -2929,7 +3019,7 @@ Version 2.02.85 - 29th April 2011
Use only vg_set_fid and new pv_set_fid fn to assign the format instance.
Make create_text_context fn static and move it inside create_instance fn.
Add mem and ref_count fields to struct format_instance for own mempool use.
Use new alloc_fid fn for common format instance initialisation.
Use new alloc_fid fn for common format instance initialization.
Optimise _get_token() and _eat_space().
Add _lv_postorder_vg() to improve efficiency for all LVs in VG.
Add gdbinit script for debugging.
@ -2938,10 +3028,10 @@ Version 2.02.85 - 29th April 2011
Avoid possible endless loop in _free_vginfo when 4 or more VGs have same name.
Use empty string instead of /dev// for LV path when there's no VG.
Don't allocate unused VG mempool in _pvsegs_sub_single.
Do not send uninitialised bytes in local clvmd messages.
Do not send uninitialized bytes in local clvmd messages.
Support --help option for clvmd and return error for unknown option.
Avoid reading freed memory when printing LV segment type.
Fix syslog initialisation in clvmd to respect lvm.conf setting.
Fix syslog initialization in clvmd to respect lvm.conf setting.
Fix possible overflow in maximum stripe size and physical extent size.
Improve pvremove error message when PV belongs to a VG.
Extend normal policy to allow mirror logs on same PVs as images if necessary.
@ -2955,7 +3045,7 @@ Version 2.02.85 - 29th April 2011
Restructure existing pv_setup and pv_write and add pv_initialise.
Add internal interface to support adding and removing metadata areas.
Allow internal indexing of metadata areas (PV id + mda order).
Generalise internal format_instance infrastrusture for PV and VG use.
Generalise internal format_instance infrastructure for PV and VG use.
Handle decimal digits with --units instead of ignoring them silently.
Fix remaining warnings and compile with -Wpointer-arith.
Fix gcc warnings for unused variables and const casts.
@ -2969,7 +3059,7 @@ Version 2.02.85 - 29th April 2011
Make pv_min_size configurable and increase to 2048KB to exclude floppy drives.
Add find_config_tree_int64 to read 64-bit ints from config.
Ensure resuming exclusive cluster mirror continues to use local mirror target.
Clear temporary postorder LV status flags to allow re-use with same LV struct.
Clear temporary postorder LV status flags to allow reuse with same LV struct.
Remove invalid snapshot umount mesg which floods syslog from dmeventd plugin.
Add extended examples to pvmove man page.
Support LVM_TEST_DEVDIR env var for private /dev during testing.
@ -3024,7 +3114,7 @@ Version 2.02.80 - 10th January 2011
Speed up command processing by caching resolved config tree.
Pass config_tree to renamed function import_vg_from_config_tree().
Detect NULL handle in get_property().
Fix superfluous /usr in ocf_scriptdir instalation path.
Fix superfluous /usr in ocf_scriptdir installation path.
Add --with-ocfdir configurable option.
Add aclocal.m4 (for pkgconfig).
Fix memory leak in persistent filter creation error path.
@ -3056,7 +3146,7 @@ Version 2.02.79 - 20th December 2010
Add copy_percent and snap_percent to liblvm.
Enhance vg_validate to ensure integrity of LV and PV structs referenced.
Enhance vg_validate to check composition of pvmove LVs.
Create /var/run/lvm directory during clvmd initialisation if missing.
Create /var/run/lvm directory during clvmd initialization if missing.
Use new dm_prepare_selinux_context instead of dm_set_selinux_context.
Avoid revalidating the label cache immediately after scanning.
Support scanning for a single VG in independent mdas.
@ -3353,7 +3443,7 @@ Version 2.02.67 - 4th June 2010
Avoid selecting names under /dev/block if there is an alternative.
Update clustered log kernel module name to log-userspace for 2.6.31 onwards.
Add replicators' LVs to dtree for activation.
Supress activation message if there is a missing replicator VG.
Suppress activation message if there is a missing replicator VG.
Fix scripts/relpath.awk to work in mawk
Extend lock_vol to check for missing replicator VGs first.
Update _process_one_vg and process_each_lv_in_vg to populate cmd_vg.
@ -3404,7 +3494,7 @@ Version 2.02.65 - 17th May 2010
Version 2.02.64 - 30th April 2010
=================================
Avoid pointless initialisation when the 'version' command is run directly.
Avoid pointless initialization when the 'version' command is run directly.
Fix memory leak for invalid regex pattern input.
Display invalid regex pattern for filter configuration in case of error.
Remove no-longer-used arg_ptr_value.
@ -3563,7 +3653,7 @@ Version 2.02.60 - 23rd January 2010
Disable memory debugging if dmeventd is configured. (Not thread-safe.)
Fix first log message prefix in syslog for dmeventd plugins.
Fix exported symbols names for dmeventd lvm2 wrapper plugin.
Make failed locking initialisation messages more descriptive.
Make failed locking initialization messages more descriptive.
Version 2.02.59 - 21st January 2010
===================================
@ -3579,7 +3669,7 @@ Version 2.02.59 - 21st January 2010
Fix detection of completed snapshot merge.
Add Red Hat cmirror initscript (unfinished).
Add cmirrord man page (incomplete).
Make cluster log communication structures architecture independant.
Make cluster log communication structures architecture independent.
Fix cluster log in-memory bitmap handling.
Improve snapshot merge metadata import validation.
Improve target type compatibility checking in _percent_run().
@ -3655,7 +3745,7 @@ Version 2.02.57 - 12th January 2010
Impose limit of 8 mirror images to match the in-kernel kcopyd restriction.
Use locking_type 3 (compiled in) for lvmconf --enable-cluster.
Remove list.c and list.h with no-longer-used dm_list macros and functions.
Log failure type and recognise type 'F' (flush) in dmeventd mirror plugin.
Log failure type and recognize type 'F' (flush) in dmeventd mirror plugin.
Extend internal PV/VG/LV/segment status variables from 32-bit to 64-bit.
Version 2.02.56 - 24th November 2009
@ -3693,14 +3783,14 @@ Version 2.02.54 - 26th October 2009
Fix clvmd segfault when refresh_toolcontext fails.
Remember to clear 'global lock held during cache refresh' state after use.
Use udev flags support in LVM and apply various fixes to udev rules.
Delay announcing mirror monitoring to syslog until initialisation succeeded.
Delay announcing mirror monitoring to syslog until initialization succeeded.
Handle metadata with unknown segment types more gracefully.
Set default owner and group to null.
Add dmeventd.static to the build.
Disable realtime support code by default.
Make clvmd return 0 on success rather than 1.
Add --pvmetadatacopies for pvcreate, vgcreate, vgextend, vgconvert.
Add implict pvcreate support to vgcreate and vgextend.
Add implicit pvcreate support to vgcreate and vgextend.
Correct example.conf to indicate that lvm2 not lvm1 is the default format.
Remove an unused stray LVM1_SUPPORT ifdef.
Only include selinux libs in libdevmapper.pc when selinux build enabled.
@ -3880,7 +3970,7 @@ Version 2.02.48 - 30th June 2009
Reinstate partial activation support in clustered mode. (2.02.40)
Allow metadata correction even when PVs are missing.
Use 'lvm lvresize' instead of 'lvresize' in fsadm.
Do not use '-n' realine option in fsadm for busybox compatiblity.
Do not use '-n' realine option in fsadm for busybox compatibility.
Add vg_lock_newname() library function for vgrename, vgsplit and vgcreate.
Round up requested readahead to at least one page and print warning.
Try to repair vg before actual vgremove when force flag provided.
@ -3941,7 +4031,7 @@ Version 2.02.46 - 21st May 2009
Fix first_seg() call for empty segment list.
Add install_lvm2 makefile target to install only the LVM2 components.
Reject missing PVs from allocation in toollib.
Fix PV datalignment for values starting prior to MDA area. (2.02.45)
Fix PV dataalignment for values starting prior to MDA area. (2.02.45)
Add sparse devices: lvcreate -s --virtualoriginsize (hidden zero origin).
Fix minimum width of devices column in reports.
Add lvs origin_size field.
@ -4014,7 +4104,7 @@ Version 2.02.45 - 3rd March 2009
Separate PV label attributes which do not need parse metadata when reporting.
Remove external dependency on the 'cut' command from fsadm.
Fix pvs segfault when pv mda attributes requested for not available PV.
Add fsadm support for reszing ext4 filesysystems.
Add fsadm support for resizing ext4 filesystems.
Move locking_type reading inside init_locking().
Rename get_vgs() to get_vgnames() and clarify related error messages.
Allow clvmd to be built with all cluster managers & select one on cmdline.
@ -4191,7 +4281,7 @@ Version 2.02.37 - 6th June 2008
Refactor some vginfo manipulation code.
Add assertions to trap deprecated P_ and V_ lock usage.
Add missing mutex around clvmd lvmcache_drop_metadata library call.
Fix uninitialised mutex in clvmd if all daemons are not running at startup.
Fix uninitialized mutex in clvmd if all daemons are not running at startup.
Avoid using DLM locks with LCK_CACHE type P_ lock requests.
When asked to drop cached committed VG metadata, invalidate cached PV labels.
Drop metadata cache before writing precommitted metadata instead of after.
@ -4238,7 +4328,7 @@ Version 2.02.34 - 10th April 2008
Mention default --clustered setting in vgcreate man page.
Add config file overrides to clvmd when it reads the active LVs list.
Fix vgreduce to use vg_split_mdas to check sufficient mdas remain.
Add (empty) orphan VGs to lvmcache during initialisation.
Add (empty) orphan VGs to lvmcache during initialization.
Fix orphan VG name used for format_pool.
Create a fid for internal orphan VGs.
Update lvmcache VG lock state for all locking types now.
@ -4256,7 +4346,7 @@ Version 2.02.34 - 10th April 2008
Fix redundant lvresize message if vg doesn't exist.
Fix another allocation bug with clvmd and large node IDs.
Add find_lv_in_lv_list() and find_pv_in_pv_list().
Fix uninitialised variable in clvmd that could cause odd hangs.
Fix uninitialized variable in clvmd that could cause odd hangs.
Add vgmerge tests.
Add pvseg_is_allocated() for identifying a PV segment allocated to a LV.
Add list_move() for moving elements from one list to another.
@ -4264,7 +4354,7 @@ Version 2.02.34 - 10th April 2008
Correct command name in lvmdiskscan man page.
clvmd no longer crashes if it sees nodeids over 50.
Fix potential deadlock in clvmd thread handling.
Refactor text format initialisation into _init_text_import.
Refactor text format initialization into _init_text_import.
Escape double quotes and backslashes in external metadata and config data.
Add functions for escaping double quotes in strings.
Rename count_chars_len to count_chars.
@ -4314,7 +4404,7 @@ Version 2.02.31 - 19th January 2008
Version 2.02.30 - 17th January 2008
===================================
Set default readahead to twice maximium stripe size.
Set default readahead to twice maximum stripe size.
Reinstate VG extent size and stripe size defaults (halved). (2.02.29)
Add lists of stacked LV segments using each LV to the internal metadata.
Change vgsplit -l (for unimplemented --list) into --maxlogicalvolumes.
@ -4686,7 +4776,7 @@ Version 2.02.11 - 12th October 2006
Capture error messages in clvmd and pass them back to the user.
Remove unused #defines from filter-md.c.
Make clvmd restart init script wait until clvmd has died before starting it.
Add -R to clvmd which tells running clvmds to reload their device cache.
Add -R to clvmd which tells running clvmd to reload their device cache.
Add LV column to reports listing kernel modules needed for activation.
Show available fields if report given invalid field. (e.g. lvs -o list)
Add timestamp functions with --disable-realtime configure option.
@ -5013,7 +5103,7 @@ Version 2.01.08 - 22nd March 2005
Improve detection of external changes affecting internal cache.
Add 'already in device cache' debug message.
Add -a to pvdisplay -C.
Avoid rmdir opendir error messsages when dir was already removed.
Avoid rmdir opendir error messages when dir was already removed.
Tighten signal handlers.
Avoid some compiler warnings.
Additional rename failure error message.
@ -5244,7 +5334,7 @@ Version 2.00.17 - 20 June 2004
fsadm support for fsck and resizing - needs testing.
Add read-only GFS pool support.
Add lvm2create_initrd script from http://poochiereds.net/svn/lvm2/
Fix rounding of large diplayed sizes.
Fix rounding of large displayed sizes.
Suppress decimal point when using units of sectors/bytes.
Additional kernel target checks before pvmove & snapshot creation.
Add i2o_block.

View File

@ -1,3 +1,34 @@
Version 1.02.206 -
===================
Add support for using regex in selection criteria for string lists.
Fix string list selection when using [<item> || <item> ...].
Version 1.02.205 - 27th February 2025
=====================================
Restore missing symbol dm_tree_node_size_changed@Base (1.02.175).
Restore missing symbol dm_bitset_parse_list@@DM_1_02_138 (1.02.175).
Version 1.02.204 - 14th January 2025
====================================
Create /dev/disk/by-diskseq/<DISKSEQ> symlink for public DM devices.
Version 1.02.203 - 09th December 2024
=====================================
Version 1.02.202 - 04th November 2024
=====================================
Introduce dm_config_parse_only_section to stop parsing after section.
For shorter string use on stack buffers when generating sections.
Enhance dm_config tokenizer.
Version 1.02.201 - 02nd October 2024
====================================
Cleanup udev sync semaphore if dm_{udev_create,task_set}_cookie fails.
Improve error messages on failed udev cookie create/inc/dec operation.
Version 1.02.200 - 23rd August 2024
===================================
Version 1.02.199 - 12nd July 2024
=================================
@ -85,7 +116,7 @@ Version 1.02.173 - 09th August 2020
Version 1.02.171 - 26th March 2020
==================================
Try to remove all created devices on dm preload tree error path.
Fix dm_list interators with gcc 10 optimization (-ftree-pta).
Fix dm_list iterators with gcc 10 optimization (-ftree-pta).
Dmeventd handles timer without looping on short intervals.
Version 1.02.169 - 11th February 2020
@ -116,7 +147,7 @@ Version 1.02.155 - 18th December 2018
=====================================
Include correct internal header inside libdm list.c.
Enhance ioctl flattening and add parameters only when needed.
Add DM_DEVICE_ARM_POLL for API completness matching kernel.
Add DM_DEVICE_ARM_POLL for API completeness matching kernel.
Do not add parameters for RESUME with DM_DEVICE_CREATE dm task.
Fix dmstats report printing no output.
@ -145,7 +176,7 @@ Version 1.02.147-rc1 - 24th May 2018
Reuse uname() result for mirror target.
Recognize also mounted btrfs through dm_device_has_mounted_fs().
Add missing log_error() into dm_stats_populate() returning 0.
Avoid calling dm_stats_populat() for DM devices without any stats regions.
Avoid calling dm_stats_populate() for DM devices without any stats regions.
Support DM_DEBUG_WITH_LINE_NUMBERS envvar for debug msg with source:line.
Configured command for thin pool threshold handling gets whole environment.
Fix tests for failing dm_snprintf() in stats code.
@ -194,7 +225,7 @@ Version 1.02.141 - 28th June 2017
Add dm_percent_to_round_float for adjusted percentage rounding.
Reset array with dead rimage devices once raid gets in sync.
Drop unneeded --config option from raid dmeventd plugin.
dm_get_status_raid() handle better some incosistent md statuses.
dm_get_status_raid() handle better some inconsistent md statuses.
Accept truncated files in calls to dm_stats_update_regions_from_fd().
Restore Warning by 5% increment when thin-pool is over 80% (1.02.138).
@ -249,7 +280,7 @@ Version 1.02.136 - 5th November 2016
Still produce output when dmsetup dependency tree building finds dev missing.
Check and report pthread_sigmask() failure in dmeventd.
Check mem alloc fail in _canonicalize_field_ids().
Use unsigned math when checking more then 31 legs of raid.
Use unsigned math when checking more than 31 legs of raid.
Fix 'dmstats delete' with dmsetup older than v1.02.129
Fix stats walk segfault with dmsetup older than v1.02.129
@ -389,7 +420,7 @@ Version 1.02.112 - 28th November 2015
=====================================
Show error message when trying to create unsupported raid type.
Improve preloading sequence of an active thin-pool target.
Drop extra space from cache target line to fix unneded table reloads.
Drop extra space from cache target line to fix unneeded table reloads.
Version 1.02.111 - 23rd November 2015
=====================================
@ -404,7 +435,7 @@ Version 1.02.110 - 30th October 2015
Disable thin monitoring plugin when it fails too often (>10 times).
Fix/restore parsing of empty field '-' when processing dmeventd event.
Enhance dm_tree_node_size_changed() to recognize size reduction.
Support exit on idle for dmenventd (1 hour).
Support exit on idle for dmeventd (1 hour).
Add support to allow unmonitor device from plugin itself.
New design for thread co-operation in dmeventd.
Dmeventd read device status with 'noflush'.
@ -577,7 +608,7 @@ Version 1.02.93 - 21st January 2015
Version 1.02.92 - 24th November 2014
====================================
Fix memory corruption with sorting empty string lists (1.02.86).
Fix man dmsetup.8 syntax warning of Groff
Fix man dmsetup.8 syntax warning of Groff.
Accept unquoted strings and / in place of {} when parsing configs.
Version 1.02.91 - 11th November 2014
@ -596,7 +627,7 @@ Version 1.02.90 - 1st September 2014
Version 1.02.89 - 26th August 2014
==================================
Improve libdevmapper-event select() error handling.
Add extra check for matching transation_id after message submitting.
Add extra check for matching transaction_id after message submitting.
Add dm_report_field_string_list_unsorted for str. list report without sorting.
Support --deferred with dmsetup remove to defer removal of open devices.
Update dm-ioctl.h to include DM_DEFERRED_REMOVE flag.
@ -683,7 +714,7 @@ Version 1.02.82 - 4th October 2013
Version 1.02.81 - 23rd September 2013
=====================================
Tidy dmeventd fifo initialisation.
Tidy dmeventd fifo initialization.
Version 1.02.80 - 20th September 2013
=====================================
@ -708,7 +739,7 @@ Version 1.02.78 - 24th July 2013
Always return success on dmeventd -V command call.
Fix parsing of 64bit snapshot status in dmeventd snapshot plugin.
Add dm_get_status_snapshot() for parsing snapshot status.
Detecte mounted fs also via reading /proc/self/mountinfo.
Detect mounted fs also via reading /proc/self/mountinfo.
Add dm_mountinfo_read() for parsing /proc/self/mountinfo.
Report error for nonexisting devices in dmeventd communication.
Prevent double free error after dmeventd call of _fill_device_data().
@ -805,7 +836,7 @@ Version 1.02.71 - 20th February 2012
Add "watch" rule to 13-dm-disk.rules.
Detect failing fifo and skip 20s retry communication period.
Add DM_DEFAULT_NAME_MANGLING_MODE environment variable as an override.
Add dm_lib_init to automatically initialise device-mapper library on load.
Add dm_lib_init to automatically initialize device-mapper library on load.
Replace any '\' char with '\\' in dm table specification on input.
Add mangle command to dmsetup to provide renaming to correct mangled form.
Add 'mangled_name' and 'unmangled_name' fields to dmsetup info -c -o.
@ -899,7 +930,7 @@ Version 1.02.66 - 12th August 2011
Fix memory leak in dmsetup _message() memory allocation error path.
Use new oom killer adjustment interface (oom_score_adj) when available.
Add systemd unit files for dmeventd.
Fix read-only identical table reload supression.
Fix read-only identical table reload suppression.
Version 1.02.65 - 8th July 2011
===============================
@ -914,7 +945,7 @@ Version 1.02.65 - 8th July 2011
Add dm_get_suspended_counter() for number of devs in suspended state by lib.
Fix "all" report field prefix matching to include label fields with pv_all.
Delay resuming new preloaded mirror devices with core logs in deptree code.
Accept new kernel version 3 uname formats in initialisation.
Accept new kernel version 3 uname formats in initialization.
Version 1.02.64 - 29th April 2011
==================================
@ -928,7 +959,7 @@ Version 1.02.64 - 29th April 2011
Improve stack debug reporting in dm_task_create().
Fallback to control node creation only if node doesn't exist yet.
Change dm_hash binary functions to take void *key instead of char *.
Fix uninitialised memory use with empty params in _reload_with_suppression_v4.
Fix uninitialized memory use with empty params in _reload_with_suppression_v4.
Lower severity of selabel_lookup and matchpathcon failure to log_debug.
Add test for failed allocation from dm_task_set_uuid() in dmeventd.
Add dm_event_get_version to dmeventd for use with -R.
@ -1097,7 +1128,7 @@ Version 1.02.44 - 15th February 2010
Version 1.02.43 - 21st January 2010
===================================
Remove bitset, hash and pool headers superceded by libdevmapper.h.
Remove bitset, hash and pool headers superseded by libdevmapper.h.
Fix off-by-one error causing bad cluster mirror table construction.
Version 1.02.42 - 14th January 2010
@ -1221,7 +1252,7 @@ Version 1.02.27 - 25th June 2008
Version 1.02.26 - 6th June 2008
===============================
Initialise params buffer to empty string in _emit_segment.
Initialize params buffer to empty string in _emit_segment.
Skip add_dev_node when ioctls disabled.
Make dm_hash_iter safe against deletion.
Accept a NULL pointer to dm_free silently.
@ -1277,7 +1308,7 @@ Version 1.02.20 - 15th June 2007
Version 1.02.19 - 27th April 2007
=================================
Standardise protective include file #defines.
Standardize protective include file #defines.
Add regex functions to library.
Avoid trailing separator in reports when there are hidden sort fields.
Fix segfault in 'dmsetup status' without --showkeys against crypt target.
@ -1308,7 +1339,7 @@ Version 1.02.16 - 25th January 2007
Streamline dm_report_field_* interface.
Add cmdline debug & version options to dmeventd.
Add DM_LIB_VERSION definition to configure.h.
Suppress 'Unrecognised field' error if report field is 'help'.
Suppress 'Unrecognized field' error if report field is 'help'.
Add --separator and --sort to dmsetup (unused).
Make alignment flag optional when specifying report fields.

61
aclocal.m4 vendored
View File

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
# generated automatically by aclocal 1.17 -*- Autoconf -*-
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -117,8 +117,8 @@ m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION], [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
@ -126,6 +126,12 @@ dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
dnl
dnl If pkg-config is not found or older than specified, it will result
dnl in an empty PKG_CONFIG variable. To avoid widespread issues with
dnl scripts not checking it, ACTION-IF-NOT-FOUND defaults to aborting.
dnl You can specify [PKG_CONFIG=false] as an action instead, which would
dnl result in pkg-config tests failing, but no bogus error messages.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
@ -146,6 +152,9 @@ if test -n "$PKG_CONFIG"; then
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi
if test -z "$PKG_CONFIG"; then
m4_default([$2], [AC_MSG_ERROR([pkg-config not found])])
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG
@ -413,7 +422,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
])dnl PKG_HAVE_DEFINE_WITH_MODULES
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
# Copyright (C) 1999-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -447,9 +456,12 @@ AC_DEFUN([AM_PATH_PYTHON],
dnl Find a Python interpreter. Python versions prior to 2.0 are not
dnl supported. (2.0 was released on October 16, 2000).
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
[python python2 python3 dnl
[python python3 dnl
python3.20 python3.19 python3.18 python3.17 python3.16 dnl
python3.15 python3.14 python3.13 python3.12 python3.11 python3.10 dnl
python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl
python3.2 python3.1 python3.0 dnl
python2 dnl
python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl
python2.0])
@ -644,15 +656,29 @@ try:
if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
can_use_sysconfig = 0
except ImportError:
pass"
pass" # end of am_python_setup_sysconfig
# More repeated code, for figuring out the installation scheme to use.
am_python_setup_scheme="if hasattr(sysconfig, 'get_default_scheme'):
scheme = sysconfig.get_default_scheme()
else:
scheme = sysconfig._get_default_scheme()
if scheme == 'posix_local':
if '$am_py_prefix' == '/usr':
scheme = 'deb_system' # should only happen during Debian package builds
else:
# Debian's default scheme installs to /usr/local/ but we want to
# follow the prefix, as we always have.
# See bugs#54412, #64837, et al.
scheme = 'posix_prefix'" # end of am_python_setup_scheme
dnl emacs-page Set up 4 directories:
dnl 1. pythondir: where to install python scripts. This is the
dnl site-packages directory, not the python standard library
dnl directory like in previous automake betas. This behavior
dnl directory as in early automake betas. This behavior
dnl is more consistent with lispdir.m4 for example.
dnl Query distutils for this directory.
dnl Query sysconfig or distutils (per above) for this directory.
dnl
AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)],
[am_cv_python_pythondir],
@ -664,7 +690,11 @@ except ImportError:
am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
try:
$am_python_setup_scheme
sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'})
except:
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
@ -694,7 +724,8 @@ sys.stdout.write(sitedir)"`
dnl 3. pyexecdir: directory for installing python extension modules
dnl (shared libraries).
dnl Query distutils for this directory.
dnl Query sysconfig or distutils for this directory.
dnl Much of this is the same as for prefix setup above.
dnl
AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)],
[am_cv_python_pyexecdir],
@ -706,7 +737,11 @@ sys.stdout.write(sitedir)"`
am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'})
try:
$am_python_setup_scheme
sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'})
except:
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix')
@ -757,7 +792,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
sys.exit(sys.hexversion < minverhex)"
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
# Copyright (C) 2001-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,

View File

@ -30,10 +30,10 @@ struct dm_hash_table {
unsigned num_nodes;
unsigned num_hint;
unsigned mask_slots; /* (slots - 1) -> used as hash mask */
unsigned collisions; /* Collissions of hash keys */
unsigned collisions; /* Collisions of hash keys */
unsigned search; /* How many keys were searched */
unsigned found; /* How many nodes were found */
unsigned same_hash; /* Was there a colision with same masked hash and len ? */
unsigned same_hash; /* Was there a collision with same masked hash and len ? */
struct dm_hash_node **slots;
};
@ -348,7 +348,7 @@ int dm_hash_insert_allow_multiple(struct dm_hash_table *t, const char *key,
/*
* Look through multiple entries with the same key for one that has a
* matching val and return that. If none have maching val, return NULL.
* matching val and return that. If none have matching val, return NULL.
*/
void *dm_hash_lookup_with_val(struct dm_hash_table *t, const char *key,
const void *val, uint32_t val_len)

View File

@ -279,7 +279,7 @@ static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, const u
pc->len = i;
if (!_insert(rt, &pc->child, kb + i, ke, rv)) {
free(pc2);
free(pc->child.value.ptr);
return false;
}
@ -293,6 +293,7 @@ static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, const u
if (pc->len == 1) {
n4->values[0] = pc->child;
free(pc);
v->value.ptr = NULL;
} else {
memmove(pc->prefix, pc->prefix + 1, pc->len - 1);
pc->len--;
@ -564,6 +565,13 @@ bool radix_tree_insert(struct radix_tree *rt, const void *key, size_t keylen, un
return _insert(rt, lr.v, lr.kb, ke, rv);
}
int radix_tree_uniq_insert(struct radix_tree *rt, const void *key, size_t keylen, union radix_value rv)
{
unsigned entries = rt->nr_entries;
return radix_tree_insert(rt, key, keylen, rv) ?
((entries != rt->nr_entries) ? 1 : -1) : 0;
}
// Note the degrade functions also free the original node.
static void _degrade_to_n4(struct node16 *n16, struct value *result)
{

View File

@ -193,12 +193,12 @@ bool radix_tree_remove(struct radix_tree *rt, const void *key, size_t keylen)
return true;
}
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *key, size_t keylen)
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, size_t prefix_len)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
const uint8_t *kb = prefix;
const uint8_t *ke = kb + prefix_len;
struct node **pn;
unsigned count;
unsigned count = 0;
pn = _lookup(&rt->root, kb, ke);
@ -280,7 +280,7 @@ static void _dump(FILE *out, struct node *n, unsigned indent)
fprintf(out, " ");
if (n->has_value) {
fprintf(out, "value: %llu\n", n->value.n);
fprintf(out, "value: %lu\n", (unsigned long) n->value.n);
} else {
fprintf(out, "key: '%c' [0x%02x] %u\n",
isprint(n->key) ? n->key : ' ', n->key, indent);

View File

@ -35,6 +35,10 @@ void radix_tree_destroy(struct radix_tree *rt);
unsigned radix_tree_size(struct radix_tree *rt);
bool radix_tree_insert(struct radix_tree *rt, const void *key, size_t keylen, union radix_value v);
bool radix_tree_remove(struct radix_tree *rt, const void *key, size_t keylen);
// Returns: 1 success
// 0 failure during insert
// -1 key had already existing value (that was updated)
int radix_tree_uniq_insert(struct radix_tree *rt, const void *key, size_t keylen, union radix_value v);
// Returns the number of values removed
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, size_t prefix_len);
@ -78,6 +82,12 @@ static inline bool radix_tree_insert_ptr(struct radix_tree *rt, const void *key,
union radix_value v = { .ptr = ptr };
return radix_tree_insert(rt, key, keylen, v);
}
static inline int radix_tree_uniq_insert_ptr(struct radix_tree *rt, const void *key, size_t keylen, void *ptr)
{
union radix_value v = { .ptr = ptr };
return radix_tree_uniq_insert(rt, key, keylen, v);
}
//----------------------------------------------------------------
#endif

View File

@ -36,6 +36,19 @@ config {
# This configuration option has an automatic default value.
# checks = 1
# Configuration option config/validate_metadata.
# Allows to select the level of validation after metadata transformation.
# Validation takes extra CPU time to verify internal consistency.
# Accepted values:
# full
# Do a full metadata validation before disk write.
# none
# Skip any checks (unrecommended, slightly faster).
#
# This configuration option is advanced.
# This configuration option has an automatic default value.
# validate_metadata = "full"
# Configuration option config/abort_on_errors.
# Abort the LVM process if a configuration mismatch is found.
# This configuration option has an automatic default value.
@ -122,7 +135,7 @@ devices {
# Configuration option devices/use_devicesfile.
# Enable or disable the use of a devices file.
# When enabled, lvm will only use devices that
# are lised in the devices file. A devices file will
# are listed in the devices file. A devices file will
# be used, regardless of this setting, when the --devicesfile
# option is set to a specific file name.
# This configuration option has an automatic default value.
@ -562,7 +575,7 @@ allocation {
# Configuration option allocation/cache_pool_max_chunks.
# The maximum number of chunks in a cache pool.
# For cache target v1.9 the recommended maximumm is 1000000 chunks.
# For cache target v1.9 the recommended maximum is 1000000 chunks.
# Using cache pool with more chunks may degrade cache performance.
# This configuration option does not have a default value defined.
@ -573,7 +586,7 @@ allocation {
# Configuration option allocation/thin_pool_crop_metadata.
# Older version of lvm2 cropped pool's metadata size to 15.81 GiB.
# This is slightly less then the actual maximum 15.88 GiB.
# This is slightly less than the actual maximum 15.88 GiB.
# For compatibility with older version and use of cropped size set to 1.
# This configuration option has an automatic default value.
# thin_pool_crop_metadata = 0
@ -646,13 +659,6 @@ allocation {
# This configuration option has an automatic default value.
# vdo_use_deduplication = 1
# Configuration option allocation/vdo_use_metadata_hints.
# Enables or disables whether VDO volume should tag its latency-critical
# writes with the REQ_SYNC flag. Some device mapper targets such as dm-raid5
# process writes with this flag at a higher priority.
# This configuration option has an automatic default value.
# vdo_use_metadata_hints = 1
# Configuration option allocation/vdo_minimum_io_size.
# The minimum IO size for VDO volume to accept, in bytes.
# Valid values are 512 or 4096. The recommended value is 4096.
@ -751,19 +757,6 @@ allocation {
# This configuration option has an automatic default value.
# vdo_physical_threads = 1
# Configuration option allocation/vdo_write_policy.
# Specifies the write policy:
# auto - VDO will check the storage device and determine whether it supports flushes.
# If it does, VDO will run in async mode, otherwise it will run in sync mode.
# sync - Writes are acknowledged only after data is stably written.
# This policy is not supported if the underlying storage is not also synchronous.
# async - Writes are acknowledged after data has been cached for writing to stable storage.
# Data which has not been flushed is not guaranteed to persist in this mode.
# async-unsafe - Writes are handled like 'async' but there is no guarantee of the atomicity async provides.
# This mode should only be used for better performance when atomicity is not required.
# This configuration option has an automatic default value.
# vdo_write_policy = "auto"
# Configuration option allocation/vdo_max_discard.
# Specified the maximum size of discard bio accepted, in 4096 byte blocks.
# I/O requests to a VDO volume are normally split into 4096-byte blocks,
@ -801,6 +794,9 @@ log {
# to define fields to display and sort fields for the log report.
# You can also use log/command_log_selection to define selection
# criteria used each time the log is reported.
# Note that if report/output_format (or --reportformat command line
# option) is set to json or json_std, then log/report_command_log=1
# is default.
# This configuration option has an automatic default value.
# report_command_log = 0
@ -830,8 +826,9 @@ log {
# define selection criteria for log report on command line directly
# using <lvm command> --configreport log -S <selection criteria>
# which has precedence over log/command_log_selection setting.
# For more information about selection criteria in general, see
# lvm(8) man page.
# To make all the command log lines visible, use "all" value
# for the command log selection. For more information about selection
# criteria in general, see lvmreport(7) man page.
# This configuration option has an automatic default value.
# command_log_selection = "!(log_type=status && message=success)"
@ -1208,6 +1205,16 @@ global {
# This configuration option has an automatic default value.
# sanlock_lv_extend = 256
# Configuration option global/sanlock_align_size.
# The sanlock lease size in MiB to use on disks with a 4K sector size.
# Possible values are 1,2,4,8. The default is 8, which supports up to
# 2000 hosts (and max host_id 2000.) Smaller values support smaller
# numbers of max hosts (and max host_ids): 250, 500, 1000, 2000 for
# lease sizes 1,2,4,8. Disks with 512 byte sectors always use 1MiB
# leases and support 2000 hosts, and are not affected by this setting.
# This configuration option has an automatic default value.
# sanlock_align_size = 8
# Configuration option global/lvmlockctl_kill_command.
# The command that lvmlockctl --kill should use to force LVs offline.
# The lvmlockctl --kill command is run when a shared VG has lost
@ -1511,12 +1518,14 @@ activation {
# Configuration option activation/reserved_stack.
# Stack size in KiB to reserve for use while devices are suspended.
# Insufficient reserve risks I/O deadlock during device suspension.
# Value 0 disables memory locking.
# This configuration option has an automatic default value.
# reserved_stack = 64
# Configuration option activation/reserved_memory.
# Memory size in KiB to reserve for use while devices are suspended.
# Insufficient reserve risks I/O deadlock during device suspension.
# Value 0 disables memory locking.
# This configuration option has an automatic default value.
# reserved_memory = 8192
@ -1865,7 +1874,7 @@ activation {
# uses are present. Other PVs in the Volume Group may be missing.
# degraded
# Like complete, but additionally RAID LVs of segment type raid1,
# raid4, raid5, radid6 and raid10 will be activated if there is no
# raid4, raid5, raid6 and raid10 will be activated if there is no
# data loss, i.e. they have sufficient redundancy to present the
# entire addressable range of the Logical Volume.
# partial
@ -1989,7 +1998,7 @@ report {
# If there is more than one report per command, then the format
# is applied for all reports. You can also change output format
# directly on command line using --reportformat option which
# has precedence over log/output_format setting.
# has precedence over report/output_format setting.
# Accepted values:
# basic
# Original format with columns and rows. If there is more than
@ -2003,6 +2012,7 @@ report {
# - it does not use double quotes around numeric values,
# - it uses 'null' for undefined numeric values,
# - it prints string list as proper JSON array of strings instead of a single string.
# Note that if json or json_std output format is used, then log/command_log_report=1 is default.
# This configuration option has an automatic default value.
# output_format = "basic"
@ -2125,7 +2135,7 @@ report {
# %F
# Equivalent to %Y-%m-%d (the ISO 8601 date format).
# %G
# The ISO 8601 week-based year with century as adecimal number.
# The ISO 8601 week-based year with century as a decimal number.
# The 4-digit year corresponding to the ISO week number (see %V).
# This has the same format and value as %Y, except that if the
# ISO week number belongs to the previous or next year, that year

View File

@ -49,9 +49,10 @@ local {
# This configuration option does not have a default value defined.
# Configuration option local/host_id.
# The lvmlockd sanlock host_id.
# This must be unique among all hosts, and must be between 1 and 2000.
# Applicable only if LVM is compiled with lockd support
# The sanlock host_id used by lvmlockd. This must be unique among all the hosts
# using shared VGs with sanlock. Accepted values are 1-2000, except when sanlock_align_size
# is configured to 1, 2 or 4, which correspond to max host_id values of 250, 500, or 1000.
# Applicable only if LVM is compiled with support for lvmlockd+sanlock.
# This configuration option has an automatic default value.
# host_id = 0
}

View File

@ -4,7 +4,6 @@
allocation {
vdo_use_compression=1
vdo_use_deduplication=1
vdo_use_metadata_hints=1
vdo_minimum_io_size=4096
vdo_block_map_cache_size_mb=128
vdo_block_map_period=16380
@ -18,6 +17,5 @@ allocation {
vdo_hash_zone_threads=1
vdo_logical_threads=1
vdo_physical_threads=1
vdo_write_policy="auto"
vdo_max_discard=1
}

303
configure vendored
View File

@ -678,6 +678,7 @@ SILENT_RULES
SHARED_LINK
SELINUX_STATIC_LIBS
SELINUX_PC
SD_NOTIFY_SUPPORT
SBINDIR
RT_LIBS
PYTHON3DIR
@ -787,6 +788,8 @@ LIBSYSTEMD_LIBS
LIBSYSTEMD_CFLAGS
UDEV_LIBS
UDEV_CFLAGS
LIBNVME_LIBS
LIBNVME_CFLAGS
BLKID_LIBS
BLKID_CFLAGS
SYSTEMD_RUN_CMD
@ -912,6 +915,7 @@ enable_silent_rules
enable_static_link
enable_shared
with_blkid
with_libnvme
with_systemd
with_udev
with_user
@ -971,8 +975,10 @@ enable_use_lvmpolld
with_lvmpolld_pidfile
enable_systemd_journal
enable_app_machineid
enable_sd_notify
with_systemd_run
enable_blkid_wiping
enable_nvme_wwid
enable_udev_sync
enable_udev_rules
enable_udev_rule_exec_detection
@ -1045,6 +1051,8 @@ LIBSEAGATEILM_CFLAGS
LIBSEAGATEILM_LIBS
BLKID_CFLAGS
BLKID_LIBS
LIBNVME_CFLAGS
LIBNVME_LIBS
UDEV_CFLAGS
UDEV_LIBS
LIBSYSTEMD_CFLAGS
@ -1713,8 +1721,10 @@ Optional Features:
--disable-systemd-journal
disable LVM systemd journaling
--disable-app-machineid disable LVM system ID using app-specific machine-id
--disable-sd-notify disable LVM sd_notify
--disable-blkid_wiping disable libblkid detection of signatures when wiping
and use native code instead
--disable-nvme-wwid do not use libnvme to detect alternate WWIDs
--enable-udev_sync enable synchronization with udev processing
--enable-udev_rules install rule files needed for udev synchronization
--enable-udev-rule-exec-detection
@ -1741,6 +1751,7 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--without-blkid do not build with blkid library
--without-libnvme do not build with libnvme library
--without-systemd do not build with systemd library
--without-udev do not build with udev library
--with-user=USER set the owner of installed files [USER=]
@ -1880,6 +1891,10 @@ Some influential environment variables:
BLKID_CFLAGS
C compiler flags for BLKID, overriding pkg-config
BLKID_LIBS linker flags for BLKID, overriding pkg-config
LIBNVME_CFLAGS
C compiler flags for LIBNVME, overriding pkg-config
LIBNVME_LIBS
linker flags for LIBNVME, overriding pkg-config
UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config
UDEV_LIBS linker flags for UDEV, overriding pkg-config
LIBSYSTEMD_CFLAGS
@ -9128,6 +9143,16 @@ esac
fi
# Check whether --with-libnvme was given.
if test ${with_libnvme+y}
then :
withval=$with_libnvme;
else case e in #(
e) with_libnvme="yes" ;;
esac
fi
# Check whether --with-systemd was given.
if test ${with_systemd+y}
then :
@ -10929,7 +10954,7 @@ printf "%s\n" "#define VDO_FORMAT_CMD \"$VDO_FORMAT_CMD\"" >>confdefs.h
#
# Do we need to use the API??
# Do we want to link lvm2 with a big library for vdoformatting ?
# Do we want to link lvm2 with a big library for VDO formatting ?
#
#AC_ARG_WITH(vdo-include,
# AS_HELP_STRING([--with-vdo-include=PATH],
@ -11286,6 +11311,9 @@ printf "%s\n" "no" >&6; }
PKG_CONFIG=""
fi
fi
if test -z "$PKG_CONFIG"; then
as_fn_error $? "pkg-config not found" "$LINENO" 5
fi
if test "$BUILD_CMIRRORD" = "yes" && test "$HAVE_CPG" != "yes"
then :
@ -12721,9 +12749,18 @@ SYSTEMD_MIN_VERSION=0
NOTIFYDBUS_SUPPORT="no"
SYSTEMD_JOURNAL_SUPPORT="no"
APP_MACHINEID_SUPPORT="no"
SD_NOTIFY_SUPPORT="no"
if test "$with_systemd" = "yes"
then :
if test -n "$PKG_CONFIG" && \
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd >= 218\""; } >&5
($PKG_CONFIG --exists --print-errors "systemd >= 218") 2>&5
ac_status=$?
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
SYSTEMD_MIN_VERSION=218 SD_NOTIFY_SUPPORT="maybe"
fi
if test -n "$PKG_CONFIG" && \
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd >= 221\""; } >&5
($PKG_CONFIG --exists --print-errors "systemd >= 221") 2>&5
ac_status=$?
@ -12811,6 +12848,41 @@ printf "%s\n" "#define APP_MACHINEID_SUPPORT 1" >>confdefs.h
fi
################################################################################
if test "$SD_NOTIFY_SUPPORT" != "no"
then :
ac_fn_c_check_header_compile "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default"
if test "x$ac_cv_header_systemd_sd_daemon_h" = xyes
then :
SD_NOTIFY_SUPPORT="yes"
else case e in #(
e) SD_NOTIFY_SUPPORT="no" ;;
esac
fi
fi
# Check whether --enable-sd-notify was given.
if test ${enable_sd_notify+y}
then :
enableval=$enable_sd_notify; if test "$enableval" = "yes" && test "$SD_NOTIFY_SUPPORT" = "no"
then :
as_fn_error $? "--enable-sd-notify requires systemd/sd-daemon.h. (--with-systemd=$with_systemd)" "$LINENO" 5
fi
SD_NOTIFY_SUPPORT=$enableval
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable to sd_notify" >&5
printf %s "checking whether to enable to sd_notify... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SD_NOTIFY_SUPPORT" >&5
printf "%s\n" "$SD_NOTIFY_SUPPORT" >&6; }
if test "$SD_NOTIFY_SUPPORT" = "yes"
then :
printf "%s\n" "#define SD_NOTIFY_SUPPORT 1" >>confdefs.h
fi
################################################################################
# Check whether --with-systemd-run was given.
@ -13126,6 +13198,181 @@ printf "%s\n" "$BLKID_WIPING" >&6; }
printf "%s\n" "#define DEFAULT_USE_BLKID_WIPING $DEFAULT_USE_BLKID_WIPING" >>confdefs.h
################################################################################
# Check whether --enable-nvme-wwid was given.
if test ${enable_nvme_wwid+y}
then :
enableval=$enable_nvme_wwid; NVME_WWID=$enableval
else case e in #(
e) if test "$with_libnvme" = "yes"
then :
NVME_WWID="maybe"
else case e in #(
e) NVME_WWID="no" ;;
esac
fi ;;
esac
fi
# ATM NVME_WWID is the only user of libnvme, so skip checking for libnvme when disabled
if test "$NVME_WWID" = "no"
then :
with_libnvme="no"
fi
if test "$with_libnvme" = "yes"
then :
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libnvme >= 1.4" >&5
printf %s "checking for libnvme >= 1.4... " >&6; }
if test -n "$LIBNVME_CFLAGS"; then
pkg_cv_LIBNVME_CFLAGS="$LIBNVME_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnvme >= 1.4\""; } >&5
($PKG_CONFIG --exists --print-errors "libnvme >= 1.4") 2>&5
ac_status=$?
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_LIBNVME_CFLAGS=`$PKG_CONFIG --cflags "libnvme >= 1.4" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$LIBNVME_LIBS"; then
pkg_cv_LIBNVME_LIBS="$LIBNVME_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnvme >= 1.4\""; } >&5
($PKG_CONFIG --exists --print-errors "libnvme >= 1.4") 2>&5
ac_status=$?
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_LIBNVME_LIBS=`$PKG_CONFIG --libs "libnvme >= 1.4" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
LIBNVME_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnvme >= 1.4" 2>&1`
else
LIBNVME_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnvme >= 1.4" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$LIBNVME_PKG_ERRORS" >&5
if test "$NVME_WWID" = "yes"
then :
NVME_WWID="error"
else case e in #(
e) NVME_WWID="no" ;;
esac
fi
elif test $pkg_failed = untried; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
if test "$NVME_WWID" = "yes"
then :
NVME_WWID="error"
else case e in #(
e) NVME_WWID="no" ;;
esac
fi
else
LIBNVME_CFLAGS=$pkg_cv_LIBNVME_CFLAGS
LIBNVME_LIBS=$pkg_cv_LIBNVME_LIBS
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for NVME_NIDT_CSI in libnvme.h" >&5
printf %s "checking for NVME_NIDT_CSI in libnvme.h... " >&6; }
if test ${ac_cv_have_libnvme_csi+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <libnvme.h>
const int a = NVME_NIDT_CSI;
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ac_cv_have_libnvme_csi="yes"
else case e in #(
e) ac_cv_have_libnvme_csi="no" ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_libnvme_csi" >&5
printf "%s\n" "$ac_cv_have_libnvme_csi" >&6; }
if test "$NVME_WWID" != "no"
then :
if test $ac_cv_have_libnvme_csi = yes
then :
NVME_WWID="yes"
printf "%s\n" "#define NVME_SUPPORT 1" >>confdefs.h
else case e in #(
e) NVME_WWID="error" ;;
esac
fi
fi
fi
else case e in #(
e) if test "$NVME_WWID" = "yes"
then :
NVME_WWID="error"
fi ;;
esac
fi
if test "$NVME_WWID" = "error"
then :
as_fn_error $? "--enable-nvme-wwid requires libnvme library >= 1.1. (--with-libnvme=$with_libnvme)" "$LINENO" 5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use libnvme for alternate WWIDs" >&5
printf %s "checking whether to use libnvme for alternate WWIDs... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NVME_WWID" >&5
printf "%s\n" "$NVME_WWID" >&6; }
################################################################################
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable synchronization with udev processing" >&5
printf %s "checking whether to enable synchronization with udev processing... " >&6; }
@ -13424,7 +13671,11 @@ printf "%s\n" "$BUILD_LVMDBUSD" >&6; }
# Check whether --enable-notify-dbus was given.
if test ${enable_notify_dbus+y}
then :
enableval=$enable_notify_dbus; NOTIFYDBUS_SUPPORT=$enableval
enableval=$enable_notify_dbus; if test "enableval" = "yes" && test "$NOTIFYDBUS_SUPPORT" = "no"
then :
as_fn_error $? "--enable-notify-dbus requires systemd >= 221. (--with-systemd=$with_systemd)" "$LINENO" 5
fi
NOTIFYDBUS_SUPPORT=$enableval
fi
@ -13441,13 +13692,9 @@ fi
if test "$NOTIFYDBUS_SUPPORT" = "yes"
then :
if test "$SYSTEMD_MIN_VERSION" -lt 221
then :
as_fn_error $? "--enable-notify-dbus requires systemd >= 221. (--with-systemd=$with_systemd)" "$LINENO" 5
fi
printf "%s\n" "#define NOTIFYDBUS_SUPPORT 1" >>confdefs.h
]
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build notifydbus" >&5
@ -13456,10 +13703,10 @@ printf %s "checking whether to build notifydbus... " >&6; }
printf "%s\n" "$NOTIFYDBUS_SUPPORT" >&6; }
################################################################################
if test "$NOTIFYDBUS_SUPPORT" = "yes" || test "$SYSTEMD_JOURNAL_SUPPORT" = "yes" || test "$APP_MACHINEID_SUPPORT" = "yes"
if test "$NOTIFYDBUS_SUPPORT" = "yes" || test "$SYSTEMD_JOURNAL_SUPPORT" = "yes" ||
test "$APP_MACHINEID_SUPPORT" = "yes" || test "$SD_NOTIFY_SUPPORT" = "yes"
then :
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5
printf %s "checking for libsystemd... " >&6; }
@ -13550,7 +13797,6 @@ else
printf "%s\n" "yes" >&6; }
fi
fi
################################################################################
@ -13877,7 +14123,21 @@ try:
if python_implementation() == 'CPython' and sys.version[:3] == '2.7':
can_use_sysconfig = 0
except ImportError:
pass"
pass" # end of am_python_setup_sysconfig
# More repeated code, for figuring out the installation scheme to use.
am_python_setup_scheme="if hasattr(sysconfig, 'get_default_scheme'):
scheme = sysconfig.get_default_scheme()
else:
scheme = sysconfig._get_default_scheme()
if scheme == 'posix_local':
if '$am_py_prefix' == '/usr':
scheme = 'deb_system' # should only happen during Debian package builds
else:
# Debian's default scheme installs to /usr/local/ but we want to
# follow the prefix, as we always have.
# See bugs#54412, #64837, et al.
scheme = 'posix_prefix'" # end of am_python_setup_scheme
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory (pythondir)" >&5
@ -13894,7 +14154,11 @@ else case e in #(
am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
try:
$am_python_setup_scheme
sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'})
except:
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
@ -13924,7 +14188,7 @@ printf "%s\n" "$am_cv_python_pythondir" >&6; }
pkgpythondir=\${pythondir}/$PACKAGE
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory (pyexecdir)" >&5
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory (pyexecdir)" >&5
printf %s "checking for $am_display_PYTHON extension module directory (pyexecdir)... " >&6; }
if test ${am_cv_python_pyexecdir+y}
then :
@ -13938,7 +14202,11 @@ else case e in #(
am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'})
try:
$am_python_setup_scheme
sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'})
except:
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix')
@ -16561,6 +16829,7 @@ AIO_LIBS=${AIO_LIBS:--laio}
################################################################################
@ -17958,3 +18227,9 @@ then :
printf "%s\n" "$as_me: WARNING: Building D-Bus support without D-Bus notifications!" >&2;}
fi
if test "$BUILD_LVMLOCKD" = "yes" && test "$SD_NOTIFY_SUPPORT" = "no"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Building lvmlockd without sd-notify support may block!" >&5
printf "%s\n" "$as_me: WARNING: Building lvmlockd without sd-notify support may block!" >&2;}
fi

View File

@ -20,7 +20,7 @@ AC_CONFIG_SRCDIR([lib/device/dev-cache.h])
AC_CONFIG_HEADERS([include/configure.h])
################################################################################
dnl -- Setup the directory where autoconf has auxilary files
dnl -- Setup the directory where autoconf has auxiliary files
AC_CONFIG_AUX_DIR(autoconf)
################################################################################
@ -217,6 +217,8 @@ test "$exec_prefix" = "NONE" && exec_prefix='${prefix}'
AC_ARG_WITH(blkid, [AS_HELP_STRING([--without-blkid], [do not build with blkid library])],
[], with_blkid="yes")
AC_ARG_WITH(libnvme, [AS_HELP_STRING([--without-libnvme], [do not build with libnvme library])],
[], with_libnvme="yes")
AC_ARG_WITH(systemd, [AS_HELP_STRING([--without-systemd], [do not build with systemd library])],
[], with_systemd="yes")
AC_ARG_WITH(udev, [AS_HELP_STRING([--without-udev], [do not build with udev library])],
@ -656,7 +658,7 @@ AC_DEFINE_UNQUOTED([VDO_FORMAT_CMD], ["$VDO_FORMAT_CMD"],
[The path to 'vdoformat', if available.])
#
# Do we need to use the API??
# Do we want to link lvm2 with a big library for vdoformatting ?
# Do we want to link lvm2 with a big library for VDO formatting ?
#
#AC_ARG_WITH(vdo-include,
# AS_HELP_STRING([--with-vdo-include=PATH],
@ -952,7 +954,7 @@ AS_IF([test "$BUILD_LOCKDDLM" = "yes"], [
AC_DEFINE([LOCKDDLM_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd dlm option.])
AS_CASE(["$LIBDLM_LIBS"],
[*lpthread*], [
dnl -- pkg-congig for libdlm_lt may give us libdlm with libpthread
dnl -- pkg-config for libdlm_lt may give us libdlm with libpthread
AC_MSG_RESULT([replacing pkg-config --libs libdlm_lt "$LIBDLM_LIBS" with... -ldlm_lt])
LIBDLM_LIBS="${LIBDLM_LIBS%%ldlm*}ldlm_lt"])
])
@ -1046,7 +1048,9 @@ SYSTEMD_MIN_VERSION=0
NOTIFYDBUS_SUPPORT="no"
SYSTEMD_JOURNAL_SUPPORT="no"
APP_MACHINEID_SUPPORT="no"
SD_NOTIFY_SUPPORT="no"
AS_IF([test "$with_systemd" = "yes"],
PKG_CHECK_EXISTS(systemd >= 218, [SYSTEMD_MIN_VERSION=218 SD_NOTIFY_SUPPORT="maybe"])
PKG_CHECK_EXISTS(systemd >= 221, [SYSTEMD_MIN_VERSION=221 NOTIFYDBUS_SUPPORT="maybe" SYSTEMD_JOURNAL_SUPPORT="maybe"])
PKG_CHECK_EXISTS(systemd >= 234, [SYSTEMD_MIN_VERSION=234 APP_MACHINEID_SUPPORT="maybe"]))
@ -1082,6 +1086,22 @@ AC_MSG_RESULT([$APP_MACHINEID_SUPPORT])
AS_IF([test "$APP_MACHINEID_SUPPORT" = "yes"],
AC_DEFINE([APP_MACHINEID_SUPPORT], 1, [Define to 1 to include code that uses libsystemd machine-id apis.]))
################################################################################
dnl -- Build with sd_notify when the header file sd-daemon.h is present
AS_IF([test "$SD_NOTIFY_SUPPORT" != "no"],
AC_CHECK_HEADER([systemd/sd-daemon.h], [SD_NOTIFY_SUPPORT="yes"], [SD_NOTIFY_SUPPORT="no"]))
AC_ARG_ENABLE(sd-notify,
AS_HELP_STRING([--disable-sd-notify],
[disable LVM sd_notify]),
AS_IF([test "$enableval" = "yes" && test "$SD_NOTIFY_SUPPORT" = "no"],
AC_MSG_ERROR([--enable-sd-notify requires systemd/sd-daemon.h. (--with-systemd=$with_systemd)]))
SD_NOTIFY_SUPPORT=$enableval, [])
AC_MSG_CHECKING([whether to enable to sd_notify])
AC_MSG_RESULT([$SD_NOTIFY_SUPPORT])
AS_IF([test "$SD_NOTIFY_SUPPORT" = "yes"],
AC_DEFINE([SD_NOTIFY_SUPPORT], 1, [Define to 1 to include code that uses sd_notify.]))
################################################################################
dnl -- Support override for systemd-run path if they need to (NixOS builds)
AC_ARG_WITH(systemd-run,
@ -1139,6 +1159,38 @@ AC_MSG_RESULT([$BLKID_WIPING])
AC_DEFINE_UNQUOTED(DEFAULT_USE_BLKID_WIPING, [$DEFAULT_USE_BLKID_WIPING],
[Use blkid wiping by default.])
################################################################################
dnl -- Enable nvme alternate WWID via libnvme
AC_ARG_ENABLE(nvme-wwid,
AS_HELP_STRING([--disable-nvme-wwid],
[do not use libnvme to detect alternate WWIDs]),
NVME_WWID=$enableval,
[AS_IF([test "$with_libnvme" = "yes"], [NVME_WWID="maybe"], [NVME_WWID="no"])])
# ATM NVME_WWID is the only user of libnvme, so skip checking for libnvme when disabled
AS_IF([test "$NVME_WWID" = "no"], [with_libnvme="no"])
AS_IF([test "$with_libnvme" = "yes"], [
PKG_CHECK_MODULES([LIBNVME], [libnvme >= 1.4], [
AC_CACHE_CHECK([for NVME_NIDT_CSI in libnvme.h],
[ac_cv_have_libnvme_csi],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <libnvme.h>
const int a = NVME_NIDT_CSI;
])], [ac_cv_have_libnvme_csi="yes"], [ac_cv_have_libnvme_csi="no"])])
AS_IF([test "$NVME_WWID" != "no"], [
AC_IF_YES(ac_cv_have_libnvme_csi, [NVME_WWID="yes"
AC_DEFINE(NVME_SUPPORT, 1, [Use libnvme for WWID.])],
[NVME_WWID="error"])])
], [AS_IF([test "$NVME_WWID" = "yes"], [NVME_WWID="error"], [NVME_WWID="no"])])
], [AS_IF([test "$NVME_WWID" = "yes"], [NVME_WWID="error"])])
AS_IF([test "$NVME_WWID" = "error"],
[AC_MSG_ERROR([--enable-nvme-wwid requires libnvme library >= 1.1. (--with-libnvme=$with_libnvme)])])
AC_MSG_CHECKING([whether to use libnvme for alternate WWIDs])
AC_MSG_RESULT([$NVME_WWID])
################################################################################
dnl -- Enable udev synchronization
AC_MSG_CHECKING([whether to enable synchronization with udev processing])
@ -1231,14 +1283,15 @@ AC_MSG_RESULT([$BUILD_LVMDBUSD])
dnl -- Build notifydbus
AC_ARG_ENABLE(notify-dbus,
[AS_HELP_STRING([--enable-notify-dbus], [enable LVM notification using dbus])],
[NOTIFYDBUS_SUPPORT=$enableval])
[AS_IF([test "enableval" = "yes" && test "$NOTIFYDBUS_SUPPORT" = "no"],
[AC_MSG_ERROR([--enable-notify-dbus requires systemd >= 221. (--with-systemd=$with_systemd)])])
NOTIFYDBUS_SUPPORT=$enableval])
AS_IF([test "$NOTIFYDBUS_SUPPORT" = "maybe"],
[AS_IF([test "$BUILD_LVMDBUSD" = "yes"], [NOTIFYDBUS_SUPPORT="yes"], [NOTIFYDBUS_SUPPORT="no"])])
[AS_IF([test "$BUILD_LVMDBUSD" = "yes"],
[NOTIFYDBUS_SUPPORT="yes"], [NOTIFYDBUS_SUPPORT="no"])])
AS_IF([test "$NOTIFYDBUS_SUPPORT" = "yes"],
[AS_IF([test "$SYSTEMD_MIN_VERSION" -lt 221],
[AC_MSG_ERROR([--enable-notify-dbus requires systemd >= 221. (--with-systemd=$with_systemd)])])
AC_DEFINE([NOTIFYDBUS_SUPPORT], 1, [Define to 1 to include code that uses dbus notification.])])
AC_MSG_CHECKING([whether to build notifydbus])
@ -1246,9 +1299,9 @@ AC_MSG_RESULT([$NOTIFYDBUS_SUPPORT])
################################################################################
dnl -- Look for libsystemd libraries if needed
AS_IF([test "$NOTIFYDBUS_SUPPORT" = "yes" || test "$SYSTEMD_JOURNAL_SUPPORT" = "yes" || test "$APP_MACHINEID_SUPPORT" = "yes"], [
PKG_CHECK_MODULES(LIBSYSTEMD, [libsystemd])
])
AS_IF([test "$NOTIFYDBUS_SUPPORT" = "yes" || test "$SYSTEMD_JOURNAL_SUPPORT" = "yes" ||
test "$APP_MACHINEID_SUPPORT" = "yes" || test "$SD_NOTIFY_SUPPORT" = "yes"],
[PKG_CHECK_MODULES(LIBSYSTEMD, [libsystemd])])
################################################################################
dnl -- Enable Python dbus library
@ -1938,6 +1991,7 @@ AC_SUBST(PYTHON3)
AC_SUBST(PYTHON3DIR)
AC_SUBST(RT_LIBS)
AC_SUBST(SBINDIR)
AC_SUBST(SD_NOTIFY_SUPPORT)
AC_SUBST(SELINUX_LIBS)
AC_SUBST(SELINUX_PC)
AC_SUBST(SELINUX_STATIC_LIBS)
@ -2075,3 +2129,6 @@ AS_IF([test "$ODIRECT" != "yes"],
AS_IF([test "$BUILD_LVMDBUSD" = "yes" && test "$NOTIFYDBUS_SUPPORT" = "no"],
[AC_MSG_WARN([Building D-Bus support without D-Bus notifications!])])
AS_IF([test "$BUILD_LVMLOCKD" = "yes" && test "$SD_NOTIFY_SUPPORT" = "no"],
[AC_MSG_WARN([Building lvmlockd without sd-notify support may block!])])

View File

@ -21,7 +21,7 @@
* compile (using outdir 'cov'):
* cov-build --dir=cov make CC=gcc
*
* analyze (agressively, using 'cov')
* analyze (aggressively, using 'cov')
* cov-analyze --dir cov --wait-for-license --hfa --concurrency --enable-fnptr --enable-constraint-fpp --security --all --aggressiveness-level=high --field-offset-escape --user-model-file=coverity/coverity_model.xml
*
* generate html output (to 'html' from 'cov'):
@ -30,6 +30,8 @@
struct lv_segment;
struct logical_volume;
struct cmd_context;
struct profile;
struct lv_segment *first_seg(const struct logical_volume *lv)
{
@ -57,7 +59,7 @@ struct logical_volume *origin_from_cow(const struct logical_volume *lv)
*/
/* simple_memccpy() from glibc */
void *memccpy(void *dest, const void *src, int c, size_t n)
void *memccpy(void *dest, const void *src, int c, unsigned long n)
{
const char *s = src;
char *d = dest;
@ -70,7 +72,7 @@ void *memccpy(void *dest, const void *src, int c, size_t n)
}
/*
* 2 lines bellow needs to be placed in coverity/config/user_nodefs.h
* 2 lines below needs to be placed in coverity/config/user_nodefs.h
* Not sure about any other way.
* Without them, coverity shows warning since x86 system header files
* are using inline assembly to reset fdset
@ -90,9 +92,14 @@ void model_FD_ZERO(void *fdset)
/* Resent Coverity reports quite weird errors... */
int *__errno_location(void)
{
static int _i = 0;
return &_i;
}
const unsigned short **__ctype_b_loc (void)
{
static const unsigned short *_a[1] = { 0 };
return _a;
}

View File

@ -279,7 +279,7 @@ static int handle_cluster_request(struct clog_cpg *entry __attribute__((unused))
* With resumes, we only handle our own.
* Resume is a special case that requires
* local action (to set up CPG), followed by
* a cluster action to co-ordinate reading
* a cluster action to coordinate reading
* the disk and checkpointing
*/
if (tmp->u_rq.request_type == DM_ULOG_RESUME) {

View File

@ -8,6 +8,8 @@
#ifndef _LVM_CLOG_COMPAT_H
#define _LVM_CLOG_COMPAT_H
#include <stddef.h>
/*
* The intermachine communication structure version are:
* 0: Unused
@ -19,6 +21,8 @@
*/
#define CLOG_TFR_VERSION 5
struct clog_request;
int clog_request_to_network(struct clog_request *rq);
int clog_request_from_network(void *data, size_t data_len);

View File

@ -254,7 +254,7 @@ static int read_log(struct log_c *lc)
bitset_size = lc->region_count / 8;
bitset_size += (lc->region_count % 8) ? 1 : 0;
/* 'lc->clean_bits + 1' becasue dm_bitset_t leads with a uint32_t */
/* 'lc->clean_bits + 1' because dm_bitset_t leads with a uint32_t */
memcpy(lc->clean_bits + 1, (char *)lc->disk_buffer + 1024, bitset_size);
return 0;
@ -281,7 +281,7 @@ static int write_log(struct log_c *lc)
bitset_size = lc->region_count / 8;
bitset_size += (lc->region_count % 8) ? 1 : 0;
/* 'lc->clean_bits + 1' becasue dm_bitset_t leads with a uint32_t */
/* 'lc->clean_bits + 1' because dm_bitset_t leads with a uint32_t */
memcpy((char *)lc->disk_buffer + 1024, lc->clean_bits + 1, bitset_size);
if (rw_log(lc, 1)) {
@ -927,7 +927,7 @@ int local_resume(struct dm_ulog_request *rq)
*
* Since this value doesn't change, the kernel
* should not need to talk to server to get this
* The function is here for completness
* The function is here for completeness
*
* Returns: 0 on success, -EXXX on failure
*/
@ -1018,7 +1018,7 @@ static int clog_in_sync(struct dm_ulog_request *rq)
* happen for reads is that additional read attempts may be
* taken.
*
* Futher investigation may be required to determine if there are
* Further investigation may be required to determine if there are
* similar possible outcomes when the mirror is in the process of
* recovering. In that case, lc->in_sync would not have been set
* yet.

View File

@ -12,6 +12,8 @@
#ifndef _LVM_CLOG_LOCAL_H
#define _LVM_CLOG_LOCAL_H
struct dm_ulog_request;
int init_local(void);
void cleanup_local(void);

View File

@ -236,7 +236,7 @@ struct thread_status {
int status; /* See DM_THREAD_{REGISTERING,RUNNING,DONE} */
int events; /* bitfield for event filter. */
int current_events; /* bitfield for occured events. */
int current_events; /* bitfield for occurred events. */
struct dm_task *wait_task;
int pending; /* Set when event filter change is pending */
time_t next_time;
@ -268,7 +268,7 @@ static void _free_dso_data(struct dso_data *data)
static struct dso_data *_alloc_dso_data(struct message_data *data)
{
struct dso_data *ret = (typeof(ret)) zalloc(sizeof(*ret));
struct dso_data *ret = (__typeof__(ret)) zalloc(sizeof(*ret));
if (!ret)
return_NULL;
@ -427,7 +427,7 @@ static struct thread_status *_alloc_thread_status(const struct message_data *dat
if (!(thread->device.name = strdup(data->device_uuid)))
goto_out;
/* runs ioctl and may register lvm2 pluging */
/* runs ioctl and may register lvm2 plugin */
thread->processing = 1;
thread->status = DM_THREAD_REGISTERING;
@ -520,7 +520,7 @@ static int _fetch_string(char **ptr, char **src, const int delimiter)
*p = delimiter;
*src = p;
}
(*src)++; /* Skip delmiter, next field */
(*src)++; /* Skip delimiter, next field */
} else if ((len = strlen(*src))) {
/* No delimiter, item ends with '\0' */
if (!(*ptr = strdup(*src))) {

View File

@ -15,6 +15,8 @@
#ifndef __DMEVENTD_DOT_H__
#define __DMEVENTD_DOT_H__
#include <stdint.h>
/* FIXME This stuff must be configurable. */
#define DM_EVENT_FIFO_CLIENT DEFAULT_DM_RUN_DIR "/dmeventd-client"

View File

@ -404,7 +404,7 @@ int daemon_talk(struct dm_event_fifos *fifos,
/*
* Check for usable client fifo file
*
* Returns: 2 cliant path does not exists, dmeventd should be restarted
* Returns: 2 client path does not exists, dmeventd should be restarted
* 1 on success, 0 otherwise
*/
static int _check_for_usable_fifos(char *dmeventd_path, struct dm_event_fifos *fifos)
@ -1007,7 +1007,7 @@ void dm_event_log(const char *subsys, int level, const char *file,
static char *_skip_string(char *src, const int delimiter)
{
src = srtchr(src, delimiter);
src = strchr(src, delimiter);
if (src && *(src + 1))
return src + 1;
return NULL;

View File

@ -29,19 +29,22 @@
*/
enum dm_event_mask {
DM_EVENT_SETTINGS_MASK = 0x0000FF,
DM_EVENT_SINGLE = 0x000001, /* Report multiple errors just once. */
DM_EVENT_MULTI = 0x000002, /* Report all of them. */
DM_EVENT_SETTINGS_MASK = 0x0000FF,
DM_EVENT_ERROR_MASK = 0x00FF00,
DM_EVENT_SECTOR_ERROR = 0x000100, /* Failure on a particular sector. */
DM_EVENT_DEVICE_ERROR = 0x000200, /* Device failure. */
DM_EVENT_PATH_ERROR = 0x000400, /* Failure on an io path. */
DM_EVENT_ADAPTOR_ERROR = 0x000800, /* Failure of a host adaptor. */
DM_EVENT_ERROR_MASK = 0x00FF00,
DM_EVENT_SYNC_STATUS = 0x010000, /* Mirror synchronization completed/failed. */
DM_EVENT_TIMEOUT = 0x020000, /* Timeout has occurred */
DM_EVENT_ERROR_AND_TIMEOUT_MASK = 0x02FF00,
DM_EVENT_STATUS_MASK = 0xFF0000,
DM_EVENT_SYNC_STATUS = 0x010000, /* Mirror synchronization completed/failed. */
DM_EVENT_TIMEOUT = 0x020000, /* Timeout has occured */
DM_EVENT_REGISTRATION_PENDING = 0x1000000, /* Monitor thread is setting-up/shutting-down */
};
@ -70,10 +73,10 @@ int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path);
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path);
/*
* Identify the device to monitor by exactly one of device_name, uuid or
* Identify the device to monitor by exactly one of dev_name, uuid or
* device number. String arguments are duplicated, see above.
*/
int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *device_name);
int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *dev_name);
int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid);
@ -109,7 +112,7 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
/* Set debug level for logging, and whether to log on stdout/stderr or syslog */
void dm_event_log_set(int debug_log_level, int use_syslog);
/* Log messages acroding to current debug level */
/* Log messages according to current debug level */
__attribute__((format(printf, 6, 0)))
void dm_event_log(const char *subsys, int level, const char *file,
int line, int dm_errno_or_class,

View File

@ -87,7 +87,7 @@ int dmeventd_lvm2_init(void)
lvm2_disable_dmeventd_monitoring(_lvm_handle);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
log_debug("lvm plugin initilized.");
log_debug("lvm plugin initialized.");
}
_register_count++;
@ -103,7 +103,7 @@ void dmeventd_lvm2_exit(void)
pthread_mutex_lock(&_register_mutex);
if (!--_register_count) {
log_debug("lvm plugin shuting down.");
log_debug("lvm plugin shutting down.");
lvm2_run(_lvm_handle, "_memlock_dec");
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;

View File

@ -25,6 +25,8 @@
#ifndef _DMEVENTD_LVMWRAP_H
#define _DMEVENTD_LVMWRAP_H
#include <stddef.h>
struct dm_pool;
int dmeventd_lvm2_init(void);

View File

@ -38,7 +38,7 @@ static void _process_status_code(dm_status_mirror_health_t health,
* A => Alive - No failures
* D => Dead - A write failure occurred leaving mirror out-of-sync
* F => Flush failed.
* S => Sync - A sychronization failure occurred, mirror out-of-sync
* S => Sync - A synchronization failure occurred, mirror out-of-sync
* R => Read - A read failure occurred, mirror data unaffected
* U => Unclassified failure (bug)
*/
@ -112,7 +112,7 @@ static int _remove_failed_devices(const char *cmd_lvconvert, const char *device)
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
enum dm_event_mask evmask __attribute__((unused)),
void **user)
{
struct dso_state *state = *user;

View File

@ -17,7 +17,7 @@
#include "daemons/dmeventd/libdevmapper-event.h"
#include "lib/config/defaults.h"
/* Hold enough elements for the mximum number of RAID images */
/* Hold enough elements for the maximum number of RAID images */
#define RAID_DEVS_ELEMS ((DEFAULT_RAID_MAX_IMAGES + 63) / 64)
struct dso_state {
@ -114,7 +114,7 @@ out:
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
enum dm_event_mask evmask __attribute__((unused)),
void **user)
{
struct dso_state *state = *user;

View File

@ -163,7 +163,7 @@ static void _umount(const char *device, int major, int minor)
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
enum dm_event_mask evmask __attribute__((unused)),
void **user)
{
struct dso_state *state = *user;

View File

@ -87,7 +87,7 @@ static int _run_command(struct dso_state *state)
log_verbose("Executing command: %s", state->cmd_str);
/* TODO:
* Support parallel run of 'task' and it's waitpid maintainence
* Support parallel run of 'task' and it's waitpid maintenance
* ATM we can't handle signaling of SIGALRM
* as signalling is not allowed while 'process_event()' is running
*/
@ -155,7 +155,7 @@ static int _wait_for_pid(struct dso_state *state)
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
enum dm_event_mask evmask,
void **user)
{
const char *device = dm_task_get_name(dmt);
@ -179,7 +179,7 @@ void process_event(struct dm_task *dmt,
return;
}
if (event & DM_EVENT_DEVICE_ERROR) {
if (evmask & DM_EVENT_DEVICE_ERROR) {
/* Error -> no need to check and do instant resize */
state->data_percent = state->metadata_percent = 0;
if (_use_policy(dmt, state))
@ -245,7 +245,7 @@ void process_event(struct dm_task *dmt,
/*
* Trigger action when threshold boundary is exceeded.
* Report 80% threshold warning when it's used above 80%.
* Only 100% is exception as it cannot be surpased so policy
* Only 100% is exception as it cannot be surpassed so policy
* action is called for: >50%, >55% ... >95%, 100%
*/
state->metadata_percent = dm_make_percent(tps->used_metadata_blocks, tps->total_metadata_blocks);
@ -379,7 +379,7 @@ int register_device(const char *device,
state->argv[1] = str + 1; /* 1 argument - vg/lv */
_init_thread_signals(state);
} else /* Unuspported command format */
} else /* Unsupported command format */
goto inval;
state->pid = -1;

View File

@ -19,7 +19,7 @@
/*
* Use parser from new device_mapper library.
* Although during compilation we can see dm_vdo_status_parse()
* in runtime we are linked agains systems libdm 'older' library
* in runtime we are linked against systems libdm 'older' library
* which does not provide this symbol and plugin fails to load
*/
/* coverity[unnecessary_header] used for parsing */
@ -78,7 +78,7 @@ static int _run_command(struct dso_state *state)
log_verbose("Executing command: %s", state->cmd_str);
/* TODO:
* Support parallel run of 'task' and it's waitpid maintainence
* Support parallel run of 'task' and it's waitpid maintenance
* ATM we can't handle signaling of SIGALRM
* as signalling is not allowed while 'process_event()' is running
*/
@ -146,7 +146,7 @@ static int _wait_for_pid(struct dso_state *state)
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
enum dm_event_mask evmask __attribute__((unused)),
void **user)
{
const char *device = dm_task_get_name(dmt);
@ -169,7 +169,7 @@ void process_event(struct dm_task *dmt,
return;
}
if (event & DM_EVENT_DEVICE_ERROR) {
if (evmask & DM_EVENT_DEVICE_ERROR) {
#if VDO_DEBUG
log_debug("VDO event error.");
#endif
@ -227,7 +227,7 @@ void process_event(struct dm_task *dmt,
/*
* Trigger action when threshold boundary is exceeded.
* Report 80% threshold warning when it's used above 80%.
* Only 100% is exception as it cannot be surpased so policy
* Only 100% is exception as it cannot be surpassed so policy
* action is called for: >50%, >55% ... >95%, 100%
*/
if ((state->percent > WARNING_THRESH) &&
@ -354,7 +354,7 @@ int register_device(const char *device,
_init_thread_signals(state);
} else if (cmd[0] == 0) {
state->name = "volume"; /* What to use with 'others?' */
} else/* Unuspported command format */
} else/* Unsupported command format */
goto inval;
state->pid = -1;

View File

@ -160,6 +160,8 @@ def call_lvm(command, debug=False, line_cb=None,
# Check to see if process has terminated, None when running
if process.poll() is not None:
stdout_text += read_decoded(process.stdout)
stderr_text += read_decoded(process.stderr)
break
except IOError as ioe:
log_debug("call_lvm:" + str(ioe))
@ -552,6 +554,14 @@ def lv_vdo_deduplication(lv_path, enable, dedup_options):
return call(cmd)
def lv_raid_repair(lv_path, new_pvs, repair_options):
cmd = ['lvconvert', '-y', '--repair']
cmd.append(lv_path)
cmd.extend(new_pvs)
cmd.extend(options_to_cli_args(repair_options))
return call(cmd)
def supports_json():
cmd = ['help']
rc, out, err = call(cmd)

View File

@ -67,7 +67,7 @@ def lvs_state_retrieve(selection, cache_refresh=True):
try:
# When building up the model, it's best to process LVs with the least
# dependencies to those that are dependant upon other LVs. Otherwise, when
# dependencies to those that are dependent upon other LVs. Otherwise, when
# we are trying to gather information we could be in a position where we
# don't have information available yet.
lvs = sorted(cfg.db.fetch_lvs(selection), key=get_key)
@ -795,6 +795,39 @@ class Lv(LvCommon):
cache_options), cb, cbe)
cfg.worker_q.put(r)
@staticmethod
def _repair_raid_lv(lv_uuid, lv_name, new_pvs, repair_options):
# Make sure we have a dbus object representing it
pv_dests = []
dbo = LvCommon.validate_dbus_object(lv_uuid, lv_name)
# If we have PVs, verify them
if len(new_pvs):
for pv in new_pvs:
pv_dbus_obj = cfg.om.get_object_by_path(pv)
if not pv_dbus_obj:
raise dbus.exceptions.DBusException(
LV_INTERFACE,
'PV Destination (%s) not found' % pv)
pv_dests.append(pv_dbus_obj.lvm_id)
LvCommon.handle_execute(*cmdhandler.lv_raid_repair(
dbo.lvm_id, pv_dests, repair_options))
return "/"
@dbus.service.method(
dbus_interface=LV_INTERFACE,
in_signature='aoia{sv}',
out_signature='o',
async_callbacks=('cb', 'cbe'))
def RepairRaidLv(self, new_pvs, tmo, repair_options, cb, cbe):
r = RequestEntry(
tmo, Lv._repair_raid_lv,
(self.Uuid, self.lvm_id, new_pvs,
repair_options), cb, cbe, return_tuple=False)
cfg.worker_q.put(r)
# noinspection PyPep8Naming
@utils.dbus_property(VDO_POOL_INTERFACE, 'OperatingMode', 's')

View File

@ -351,7 +351,7 @@ class DataStore(object):
else:
rc = []
for s in pv_name:
# Ths user could be using a symlink instead of the actual
# The user could be using a symlink instead of the actual
# block device, make sure we are using actual block device file
# if the pv name isn't in the lookup
if s not in self.pv_path_to_uuid:

View File

@ -133,7 +133,7 @@ def process_args():
def running_under_systemd():
""""
Checks to see if we are running under systemd, by checking damon fd 0, 1
Checks to see if we are running under systemd, by checking daemon fd 0, 1
systemd sets stdin to /dev/null and 1 & 2 are a socket
"""
base = "/proc/self/fd"
@ -214,7 +214,7 @@ def main():
cfg.loop = GLib.MainLoop()
for thread in thread_list:
thread.damon = True
thread.daemon = True
thread.start()
# In all cases we are going to monitor for udev until we get an

View File

@ -160,7 +160,7 @@ class ObjectManager(AutomatedProperties):
# (path, dbus_object.lvm_id))
# We want fast access to the object by a number of different ways,
# so we use multiple hashs with different keys
# so we use multiple hashes with different keys
self._lookup_add(dbus_object, path, dbus_object.lvm_id,
dbus_object.Uuid)

View File

@ -50,8 +50,7 @@ INCLUDES += -I$(top_srcdir)/libdaemon/server
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
LIBS += $(DAEMON_LIBS) $(PTHREAD_LIBS)
ifneq (,$(firstword $(LIBSYSTEMD_LIBS)))
DEFS += -DUSE_SD_NOTIFY
ifeq ("@SD_NOTIFY_SUPPORT@", "yes")
CFLAGS += $(LIBSYSTEMD_CFLAGS)
LIBS += $(LIBSYSTEMD_LIBS)
endif

View File

@ -38,7 +38,7 @@ static int stop_lockspaces = 0;
static char *arg_vg_name = NULL;
#define DUMP_SOCKET_NAME "lvmlockd-dump.sock"
#define DUMP_BUF_SIZE (1024 * 1024)
#define DUMP_BUF_SIZE (4 * 1024 * 1024)
static char dump_buf[DUMP_BUF_SIZE+1];
static int dump_len;
static struct sockaddr_un dump_addr;
@ -97,8 +97,9 @@ static void save_client_info(char *line)
uint32_t client_id = 0;
char name[MAX_NAME+1] = { 0 };
(void) sscanf(line, "info=client pid=%u fd=%d pi=%d id=%u name=%s",
&pid, &fd, &pi, &client_id, name);
(void) sscanf(line, "info=client pid=%u fd=%d pi=%d id=%u name=%"
DM_TO_STRING(MAX_NAME) "s",
&pid, &fd, &pi, &client_id, name);
clients[num_clients].client_id = client_id;
clients[num_clients].pid = pid;
@ -126,12 +127,14 @@ static void format_info_ls(char *line)
char ls_name[MAX_NAME+1] = { 0 };
char vg_name[MAX_NAME+1] = { 0 };
char vg_uuid[MAX_NAME+1] = { 0 };
char vg_sysid[MAX_NAME+1] = { 0 };
char lock_args[MAX_ARGS+1] = { 0 };
char lock_type[MAX_NAME+1] = { 0 };
(void) sscanf(line, "info=ls ls_name=%s vg_name=%s vg_uuid=%s vg_sysid=%s vg_args=%s lm_type=%s",
ls_name, vg_name, vg_uuid, vg_sysid, lock_args, lock_type);
(void) sscanf(line, "info=ls ls_name=%" DM_TO_STRING(MAX_NAME) "s vg_name=%"
DM_TO_STRING(MAX_NAME) "s vg_uuid=%" DM_TO_STRING(MAX_NAME)
"s vg_args=%" DM_TO_STRING(MAX_NAME) "s lm_type=%"
DM_TO_STRING(MAX_NAME) "s",
ls_name, vg_name, vg_uuid, lock_args, lock_type);
if (!first_ls)
printf("\n");
@ -151,8 +154,11 @@ static void format_info_ls_action(char *line)
uint32_t pid = 0;
char cl_name[MAX_NAME+1] = { 0 };
(void) sscanf(line, "info=ls_action client_id=%u %s %s op=%s",
&client_id, flags, version, op);
(void) sscanf(line, "info=ls_action client_id=%u %"
DM_TO_STRING(MAX_NAME) "s %"
DM_TO_STRING(MAX_NAME) "s op=%"
DM_TO_STRING(MAX_NAME) "s",
&client_id, flags, version, op);
find_client_info(client_id, &pid, cl_name);
@ -167,8 +173,10 @@ static void format_info_r(char *line, char *r_name_out, char *r_type_out)
char sh_count[MAX_NAME+1] = { 0 };
uint32_t ver = 0;
(void) sscanf(line, "info=r name=%s type=%s mode=%s %s version=%u",
r_name, r_type, mode, sh_count, &ver);
(void) sscanf(line, "info=r name=%" DM_TO_STRING(MAX_NAME)
"s type=%3s mode=%3s %"
DM_TO_STRING(MAX_NAME) "s version=%u",
r_name, r_type, mode, sh_count, &ver);
strcpy(r_name_out, r_name);
strcpy(r_type_out, r_type);
@ -205,8 +213,9 @@ static void format_info_lk(char *line, char *r_name, char *r_type)
return;
}
(void) sscanf(line, "info=lk mode=%s version=%u %s client_id=%u",
mode, &ver, flags, &client_id);
(void) sscanf(line, "info=lk mode=%3s version=%u %"
DM_TO_STRING(MAX_NAME) "s client_id=%u",
mode, &ver, flags, &client_id);
find_client_info(client_id, &pid, cl_name);
@ -241,8 +250,11 @@ static void format_info_r_action(char *line, char *r_name, char *r_type)
return;
}
(void) sscanf(line, "info=r_action client_id=%u %s %s op=%s rt=%s mode=%s %s %s %s",
&client_id, flags, version, op, rt, mode, lm, result, lm_rv);
(void) sscanf(line, "info=r_action client_id=%u %" DM_TO_STRING(MAX_NAME)
"s %" DM_TO_STRING(MAX_NAME) "s op=%" DM_TO_STRING(MAX_NAME)
"s rt=%3s mode=%3s %" DM_TO_STRING(MAX_NAME) "s %"
DM_TO_STRING(MAX_NAME) "s %" DM_TO_STRING(MAX_NAME) "s",
&client_id, flags, version, op, rt, mode, lm, result, lm_rv);
find_client_info(client_id, &pid, cl_name);

View File

@ -11,7 +11,7 @@
#include "tools/tool.h"
#include "libdaemon/client/daemon-io.h"
#include "daemon-server.h"
#include "libdaemon/server/daemon-server.h"
#include "lvm-version.h"
#include "daemons/lvmlockd/lvmlockd-client.h"
#include "device_mapper/misc/dm-ioctl.h"
@ -31,7 +31,7 @@
#include <sys/utsname.h>
#include <sys/un.h>
#ifdef USE_SD_NOTIFY
#ifdef SD_NOTIFY_SUPPORT
#include <systemd/sd-daemon.h>
#endif
@ -78,7 +78,7 @@ static int str_to_mode(const char *str);
* . Other misc actions are are passed to the worker_thread:
* add_work_action(act).
*
* Onec the client_thread has passed the action off to another
* Once the client_thread has passed the action off to another
* thread to process, it goes back to waiting for more client
* handling work to do.
*
@ -155,7 +155,7 @@ static const char *adopt_file;
* 1MB should fit all the info we need to dump.
*/
#define DUMP_SOCKET_NAME "lvmlockd-dump.sock"
#define DUMP_BUF_SIZE (1024 * 1024)
#define DUMP_BUF_SIZE (4 * 1024 * 1024)
static char dump_buf[DUMP_BUF_SIZE];
static struct sockaddr_un dump_addr;
static socklen_t dump_addrlen;
@ -416,6 +416,7 @@ struct lockspace *alloc_lockspace(void)
INIT_LIST_HEAD(&ls->actions);
INIT_LIST_HEAD(&ls->resources);
INIT_LIST_HEAD(&ls->dispose);
pthread_mutex_init(&ls->mutex, NULL);
pthread_cond_init(&ls->cond, NULL);
return ls;
@ -754,7 +755,7 @@ static const char *rt_str(int x)
case LD_RT_LV:
return "lv";
default:
return ".";
return "";
};
}
@ -999,7 +1000,7 @@ static int read_adopt_file(struct list_head *vg_lockd)
memset(vg_uuid, 0, sizeof(vg_uuid));
memset(mode, 0, sizeof(mode));
if (sscanf(adopt_line, "LV: %64s %64s %s %7s %u",
if (sscanf(adopt_line, "LV: %64s %64s %64s %7s %u",
vg_uuid, r->name, r->lv_args, mode, &r->version) != 5) {
free_resource(r);
goto fail;
@ -1046,7 +1047,7 @@ fail:
static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
{
int rv;
int rv = -1;
if (ls->lm_type == LD_LM_DLM)
rv = lm_prepare_lockspace_dlm(ls);
@ -1054,26 +1055,22 @@ static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
rv = lm_prepare_lockspace_sanlock(ls);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_prepare_lockspace_idm(ls);
else
return -1;
if (act)
act->lm_rv = rv;
return rv;
}
static int lm_add_lockspace(struct lockspace *ls, struct action *act, int adopt_only, int adopt_ok)
static int lm_add_lockspace(struct lockspace *ls, struct action *act, int adopt_only, int adopt_ok, int nodelay)
{
int rv;
int rv = -1;
if (ls->lm_type == LD_LM_DLM)
rv = lm_add_lockspace_dlm(ls, adopt_only, adopt_ok);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_add_lockspace_sanlock(ls, adopt_only, adopt_ok);
rv = lm_add_lockspace_sanlock(ls, adopt_only, adopt_ok, nodelay);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_add_lockspace_idm(ls, adopt_only, adopt_ok);
else
return -1;
if (act)
act->lm_rv = rv;
@ -1082,7 +1079,7 @@ static int lm_add_lockspace(struct lockspace *ls, struct action *act, int adopt_
static int lm_rem_lockspace(struct lockspace *ls, struct action *act, int free_vg)
{
int rv;
int rv = -1;
if (ls->lm_type == LD_LM_DLM)
rv = lm_rem_lockspace_dlm(ls, free_vg);
@ -1090,18 +1087,30 @@ static int lm_rem_lockspace(struct lockspace *ls, struct action *act, int free_v
rv = lm_rem_lockspace_sanlock(ls, free_vg);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_rem_lockspace_idm(ls, free_vg);
else
return -1;
if (act)
act->lm_rv = rv;
return rv;
}
static int lm_add_resource(struct lockspace *ls, struct resource *r)
{
int rv = -1;
if (ls->lm_type == LD_LM_DLM)
rv = lm_add_resource_dlm(ls, r, 0);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_add_resource_sanlock(ls, r);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_add_resource_idm(ls, r);
return rv;
}
static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct action *act,
struct val_blk *vb_out, int *retry, int adopt_only, int adopt_ok)
{
int rv;
int rv = -1;
if (ls->lm_type == LD_LM_DLM)
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt_only, adopt_ok);
@ -1110,8 +1119,6 @@ static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct ac
else if (ls->lm_type == LD_LM_IDM)
rv = lm_lock_idm(ls, r, mode, vb_out, act->lv_uuid,
&act->pvs, adopt_only, adopt_ok);
else
return -1;
if (act)
act->lm_rv = rv;
@ -1121,7 +1128,7 @@ static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct ac
static int lm_convert(struct lockspace *ls, struct resource *r,
int mode, struct action *act, uint32_t r_version)
{
int rv;
int rv = -1;
if (ls->lm_type == LD_LM_DLM)
rv = lm_convert_dlm(ls, r, mode, r_version);
@ -1129,8 +1136,6 @@ static int lm_convert(struct lockspace *ls, struct resource *r,
rv = lm_convert_sanlock(ls, r, mode, r_version);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_convert_idm(ls, r, mode, r_version);
else
return -1;
if (act)
act->lm_rv = rv;
@ -1140,7 +1145,7 @@ static int lm_convert(struct lockspace *ls, struct resource *r,
static int lm_unlock(struct lockspace *ls, struct resource *r, struct action *act,
uint32_t r_version, uint32_t lmu_flags)
{
int rv;
int rv = -1;
if (ls->lm_type == LD_LM_DLM)
rv = lm_unlock_dlm(ls, r, r_version, lmu_flags);
@ -1148,8 +1153,6 @@ static int lm_unlock(struct lockspace *ls, struct resource *r, struct action *ac
rv = lm_unlock_sanlock(ls, r, r_version, lmu_flags);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_unlock_idm(ls, r, r_version, lmu_flags);
else
return -1;
if (act)
act->lm_rv = rv;
@ -1177,12 +1180,12 @@ static void lm_rem_resource(struct lockspace *ls, struct resource *r)
lm_rem_resource_idm(ls, r);
}
static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size)
static int lm_find_free_lock(struct lockspace *ls, uint64_t lv_size_bytes)
{
if (ls->lm_type == LD_LM_DLM)
return 0;
else if (ls->lm_type == LD_LM_SANLOCK)
return lm_find_free_lock_sanlock(ls, free_offset, sector_size, align_size);
return lm_find_free_lock_sanlock(ls, lv_size_bytes);
else if (ls->lm_type == LD_LM_IDM)
return 0;
return -1;
@ -1413,7 +1416,7 @@ static int res_lock(struct lockspace *ls, struct resource *r, struct action *act
* It can be lost during dlm recovery when the master node
* is removed.
*
* If we're the next to write the lvb, reinitialze it to the
* If we're the next to write the lvb, reinitialize it to the
* new VG seqno, or a new GL counter larger than was seen by
* any hosts before (how to estimate that?)
*
@ -1678,20 +1681,32 @@ static int res_unlock(struct lockspace *ls, struct resource *r,
{
struct lock *lk;
uint32_t r_version;
int found_transient = 0;
int found_persistent = 0;
int rv;
if (act->flags & LD_AF_PERSISTENT) {
lk = find_lock_persistent(r);
if (lk)
goto do_unlock;
if (find_lock_client(r, act->client_id))
found_transient = 1;
} else {
lk = find_lock_client(r, act->client_id);
if (lk)
goto do_unlock;
if (find_lock_persistent(r))
found_persistent = 1;
}
if (act->op != LD_OP_CLOSE)
log_debug("%s:%s res_unlock cl %u no locks", ls->name, r->name, act->client_id);
if (act->op != LD_OP_CLOSE) {
if (found_transient)
log_debug("%s:%s res_unlock cl %u ENOENT (found transient)", ls->name, r->name, act->client_id);
else if (found_persistent)
log_debug("%s:%s res_unlock cl %u ENOENT (found persistent)", ls->name, r->name, act->client_id);
else
log_debug("%s:%s res_unlock cl %u ENOENT (no lock)", ls->name, r->name, act->client_id);
}
return -ENOENT;
do_unlock:
@ -1888,6 +1903,7 @@ static void res_process(struct lockspace *ls, struct resource *r,
{
struct action *act, *safe, *act_close;
struct lock *lk;
uint32_t unlock_by_client_id = 0;
int lm_retry;
int rv;
@ -1921,6 +1937,9 @@ static void res_process(struct lockspace *ls, struct resource *r,
if (rv == -ENOENT && (act->flags & LD_AF_UNLOCK_CANCEL))
rv = res_cancel(ls, r, act);
if (!rv && r->mode == LD_LK_UN)
unlock_by_client_id = act->client_id;
/*
* possible unlock results:
* 0: unlock succeeded
@ -1944,22 +1963,6 @@ static void res_process(struct lockspace *ls, struct resource *r,
res_cancel(ls, r, act_close);
}
/*
* handle freeing a lock for an lv that has been removed
*/
list_for_each_entry_safe(act, safe, &r->actions, list) {
if (act->op == LD_OP_FREE && act->rt == LD_RT_LV) {
log_debug("%s:%s free_lv", ls->name, r->name);
rv = free_lv(ls, r);
act->result = rv;
list_del(&act->list);
add_client_result(act);
goto r_free;
}
}
/*
* handle enable/disable
*/
@ -2103,6 +2106,7 @@ static void res_process(struct lockspace *ls, struct resource *r,
* be held for reading. If the T lock was sh, it would
* be converted to P ex. If the T/P modes matched, the
* lock could just be changed from T to P.
* Update: T->P is known to happen sometimes with LV locks.
*/
list_for_each_entry_safe(act, safe, &r->actions, list) {
@ -2121,6 +2125,7 @@ static void res_process(struct lockspace *ls, struct resource *r,
list_del(&act->list);
add_client_result(act);
} else {
log_debug("res_process %s change transient to persistent", r->name);
r->last_client_id = act->client_id;
lk->flags |= LD_LF_PERSISTENT;
lk->client_id = 0;
@ -2237,18 +2242,44 @@ static void res_process(struct lockspace *ls, struct resource *r,
}
}
/*
* In general, if the resource struct has no locks, no actions, and is
* unlocked, then it can be freed. (This is only needed for LV
* resources since LVs can be removed.) However, for lvremove (and
* vgremove, sometimes lvconvert), the command will send a free_lv op
* after unlocking. The free_lv op also needs the resource struct.
* So, rather than freeing it here, move the resource struct to the
* ls->dispose list. A free_lv op will find r on the dispose list, do
* free_lv, then free_resource. If the command closes its connection
* without doing free_lv (e.g. normal deactivation), then the structs
* that the client moved to the dispose list will all be freed when
* processing the OP_CLOSE for the client.
*/
if ((r->type == LD_RT_LV) && (r->mode == LD_LK_UN) &&
list_empty(&r->locks) && list_empty(&r->actions)) {
/* An implicit unlock of a transient lock. */
if (!unlock_by_client_id)
goto r_free;
log_debug("%s:%s will dispose for %u", ls->name, r->name, unlock_by_client_id);
list_del(&r->list);
r->dispose_client_id = unlock_by_client_id;
list_add(&r->list, &ls->dispose);
}
return;
r_free:
/* For the EUNATCH case it may be possible there are queued actions? */
list_for_each_entry_safe(act, safe, &r->actions, list) {
log_error("%s:%s res_process r_free cancel %s client %d",
log_error("%s:%s res_process r_free cancel %s client %u",
ls->name, r->name, op_str(act->op), act->client_id);
act->result = -ECANCELED;
list_del(&act->list);
add_client_result(act);
}
log_debug("%s:%s res_process free", ls->name, r->name);
log_debug("%s:%s res_process free_resource", ls->name, r->name);
lm_rem_resource(ls, r);
list_del(&r->list);
free_resource(r);
@ -2283,7 +2314,7 @@ static int for_each_lock(struct lockspace *ls, int locks_do)
return 0;
}
static int clear_locks(struct lockspace *ls, int free_vg, int drop_vg)
static void clear_locks(struct lockspace *ls, int free_vg, int drop_vg)
{
struct resource *r, *r_safe;
struct lock *lk, *lk_safe;
@ -2293,6 +2324,13 @@ static int clear_locks(struct lockspace *ls, int free_vg, int drop_vg)
int lk_count = 0;
int rv;
list_for_each_entry_safe(r, r_safe, &ls->dispose, list) {
log_debug("%s:%s clear_locks dispose free_resource", ls->name, r->name);
list_del(&r->list);
lm_rem_resource(ls, r);
free_resource(r);
}
list_for_each_entry_safe(r, r_safe, &ls->resources, list) {
lk_version = 0;
@ -2308,7 +2346,7 @@ static int clear_locks(struct lockspace *ls, int free_vg, int drop_vg)
if (lk->flags & LD_LF_PERSISTENT && !drop_vg)
log_error("%s:%s clear lock persistent", ls->name, r->name);
else
log_debug("%s:%s clear lock mode %s client %d", ls->name, r->name, mode_str(lk->mode), lk->client_id);
log_debug("%s:%s clear lock mode %s client %u", ls->name, r->name, mode_str(lk->mode), lk->client_id);
if (lk->version > lk_version)
lk_version = lk->version;
@ -2344,20 +2382,33 @@ static int clear_locks(struct lockspace *ls, int free_vg, int drop_vg)
}
list_for_each_entry_safe(act, act_safe, &r->actions, list) {
log_error("%s:%s clear_locks cancel %s client %d",
log_error("%s:%s clear_locks cancel %s client %u",
ls->name, r->name, op_str(act->op), act->client_id);
act->result = -ECANCELED;
list_del(&act->list);
add_client_result(act);
}
r_free:
log_debug("%s:%s free", ls->name, r->name);
log_debug("%s:%s clear_locks free_resource", ls->name, r->name);
lm_rem_resource(ls, r);
list_del(&r->list);
free_resource(r);
}
}
return lk_count;
static struct resource *find_dispose_act(struct lockspace *ls, struct action *act)
{
struct resource *r;
/* Only resources for unlocked LVs should exist on the dispose list. */
list_for_each_entry(r, &ls->dispose, list) {
if (r->type == LD_RT_LV && !strcmp(r->name, act->lv_uuid)) {
list_del(&r->list);
return r;
}
}
return NULL;
}
/*
@ -2495,6 +2546,8 @@ static void *lockspace_thread_main(void *arg_in)
int adopt_only = 0;
int adopt_ok = 0;
int wait_flag = 0;
int nodelay = 0;
int nocreate;
int retry;
int rv;
@ -2517,6 +2570,8 @@ static void *lockspace_thread_main(void *arg_in)
adopt_only = 1;
if (add_act->flags & LD_AF_ADOPT)
adopt_ok = 1;
if (add_act->flags & LD_AF_NODELAY)
nodelay = 1;
}
}
pthread_mutex_unlock(&ls->mutex);
@ -2546,7 +2601,7 @@ static void *lockspace_thread_main(void *arg_in)
* The actual lockspace join can take a while.
*/
if (!error) {
error = lm_add_lockspace(ls, add_act, adopt_only, adopt_ok);
error = lm_add_lockspace(ls, add_act, adopt_only, adopt_ok, nodelay);
log_debug("S %s lm_add_lockspace done %d", ls->name, error);
@ -2712,27 +2767,74 @@ static void *lockspace_thread_main(void *arg_in)
}
if (act->op == LD_OP_FIND_FREE_LOCK && act->rt == LD_RT_VG) {
uint64_t free_offset = 0;
int sector_size = 0;
int align_size = 0;
log_debug("S %s find free lock", ls->name);
rv = lm_find_free_lock(ls, &free_offset, &sector_size, &align_size);
log_debug("S %s find free lock %d offset %llu sector_size %d align_size %d",
ls->name, rv, (unsigned long long)free_offset, sector_size, align_size);
ls->free_lock_offset = free_offset;
ls->free_lock_sector_size = sector_size;
ls->free_lock_align_size = align_size;
rv = lm_find_free_lock(ls, act->lv_size_bytes);
log_debug("S %s find free lock %d offset %llu",
ls->name, rv, (unsigned long long)ls->free_lock_offset);
list_del(&act->list);
act->result = rv;
add_client_result(act);
continue;
}
if (act->op == LD_OP_FREE && act->rt == LD_RT_LV) {
list_del(&act->list);
r = find_dispose_act(ls, act); /* removes r from dispose list */
if (r) {
log_debug("%s:%s free_lv from dispose for %u", ls->name, r->name, act->client_id);
rv = free_lv(ls, r);
lm_rem_resource(ls, r);
free_resource(r);
act->result = rv;
add_client_result(act);
} else {
/* Happens when init_lv was called, but lock was never acquired. */
log_debug("%s:%s free_lv lock_args %s not found on dispose list",
ls->name, act->lv_uuid, act->lv_args);
if (!(r = alloc_resource())) {
rv = -ENOMEM;
} else {
dm_strncpy(r->name, act->lv_uuid, sizeof(r->name));
memcpy(r->lv_args, act->lv_args, MAX_ARGS);
r->type = LD_RT_LV;
r->mode = LD_LK_UN;
lm_add_resource(ls, r);
rv = free_lv(ls, r);
lm_rem_resource(ls, r);
free_resource(r);
}
act->result = rv;
add_client_result(act);
}
continue;
}
list_del(&act->list);
/* applies to all resources */
if (act->op == LD_OP_CLOSE) {
/*
* free any resources the client moved to
* ls->dispose after unlocking. Between the
* time the client unlocked the LV, and now,
* another client could have created a new
* struct resource on ls->resources for the
* same LV. This would not be a problem.
*/
list_for_each_entry_safe(r, r2, &ls->dispose, list) {
if (r->dispose_client_id == act->client_id) {
log_debug("%s:%s free_resource from dispose for %u",
ls->name, r->name, act->client_id);
list_del(&r->list);
lm_rem_resource(ls, r);
free_resource(r);
}
}
/*
* check all resources for transient locks the client
* was holding that should be automatically unlocked
*/
list_add(&act->list, &act_close);
continue;
}
@ -2745,10 +2847,12 @@ static void *lockspace_thread_main(void *arg_in)
* (This creates a new resource if the one named in
* the act is not found.)
*/
nocreate = (act->op == LD_OP_FREE) ||
((act->op == LD_OP_LOCK) && (act->mode == LD_LK_UN));
r = find_resource_act(ls, act, (act->op == LD_OP_FREE) ? 1 : 0);
r = find_resource_act(ls, act, nocreate);
if (!r) {
act->result = (act->op == LD_OP_FREE) ? -ENOENT : -ENOMEM;
act->result = nocreate ? -ENOENT : -ENOMEM;
add_client_result(act);
continue;
}
@ -2798,7 +2902,7 @@ out_rem:
* operating under the assumption that they hold the lock.
* drop_vg drops all existing locks, but should only
* happen when the VG access has been forcibly and
* succesfully terminated.
* successfully terminated.
*
* For vgremove of a sanlock vg, the vg lock will be held,
* and possibly the gl lock if this vg holds the gl.
@ -2807,7 +2911,7 @@ out_rem:
log_debug("S %s clearing locks", ls->name);
(void) clear_locks(ls, free_vg, drop_vg);
clear_locks(ls, free_vg, drop_vg);
/*
* Tell any other hosts in the lockspace to leave it
@ -3042,7 +3146,7 @@ static int add_lockspace_thread(const char *ls_name,
ls->start_client_id = act->client_id;
/*
* Copy PV list to lockspact structure, so this is
* Copy PV list to lockspace structure, so this is
* used for VG locking for idm scheme.
*/
if (lm_type == LD_LM_IDM &&
@ -3287,7 +3391,7 @@ static int add_lockspace(struct action *act)
/*
* vgchange --lock-stop vgname will lock the vg ex, then send a stop,
* so we exect to find the ex vg lock held here, and will automatically
* so we expect to find the ex vg lock held here, and will automatically
* unlock it when stopping.
*
* Should we attempt to stop the lockspace containing the gl last?
@ -3556,7 +3660,7 @@ static int work_init_vg(struct action *act)
}
if (act->lm_type == LD_LM_SANLOCK)
rv = lm_init_vg_sanlock(ls_name, act->vg_name, act->flags, act->vg_args);
rv = lm_init_vg_sanlock(ls_name, act->vg_name, act->flags, act->vg_args, act->align_mb);
else if (act->lm_type == LD_LM_DLM)
rv = lm_init_vg_dlm(ls_name, act->vg_name, act->flags, act->vg_args);
else if (act->lm_type == LD_LM_IDM)
@ -3622,9 +3726,6 @@ static int work_init_lv(struct action *act)
char ls_name[MAX_NAME+1];
char vg_args[MAX_ARGS+1];
char lv_args[MAX_ARGS+1];
uint64_t free_offset = 0;
int sector_size = 0;
int align_size = 0;
int lm_type = 0;
int rv = 0;
@ -3639,9 +3740,6 @@ static int work_init_lv(struct action *act)
if (ls) {
lm_type = ls->lm_type;
memcpy(vg_args, ls->vg_args, MAX_ARGS);
free_offset = ls->free_lock_offset;
sector_size = ls->free_lock_sector_size;
align_size = ls->free_lock_align_size;
}
pthread_mutex_unlock(&lockspaces_mutex);
@ -3657,9 +3755,9 @@ static int work_init_lv(struct action *act)
}
if (lm_type == LD_LM_SANLOCK) {
rv = lm_init_lv_sanlock(ls_name, act->vg_name, act->lv_uuid,
vg_args, lv_args, sector_size, align_size, free_offset);
/* ls is NULL if the lockspace is not started, which happens
for vgchange --locktype sanlock. */
rv = lm_init_lv_sanlock(ls, ls_name, act->vg_name, act->lv_uuid, vg_args, lv_args, act->prev_lv_args);
memcpy(act->lv_args, lv_args, MAX_ARGS);
return rv;
@ -4026,7 +4124,7 @@ static int client_send_result(struct client *cl, struct action *act)
* The lockspace could not be found, in which case
* the caller may want to know if any lockspaces exist
* or if lockspaces exist, but not one with the global lock.
* Given this detail, it may be able to procede without
* Given this detail, it may be able to proceed without
* the lock.
*/
pthread_mutex_lock(&lockspaces_mutex);
@ -4083,9 +4181,9 @@ static int client_send_result(struct client *cl, struct action *act)
if (act->lv_args[0])
lv_args = act->lv_args;
log_debug("send %s[%d] cl %u %s %s rv %d vg_args %s lv_args %s",
log_debug("send %s[%d][%u] %s%s%s result %d vg_args %s lv_args %s",
cl->name[0] ? cl->name : "client", cl->pid, cl->id,
op_str(act->op), rt_str(act->rt),
op_str(act->op), act->rt ? "_" : "", rt_str(act->rt),
act->result, vg_args ? vg_args : "", lv_args ? lv_args : "");
res = daemon_reply_simple("OK",
@ -4099,9 +4197,9 @@ static int client_send_result(struct client *cl, struct action *act)
} else if (act->op == LD_OP_QUERY_LOCK) {
log_debug("send %s[%d] cl %u %s %s rv %d mode %d",
log_debug("send %s[%d][%u] %s%s%s result %d mode %d",
cl->name[0] ? cl->name : "client", cl->pid, cl->id,
op_str(act->op), rt_str(act->rt),
op_str(act->op), act->rt ? "_" : "", rt_str(act->rt),
act->result, act->mode);
res = daemon_reply_simple("OK",
@ -4129,7 +4227,7 @@ static int client_send_result(struct client *cl, struct action *act)
else
act->result = -EINVAL;
log_debug("send %s[%d] cl %u dump result %d dump_len %d",
log_debug("send %s[%d][%u] dump result %d dump_len %d",
cl->name[0] ? cl->name : "client", cl->pid, cl->id,
act->result, dump_len);
@ -4142,9 +4240,9 @@ static int client_send_result(struct client *cl, struct action *act)
* A normal reply.
*/
log_debug("send %s[%d] cl %u %s %s rv %d %s %s",
log_debug("send %s[%d][%u] %s%s%s result %d %s %s",
cl->name[0] ? cl->name : "client", cl->pid, cl->id,
op_mode_str(act->op, act->mode), rt_str(act->rt),
op_mode_str(act->op, act->mode), act->rt ? "_" : "", rt_str(act->rt),
act->result, (act->result == -ENOLS) ? "ENOLS" : "", result_flags);
res = daemon_reply_simple("OK",
@ -4553,6 +4651,8 @@ static uint32_t str_to_opts(const char *str)
flags |= LD_AF_ENABLE;
if (strstr(str, "disable"))
flags |= LD_AF_DISABLE;
if (strstr(str, "nodelay"))
flags |= LD_AF_NODELAY;
/* FIXME: parse the flag values properly */
if (strstr(str, "adopt_only"))
@ -4667,7 +4767,6 @@ static int print_lockspace(struct lockspace *ls, const char *prefix, int pos, in
"ls_name=%s "
"vg_name=%s "
"vg_uuid=%s "
"vg_sysid=%s "
"vg_args=%s "
"lm_type=%s "
"host_id=%llu "
@ -4683,7 +4782,6 @@ static int print_lockspace(struct lockspace *ls, const char *prefix, int pos, in
ls->name,
ls->vg_name,
ls->vg_uuid,
ls->vg_sysid[0] ? ls->vg_sysid : ".",
ls->vg_args,
lm_str(ls->lm_type),
(unsigned long long)ls->host_id,
@ -4870,7 +4968,6 @@ static void client_recv_action(struct client *cl)
const char *cl_name;
const char *vg_name;
const char *vg_uuid;
const char *vg_sysid;
const char *path;
const char *str;
struct pvs pvs;
@ -4953,7 +5050,6 @@ static void client_recv_action(struct client *cl)
cl_pid = daemon_request_int(req, "pid", 0);
vg_name = daemon_request_str(req, "vg_name", NULL);
vg_uuid = daemon_request_str(req, "vg_uuid", NULL);
vg_sysid = daemon_request_str(req, "vg_sysid", NULL);
str = daemon_request_str(req, "mode", NULL);
mode = str_to_mode(str);
str = daemon_request_str(req, "opts", NULL);
@ -5004,9 +5100,6 @@ static void client_recv_action(struct client *cl)
if (vg_uuid && strcmp(vg_uuid, "none"))
memccpy(act->vg_uuid, vg_uuid, 0, 64);
if (vg_sysid && strcmp(vg_sysid, "none"))
dm_strncpy(act->vg_sysid, vg_sysid, sizeof(act->vg_sysid));
str = daemon_request_str(req, "lv_name", NULL);
if (str && strcmp(str, "none"))
strncpy(act->lv_name, str, MAX_NAME);
@ -5027,11 +5120,21 @@ static void client_recv_action(struct client *cl)
if (str && strcmp(str, "none"))
strncpy(act->lv_args, str, MAX_ARGS);
str = daemon_request_str(req, "prev_lv_args", NULL);
if (str && strcmp(str, "none"))
strncpy(act->prev_lv_args, str, MAX_ARGS);
/* start_vg will include lvmlocal.conf local/host_id here */
val = daemon_request_int(req, "host_id", 0);
if (val)
act->host_id = val;
val = daemon_request_int(req, "align_mb", 0);
if (val)
act->align_mb = val;
act->lv_size_bytes = (uint64_t)dm_config_find_int64(req.cft->root, "lv_size_bytes", 0);
/* Create PV list for idm */
if (lm == LD_LM_IDM) {
memset(&pvs, 0x0, sizeof(pvs));
@ -5071,9 +5174,16 @@ skip_pvs_path:
dm_config_destroy(req.cft);
buffer_destroy(&req.buffer);
log_debug("recv %s[%d] cl %u %s %s \"%s\" flags %x",
log_debug("recv %s[%d][%u] %s%s%s %s%s %s%s%s%s opts=%x",
cl->name[0] ? cl->name : "client", cl->pid, cl->id,
op_mode_str(act->op, act->mode), rt_str(act->rt), act->vg_name, opts);
op_mode_str(act->op, act->mode), act->rt ? "_" : "", rt_str(act->rt),
act->vg_name[0] ? "vg=" : "",
act->vg_name,
act->lv_name[0] || act->lv_uuid[0] ? "lv=" : "",
act->lv_name[0] ? act->lv_name : "",
act->lv_uuid[0] ? ":" : "",
act->lv_uuid[0] ? act->lv_uuid : "",
opts);
if (lm == LD_LM_DLM && !lm_support_dlm()) {
log_debug("dlm not supported");
@ -5529,6 +5639,9 @@ static void adopt_locks(void)
INIT_LIST_HEAD(&vg_lockd);
INIT_LIST_HEAD(&to_unlock);
if (daemon_test)
return;
/*
* Get list of lockspaces from currently running lock managers.
* Get list of shared VGs from file written by prior lvmlockd.
@ -6205,7 +6318,7 @@ static int main_loop(daemon_state *ds_arg)
setup_worker_thread();
setup_restart();
#ifdef USE_SD_NOTIFY
#ifdef SD_NOTIFY_SUPPORT
sd_notify(0, "READY=1");
#endif

View File

@ -13,7 +13,7 @@
#include "tools/tool.h"
#include "daemon-server.h"
#include "libdaemon/server/daemon-server.h"
#include "lib/mm/xlate.h"
#include "lvmlockd-internal.h"
@ -169,8 +169,10 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls)
struct lm_dlm *lmd;
int rv;
if (daemon_test)
if (daemon_test) {
log_debug("lm_prepare_lockspace_dlm test");
goto skip_args;
}
memset(sys_clustername, 0, sizeof(sys_clustername));
memset(arg_clustername, 0, sizeof(arg_clustername));
@ -361,7 +363,7 @@ int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
return 0;
}
static int lm_add_resource_dlm(struct lockspace *ls, struct resource *r, int with_lock_nl)
int lm_add_resource_dlm(struct lockspace *ls, struct resource *r, int with_lock_nl)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;

View File

@ -13,7 +13,7 @@
#include "tools/tool.h"
#include "daemon-server.h"
#include "libdaemon/server/daemon-server.h"
#include "lib/mm/xlate.h"
#include "lvmlockd-internal.h"
@ -136,7 +136,7 @@ static int lm_idm_scsi_directory_select(const struct dirent *s)
return 0;
}
static int lm_idm_scsi_find_block_dirctory(const char *block_path)
static int lm_idm_scsi_find_block_directory(const char *block_path)
{
struct stat stats;
@ -252,7 +252,7 @@ static char *lm_idm_scsi_get_block_device_node(const char *scsi_path)
goto fail;
}
ret = lm_idm_scsi_find_block_dirctory(blk_path);
ret = lm_idm_scsi_find_block_directory(blk_path);
if (ret < 0) {
log_error("Fail to find block path %s", blk_path);
goto fail;
@ -364,7 +364,7 @@ static void lm_idm_update_vb_timestamp(uint64_t *vb_timestamp)
/*
* It's possible that the multiple nodes have no clock
* synchronization with microsecond prcision and the time
* synchronization with microsecond precision and the time
* is going backward. For this case, simply increment the
* existing timestamp and write out to drive.
*/
@ -490,7 +490,7 @@ out:
return rv;
}
static int lm_add_resource_idm(struct lockspace *ls, struct resource *r)
int lm_add_resource_idm(struct lockspace *ls, struct resource *r)
{
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;

View File

@ -13,6 +13,9 @@
#include "base/memory/container_of.h"
#include <stdint.h>
#include <pthread.h>
#define MAX_NAME 64
#define MAX_ARGS 64
@ -113,6 +116,7 @@ struct client {
#define LD_AF_LV_UNLOCK 0x00080000
#define LD_AF_SH_EXISTS 0x00100000
#define LD_AF_ADOPT_ONLY 0x00200000 /* adopt orphan or fail */
#define LD_AF_NODELAY 0x00400000
/*
* Number of times to repeat a lock request after
@ -132,6 +136,7 @@ struct action {
uint32_t flags; /* LD_AF_ */
uint32_t version;
uint64_t host_id;
uint64_t lv_size_bytes;
int8_t op; /* operation type LD_OP_ */
int8_t rt; /* resource type LD_RT_ */
int8_t mode; /* lock mode LD_LK_ */
@ -140,6 +145,7 @@ struct action {
int max_retries;
int result;
int lm_rv; /* return value from lm_ function */
int align_mb;
char *path;
char vg_uuid[64];
char vg_name[MAX_NAME+1];
@ -147,7 +153,7 @@ struct action {
char lv_uuid[MAX_NAME+1];
char vg_args[MAX_ARGS+1];
char lv_args[MAX_ARGS+1];
char vg_sysid[MAX_NAME+1];
char prev_lv_args[MAX_ARGS+1];
struct pvs pvs; /* PV list for idm */
};
@ -160,6 +166,7 @@ struct resource {
unsigned int sh_count; /* number of sh locks on locks list */
uint32_t version;
uint32_t last_client_id; /* last client_id to lock or unlock resource */
uint32_t dispose_client_id; /* client_id disposing of resource struct */
unsigned int lm_init : 1; /* lm_data is initialized */
unsigned int adopt : 1; /* temp flag in remove_inactive_lvs */
unsigned int version_zero_valid : 1;
@ -186,13 +193,10 @@ struct lockspace {
char vg_name[MAX_NAME+1];
char vg_uuid[64];
char vg_args[MAX_ARGS+1]; /* lock manager specific args */
char vg_sysid[MAX_NAME+1];
int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
void *lm_data;
uint64_t host_id;
uint64_t free_lock_offset; /* for sanlock, start search for free lock here */
int free_lock_sector_size; /* for sanlock */
int free_lock_align_size; /* for sanlock */
struct pvs pvs; /* for idm: PV list */
uint32_t start_client_id; /* client_id that started the lockspace */
@ -212,6 +216,7 @@ struct lockspace {
struct list_head actions; /* new client actions */
struct list_head resources; /* resource/lock state for gl/vg/lv */
struct list_head dispose; /* resources to free */
};
/* val_blk version */
@ -278,15 +283,15 @@ static inline int list_empty(const struct list_head *head)
list_entry((ptr)->next, type, member)
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
for (pos = list_entry((head)->next, __typeof__(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
pos = list_entry(pos->member.next, __typeof__(*pos), member))
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
for (pos = list_entry((head)->next, __typeof__(*pos), member), \
n = list_entry(pos->member.next, __typeof__(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
pos = n, n = list_entry(n->member.next, __typeof__(*n), member))
/* to improve readability */
@ -397,6 +402,7 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls);
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt_only, int adopt_ok);
int lm_purge_locks_dlm(struct lockspace *ls);
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg);
int lm_add_resource_dlm(struct lockspace *ls, struct resource *r, int with_lock_nl);
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, int adopt_only, int adopt_ok);
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
@ -420,69 +426,102 @@ static inline int lm_support_dlm(void)
static inline int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_prepare_lockspace_dlm(struct lockspace *ls)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_add_lockspace_dlm(struct lockspace *ls, int adopt_only, int adopt_ok)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_purge_locks_dlm(struct lockspace *ls)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_add_resource_dlm(struct lockspace *ls, struct resource *r, int with_lock_nl)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, int adopt_only, int adopt_ok)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_convert_dlm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
uint32_t r_version, uint32_t lmu_flags)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_data_size_dlm(void)
{
if (daemon_test)
return 0;
return -1;
}
static inline int lm_is_running_dlm(void)
{
if (daemon_test)
return 1;
return 0;
}
static inline int lm_support_dlm(void)
{
if (daemon_test)
return 1;
return 0;
}
@ -505,13 +544,14 @@ static inline int lm_refresh_lv_check_dlm(struct action *act)
#ifdef LOCKDSANLOCK_SUPPORT
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, int sector_size, int align_size, uint64_t free_offset);
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb);
int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, char *prev_args);
int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r);
int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
int lm_prepare_lockspace_sanlock(struct lockspace *ls);
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok);
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok, int nodelay);
int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
int lm_add_resource_sanlock(struct lockspace *ls, struct resource *r);
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, int *retry,
int adopt_only, int adopt_ok);
@ -527,7 +567,7 @@ int lm_gl_is_enabled(struct lockspace *ls);
int lm_get_lockspaces_sanlock(struct list_head *ls_rejoin);
int lm_data_size_sanlock(void);
int lm_is_running_sanlock(void);
int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size);
int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes);
static inline int lm_support_sanlock(void)
{
@ -536,12 +576,12 @@ static inline int lm_support_sanlock(void)
#else
static inline int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
static inline int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb)
{
return -1;
}
static inline int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, int sector_size, int align_size, uint64_t free_offset)
static inline int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, char *prev_args)
{
return -1;
}
@ -561,7 +601,7 @@ static inline int lm_prepare_lockspace_sanlock(struct lockspace *ls)
return -1;
}
static inline int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok)
static inline int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok, int nodelay)
{
return -1;
}
@ -571,6 +611,11 @@ static inline int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
return -1;
}
static inline int lm_add_resource_sanlock(struct lockspace *ls, struct resource *r)
{
return -1;
}
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, int *retry,
int adopt_only, int adopt_ok)
@ -630,7 +675,7 @@ static inline int lm_is_running_sanlock(void)
return 0;
}
static inline int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size)
static inline int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes)
{
return -1;
}
@ -649,6 +694,7 @@ int lm_init_vg_idm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
int lm_prepare_lockspace_idm(struct lockspace *ls);
int lm_add_lockspace_idm(struct lockspace *ls, int adopt_only, int adopt_ok);
int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg);
int lm_add_resource_idm(struct lockspace *ls, struct resource *r);
int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
int adopt_only, int adopt_ok);
@ -694,6 +740,11 @@ static inline int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg)
return -1;
}
static inline int lm_add_resource_idm(struct lockspace *ls, struct resource *r)
{
return -1;
}
static inline int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
int adopt_only, int adopt_ok)

View File

@ -13,7 +13,7 @@
#include "tools/tool.h"
#include "daemon-server.h"
#include "libdaemon/server/daemon-server.h"
#include "lib/mm/xlate.h"
#include "lvmlockd-internal.h"
@ -24,11 +24,13 @@
#include "sanlock_admin.h"
#include "sanlock_resource.h"
/* FIXME: copied from sanlock header until the sanlock update is more widespread */
#define SANLK_ADD_NODELAY 0x00000002
#include <stddef.h>
#include <poll.h>
#include <errno.h>
#include <syslog.h>
#include <blkid/blkid.h>
#include <sys/sysmacros.h>
#define ONE_MB 1048576
@ -107,7 +109,7 @@ which:
1. Uses syslog to explain what is happening.
2. Notifies lvmlockd that the VG is being killed, so lvmlockd can
immediatley return an error for this condition if any new lock
immediately return an error for this condition if any new lock
requests are made. (This step would not be strictly necessary.)
3. Attempts to quit using the VG. This is not yet implemented, but
@ -137,7 +139,7 @@ release all the leases for the VG.
* from each pid: signals due to a sanlock_request, and
* acquire/release/convert/inquire. The later can probably be
* addressed with a flag to indicate that the pid field should be
* interpretted as 'ci' (which the caller would need to figure
* interpreted as 'ci' (which the caller would need to figure
* out somehow.)
*/
@ -146,14 +148,16 @@ struct lm_sanlock {
int sector_size;
int align_size;
int sock; /* sanlock daemon connection */
uint32_t ss_flags; /* sector and align flags for lockspace */
uint32_t rs_flags; /* sector and align flags for resource */
};
struct rd_sanlock {
struct val_blk *vb;
union {
struct sanlk_resource rs;
char buf[sizeof(struct sanlk_resource) + sizeof(struct sanlk_disk)];
};
struct val_blk *vb;
};
struct sanlk_resourced {
@ -294,8 +298,8 @@ static int read_host_id_file(void)
*sep = '\0';
memset(key_str, 0, sizeof(key_str));
memset(val_str, 0, sizeof(val_str));
(void) sscanf(key, "%s", key_str);
(void) sscanf(val, "%s", val_str);
(void) sscanf(key, "%63s", key_str);
(void) sscanf(val, "%63s", val_str);
if (!strcmp(key_str, "host_id")) {
host_id = atoi(val_str);
@ -340,14 +344,16 @@ fail:
return rv;
}
static void _read_sysfs_size(dev_t devno, const char *name, unsigned int *val)
static void _read_sysfs_size(dev_t devno, const char *name, uint64_t *val)
{
char path[PATH_MAX];
char buf[32];
FILE *fp;
size_t len;
snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/queue/%s",
*val = 0;
snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/%s",
(int)major(devno), (int)minor(devno), name);
if (!(fp = fopen(path, "r")))
@ -360,20 +366,19 @@ static void _read_sysfs_size(dev_t devno, const char *name, unsigned int *val)
buf[--len] = '\0';
if (strlen(buf))
*val = atoi(buf);
*val = strtoull(buf, NULL, 0);
out:
if (fclose(fp))
log_debug("Failed to fclose host id file %s (%s).", path, strerror(errno));
(void)fclose(fp);
}
/* Select sector/align size for a new VG based on what the device reports for
sector size of the lvmlock LV. */
static int get_sizes_device(char *path, int *sector_size, int *align_size)
static int get_sizes_device(char *path, uint64_t *dev_size, int *sector_size, int *align_size, int *align_mb)
{
unsigned int physical_block_size = 0;
unsigned int logical_block_size = 0;
uint64_t val;
struct stat st;
int rv;
@ -383,18 +388,26 @@ static int get_sizes_device(char *path, int *sector_size, int *align_size)
return -1;
}
_read_sysfs_size(st.st_rdev, "physical_block_size", &physical_block_size);
_read_sysfs_size(st.st_rdev, "logical_block_size", &logical_block_size);
_read_sysfs_size(st.st_rdev, "size", &val);
*dev_size = val * 512;
_read_sysfs_size(st.st_rdev, "queue/physical_block_size", &val);
physical_block_size = (unsigned int)val;
_read_sysfs_size(st.st_rdev, "queue/logical_block_size", &val);
logical_block_size = (unsigned int)val;
if ((physical_block_size == 512) && (logical_block_size == 512)) {
*sector_size = 512;
*align_size = ONE_MB;
*align_mb = 1;
return 0;
}
if ((physical_block_size == 4096) && (logical_block_size == 4096)) {
*sector_size = 4096;
*align_size = 8 * ONE_MB;
*align_mb = 8;
return 0;
}
@ -429,6 +442,7 @@ static int get_sizes_device(char *path, int *sector_size, int *align_size)
physical_block_size, logical_block_size, path);
*sector_size = 4096;
*align_size = 8 * ONE_MB;
*align_mb = 8;
return 0;
}
@ -437,18 +451,21 @@ static int get_sizes_device(char *path, int *sector_size, int *align_size)
physical_block_size, logical_block_size, path);
*sector_size = 4096;
*align_size = 8 * ONE_MB;
*align_mb = 8;
return 0;
}
if (physical_block_size == 512) {
*sector_size = 512;
*align_size = ONE_MB;
*align_mb = 1;
return 0;
}
if (physical_block_size == 4096) {
*sector_size = 4096;
*align_size = 8 * ONE_MB;
*align_mb = 8;
return 0;
}
@ -460,7 +477,8 @@ static int get_sizes_device(char *path, int *sector_size, int *align_size)
/* Get the sector/align sizes that were used to create an existing VG.
sanlock encoded this in the lockspace/resource structs on disk. */
static int get_sizes_lockspace(char *path, int *sector_size, int *align_size)
static int get_sizes_lockspace(char *path, int *sector_size, int *align_size, int *align_mb,
uint32_t *ss_flags, uint32_t *rs_flags)
{
struct sanlk_lockspace ss;
uint32_t io_timeout = 0;
@ -478,10 +496,38 @@ static int get_sizes_lockspace(char *path, int *sector_size, int *align_size)
if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN8M)) {
*sector_size = 4096;
*align_mb = 8;
*align_size = 8 * ONE_MB;
*ss_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M;
*rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M;
} else if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN4M)) {
*sector_size = 4096;
*align_mb = 4;
*align_size = 4 * ONE_MB;
*ss_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN4M;
*rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN4M;
} else if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN2M)) {
*sector_size = 4096;
*align_mb = 2;
*align_size = 2 * ONE_MB;
*ss_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN2M;
*rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN2M;
} else if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN1M)) {
*sector_size = 4096;
*align_mb = 1;
*align_size = ONE_MB;
*ss_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN1M;
*rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN1M;
} else if ((ss.flags & SANLK_LSF_SECTOR512) && (ss.flags & SANLK_LSF_ALIGN1M)) {
*sector_size = 512;
*align_mb = 1;
*align_size = ONE_MB;
*ss_flags = SANLK_LSF_SECTOR512 | SANLK_LSF_ALIGN1M;
*rs_flags = SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M;
}
log_debug("get_sizes_lockspace found %d %d", *sector_size, *align_size);
@ -498,7 +544,7 @@ static int get_sizes_lockspace(char *path, int *sector_size, int *align_size)
#define MAX_VERSION 16
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb)
{
struct sanlk_lockspace ss;
struct sanlk_resourced rd;
@ -506,11 +552,14 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
char lock_lv_name[MAX_ARGS+1];
char lock_args_version[MAX_VERSION+1];
const char *gl_name = NULL;
uint32_t rs_flags;
uint32_t daemon_version;
uint32_t daemon_proto;
uint64_t offset;
uint64_t dev_size;
int sector_size = 0;
int align_size = 0;
int align_mb = 0;
int i, rv;
memset(&ss, 0, sizeof(ss));
@ -535,7 +584,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
if ((rv = build_dm_path(disk.path, SANLK_PATH_LEN, vg_name, lock_lv_name)))
return rv;
log_debug("S %s init_vg_san path %s", ls_name, disk.path);
log_debug("S %s init_vg_san path %s align %d", ls_name, disk.path, opt_align_mb);
if (daemon_test) {
if (!gl_lsname_sanlock[0])
@ -556,7 +605,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
daemon_version, daemon_proto);
/* Nothing formatted on disk yet, use what the device reports. */
rv = get_sizes_device(disk.path, &sector_size, &align_size);
rv = get_sizes_device(disk.path, &dev_size, &sector_size, &align_size, &align_mb);
if (rv < 0) {
if (rv == -EACCES) {
log_error("S %s init_vg_san sanlock error -EACCES: no permission to access %s",
@ -569,11 +618,48 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
}
}
/* Non-default lease size is requested. */
if ((sector_size == 4096) && opt_align_mb && (opt_align_mb != 8)) {
if (opt_align_mb != 1 && opt_align_mb != 2 && opt_align_mb != 4) {
log_error("S %s init_vg_sanlock invalid align input %u", ls_name, opt_align_mb);
return -EARGS;
}
align_mb = opt_align_mb;
align_size = align_mb * ONE_MB;
}
log_debug("S %s init_vg_san %s dev_size %llu sector_size %u align_size %u",
ls_name, disk.path, (unsigned long long)dev_size, sector_size, align_size);
strcpy_name_len(ss.name, ls_name, SANLK_NAME_LEN);
memcpy(ss.host_id_disk.path, disk.path, SANLK_PATH_LEN);
ss.host_id_disk.offset = 0;
ss.flags = (sector_size == 4096) ? (SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M) :
(SANLK_LSF_SECTOR512 | SANLK_LSF_ALIGN1M);
if (sector_size == 512) {
ss.flags = SANLK_LSF_SECTOR512 | SANLK_LSF_ALIGN1M;
rs_flags = SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M;
} else if (sector_size == 4096) {
if (align_mb == 8) {
ss.flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M;
rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M;
} else if (align_mb == 4) {
ss.flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN4M;
rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN4M;
} else if (align_mb == 2) {
ss.flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN2M;
rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN2M;
} else if (align_mb == 1) {
ss.flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN1M;
rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN1M;
}
else {
log_error("Invalid sanlock align_size %d %d", align_size, align_mb);
return -EARGS;
}
} else {
log_error("Invalid sanlock sector_size %d", sector_size);
return -EARGS;
}
rv = sanlock_write_lockspace(&ss, 0, 0, sanlock_io_timeout);
if (rv < 0) {
@ -606,8 +692,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN);
rd.rs.disks[0].offset = align_size * GL_LOCK_BEGIN;
rd.rs.num_disks = 1;
rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rd.rs.flags = rs_flags;
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
if (rv < 0) {
@ -621,8 +706,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN);
rd.rs.disks[0].offset = align_size * VG_LOCK_BEGIN;
rd.rs.num_disks = 1;
rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rd.rs.flags = rs_flags;
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
if (rv < 0) {
@ -648,8 +732,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
memset(&rd, 0, sizeof(rd));
rd.rs.num_disks = 1;
rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rd.rs.flags = rs_flags;
memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN);
strcpy_name_len(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
strcpy_name_len(rd.rs.name, "#unused", SANLK_NAME_LEN);
@ -659,6 +742,9 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
log_debug("S %s init_vg_san clearing lv lease areas", ls_name);
for (i = 0; ; i++) {
if (dev_size && (offset + align_size > dev_size))
break;
rd.rs.disks[0].offset = offset;
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
@ -687,19 +773,39 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
* can be saved in the lv's lock_args in the vg metadata.
*/
int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
char *vg_args, char *lv_args,
int sector_size, int align_size, uint64_t free_offset)
int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, char *prev_args)
{
char disk_path[SANLK_PATH_LEN];
struct lm_sanlock *lms;
struct sanlk_resourced rd;
char lock_lv_name[MAX_ARGS+1];
char lock_args_version[MAX_VERSION+1];
uint64_t offset;
uint64_t prev_offset = 0;
int sector_size = 0;
int align_size = 0;
int align_mb;
uint32_t ss_flags;
uint32_t rs_flags = 0;
uint32_t tries = 1;
int rv;
memset(&rd, 0, sizeof(rd));
memset(lock_lv_name, 0, sizeof(lock_lv_name));
memset(lock_args_version, 0, sizeof(lock_args_version));
memset(disk_path, 0, sizeof(disk_path));
snprintf(lock_args_version, MAX_VERSION, "%u.%u.%u",
LV_LOCK_ARGS_MAJOR, LV_LOCK_ARGS_MINOR, LV_LOCK_ARGS_PATCH);
if (daemon_test) {
align_size = 1024 * 1024;
snprintf(lv_args, MAX_ARGS, "%s:%llu",
lock_args_version,
(unsigned long long)((align_size * LV_LOCK_BEGIN) + (align_size * daemon_test_lv_count)));
daemon_test_lv_count++;
return 0;
}
rv = lock_lv_name_from_args(vg_args, lock_lv_name);
if (rv < 0) {
@ -708,57 +814,47 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
return rv;
}
snprintf(lock_args_version, MAX_VERSION, "%u.%u.%u",
LV_LOCK_ARGS_MAJOR, LV_LOCK_ARGS_MINOR, LV_LOCK_ARGS_PATCH);
if ((rv = build_dm_path(disk_path, SANLK_PATH_LEN, vg_name, lock_lv_name))) {
log_error("S %s init_lv_san lock_lv_name path error %d %s",
ls_name, rv, vg_args);
return rv;
}
if (daemon_test) {
align_size = ONE_MB;
snprintf(lv_args, MAX_ARGS, "%s:%llu",
lock_args_version,
(unsigned long long)((align_size * LV_LOCK_BEGIN) + (align_size * daemon_test_lv_count)));
daemon_test_lv_count++;
return 0;
if (ls) {
lms = (struct lm_sanlock *)ls->lm_data;
align_size = lms->align_size;
rs_flags = lms->rs_flags;
offset = ls->free_lock_offset;
} else {
/* FIXME: optimize repeated init_lv for vgchange --locktype sanlock,
to avoid finding align_size/rs_flags each time. */
rv = get_sizes_lockspace(disk_path, &sector_size, &align_size, &align_mb, &ss_flags, &rs_flags);
if (rv < 0) {
log_error("S %s init_lv_san get_sizes error %d %s",
ls_name, rv, disk_path);
return rv;
}
/*
* With a prev offset, start search after that.
* Without a prev offset, start search from the beginning.
*/
if (prev_args && !lock_lv_offset_from_args(prev_args, &prev_offset))
offset = prev_offset + align_size;
else
offset = align_size * LV_LOCK_BEGIN;
}
if (offset < (align_size * LV_LOCK_BEGIN)) {
log_error("S %s init_lv_san invalid offset %llu", ls_name, (unsigned long long)offset);
return -1;
}
strcpy_name_len(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
rd.rs.num_disks = 1;
if ((rv = build_dm_path(rd.rs.disks[0].path, SANLK_PATH_LEN, vg_name, lock_lv_name)))
return rv;
/*
* These should not usually be zero, maybe only the first time this function is called?
* We need to use the same sector/align sizes that are already being used.
*/
if (!sector_size || !align_size) {
rv = get_sizes_lockspace(rd.rs.disks[0].path, &sector_size, &align_size);
if (rv < 0) {
log_error("S %s init_lv_san read_lockspace error %d %s",
ls_name, rv, rd.rs.disks[0].path);
return rv;
}
if (sector_size)
log_debug("S %s init_lv_san found ls sector_size %d align_size %d", ls_name, sector_size, align_size);
else {
/* use the old method */
align_size = sanlock_align(&rd.rs.disks[0]);
if (align_size <= 0) {
log_error("S %s init_lv_san align error %d", ls_name, align_size);
return -EINVAL;
}
sector_size = (align_size == ONE_MB) ? 512 : 4096;
log_debug("S %s init_lv_san found old sector_size %d align_size %d", ls_name, sector_size, align_size);
}
}
rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
if (free_offset)
offset = free_offset;
else
offset = align_size * LV_LOCK_BEGIN;
rd.rs.disks[0].offset = offset;
memcpy(rd.rs.disks[0].path, disk_path, SANLK_PATH_LEN-1);
rd.rs.flags = rs_flags;
while (1) {
rd.rs.disks[0].offset = offset;
@ -792,12 +888,11 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
* indicating an uninitialized paxos structure on disk.
*/
if ((rv == SANLK_LEADER_MAGIC) || !strcmp(rd.rs.name, "#unused")) {
log_debug("S %s init_lv_san %s found unused area at %llu",
ls_name, lv_name, (unsigned long long)offset);
log_debug("S %s init_lv_san %s found unused area at %llu try %u",
ls_name, lv_name, (unsigned long long)offset, tries);
strcpy_name_len(rd.rs.name, lv_name, SANLK_NAME_LEN);
rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rd.rs.flags = rs_flags;
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
if (!rv) {
@ -811,6 +906,7 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
}
offset += align_size;
tries++;
}
return rv;
@ -874,12 +970,19 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_
return rv;
}
if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN8M)) {
sector_size = 4096;
align_size = 8 * ONE_MB;
} else if ((ss.flags & SANLK_LSF_SECTOR512) && (ss.flags & SANLK_LSF_ALIGN1M)) {
if (ss.flags & SANLK_LSF_SECTOR512) {
sector_size = 512;
align_size = ONE_MB;
} else if (ss.flags & SANLK_LSF_SECTOR4K) {
sector_size = 4096;
if (ss.flags & SANLK_LSF_ALIGN8M)
align_size = 8 * ONE_MB;
else if (ss.flags & SANLK_LSF_ALIGN4M)
align_size = 4 * ONE_MB;
else if (ss.flags & SANLK_LSF_ALIGN2M)
align_size = 2 * ONE_MB;
else if (ss.flags & SANLK_LSF_ALIGN1M)
align_size = ONE_MB;
} else {
/* use the old method */
align_size = sanlock_align(&ss.host_id_disk);
@ -996,22 +1099,35 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_
int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r)
{
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
struct sanlk_resource *rs = &rds->rs;
uint64_t offset = rds->rs.disks[0].offset;
int rv;
log_debug("%s:%s free_lv_san", ls->name, r->name);
log_debug("%s:%s free_lv_san %llu", ls->name, r->name, (unsigned long long)offset);
if (daemon_test)
return 0;
strcpy_name_len(rs->name, "#unused", SANLK_NAME_LEN);
rv = sanlock_write_resource(rs, 0, 0, 0);
if (rv < 0) {
log_error("%s:%s free_lv_san write error %d",
ls->name, r->name, rv);
if (!offset) {
lock_lv_offset_from_args(r->lv_args, &offset);
rds->rs.disks[0].offset = offset;
log_debug("%s:%s free_lv_san lock_args offset %llu", ls->name, r->name, (unsigned long long)offset);
}
if (offset < (lms->align_size * LV_LOCK_BEGIN)) {
log_error("%s:%s free_lv_san invalid offset %llu",
ls->name, r->name, (unsigned long long)offset);
return -1;
}
rv = sanlock_write_resource(rs, 0, 0, 0);
if (rv < 0)
log_error("%s:%s free_lv_san %llu write error %d",
ls->name, r->name, (unsigned long long)offset, rv);
return rv;
}
@ -1048,10 +1164,8 @@ int lm_ex_disable_gl_sanlock(struct lockspace *ls)
memcpy(rd1.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
rd1.rs.disks[0].offset = lms->align_size * GL_LOCK_BEGIN;
rd1.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rd2.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rd1.rs.flags = lms->rs_flags;
rd2.rs.flags = lms->rs_flags;
rv = sanlock_acquire(lms->sock, -1, 0, 1, &rs1, NULL);
if (rv < 0) {
@ -1113,8 +1227,7 @@ int lm_able_gl_sanlock(struct lockspace *ls, int enable)
rd.rs.num_disks = 1;
memcpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
rd.rs.disks[0].offset = lms->align_size * GL_LOCK_BEGIN;
rd.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rd.rs.flags = lms->rs_flags;
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
if (rv < 0) {
@ -1198,32 +1311,27 @@ int lm_gl_is_enabled(struct lockspace *ls)
* been disabled.)
*/
int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size)
int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes)
{
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
struct sanlk_resourced rd;
uint64_t offset;
uint64_t start_offset;
uint32_t tries = 0;
int rv;
int round = 0;
if (daemon_test) {
*free_offset = (ONE_MB * LV_LOCK_BEGIN) + (ONE_MB * (daemon_test_lv_count + 1));
*sector_size = 512;
*align_size = ONE_MB;
ls->free_lock_offset = (ONE_MB * LV_LOCK_BEGIN) + (ONE_MB * (daemon_test_lv_count + 1));
return 0;
}
*sector_size = lms->sector_size;
*align_size = lms->align_size;
memset(&rd, 0, sizeof(rd));
strcpy_name_len(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
rd.rs.num_disks = 1;
memcpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
rd.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rd.rs.flags = lms->rs_flags;
if (ls->free_lock_offset)
offset = ls->free_lock_offset;
@ -1245,15 +1353,37 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *
memset(rd.rs.name, 0, SANLK_NAME_LEN);
/*
* End of the device. Older lvm versions didn't pass lv_size_bytes
* and just relied on sanlock_read_resource returning an error when
* reading beyond the device.
*/
if (lv_size_bytes && (offset + lms->align_size > lv_size_bytes)) {
/* end of the device */
log_debug("S %s find_free_lock_san read limit offset %llu lv_size_bytes %llu",
ls->name, (unsigned long long)offset, (unsigned long long)lv_size_bytes);
/* remember the NO SPACE offset, if no free area left,
* search from this offset after extend */
ls->free_lock_offset = offset;
offset = lms->align_size * LV_LOCK_BEGIN;
round = 1;
continue;
}
rv = sanlock_read_resource(&rd.rs, 0);
if (rv == -EMSGSIZE || rv == -ENOSPC) {
/* This indicates the end of the device is reached. */
/*
* These errors indicate the end of the device is reached.
* Still check this in case lv_size_bytes is not provided.
*/
log_debug("S %s find_free_lock_san read limit offset %llu",
ls->name, (unsigned long long)offset);
/* remember the NO SPACE offset, if no free area left,
* search from this offset after extend */
*free_offset = offset;
ls->free_lock_offset = offset;
offset = lms->align_size * LV_LOCK_BEGIN;
round = 1;
@ -1266,9 +1396,9 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *
* an invalid paxos structure on disk.
*/
if (rv == SANLK_LEADER_MAGIC) {
log_debug("S %s find_free_lock_san found empty area at %llu",
ls->name, (unsigned long long)offset);
*free_offset = offset;
log_debug("S %s find_free_lock_san found empty area at %llu try %u",
ls->name, (unsigned long long)offset, tries);
ls->free_lock_offset = offset;
return 0;
}
@ -1279,12 +1409,13 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *
}
if (!strcmp(rd.rs.name, "#unused")) {
log_debug("S %s find_free_lock_san found unused area at %llu",
ls->name, (unsigned long long)offset);
*free_offset = offset;
log_debug("S %s find_free_lock_san found unused area at %llu try %u",
ls->name, (unsigned long long)offset, tries);
ls->free_lock_offset = offset;
return 0;
}
tries++;
offset += lms->align_size;
}
@ -1323,8 +1454,11 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls)
char disk_path[SANLK_PATH_LEN];
char killpath[SANLK_PATH_LEN];
char killargs[SANLK_PATH_LEN];
uint32_t ss_flags = 0;
uint32_t rs_flags = 0;
int sector_size = 0;
int align_size = 0;
int align_mb = 0;
int gl_found;
int ret, rv;
@ -1412,6 +1546,8 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls)
strncpy(gl_lsname_sanlock, lsname, MAX_NAME);
log_debug("S %s prepare_lockspace_san use global lock", lsname);
}
lms->align_size = ONE_MB;
lms->sector_size = 512;
goto out;
}
@ -1439,7 +1575,7 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls)
goto fail;
}
rv = get_sizes_lockspace(disk_path, &sector_size, &align_size);
rv = get_sizes_lockspace(disk_path, &sector_size, &align_size, &align_mb, &ss_flags, &rs_flags);
if (rv < 0) {
log_error("S %s prepare_lockspace_san cannot get sector/align sizes %d", lsname, rv);
ret = -EMANAGER;
@ -1459,13 +1595,27 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls)
log_debug("S %s prepare_lockspace_san found old sector_size %d align_size %d", lsname, sector_size, align_size);
}
log_debug("S %s prepare_lockspace_san sizes %d %d", lsname, sector_size, align_size);
log_debug("S %s prepare_lockspace_san sector_size %d align_mb %d align_size %d",
lsname, sector_size, align_mb, align_size);
if (sector_size == 4096) {
if (((align_mb == 1) && (ls->host_id > 250)) ||
((align_mb == 2) && (ls->host_id > 500)) ||
((align_mb == 4) && (ls->host_id > 1000)) ||
((align_mb == 8) && (ls->host_id > 2000))) {
log_error("S %s prepare_lockspace_san invalid host_id %llu for align %d MiB",
lsname, (unsigned long long)ls->host_id, align_mb);
ret = -EHOSTID;
goto fail;
}
}
lms->align_size = align_size;
lms->sector_size = sector_size;
lms->ss_flags = ss_flags;
lms->rs_flags = rs_flags;
lms->ss.flags = (sector_size == 4096) ? (SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M) :
(SANLK_LSF_SECTOR512 | SANLK_LSF_ALIGN1M);
lms->ss.flags = ss_flags;
gl_found = gl_is_enabled(ls, lms);
if (gl_found < 0) {
@ -1501,9 +1651,10 @@ fail:
return ret;
}
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok)
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok, int nodelay)
{
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
uint32_t flags = 0;
int rv;
if (daemon_test) {
@ -1511,7 +1662,10 @@ int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok)
goto out;
}
rv = sanlock_add_lockspace_timeout(&lms->ss, 0, sanlock_io_timeout);
if (nodelay)
flags |= SANLK_ADD_NODELAY;
rv = sanlock_add_lockspace_timeout(&lms->ss, flags, sanlock_io_timeout);
if (rv == -EEXIST && (adopt_ok || adopt_only)) {
/* We could alternatively just skip the sanlock call for adopt. */
log_debug("S %s add_lockspace_san adopt found ls", ls->name);
@ -1598,7 +1752,7 @@ out:
return 0;
}
static int lm_add_resource_sanlock(struct lockspace *ls, struct resource *r)
int lm_add_resource_sanlock(struct lockspace *ls, struct resource *r)
{
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
@ -1607,7 +1761,7 @@ static int lm_add_resource_sanlock(struct lockspace *ls, struct resource *r)
strcpy_name_len(rds->rs.name, r->name, SANLK_NAME_LEN);
rds->rs.num_disks = 1;
memcpy(rds->rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN);
rds->rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
rds->rs.flags = lms->rs_flags;
if (r->type == LD_RT_GL)
rds->rs.disks[0].offset = GL_LOCK_BEGIN * lms->align_size;

View File

@ -15,8 +15,8 @@
#include "lvmpolld-common.h"
#include "lvm-version.h"
#include "daemon-server.h"
#include "daemon-log.h"
#include "libdaemon/server/daemon-server.h"
#include "libdaemon/server/daemon-log.h"
#include <getopt.h>
#include <poll.h>
@ -75,7 +75,7 @@ static void _usage(const char *prog, FILE *file)
" -p|--pidfile Set path to the pidfile\n"
" -s|--socket Set path to the communication socket\n"
" -B|--binary Path to lvm2 binary\n"
" -t|--timeout Time to wait in seconds before shutdown on idle (missing or 0 = inifinite)\n\n", prog, prog);
" -t|--timeout Time to wait in seconds before shutdown on idle (missing or 0 = infinite)\n\n", prog, prog);
}
static int _init(struct daemon_state *s)
@ -390,6 +390,11 @@ static void *fork_and_poll(void *args)
goto err;
}
if (!pdlv->cmdargv || !*(pdlv->cmdargv)) {
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "Missing command");
goto err;
}
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "cmd line arguments:");
debug_print(ls, pdlv->cmdargv);
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "---end---");

View File

@ -46,7 +46,7 @@ static char *_construct_lvm_system_dir_env(const char *sysdir)
* - or -
* just single char to store NULL byte
*/
size_t l = sysdir ? strlen(sysdir) + 16 : 1;
size_t l = sysdir ? strlen(sysdir) + sizeof(LVM_SYSTEM_DIR): 1;
char *env = (char *) malloc(l * sizeof(char));
if (!env)
@ -89,6 +89,17 @@ char *construct_id(const char *sysdir, const char *uuid)
return id;
}
static void _free_lvmpolld_lv(struct lvmpolld_lv *p)
{
free((void *)p->devicesfile);
free((void *)p->lvm_system_dir_env);
free((void *)p->lvmpolld_id);
free((void *)p->lvname);
free((void *)p->sinterval);
free((void *)p->cmdargv);
free((void *)p->cmdenvp);
}
struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
@ -96,30 +107,26 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
struct lvmpolld_store *pdst,
const char *devicesfile)
{
char *lvmpolld_id = strdup(id), /* copy */
*full_lvname = _construct_full_lvname(vgname, lvname), /* copy */
*lvm_system_dir_env = _construct_lvm_system_dir_env(sysdir); /* copy */
char *devicesfile_dup = devicesfile ? strdup(devicesfile) : NULL;
struct lvmpolld_lv tmp = {
.ls = ls,
.type = type,
.lvmpolld_id = lvmpolld_id,
.lvid = _get_lvid(lvmpolld_id, sysdir),
.lvname = full_lvname,
.devicesfile = devicesfile_dup,
.lvm_system_dir_env = lvm_system_dir_env,
.sinterval = strdup(sinterval), /* copy */
.lvmpolld_id = strdup(id),
.lvname = _construct_full_lvname(vgname, lvname),
.devicesfile = devicesfile ? strdup(devicesfile) : NULL,
.lvm_system_dir_env = _construct_lvm_system_dir_env(sysdir),
.sinterval = strdup(sinterval),
.pdtimeout = pdtimeout < MIN_POLLING_TIMEOUT ? MIN_POLLING_TIMEOUT : pdtimeout,
.cmd_state = { .retcode = -1, .signal = 0 },
.pdst = pdst,
.init_rq_count = 1
}, *pdlv = (struct lvmpolld_lv *) malloc(sizeof(struct lvmpolld_lv));
if (!pdlv || !tmp.lvid || !tmp.lvname || !tmp.lvm_system_dir_env || !tmp.sinterval)
if (!pdlv || !tmp.lvmpolld_id || !tmp.lvname || !tmp.lvm_system_dir_env || !tmp.sinterval)
goto err;
memcpy(pdlv, &tmp, sizeof(*pdlv));
tmp.lvid = _get_lvid(tmp.lvmpolld_id, sysdir),
*pdlv = tmp;
if (pthread_mutex_init(&pdlv->lock, NULL))
goto err;
@ -127,29 +134,20 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
return pdlv;
err:
free((void *)devicesfile_dup);
free((void *)full_lvname);
free((void *)lvmpolld_id);
free((void *)lvm_system_dir_env);
free((void *)tmp.sinterval);
free((void *)pdlv);
_free_lvmpolld_lv(&tmp);
free(pdlv);
return NULL;
}
void pdlv_destroy(struct lvmpolld_lv *pdlv)
{
free((void *)pdlv->lvmpolld_id);
free((void *)pdlv->devicesfile);
free((void *)pdlv->lvname);
free((void *)pdlv->sinterval);
free((void *)pdlv->lvm_system_dir_env);
free((void *)pdlv->cmdargv);
free((void *)pdlv->cmdenvp);
_free_lvmpolld_lv(pdlv);
pthread_mutex_destroy(&pdlv->lock);
free((void *)pdlv);
free(pdlv);
}
unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv)
@ -273,12 +271,12 @@ static void _pdlv_locked_dump(struct buffer *buff, const struct lvmpolld_lv *pdl
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tpolling_finished=%d\n", pdlv->polling_finished) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\terror_occured=%d\n", pdlv->error) > 0)
if (dm_snprintf(tmp, sizeof(tmp), "\t\terror_occurred=%d\n", pdlv->error) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tinit_requests_count=%d\n", pdlv->init_rq_count) > 0)
buffer_append(buff, tmp);
/* lvm_commmand-section { */
/* lvm_command-section { */
buffer_append(buff, "\t\tlvm_command {\n");
if (cmd_state->retcode == -1 && !cmd_state->signal)
buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_IN_PROGRESS "\"\n");
@ -290,7 +288,7 @@ static void _pdlv_locked_dump(struct buffer *buff, const struct lvmpolld_lv *pdl
buffer_append(buff, tmp);
}
buffer_append(buff, "\t\t}\n");
/* } lvm_commmand-section */
/* } lvm_command-section */
buffer_append(buff, "\t}\n");
/* } pdlv-section */

View File

@ -15,7 +15,10 @@
#ifndef _LVM_LVMPOLLD_DATA_UTILS_H
#define _LVM_LVMPOLLD_DATA_UTILS_H
#include "base/data-struct/hash.h"
#include <pthread.h>
#include <stdio.h>
struct buffer;
struct lvmpolld_state;
@ -68,7 +71,7 @@ struct lvmpolld_lv {
struct lvmpolld_cmd_stat cmd_state;
unsigned init_rq_count; /* for debugging purposes only */
unsigned polling_finished:1; /* no more updates */
unsigned error:1; /* unrecoverable error occured in lvmpolld */
unsigned error:1; /* unrecoverable error occurred in lvmpolld */
};
typedef void (*lvmpolld_parse_output_fn_t) (struct lvmpolld_lv *pdlv, const char *line);
@ -93,7 +96,7 @@ struct lvmpolld_thread_data {
struct lvmpolld_lv *pdlv;
};
char *construct_id(const char *sysdir, const char *lvid);
char *construct_id(const char *sysdir, const char *uuid);
/* LVMPOLLD_LV_T section */

View File

@ -45,7 +45,7 @@
#define LVMPD_RESP_OK "OK"
#define LVMPD_REAS_RETCODE "retcode" /* lvm cmd ret code */
#define LVMPD_REAS_SIGNAL "signal" /* lvm cmd terminating singal */
#define LVMPD_REAS_SIGNAL "signal" /* lvm cmd terminating signal */
#define LVMPD_RET_DUP_FAILED 100
#define LVMPD_RET_EXC_FAILED 101

View File

@ -191,7 +191,7 @@ struct dm_versions {
int dm_get_library_version(char *version, size_t size);
int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size);
int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi);
int dm_task_get_info(struct dm_task *dmt, struct dm_info *info);
/*
* This function returns dm device's UUID based on the value
@ -304,15 +304,15 @@ int dm_task_add_target(struct dm_task *dmt,
#define DM_FORMAT_DEV_BUFSIZE 13 /* Minimum bufsize to handle worst case. */
int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor);
/* Use this to retrive target information returned from a STATUS call */
/* Use this to retrieve target information returned from a STATUS call */
void *dm_get_next_target(struct dm_task *dmt,
void *next, uint64_t *start, uint64_t *length,
char **target_type, char **params);
/*
* Following dm_get_status_* functions will allocate approriate status structure
* Following dm_get_status_* functions will allocate appropriate status structure
* from passed mempool together with the necessary character arrays.
* Destroying the mempool will release all asociated allocation.
* Destroying the mempool will release all associated allocation.
*/
/* Parse params from STATUS call for mirror target */
@ -541,7 +541,7 @@ const char *dm_sysfs_dir(void);
/*
* Configure default UUID prefix string.
* Conventionally this is a short capitalised prefix indicating the subsystem
* Conventionally this is a short capitalized prefix indicating the subsystem
* that is managing the devices, e.g. "LVM-" or "MPATH-".
* To support stacks of devices from different subsystems, recursive functions
* stop recursing if they reach a device with a different prefix.
@ -584,7 +584,7 @@ int dm_device_has_mounted_fs(uint32_t major, uint32_t minor);
/*
* Callback is invoked for individal mountinfo lines,
* Callback is invoked for individual mountinfo lines,
* minor, major and mount target are parsed and unmangled.
*/
typedef int (*dm_mountinfo_line_callback_fn) (char *line, unsigned maj, unsigned min,
@ -698,7 +698,7 @@ void *dm_tree_node_get_context(const struct dm_tree_node *node);
/*
* Returns 0 when node size and its children is unchanged.
* Returns 1 when node or any of its children has increased size.
* Rerurns -1 when node or any of its children has reduced size.
* Returns -1 when node or any of its children has reduced size.
*/
int dm_tree_node_size_changed(const struct dm_tree_node *dnode);
@ -885,7 +885,7 @@ struct dm_tree_node_raid_params {
};
/*
* Version 2 of above node raid params struct to keeep API compatibility.
* Version 2 of above node raid params struct to keep API compatibility.
*
* Extended for more than 64 legs (max 253 in the MD kernel runtime!),
* delta_disks for disk add/remove reshaping,
@ -908,7 +908,7 @@ struct dm_tree_node_raid_params_v2 {
* 'rebuilds' and 'writemostly' are bitfields that signify
* which devices in the array are to be rebuilt or marked
* writemostly. The kernel supports up to 253 legs.
* We limit ourselvs by choosing a lower value
* We limit ourselves by choosing a lower value
* for DEFAULT_RAID_MAX_IMAGES.
*/
uint64_t rebuilds[RAID_BITMAP_SIZE];
@ -945,7 +945,7 @@ struct dm_config_node;
*
* policy_settings {
* migration_threshold=2048
* sequention_threashold=100
* sequential_threshold=100
* ...
* }
*
@ -1023,6 +1023,7 @@ struct integrity_settings {
uint32_t commit_time;
uint32_t bitmap_flush_interval;
uint64_t sectors_per_bit;
uint32_t allow_discards;
unsigned journal_sectors_set:1;
unsigned interleave_sectors_set:1;
@ -1031,6 +1032,7 @@ struct integrity_settings {
unsigned commit_time_set:1;
unsigned bitmap_flush_interval_set:1;
unsigned sectors_per_bit_set:1;
unsigned allow_discards_set:1;
};
int dm_tree_node_add_integrity_target(struct dm_tree_node *node,
@ -1049,7 +1051,7 @@ int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
const char *vdo_pool_name,
const char *data_uuid,
uint64_t data_size,
const struct dm_vdo_target_params *param);
const struct dm_vdo_target_params *vtp);
/*
* FIXME Add individual cache policy pairs <key> = value, like:
@ -1092,7 +1094,7 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
/* End of Replicator API */
/*
* FIXME: Defines bellow are based on kernel's dm-thin.c defines
* FIXME: Defines below are based on kernel's dm-thin.c defines
* DATA_DEV_BLOCK_SIZE_MIN_SECTORS (64 * 1024 >> SECTOR_SHIFT)
* DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT)
*/
@ -1158,7 +1160,7 @@ int dm_tree_node_set_thin_pool_error_if_no_space(struct dm_tree_node *node,
int dm_tree_node_set_thin_pool_read_only(struct dm_tree_node *node,
unsigned read_only);
/*
* FIXME: Defines bellow are based on kernel's dm-thin.c defines
* FIXME: Defines below are based on kernel's dm-thin.c defines
* MAX_DEV_ID ((1 << 24) - 1)
*/
#define DM_THIN_MAX_DEVICE_ID (UINT32_C((1 << 24) - 1))
@ -1176,9 +1178,9 @@ void dm_tree_node_set_presuspend_node(struct dm_tree_node *node,
struct dm_tree_node *presuspend_node);
int dm_tree_node_add_target_area(struct dm_tree_node *node,
const char *dev_name,
const char *dlid,
uint64_t offset);
const char *dev_name,
const char *uuid,
uint64_t offset);
/*
* Only for temporarily-missing raid devices where changes are tracked.
@ -1588,9 +1590,9 @@ int dm_fclose(FILE *stream);
* Pointer to the buffer is stored in *buf.
* Returns -1 on failure leaving buf undefined.
*/
int dm_asprintf(char **buf, const char *format, ...)
int dm_asprintf(char **result, const char *format, ...)
__attribute__ ((format(printf, 2, 3)));
int dm_vasprintf(char **buf, const char *format, va_list ap)
int dm_vasprintf(char **result, const char *format, va_list aq)
__attribute__ ((format(printf, 2, 0)));
/*
@ -1939,7 +1941,7 @@ void dm_report_free(struct dm_report *rh);
* Prefix added to each field name with DM_REPORT_OUTPUT_FIELD_NAME_PREFIX
*/
int dm_report_set_output_field_name_prefix(struct dm_report *rh,
const char *report_prefix);
const char *output_field_name_prefix);
int dm_report_set_selection(struct dm_report *rh, const char *selection);
@ -2032,6 +2034,7 @@ struct dm_config_tree *dm_config_create(void);
struct dm_config_tree *dm_config_from_string(const char *config_settings);
int dm_config_parse(struct dm_config_tree *cft, const char *start, const char *end);
int dm_config_parse_without_dup_node_check(struct dm_config_tree *cft, const char *start, const char *end);
int dm_config_parse_only_section(struct dm_config_tree *cft, const char *start, const char *end, const char *section);
void *dm_config_get_custom(struct dm_config_tree *cft);
void dm_config_set_custom(struct dm_config_tree *cft, void *custom);
@ -2056,7 +2059,7 @@ void dm_config_destroy(struct dm_config_tree *cft);
/* Simple output line by line. */
typedef int (*dm_putline_fn)(const char *line, void *baton);
/* More advaced output with config node reference. */
/* More advanced output with config node reference. */
typedef int (*dm_config_node_out_fn)(const struct dm_config_node *cn, const char *line, void *baton);
/*
@ -2078,7 +2081,7 @@ int dm_config_write_one_node_out(const struct dm_config_node *cn, const struct d
struct dm_config_node *dm_config_find_node(const struct dm_config_node *cn, const char *path);
int dm_config_has_node(const struct dm_config_node *cn, const char *path);
int dm_config_remove_node(struct dm_config_node *parent, struct dm_config_node *remove);
int dm_config_remove_node(struct dm_config_node *parent, struct dm_config_node *rem_node);
const char *dm_config_find_str(const struct dm_config_node *cn, const char *path, const char *fail);
const char *dm_config_find_str_allow_empty(const struct dm_config_node *cn, const char *path, const char *fail);
int dm_config_find_int(const struct dm_config_node *cn, const char *path, int fail);
@ -2110,7 +2113,7 @@ unsigned dm_config_maybe_section(const char *str, unsigned len);
const char *dm_config_parent_name(const struct dm_config_node *n);
struct dm_config_node *dm_config_clone_node_with_mem(struct dm_pool *mem, const struct dm_config_node *node, int siblings);
struct dm_config_node *dm_config_clone_node_with_mem(struct dm_pool *mem, const struct dm_config_node *cn, int siblings);
struct dm_config_node *dm_config_create_node(struct dm_config_tree *cft, const char *key);
struct dm_config_value *dm_config_create_value(struct dm_config_tree *cft);
struct dm_config_node *dm_config_clone_node(struct dm_config_tree *cft, const struct dm_config_node *cn, int siblings);
@ -2119,7 +2122,7 @@ struct dm_config_node *dm_config_clone_node(struct dm_config_tree *cft, const st
* Common formatting flags applicable to all config node types (lower 16 bits).
*/
#define DM_CONFIG_VALUE_FMT_COMMON_ARRAY 0x00000001 /* value is array */
#define DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES 0x00000002 /* add spaces in "key = value" pairs in constrast to "key=value" for better readability */
#define DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES 0x00000002 /* add spaces in "key = value" pairs in contrast to "key=value" for better readability */
/*
* Type-related config node formatting flags (higher 16 bits).
@ -2165,7 +2168,7 @@ struct dm_pool *dm_config_memory(struct dm_config_tree *cft);
*/
#define DM_UDEV_DISABLE_DM_RULES_FLAG 0x0001
/*
* DM_UDEV_DISABLE_SUBSYTEM_RULES_FLAG is set in case we need to disable
* DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG is set in case we need to disable
* subsystem udev rules, but still we need the general DM udev rules to
* be applied (to create the nodes and symlinks under /dev and /dev/disk).
*/

View File

@ -70,6 +70,7 @@ static unsigned _dm_version_minor = 0;
static unsigned _dm_version_patchlevel = 0;
static int _log_suppress = 0;
static struct dm_timestamp *_dm_ioctl_timestamp = NULL;
static int _dm_warn_inactive_suppress = 0;
/*
* If the kernel dm driver only supports one major number
@ -485,7 +486,7 @@ static void _dm_zfree_string(char *string)
{
if (string) {
memset(string, 0, strlen(string));
asm volatile ("" ::: "memory"); /* Compiler barrier. */
__asm__ volatile ("" ::: "memory"); /* Compiler barrier. */
free(string);
}
}
@ -494,7 +495,7 @@ static void _dm_zfree_dmi(struct dm_ioctl *dmi)
{
if (dmi) {
memset(dmi, 0, dmi->data_size);
asm volatile ("" ::: "memory"); /* Compiler barrier. */
__asm__ volatile ("" ::: "memory"); /* Compiler barrier. */
free(dmi);
}
}
@ -659,7 +660,7 @@ void *dm_get_next_target(struct dm_task *dmt, void *next,
return t->next;
}
/* Unmarshall the target info returned from a status call */
/* Unmarshal the target info returned from a status call */
static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi)
{
char *outbuf = (char *) dmi + dmi->data_start;
@ -1412,22 +1413,23 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
}
if (dmt->query_inactive_table) {
if (!_dm_inactive_supported())
log_warn("WARNING: Inactive table query unsupported "
"by kernel. It will use live table.");
log_warn_suppress(_dm_warn_inactive_suppress++,
"WARNING: Inactive table query unsupported by kernel. "
"It will use live table.");
dmi->flags |= DM_QUERY_INACTIVE_TABLE_FLAG;
}
if (dmt->new_uuid) {
if (_dm_version_minor < 19) {
log_error("WARNING: Setting UUID unsupported by "
"kernel. Aborting operation.");
log_error("Setting UUID unsupported by kernel. "
"Aborting operation.");
goto bad;
}
dmi->flags |= DM_UUID_FLAG;
}
if (dmt->ima_measurement) {
if (_dm_version_minor < 45) {
log_error("WARNING: IMA measurement unsupported by "
"kernel. Aborting operation.");
log_error("IMA measurement unsupported by kernel. "
"Aborting operation.");
goto bad;
}
dmi->flags |= DM_IMA_MEASUREMENT_FLAG;

View File

@ -16,6 +16,8 @@
#ifndef LIB_DMTARGETS_H
#define LIB_DMTARGETS_H
#include "device_mapper/all.h"
#include <inttypes.h>
#include <sys/types.h>

View File

@ -511,7 +511,7 @@ int unmangle_string(const char *str, const char *str_name, size_t len,
char *buf, size_t buf_len, dm_string_mangling_t mode)
{
int strict = mode != DM_STRING_MANGLING_NONE;
char str_rest[DM_NAME_LEN];
char str_rest[DM_NAME_LEN + 1];
size_t i, j;
unsigned int code;
int r = 0;
@ -1796,7 +1796,7 @@ static int _mountinfo_parse_line(const char *line, unsigned *maj, unsigned *min,
}
/*
* Function to operate on individal mountinfo line,
* Function to operate on individual mountinfo line,
* minor, major and mount target are parsed and unmangled
*/
int dm_mountinfo_read(dm_mountinfo_line_callback_fn read_fn, void *cb_data)
@ -1961,7 +1961,7 @@ static int _sysfs_find_kernel_name(uint32_t major, uint32_t minor, char *buf, si
!strcmp(name_dev, "holders") ||
!strcmp(name_dev, "integrity") ||
!strcmp(name_dev, "loop") ||
!strcmp(name_dev, "queueu") ||
!strcmp(name_dev, "queue") ||
!strcmp(name_dev, "md") ||
!strcmp(name_dev, "mq") ||
!strcmp(name_dev, "power") ||
@ -2416,7 +2416,7 @@ static int _get_cookie_sem(uint32_t cookie, int *semid)
break;
case EACCES:
log_error("No permission to access "
"notificaton semaphore identified "
"notification semaphore identified "
"by cookie value %" PRIu32 " (0x%x)",
cookie, cookie);
break;
@ -2437,20 +2437,20 @@ static int _udev_notify_sem_inc(uint32_t cookie, int semid)
int val;
if (semop(semid, &sb, 1) < 0) {
log_error("semid %d: semop failed for cookie 0x%" PRIx32 ": %s",
log_error("cookie inc: semid %d: semop failed for cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
return 0;
}
if ((val = semctl(semid, 0, GETVAL)) < 0) {
log_error("semid %d: sem_ctl GETVAL failed for "
log_warn("cookie inc: semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
return 0;
}
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
cookie, semid, val);
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented.",
cookie, semid);
} else
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
cookie, semid, val);
return 1;
}
@ -2460,23 +2460,21 @@ static int _udev_notify_sem_dec(uint32_t cookie, int semid)
struct sembuf sb = {0, -1, IPC_NOWAIT};
int val;
if ((val = semctl(semid, 0, GETVAL)) < 0) {
log_error("semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
return 0;
}
if ((val = semctl(semid, 0, GETVAL)) < 0)
log_warn("cookie dec: semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
if (semop(semid, &sb, 1) < 0) {
switch (errno) {
case EAGAIN:
log_error("semid %d: semop failed for cookie "
log_error("cookie dec: semid %d: semop failed for cookie "
"0x%" PRIx32 ": "
"incorrect semaphore state",
semid, cookie);
break;
default:
log_error("semid %d: semop failed for cookie "
log_error("cookie dec: semid %d: semop failed for cookie "
"0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
break;
@ -2484,9 +2482,12 @@ static int _udev_notify_sem_dec(uint32_t cookie, int semid)
return 0;
}
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) decremented to %d",
cookie, semid, val - 1);
if (val < 0)
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) decremented.",
cookie, semid);
else
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) decremented to %d",
cookie, semid, val - 1);
return 1;
}
@ -2563,7 +2564,7 @@ static int _udev_notify_sem_create(uint32_t *cookie, int *semid)
sem_arg.val = 1;
if (semctl(gen_semid, 0, SETVAL, sem_arg) < 0) {
log_error("semid %d: semctl failed: %s", gen_semid, strerror(errno));
log_error("cookie create: semid %d: semctl failed: %s", gen_semid, strerror(errno));
/* We have to destroy just created semaphore
* so it won't stay in the system. */
(void) _udev_notify_sem_destroy(gen_cookie, gen_semid);
@ -2571,9 +2572,10 @@ static int _udev_notify_sem_create(uint32_t *cookie, int *semid)
}
if ((val = semctl(gen_semid, 0, GETVAL)) < 0) {
log_error("semid %d: sem_ctl GETVAL failed for "
log_error("cookie create: semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
gen_semid, gen_cookie, strerror(errno));
(void) _udev_notify_sem_destroy(gen_cookie, gen_semid);
goto bad;
}

View File

@ -36,7 +36,7 @@ struct target *create_target(uint64_t start,
uint64_t len,
const char *type, const char *params);
int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major,
int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
uid_t uid, gid_t gid, mode_t mode, int check_udev, unsigned rely_on_udev);
int rm_dev_node(const char *dev_name, int check_udev, unsigned rely_on_udev);
int rename_dev_node(const char *old_name, const char *new_name,

View File

@ -53,6 +53,8 @@ struct parser {
int no_dup_node_check; /* whether to disable dup node checking */
const char *key; /* last obtained key */
unsigned ignored_creation_time;
unsigned section_indent;
const char *stop_after_section;
};
struct config_output {
@ -70,7 +72,8 @@ static struct dm_config_value *_value(struct parser *p);
static struct dm_config_value *_type(struct parser *p);
static int _match_aux(struct parser *p, int t);
static struct dm_config_value *_create_value(struct dm_pool *mem);
static struct dm_config_node *_create_node(struct dm_pool *mem);
static struct dm_config_value *_create_str_value(struct dm_pool *mem, const char *str, size_t str_len);
static struct dm_config_node *_create_node(struct dm_pool *mem, const char *key, size_t key_len);
static char *_dup_tok(struct parser *p);
static char *_dup_token(struct dm_pool *mem, const char *b, const char *e);
@ -84,20 +87,24 @@ static char *_dup_token(struct dm_pool *mem, const char *b, const char *e);
} \
} while(0)
/* match token */
static int _tok_match(const char *str, const char *b, const char *e)
{
while (*str && (b != e)) {
if (*str++ != *b++)
while (b < e) {
if (!*str ||
(*str != *b))
return 0;
++str;
++b;
}
return !(*str || (b != e));
return !*str; /* token is matching for \0 end */
}
struct dm_config_tree *dm_config_create(void)
{
struct dm_config_tree *cft;
struct dm_pool *mem = dm_pool_create("config", 10 * 1024);
struct dm_pool *mem = dm_pool_create("config", 63 * 1024);
if (!mem) {
log_error("Failed to allocate config pool.");
@ -171,7 +178,8 @@ static struct dm_config_node *_config_reverse(struct dm_config_node *head)
return middle;
}
static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, const char *end, int no_dup_node_check)
static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, const char *end,
int no_dup_node_check, const char *section)
{
/* TODO? if (start == end) return 1; */
@ -182,6 +190,7 @@ static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, co
.fb = start,
.fe = end,
.line = 1,
.stop_after_section = section,
.no_dup_node_check = no_dup_node_check
};
@ -196,12 +205,23 @@ static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, co
int dm_config_parse(struct dm_config_tree *cft, const char *start, const char *end)
{
return _do_dm_config_parse(cft, start, end, 0);
return _do_dm_config_parse(cft, start, end, 0, NULL);
}
int dm_config_parse_without_dup_node_check(struct dm_config_tree *cft, const char *start, const char *end)
{
return _do_dm_config_parse(cft, start, end, 1);
return _do_dm_config_parse(cft, start, end, 1, NULL);
}
/*
* Stop parsing more sections after given section is parsed.
* Only non-section config nodes are then still parsed.
* It can be useful, when parsing i.e. lvm2 metadata and only physical_volumes config node is needed.
* This function is automatically running without_dup_node_check.
*/
int dm_config_parse_only_section(struct dm_config_tree *cft, const char *start, const char *end, const char *section)
{
return _do_dm_config_parse(cft, start, end, 1, section);
}
struct dm_config_tree *dm_config_from_string(const char *config_settings)
@ -467,23 +487,33 @@ int dm_config_write_node_out(const struct dm_config_node *cn,
/*
* parser
*/
static char *_dup_string_tok(struct parser *p)
static const char *_string_tok(struct parser *p, size_t *len)
{
char *str;
ptrdiff_t d = p->te - p->tb;
p->tb++, p->te--; /* strip "'s */
if (p->te < p->tb) {
if (d < 2) {
log_error("Parse error at byte %" PRIptrdiff_t " (line %d): "
"expected a string token.",
p->tb - p->fb + 1, p->line);
return NULL;
}
if (!(str = _dup_tok(p)))
*len = (size_t)(d - 2); /* strip "'s */
return p->tb + 1;
}
static char *_dup_string_tok(struct parser *p)
{
const char *tok;
size_t len;
char *str;
if (!(tok = _string_tok(p, &len)))
return_NULL;
p->te++;
if (!(str = _dup_token(p->mem, tok, tok + len)))
return_NULL;
return str;
}
@ -505,10 +535,9 @@ static struct dm_config_node *_make_node(struct dm_pool *mem,
{
struct dm_config_node *n;
if (!(n = _create_node(mem)))
if (!(n = _create_node(mem, key_b, key_e - key_b)))
return_NULL;
n->key = _dup_token(mem, key_b, key_e);
if (parent) {
n->parent = parent;
n->sib = parent->child;
@ -578,6 +607,8 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
struct dm_config_node *root;
struct dm_config_value *value;
char *str;
size_t len;
char buf[8192];
if (p->t == TOK_STRING_ESCAPED) {
if (!(str = _dup_string_tok(p)))
@ -591,9 +622,16 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
match(TOK_STRING);
} else {
if (!(str = _dup_tok(p)))
return_NULL;
len = p->te - p->tb;
if (len < (sizeof(buf) - 1)) {
/* Use stack for smaller string */
str = buf;
memcpy(str, p->tb, len);
str[len] = '\0';
} else {
if (!(str = _dup_tok(p)))
return_NULL;
}
match(TOK_IDENTIFIER);
}
@ -607,12 +645,28 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
return_NULL;
if (p->t == TOK_SECTION_B) {
if (p->stop_after_section)
++p->section_indent;
match(TOK_SECTION_B);
while (p->t != TOK_SECTION_E) {
if (!(_section(p, root)))
return_NULL;
}
match(TOK_SECTION_E);
if (p->stop_after_section && (--p->section_indent == 1)) {
if (!strcmp(str, p->stop_after_section)) {
/* Found stopping section name -> parsing is finished.
* Now try to find the sequence "\n}\n" from end of b
* parsed buffer to continue filling remaining nodes */
for (p->te = p->fe - 1; p->te > p->tb; --p->te)
if ((p->te[-2] == '\n') &&
(p->te[-1] == '}') &&
(p->te[ 0] == '\n')) {
p->t = TOK_SECTION_E;
break;
}
}
}
} else {
match(TOK_EQ);
p->key = root->key;
@ -669,16 +723,14 @@ static struct dm_config_value *_value(struct parser *p)
static struct dm_config_value *_type(struct parser *p)
{
/* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */
struct dm_config_value *v = _create_value(p->mem);
char *str;
if (!v) {
log_error("Failed to allocate type value");
return NULL;
}
struct dm_config_value *v;
const char *str;
size_t len;
switch (p->t) {
case TOK_INT:
if (!(v = _create_value(p->mem)))
break;
v->type = DM_CFG_INT;
errno = 0;
v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */
@ -699,6 +751,8 @@ static struct dm_config_value *_type(struct parser *p)
break;
case TOK_FLOAT:
if (!(v = _create_value(p->mem)))
break;
v->type = DM_CFG_FLOAT;
errno = 0;
v->v.f = strtod(p->tb, NULL); /* FIXME: check error */
@ -710,31 +764,31 @@ static struct dm_config_value *_type(struct parser *p)
break;
case TOK_STRING:
v->type = DM_CFG_STRING;
if (!(v->v.str = _dup_string_tok(p)))
if (!(str = _string_tok(p, &len)))
return_NULL;
match(TOK_STRING);
if ((v = _create_str_value(p->mem, str, len))) {
v->type = DM_CFG_STRING;
match(TOK_STRING);
}
break;
case TOK_STRING_BARE:
v->type = DM_CFG_STRING;
if (!(v->v.str = _dup_tok(p)))
return_NULL;
match(TOK_STRING_BARE);
if ((v = _create_str_value(p->mem, p->tb, p->te - p->tb))) {
v->type = DM_CFG_STRING;
match(TOK_STRING_BARE);
}
break;
case TOK_STRING_ESCAPED:
v->type = DM_CFG_STRING;
if (!(str = _dup_string_tok(p)))
if (!(str = _string_tok(p, &len)))
return_NULL;
dm_unescape_double_quotes(str);
v->v.str = str;
match(TOK_STRING_ESCAPED);
if ((v = _create_str_value(p->mem, str, len))) {
v->type = DM_CFG_STRING;
dm_unescape_double_quotes((char*)v->v.str);
match(TOK_STRING_ESCAPED);
}
break;
default:
@ -742,6 +796,12 @@ static struct dm_config_value *_type(struct parser *p)
p->tb - p->fb + 1, p->line);
return NULL;
}
if (!v) {
log_error("Failed to allocate type value.");
return NULL;
}
return v;
}
@ -759,60 +819,52 @@ static int _match_aux(struct parser *p, int t)
*/
static void _get_token(struct parser *p, int tok_prev)
{
int values_allowed = 0;
/* Should next token be interpreted as value instead of identifier? */
const int values_allowed = (tok_prev == TOK_EQ ||
tok_prev == TOK_ARRAY_B ||
tok_prev == TOK_COMMA);
const char *te;
char c;
p->tb = p->te;
_eat_space(p);
if (p->tb == p->fe || !*p->tb) {
if (p->tb == p->fe ||
!((c = *p->tb))) {
p->t = TOK_EOF;
return;
}
/* Should next token be interpreted as value instead of identifier? */
if (tok_prev == TOK_EQ || tok_prev == TOK_ARRAY_B ||
tok_prev == TOK_COMMA)
values_allowed = 1;
p->t = TOK_INT; /* fudge so the fall through for
floats works */
te = p->te + 1; /* next character */
te = p->te;
switch (*te) {
switch (c) {
case SECTION_B_CHAR:
p->t = TOK_SECTION_B;
te++;
break;
case SECTION_E_CHAR:
p->t = TOK_SECTION_E;
te++;
break;
case '[':
p->t = TOK_ARRAY_B;
te++;
break;
case ']':
p->t = TOK_ARRAY_E;
te++;
break;
case ',':
p->t = TOK_COMMA;
te++;
break;
case '=':
p->t = TOK_EQ;
te++;
break;
case '"':
p->t = TOK_STRING_ESCAPED;
te++;
while ((te != p->fe) && (*te) && (*te != '"')) {
if ((*te == '\\') && (te + 1 != p->fe) &&
*(te + 1))
@ -826,7 +878,6 @@ static void _get_token(struct parser *p, int tok_prev)
case '\'':
p->t = TOK_STRING;
te++;
while ((te != p->fe) && (*te) && (*te != '\''))
te++;
@ -850,7 +901,7 @@ static void _get_token(struct parser *p, int tok_prev)
case '+':
case '-':
if (values_allowed) {
while (++te != p->fe) {
for (; te != p->fe; ++te) {
if (!isdigit((int) *te)) {
if (*te == '.') {
if (p->t != TOK_FLOAT) {
@ -867,10 +918,10 @@ static void _get_token(struct parser *p, int tok_prev)
default:
p->t = TOK_IDENTIFIER;
while ((te != p->fe) && (*te) && !isspace(*te) &&
(*te != '#') && (*te != '=') &&
(*te != SECTION_B_CHAR) &&
(*te != SECTION_E_CHAR))
while ((te != p->fe) && ((c = *te)) && !isspace(c) &&
(c != '#') && (c != '=') &&
(c != SECTION_B_CHAR) &&
(c != SECTION_E_CHAR))
te++;
if (values_allowed)
p->t = TOK_STRING_BARE;
@ -883,16 +934,19 @@ static void _get_token(struct parser *p, int tok_prev)
static void _eat_space(struct parser *p)
{
while (p->tb != p->fe) {
if (*p->te == '#')
if (!isspace(*p->te)) {
if (*p->te != '#')
break;
while ((p->te != p->fe) && (*p->te != '\n') && (*p->te))
++p->te;
}
else if (!isspace(*p->te))
break;
while ((p->te != p->fe) && isspace(*p->te)) {
while (p->te != p->fe) {
if (*p->te == '\n')
++p->line;
else if (!isspace(*p->te))
break;
++p->te;
}
@ -908,9 +962,44 @@ static struct dm_config_value *_create_value(struct dm_pool *mem)
return dm_pool_zalloc(mem, sizeof(struct dm_config_value));
}
static struct dm_config_node *_create_node(struct dm_pool *mem)
static struct dm_config_value *_create_str_value(struct dm_pool *mem, const char *str, size_t str_len)
{
return dm_pool_zalloc(mem, sizeof(struct dm_config_node));
struct dm_config_value *cv;
char *str_buf;
if (!(cv = dm_pool_alloc(mem, sizeof(struct dm_config_value) + str_len + 1)))
return_NULL;
memset(cv, 0, sizeof(*cv));
if (str) {
str_buf = (char *)(cv + 1);
memcpy(str_buf, str, str_len);
str_buf[str_len] = '\0';
cv->v.str = str_buf;
}
return cv;
}
static struct dm_config_node *_create_node(struct dm_pool *mem, const char *key, size_t key_len)
{
struct dm_config_node *cn;
char *key_buf;
if (!(cn = dm_pool_alloc(mem, sizeof(struct dm_config_node) + key_len + 1)))
return_NULL;
memset(cn, 0, sizeof(*cn));
if (key) {
key_buf = (char *)(cn + 1);
memcpy(key_buf, key, key_len);
key_buf[key_len] = '\0';
cn->key = key_buf;
}
return cn;
}
static char *_dup_token(struct dm_pool *mem, const char *b, const char *e)
@ -1327,19 +1416,20 @@ static struct dm_config_value *_clone_config_value(struct dm_pool *mem,
{
struct dm_config_value *new_cv;
if (!(new_cv = _create_value(mem))) {
log_error("Failed to clone config value.");
return NULL;
if (v->type == DM_CFG_STRING) {
if (!(new_cv = _create_str_value(mem, v->v.str, strlen(v->v.str)))) {
log_error("Failed to clone string config value.");
return NULL;
}
} else {
if (!(new_cv = _create_value(mem))) {
log_error("Failed to clone config value.");
return NULL;
}
new_cv->v = v->v;
}
new_cv->type = v->type;
if (v->type == DM_CFG_STRING) {
if (!(new_cv->v.str = dm_pool_strdup(mem, v->v.str))) {
log_error("Failed to clone config string value.");
return NULL;
}
} else
new_cv->v = v->v;
if (v->next && !(new_cv->next = _clone_config_value(mem, v->next)))
return_NULL;
@ -1356,16 +1446,11 @@ struct dm_config_node *dm_config_clone_node_with_mem(struct dm_pool *mem, const
return NULL;
}
if (!(new_cn = _create_node(mem))) {
if (!(new_cn = _create_node(mem, cn->key, cn->key ? strlen(cn->key) : 0))) {
log_error("Failed to clone config node.");
return NULL;
}
if ((cn->key && !(new_cn->key = dm_pool_strdup(mem, cn->key)))) {
log_error("Failed to clone config node key.");
return NULL;
}
new_cn->id = cn->id;
if ((cn->v && !(new_cn->v = _clone_config_value(mem, cn->v))) ||
@ -1376,23 +1461,20 @@ struct dm_config_node *dm_config_clone_node_with_mem(struct dm_pool *mem, const
return new_cn;
}
struct dm_config_node *dm_config_clone_node(struct dm_config_tree *cft, const struct dm_config_node *node, int sib)
struct dm_config_node *dm_config_clone_node(struct dm_config_tree *cft, const struct dm_config_node *cn, int sib)
{
return dm_config_clone_node_with_mem(cft->mem, node, sib);
return dm_config_clone_node_with_mem(cft->mem, cn, sib);
}
struct dm_config_node *dm_config_create_node(struct dm_config_tree *cft, const char *key)
{
struct dm_config_node *cn;
if (!(cn = _create_node(cft->mem))) {
if (!(cn = _create_node(cft->mem, key, strlen(key)))) {
log_error("Failed to create config node.");
return NULL;
}
if (!(cn->key = dm_pool_strdup(cft->mem, key))) {
log_error("Failed to create config node's key.");
return NULL;
}
cn->parent = NULL;
cn->v = NULL;

View File

@ -152,15 +152,17 @@ struct thin_message {
struct load_segment {
struct dm_list list;
unsigned type;
uint64_t size;
unsigned type;
unsigned area_count; /* Linear + Striped + Mirrored + Crypt */
struct dm_list areas; /* Linear + Striped + Mirrored + Crypt */
uint32_t stripe_size; /* Striped + raid */
uint32_t region_size; /* Mirror + raid */
int persistent; /* Snapshot */
uint32_t chunk_size; /* Snapshot */
struct dm_tree_node *cow; /* Snapshot */
@ -168,7 +170,6 @@ struct load_segment {
struct dm_tree_node *merge; /* Snapshot */
struct dm_tree_node *log; /* Mirror */
uint32_t region_size; /* Mirror + raid */
unsigned clustered; /* Mirror */
unsigned mirror_area_count; /* Mirror */
uint64_t flags; /* Mirror + Raid + Cache */
@ -265,7 +266,7 @@ struct load_properties {
/*
* Preload tree normally only loads and not resume, but there is
* automatic resume when target is extended, as it's believed
* there can be no i/o flying to this 'new' extedend space
* there can be no i/o flying to this 'new' extended space
* from any device above. Reason is that preloaded target above
* may actually need to see its bigger subdevice before it
* gets suspended. As long as devices are simple linears
@ -277,7 +278,7 @@ struct load_properties {
/*
* When comparing table lines to decide if a reload is
* needed, ignore any differences betwen the lvm device
* needed, ignore any differences between the lvm device
* params and the kernel-reported device params.
* dm-integrity reports many internal parameters on the
* table line when lvm does not explicitly set them,
@ -288,8 +289,8 @@ struct load_properties {
/*
* Call node_send_messages(), set to 2 if there are messages
* When != 0, it validates matching transaction id, thus thin-pools
* where transation_id is passed as 0 are never validated, this
* allows external managment of thin-pool TID.
* where transaction_id is passed as 0 are never validated, this
* allows external management of thin-pool TID.
*/
unsigned send_messages;
/* Skip suspending node's children, used when sending messages to thin-pool */
@ -540,7 +541,8 @@ static struct dm_tree_node *_create_dm_tree_node(struct dm_tree *dtree,
struct dm_tree_node *node;
dev_t dev;
if (!(node = dm_pool_zalloc(dtree->mem, sizeof(*node))) ||
if (!dtree || !dtree->mem ||
!(node = dm_pool_zalloc(dtree->mem, sizeof(*node))) ||
!(node->name = dm_pool_strdup(dtree->mem, name)) ||
!(node->uuid = dm_pool_strdup(dtree->mem, uuid))) {
log_error("_create_dm_tree_node alloc failed.");
@ -968,7 +970,7 @@ static int _check_device_not_in_use(const char *name, struct dm_info *info)
} else if (dm_device_has_holders(info->major, info->minor))
reason = "is used by another device";
else if (dm_device_has_mounted_fs(info->major, info->minor))
reason = "constains a filesystem in use";
reason = "contains a filesystem in use";
else
return 1;
@ -1816,7 +1818,7 @@ static int _dm_tree_deactivate_children(struct dm_tree_node *dnode,
if (info.open_count) {
/* Skip internal non-toplevel opened nodes */
/* On some old udev systems without corrrect udev rules
/* On some old udev systems without correct udev rules
* this hack avoids 'leaking' active _mimageX legs after
* deactivation of mirror LV. Other suffixes are not added
* since it's expected newer systems with wider range of
@ -2182,7 +2184,7 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
/*
* FIXME: Implement delayed error reporting
* activation should be stopped only in the case,
* the submission of transation_id message fails,
* the submission of transaction_id message fails,
* resume should continue further, just whole command
* has to report failure.
*/
@ -2274,7 +2276,7 @@ static int _build_dev_string(char *devbuf, size_t bufsize, struct dm_tree_node *
return 1;
}
/* simplify string emiting code */
/* simplify string emitting code */
#define EMIT_PARAMS(p, str...)\
do {\
int w;\
@ -2868,6 +2870,8 @@ static int _integrity_emit_segment_line(struct dm_task *dmt,
count++;
if (set->sectors_per_bit_set)
count++;
if (set->allow_discards_set && set->allow_discards)
count++;
EMIT_PARAMS(pos, "%s 0 %u %s %d fix_padding block_size:%u internal_hash:%s",
origin_dev,
@ -2887,7 +2891,7 @@ static int _integrity_emit_segment_line(struct dm_task *dmt,
EMIT_PARAMS(pos, " journal_sectors:%u", set->journal_sectors);
if (set->interleave_sectors_set)
EMIT_PARAMS(pos, " ineterleave_sectors:%u", set->interleave_sectors);
EMIT_PARAMS(pos, " interleave_sectors:%u", set->interleave_sectors);
if (set->buffer_sectors_set)
EMIT_PARAMS(pos, " buffer_sectors:%u", set->buffer_sectors);
@ -2904,6 +2908,9 @@ static int _integrity_emit_segment_line(struct dm_task *dmt,
if (set->sectors_per_bit_set)
EMIT_PARAMS(pos, " sectors_per_bit:%llu", (unsigned long long)set->sectors_per_bit);
if (set->allow_discards_set && set->allow_discards)
EMIT_PARAMS(pos, " allow_discards");
if (!dm_task_secure_data(dmt))
stack;
@ -2965,7 +2972,7 @@ static int _vdo_emit_segment_line(struct dm_task *dmt, uint32_t major, uint32_t
* If there is already running VDO target, read 'existing' virtual size out of table line
* and avoid reading it them from VDO metadata device
*
* NOTE: ATM VDO virtual size can be ONLY extended thus it's simple to recongnize 'right' size.
* NOTE: ATM VDO virtual size can be ONLY extended thus it's simple to recognize 'right' size.
* However if there would be supported also reduction, this check would need to check range.
*/
if ((vdo_dmt = dm_task_create(DM_DEVICE_TABLE))) {
@ -3377,7 +3384,7 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (!child->info.exists && !(node_created = _create_node(child, dnode)))
return_0;
/* Propagate delayed resume from exteded child node */
/* Propagate delayed resume from extended child node */
if (child->props.delay_resume_if_extended)
dnode->props.delay_resume_if_extended = 1;
@ -3813,7 +3820,7 @@ int dm_tree_node_add_raid_target(struct dm_tree_node *node,
* - maximum 253 legs in a raid set (MD kernel limitation)
* - delta_disks for disk add/remove reshaping
* - data_offset for out-of-place reshaping
* - data_copies to cope witth odd numbers of raid10 disks
* - data_copies to cope with odd numbers of raid10 disks
*/
int dm_tree_node_add_raid_target_with_params_v2(struct dm_tree_node *node,
uint64_t size,
@ -4077,7 +4084,7 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
uint32_t slog_flags,
uint32_t slog_region_size)
{
log_error("Replicator targer is unsupported.");
log_error("Replicator target is unsupported.");
return 0;
}

View File

@ -31,6 +31,7 @@
struct selection {
struct dm_pool *mem;
struct dm_pool *regex_mem;
struct selection_node *selection_root;
int add_new_fields;
};
@ -204,7 +205,9 @@ static const struct op_def _op_log[] = {
struct selection_str_list {
struct dm_str_list str_list;
unsigned type; /* either SEL_AND or SEL_OR */
struct dm_regex *regex;
size_t regex_num_patterns;
unsigned type; /* either SEL_LIST_LS or SEL_LIST_SUBSET_LS with either SEL_AND or SEL_OR */
};
struct field_selection_value {
@ -459,7 +462,7 @@ static int _report_field_string_list(struct dm_report *rh,
*
* The very first item in the array of 'struct pos_len' is always
* a pair denoting '[list_size,strlen(field->report_string)]'. The
* rest of items denote start and lenght of each item in the list.
* rest of items denote start and length of each item in the list.
*
*
* For example, if we have a list with "abc", "xy", "defgh"
@ -547,7 +550,7 @@ static int _report_field_string_list(struct dm_report *rh,
}
/* more than one item - allocate temporary array for string list items for further processing */
if (!(arr = malloc(list_size * sizeof(struct str_pos_len)))) {
if (!(arr = zalloc(list_size * sizeof(struct str_pos_len)))) {
log_error("%s failed to allocate temporary array for processing", _error_msg_prefix);
goto out;
}
@ -589,7 +592,8 @@ static int _report_field_string_list(struct dm_report *rh,
for (i = 0, pos = 0; i < list_size; i++) {
arr[i].item.pos = pos;
memcpy(repstr + pos, arr[i].str, arr[i].item.len);
if (arr[i].str)
memcpy(repstr + pos, arr[i].str, arr[i].item.len);
memcpy(repstr_extra + i + 1, &arr[i].item, sizeof(struct pos_len));
pos += arr[i].item.len;
@ -1396,7 +1400,7 @@ struct dm_report *dm_report_init(uint32_t *report_types,
}
/*
* Return updated types value for further compatility check by caller.
* Return updated types value for further compatibility check by caller.
*/
_dm_report_init_update_types(rh, report_types);
@ -1411,8 +1415,11 @@ struct dm_report *dm_report_init(uint32_t *report_types,
void dm_report_free(struct dm_report *rh)
{
if (rh->selection)
if (rh->selection) {
dm_pool_destroy(rh->selection->mem);
if (rh->selection->regex_mem)
dm_pool_destroy(rh->selection->regex_mem);
}
if (rh->value_cache)
dm_hash_destroy(rh->value_cache);
dm_pool_destroy(rh->mem);
@ -1751,8 +1758,74 @@ static int _cmp_field_time(struct dm_report *rh,
return 0;
}
static int _str_list_item_match_regex(const struct str_list_sort_value *val, unsigned int i, struct dm_regex *regex)
{
struct pos_len *item = val->items + i;
char *s = (char *) (val->value + item->pos);
char c = s[item->len];
int r;
/*
* The val->items contains the whole string list in the form of a single string,
* where each item is delimited by a delimiter.
*
* The item->pos + item->len pair then points to the exact item within the val->items.
*
* The dm_regex_match accepts a string, not the pos + len pair, so we need to adapt here:
* replace the delimiter with '\0' temporarily so the item is a proper string.
*/
s[item->len] = '\0';
r = dm_regex_match(regex, s);
s[item->len] = c;
return r;
}
static size_t _bitset_count_set(dm_bitset_t bs)
{
size_t i, size = bs[0]/DM_BITS_PER_INT + 1;
size_t count = 0;
for (i = 1; i <= size; i++)
count += hweight32(bs[i]);
return count;
}
/* Matches if all items from selection string list match list value strictly 1:1. */
static int _cmp_field_string_list_strict_all(const struct str_list_sort_value *val,
static int _cmp_field_string_list_strict_regex_all(const struct dm_report *rh,
const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
unsigned int i;
dm_bitset_t bs;
int r;
if (!val->items)
return (sel->regex_num_patterns == 1) && dm_regex_match(sel->regex, "") >= 0;
if (!(bs = dm_bitset_create(rh->selection->mem, sel->regex_num_patterns))) {
log_error("Failed to create bitset for regex match counter.");
return 0;
}
for (i = 1; i <= val->items[0].pos; i++) {
if ((r = _str_list_item_match_regex(val, i, sel->regex)) < 0) {
r = 0;
goto out;
}
dm_bit_set(bs, r);
}
r = _bitset_count_set(bs) == sel->regex_num_patterns;
out:
dm_pool_free(rh->selection->mem, bs);
return r;
}
/* Matches if all items from selection string list match list value strictly 1:1. */
static int _cmp_field_string_list_strict_all(const struct dm_report *rh,
const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
unsigned int sel_list_size = dm_list_size(&sel->str_list.list);
@ -1784,7 +1857,36 @@ static int _cmp_field_string_list_strict_all(const struct str_list_sort_value *v
}
/* Matches if all items from selection string list match a subset of list value. */
static int _cmp_field_string_list_subset_all(const struct str_list_sort_value *val,
static int _cmp_field_string_list_subset_regex_all(const struct dm_report *rh,
const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
dm_bitset_t bs;
unsigned int i;
int r;
if (!val->items)
return (sel->regex_num_patterns == 1) && dm_regex_match(sel->regex, "") >= 0;
if (!(bs = dm_bitset_create(rh->selection->mem, sel->regex_num_patterns))) {
log_error("Failed to create bitset for regex match counter.");
return 0;
}
for (i = 1; i <= val->items[0].pos; i++) {
if ((r = _str_list_item_match_regex(val, i, sel->regex)) < 0)
continue;
dm_bit_set(bs, r);
}
r = _bitset_count_set(bs) == sel->regex_num_patterns;
dm_pool_free(rh->selection->mem, bs);
return r;
}
/* Matches if all items from selection string list match a subset of list value. */
static int _cmp_field_string_list_subset_all(const struct dm_report *rh __attribute__((unused)),
const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
unsigned int sel_list_size = dm_list_size(&sel->str_list.list);
@ -1819,8 +1921,26 @@ static int _cmp_field_string_list_subset_all(const struct str_list_sort_value *v
}
/* Matches if any item from selection string list matches list value. */
static int _cmp_field_string_list_any(const struct str_list_sort_value *val,
const struct selection_str_list *sel)
static int _cmp_field_string_list_subset_regex_any(const struct dm_report *rh __attribute__((unused)),
const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
unsigned int i;
if (!val->items)
return dm_regex_match(sel->regex, "") >= 0;
for (i = 1; i <= val->items[0].pos; i++) {
if (_str_list_item_match_regex(val, i, sel->regex) >= 0)
return 1;
}
return 0;
}
/* Matches if any item from selection string list matches list value. */
static int _cmp_field_string_list_subset_any(const struct dm_report *rh __attribute__((unused)),
const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
struct dm_str_list *sel_item;
unsigned int i;
@ -1849,7 +1969,59 @@ static int _cmp_field_string_list_any(const struct str_list_sort_value *val,
return 0;
}
static int _cmp_field_string_list(struct dm_report *rh __attribute__((unused)),
/* Matches if all items from list value can be matched by any item from selection list. */
static int _cmp_field_string_list_strict_regex_any(const struct dm_report *rh __attribute__((unused)),
const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
unsigned int i;
if (!val->items)
return dm_regex_match(sel->regex, "") >= 0;
for (i = 1; i <= val->items[0].pos; i++) {
if (_str_list_item_match_regex(val, i, sel->regex) < 0)
return 0;
}
return 1;
}
/* Matches if all items from list value can be matched by any item from selection list. */
static int _cmp_field_string_list_strict_any(const struct dm_report *rh __attribute__((unused)),
const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
struct dm_str_list *sel_item;
unsigned int i;
int match;
/* match blank string list with selection that contains blank string */
if (!val->items) {
dm_list_iterate_items(sel_item, &sel->str_list.list) {
if (!strcmp(sel_item->str, ""))
return 1;
}
return 0;
}
for (i = 1; i <= val->items[0].pos; i++) {
match = 0;
dm_list_iterate_items(sel_item, &sel->str_list.list) {
if ((strlen(sel_item->str) == val->items[i].len) &&
!strncmp(sel_item->str, val->value + val->items[i].pos, val->items[i].len)) {
match = 1;
break;
}
}
if (!match)
return 0;
}
return 1;
}
static int _cmp_field_string_list(struct dm_report *rh,
uint32_t field_num, const char *field_id,
const struct str_list_sort_value *val,
struct field_selection *fs)
@ -1871,11 +2043,16 @@ static int _cmp_field_string_list(struct dm_report *rh __attribute__((unused)),
switch (sel->type & SEL_MASK) {
case SEL_AND:
r = subset ? _cmp_field_string_list_subset_all(val, sel)
: _cmp_field_string_list_strict_all(val, sel);
r = subset ? sel->regex ? _cmp_field_string_list_subset_regex_all(rh, val, sel)
: _cmp_field_string_list_subset_all(rh, val, sel)
: sel->regex ? _cmp_field_string_list_strict_regex_all(rh, val, sel)
: _cmp_field_string_list_strict_all(rh, val, sel);
break;
case SEL_OR:
r = _cmp_field_string_list_any(val, sel);
r = subset ? sel->regex ? _cmp_field_string_list_subset_regex_any(rh, val, sel)
: _cmp_field_string_list_subset_any(rh, val, sel)
: sel->regex ? _cmp_field_string_list_strict_regex_any(rh, val, sel)
: _cmp_field_string_list_strict_any(rh, val, sel);
break;
default:
log_error(INTERNAL_ERROR "_cmp_field_string_list: unsupported string "
@ -1909,7 +2086,17 @@ static int _compare_selection_field(struct dm_report *rh,
}
if (fs->flags & FLD_CMP_REGEX)
r = _cmp_field_regex((const char *) f->sort_value, fs);
switch (f->props->flags & DM_REPORT_FIELD_TYPE_MASK) {
case DM_REPORT_FIELD_TYPE_STRING:
r = _cmp_field_regex((const char *) f->sort_value, fs);
break;
case DM_REPORT_FIELD_TYPE_STRING_LIST:
r = _cmp_field_string_list(rh, f->props->field_num, field_id, (const struct str_list_sort_value *) f->sort_value, fs);
break;
default:
log_error(INTERNAL_ERROR "_compare_selection_field: regex: incorrect type %" PRIu32 " for field %s",
f->props->flags & DM_REPORT_FIELD_TYPE_MASK, field_id);
}
else {
switch(f->props->flags & DM_REPORT_FIELD_TYPE_MASK) {
case DM_REPORT_FIELD_TYPE_PERCENT:
@ -1936,7 +2123,8 @@ static int _compare_selection_field(struct dm_report *rh,
r = _cmp_field_time(rh, f->props->field_num, field_id, *(const time_t *) f->sort_value, fs);
break;
default:
log_error(INTERNAL_ERROR "_compare_selection_field: unknown field type for field %s", field_id);
log_error(INTERNAL_ERROR "_compare_selection_field: incorrect type %" PRIu32 " for field %s",
f->props->flags & DM_REPORT_FIELD_TYPE_MASK, field_id);
}
}
@ -2430,7 +2618,7 @@ static const char *_reserved_name(struct dm_report *rh,
(reserved->type & DM_REPORT_FIELD_TYPE_MASK) ? "type-specific" : "field-specific",
rh->fields[field_num].id);
else
log_error("Error occured while processing %s reserved value handler for field %s",
log_error("Error occurred while processing %s reserved value handler for field %s",
(reserved->type & DM_REPORT_FIELD_TYPE_MASK) ? "type-specific" : "field-specific",
rh->fields[field_num].id);
}
@ -2628,11 +2816,9 @@ static int _check_reserved_values_supported(const struct dm_report_field_type fi
static const char *_tok_value_regex(struct dm_report *rh,
const struct dm_report_field_type *ft,
const char *s, const char **begin,
const char **end, uint32_t *flags,
struct reserved_value_wrapper *rvw)
const char **end, uint32_t *flags)
{
char c;
rvw->reserved = NULL;
s = _skip_space(s);
@ -2695,7 +2881,8 @@ static int _add_item_to_string_list(struct dm_pool *mem, const char *begin,
static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
struct dm_pool *mem, const char *s,
const char **begin, const char **end,
struct selection_str_list **sel_str_list)
struct selection_str_list **sel_str_list,
uint32_t *flags)
{
static const char _str_list_item_parsing_failed[] = "Failed to parse string list value "
"for selection field %s.";
@ -2709,12 +2896,11 @@ static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
int list_end = 0;
char c;
if (!(ssl = dm_pool_alloc(mem, sizeof(*ssl)))) {
log_error("_tok_value_string_list: memory allocation failed for selection list");
if (!(ssl = dm_pool_zalloc(mem, sizeof(*ssl)))) {
log_error("_tok_value_string_list: memory allocation failed for selection list.");
goto bad;
}
dm_list_init(&ssl->str_list.list);
ssl->type = 0;
*begin = s;
if (!(op_flags = _tok_op_log(s, &tmp, SEL_LIST_LS | SEL_LIST_SUBSET_LS))) {
@ -2726,7 +2912,7 @@ static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
}
if (!_add_item_to_string_list(mem, begin_item, end_item, &ssl->str_list.list))
goto_bad;
ssl->type = SEL_OR | SEL_LIST_LS;
ssl->type = SEL_OR | SEL_LIST_SUBSET_LS;
goto out;
}
@ -2801,12 +2987,17 @@ static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
else
ssl->type |= SEL_LIST_SUBSET_LS;
/* Sort the list. */
if (!(list_size = dm_list_size(&ssl->str_list.list))) {
log_error(INTERNAL_ERROR "_tok_value_string_list: list has no items");
goto bad;
} else if (list_size == 1)
goto out;
if (*flags & FLD_CMP_REGEX)
/* No need to sort the list for regex. */
goto out;
/* Sort the list. */
if (!(arr = malloc(sizeof(item) * list_size))) {
log_error("_tok_value_string_list: memory allocation failed for sort array");
goto bad;
@ -3322,7 +3513,10 @@ static const char *_tok_value(struct dm_report *rh,
s = _skip_space(s);
s = _get_reserved(rh, expected_type, field_num, implicit, s, begin, end, rvw);
/* recognize possible reserved value (but not in a regex) */
if (!(*flags & FLD_CMP_REGEX))
s = _get_reserved(rh, expected_type, field_num, implicit, s, begin, end, rvw);
if (rvw->reserved) {
/*
* FLD_CMP_NUMBER shares operators with FLD_CMP_TIME,
@ -3333,17 +3527,24 @@ static const char *_tok_value(struct dm_report *rh,
else if (expected_type == DM_REPORT_FIELD_TYPE_NUMBER)
*flags &= ~FLD_CMP_TIME;
*flags |= expected_type;
/* if we matched a reserved value, skip further processing of this token */
return s;
}
switch (expected_type) {
case DM_REPORT_FIELD_TYPE_STRING:
c = _get_and_skip_quote_char(&s);
if (!(s = _tok_value_string(s, begin, end, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL))) {
log_error("Failed to parse string value "
"for selection field %s.", ft->id);
return NULL;
if (*flags & FLD_CMP_REGEX) {
if (!(s = _tok_value_regex(rh, ft, s, begin, end, flags)))
return NULL;
} else {
c = _get_and_skip_quote_char(&s);
if (!(s = _tok_value_string(s, begin, end, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL))) {
log_error("Failed to parse string value "
"for selection field %s.", ft->id);
return NULL;
}
}
*flags |= DM_REPORT_FIELD_TYPE_STRING;
break;
@ -3352,7 +3553,7 @@ static const char *_tok_value(struct dm_report *rh,
if (!(str_list = (struct selection_str_list **) custom))
goto_bad;
s = _tok_value_string_list(ft, mem, s, begin, end, str_list);
s = _tok_value_string_list(ft, mem, s, begin, end, str_list, flags);
if (!(*str_list)) {
log_error("Failed to parse string list value "
"for selection field %s.", ft->id);
@ -3436,7 +3637,7 @@ static const char *_tok_value(struct dm_report *rh,
return s;
bad:
log_error(INTERNAL_ERROR "Forbidden NULL custom detected.");
log_error(INTERNAL_ERROR "_tok_value: Forbidden NULL custom parameter detected.");
return NULL;
}
@ -3496,7 +3697,7 @@ static int _get_reserved_value(struct dm_report *rh, uint32_t field_num,
(rvw->reserved->type) & DM_REPORT_FIELD_TYPE_MASK ? "type-specific" : "field-specific",
rh->fields[field_num].id);
else
log_error("Error occured while processing %s reserved value handler for field %s",
log_error("Error occurred while processing %s reserved value handler for field %s",
(rvw->reserved->type) & DM_REPORT_FIELD_TYPE_MASK ? "type-specific" : "field-specific",
rh->fields[field_num].id);
return 0;
@ -3507,6 +3708,19 @@ static int _get_reserved_value(struct dm_report *rh, uint32_t field_num,
return 1;
}
static struct dm_regex *_selection_regex_create(struct selection *selection, const char * const *patterns,
unsigned num_patterns)
{
if (!selection->regex_mem) {
if (!(selection->regex_mem = dm_pool_create("report selection regex", 32 * 1024))) {
log_error("Failed to create report selection regex memory pool.");
return NULL;
}
}
return dm_regex_create(selection->regex_mem, patterns, num_patterns);
}
static struct field_selection *_create_field_selection(struct dm_report *rh,
uint32_t field_num,
int implicit,
@ -3524,6 +3738,11 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
struct time_value *tval;
uint64_t factor;
char *s;
const char *s_arr_single[2] = { 0 };
const char **s_arr;
size_t s_arr_size;
struct dm_str_list *sl;
size_t i;
dm_list_iterate_items(fp, &rh->field_props) {
if ((fp->implicit == implicit) && (fp->field_num == field_num)) {
@ -3588,20 +3807,53 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
/* store comparison operand */
if (flags & FLD_CMP_REGEX) {
/* REGEX */
if (!(s = malloc(len + 1))) {
log_error("dm_report: malloc failed to store "
"regex value for selection field %s", field_id);
goto error;
}
memcpy(s, v, len);
s[len] = '\0';
switch (flags & DM_REPORT_FIELD_TYPE_MASK) {
case DM_REPORT_FIELD_TYPE_STRING:
if (!(s = malloc(len + 1))) {
log_error("dm_report: malloc failed to store "
"regex value for selection field %s", field_id);
goto error;
}
memcpy(s, v, len);
s[len] = '\0';
s_arr_single[0] = s;
fs->value->v.r = dm_regex_create(rh->selection->mem, (const char * const *) &s, 1);
free(s);
if (!fs->value->v.r) {
log_error("dm_report: failed to create regex "
"matcher for selection field %s", field_id);
goto error;
fs->value->v.r = _selection_regex_create(rh->selection, s_arr_single, 1);
free(s);
if (!fs->value->v.r) {
log_error("dm_report: failed to create regex "
"matcher for selection field %s", field_id);
goto error;
}
break;
case DM_REPORT_FIELD_TYPE_STRING_LIST:
if (!custom)
goto bad;
fs->value->v.l = *((struct selection_str_list **) custom);
s_arr_size = dm_list_size(&fs->value->v.l->str_list.list);
if (!(s_arr = malloc(sizeof(char *) * s_arr_size))) {
log_error("dm_report: malloc failed for regex array "
"for selection field %s", field_id);
goto error;
}
i = 0;
dm_list_iterate_items(sl, &fs->value->v.l->str_list.list)
s_arr[i++] = sl->str;
fs->value->v.l->regex = _selection_regex_create(rh->selection, s_arr, s_arr_size);
fs->value->v.l->regex_num_patterns = s_arr_size;
free(s_arr);
if (!fs->value->v.l->regex) {
log_error("dm_report: failed to create regex "
"matcher for selection field %s", field_id);
goto error;
}
break;
default:
log_error(INTERNAL_ERROR "_create_field_selection: regex: incorrect type %" PRIu32 " for field %s",
flags & DM_REPORT_FIELD_TYPE_MASK, field_id);
goto error;
}
} else {
/* STRING, NUMBER, SIZE, PERCENT, STRING_LIST, TIME */
@ -3715,8 +3967,8 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
}
break;
default:
log_error(INTERNAL_ERROR "_create_field_selection: "
"unknown type of selection field %s", field_id);
log_error(INTERNAL_ERROR "_create_field_selection: incorrect type %" PRIu32 " for field %s",
flags & DM_REPORT_FIELD_TYPE_MASK, field_id);
goto error;
}
}
@ -3727,7 +3979,7 @@ error_field_id:
field_id);
goto error;
bad:
log_error(INTERNAL_ERROR "Forbiden NULL custom detected.");
log_error(INTERNAL_ERROR "_create_field_selection: Forbidden NULL custom detected.");
error:
dm_pool_free(rh->selection->mem, fs);
@ -3863,7 +4115,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
char *tmp;
char c;
/* field name */
/* get field name */
if (!(last = _tok_field_name(s, &ws, &we))) {
log_error("Expecting field name");
goto bad;
@ -3896,7 +4148,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
} else
ft = &rh->fields[field_num];
/* comparison operator */
/* get comparison operator */
if (!(flags = _tok_op_cmp(we, &last))) {
_display_selection_help(rh);
log_error("Unrecognised comparison operator: %s", we);
@ -3908,50 +4160,49 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
goto bad;
}
/* comparison value */
/* check we can use the operator with the field */
if (flags & FLD_CMP_REGEX) {
/*
* REGEX value
*/
if (!(last = _tok_value_regex(rh, ft, last, &vs, &ve, &flags, &rvw)))
goto_bad;
} else {
/*
* STRING, NUMBER, SIZE, PERCENT, STRING_LIST, TIME value
*/
if (flags & FLD_CMP_NUMBER) {
if (!(ft->flags & (DM_REPORT_FIELD_TYPE_NUMBER |
DM_REPORT_FIELD_TYPE_SIZE |
DM_REPORT_FIELD_TYPE_PERCENT |
DM_REPORT_FIELD_TYPE_TIME))) {
_display_selection_help(rh);
log_error("Operator can be used only with number, size, time or percent fields: %s", ws);
goto bad;
}
} else if (flags & FLD_CMP_TIME) {
if (!(ft->flags & DM_REPORT_FIELD_TYPE_TIME)) {
_display_selection_help(rh);
log_error("Operator can be used only with time fields: %s", ws);
goto bad;
}
if (!(ft->flags & (DM_REPORT_FIELD_TYPE_STRING |
DM_REPORT_FIELD_TYPE_STRING_LIST))) {
_display_selection_help(rh);
log_error("Operator can be used only with string or string list fields: %s", ws);
goto bad;
}
} else if (flags & FLD_CMP_NUMBER) {
if (!(ft->flags & (DM_REPORT_FIELD_TYPE_NUMBER |
DM_REPORT_FIELD_TYPE_SIZE |
DM_REPORT_FIELD_TYPE_PERCENT |
DM_REPORT_FIELD_TYPE_TIME))) {
_display_selection_help(rh);
log_error("Operator can be used only with number, size, time or percent fields: %s", ws);
goto bad;
}
} else if (flags & FLD_CMP_TIME) {
if (!(ft->flags & DM_REPORT_FIELD_TYPE_TIME)) {
_display_selection_help(rh);
log_error("Operator can be used only with time fields: %s", ws);
goto bad;
}
if (ft->flags == DM_REPORT_FIELD_TYPE_SIZE ||
ft->flags == DM_REPORT_FIELD_TYPE_NUMBER ||
ft->flags == DM_REPORT_FIELD_TYPE_PERCENT)
custom = &factor;
else if (ft->flags & DM_REPORT_FIELD_TYPE_TIME)
custom = &tval;
else if (ft->flags == DM_REPORT_FIELD_TYPE_STRING_LIST)
custom = &str_list;
else
custom = NULL;
if (!(last = _tok_value(rh, ft, field_num, implicit,
last, &vs, &ve, &flags,
&rvw, rh->selection->mem, custom)))
goto_bad;
}
/* assign custom structures to hold extra information for specific value types */
if (ft->flags == DM_REPORT_FIELD_TYPE_SIZE ||
ft->flags == DM_REPORT_FIELD_TYPE_NUMBER ||
ft->flags == DM_REPORT_FIELD_TYPE_PERCENT)
custom = &factor;
else if (ft->flags & DM_REPORT_FIELD_TYPE_TIME)
custom = &tval;
else if (ft->flags == DM_REPORT_FIELD_TYPE_STRING_LIST)
custom = &str_list;
else
custom = NULL;
/* get value to compare with */
if (!(last = _tok_value(rh, ft, field_num, implicit,
last, &vs, &ve, &flags,
&rvw, rh->selection->mem, custom)))
goto_bad;
*next = _skip_space(last);
/* create selection */
@ -4025,7 +4276,7 @@ error:
return NULL;
}
/* AND_EXPRESSION := EX (AND_OP AND_EXPRSSION) */
/* AND_EXPRESSION := EX (AND_OP AND_EXPRESSION) */
static struct selection_node *_parse_and_ex(struct dm_report *rh,
const char *s,
const char **next,
@ -4092,7 +4343,7 @@ error:
static int _alloc_rh_selection(struct dm_report *rh)
{
if (!(rh->selection = dm_pool_zalloc(rh->mem, sizeof(struct selection))) ||
!(rh->selection->mem = dm_pool_create("report selection", 10 * 1024))) {
!(rh->selection->mem = dm_pool_create("report selection", 1024))) {
log_error("Failed to allocate report selection structure.");
if (rh->selection)
dm_pool_free(rh->mem, rh->selection);
@ -4371,9 +4622,10 @@ static int _row_compare(const void *a, const void *b)
for (cnt = 0; cnt < rowa->rh->keys_count; cnt++) {
sfa = (*rowa->sort_fields)[cnt];
sfb = (*rowb->sort_fields)[cnt];
if ((sfa->props->flags & DM_REPORT_FIELD_TYPE_NUMBER) ||
(sfa->props->flags & DM_REPORT_FIELD_TYPE_SIZE) ||
(sfa->props->flags & DM_REPORT_FIELD_TYPE_TIME)) {
if (sfa->props->flags &
((DM_REPORT_FIELD_TYPE_NUMBER) |
(DM_REPORT_FIELD_TYPE_SIZE) |
(DM_REPORT_FIELD_TYPE_TIME))) {
const uint64_t numa =
*(const uint64_t *) sfa->sort_value;
const uint64_t numb =
@ -4484,6 +4736,7 @@ static const char *_get_field_id(struct dm_report *rh, struct dm_report_field *f
static int _output_field_basic_fmt(struct dm_report *rh, struct dm_report_field *field)
{
char buf_local[8192];
char *field_id;
int32_t width;
uint32_t align;
@ -4491,25 +4744,26 @@ static int _output_field_basic_fmt(struct dm_report *rh, struct dm_report_field
size_t buf_size = 0;
if (rh->flags & DM_REPORT_OUTPUT_FIELD_NAME_PREFIX) {
if (!(field_id = strdup(_get_field_id(rh, field)))) {
log_error("dm_report: Failed to copy field name");
buf_size = strlen(_get_field_id(rh, field)) + 1;
if (buf_size >= sizeof(buf_local)) {
/* for field names our buf_local should be enough */
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
return 0;
}
field_id = buf_local;
memcpy(field_id, _get_field_id(rh, field), buf_size);
if (!dm_pool_grow_object(rh->mem, rh->output_field_name_prefix, 0)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
free(field_id);
return 0;
}
if (!dm_pool_grow_object(rh->mem, _toupperstr(field_id), 0)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
free(field_id);
return 0;
}
free(field_id);
if (!dm_pool_grow_object(rh->mem, STANDARD_PAIR, 1)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
return 0;
@ -4532,7 +4786,10 @@ static int _output_field_basic_fmt(struct dm_report *rh, struct dm_report_field
/* Including trailing '\0'! */
buf_size = width + 1;
if (!(buf = malloc(buf_size))) {
if (buf_size < sizeof(buf_local))
/* Use local buffer on stack for smaller strings */
buf = buf_local;
else if (!(buf = malloc(buf_size))) {
log_error("dm_report: Could not allocate memory for output line buffer.");
return 0;
}
@ -4574,10 +4831,12 @@ static int _output_field_basic_fmt(struct dm_report *rh, struct dm_report_field
}
}
free(buf);
if (buf != buf_local)
free(buf);
return 1;
bad:
free(buf);
if (buf != buf_local)
free(buf);
return 0;
}
@ -4757,6 +5016,8 @@ static int _output_as_rows(struct dm_report *rh)
dm_list_iterate_items(fp, &rh->field_props) {
if (fp->flags & FLD_HIDDEN) {
dm_list_iterate_items(row, &rh->rows) {
if (dm_list_empty(&row->fields))
continue;
field = dm_list_item(dm_list_first(&row->fields), struct dm_report_field);
dm_list_del(&field->list);
}
@ -4845,6 +5106,7 @@ static int _output_as_columns(struct dm_report *rh)
struct dm_report_field *field;
struct dm_list *last_rowh;
int do_field_delim;
int is_json_report = _is_json_report(rh);
char *line;
/* If headings not printed yet, calculate field widths and print them */
@ -4864,7 +5126,7 @@ static int _output_as_columns(struct dm_report *rh)
return 0;
}
if (_is_json_report(rh)) {
if (is_json_report) {
if (!dm_pool_grow_object(rh->mem, JSON_OBJECT_START, 0)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
goto bad;
@ -4879,7 +5141,7 @@ static int _output_as_columns(struct dm_report *rh)
continue;
if (do_field_delim) {
if (_is_json_report(rh)) {
if (is_json_report) {
if (!dm_pool_grow_object(rh->mem, JSON_SEPARATOR, 0) ||
!dm_pool_grow_object(rh->mem, JSON_SPACE, 0)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
@ -4901,7 +5163,7 @@ static int _output_as_columns(struct dm_report *rh)
dm_list_del(&field->list);
}
if (_is_json_report(rh)) {
if (is_json_report) {
if (!dm_pool_grow_object(rh->mem, JSON_OBJECT_END, 0)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
goto bad;
@ -5103,7 +5365,7 @@ struct dm_report_group *dm_report_group_create(dm_report_group_type_t type, void
dm_list_init(&group->items);
if (!(item = dm_pool_zalloc(mem, sizeof(*item)))) {
log_error("dm_report: faile to allocate root report group item");
log_error("dm_report: failed to allocate root report group item");
goto bad;
}

View File

@ -169,7 +169,7 @@ int dm_vasprintf(char **result, const char *format, va_list aq)
}
if (i > 1) {
/* Reallocating more then once? */
/* Reallocating more than once? */
if (!(*result = strdup(buf))) {
free(buf);
return -1;
@ -471,10 +471,10 @@ const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
double d;
uint64_t byte = UINT64_C(0);
uint64_t units = UINT64_C(1024);
char *size_buf = NULL;
char *size_buf;
char new_unit_type = '\0', unit_type_buf[2];
const char *prefix = "";
const char * const size_str[][3] = {
static const char _size_str[][3][12] = {
/* BASE_UNKNOWN */
{" ", " ", " "}, /* [0] */
@ -519,14 +519,14 @@ const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
/* Case-independent match */
for (s = 0; s < NUM_UNIT_PREFIXES; s++)
if (toupper((int) unit_type) ==
*size_str[BASE_SHARED + s][2]) {
*_size_str[BASE_SHARED + s][2]) {
base = BASE_SHARED;
break;
}
} else {
/* Case-dependent match for powers of 1000 */
for (s = 0; s < NUM_UNIT_PREFIXES; s++)
if (unit_type == *size_str[BASE_1000 + s][2]) {
if (unit_type == *_size_str[BASE_1000 + s][2]) {
base = BASE_1000;
break;
}
@ -534,7 +534,7 @@ const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
/* Case-dependent match for powers of 1024 */
if (base == BASE_UNKNOWN)
for (s = 0; s < NUM_UNIT_PREFIXES; s++)
if (unit_type == *size_str[BASE_1024 + s][2]) {
if (unit_type == *_size_str[BASE_1024 + s][2]) {
base = BASE_1024;
break;
}
@ -544,7 +544,7 @@ const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
/* Check for special units - s, b or u */
for (s = 0; s < NUM_SPECIAL; s++)
if (toupper((int) unit_type) ==
*size_str[BASE_SPECIAL + s][2]) {
*_size_str[BASE_SPECIAL + s][2]) {
base = BASE_SPECIAL;
break;
}
@ -552,7 +552,7 @@ const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
if (size == UINT64_C(0)) {
if (base == BASE_UNKNOWN)
s = 0;
snprintf(size_buf, SIZE_BUF, "0%s", include_suffix ? size_str[base + s][suffix_type] : "");
snprintf(size_buf, SIZE_BUF, "0%s", include_suffix ? _size_str[base + s][suffix_type] : "");
return size_buf;
}
@ -591,7 +591,7 @@ const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
if ((s < NUM_UNIT_PREFIXES) &&
((unit_type == 'R') || (unit_type == 'r'))) {
/* When the rounding would cause difference, add '<' prefix
* i.e. 2043M is more then 1.9949G prints <2.00G
* i.e. 2043M is more than 1.9949G prints <2.00G
* This version is for 2 digits fixed precision */
d = 100. * (double) size / byte;
if (!_close_enough(floorl(d), nearbyintl(d)))
@ -602,7 +602,7 @@ const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
}
/* FIXME Make precision configurable */
switch (toupper(*size_str[base + s][DM_SIZE_UNIT])) {
switch (toupper(*_size_str[base + s][DM_SIZE_UNIT])) {
case 'B':
case 'S':
precision = 0;
@ -612,7 +612,7 @@ const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
}
snprintf(size_buf, SIZE_BUF, "%s%.*f%s", prefix, precision,
(double) size / byte, include_suffix ? size_str[base + s][suffix_type] : "");
(double) size / byte, include_suffix ? _size_str[base + s][suffix_type] : "");
return size_buf;
}

View File

@ -120,7 +120,7 @@ int dm_get_status_raid(struct dm_pool *mem, const char *params,
if (!(pp = _skip_fields(p, 1)))
goto_bad;
/* Raid target can actually report more then real number of legs in a case
/* Raid target can actually report more than real number of legs in a case
* raid legs have been removed during initial raid array resynchronization */
if (i > (pp - p - 1))
i = pp - p - 1;
@ -401,12 +401,12 @@ int dm_get_status_integrity(struct dm_pool *mem, const char *params,
struct dm_status_integrity **status)
{
struct dm_status_integrity *s;
char recalc_str[16] = "\0";
char recalc_str[16] = { 0 };
if (!(s = dm_pool_zalloc(mem, sizeof(*s))))
return_0;
if (sscanf(params, "%llu %llu %s",
if (sscanf(params, "%llu %llu %15s",
(unsigned long long *)&s->number_of_mismatches,
(unsigned long long *)&s->provided_data_sectors,
recalc_str) != 3) {
@ -571,7 +571,7 @@ int dm_get_status_mirror(struct dm_pool *mem, const char *params,
pos += used;
if (num_devs > DM_MIRROR_MAX_IMAGES) {
log_error(INTERNAL_ERROR "More then " DM_TO_STRING(DM_MIRROR_MAX_IMAGES)
log_error(INTERNAL_ERROR "More than " DM_TO_STRING(DM_MIRROR_MAX_IMAGES)
" reported in mirror status.");
goto out;
}

View File

@ -13,6 +13,8 @@
# include <linux/types.h>
#endif
#include <stdint.h>
#define DM_DIR "mapper" /* Slashes not supported */
#define DM_CONTROL_NODE "control"
#define DM_MAX_TYPE_NAME 16
@ -209,7 +211,7 @@ struct dm_name_list {
};
#define DM_NAME_LIST_FLAG_HAS_UUID 1
#define DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID 2
#define DM_NAME_LIST_FLAG_DOES_NOT_HAVE_UUID 2
/*
* Used to retrieve the target versions

View File

@ -62,7 +62,7 @@
*
* The UUID contained in the dm_ulog_request structure is the reference that
* will be used by all request types to a specific log. The constructor must
* record this assotiation with the instance created.
* record this association with the instance created.
*
* When the request has been processed, user-space must return the
* dm_ulog_request to the kernel - setting the 'error' field, filling the

View File

@ -13,7 +13,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dmlib.h"
#include "base/memory/zalloc.h"
#include "device_mapper/misc/dmlib.h"
#include <assert.h>
struct block {

View File

@ -14,7 +14,7 @@
*/
#ifdef VALGRIND_POOL
#include "memcheck.h"
#include <memcheck.h>
#endif
#include "base/memory/zalloc.h"

View File

@ -129,7 +129,7 @@ int dm_pool_locked(struct dm_pool *p)
* Bool specifies whether to store the pool crc/hash checksum.
*
* \return
* 1 (success) when the pool was preperly locked, 0 otherwise.
* 1 (success) when the pool was properly locked, 0 otherwise.
*/
int dm_pool_lock(struct dm_pool *p, int crc)
{

View File

@ -356,7 +356,7 @@ struct dm_regex *dm_regex_create(struct dm_pool *mem, const char * const *patter
for (i = 0; i < num_patterns; i++) {
ptr += sprintf(ptr, "(.*(%s)%c)", patterns[i], TARGET_TRANS);
if (i < (num_patterns - 1))
if ((i + 1) < num_patterns)
*ptr++ = '|';
}

View File

@ -13,7 +13,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "device_mapper/misc/dmlib.h"
#include "parse_rx.h"
#ifdef DEBUG

View File

@ -16,6 +16,8 @@
#ifndef _DM_PARSE_REGEX_H
#define _DM_PARSE_REGEX_H
#include "device_mapper/misc/dmlib.h"
enum {
CAT,
STAR,

View File

@ -13,7 +13,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "device_mapper/misc/dmlib.h"
#include "ttree.h"
struct node {
@ -84,9 +83,7 @@ int ttree_insert(struct ttree *tt, unsigned int *key, void *data)
} while (*c && count);
if (!*c) {
count++;
while (count--) {
do {
if (!(*c = _tree_node(tt->mem, k)))
return_0;
@ -94,7 +91,7 @@ int ttree_insert(struct ttree *tt, unsigned int *key, void *data)
k = *key++;
c = &((*c)->m);
}
}
} while (count--);
}
(*c)->data = data;

View File

@ -16,6 +16,8 @@
#ifndef _DM_TTREE_H
#define _DM_TTREE_H
#include "device_mapper/misc/dmlib.h"
struct ttree;
struct ttree *ttree_create(struct dm_pool *mem, unsigned int klen);

View File

@ -136,7 +136,7 @@ struct vdo_volume_geometry_4 {
struct vdo_index_config index_config;
} __packed;
/* Decoding mostly only some used stucture members */
/* Decoding mostly only some used structure members */
static void _vdo_decode_version(struct vdo_version_number *v)
{
@ -226,7 +226,7 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks)
size = st.st_size;
}
if (read(fh, buffer, sizeof(buffer)) < 0) {
if (read(fh, buffer, sizeof(buffer)) < (int)(MAGIC_NUMBER_SIZE + sizeof(h))) {
log_sys_debug("read", vdo_path);
goto err;
}
@ -270,7 +270,7 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks)
goto err;
}
if (read(fh, buffer, sizeof(buffer)) < 0) {
if (read(fh, buffer, sizeof(buffer)) < (int)(sizeof(struct vdo_geometry_block) + sizeof(vn))) {
log_sys_debug("read", vdo_path);
goto err;
}

View File

@ -28,7 +28,7 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp,
if ((vtp->minimum_io_size != (512 >> SECTOR_SHIFT)) &&
(vtp->minimum_io_size != (4096 >> SECTOR_SHIFT))) {
log_error("VDO minimum io size %u is unsupported [512, 4096].",
vtp->minimum_io_size);
(vtp->minimum_io_size << SECTOR_SHIFT));
valid = false;
}

View File

@ -49,7 +49,7 @@ List of official [mirror sites](https://sourceware.org/mirrors.html) (including
### LVM Releases
[[!inline pages="release-notes/2.03.* and !*/template and !*/Discussion and !tagged(draft) and !tagged(pending)" limit=2 rootpage="release-notes"]]
[[!inline pages="release-notes/2.03.* and !*/template and !*/Discussion and !tagged(draft) and !tagged(pending)" limit="2" show="2" rootpage="release-notes"]]
[[More releases|release-notes/index]]

View File

@ -13,7 +13,7 @@ different targets were rolling their own data structures, for example:
Maintaining these data structures takes a lot of work, so if possible
we'd like to reduce the number.
The persistent-data library is an attempt to provide a re-usable
The persistent-data library is an attempt to provide a reusable
framework for people who want to store metadata in device-mapper
targets. It's currently used by the thin-provisioning target and an
upcoming hierarchical storage target.

View File

@ -41,7 +41,7 @@ metadata.
The zones of the device are separated into 2 types:
1) Metadata zones: these are conventional zones used to store metadata.
Metadata zones are not reported as useable capacity to the user.
Metadata zones are not reported as usable capacity to the user.
2) Data zones: all remaining zones, the vast majority of which will be
sequential zones used exclusively to store user data. The conventional

View File

@ -86,7 +86,7 @@ are as follows:
the policies outlined in the LVM configuration file - usually,
/etc/lvm/lvm.conf. Once this operation is complete, the logical volumes
will be consistent. However, the volume group will still be inconsistent -
due to the refernced-but-missing device/PV - and operations will still be
due to the referenced-but-missing device/PV - and operations will still be
restricted to the aforementioned actions until either the device is
restored or 'vgreduce --removemissing' is run.

View File

@ -108,7 +108,7 @@ really an orphan and enable its usage for creating or extending VGs. In
practice, the decision might be governed by a timeout or assumed immediately --
the former case is a little safer, the latter is probably more transparent. I
am not very keen on using timeouts and we can probably assume that the admin
won't blindly try to re-use devices in a way that would trip up LVM in this
won't blindly try to reuse devices in a way that would trip up LVM in this
respect. I would be in favour of just assuming that metadata-less VGs with no
known referencing VGs are orphans -- after all, this is the same approach as we
use today. The metadata balancing support may stress this a bit more than the
@ -153,7 +153,7 @@ Protocol & co.
I expect a simple text-based protocol executed on top of an Unix Domain Socket
to be the communication interface for lvmetad. Ideally, the requests and
replies will be well-formed "config file" style strings, so we can re-use
replies will be well-formed "config file" style strings, so we can reuse
existing parsing infrastructure.
Since we already have two daemons, I would probably look into factoring some

View File

@ -56,7 +56,7 @@ Device mapper
-------------
As well as the low level dm-ioctl driving code we need to have all our dm 'best
practise' stuff in here. For instance this is the code that decides to use the
practice' stuff in here. For instance this is the code that decides to use the
mirror target to move some data around; that knows to suspend a thin volume
before taking a snapshot of it. This module is going to have a lot more code
in it than the current libdevmapper.
@ -150,7 +150,7 @@ interface to get round.
'lib' is where the bulk of our code currently is. Dependency-wise the code is
a bit like a ball of string. So splitting it up is going to take time. We can
probably pull code pretty quickly into the 'metadata model' dir. But factoring
out the dm best practises stuff is going to require splitting at least
out the dm best practices stuff is going to require splitting at least
files, and probably functions. Certainly not something that can be done in one
go. System should just be a question of cherry picking functions.

View File

@ -14,9 +14,6 @@ Version 2.03.25
* And as usually some clean up, static analysis fixes, etc.
<!-- remove the pending tag on release, remove draft tag once editing is complete -->
[[!tag draft pending]]
<!--
For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
\[[!meta date="Tue Nov 21 14:26:07 2023 +0100"]]
-->
[[!tag]]
[[!meta date="Fri Jul 12 12:49:07 2024 +0200"]]

View File

@ -0,0 +1,18 @@
<!-- Page title -->
[[!meta title="Version 2.03.26 - Feature and Bug Fix Release"]]
Version 2.03.26
===============
* Add `--integritysettings` option to manipulate dm-integrity settings.
* Add `--refresh` with `vgscan --mknodes`.
* Improve documentation for `--refresh` option.
* Use `log/report_command_log=1` config setting by default for JSON output format.
* Fix `vgmknodes --refresh` to wait for udev before checking `/dev` content.
* Fix internal error reported by pvmove on a VG with single PV.
* Fix unreleased memory pools on RAID lvextend.
* And as usually some clean up, static analysis fixes, etc.
<!-- remove the pending tag on release, remove draft tag once editing is complete -->
[[!tag]]
[[!meta date="Fri Aug 23 16:02:00 2024 +0200"]]

View File

@ -0,0 +1,26 @@
<!-- Page title -->
[[!meta title="Version 2.03.27 - Bug Fix Release"]]
Version 2.03.27
===============
* Deprecate vdo settings `vdo_write_policy` and `vdo_write_policy`.
* Do not accept duplicate device names for pvcreate.
* Fix swap device size detection using blkid for lvresize/lvreduce/lvextend.
* Detect GPT partition table and pass partition filter if no partitions defined.
* Add `global/sanlock_align_size` option to configure sanlock lease size.
* Disable mem locking when `activation/reserved_stack` or `reserved_memory` is `0`.
* Fix locking issues in lvmlockd leaving thin pool inactive but locked.
* Corrected integrity parameter `interleave_sectors` for DM table line.
* Ignore `-i|--stripes`, `-I|--stripesize` for lvextend on raid0 LV, like on raid10.
* Fix lot of typos across lvm2 code base (codespell).
* Cleanup udev sync semaphore if `dm_{udev_create,task_set}_cookie` fails.
* Improve error messages on failed udev cookie create/inc/dec operation.
<!-- remove the pending tag on release, remove draft tag once editing is complete -->
[[!tag]]
<!--
For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
[[!meta date="Wed Oct 2 14:19:23 2024 +0200"]]
-->

View File

@ -0,0 +1,20 @@
<!-- Page title -->
[[!meta title="Version 2.03.28 - Bug Fix Release"]]
Version 2.03.28
===============
Few bugfixes and a lot of speed improvements mainly for many LVs.
* Introduce setting config/validate_metadata = full | none.
* Restore fs resize call for lvresize -r on the same size LV (2.03.17).
* Correct off-by-one devicesfile backup counting.
* Fall back to direct zeroing if BLKZEROOUT fails during new LV initialization.
<!-- remove the pending tag on release, remove draft tag once editing is complete -->
[[!tag]]
<!--
For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
[[!meta date="Mon Nov 4 16:42:12 2024 +0100"]]
-->

View File

@ -0,0 +1,23 @@
<!-- Page title -->
[[!meta title="Version 2.03.29 - Bug Fix Release"]]
Version 2.03.29
===============
Mostly bugfix release, few interesting changes:
* **Fix renaming of raid sub LVs when converting a volume to raid (2.03.28)**.
* **Fix segfault/VG write error for raid LV `lvextend -i|--stripes -I|--stripesize`**.
* Add configure --enable/disable-sd-notify to control lvmlockd build with sd-notify.
* Allow test mode when lvmlockd is built without dlm support.
* Add a note about RAID + integrity synchronization to lvmraid(7) man page.
* Add a function for running lvconvert --repair on RAID LVs to lvmdbusd.
* Improve option section of man pages for listing commands ({pv,lv,vg}{s,display}).
* And some cleanup mostly in test code.
<!-- remove the pending tag on release, remove draft tag once editing is complete -->
[[!tag]]
<!--
For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
[[!meta date="Mon Dec 09 12:57:57 2024 +0100"]]
-->

View File

@ -0,0 +1,24 @@
<!-- Page title -->
[[!meta title="Version 2.03.30 - Bug Fix Release"]]
Version 2.03.30
===============
Small bugfix release:
* **NEW** Create `/dev/disk/by-diskseq/<DISKSEQ>` symlink for public DM devices.
* Lvresize reports origin vdo volume cannot be resized.
* Support setting `reserved_memory|stack` using `--config` on cmdline.
* Fix support for disabling memory locking (2.03.27).
* Do not extend an LV if FS resize unsupported and `--fs resize` used.
* Prevent leftover temporary device when converting in use volume to a pool.
* lvconvert detects volume in use early when converting it to a pool.
* Handle NVMe with quirk changed WWID not matching WWID in devices file.
<!-- remove the pending tag on release, remove draft tag once editing is complete -->
[[!tag]]
<!--
For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
[[!meta date="Tue Jan 14 20:55:33 2025 +0100"]]
-->

View File

@ -0,0 +1,33 @@
<!-- Page title -->
[[!meta title="Version 2.03.31 - Bug Fix Release"]]
Version 2.03.31
===============
Bugfix release:
* Disallow shared activation of LV with CoW snapshot.
* Ignore reported `optimal_io_size` not divisible by 4096.
* Restore support for `LVM_SUPPRESS_FD_WARNINGS` (2.03.24).
* Fix DM cache preserving logic (2.03.28).
* Restore missing symbol `dm_tree_node_size_changed@Base` (1.02.175).
* Restore missing symbol `dm_bitset_parse_list@@DM_1_02_138` (1.02.175).
* Fix uncache and split cache restoring original state of volume.
* Extend use of lockopt skip to more scenarios.
* Reduce `mandoc -T lint` reported issues for man pages.
* Enhance error path resolving in polling code.
* Fix lvmlockd use in lvremove of CoW snapshot, VDO pool, and uncache.
* Improve mirror split with opened temporary volumes.
* Improve pvmove finish with opened temporary volumes.
* Fix backup limit for devices file, handle over 10,000 files.
* Fix busy-loop in config reading when read returned 0.
* Improve use of lvmlockd for usecases involving thin volumes and pools.
<!-- remove the pending tag on release, remove draft tag once editing is complete -->
[[!tag]]
<!--
For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
[[!meta date="Thu Feb 27 16:51:29 2025 +0100"]]
-->

View File

@ -4,5 +4,5 @@ This list is incomplete, only releases with a release-note are included.
For releases of stable branch 2.03 see [[index]].
[[!inline pages="release-notes/2.02.* and !*/template and !*/Discussion and !tagged(draft) and !tagged(pending)" limit=2 rootpage="release-notes"]]
[[!inline pages="release-notes/2.02.* and !*/template and !*/Discussion and !tagged(draft) and !tagged(pending)" rootpage="release-notes"]]

View File

@ -25,7 +25,7 @@ TODO: It would be nice if we could use a real session output, so we could test t
Changes in command line
-----------------------
Describe important changes in command line tools, especially any chnages of behavior, which user must be aware of:
Describe important changes in command line tools, especially any changes of behavior, which user must be aware of:
* New options
* Removed options

View File

@ -29,7 +29,7 @@ LVM2 that is running the LV's on my development box.
variable LVM_SYSTEM_DIR to point to your config directory
(/etc/lvm_loops in my case).
5) It's a good idea to do a vgscan to initialise the filters:
5) It's a good idea to do a vgscan to initialize the filters:
export LVM_SYSTEM_DIR=/etc/lvm_loops
./lvm vgscan

View File

@ -633,6 +633,9 @@
/* Define to 1 to include code that uses dbus notification. */
#undef NOTIFYDBUS_SUPPORT
/* Use libnvme for WWID. */
#undef NVME_SUPPORT
/* Define to 1 to enable O_DIRECT support. */
#undef O_DIRECT_SUPPORT
@ -660,6 +663,9 @@
/* Define to 1 to include the LVM readline shell. */
#undef READLINE_SUPPORT
/* Define to 1 to include code that uses sd_notify. */
#undef SD_NOTIFY_SUPPORT
/* Define to 1 to include built-in support for snapshots. */
#undef SNAPSHOT_INTERNAL

View File

@ -43,6 +43,7 @@ SOURCES =\
device/filesystem.c \
device/online.c \
device/parse_vpd.c \
device/nvme.c \
device/dev_util.c \
display/display.c \
error/errseg.c \
@ -142,7 +143,7 @@ LIB_STATIC = $(LIB_NAME).a
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
PROGS_CFLAGS = $(BLKID_CFLAGS) $(UDEV_CFLAGS)
PROGS_CFLAGS = $(BLKID_CFLAGS) $(LIBNVME_CFLAGS) $(UDEV_CFLAGS)
include $(top_builddir)/make.tmpl

View File

@ -855,7 +855,7 @@ int lv_info_with_seg_status(struct cmd_context *cmd,
/* Merge not yet started, still a snapshot... */
}
/* Hadle fictional lvm2 snapshot and query snapshotX volume */
/* Handle fictional lvm2 snapshot and query snapshotX volume */
lv_seg = find_snapshot(lv);
}
@ -936,7 +936,7 @@ int lv_check_not_in_use(const struct logical_volume *lv, int error_if_used)
log_debug_activation("Retrying open_count check for %s.",
display_lvname(lv));
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) || !info.exists) {
stack; /* device dissappeared? */
stack; /* device disappeared? */
return 1;
} else if (!info.open_count)
return 1;
@ -1006,7 +1006,7 @@ int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
int r;
struct dev_manager *dm;
/* If mirrored LV is temporarily shrinked to 1 area (= linear),
/* If mirrored LV is temporarily shrunk to 1 area (= linear),
* it should be considered in-sync. */
if (dm_list_size(&lv->segments) == 1 && first_seg(lv)->area_count == 1) {
*percent = DM_PERCENT_100;
@ -2235,7 +2235,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
(pvmove_lv = find_pvmove_lv_in_lv(lv_pre))) {
/*
* When starting PVMOVE, suspend participating LVs first
* with committed metadata by looking at precommited pvmove list.
* with committed metadata by looking at precommitted pvmove list.
* In committed metadata these LVs are not connected in any way.
*
* TODO: prepare list of LVs needed to be suspended and pass them
@ -2264,7 +2264,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
log_error("lv_list alloc failed.");
goto out;
}
/* Look for precommitted LV name in commmitted VG */
/* Look for precommitted LV name in committed VG */
if (!(lvl->lv = find_lv(lv->vg, lv_tmp->name))) {
log_error(INTERNAL_ERROR "LV %s missing from preload metadata.",
display_lvname(lv_tmp));
@ -2524,7 +2524,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
/*
* Remove any transiently activated error
* devices which arean't used any more.
* devices which aren't used any more.
*/
if (r && lv_is_raid(lv) && !lv_deactivate_any_missing_subdevs(lv)) {
log_error("Failed to remove temporary SubLVs from %s",
@ -2771,7 +2771,7 @@ static int _lv_remove_any_missing_subdevs(struct logical_volume *lv)
return 1;
}
/* Remove any "*-missing_*" sub devices added by the activation layer for an rmate/rimage missing PV mapping */
/* Remove any "*-missing_*" sub devices added by the activation layer for an rmeta/rimage missing PV mapping */
int lv_deactivate_any_missing_subdevs(const struct logical_volume *lv)
{
uint32_t s;
@ -2849,7 +2849,7 @@ static int _component_cb(struct logical_volume *lv, void *data)
* Finds out for any LV if any of its component LVs are active.
* Function first checks if an existing LV is visible and active eventually
* it's lock holding LV is already active. In such case sub LV cannot be
* actived alone and no further checking is needed.
* activated alone and no further checking is needed.
*
* Returns active component LV if there is such.
*/
@ -2912,7 +2912,7 @@ static int _deactivate_sub_lv_cb(struct logical_volume *lv, void *data)
}
/*
* Deactivates LV toghether with explicit deactivation call made also for all its component LVs.
* Deactivates LV together with explicit deactivation call made also for all its component LVs.
*/
int deactivate_lv_with_sub_lv(const struct logical_volume *lv)
{

View File

@ -449,7 +449,7 @@ static int _ignore_blocked_mirror_devices(struct cmd_context *cmd,
struct dm_task *dmt = NULL;
int r = 0;
char fake_dev_name[16];
struct device fake_dev = { 0 };
struct device fake_dev = { .fd = 0 };
struct dm_str_list *alias;
if (!(mem = dm_pool_create("blocked_mirrors", 128)))
@ -840,7 +840,7 @@ int dm_device_is_usable(struct cmd_context *cmd, struct device *dev, struct dev_
*
* This is a quick check for now, but replace it with more
* robust and better check that would check the stack
* correctly, not just snapshots but any cobimnation possible
* correctly, not just snapshots but any combination possible
* in a stack - use proper dm tree to check this instead.
*/
if (check.check_suspended &&
@ -902,6 +902,9 @@ int devno_dm_uuid(struct cmd_context *cmd, int major, int minor,
const char *uuid;
int r = 0;
if (major != (int) cmd->dev_types->device_mapper_major)
return 0;
if (dm_devs_cache_use()) {
if ((dm_dev = dm_devs_cache_get_by_devno(cmd, MKDEV(major, minor)))) {
dm_strncpy(uuid_buf, dm_dev->uuid, uuid_buf_size);
@ -2011,7 +2014,7 @@ int dev_manager_thin_device_id(struct dev_manager *dm,
if (dm_get_next_target(dmt, NULL, &start, &length,
&target_type, &params)) {
log_error("More then one table line found for %s.",
log_error("More than one table line found for %s.",
display_lvname(lv));
goto out;
}
@ -2064,7 +2067,7 @@ int dev_manager_vdo_pool_status(struct dev_manager *dm,
display_lvname(lv));
if (dm_get_next_target(dmt, NULL, &start, &length, &type, &params)) {
log_error("More then one table line found for %s.",
log_error("More than one table line found for %s.",
display_lvname(lv));
goto out;
}
@ -2118,7 +2121,7 @@ int dev_manager_vdo_pool_size_config(struct dev_manager *dm,
display_lvname(lv));
if (dm_get_next_target(dmt, NULL, &start, &length, &type, &params)) {
log_error("More then one table line found for %s.",
log_error("More than one table line found for %s.",
display_lvname(lv));
goto out;
}
@ -2337,7 +2340,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
* Check for device holders (ATM used only for removed pvmove targets)
* and add them into dtree structures.
* When 'laopts != NULL' add them as new nodes - which also corrects READ_AHEAD.
* Note: correct table are already explicitelly PRELOADED.
* Note: correct table are already explicitly PRELOADED.
*/
static int _check_holder(struct dev_manager *dm, struct dm_tree *dtree,
const struct logical_volume *lv,
@ -2770,9 +2773,10 @@ static int _add_cvol_subdev_to_dtree(struct dev_manager *dm, struct dm_tree *dtr
const struct logical_volume *pool_lv = lvseg->pool_lv;
struct dm_info info;
char *name ,*dlid;
union lvid lvid = { { lv->vg->id, _get_id_for_meta_or_data(lvseg, meta_or_data) } };
union lvid lvid = { .id = { lv->vg->id, _get_id_for_meta_or_data(lvseg, meta_or_data) } };
lvid.s[sizeof(lvid.id)] = 0;
if (!(dlid = dm_build_dm_uuid(mem, UUID_PREFIX, (const char *)&lvid.s, layer)))
if (!(dlid = dm_build_dm_uuid(mem, UUID_PREFIX, lvid.s, layer)))
return_0;
/* Name is actually not really needed here, but aids debugging... */
@ -2884,7 +2888,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
.send_messages = 1 /* Node with messages */
};
/*
* Add some messsages if right node exist in the table only
* Add some messages if right node exist in the table only
* when building SUSPEND tree for origin-only thin-pool.
*
* TODO: Fix call of '_add_target_to_dtree()' to add message
@ -3423,9 +3427,10 @@ static int _add_new_cvol_subdev_to_dtree(struct dev_manager *dm,
const struct logical_volume *pool_lv = lvseg->pool_lv;
struct dm_tree_node *dnode;
char *dlid, *dlid_pool, *name;
union lvid lvid = { { lv->vg->id, _get_id_for_meta_or_data(lvseg, meta_or_data) } };
union lvid lvid = { .id = { lv->vg->id, _get_id_for_meta_or_data(lvseg, meta_or_data) } };
lvid.s[sizeof(lvid.id)] = 0;
if (!(dlid = dm_build_dm_uuid(dm->mem, UUID_PREFIX, (const char *)&lvid.s, layer)))
if (!(dlid = dm_build_dm_uuid(dm->mem, UUID_PREFIX, lvid.s, layer)))
return_0;
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, pool_lv->name, layer)))
@ -3610,7 +3615,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
* so just use the tree's existing nodes' info
*/
if ((dinfo = _cached_dm_info(dm->mem, dtree, lv, NULL))) {
/* Merging origin LV is present, check if mergins is already running. */
/* Merging origin LV is present, check if merging is already running. */
if ((seg_is_thin_volume(seg) && _lv_has_thin_device_id(dm->mem, lv, NULL, seg->device_id)) ||
(!seg_is_thin_volume(seg) && lv_has_target_type(dm->mem, lv, NULL, TARGET_NAME_SNAPSHOT_MERGE))) {
log_debug_activation("Merging of snapshot volume %s to origin %s is in progress.",

View File

@ -16,8 +16,12 @@
#ifndef _LVM_TARGETS_H
#define _LVM_TARGETS_H
#include <stddef.h>
#include <stdint.h>
struct dev_manager;
struct lv_segment;
struct dm_tree_node;
int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
char *params, size_t paramsize, int *pos,

129
lib/cache/lvmcache.c vendored
View File

@ -21,7 +21,6 @@
#include "lib/device/device_id.h"
#include "lib/locking/locking.h"
#include "lib/metadata/metadata.h"
#include "lib/mm/memlock.h"
#include "lib/format_text/format-text.h"
#include "lib/config/config.h"
#include "lib/filters/filter.h"
@ -1052,6 +1051,8 @@ next:
log_debug_cache("PV %s with duplicates unselected using %s.",
pvid, dev_name(devl->dev));
goto next;
} else if (dm_list_empty(&altdevs)) {
goto next;
} else {
devl = dm_list_item(dm_list_first(&altdevs), struct device_list);
dev1 = devl->dev;
@ -1460,7 +1461,7 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
* not careful to do it only when there's a good reason to believe a
* dev is an md component.
*
* If the pv/dev size mismatches are commonly occuring for
* If the pv/dev size mismatches are commonly occurring for
* non-md-components then we'll want to stop using that as a trigger
* for the full md check.
*/
@ -1545,7 +1546,7 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
* incorrectly placed PVs should have been moved from the orphan vginfo
* onto their correct vginfo's, and the orphan vginfo should (in theory)
* represent only real orphan PVs. (Note: if lvmcache_label_scan is run
* after vg_read udpates to lvmcache state, then the lvmcache will be
* after vg_read updates to lvmcache state, then the lvmcache will be
* incorrect again, so do not run lvmcache_label_scan during the
* processing phase.)
*
@ -1952,7 +1953,7 @@ static int _lvmcache_update_vgname(struct cmd_context *cmd,
log_warn("WARNING: VG name %s is used by VGs %s and %s.",
vgname, vgid_dashed, other_dashed);
log_warn("Fix duplicate VG names with vgrename uuid, a device filter, or system IDs.");
log_warn("WARNING: fix duplicate VG names with vgrename uuid, or vgrename --devices");
}
if (!vginfo_is_allowed && !other_is_allowed) {
@ -2095,12 +2096,17 @@ int lvmcache_update_vgname_and_id(struct cmd_context *cmd, struct lvmcache_info
vgid = vgname;
}
/* FIXME: remove this, it shouldn't be needed */
/* If PV without mdas is already in a real VG, don't make it orphan */
if (is_orphan_vg(vgname) && info->vginfo &&
mdas_empty_or_ignored(&info->mdas) &&
!is_orphan_vg(info->vginfo->vgname) && critical_section())
/*
* This happens when vgremove does pv_write to make a PV
* that was previously part of a VG into a new orphan.
* FIXME: change pv_write to not use or update lvmcache,
* which should only be updated by label_scan.
*/
if (is_orphan_vg(vgname) && info->vginfo && !is_orphan_vg(info->vginfo->vgname)) {
log_debug("lvmcache change %s to orphan from previous VG %s.",
dev_name(info->dev), info->vginfo->vgname);
return 1;
}
/*
* Creates a new vginfo struct for this vgname/vgid if none exists,
@ -2241,7 +2247,7 @@ int lvmcache_update_vgname_and_id(struct cmd_context *cmd, struct lvmcache_info
if (!_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host,
vgsummary->lock_type, vgsummary->system_id)) {
/*
* This shouldn't happen, it's an internal errror, and we can leave
* This shouldn't happen, it's an internal error, and we can leave
* the info in place without saving the summary values in vginfo.
*/
log_error("Failed to update VG %s info in lvmcache.", vgname);
@ -2263,7 +2269,7 @@ int lvmcache_update_vgname_and_id(struct cmd_context *cmd, struct lvmcache_info
* using the 'vg'.
*/
int lvmcache_update_vg_from_read(struct volume_group *vg, unsigned precommitted)
void lvmcache_update_vg_from_read(struct volume_group *vg, int *incorrect_pv_claim)
{
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
@ -2283,9 +2289,11 @@ int lvmcache_update_vg_from_read(struct volume_group *vg, unsigned precommitted)
if (!(vginfo = lvmcache_vginfo_from_vgname(vg->name, vgid))) {
log_error(INTERNAL_ERROR "lvmcache_update_vg %s no vginfo", vg->name);
return 0;
return;
}
log_debug_cache("lvmcache_update_vg %s vginfo from metadata", vg->name);
/*
* The label scan doesn't know when a PV with old metadata has been
* removed from the VG. Now with the vg we can tell, so remove the
@ -2324,8 +2332,32 @@ int lvmcache_update_vg_from_read(struct volume_group *vg, unsigned precommitted)
continue;
}
log_debug_cache("lvmcache_update_vg %s for info %s",
vg->name, dev_name(info->dev));
/*
* If this PV info is already attached to a different VG, don't
* override that. The info/vginfo map a PV to a VG based on the
* metadata which appears on the PV itself. That has precedence
* over a different mapping of PV to another VG (the vg arg here)
* which is likely outdated metadata from some other device.
*/
if (info->vginfo && !is_orphan_vg(info->vginfo->vgname) &&
(strcmp(info->vginfo->vgname, vg->name) || memcmp(info->vginfo->vgid, &vg->id, ID_LEN))) {
char vgid_old[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
char vgid_new[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
memcpy(vgid_old, &vg->id, ID_LEN);
memcpy(vgid_new, info->vginfo->vgid, ID_LEN);
if (!strcmp(info->vginfo->vgname, vg->name))
log_warn("WARNING: PV %s %s belongs to VGID %s, ignoring claim from VGID %s (%s).",
dev_name(info->dev), pvid, vgid_new, vgid_old, vg->name);
else
log_warn("WARNING: PV %s %s belongs to VG %s, ignoring claim from VG %s.",
dev_name(info->dev), pvid, info->vginfo->vgname, vg->name);
pvl->pv->wrong_vg = 1;
*incorrect_pv_claim = 1;
continue;
}
log_debug_cache("lvmcache_update_vg %s for %s", vg->name, dev_name(info->dev));
/*
* FIXME: use a different function that just attaches info's that
@ -2357,8 +2389,6 @@ int lvmcache_update_vg_from_read(struct volume_group *vg, unsigned precommitted)
break;
}
}
return 1;
}
/*
@ -3201,6 +3231,73 @@ bool lvmcache_is_outdated_dev(struct cmd_context *cmd,
return false;
}
/*
* Metadata is being processed which shows 'vg' containing 'pv'.
* Verify that this is consistent with the headers/metadata that
* were scanned from PV. The headers/metadata scanned from the
* actual PV could be different from what 'vg' metadata claims,
* if the 'vg' metadata is old/outdated.
*/
int lvmcache_verify_info_in_vg(struct volume_group *vg, struct lvmcache_info *info)
{
char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
memcpy(vgid, &vg->id, ID_LEN);
if (!info->dev) {
log_error(INTERNAL_ERROR "Verify PV info in %s: skip, no dev", vg->name);
return 1;
}
if (!info->dev->pvid[0]) {
log_debug("Verify PV %s in %s: uncertain, no pvid",
dev_name(info->dev), vg->name);
return 1;
}
if (!info->vginfo) {
log_debug("Verify PV %s %s in %s: uncertain, no vginfo",
info->dev->pvid, dev_name(info->dev), vg->name);
return 1;
}
if (strcmp(vg->name, info->vginfo->vgname)) {
log_debug("Verify PV %s %s in %s: fail, other VG %s",
info->dev->pvid, dev_name(info->dev), vg->name, info->vginfo->vgname);
return 0;
}
if (memcmp(vgid, info->vginfo->vgid, ID_LEN)) {
log_debug("Verify PV %s %s in %s: fail, other vgid %s",
info->dev->pvid, dev_name(info->dev), vg->name, info->vginfo->vgid);
return 0;
}
return 1;
}
int lvmcache_verify_pv_in_vg(struct volume_group *vg, struct physical_volume *pv)
{
struct lvmcache_info *info;
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
memcpy(&pvid, &pv->id.uuid, ID_LEN);
if (!(info = lvmcache_info_from_pvid(pvid, NULL, 0))) {
log_debug("Verify PV %s in %s: skip, no info", pvid, vg->name);
return 1;
}
if (pv->dev != info->dev) {
log_debug("Verify PV %s in %s: skip, different devs", info->dev->pvid, vg->name);
return 1;
}
return lvmcache_verify_info_in_vg(vg, info);
}
const char *dev_filtered_reason(struct device *dev)
{
if (dev->filtered_flags & DEV_FILTERED_REGEX)

View File

@ -83,7 +83,7 @@ void lvmcache_del_dev(struct device *dev);
/* Update things */
int lvmcache_update_vgname_and_id(struct cmd_context *cmd, struct lvmcache_info *info,
struct lvmcache_vgsummary *vgsummary);
int lvmcache_update_vg_from_read(struct volume_group *vg, unsigned precommitted);
void lvmcache_update_vg_from_read(struct volume_group *vg, int *incorrect_pv_claim);
void lvmcache_lock_vgname(const char *vgname, int read_only);
void lvmcache_unlock_vgname(const char *vgname);
@ -98,7 +98,7 @@ struct lvmcache_info *lvmcache_info_from_pvid(const char *pvid, struct device *d
struct lvmcache_info *lvmcache_info_from_pv_id(const struct id *pv_id, struct device *dev, int valid_only);
const char *lvmcache_vgname_from_vgid(struct dm_pool *mem, const char *vgid);
const char *lvmcache_vgid_from_vgname(struct cmd_context *cmd, const char *vgname);
struct device *lvmcache_device_from_pv_id(struct cmd_context *cmd, const struct id *pv_id, uint64_t *label_sector);
struct device *lvmcache_device_from_pv_id(struct cmd_context *cmd, const struct id *pvid, uint64_t *label_sector);
const char *lvmcache_vgname_from_info(struct lvmcache_info *info);
const struct format_type *lvmcache_fmt_from_info(struct lvmcache_info *info);
@ -190,6 +190,9 @@ void lvmcache_save_metadata_size(uint64_t val);
bool lvmcache_has_old_metadata(struct cmd_context *cmd, const char *vgname, const char *vgid, struct device *dev);
int lvmcache_verify_pv_in_vg(struct volume_group *vg, struct physical_volume *pv);
int lvmcache_verify_info_in_vg(struct volume_group *vg, struct lvmcache_info *info);
void lvmcache_get_outdated_devs(struct cmd_context *cmd,
const char *vgname, const char *vgid,
struct dm_list *devs);

View File

@ -82,7 +82,7 @@ static void _cache_display(const struct lv_segment *seg)
/*
* When older metadata are loaded without newer settings,
* set then to default settings (the one that could have been
* used implicitely at that time).
* used implicitly at that time).
*
* Needs both segments cache and cache_pool to be loaded.
*/
@ -144,8 +144,8 @@ static int _settings_text_import(struct lv_segment *seg,
* Read in policy args:
* policy_settings {
* migration_threshold=2048
* sequention_threashold=100
* random_threashold=200
* sequential_threshold=100
* random_threshold=200
* read_promote_adjustment=10
* write_promote_adjustment=20
* discard_promote_adjustment=40
@ -202,8 +202,7 @@ static int _settings_text_export(const struct lv_segment *seg,
}
static int _cache_pool_text_import(struct lv_segment *seg,
const struct dm_config_node *sn,
struct dm_hash_table *pv_hash __attribute__((unused)))
const struct dm_config_node *sn)
{
struct logical_volume *data_lv, *meta_lv;
const char *str = NULL;
@ -277,7 +276,7 @@ static int _cache_pool_text_export(const struct lv_segment *seg,
outf(f, "metadata_format = " FMTu32, seg->cache_metadata_format);
break;
default:
log_error(INTERNAL_ERROR "LV %s is using unknown cache metadada format %u.",
log_error(INTERNAL_ERROR "LV %s is using unknown cache metadata format %u.",
display_lvname(seg->lv), seg->cache_metadata_format);
return 0;
}
@ -438,8 +437,7 @@ static const struct segtype_handler _cache_pool_ops = {
};
static int _cache_text_import(struct lv_segment *seg,
const struct dm_config_node *sn,
struct dm_hash_table *pv_hash __attribute__((unused)))
const struct dm_config_node *sn)
{
struct logical_volume *pool_lv, *origin_lv;
const char *name;
@ -634,7 +632,7 @@ static int _cache_add_target_line(struct dev_manager *dm,
return_0;
if (!(attr & CACHE_FEATURE_METADATA2)) {
log_error("LV %s has metadata format %u unsuported by kernel.",
log_error("LV %s has metadata format %u unsupported by kernel.",
display_lvname(seg->lv), setting_seg->cache_metadata_format);
return 0;
}
@ -706,7 +704,7 @@ static int _cache_add_target_line(struct dev_manager *dm,
}
};
/* Check if cache settings are acceptable to knownm policies */
/* Check if cache settings are acceptable to known policies */
for (i = 0; i < DM_ARRAY_SIZE(_accepted); i++) {
if (strcasecmp(cache_pool_seg->policy_name, _accepted[i].name))
continue;

View File

@ -12,7 +12,7 @@
enum {
#define cmd(a, b) a ,
#include "cmds.h"
#include "include/cmds.h"
#undef cmd
};

View File

@ -658,7 +658,7 @@ static int _process_config(struct cmd_context *cmd)
{
mode_t old_umask;
const char *dev_ext_info_src = NULL;
const char *read_ahead;
const char *read_ahead, *validate_metadata;
struct stat st;
const struct dm_config_node *cn;
const struct dm_config_value *cv;
@ -744,6 +744,15 @@ static int _process_config(struct cmd_context *cmd)
return 0;
}
cmd->vg_write_validates_vg = 1;
if ((validate_metadata = find_config_tree_str(cmd, config_validate_metadata_CFG, NULL))) {
if (!strcasecmp(validate_metadata, "none"))
cmd->vg_write_validates_vg = 0;
else if (strcasecmp(validate_metadata, "full"))
log_warn("WARNING: Ignoring unknown validate_metadata setting: %s.",
validate_metadata);
}
/*
* If udev is disabled using DM_DISABLE_UDEV environment
* variable, override existing config and hardcode these:
@ -1228,7 +1237,7 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
* sysfs filter. Only available on 2.6 kernels. Non-critical.
* Eliminates unavailable devices.
* TODO: this may be unnecessary now with device ids
* (currently not used for devs match to device id using syfs)
* (currently not used for devs match to device id using sysfs)
*/
if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) {
if ((filters[nr_filt] = sysfs_filter_create(dm_sysfs_dir())))
@ -1237,7 +1246,7 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
/* usable device filter. Required. */
if (!(filters[nr_filt] = usable_filter_create(cmd, cmd->dev_types))) {
log_error("Failed to create usabled device filter");
log_error("Failed to create usable device filter");
goto bad;
}
nr_filt++;
@ -1312,7 +1321,7 @@ int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
init_ignore_lvm_mirrors(find_config_tree_bool(cmd, devices_ignore_lvm_mirrors_CFG, NULL));
/*
* persisent filter is a cache of the previous result real filter result.
* persistent filter is a cache of the previous result real filter result.
* If a dev is found in persistent filter, the pass/fail result saved by
* the pfilter is used. If a dev does not existing in the persistent
* filter, the dev is passed on to the real filter, and when the result
@ -1428,8 +1437,8 @@ static int _init_segtypes(struct cmd_context *cmd)
struct segment_type *segtype;
struct segtype_library seglib = { .cmd = cmd, .lib = NULL };
struct segment_type *(*init_segtype_array[])(struct cmd_context *cmd) = {
init_linear_segtype,
init_striped_segtype,
init_linear_segtype,
init_zero_segtype,
init_error_segtype,
/* disabled until needed init_free_segtype, */

View File

@ -19,6 +19,8 @@
#include "lib/device/dev-cache.h"
#include "lib/device/dev-type.h"
#include "lib/commands/cmd_enum.h"
#include "lib/log/lvm-logging.h"
#include "lib/misc/lvm-string.h"
#include <limits.h>
@ -163,6 +165,10 @@ struct cmd_context {
unsigned vg_read_print_access_error:1; /* print access errors from vg_read */
unsigned allow_mixed_block_sizes:1;
unsigned force_access_clustered:1;
unsigned lockd_creating_thin_pool:1;
unsigned lockd_creating_thin_volume:1;
unsigned lockd_created_thin_pool:1;
unsigned lockd_created_thin_volume:1;
unsigned lockd_gl_disable:1;
unsigned lockd_vg_disable:1;
unsigned lockd_lv_disable:1;
@ -218,6 +224,7 @@ struct cmd_context {
unsigned device_ids_invalid:1;
unsigned device_ids_auto_import:1;
unsigned get_vgname_from_options:1; /* used by lvconvert */
unsigned vg_write_validates_vg:1;
/*
* Devices and filtering.
@ -271,7 +278,7 @@ struct cmd_context {
/*
* Buffers.
*/
char display_buffer[NAME_LEN * 10]; /* ring buffer for upto 10 longest vg/lv names */
char display_buffer[NAME_LEN * 10]; /* ring buffer for up to 10 longest vg/lv names */
unsigned display_lvname_idx; /* index to ring buffer */
char *linebuffer;

View File

@ -66,11 +66,16 @@ struct config_source {
* Map each ID to respective definition of the configuration item.
*/
static const struct cfg_def_item _cfg_def_items[CFG_COUNT + 1] = {
#define cfg_section(id, name, parent, flags, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_SECTION, {0}, (flags), since_version, {0}, deprecated_since_version, deprecation_comment, comment},
#define cfg(id, name, parent, flags, type, default_value, since_version, unconfigured_value, deprecated_since_version, deprecation_comment, comment) {id, parent, name, type, {.v_##type = (default_value)}, (flags), since_version, {.v_UNCONFIGURED = (unconfigured_value)}, deprecated_since_version, deprecation_comment, comment},
#define cfg_runtime(id, name, parent, flags, type, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, type, {.fn_##type = get_default_##id}, (flags) | CFG_DEFAULT_RUN_TIME, since_version, {.fn_UNCONFIGURED = get_default_unconfigured_##id}, deprecated_since_version, (deprecation_comment), comment},
#define cfg_array(id, name, parent, flags, types, default_value, since_version, unconfigured_value, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_ARRAY | (types), {.v_CFG_TYPE_STRING = (default_value)}, (flags), (since_version), {.v_UNCONFIGURED = (unconfigured_value)}, deprecated_since_version, deprecation_comment, comment},
#define cfg_array_runtime(id, name, parent, flags, types, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_ARRAY | (types), {.fn_CFG_TYPE_STRING = get_default_##id}, (flags) | CFG_DEFAULT_RUN_TIME, (since_version), {.fn_UNCONFIGURED = get_default_unconfigured_##id}, deprecated_since_version, deprecation_comment, comment},
#define cfg_section(id, name, parent, flags, since_version, deprecated_since_version, deprecation_comment, comment)\
{id, parent, name, CFG_TYPE_SECTION, (flags), since_version, deprecated_since_version, {0}, {0}, deprecation_comment, comment},
#define cfg(id, name, parent, flags, type, default_value, since_version, unconfigured_value, deprecated_since_version, deprecation_comment, comment)\
{id, parent, name, type, (flags), since_version, deprecated_since_version, {.v_##type = (default_value)}, {.v_UNCONFIGURED = (unconfigured_value)}, deprecation_comment, comment},
#define cfg_runtime(id, name, parent, flags, type, since_version, deprecated_since_version, deprecation_comment, comment)\
{id, parent, name, type, (flags) | CFG_DEFAULT_RUN_TIME, since_version, deprecated_since_version, {.fn_##type = get_default_##id}, {.fn_UNCONFIGURED = get_default_unconfigured_##id}, (deprecation_comment), comment},
#define cfg_array(id, name, parent, flags, types, default_value, since_version, unconfigured_value, deprecated_since_version, deprecation_comment, comment)\
{id, parent, name, CFG_TYPE_ARRAY | (types), (flags), (since_version), deprecated_since_version, {.v_CFG_TYPE_STRING = (default_value)}, {.v_UNCONFIGURED = (unconfigured_value)}, deprecation_comment, comment},
#define cfg_array_runtime(id, name, parent, flags, types, since_version, deprecated_since_version, deprecation_comment, comment)\
{id, parent, name, CFG_TYPE_ARRAY | (types), (flags) | CFG_DEFAULT_RUN_TIME, (since_version), deprecated_since_version, {.fn_CFG_TYPE_STRING = get_default_##id}, {.fn_UNCONFIGURED = get_default_unconfigured_##id},deprecation_comment, comment},
#include "lib/config/config_settings.h"
#undef cfg_section
#undef cfg
@ -103,7 +108,7 @@ static inline int _is_file_based_config_source(config_source_t source)
*/
struct dm_config_tree *config_open(config_source_t source,
const char *filename,
int unused)
int keep_open __attribute__((unused)))
{
struct dm_config_tree *cft = dm_config_create();
struct config_source *cs;
@ -483,7 +488,7 @@ int override_config_tree_from_profile(struct cmd_context *cmd,
int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_reason_t reason,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
int checksum_only, int no_dup_node_check)
int checksum_only, int no_dup_node_check, int only_pv_summary)
{
char namebuf[NAME_LEN + 1] __attribute__((aligned(8)));
int namelen = 0;
@ -507,7 +512,7 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
use_plain_read = 0;
/* Ensure there is extra '\0' after end of buffer since we pass
* buffer to funtions like strtoll() */
* buffer to functions like strtoll() */
if (!(buf = zalloc(size + size2 + 1))) {
log_error("Failed to allocate circular buffer.");
return 0;
@ -520,7 +525,7 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
sz = read(dev_fd(dev), buf + rsize, size - rsize);
} while ((sz < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (sz < 0) {
if (sz <= 0) {
log_sys_error("read", dev_name(dev));
goto out;
}
@ -573,7 +578,10 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
if (!checksum_only) {
fe = fb + size + size2;
if (no_dup_node_check) {
if (!dm_config_parse_without_dup_node_check(cft, fb, fe))
if (only_pv_summary) {
if (!dm_config_parse_only_section(cft, fb, fe, "physical_volumes"))
goto_out;
} else if (!dm_config_parse_without_dup_node_check(cft, fb, fe))
goto_out;
} else {
if (!dm_config_parse(cft, fb, fe))
@ -595,7 +603,7 @@ int config_file_read_from_file(struct dm_config_tree *cft)
struct config_source *cs = dm_config_get_custom(cft);
struct config_file *cf;
struct stat info;
struct device fake_dev = { 0 };
struct device fake_dev = { .fd = 0 };
struct dm_str_list *alias;
int fd;
int r;
@ -635,7 +643,7 @@ int config_file_read_from_file(struct dm_config_tree *cft)
cf->dev = &fake_dev;
r = config_file_read_fd(cft, cf->dev, DEV_IO_MDA_CONTENT, 0, (size_t) info.st_size, 0, 0,
(checksum_fn_t) NULL, 0, 0, 0);
(checksum_fn_t) NULL, 0, 0, 0, 0);
free((void*)alias->str);
free((void*)alias);
@ -924,7 +932,7 @@ static int _check_value_differs_from_default(struct cft_check_handle *handle,
case DM_CFG_FLOAT:
f = v_def ? v_def->v.f
: cfg_def_get_default_value(handle->cmd, def, CFG_TYPE_FLOAT, NULL);
diff = fabs(f - v->v.f) < FLT_EPSILON;
diff = fabsf(f - v->v.f) < FLT_EPSILON;
break;
case DM_CFG_STRING:
/* string value can be a real string but it can also represent bool */
@ -1933,11 +1941,13 @@ int config_write(struct dm_config_tree *cft,
.tree_spec = tree_spec,
.mem = cft->mem
};
int free_fp = 1;
int r = 1;
if (!file) {
baton.fp = stdout;
file = "stdout";
free_fp = 0;
} else if (!(baton.fp = fopen(file, "w"))) {
log_sys_error("open", file);
return 0;
@ -1968,7 +1978,7 @@ int config_write(struct dm_config_tree *cft,
argv++;
}
if (baton.fp && baton.fp != stdout && dm_fclose(baton.fp)) {
if (free_fp && baton.fp && dm_fclose(baton.fp)) {
stack;
r = 0;
}
@ -2558,3 +2568,18 @@ uint64_t get_default_allocation_cache_pool_max_chunks_CFG(struct cmd_context *cm
return max_chunks;
}
int get_default_allocation_vdo_use_metadata_hints_CFG(struct cmd_context *cmd, struct profile *profile)
{
unsigned maj, min;
if ((sscanf(cmd->kernel_vsn, "%u.%u", &maj, &min) == 2) &&
((maj > 6) || ((maj == 6) && (min > 8)))) {
/* With kernels > 6.8 this feature is considered deprecated.
* Return false as default setting. */
return false;
}
/* With older kernels use the configured default setting. */
return DEFAULT_VDO_USE_METADATA_HINTS;
}

View File

@ -112,7 +112,7 @@ typedef union {
* and whether it can be attached to VG/LV metadata at the same time
* The CFG_PROFILABLE_METADATA flag incorporates CFG_PROFILABLE flag!!! */
#define CFG_PROFILABLE_METADATA 0x0030
/* whether the default value is undefned */
/* whether the default value is undefined */
#define CFG_DEFAULT_UNDEFINED 0x0040
/* whether the default value is commented out on output */
#define CFG_DEFAULT_COMMENTED 0x0080
@ -134,14 +134,14 @@ typedef struct cfg_def_item {
int parent; /* ID of parent item */
const char *name; /* name of the item in configuration tree */
int type; /* configuration item type (bits of cfg_def_type_t) */
cfg_def_value_t default_value; /* default value (only for settings) */
uint16_t flags; /* configuration item definition flags */
uint16_t since_version; /* version this item appeared in */
cfg_def_unconfigured_value_t default_unconfigured_value; /* default value in terms of @FOO@, pre-configured (only for settings) */
uint16_t deprecated_since_version; /* version since this item is deprecated */
cfg_def_value_t default_value; /* default value (only for settings) */
cfg_def_unconfigured_value_t default_unconfigured_value; /* default value in terms of @FOO@, pre-configured (only for settings) */
const char *deprecation_comment; /* comment about reasons for deprecation and settings that supersede this one */
const char *comment; /* comment */
const char *file_premable; /* comment text to use at the start of the file */
const char *file_preamble; /* comment text to use at the start of the file */
} cfg_def_item_t;
/* configuration definition tree types */
@ -218,7 +218,7 @@ struct cft_check_handle {
unsigned skip_if_checked:1; /* skip the check if already done before - return last state */
unsigned suppress_messages:1; /* suppress messages during the check if config item is found invalid */
unsigned check_diff:1; /* check if the value used differs from default one */
unsigned ignoreadvanced:1; /* do not include advnced configs */
unsigned ignoreadvanced:1; /* do not include advanced configs */
unsigned ignoreunsupported:1; /* do not include unsupported configs */
uint16_t disallowed_flags; /* set of disallowed flags */
uint8_t status[CFG_COUNT]; /* flags for each configuration item - the result of the check */
@ -243,7 +243,7 @@ struct dm_config_tree *config_open(config_source_t source, const char *filename,
int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_reason_t reason,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
int skip_parse, int no_dup_node_check);
int checksum_only, int no_dup_node_check, int only_pv_summary);
int config_file_read_from_file(struct dm_config_tree *cft);
struct dm_config_tree *config_file_open_and_read(const char *config_file, config_source_t source,
struct cmd_context *cmd);
@ -312,6 +312,8 @@ int get_default_allocation_cache_pool_chunk_size_CFG(struct cmd_context *cmd, st
const char *get_default_allocation_cache_policy_CFG(struct cmd_context *cmd, struct profile *profile);
#define get_default_unconfigured_allocation_cache_policy_CFG NULL
uint64_t get_default_allocation_cache_pool_max_chunks_CFG(struct cmd_context *cmd, struct profile *profile);
int get_default_allocation_vdo_use_metadata_hints_CFG(struct cmd_context *cmd, struct profile *profile);
#define get_default_unconfigured_allocation_vdo_use_metadata_hints_CFG NULL
int get_default_metadata_pvmetadatasize_CFG(struct cmd_context *cmd, struct profile *profile);
#define get_default_unconfigured_metadata_pvmetadatasize_CFG NULL

View File

@ -47,7 +47,7 @@
*
* flags: Configuration item flags:
* CFG_NAME_VARIABLE - configuration node name is variable
* CFG_ALLOW_EMPTY - node value can be emtpy
* CFG_ALLOW_EMPTY - node value can be empty
* CFG_ADVANCED - this node belongs to advanced config set
* CFG_UNSUPPORTED - this node is not officially supported and it's used primarily by developers
* CFG_PROFILABLE - this node is customizable by a profile
@ -59,7 +59,7 @@
* CFG_SECTION_NO_CHECK - do not check content of the section at all - use with care!!!
* CFG_DISALLOW_INTERACTIVE - disallow configuration node for use in interactive environment (e.g. cmds run in lvm shell)
*
* type: Allowed type for the value of simple configuation setting, one of:
* type: Allowed type for the value of simple configuration setting, one of:
* CFG_TYPE_BOOL
* CFG_TYPE_INT
* CFG_TYPE_FLOAT
@ -214,6 +214,16 @@ cfg(config_checks_CFG, "checks", config_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_
"without any warning (a message about the configuration key not being\n"
"found is issued in verbose mode only).\n")
cfg(config_validate_metadata_CFG, "validate_metadata", config_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ADVANCED, CFG_TYPE_STRING, DEFAULT_VALIDATE_METADATA, vsn(2, 3, 28), NULL, 0, NULL,
"Allows to select the level of validation after metadata transformation.\n"
"Validation takes extra CPU time to verify internal consistency.\n"
"Accepted values:\n"
" full\n"
" Do a full metadata validation before disk write.\n"
" none\n"
" Skip any checks (unrecommended, slightly faster).\n"
"#\n")
cfg(config_abort_on_errors_CFG, "abort_on_errors", config_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2,2,99), NULL, 0, NULL,
"Abort the LVM process if a configuration mismatch is found.\n")
@ -283,7 +293,7 @@ cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, C
cfg(devices_use_devicesfile_CFG, "use_devicesfile", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_DEVICES_FILE, vsn(2, 3, 12), "@DEFAULT_USE_DEVICES_FILE@", 0, NULL,
"Enable or disable the use of a devices file.\n"
"When enabled, lvm will only use devices that\n"
"are lised in the devices file. A devices file will\n"
"are listed in the devices file. A devices file will\n"
"be used, regardless of this setting, when the --devicesfile\n"
"option is set to a specific file name.\n")
@ -663,7 +673,7 @@ cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", alloc
cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, 0, vsn(2, 2, 165), NULL, 0, NULL,
"The maximum number of chunks in a cache pool.\n"
"For cache target v1.9 the recommended maximumm is 1000000 chunks.\n"
"For cache target v1.9 the recommended maximum is 1000000 chunks.\n"
"Using cache pool with more chunks may degrade cache performance.\n")
cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL, 0, NULL,
@ -671,7 +681,7 @@ cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_
cfg(allocation_thin_pool_crop_metadata_CFG, "thin_pool_crop_metadata", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_CROP_METADATA, vsn(2, 3, 12), NULL, 0, NULL,
"Older version of lvm2 cropped pool's metadata size to 15.81 GiB.\n"
"This is slightly less then the actual maximum 15.88 GiB.\n"
"This is slightly less than the actual maximum 15.88 GiB.\n"
"For compatibility with older version and use of cropped size set to 1.\n")
cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL, 0, NULL,
@ -728,8 +738,8 @@ cfg(allocation_vdo_use_deduplication_CFG, "vdo_use_deduplication", allocation_CF
"Deduplication may be disabled in instances where data is not expected\n"
"to have good deduplication rates but compression is still desired.\n")
cfg(allocation_vdo_use_metadata_hints_CFG, "vdo_use_metadata_hints", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_USE_METADATA_HINTS, VDO_1ST_VSN, NULL, 0, NULL,
"Enables or disables whether VDO volume should tag its latency-critical\n"
cfg_runtime(allocation_vdo_use_metadata_hints_CFG, "vdo_use_metadata_hints", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, VDO_1ST_VSN, vsn(2, 3, 27), NULL,
"Deprecated enablement whether VDO volume should tag its latency-critical\n"
"writes with the REQ_SYNC flag. Some device mapper targets such as dm-raid5\n"
"process writes with this flag at a higher priority.\n")
@ -821,8 +831,8 @@ cfg(allocation_vdo_physical_threads_CFG, "vdo_physical_threads", allocation_CFG_
"vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be\n"
"either all zero or all non-zero.\n")
cfg(allocation_vdo_write_policy_CFG, "vdo_write_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_VDO_WRITE_POLICY, VDO_1ST_VSN, NULL, 0, NULL,
"Specifies the write policy:\n"
cfg(allocation_vdo_write_policy_CFG, "vdo_write_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_VDO_WRITE_POLICY, VDO_1ST_VSN, NULL, vsn(2, 3, 27), NULL,
"Deprecated option to specify the write policy with these accepted values:\n"
"auto - VDO will check the storage device and determine whether it supports flushes.\n"
" If it does, VDO will run in async mode, otherwise it will run in sync mode.\n"
"sync - Writes are acknowledged only after data is stably written.\n"
@ -859,7 +869,10 @@ cfg(log_report_command_log_CFG, "report_command_log", log_CFG_SECTION, CFG_PROFI
"option. Use log/command_log_cols and log/command_log_sort settings\n"
"to define fields to display and sort fields for the log report.\n"
"You can also use log/command_log_selection to define selection\n"
"criteria used each time the log is reported.\n")
"criteria used each time the log is reported.\n"
"Note that if report/output_format (or --reportformat command line\n"
"option) is set to json or json_std, then log/report_command_log=1\n"
"is default.\n")
cfg(log_command_log_sort_CFG, "command_log_sort", log_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED | CFG_DISALLOW_INTERACTIVE, CFG_TYPE_STRING, DEFAULT_COMMAND_LOG_SORT, vsn(2, 2, 158), NULL, 0, NULL,
"List of columns to sort by when reporting command log.\n"
@ -883,8 +896,9 @@ cfg(log_command_log_selection_CFG, "command_log_selection", log_CFG_SECTION, CFG
"define selection criteria for log report on command line directly\n"
"using <lvm command> --configreport log -S <selection criteria>\n"
"which has precedence over log/command_log_selection setting.\n"
"For more information about selection criteria in general, see\n"
"lvm(8) man page.\n")
"To make all the command log lines visible, use \"all\" value\n"
"for the command log selection. For more information about selection\n"
"criteria in general, see lvmreport(7) man page.\n")
cfg(log_verbose_CFG, "verbose", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VERBOSE, vsn(1, 0, 0), NULL, 0, NULL,
"Controls the messages sent to stdout or stderr.\n")
@ -1185,6 +1199,14 @@ cfg(global_sanlock_lv_extend_CFG, "sanlock_lv_extend", global_CFG_SECTION, CFG_D
"and can cause lvcreate to fail. Applicable only if LVM is compiled\n"
"with lockd support\n")
cfg(global_sanlock_align_size_CFG, "sanlock_align_size", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_SANLOCK_ALIGN_SIZE, vsn(2, 3, 27), NULL, 0, NULL,
"The sanlock lease size in MiB to use on disks with a 4K sector size.\n"
"Possible values are 1,2,4,8. The default is 8, which supports up to\n"
"2000 hosts (and max host_id 2000.) Smaller values support smaller\n"
"numbers of max hosts (and max host_ids): 250, 500, 1000, 2000 for\n"
"lease sizes 1,2,4,8. Disks with 512 byte sectors always use 1MiB\n"
"leases and support 2000 hosts, and are not affected by this setting.\n")
cfg(global_lvmlockctl_kill_command_CFG, "lvmlockctl_kill_command", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "", vsn(2, 3, 12), NULL, 0, NULL,
"The command that lvmlockctl --kill should use to force LVs offline.\n"
"The lvmlockctl --kill command is run when a shared VG has lost\n"
@ -1420,11 +1442,14 @@ cfg(activation_use_linear_target_CFG, "use_linear_target", activation_CFG_SECTIO
cfg(activation_reserved_stack_CFG, "reserved_stack", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_RESERVED_STACK, vsn(1, 0, 0), NULL, 0, NULL,
"Stack size in KiB to reserve for use while devices are suspended.\n"
"Insufficient reserve risks I/O deadlock during device suspension.\n")
"Insufficient reserve risks I/O deadlock during device suspension.\n"
"Value 0 disables memory locking.\n")
cfg(activation_reserved_memory_CFG, "reserved_memory", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_RESERVED_MEMORY, vsn(1, 0, 0), NULL, 0, NULL,
"Memory size in KiB to reserve for use while devices are suspended.\n"
"Insufficient reserve risks I/O deadlock during device suspension.\n")
"Insufficient reserve risks I/O deadlock during device suspension.\n"
"Value 0 disables memory locking.\n")
cfg(activation_process_priority_CFG, "process_priority", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_PROCESS_PRIORITY, vsn(1, 0, 0), NULL, 0, NULL,
"Nice value used while devices are suspended.\n"
@ -1740,7 +1765,7 @@ cfg(activation_mode_CFG, "activation_mode", activation_CFG_SECTION, CFG_DEFAULT_
" uses are present. Other PVs in the Volume Group may be missing.\n"
" degraded\n"
" Like complete, but additionally RAID LVs of segment type raid1,\n"
" raid4, raid5, radid6 and raid10 will be activated if there is no\n"
" raid4, raid5, raid6 and raid10 will be activated if there is no\n"
" data loss, i.e. they have sufficient redundancy to present the\n"
" entire addressable range of the Logical Volume.\n"
" partial\n"
@ -1840,7 +1865,7 @@ cfg(report_output_format_CFG, "output_format", report_CFG_SECTION, CFG_PROFILABL
"If there is more than one report per command, then the format\n"
"is applied for all reports. You can also change output format\n"
"directly on command line using --reportformat option which\n"
"has precedence over log/output_format setting.\n"
"has precedence over report/output_format setting.\n"
"Accepted values:\n"
" basic\n"
" Original format with columns and rows. If there is more than\n"
@ -1853,8 +1878,8 @@ cfg(report_output_format_CFG, "output_format", report_CFG_SECTION, CFG_PROFILABL
" Compared to original \"json\" format:\n"
" - it does not use double quotes around numeric values,\n"
" - it uses 'null' for undefined numeric values,\n"
" - it prints string list as proper JSON array of strings instead of a single string."
"\n")
" - it prints string list as proper JSON array of strings instead of a single string.\n"
"Note that if json or json_std output format is used, then log/command_log_report=1 is default.\n")
cfg(report_compact_output_CFG, "compact_output", report_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_REP_COMPACT_OUTPUT, vsn(2, 2, 115), NULL, 0, NULL,
"Do not print empty values for all report fields.\n"
@ -1953,7 +1978,7 @@ cfg(report_time_format_CFG, "time_format", report_CFG_SECTION, CFG_PROFILABLE |
" %F\n"
" Equivalent to %Y-%m-%d (the ISO 8601 date format).\n"
" %G\n"
" The ISO 8601 week-based year with century as adecimal number.\n"
" The ISO 8601 week-based year with century as a decimal number.\n"
" The 4-digit year corresponding to the ISO week number (see %V).\n"
" This has the same format and value as %Y, except that if the\n"
" ISO week number belongs to the previous or next year, that year\n"
@ -2260,8 +2285,9 @@ cfg_array(local_extra_system_ids_CFG, "extra_system_ids", local_CFG_SECTION, CFG
"correct usage and possible dangers.\n")
cfg(local_host_id_CFG, "host_id", local_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 124), NULL, 0, NULL,
"The lvmlockd sanlock host_id.\n"
"This must be unique among all hosts, and must be between 1 and 2000.\n"
"Applicable only if LVM is compiled with lockd support\n")
"The sanlock host_id used by lvmlockd. This must be unique among all the hosts\n"
"using shared VGs with sanlock. Accepted values are 1-2000, except when sanlock_align_size\n"
"is configured to 1, 2 or 4, which correspond to max host_id values of 250, 500, or 1000.\n"
"Applicable only if LVM is compiled with support for lvmlockd+sanlock.\n")
cfg(CFG_COUNT, NULL, root_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(0, 0, 0), NULL, 0, NULL, NULL)

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