Peter Rajnoha [Tue, 5 Nov 2024 13:20:59 +0000 (14:20 +0100)]
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.
Peter Rajnoha [Tue, 5 Nov 2024 08:26:03 +0000 (09:26 +0100)]
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 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).
Zdenek Kabelac [Tue, 5 Nov 2024 13:39:04 +0000 (14:39 +0100)]
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.
Zdenek Kabelac [Fri, 1 Nov 2024 14:20:50 +0000 (15:20 +0100)]
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().
David Teigland [Fri, 1 Nov 2024 01:29:00 +0000 (20:29 -0500)]
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.
David Teigland [Thu, 31 Oct 2024 21:31:35 +0000 (16:31 -0500)]
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.
Zdenek Kabelac [Sat, 26 Oct 2024 20:37:00 +0000 (22:37 +0200)]
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().
Zdenek Kabelac [Sat, 26 Oct 2024 20:18:19 +0000 (22:18 +0200)]
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...
Zdenek Kabelac [Thu, 31 Oct 2024 13:42:16 +0000 (14:42 +0100)]
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.
Zdenek Kabelac [Tue, 29 Oct 2024 17:44:55 +0000 (18:44 +0100)]
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.
Zdenek Kabelac [Mon, 28 Oct 2024 20:41:30 +0000 (21:41 +0100)]
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.
Zdenek Kabelac [Fri, 25 Oct 2024 12:44:50 +0000 (14:44 +0200)]
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).
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().
Zdenek Kabelac [Thu, 24 Oct 2024 14:12:18 +0000 (16:12 +0200)]
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.
Zdenek Kabelac [Thu, 24 Oct 2024 12:04:07 +0000 (14:04 +0200)]
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.
Zdenek Kabelac [Wed, 23 Oct 2024 17:22:10 +0000 (19:22 +0200)]
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.
Zdenek Kabelac [Wed, 23 Oct 2024 11:30:55 +0000 (13:30 +0200)]
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.
Zdenek Kabelac [Sun, 20 Oct 2024 20:14:39 +0000 (22:14 +0200)]
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.
Zdenek Kabelac [Wed, 23 Oct 2024 09:49:55 +0000 (11:49 +0200)]
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....
Zdenek Kabelac [Sun, 20 Oct 2024 18:48:56 +0000 (20:48 +0200)]
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.
Zdenek Kabelac [Thu, 17 Oct 2024 21:10:01 +0000 (23:10 +0200)]
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).
Zdenek Kabelac [Fri, 18 Oct 2024 22:05:45 +0000 (00:05 +0200)]
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.