1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-26 01:44:19 +03:00

Compare commits

..

9 Commits

Author SHA1 Message Date
Zdenek Kabelac
3777feb7a7 refactor: change dm_strncpy to dm_strncpy_check
For places where dm_strncpy is checked for result use
inline wrapper dm_strncpy_check.
2024-04-04 18:52:14 +02:00
Zdenek Kabelac
55f33d734f refactor: replace dm_strncpy 2024-04-04 18:52:14 +02:00
Zdenek Kabelac
25bf939e31 tests: inittest fix skipping condition 2024-04-04 18:52:14 +02:00
Zdenek Kabelac
f0a4888b33 dev_manager: improve readability
Make a seperate function to decode which ID should be user
for cvol meta or data volume - also avoids duplication of code.
As a result it's now also easier to see how the lvid is build.
2024-04-04 18:52:14 +02:00
Zdenek Kabelac
7153a5094d device_id: add comment for trim 2024-04-04 18:51:38 +02:00
Zdenek Kabelac
c317554b1d lvmlocks: rework dm_strncpy
The patch for dm_strncpy() was cutting away 1 character,
so make the buffer properly sized.

In case of use strcpy_name_len() the replacement was invalid,
so we need to restore this case since sanlock uses buffer without
nul ending, so we would strip one more character from the buffer.
2024-04-04 18:49:37 +02:00
Zdenek Kabelac
051f9c52c4 util: add dm_strncpy_check
Add inline wrapper function for dm_strncpy().
We will use this function for tested calls of this function.
This will make sure Coverity will not be emitting warnings
for every unchecked use of this function.
2024-04-04 18:49:37 +02:00
Zdenek Kabelac
17cf661867 util: switch header file orders
Ensure libdevmapper is included before util.h
2024-04-04 18:49:37 +02:00
Zdenek Kabelac
8145f8b061 cov: missing initializer
Ensure there is no code path with uninitialized takes_arg.
2024-04-04 18:49:37 +02:00
902 changed files with 26436 additions and 52798 deletions

9
.gitignore vendored
View File

@@ -14,8 +14,6 @@
*.so
*.so.*
*.sw*
*.su
*.patch
*~
# gcov files:
@@ -45,12 +43,6 @@ make.tmpl
coverity/coverity_model.xml
/.cache/
/compile_commands.json
/doc/.ikiwiki
/public
/libdm/.symver_check
daemons/clvmd
@@ -58,6 +50,7 @@ daemons/dmfilemapd
daemons/lvmetad/
tools/man-generator
tools/man-generator.c
test/.lib-dir-stamp
test/.tests-stamp

View File

@@ -16,23 +16,6 @@ approve1:
- when: on_success
allow_failure: false
pages:
image: elecnix/ikiwiki
stage: test
script:
- ikiwiki --setup ikiwiki.setup --libdir themes/ikistrap/lib
artifacts:
paths:
- public
only:
refs:
- main
changes:
- doc/**/*
- ikiwiki.setup
# TODO:
# - check results of autoreconf and make generate - may need additional commit
# - we need a particular setup (rawhide OR latest supported fedora?)

View File

@@ -55,7 +55,7 @@ po: tools daemons
man: tools
all_man: tools
test: tools daemons
unit-test run-unit-test: test libdm
unit-test run-unit-test: test
daemons.device-mapper: libdm.device-mapper
tools.device-mapper: libdm.device-mapper
@@ -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,8 +194,7 @@ ifneq ("$(GENHTML)", "")
lcov:
$(RM) -rf $(LCOV_REPORTS_DIR)
$(MKDIR_P) $(LCOV_REPORTS_DIR)
-find . -name '*.gc[dn][ao]' ! -newer make.tmpl -delete
-$(LCOV) --capture --directory $(top_builddir) --ignore-errors source,negative,gcov \
$(LCOV) --capture --directory $(top_builddir) --ignore-errors source \
--output-file $(LCOV_REPORTS_DIR)/out.info
-test ! -s $(LCOV_REPORTS_DIR)/out.info || \
$(GENHTML) -o $(LCOV_REPORTS_DIR) --ignore-errors source \

2
README
View File

@@ -1,5 +1,7 @@
This tree contains the LVM2 and device-mapper tools and libraries.
This is development branch, for stable 2.02 release see stable-2.02 branch.
For more information about LVM2 read the changelog in the WHATS_NEW file.
Installation instructions are in INSTALL.

View File

@@ -21,11 +21,6 @@ You MUST disable (or mask) any LVM daemons:
- clvmd
- cmirrord
Some lvm.conf options should be set:
- global/event_activation = 0
- activation/monitoring = 0
For running cluster tests, we are using singlenode locking. Pass
`--with-clvmd=singlenode` to configure.

View File

@@ -1 +1 @@
2.03.35(2)-git (2025-07-30)
2.03.24(2)-git (2023-11-21)

View File

@@ -1 +1 @@
1.02.209-git (2025-07-30)
1.02.198-git (2023-11-21)

302
WHATS_NEW
View File

@@ -1,151 +1,5 @@
Version 2.03.35 -
Version 2.03.24 -
==================
Fix possible report output format inconsistencies while processing PVs.
Allow report options for pv/vg/lvdisplay only if used with -C|--columns.
Fix vgsplit failing to split a VG with RAID+integrity or cache with cachevol.
Optimize dmeventd when remonitoring active devices.
Version 2.03.34 - 30th July 2025
================================
Support dmeventd restart when there are no monitored devices.
Dmeventd no longer calls 'action commands' on removed devices.
Fix reader of VDO metadata on 32bit architecture.
Fix lvmdevices --deldev/--delpvid to error out if devices file not writeable.
Fix lvresize corruption in LV->crypt->FS stack if near crypt min size limit.
Enhanced lvresize -r support for btrfs.
Use glibc standard functions htoX, Xtoh functions for endian conversion.
Fix structure copying within sanlock's release_rename().
Fix autoactivation on top of loop dev PVs to trigger once for change uevents.
Add lvmlockd --lockopt repair to reinitialize corrupted sanlock leases.
Fix support for lvcreate -T --setautoactivation.
Add lvm.conf global/lvresize_fs_helper_executable.
Enable lvm to use persistent reservations on a VG.
Version 2.03.33 - 27th June 2025
================================
Various spelling, grammar, formatting, test, and build script improvements.
Override LC_NUMERIC locale if unsuitable for json_std report format.
Repair raid arrays with transiently lost devices.
Version 2.03.32 - 05th May 2025
===============================
Lvconvert vdopool conversion properly validates acceptable LVs.
Accept thin pool data LV as cacheable 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.
Ignore PV claims from old metadata when then PV belongs to a new VG.
Fix integrity metadata rounding.
Accept --autobackup option in pvresize.
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.
Refactor DM uuid caching from device_mapper directory.
Enhance checking for DM uuid device.
Fix lvm shell command completion on tab key (2.03.24).
Avoid lockd_vg call to lvmlockd for local VGs.
Allow forced change of locktype from none.
Handle OPTIONS defined in /etc/sysconfig/lvmlockd.
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.
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 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.
Skip checking of pools for lvremove and vgremove commands.
VDO modprobes dm-vdo for 6.9 kernel and kvdo for older kernel version.
Fix lvs reporting for VDO volumes with new upstream kernel driver.
Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it.
Fix table line generation for cache snapshots using cachevol.
Enhance lvconvert support for external origins stacking.
@@ -183,7 +37,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.
Recognise lvm.conf report/headings=2 for full column names in report headings.
Recognize 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.
@@ -253,7 +107,6 @@ 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.
@@ -273,7 +126,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 losing of delete message on thin-pool extension.
Fix lossing of delete message on thin-pool extension.
Version 2.03.15 - 07th February 2022
====================================
@@ -360,7 +213,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 metadata profiles with volume VDO pool conversions.
Support metatadata 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.
@@ -391,7 +244,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 wiping LVs.
Support interruption when wipping LVs.
Support interruption for bcache waiting.
Fix bcache when device has too many failing writes.
Fix bcache waiting for IO completion with failing disks.
@@ -518,7 +371,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 _pmspare volume when extending _tmeta volume.
Fix missing growth of _pmsmare 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.
@@ -531,14 +384,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 resizing for VDOPoolLV and VDOLV.
Support reszing 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 misleading comment for metadata minimum_io_size for VDO segment.
Drop misleadning 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 querying lvmconfig unpresent config option.
Fix generator quering 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.
@@ -600,7 +453,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 reinitializing mirror log.
Reload whole device stack when reinitilizing 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.
@@ -645,7 +498,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 snapshot merge.
Preserve exclusive activation during thin snaphost merge.
Avoid exceeding array bounds in allocation tag processing.
Add --lockopt to common options and add option to skip selected locks.
@@ -661,7 +514,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 deactivation.
Deactivate missing raid LV legs (_rimage_X-missing_Y_Z) on decativation.
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.
@@ -683,7 +536,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.
Enhance pvmove locking.
Ehnance 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.
@@ -773,13 +626,13 @@ Version 2.02.173 - 20th July 2017
Version 2.02.172 - 28th June 2017
=================================
Add missing NULL to argv array when splitting cmdline arguments.
Add missing NULL to argv array when spliting 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.
Re-enable conversion of data and metadata thin-pool volumes to raid.
Reenable 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".
@@ -847,7 +700,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 boundary when create cache LV.
Skip rounding on cache chunk size boudary 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.
@@ -897,8 +750,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 split RAID LV and require explicit activation.
Always active split RAID LV exclusively locally.
Fix table load for splitted RAID LV and require explicit activation.
Always active splitted 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.
@@ -961,7 +814,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 dereference when checking for monitoring.
Fix possible NULL pointer derefence 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.
@@ -1001,7 +854,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 params in lvm shell.
Restrict in-command modification of some parms 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.
@@ -1154,11 +1007,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 processing of volumes during lvchange.
Improve support for interrupting procesing 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 existence before using modprobe.
Check first /sys/module/dm_* dir existance 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
@@ -1183,7 +1036,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 approximation with lvcreate -l%PVS thin-pool.
Reuse %FREE size aproximation 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).
@@ -1260,7 +1113,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 'unknown' for lv_{snapshot_invalid,merge_failed} with --binary.
Report -1, not 'unkown' 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.
@@ -1289,7 +1142,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 autodetection as disabled.
Fix configure to set proper use_blkid_wiping if autodetected 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.
@@ -1439,7 +1292,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 --cachesettings with lvconvert.
Enable usage of --cachepolicy and --cachesetting 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.
@@ -1596,7 +1449,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 initial contiguous allocation.
Respect allocation/cling_tag_list during intial 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.
@@ -1674,7 +1527,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 writethrough when missing in metadata.
Set default cache_mode to writehrough 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.
@@ -1740,13 +1593,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.
Initial support for external users of thin pools based on transaction_id.
Inital 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 lvconvert man pages.
Update and correct lvcreate and lvcovert 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.
@@ -1799,7 +1652,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 inability to specify cachemode when 'lvconvert'ing to cache-pool.
Fix inablility 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.
@@ -1867,7 +1720,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 functions.
Return proper error codes for some failing lvconvert funtions.
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.
@@ -1886,7 +1739,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 builddir in make pofile.
Fix use of buildir 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.
@@ -1991,7 +1844,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.
Reinitialize lvmcache properly on fork to fix premature polldaemon exit.
Reinitialise 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.
@@ -2018,7 +1871,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 querying for any message.
Fix return value in pool_has_message() when quering 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.
@@ -2060,7 +1913,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 libblkid detects signature and fails to return offset/length.
Issue error if libbblkid 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.
@@ -2133,7 +1986,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 implicitly exclusive activations.
Fix and improve logic for implicitely 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.
@@ -2296,11 +2149,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.
Release memory and unblock signals in lock_vol error path.
Relase 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 logging when user tries to interrupt commands.
Improve error loging 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
@@ -2501,7 +2354,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-snapshot LVs.
Report invalid percentage for property snap_percent of non-snaphot 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.
@@ -2551,7 +2404,7 @@ Version 2.02.98 - 15th October 2012
Version 2.02.97 - 7th August 2012
=================================
Improve documentation of allocation policies in lvm.8.
Improve documention 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.
@@ -2635,7 +2488,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 initialization of thin monitoring. (2.02.92)
Fix initializiation 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.
@@ -2648,7 +2501,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 uninitialized devices.
Change message severity for creation of VG over uninitialised 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.
@@ -2683,7 +2536,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 uninitialized bytes in cluster error reply messages.
Do not send uninitialised 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().
@@ -2756,7 +2609,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 initialization.
sync_local_dev_names before (re)activating mirror log for initialisation.
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.
@@ -2775,7 +2628,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 param to use_layer for lv_info and use with thin LVs.
Rename origin_only parm 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).
@@ -2805,7 +2658,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 dereference lv pointer in _percent_run() function before NULL check.
Do not derefence 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)
@@ -2876,11 +2729,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 initialization.
Fix log_error() usage in raid and unknown segtype initialisation.
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 exclusive locks). (2.02.64)
Fix restart of clvmd (preserve exlusive 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.
@@ -2946,13 +2799,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 uninitialized descriptors.
If pipe in clvmd fails return busy instead of using uninitialised 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.
Initialize clvmd locks before lvm context to avoid open descriptor leaks.
Initialise 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().
@@ -3025,7 +2878,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 comparison gcc warnings in the code.
Fix some unmatching sign comparation 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.
@@ -3051,7 +2904,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 initialization.
Use new alloc_fid fn for common format instance initialisation.
Optimise _get_token() and _eat_space().
Add _lv_postorder_vg() to improve efficiency for all LVs in VG.
Add gdbinit script for debugging.
@@ -3060,10 +2913,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 uninitialized bytes in local clvmd messages.
Do not send uninitialised 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 initialization in clvmd to respect lvm.conf setting.
Fix syslog initialisation 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.
@@ -3077,7 +2930,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 infrastructure for PV and VG use.
Generalise internal format_instance infrastrusture 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.
@@ -3091,7 +2944,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 reuse with same LV struct.
Clear temporary postorder LV status flags to allow re-use 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.
@@ -3146,7 +2999,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 installation path.
Fix superfluous /usr in ocf_scriptdir instalation path.
Add --with-ocfdir configurable option.
Add aclocal.m4 (for pkgconfig).
Fix memory leak in persistent filter creation error path.
@@ -3178,7 +3031,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 initialization if missing.
Create /var/run/lvm directory during clvmd initialisation 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.
@@ -3475,7 +3328,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.
Suppress activation message if there is a missing replicator VG.
Supress 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.
@@ -3526,7 +3379,7 @@ Version 2.02.65 - 17th May 2010
Version 2.02.64 - 30th April 2010
=================================
Avoid pointless initialization when the 'version' command is run directly.
Avoid pointless initialisation 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.
@@ -3685,7 +3538,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 initialization messages more descriptive.
Make failed locking initialisation messages more descriptive.
Version 2.02.59 - 21st January 2010
===================================
@@ -3701,7 +3554,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 independent.
Make cluster log communication structures architecture independant.
Fix cluster log in-memory bitmap handling.
Improve snapshot merge metadata import validation.
Improve target type compatibility checking in _percent_run().
@@ -3777,7 +3630,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 recognize type 'F' (flush) in dmeventd mirror plugin.
Log failure type and recognise 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
@@ -3815,14 +3668,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 initialization succeeded.
Delay announcing mirror monitoring to syslog until initialisation 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 implicit pvcreate support to vgcreate and vgextend.
Add implict 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.
@@ -4002,7 +3855,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 compatibility.
Do not use '-n' realine option in fsadm for busybox compatiblity.
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.
@@ -4063,7 +3916,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 dataalignment for values starting prior to MDA area. (2.02.45)
Fix PV datalignment 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.
@@ -4136,7 +3989,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 resizing ext4 filesystems.
Add fsadm support for reszing ext4 filesysystems.
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.
@@ -4313,7 +4166,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 uninitialized mutex in clvmd if all daemons are not running at startup.
Fix uninitialised 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.
@@ -4360,7 +4213,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 initialization.
Add (empty) orphan VGs to lvmcache during initialisation.
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.
@@ -4378,7 +4231,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 uninitialized variable in clvmd that could cause odd hangs.
Fix uninitialised 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.
@@ -4386,7 +4239,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 initialization into _init_text_import.
Refactor text format initialisation 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.
@@ -4436,7 +4289,7 @@ Version 2.02.31 - 19th January 2008
Version 2.02.30 - 17th January 2008
===================================
Set default readahead to twice maximum stripe size.
Set default readahead to twice maximium 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.
@@ -4808,7 +4661,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 clvmd to reload their device cache.
Add -R to clvmd which tells running clvmds 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.
@@ -5135,7 +4988,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 messages when dir was already removed.
Avoid rmdir opendir error messsages when dir was already removed.
Tighten signal handlers.
Avoid some compiler warnings.
Additional rename failure error message.
@@ -5366,7 +5219,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 displayed sizes.
Fix rounding of large diplayed sizes.
Suppress decimal point when using units of sectors/bytes.
Additional kernel target checks before pvmove & snapshot creation.
Add i2o_block.
@@ -5582,4 +5435,3 @@ Display output. Some metadata information cannot yet be displayed.
Recovery tools to salvage "lost" metadata directly from the disks:
but we hope the new format will mean such tools are hardly ever needed!

View File

@@ -1,55 +1,5 @@
Version 1.02.209 -
Version 1.02.198 -
===================
Version 1.02.208 - 30th July 2025
=================================
Version 1.02.207 - 27th June 2025
=================================
Escape the escape character itself on JSON report format output.
Fail dm_report_group_create if radix char from locale unsuitable for JSON_STD.
Version 1.02.206 - 05th May 2025
================================
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
=================================
Version 1.02.198 - 16th May 2024
================================
Fix static only compilation of libdevmapper.a and dmsetup tool.
Use better code for closing opened descriptors when starting dmeventd.
Correct dmeventd -R for systemd environment.
Restart of dmeventd -R checks pid file to detect running dmeventd first.
Query with dmeventd -i quickly ends when there is no running dmeventd.
Enhance dm_get_status_raid to handle mismatching status or reported legs.
Create /dev/disk/by-label symlinks for DM devs that have crypto as next layer.
Persist udev db for DM devs on cleanup used in initrd to rootfs transition.
@@ -127,7 +77,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 iterators with gcc 10 optimization (-ftree-pta).
Fix dm_list interators with gcc 10 optimization (-ftree-pta).
Dmeventd handles timer without looping on short intervals.
Version 1.02.169 - 11th February 2020
@@ -158,7 +108,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 completeness matching kernel.
Add DM_DEVICE_ARM_POLL for API completness matching kernel.
Do not add parameters for RESUME with DM_DEVICE_CREATE dm task.
Fix dmstats report printing no output.
@@ -187,7 +137,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_populate() for DM devices without any stats regions.
Avoid calling dm_stats_populat() 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.
@@ -236,7 +186,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 inconsistent md statuses.
dm_get_status_raid() handle better some incosistent 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).
@@ -291,7 +241,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 than 31 legs of raid.
Use unsigned math when checking more then 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
@@ -431,7 +381,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 unneeded table reloads.
Drop extra space from cache target line to fix unneded table reloads.
Version 1.02.111 - 23rd November 2015
=====================================
@@ -446,7 +396,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 dmeventd (1 hour).
Support exit on idle for dmenventd (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'.
@@ -619,7 +569,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
@@ -638,7 +588,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 transaction_id after message submitting.
Add extra check for matching transation_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.
@@ -725,7 +675,7 @@ Version 1.02.82 - 4th October 2013
Version 1.02.81 - 23rd September 2013
=====================================
Tidy dmeventd fifo initialization.
Tidy dmeventd fifo initialisation.
Version 1.02.80 - 20th September 2013
=====================================
@@ -750,7 +700,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.
Detect mounted fs also via reading /proc/self/mountinfo.
Detecte 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().
@@ -847,7 +797,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 initialize device-mapper library on load.
Add dm_lib_init to automatically initialise 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.
@@ -941,7 +891,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 suppression.
Fix read-only identical table reload supression.
Version 1.02.65 - 8th July 2011
===============================
@@ -956,7 +906,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 initialization.
Accept new kernel version 3 uname formats in initialisation.
Version 1.02.64 - 29th April 2011
==================================
@@ -970,7 +920,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 uninitialized memory use with empty params in _reload_with_suppression_v4.
Fix uninitialised 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.
@@ -1139,7 +1089,7 @@ Version 1.02.44 - 15th February 2010
Version 1.02.43 - 21st January 2010
===================================
Remove bitset, hash and pool headers superseded by libdevmapper.h.
Remove bitset, hash and pool headers superceded by libdevmapper.h.
Fix off-by-one error causing bad cluster mirror table construction.
Version 1.02.42 - 14th January 2010
@@ -1263,7 +1213,7 @@ Version 1.02.27 - 25th June 2008
Version 1.02.26 - 6th June 2008
===============================
Initialize params buffer to empty string in _emit_segment.
Initialise 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.
@@ -1319,7 +1269,7 @@ Version 1.02.20 - 15th June 2007
Version 1.02.19 - 27th April 2007
=================================
Standardize protective include file #defines.
Standardise 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.
@@ -1350,7 +1300,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 'Unrecognized field' error if report field is 'help'.
Suppress 'Unrecognised field' error if report field is 'help'.
Add --separator and --sort to dmsetup (unused).
Make alignment flag optional when specifying report fields.
@@ -1599,4 +1549,3 @@ Version 1.00.08 - 27 Feb 2004
Updated README/INSTALL to reflect move to sources.redhat.com.
Updated autoconf files to 2003-06-17.

61
aclocal.m4 vendored
View File

@@ -1,6 +1,6 @@
# generated automatically by aclocal 1.18.1 -*- Autoconf -*-
# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
# Copyright (C) 1996-2025 Free Software Foundation, Inc.
# Copyright (C) 1996-2021 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], [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
@@ -126,12 +126,6 @@ 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)))?$])
@@ -152,9 +146,6 @@ 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
@@ -422,7 +413,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-2025 Free Software Foundation, Inc.
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -456,12 +447,9 @@ 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 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
[python python2 python3 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])
@@ -656,29 +644,15 @@ try:
if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
can_use_sysconfig = 0
except ImportError:
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
pass"
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 as in early automake betas. This behavior
dnl directory like in previous automake betas. This behavior
dnl is more consistent with lispdir.m4 for example.
dnl Query sysconfig or distutils (per above) for this directory.
dnl Query distutils for this directory.
dnl
AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)],
[am_cv_python_pythondir],
@@ -690,11 +664,7 @@ except ImportError:
am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
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'})
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')
@@ -724,8 +694,7 @@ sys.stdout.write(sitedir)"`
dnl 3. pyexecdir: directory for installing python extension modules
dnl (shared libraries).
dnl Query sysconfig or distutils for this directory.
dnl Much of this is the same as for prefix setup above.
dnl Query distutils for this directory.
dnl
AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)],
[am_cv_python_pyexecdir],
@@ -737,11 +706,7 @@ sys.stdout.write(sitedir)"`
am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
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'})
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')
@@ -792,7 +757,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-2025 Free Software Foundation, Inc.
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,

View File

@@ -31,10 +31,10 @@ CLEAN_TARGETS += $(BASE_DEPENDS) $(BASE_OBJECTS) \
$(BASE_TARGET)
$(BASE_TARGET): $(BASE_OBJECTS)
$(SHOW) " [AR] $@"
@echo " [AR] $@"
$(Q) $(RM) $@
$(Q) $(AR) rsv $@ $(BASE_OBJECTS) > /dev/null
ifeq ("$(USE_TRACKING)","yes")
ifeq ("$(DEPENDS)","yes")
-include $(BASE_DEPENDS)
endif

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; /* Collisions of hash keys */
unsigned collisions; /* Collissions of hash keys */
unsigned search; /* How many keys were searched */
unsigned found; /* How many nodes were found */
unsigned same_hash; /* Was there a collision with same masked hash and len ? */
unsigned same_hash; /* Was there a colision with same masked hash and len ? */
struct dm_hash_node **slots;
};
@@ -41,7 +41,7 @@ struct dm_hash_table {
static unsigned _hash(const void *key, unsigned len)
{
/* Permutation of the Integers 0 through 255 */
static const unsigned char _nums[] = {
static unsigned char _nums[] = {
1, 14, 110, 25, 97, 174, 132, 119, 138, 170, 125, 118, 27, 233, 140, 51,
87, 197, 177, 107, 234, 169, 56, 68, 30, 7, 173, 73, 188, 40, 36, 65,
49, 213, 104, 190, 57, 211, 148, 223, 48, 115, 15, 2, 67, 186, 210, 28,
@@ -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 matching val, return NULL.
* matching val and return that. If none have maching 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

@@ -19,7 +19,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//----------------------------------------------------------------
@@ -70,7 +69,7 @@ struct node48 {
};
struct node256 {
uint32_t nr_entries;
uint32_t nr_entries;
struct value values[256];
};
@@ -100,7 +99,7 @@ struct radix_tree *radix_tree_create(radix_value_dtr dtr, void *dtr_context)
static inline void _dtr(struct radix_tree *rt, union radix_value v)
{
if (rt->dtr)
rt->dtr(rt->dtr_context, v);
rt->dtr(rt->dtr_context, v);
}
// Returns the number of values removed
@@ -119,8 +118,8 @@ static unsigned _free_node(struct radix_tree *rt, struct value v)
break;
case VALUE:
_dtr(rt, v.value);
nr = 1;
_dtr(rt, v.value);
nr = 1;
break;
case VALUE_CHAIN:
@@ -179,9 +178,9 @@ unsigned radix_tree_size(struct radix_tree *rt)
return rt->nr_entries;
}
static bool _insert(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv);
static bool _insert(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv);
static bool _insert_unset(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert_unset(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
unsigned len = ke - kb;
@@ -208,7 +207,7 @@ static bool _insert_unset(struct radix_tree *rt, struct value *v, const uint8_t
return true;
}
static bool _insert_value(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert_value(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
unsigned len = ke - kb;
@@ -235,7 +234,7 @@ static bool _insert_value(struct radix_tree *rt, struct value *v, const uint8_t
return true;
}
static bool _insert_value_chain(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert_value_chain(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
struct value_chain *vc = v->value.ptr;
return _insert(rt, &vc->child, kb, ke, rv);
@@ -249,7 +248,7 @@ static unsigned min(unsigned lhs, unsigned rhs)
return rhs;
}
static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
struct prefix_chain *pc = v->value.ptr;
@@ -279,7 +278,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(pc->child.value.ptr);
free(pc2);
return false;
}
@@ -293,7 +292,6 @@ 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--;
@@ -315,7 +313,7 @@ static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, const u
return true;
}
static bool _insert_node4(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert_node4(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
struct node4 *n4 = v->value.ptr;
if (n4->nr_entries == 4) {
@@ -345,7 +343,7 @@ static bool _insert_node4(struct radix_tree *rt, struct value *v, const uint8_t
return true;
}
static bool _insert_node16(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert_node16(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
struct node16 *n16 = v->value.ptr;
@@ -384,7 +382,7 @@ static bool _insert_node16(struct radix_tree *rt, struct value *v, const uint8_t
return true;
}
static bool _insert_node48(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert_node48(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
struct node48 *n48 = v->value.ptr;
if (n48->nr_entries == 48) {
@@ -419,20 +417,20 @@ static bool _insert_node48(struct radix_tree *rt, struct value *v, const uint8_t
return true;
}
static bool _insert_node256(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert_node256(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
struct node256 *n256 = v->value.ptr;
bool r, was_unset = n256->values[*kb].type == UNSET;
r = _insert(rt, n256->values + *kb, kb + 1, ke, rv);
if (r && was_unset)
n256->nr_entries++;
n256->nr_entries++;
return r;
}
// FIXME: the tree should not be touched if insert fails (eg, OOM)
static bool _insert(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
static bool _insert(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
if (kb == ke) {
if (v->type == UNSET) {
@@ -489,10 +487,10 @@ static bool _insert(struct radix_tree *rt, struct value *v, const uint8_t *kb, c
struct lookup_result {
struct value *v;
const uint8_t *kb;
uint8_t *kb;
};
static struct lookup_result _lookup_prefix(struct value *v, const uint8_t *kb, const uint8_t *ke)
static struct lookup_result _lookup_prefix(struct value *v, uint8_t *kb, uint8_t *ke)
{
unsigned i;
struct value_chain *vc;
@@ -502,7 +500,7 @@ static struct lookup_result _lookup_prefix(struct value *v, const uint8_t *kb, c
struct node48 *n48;
struct node256 *n256;
if (kb == ke || !kb) /* extra check for !kb for coverity */
if (kb == ke)
return (struct lookup_result) {.v = v, .kb = kb};
switch (v->type) {
@@ -557,32 +555,23 @@ static struct lookup_result _lookup_prefix(struct value *v, const uint8_t *kb, c
return (struct lookup_result) {.v = v, .kb = kb};
}
bool radix_tree_insert(struct radix_tree *rt, const void *key, size_t keylen, union radix_value rv)
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value rv)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct lookup_result lr = _lookup_prefix(&rt->root, kb, ke);
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)
{
struct node4 *n4 = zalloc(sizeof(*n4));
struct node4 *n4 = zalloc(sizeof(*n4));
assert(n4 != NULL);
n4->nr_entries = n16->nr_entries;
memcpy(n4->keys, n16->keys, n16->nr_entries * sizeof(*n4->keys));
memcpy(n4->values, n16->values, n16->nr_entries * sizeof(*n4->values));
free(n16);
n4->nr_entries = n16->nr_entries;
memcpy(n4->keys, n16->keys, n16->nr_entries * sizeof(*n4->keys));
memcpy(n4->values, n16->values, n16->nr_entries * sizeof(*n4->values));
free(n16);
result->type = NODE4;
result->value.ptr = n4;
@@ -591,20 +580,20 @@ static void _degrade_to_n4(struct node16 *n16, struct value *result)
static void _degrade_to_n16(struct node48 *n48, struct value *result)
{
unsigned i, count = 0;
struct node16 *n16 = zalloc(sizeof(*n16));
struct node16 *n16 = zalloc(sizeof(*n16));
assert(n16 != NULL);
n16->nr_entries = n48->nr_entries;
for (i = 0; i < 256; i++) {
if (n48->keys[i] < 48) {
n16->keys[count] = i;
n16->values[count] = n48->values[n48->keys[i]];
count++;
}
}
n16->nr_entries = n48->nr_entries;
for (i = 0; i < 256; i++) {
if (n48->keys[i] < 48) {
n16->keys[count] = i;
n16->values[count] = n48->values[n48->keys[i]];
count++;
}
}
free(n48);
free(n48);
result->type = NODE16;
result->value.ptr = n16;
@@ -612,13 +601,13 @@ static void _degrade_to_n16(struct node48 *n48, struct value *result)
static void _degrade_to_n48(struct node256 *n256, struct value *result)
{
unsigned i, count = 0;
struct node48 *n48 = zalloc(sizeof(*n48));
unsigned i, count = 0;
struct node48 *n48 = zalloc(sizeof(*n48));
assert(n48 != NULL);
n48->nr_entries = n256->nr_entries;
for (i = 0; i < 256; i++) {
n48->nr_entries = n256->nr_entries;
for (i = 0; i < 256; i++) {
if (n256->values[i].type == UNSET)
n48->keys[i] = 48;
@@ -627,9 +616,9 @@ static void _degrade_to_n48(struct node256 *n256, struct value *result)
n48->values[count] = n256->values[i];
count++;
}
}
}
free(n256);
free(n256);
result->type = NODE48;
result->value.ptr = n48;
@@ -643,14 +632,14 @@ static void _erase_elt(void *array, size_t obj_size, unsigned count, unsigned id
return;
memmove(((uint8_t *) array) + (obj_size * idx),
((uint8_t *) array) + (obj_size * (idx + 1)),
obj_size * (count - idx - 1));
((uint8_t *) array) + (obj_size * (idx + 1)),
obj_size * (count - idx - 1));
// Zero the now unused last elt (set's v.type to UNSET)
memset(((uint8_t *) array) + (count - 1) * obj_size, 0, obj_size);
}
static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb, const uint8_t *ke)
static bool _remove(struct radix_tree *rt, struct value *root, uint8_t *kb, uint8_t *ke)
{
bool r;
unsigned i, j;
@@ -662,27 +651,27 @@ static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb
struct node256 *n256;
if (kb == ke) {
if (root->type == VALUE) {
root->type = UNSET;
_dtr(rt, root->value);
return true;
if (root->type == VALUE) {
root->type = UNSET;
_dtr(rt, root->value);
return true;
} else if (root->type == VALUE_CHAIN) {
} else if (root->type == VALUE_CHAIN) {
vc = root->value.ptr;
_dtr(rt, vc->value);
memcpy(root, &vc->child, sizeof(*root));
free(vc);
return true;
} else
} else
return false;
}
switch (root->type) {
case UNSET:
case VALUE:
// this is a value for a prefix of the key
return false;
// this is a value for a prefix of the key
return false;
case VALUE_CHAIN:
vc = root->value.ptr;
@@ -697,11 +686,11 @@ static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb
case PREFIX_CHAIN:
pc = root->value.ptr;
if (ke - kb < pc->len)
return false;
return false;
for (i = 0; i < pc->len; i++)
if (kb[i] != pc->prefix[i])
return false;
return false;
r = _remove(rt, &pc->child, kb + pc->len, ke);
if (r && pc->child.type == UNSET) {
@@ -716,12 +705,12 @@ static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb
if (n4->keys[i] == *kb) {
r = _remove(rt, n4->values + i, kb + 1, ke);
if (r && n4->values[i].type == UNSET) {
if (i < n4->nr_entries) {
_erase_elt(n4->keys, sizeof(*n4->keys), n4->nr_entries, i);
_erase_elt(n4->values, sizeof(*n4->values), n4->nr_entries, i);
}
if (i < n4->nr_entries) {
_erase_elt(n4->keys, sizeof(*n4->keys), n4->nr_entries, i);
_erase_elt(n4->values, sizeof(*n4->values), n4->nr_entries, i);
}
n4->nr_entries--;
n4->nr_entries--;
if (!n4->nr_entries) {
free(n4);
root->type = UNSET;
@@ -733,19 +722,19 @@ static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb
return false;
case NODE16:
n16 = root->value.ptr;
n16 = root->value.ptr;
for (i = 0; i < n16->nr_entries; i++) {
if (n16->keys[i] == *kb) {
r = _remove(rt, n16->values + i, kb + 1, ke);
if (r && n16->values[i].type == UNSET) {
if (i < n16->nr_entries) {
_erase_elt(n16->keys, sizeof(*n16->keys), n16->nr_entries, i);
_erase_elt(n16->values, sizeof(*n16->values), n16->nr_entries, i);
}
if (i < n16->nr_entries) {
_erase_elt(n16->keys, sizeof(*n16->keys), n16->nr_entries, i);
_erase_elt(n16->values, sizeof(*n16->values), n16->nr_entries, i);
}
n16->nr_entries--;
n16->nr_entries--;
if (n16->nr_entries <= 4) {
_degrade_to_n4(n16, root);
_degrade_to_n4(n16, root);
}
}
return r;
@@ -757,18 +746,18 @@ static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb
n48 = root->value.ptr;
i = n48->keys[*kb];
if (i < 48) {
r = _remove(rt, n48->values + i, kb + 1, ke);
if (r && n48->values[i].type == UNSET) {
n48->keys[*kb] = 48;
for (j = 0; j < 256; j++)
if (n48->keys[j] < 48 && n48->keys[j] > i)
n48->keys[j]--;
r = _remove(rt, n48->values + i, kb + 1, ke);
if (r && n48->values[i].type == UNSET) {
n48->keys[*kb] = 48;
for (j = 0; j < 256; j++)
if (n48->keys[j] < 48 && n48->keys[j] > i)
n48->keys[j]--;
_erase_elt(n48->values, sizeof(*n48->values), n48->nr_entries, i);
n48->nr_entries--;
if (n48->nr_entries <= 16)
_degrade_to_n16(n48, root);
}
return r;
_degrade_to_n16(n48, root);
}
return r;
}
return false;
@@ -778,7 +767,7 @@ static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb
if (r && n256->values[*kb].type == UNSET) {
n256->nr_entries--;
if (n256->nr_entries <= 48)
_degrade_to_n48(n256, root);
_degrade_to_n48(n256, root);
}
return r;
}
@@ -786,14 +775,11 @@ static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb
return false;
}
bool radix_tree_remove(struct radix_tree *rt, const void *key, size_t keylen)
bool radix_tree_remove(struct radix_tree *rt, uint8_t *key_begin, uint8_t *key_end)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
if (_remove(rt, &rt->root, kb, ke)) {
rt->nr_entries--;
return true;
if (_remove(rt, &rt->root, key_begin, key_end)) {
rt->nr_entries--;
return true;
}
return false;
@@ -801,25 +787,25 @@ bool radix_tree_remove(struct radix_tree *rt, const void *key, size_t keylen)
//----------------------------------------------------------------
static bool _prefix_chain_matches(const struct lookup_result *lr, const uint8_t *ke)
static bool _prefix_chain_matches(struct lookup_result *lr, uint8_t *ke)
{
// It's possible the top node is a prefix chain, and
// the remaining key matches part of it.
if (lr->v->type == PREFIX_CHAIN) {
unsigned i, rlen = ke - lr->kb;
const struct prefix_chain *pc = lr->v->value.ptr;
if (rlen < pc->len) {
for (i = 0; i < rlen; i++)
if (pc->prefix[i] != lr->kb[i])
return false;
return true;
// It's possible the top node is a prefix chain, and
// the remaining key matches part of it.
if (lr->v->type == PREFIX_CHAIN) {
unsigned i, rlen = ke - lr->kb;
struct prefix_chain *pc = lr->v->value.ptr;
if (rlen < pc->len) {
for (i = 0; i < rlen; i++)
if (pc->prefix[i] != lr->kb[i])
return false;
return true;
}
}
}
return false;
return false;
}
static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uint8_t *kb, const uint8_t *ke, unsigned *count)
static bool _remove_subtree(struct radix_tree *rt, struct value *root, uint8_t *kb, uint8_t *ke, unsigned *count)
{
bool r;
unsigned i, j, len;
@@ -840,7 +826,7 @@ static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uin
case UNSET:
case VALUE:
// No entries with the given prefix
return true;
return true;
case VALUE_CHAIN:
vc = root->value.ptr;
@@ -857,7 +843,7 @@ static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uin
len = min(pc->len, ke - kb);
for (i = 0; i < len; i++)
if (kb[i] != pc->prefix[i])
return true;
return true;
r = _remove_subtree(rt, &pc->child, len < pc->len ? ke : (kb + pc->len), ke, count);
if (r && pc->child.type == UNSET) {
@@ -872,12 +858,12 @@ static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uin
if (n4->keys[i] == *kb) {
r = _remove_subtree(rt, n4->values + i, kb + 1, ke, count);
if (r && n4->values[i].type == UNSET) {
if (i < n4->nr_entries) {
_erase_elt(n4->keys, sizeof(*n4->keys), n4->nr_entries, i);
_erase_elt(n4->values, sizeof(*n4->values), n4->nr_entries, i);
}
if (i < n4->nr_entries) {
_erase_elt(n4->keys, sizeof(*n4->keys), n4->nr_entries, i);
_erase_elt(n4->values, sizeof(*n4->values), n4->nr_entries, i);
}
n4->nr_entries--;
n4->nr_entries--;
if (!n4->nr_entries) {
free(n4);
root->type = UNSET;
@@ -889,19 +875,19 @@ static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uin
return true;
case NODE16:
n16 = root->value.ptr;
n16 = root->value.ptr;
for (i = 0; i < n16->nr_entries; i++) {
if (n16->keys[i] == *kb) {
r = _remove_subtree(rt, n16->values + i, kb + 1, ke, count);
if (r && n16->values[i].type == UNSET) {
if (i < n16->nr_entries) {
_erase_elt(n16->keys, sizeof(*n16->keys), n16->nr_entries, i);
_erase_elt(n16->values, sizeof(*n16->values), n16->nr_entries, i);
}
if (i < n16->nr_entries) {
_erase_elt(n16->keys, sizeof(*n16->keys), n16->nr_entries, i);
_erase_elt(n16->values, sizeof(*n16->values), n16->nr_entries, i);
}
n16->nr_entries--;
n16->nr_entries--;
if (n16->nr_entries <= 4)
_degrade_to_n4(n16, root);
_degrade_to_n4(n16, root);
}
return r;
}
@@ -912,18 +898,18 @@ static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uin
n48 = root->value.ptr;
i = n48->keys[*kb];
if (i < 48) {
r = _remove_subtree(rt, n48->values + i, kb + 1, ke, count);
if (r && n48->values[i].type == UNSET) {
n48->keys[*kb] = 48;
for (j = 0; j < 256; j++)
if (n48->keys[j] < 48 && n48->keys[j] > i)
n48->keys[j]--;
r = _remove_subtree(rt, n48->values + i, kb + 1, ke, count);
if (r && n48->values[i].type == UNSET) {
n48->keys[*kb] = 48;
for (j = 0; j < 256; j++)
if (n48->keys[j] < 48 && n48->keys[j] > i)
n48->keys[j]--;
_erase_elt(n48->values, sizeof(*n48->values), n48->nr_entries, i);
n48->nr_entries--;
if (n48->nr_entries <= 16)
_degrade_to_n16(n48, root);
}
return r;
_degrade_to_n16(n48, root);
}
return r;
}
return true;
@@ -936,7 +922,7 @@ static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uin
if (r && n256->values[*kb].type == UNSET) {
n256->nr_entries--;
if (n256->nr_entries <= 48)
_degrade_to_n48(n256, root);
_degrade_to_n48(n256, root);
}
return r;
}
@@ -945,13 +931,11 @@ static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uin
return false;
}
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, size_t prefix_len)
unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
{
const uint8_t *kb = prefix;
const uint8_t *ke = kb + prefix_len;
unsigned count = 0;
unsigned count = 0;
if (_remove_subtree(rt, &rt->root, kb, ke, &count))
if (_remove_subtree(rt, &rt->root, kb, ke, &count))
rt->nr_entries -= count;
return count;
@@ -959,11 +943,9 @@ unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, siz
//----------------------------------------------------------------
bool radix_tree_lookup(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value *result)
bool radix_tree_lookup(struct radix_tree *rt,
uint8_t *kb, uint8_t *ke, union radix_value *result)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct value_chain *vc;
struct lookup_result lr = _lookup_prefix(&rt->root, kb, ke);
if (lr.kb == ke) {
@@ -986,58 +968,58 @@ bool radix_tree_lookup(struct radix_tree *rt, const void *key, size_t keylen,
}
// FIXME: build up the keys too
static bool _iterate(struct radix_tree_iterator *it, const struct value *v)
static bool _iterate(struct value *v, struct radix_tree_iterator *it)
{
unsigned i;
const struct value_chain *vc;
const struct prefix_chain *pc;
const struct node4 *n4;
const struct node16 *n16;
const struct node48 *n48;
const struct node256 *n256;
struct value_chain *vc;
struct prefix_chain *pc;
struct node4 *n4;
struct node16 *n16;
struct node48 *n48;
struct node256 *n256;
switch (v->type) {
case UNSET:
// can't happen
// can't happen
break;
case VALUE:
return it->visit(it, NULL, 0, v->value);
return it->visit(it, NULL, NULL, v->value);
case VALUE_CHAIN:
vc = v->value.ptr;
return it->visit(it, NULL, 0, vc->value) && _iterate(it, &vc->child);
return it->visit(it, NULL, NULL, vc->value) && _iterate(&vc->child, it);
case PREFIX_CHAIN:
pc = v->value.ptr;
return _iterate(it, &pc->child);
return _iterate(&pc->child, it);
case NODE4:
n4 = (const struct node4 *) v->value.ptr;
n4 = (struct node4 *) v->value.ptr;
for (i = 0; i < n4->nr_entries; i++)
if (!_iterate(it, n4->values + i))
return false;
return true;
if (!_iterate(n4->values + i, it))
return false;
return true;
case NODE16:
n16 = (const struct node16 *) v->value.ptr;
n16 = (struct node16 *) v->value.ptr;
for (i = 0; i < n16->nr_entries; i++)
if (!_iterate(it, n16->values + i))
return false;
if (!_iterate(n16->values + i, it))
return false;
return true;
case NODE48:
n48 = (const struct node48 *) v->value.ptr;
n48 = (struct node48 *) v->value.ptr;
for (i = 0; i < n48->nr_entries; i++)
if (!_iterate(it, n48->values + i))
return false;
if (!_iterate(n48->values + i, it))
return false;
return true;
case NODE256:
n256 = (const struct node256 *) v->value.ptr;
n256 = (struct node256 *) v->value.ptr;
for (i = 0; i < 256; i++)
if (n256->values[i].type != UNSET && !_iterate(it, n256->values + i))
return false;
if (n256->values[i].type != UNSET && !_iterate(n256->values + i, it))
return false;
return true;
}
@@ -1045,14 +1027,12 @@ static bool _iterate(struct radix_tree_iterator *it, const struct value *v)
return false;
}
void radix_tree_iterate(struct radix_tree *rt, const void *key, size_t keylen,
struct radix_tree_iterator *it)
void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
struct radix_tree_iterator *it)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct lookup_result lr = _lookup_prefix(&rt->root, kb, ke);
if (lr.kb == ke || _prefix_chain_matches(&lr, ke))
(void) _iterate(it, lr.v);
(void) _iterate(lr.v, it);
}
//----------------------------------------------------------------
@@ -1150,7 +1130,7 @@ static bool _check_nodes(struct value *v, unsigned *count)
if (ncount != n48->nr_entries) {
fprintf(stderr, "incorrect number of entries in n48, n48->nr_entries = %u, actual = %u\n",
n48->nr_entries, ncount);
n48->nr_entries, ncount);
return false;
}
@@ -1186,7 +1166,7 @@ static bool _check_nodes(struct value *v, unsigned *count)
if (ncount != n256->nr_entries) {
fprintf(stderr, "incorrect number of entries in n256, n256->nr_entries = %u, actual = %u\n",
n256->nr_entries, ncount);
n256->nr_entries, ncount);
return false;
}
@@ -1209,7 +1189,7 @@ bool radix_tree_is_well_formed(struct radix_tree *rt)
if (rt->nr_entries != count) {
fprintf(stderr, "incorrect entry count: rt->nr_entries = %u, actual = %u\n",
rt->nr_entries, count);
rt->nr_entries, count);
return false;
}
@@ -1227,7 +1207,6 @@ static void _dump(FILE *out, struct value v, unsigned indent)
struct node16 *n16;
struct node48 *n48;
struct node256 *n256;
unsigned printable;
if (v.type == UNSET)
return;
@@ -1252,22 +1231,9 @@ static void _dump(FILE *out, struct value v, unsigned indent)
case PREFIX_CHAIN:
pc = v.value.ptr;
fprintf(out, "<prefix(%u): ", pc->len);
printable = 1;
fprintf(out, "<prefix: ");
for (i = 0; i < pc->len; i++)
if (!isprint(pc->prefix[i])) {
printable = 0;
break;
}
if (printable)
fputc('"', out);
for (i = 0; i < pc->len; i++)
if (printable)
fprintf(out, "%c", pc->prefix[i]);
else
fprintf(out, "%02x.", (unsigned) *(pc->prefix + i));
if (printable)
fputc('"', out);
fprintf(out, "%x.", (unsigned) *(pc->prefix + i));
fprintf(out, ">\n");
_dump(out, pc->child, indent + 1);
break;
@@ -1276,7 +1242,7 @@ static void _dump(FILE *out, struct value v, unsigned indent)
n4 = v.value.ptr;
fprintf(out, "<n4: ");
for (i = 0; i < n4->nr_entries; i++)
fprintf(out, "%02x ", (unsigned) n4->keys[i]);
fprintf(out, "%x ", (unsigned) n4->keys[i]);
fprintf(out, ">\n");
for (i = 0; i < n4->nr_entries; i++)
@@ -1287,7 +1253,7 @@ static void _dump(FILE *out, struct value v, unsigned indent)
n16 = v.value.ptr;
fprintf(out, "<n16: ");
for (i = 0; i < n16->nr_entries; i++)
fprintf(out, "%02x ", (unsigned) n16->keys[i]);
fprintf(out, "%x ", (unsigned) n16->keys[i]);
fprintf(out, ">\n");
for (i = 0; i < n16->nr_entries; i++)
@@ -1299,7 +1265,7 @@ static void _dump(FILE *out, struct value v, unsigned indent)
fprintf(out, "<n48: ");
for (i = 0; i < 256; i++)
if (n48->keys[i] < 48)
fprintf(out, "%02x ", i);
fprintf(out, "%x ", i);
fprintf(out, ">\n");
for (i = 0; i < n48->nr_entries; i++) {
@@ -1313,7 +1279,7 @@ static void _dump(FILE *out, struct value v, unsigned indent)
fprintf(out, "<n256: ");
for (i = 0; i < 256; i++)
if (n256->values[i].type != UNSET)
fprintf(out, "%02x ", i);
fprintf(out, "%x ", i);
fprintf(out, ">\n");
for (i = 0; i < 256; i++)

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2018 Red Hat, Inc. All rights reserved.
//
//
// This file is part of LVM2.
//
// This copyrighted material is made available to anyone wishing to use,
@@ -18,7 +18,6 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
//----------------------------------------------------------------
// This implementation is based around nested binary trees. Very
@@ -38,12 +37,12 @@ struct node {
struct radix_tree {
radix_value_dtr dtr;
void *dtr_context;
unsigned nr_entries;
struct node *root;
};
struct radix_tree *radix_tree_create(radix_value_dtr dtr, void *dtr_context)
struct radix_tree *
radix_tree_create(radix_value_dtr dtr, void *dtr_context)
{
struct radix_tree *rt = zalloc(sizeof(*rt));
@@ -106,7 +105,7 @@ unsigned radix_tree_size(struct radix_tree *rt)
return _count(rt->root);
}
static struct node **_lookup(struct node **pn, const uint8_t *kb, const uint8_t *ke)
static struct node **_lookup(struct node **pn, uint8_t *kb, uint8_t *ke)
{
struct node *n = *pn;
@@ -123,7 +122,7 @@ static struct node **_lookup(struct node **pn, const uint8_t *kb, const uint8_t
return _lookup(&n->center, kb + 1, ke);
}
static bool _insert(struct node **pn, const uint8_t *kb, const uint8_t *ke, union radix_value v)
static bool _insert(struct node **pn, uint8_t *kb, uint8_t *ke, union radix_value v)
{
struct node *n = *pn;
@@ -152,53 +151,41 @@ static bool _insert(struct node **pn, const uint8_t *kb, const uint8_t *ke, unio
return _insert(&n->center, kb + 1, ke, v);
}
bool radix_tree_insert(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value v)
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value v)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
if (!_insert(&rt->root, kb, ke, v))
return false;
rt->nr_entries++;
return true;
return _insert(&rt->root, kb, ke, v);
}
bool radix_tree_remove(struct radix_tree *rt, const void *key, size_t keylen)
bool radix_tree_remove(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct node **pn = _lookup(&rt->root, kb, ke);
struct node *n = *pn;
if (!n || !n->has_value)
return false;
rt->nr_entries--;
else {
if (rt->dtr)
rt->dtr(rt->dtr_context, n->value);
if (rt->dtr)
rt->dtr(rt->dtr_context, n->value);
if (n->left || n->center || n->right) {
n->has_value = false;
return true;
if (n->left || n->center || n->right) {
n->has_value = false;
return true;
} else {
// FIXME: delete parent if this was the last entry
free(n);
*pn = NULL;
}
return true;
}
// FIXME: delete parent if this was the last entry
free(n);
*pn = NULL;
return true;
}
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, size_t prefix_len)
unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
{
const uint8_t *kb = prefix;
const uint8_t *ke = kb + prefix_len;
struct node **pn;
unsigned count = 0;
unsigned count;
pn = _lookup(&rt->root, kb, ke);
@@ -210,20 +197,17 @@ unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, siz
return count;
}
bool radix_tree_lookup(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value *result)
bool
radix_tree_lookup(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value *result)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct node **pn = _lookup(&rt->root, kb, ke);
struct node *n = *pn;
if (n && n->has_value) {
*result = n->value;
return true;
}
return false;
} else
return false;
}
static void _iterate(struct node *n, struct radix_tree_iterator *it)
@@ -235,18 +219,15 @@ static void _iterate(struct node *n, struct radix_tree_iterator *it)
if (n->has_value)
// FIXME: fill out the key
it->visit(it, NULL, 0, n->value);
it->visit(it, NULL, NULL, n->value);
_iterate(n->center, it);
_iterate(n->right, it);
}
void radix_tree_iterate(struct radix_tree *rt, const void *key, size_t keylen,
void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
struct radix_tree_iterator *it)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
if (kb == ke)
_iterate(rt->root, it);
@@ -256,7 +237,7 @@ void radix_tree_iterate(struct radix_tree *rt, const void *key, size_t keylen,
if (n) {
if (n->has_value)
it->visit(it, NULL, 0, n->value);
it->visit(it, NULL, NULL, n->value);
_iterate(n->center, it);
}
}
@@ -267,32 +248,8 @@ bool radix_tree_is_well_formed(struct radix_tree *rt)
return true;
}
static void _dump(FILE *out, struct node *n, unsigned indent)
{
unsigned i;
if (!n)
return;
_dump(out, n->left, indent + 1);
for (i = 0; i < 2 * indent; i++)
fprintf(out, " ");
if (n->has_value) {
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);
}
_dump(out, n->center, indent + 1);
_dump(out, n->right, indent + 1);
}
void radix_tree_dump(struct radix_tree *rt, FILE *out)
{
_dump(out, rt->root, 0);
}
//----------------------------------------------------------------

View File

@@ -19,45 +19,3 @@
#endif
//----------------------------------------------------------------
struct visitor {
struct radix_tree_iterator it;
unsigned pos, nr_entries;
union radix_value *values;
};
static bool _visitor(struct radix_tree_iterator *it,
const void *key, size_t keylen,
union radix_value v)
{
struct visitor *vt = container_of(it, struct visitor, it);
if (vt->pos >= vt->nr_entries)
return false;
vt->values[vt->pos++] = v;
return true;
}
bool radix_tree_values(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value **values, unsigned *nr_values)
{
struct visitor vt = {
.it.visit = _visitor,
.nr_entries = rt->nr_entries,
.values = calloc(rt->nr_entries + 1, sizeof(union radix_value)),
};
if (vt.values) {
// build set of all values in current radix tree
radix_tree_iterate(rt, key, keylen, &vt.it);
*nr_values = vt.pos;
*values = vt.values;
return true;
}
return false;
}
//----------------------------------------------------------------

View File

@@ -33,61 +33,32 @@ struct radix_tree *radix_tree_create(radix_value_dtr dtr, void *dtr_context);
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);
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value v);
bool radix_tree_remove(struct radix_tree *rt, uint8_t *kb, uint8_t *ke);
// Returns the number of values removed
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, size_t prefix_len);
unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *prefix_b, uint8_t *prefix_e);
bool radix_tree_lookup(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value *result);
bool radix_tree_lookup(struct radix_tree *rt,
uint8_t *kb, uint8_t *ke, union radix_value *result);
// The radix tree stores entries in lexicographical order. Which means
// we can iterate entries, in order. Or iterate entries with a particular
// prefix.
struct radix_tree_iterator {
// Returns false if the iteration should end.
// Returns false if the iteration should end.
bool (*visit)(struct radix_tree_iterator *it,
const void *key, size_t keylen, union radix_value v);
uint8_t *kb, uint8_t *ke, union radix_value v);
};
void radix_tree_iterate(struct radix_tree *rt, const void *key, size_t keylen,
struct radix_tree_iterator *it);
// Alternative traversing radix_tree.
// Builds whole set all radix_tree nr_values values.
// After use, free(values).
bool radix_tree_values(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value **values, unsigned *nr_values);
void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
struct radix_tree_iterator *it);
// Checks that some constraints on the shape of the tree are
// being held. For debug only.
bool radix_tree_is_well_formed(struct radix_tree *rt);
void radix_tree_dump(struct radix_tree *rt, FILE *out);
// Shortcut for ptr value return
// Note: if value would be NULL, it's same result for not/found case.
static inline void *radix_tree_lookup_ptr(struct radix_tree *rt, const void *key, size_t keylen)
{
union radix_value v;
return radix_tree_lookup(rt, key, keylen, &v) ? v.ptr : NULL;
}
static inline bool radix_tree_insert_ptr(struct radix_tree *rt, const void *key, size_t keylen, void *ptr)
{
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

@@ -49,7 +49,7 @@ install_localconf: $(CONFLOCAL)
fi
install_profiles: $(PROFILES)
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_DIR) $(profiledir)
$(Q) $(INSTALL_DATA) $(PROFILES) $(profiledir)/

View File

@@ -36,19 +36,6 @@ 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.
@@ -135,7 +122,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 listed in the devices file. A devices file will
# are lised 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.
@@ -575,7 +562,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 maximum is 1000000 chunks.
# For cache target v1.9 the recommended maximumm is 1000000 chunks.
# Using cache pool with more chunks may degrade cache performance.
# This configuration option does not have a default value defined.
@@ -586,7 +573,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 than the actual maximum 15.88 GiB.
# This is slightly less then 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
@@ -659,6 +646,13 @@ 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.
@@ -757,6 +751,19 @@ 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,
@@ -794,9 +801,6 @@ 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
@@ -826,9 +830,8 @@ 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.
# 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.
# For more information about selection criteria in general, see
# lvm(8) man page.
# This configuration option has an automatic default value.
# command_log_selection = "!(log_type=status && message=success)"
@@ -1029,7 +1032,7 @@ global {
# Location of proc filesystem.
# This configuration option is advanced.
# This configuration option has an automatic default value.
# proc = "@DEFAULT_PROC_DIR@"
# proc = "/proc"
# Configuration option global/etc.
# Location of /etc system configuration directory.
@@ -1173,7 +1176,7 @@ global {
# services (via the lvm2-activation-generator), but the autoactivation
# services and generator have been removed.
# This configuration option has an automatic default value.
# event_activation = @DEFAULT_EVENT_ACTIVATION@
# event_activation = 1
# Configuration option global/use_aio.
# Use async I/O when reading and writing devices.
@@ -1205,16 +1208,6 @@ 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
@@ -1379,12 +1372,6 @@ global {
# This configuration option has an automatic default value.
# fsadm_executable = "@FSADM_PATH@"
# Configuration option global/lvresize_fs_helper_executable.
# The full path to the lvresize_fs_helper command.
# LVM uses this command to help with filesystem operations during lvresize.
# This configuration option has an automatic default value.
# lvresize_fs_helper_executable = "@LVRESIZE_FS_HELPER_PATH@"
# Configuration option global/system_id_source.
# The method LVM uses to set the local system ID.
# Volume Groups can also be given a system ID (by vgcreate, vgchange,
@@ -1524,14 +1511,12 @@ 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
@@ -1880,7 +1865,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, raid6 and raid10 will be activated if there is no
# raid4, raid5, radid6 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
@@ -2004,7 +1989,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 report/output_format setting.
# has precedence over log/output_format setting.
# Accepted values:
# basic
# Original format with columns and rows. If there is more than
@@ -2018,7 +2003,6 @@ 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"
@@ -2141,7 +2125,7 @@ report {
# %F
# Equivalent to %Y-%m-%d (the ISO 8601 date format).
# %G
# The ISO 8601 week-based year with century as a decimal number.
# The ISO 8601 week-based year with century as adecimal 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

@@ -38,14 +38,6 @@ local {
# This configuration option has an automatic default value.
# system_id = ""
# Configuration option local/pr_key.
# The local persistent reservation key in hexidecimal.
# The value must be unique among all hosts using the same VG.
# The max length is 16 hex characters (8 bytes), plus an optional
# 0x prefix. If pr_key is not set, host_id will be used to create a key.
# This configuration option has an automatic default value.
# pr_key = ""
# Configuration option local/extra_system_ids.
# A list of extra VG system IDs the local host can access.
# VGs with the system IDs listed here (in addition to the host's own
@@ -57,12 +49,9 @@ local {
# This configuration option does not have a default value defined.
# Configuration option local/host_id.
# 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.
# When using persistent reservations, lvm will generate a PR key from the host_id
# if pr_key is not defined. All hosts using a sanlock shared VG with PR must use
# the same approach for configuring their PR key (pr_key or 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
# This configuration option has an automatic default value.
# host_id = 0
}

View File

@@ -4,6 +4,7 @@
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
@@ -17,5 +18,6 @@ allocation {
vdo_hash_zone_threads=1
vdo_logical_threads=1
vdo_physical_threads=1
vdo_write_policy="auto"
vdo_max_discard=1
}

399
configure vendored
View File

@@ -678,7 +678,6 @@ SILENT_RULES
SHARED_LINK
SELINUX_STATIC_LIBS
SELINUX_PC
SD_NOTIFY_SUPPORT
SBINDIR
RT_LIBS
PYTHON3DIR
@@ -730,11 +729,9 @@ DEFAULT_SPARSE_SEGTYPE
DEFAULT_RUN_DIR
DEFAULT_RAID10_SEGTYPE
DEFAULT_PROFILE_SUBDIR
DEFAULT_PROC_DIR
DEFAULT_PID_DIR
DEFAULT_MIRROR_SEGTYPE
DEFAULT_LOCK_DIR
DEFAULT_EVENT_ACTIVATION
DEFAULT_DMEVENTD_EXIT_ON_PATH
DEFAULT_DM_RUN_DIR
DEFAULT_CACHE_SUBDIR
@@ -788,8 +785,6 @@ LIBSYSTEMD_LIBS
LIBSYSTEMD_CFLAGS
UDEV_LIBS
UDEV_CFLAGS
LIBNVME_LIBS
LIBNVME_CFLAGS
BLKID_LIBS
BLKID_CFLAGS
SYSTEMD_RUN_CMD
@@ -915,7 +910,6 @@ enable_silent_rules
enable_static_link
enable_shared
with_blkid
with_libnvme
with_systemd
with_udev
with_user
@@ -926,7 +920,6 @@ with_device_mode
with_device_nodes_on
with_default_use_devices_file
with_default_name_mangling
with_default_event_activation
with_snapshots
with_mirrors
with_default_mirror_segtype
@@ -975,10 +968,8 @@ 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
@@ -1051,8 +1042,6 @@ LIBSEAGATEILM_CFLAGS
LIBSEAGATEILM_LIBS
BLKID_CFLAGS
BLKID_LIBS
LIBNVME_CFLAGS
LIBNVME_LIBS
UDEV_CFLAGS
UDEV_LIBS
LIBSYSTEMD_CFLAGS
@@ -1721,10 +1710,8 @@ 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
@@ -1751,7 +1738,6 @@ 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=]
@@ -1761,12 +1747,10 @@ Optional Packages:
--with-device-mode=MODE set the mode used for new device nodes [MODE=0600]
--with-device-nodes-on=ON
create nodes on resume or create [ON=resume]
--with-default-use-devices-file=ON
default lvm.conf devices/use_devicesfile = [ON=0]
--with-default-use-devices-file
default for lvm.conf devices/use_devicesfile = [0]
--with-default-name-mangling=MANGLING
default name mangling: auto/none/hex [auto]
--with-default-event-activation=ON
default lvm.conf global/event_activation = [ON=1]
--with-snapshots=TYPE snapshot support: internal/none [internal]
--with-mirrors=TYPE mirror support: internal/none [internal]
--with-default-mirror-segtype=TYPE
@@ -1891,10 +1875,6 @@ 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
@@ -3776,7 +3756,7 @@ case "$host_os" in #(
LVMIMPORTVDO="no"
BLKDEACTIVATE="no" ;; #(
*) :
;;
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}" ;;
esac
################################################################################
@@ -9080,9 +9060,9 @@ printf "%s\n" "$ac_cv_flag_HAVE_PIE" >&6; }
ac_save_LDFLAGS=$LDFLAGS
LDFLAGS=-Wl,-z,relro,-z,now,-z,pack-relative-relocs,--as-needed
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Wl,-z,relro,-z,now,-z,pack-relative-relocs,--as-needed ld flags" >&5
printf %s "checking whether $CC accepts -Wl,-z,relro,-z,now,-z,pack-relative-relocs,--as-needed ld flags... " >&6; }
LDFLAGS=-Wl,-z,relro,-z,now
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Wl,-z,relro,-z,now ld flags" >&5
printf %s "checking whether $CC accepts -Wl,-z,relro,-z,now ld flags... " >&6; }
if test ${ac_cv_flag_HAVE_FULL_RELRO+y}
then :
printf %s "(cached) " >&6
@@ -9143,16 +9123,6 @@ 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 :
@@ -9340,30 +9310,6 @@ printf "%s\n" "$MANGLING" >&6; }
printf "%s\n" "#define DEFAULT_DM_NAME_MANGLING $mangling" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking default for event_activation" >&5
printf %s "checking default for event_activation... " >&6; }
# Check whether --with-default-event-activation was given.
if test ${with_default_event_activation+y}
then :
withval=$with_default_event_activation; DEFAULT_EVENT_ACTIVATION=$withval
else case e in #(
e) DEFAULT_EVENT_ACTIVATION=1 ;;
esac
fi
case "$DEFAULT_EVENT_ACTIVATION" in #(
0|1) :
;; #(
*) :
as_fn_error $? "--with-default-event-activation parameter invalid" "$LINENO" 5 ;;
esac
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_EVENT_ACTIVATION" >&5
printf "%s\n" "$DEFAULT_EVENT_ACTIVATION" >&6; }
printf "%s\n" "#define DEFAULT_EVENT_ACTIVATION $DEFAULT_EVENT_ACTIVATION" >>confdefs.h
################################################################################
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to include snapshots" >&5
printf %s "checking whether to include snapshots... " >&6; }
@@ -10954,7 +10900,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 VDO formatting ?
# Do we want to link lvm2 with a big library for vdoformatting ?
#
#AC_ARG_WITH(vdo-include,
# AS_HELP_STRING([--with-vdo-include=PATH],
@@ -11311,9 +11257,6 @@ 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 :
@@ -11605,7 +11548,7 @@ printf "%s\n" "#define GNU_SYMVER 1" >>confdefs.h
case "$host_os" in #(
linux*) :
CLDFLAGS="-Wl,--version-script,.export.sym"
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
LDDEPS="$LDDEPS .export.sym" ;; #(
*) :
;;
@@ -12174,38 +12117,21 @@ printf "%s\n" "$BUILD_LOCKDSANLOCK" >&6; }
if test "$BUILD_LOCKDSANLOCK" = "yes"
then :
LOCKDSANLOCK_SUPPORT=370
if test -n "$PKG_CONFIG" && \
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsanlock_client >= 4.0.0\""; } >&5
($PKG_CONFIG --exists --print-errors "libsanlock_client >= 4.0.0") 2>&5
ac_status=$?
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
LOCKDSANLOCK_SUPPORT=400
fi
if test -n "$PKG_CONFIG" && \
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsanlock_client >= 4.1.0\""; } >&5
($PKG_CONFIG --exists --print-errors "libsanlock_client >= 4.1.0") 2>&5
ac_status=$?
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
LOCKDSANLOCK_SUPPORT=410
fi
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsanlock_client >= 3.7.0" >&5
printf %s "checking for libsanlock_client >= 3.7.0... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsanlock_client >= 3.3.0" >&5
printf %s "checking for libsanlock_client >= 3.3.0... " >&6; }
if test -n "$LIBSANLOCKCLIENT_CFLAGS"; then
pkg_cv_LIBSANLOCKCLIENT_CFLAGS="$LIBSANLOCKCLIENT_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 \"libsanlock_client >= 3.7.0\""; } >&5
($PKG_CONFIG --exists --print-errors "libsanlock_client >= 3.7.0") 2>&5
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsanlock_client >= 3.3.0\""; } >&5
($PKG_CONFIG --exists --print-errors "libsanlock_client >= 3.3.0") 2>&5
ac_status=$?
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_LIBSANLOCKCLIENT_CFLAGS=`$PKG_CONFIG --cflags "libsanlock_client >= 3.7.0" 2>/dev/null`
pkg_cv_LIBSANLOCKCLIENT_CFLAGS=`$PKG_CONFIG --cflags "libsanlock_client >= 3.3.0" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -12217,12 +12143,12 @@ if test -n "$LIBSANLOCKCLIENT_LIBS"; then
pkg_cv_LIBSANLOCKCLIENT_LIBS="$LIBSANLOCKCLIENT_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 \"libsanlock_client >= 3.7.0\""; } >&5
($PKG_CONFIG --exists --print-errors "libsanlock_client >= 3.7.0") 2>&5
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsanlock_client >= 3.3.0\""; } >&5
($PKG_CONFIG --exists --print-errors "libsanlock_client >= 3.3.0") 2>&5
ac_status=$?
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_LIBSANLOCKCLIENT_LIBS=`$PKG_CONFIG --libs "libsanlock_client >= 3.7.0" 2>/dev/null`
pkg_cv_LIBSANLOCKCLIENT_LIBS=`$PKG_CONFIG --libs "libsanlock_client >= 3.3.0" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -12243,14 +12169,14 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
LIBSANLOCKCLIENT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsanlock_client >= 3.7.0" 2>&1`
LIBSANLOCKCLIENT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsanlock_client >= 3.3.0" 2>&1`
else
LIBSANLOCKCLIENT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsanlock_client >= 3.7.0" 2>&1`
LIBSANLOCKCLIENT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsanlock_client >= 3.3.0" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$LIBSANLOCKCLIENT_PKG_ERRORS" >&5
as_fn_error $? "Package requirements (libsanlock_client >= 3.7.0) were not met:
as_fn_error $? "Package requirements (libsanlock_client >= 3.3.0) were not met:
$LIBSANLOCKCLIENT_PKG_ERRORS
@@ -12283,7 +12209,7 @@ printf "%s\n" "yes" >&6; }
BUILD_LVMLOCKD="yes"
fi
printf "%s\n" "#define LOCKDSANLOCK_SUPPORT $LOCKDSANLOCK_SUPPORT" >>confdefs.h
printf "%s\n" "#define LOCKDSANLOCK_SUPPORT 1" >>confdefs.h
fi
@@ -12766,18 +12692,9 @@ 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=$?
@@ -12865,41 +12782,6 @@ 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.
@@ -13215,181 +13097,6 @@ 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; }
@@ -13688,11 +13395,7 @@ printf "%s\n" "$BUILD_LVMDBUSD" >&6; }
# Check whether --enable-notify-dbus was given.
if test ${enable_notify_dbus+y}
then :
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
enableval=$enable_notify_dbus; NOTIFYDBUS_SUPPORT=$enableval
fi
@@ -13709,6 +13412,10 @@ 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
@@ -13720,10 +13427,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" || test "$SD_NOTIFY_SUPPORT" = "yes"
if test "$NOTIFYDBUS_SUPPORT" = "yes" || test "$SYSTEMD_JOURNAL_SUPPORT" = "yes" || test "$APP_MACHINEID_SUPPORT" = "yes"
then :
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5
printf %s "checking for libsystemd... " >&6; }
@@ -13814,6 +13521,7 @@ else
printf "%s\n" "yes" >&6; }
fi
fi
################################################################################
@@ -14140,21 +13848,7 @@ try:
if python_implementation() == 'CPython' and sys.version[:3] == '2.7':
can_use_sysconfig = 0
except ImportError:
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
pass"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory (pythondir)" >&5
@@ -14171,11 +13865,7 @@ else case e in #(
am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
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'})
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')
@@ -14205,7 +13895,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 :
@@ -14219,11 +13909,7 @@ else case e in #(
am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
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'})
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')
@@ -14572,7 +14258,7 @@ printf %s "checking whether to compile liblvm2cmd.so... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CMDLIB" >&5
printf "%s\n" "$CMDLIB" >&6; }
if test "$CMDLIB" = "yes" && test "$SHARED_LINK" = "no"
if test "$CMDLIB" == "yes" && test "$SHARED_LINK" = "no"
then :
as_fn_error $? "--enable-cmdlib requires dynamic linking." "$LINENO" 5
fi
@@ -16503,11 +16189,6 @@ LVRESIZE_FS_HELPER_PATH="$LIBEXECDIR/lvresize_fs_helper"
printf "%s\n" "#define LVRESIZE_FS_HELPER_PATH \"$LVRESIZE_FS_HELPER_PATH\"" >>confdefs.h
LVMPERSIST_PATH="$SBINDIR/lvmpersist"
printf "%s\n" "#define LVMPERSIST_PATH \"$LVMPERSIST_PATH\"" >>confdefs.h
################################################################################
# Check whether --with-dmeventd-pidfile was given.
@@ -16649,11 +16330,6 @@ printf "%s\n" "$DEFAULT_LOCK_DIR" >&6; }
printf "%s\n" "#define DEFAULT_LOCK_DIR \"$DEFAULT_LOCK_DIR\"" >>confdefs.h
# No --with configure setting, but store in the main configure.h
printf "%s\n" "#define DEFAULT_PROC_DIR \"/proc\"" >>confdefs.h
################################################################################
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for kernel interface choice" >&5
printf %s "checking for kernel interface choice... " >&6; }
@@ -16847,9 +16523,6 @@ AIO_LIBS=${AIO_LIBS:--laio}
@@ -18249,9 +17922,3 @@ 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

@@ -1,3 +1,4 @@
###############################################################################
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
## Copyright (C) 2004-2023 Red Hat, Inc. All rights reserved.
##
@@ -19,7 +20,7 @@ AC_CONFIG_SRCDIR([lib/device/dev-cache.h])
AC_CONFIG_HEADERS([include/configure.h])
################################################################################
dnl -- Setup the directory where autoconf has auxiliary files
dnl -- Setup the directory where autoconf has auxilary files
AC_CONFIG_AUX_DIR(autoconf)
################################################################################
@@ -56,7 +57,7 @@ AS_CASE(["$host_os"],
FSADM="no"
LVMIMPORTVDO="no"
BLKDEACTIVATE="no"],
[])
[CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"])
################################################################################
dnl -- Checks for programs.
@@ -198,7 +199,7 @@ AC_MSG_RESULT([$SHARED_LINK])
dnl -- Check if compiler/linker supports PIE and RELRO
AC_TRY_CCFLAG([-pie], [HAVE_PIE], [], [])
AC_SUBST(HAVE_PIE)
AC_TRY_LDFLAGS([-Wl,-z,relro,-z,now,-z,pack-relative-relocs,--as-needed], [HAVE_FULL_RELRO], [], [])
AC_TRY_LDFLAGS([-Wl,-z,relro,-z,now], [HAVE_FULL_RELRO], [], [])
AC_SUBST(HAVE_FULL_RELRO)
################################################################################
@@ -216,8 +217,6 @@ 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])],
@@ -292,7 +291,7 @@ AC_DEFINE_UNQUOTED([DEFAULT_DM_ADD_NODE], $add_on, [Define default node creation
dnl -- Default settings for lvm.conf { devices/use_devicesfile }
AC_MSG_CHECKING([default for use_devicesfile])
AC_ARG_WITH(default-use-devices-file,
AS_HELP_STRING([--with-default-use-devices-file=ON], [default lvm.conf devices/use_devicesfile = [ON=0]]),
AS_HELP_STRING([--with-default-use-devices-file], [default for lvm.conf devices/use_devicesfile = [0]]),
DEFAULT_USE_DEVICES_FILE=$withval, DEFAULT_USE_DEVICES_FILE=0)
AS_CASE(["$DEFAULT_USE_DEVICES_FILE"],
[0|1], [],
@@ -314,17 +313,6 @@ AS_CASE(["$MANGLING"],
AC_MSG_RESULT([$MANGLING])
AC_DEFINE_UNQUOTED([DEFAULT_DM_NAME_MANGLING], $mangling, [Define default name mangling behaviour])
AC_MSG_CHECKING([default for event_activation])
AC_ARG_WITH(default-event-activation,
AS_HELP_STRING([--with-default-event-activation=ON], [default lvm.conf global/event_activation = [ON=1]]),
DEFAULT_EVENT_ACTIVATION=$withval, DEFAULT_EVENT_ACTIVATION=1)
AS_CASE(["$DEFAULT_EVENT_ACTIVATION"],
[0|1], [],
[AC_MSG_ERROR([--with-default-event-activation parameter invalid])])
AC_MSG_RESULT([$DEFAULT_EVENT_ACTIVATION])
AC_DEFINE_UNQUOTED(DEFAULT_EVENT_ACTIVATION, [$DEFAULT_EVENT_ACTIVATION],
[Default for lvm.conf event_activation.])
################################################################################
dnl -- snapshots inclusion type
AC_MSG_CHECKING([whether to include snapshots])
@@ -657,7 +645,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 VDO formatting ?
# Do we want to link lvm2 with a big library for vdoformatting ?
#
#AC_ARG_WITH(vdo-include,
# AS_HELP_STRING([--with-vdo-include=PATH],
@@ -837,7 +825,7 @@ AS_IF([test "$GCC" = "yes" && test "$symvers" = "gnu"], [
[Define to use GNU versioning in the shared library.])
AS_CASE(["$host_os"],
[linux*], [
CLDFLAGS="-Wl,--version-script,.export.sym"
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
LDDEPS="$LDDEPS .export.sym"])
])
@@ -934,11 +922,8 @@ AC_MSG_RESULT([$BUILD_LOCKDSANLOCK])
dnl -- Look for sanlock libraries
AS_IF([test "$BUILD_LOCKDSANLOCK" = "yes"], [
LOCKDSANLOCK_SUPPORT=370
PKG_CHECK_EXISTS(libsanlock_client >= 4.0.0, [LOCKDSANLOCK_SUPPORT=400])
PKG_CHECK_EXISTS(libsanlock_client >= 4.1.0, [LOCKDSANLOCK_SUPPORT=410])
PKG_CHECK_MODULES(LIBSANLOCKCLIENT, libsanlock_client >= 3.7.0, [BUILD_LVMLOCKD="yes"])
AC_DEFINE_UNQUOTED([LOCKDSANLOCK_SUPPORT], [$LOCKDSANLOCK_SUPPORT], [Define version of sanlock.])
PKG_CHECK_MODULES(LIBSANLOCKCLIENT, libsanlock_client >= 3.3.0, [BUILD_LVMLOCKD="yes"])
AC_DEFINE([LOCKDSANLOCK_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd sanlock option.])
])
################################################################################
@@ -956,7 +941,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-config for libdlm_lt may give us libdlm with libpthread
dnl -- pkg-congig 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"])
])
@@ -1050,9 +1035,7 @@ 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"]))
@@ -1088,22 +1071,6 @@ 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,
@@ -1161,38 +1128,6 @@ 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])
@@ -1285,25 +1220,24 @@ AC_MSG_RESULT([$BUILD_LVMDBUSD])
dnl -- Build notifydbus
AC_ARG_ENABLE(notify-dbus,
[AS_HELP_STRING([--enable-notify-dbus], [enable LVM notification using dbus])],
[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])
[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"],
[AC_DEFINE([NOTIFYDBUS_SUPPORT], 1, [Define to 1 to include code that uses dbus notification.])])
[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])
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" || test "$SD_NOTIFY_SUPPORT" = "yes"],
[PKG_CHECK_MODULES(LIBSYSTEMD, [libsystemd])])
AS_IF([test "$NOTIFYDBUS_SUPPORT" = "yes" || test "$SYSTEMD_JOURNAL_SUPPORT" = "yes" || test "$APP_MACHINEID_SUPPORT" = "yes"], [
PKG_CHECK_MODULES(LIBSYSTEMD, [libsystemd])
])
################################################################################
dnl -- Enable Python dbus library
@@ -1396,7 +1330,7 @@ AS_IF([test "$CMDLIB" != "yes"], [CMDLIB="no" LVM2CMD_LIB=], [LVM2CMD_LIB="-llvm
AC_MSG_CHECKING([whether to compile liblvm2cmd.so])
AC_MSG_RESULT([$CMDLIB])
AS_IF([test "$CMDLIB" = "yes" && test "$SHARED_LINK" = "no"],
AS_IF([test "$CMDLIB" == "yes" && test "$SHARED_LINK" = "no"],
[AC_MSG_ERROR([--enable-cmdlib requires dynamic linking.])])
@@ -1772,9 +1706,6 @@ LIBEXECDIR="$(eval echo $(eval echo $libexecdir))"
LVRESIZE_FS_HELPER_PATH="$LIBEXECDIR/lvresize_fs_helper"
AC_DEFINE_UNQUOTED(LVRESIZE_FS_HELPER_PATH, ["$LVRESIZE_FS_HELPER_PATH"], [Path to lvresize_fs_helper script.])
LVMPERSIST_PATH="$SBINDIR/lvmpersist"
AC_DEFINE_UNQUOTED(LVMPERSIST_PATH, ["$LVMPERSIST_PATH"], [Path to lvmpersist script.])
################################################################################
dnl -- dmeventd pidfile and executable path
AC_ARG_WITH(dmeventd-pidfile,
@@ -1854,9 +1785,6 @@ AC_MSG_RESULT([$DEFAULT_LOCK_DIR])
AC_DEFINE_UNQUOTED(DEFAULT_LOCK_DIR, ["$DEFAULT_LOCK_DIR"],
[Name of default locking directory.])
# No --with configure setting, but store in the main configure.h
AC_DEFINE_UNQUOTED(DEFAULT_PROC_DIR, ["/proc"], [Path to /proc.])
################################################################################
dnl -- which kernel interface to use (ioctl only)
AC_MSG_CHECKING([for kernel interface choice])
@@ -1937,11 +1865,9 @@ AC_SUBST(DEFAULT_BACKUP_SUBDIR)
AC_SUBST(DEFAULT_CACHE_SUBDIR)
AC_SUBST(DEFAULT_DM_RUN_DIR)
AC_SUBST(DEFAULT_DMEVENTD_EXIT_ON_PATH)
AC_SUBST(DEFAULT_EVENT_ACTIVATION)
AC_SUBST(DEFAULT_LOCK_DIR)
AC_SUBST(DEFAULT_MIRROR_SEGTYPE)
AC_SUBST(DEFAULT_PID_DIR)
AC_SUBST(DEFAULT_PROC_DIR)
AC_SUBST(DEFAULT_PROFILE_SUBDIR)
AC_SUBST(DEFAULT_RAID10_SEGTYPE)
AC_SUBST(DEFAULT_RUN_DIR)
@@ -1996,7 +1922,6 @@ 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)
@@ -2134,6 +2059,3 @@ 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 (aggressively, using 'cov')
* analyze (agressively, 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,8 +30,6 @@
struct lv_segment;
struct logical_volume;
struct cmd_context;
struct profile;
struct lv_segment *first_seg(const struct logical_volume *lv)
{
@@ -59,7 +57,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, unsigned long n)
void *memccpy(void *dest, const void *src, int c, size_t n)
{
const char *s = src;
char *d = dest;
@@ -72,7 +70,7 @@ void *memccpy(void *dest, const void *src, int c, unsigned long n)
}
/*
* 2 lines below needs to be placed in coverity/config/user_nodefs.h
* 2 lines bellow 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
@@ -92,14 +90,9 @@ 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

@@ -32,12 +32,12 @@ CFLAGS += $(CPG_CFLAGS) $(EXTRA_EXEC_CFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
cmirrord: $(OBJECTS)
$(SHOW) " [CC] $@"
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
$(LMLIBS) -L$(top_builddir)/libdm -ldevmapper $(LIBS)
install_cluster: $(TARGETS)
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_PROGRAM) -D $< $(usrsbindir)/$(<F)
install: install_cluster

View File

@@ -43,14 +43,14 @@ static void usage (FILE *dest)
int main(int argc, char *argv[])
{
int foreground_mode = 0;
static const struct option _long_options[] = {
struct option longopts[] = {
{ "foreground", no_argument, NULL, 'f' },
{ "help" , no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
int opt;
while ((opt = getopt_long (argc, argv, "fh", _long_options, NULL)) != -1) {
while ((opt = getopt_long (argc, argv, "fh", longopts, NULL)) != -1) {
switch (opt) {
case 'f':
foreground_mode = 1;

View File

@@ -197,7 +197,7 @@ int cluster_send(struct clog_request *rq)
iov.iov_base = rq;
iov.iov_len = sizeof(struct clog_request) + rq->u_rq.data_size;
rq->u.version[0] = htole64(CLOG_TFR_VERSION);
rq->u.version[0] = xlate64(CLOG_TFR_VERSION);
rq->u.version[1] = CLOG_TFR_VERSION;
r = clog_request_to_network(rq);
@@ -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 coordinate reading
* a cluster action to co-ordinate reading
* the disk and checkpointing
*/
if (tmp->u_rq.request_type == DM_ULOG_RESUME) {

View File

@@ -52,19 +52,19 @@ static void v5_data_endian_switch(struct clog_request *rq, int to_network __attr
case DM_ULOG_GET_REGION_SIZE:
case DM_ULOG_GET_SYNC_COUNT:
pu64 = (uint64_t *)rq->u_rq.data;
*pu64 = htole64(*pu64);
*pu64 = xlate64(*pu64);
break;
case DM_ULOG_IS_CLEAN:
case DM_ULOG_IN_SYNC:
pi64 = (int64_t *)rq->u_rq.data;
*pi64 = htole64(*pi64);
*pi64 = xlate64(*pi64);
break;
case DM_ULOG_GET_RESYNC_WORK:
case DM_ULOG_IS_REMOTE_RECOVERING:
pi64 = (int64_t *)rq->u_rq.data;
pu64 = ((uint64_t *)rq->u_rq.data) + 1;
*pi64 = htole64(*pi64);
*pu64 = htole64(*pu64);
*pi64 = xlate64(*pi64);
*pu64 = xlate64(*pu64);
break;
default:
LOG_ERROR("Unknown request type, %u", rq_type);
@@ -94,7 +94,7 @@ static void v5_data_endian_switch(struct clog_request *rq, int to_network __attr
case DM_ULOG_IN_SYNC:
case DM_ULOG_IS_REMOTE_RECOVERING:
pu64 = (uint64_t *)rq->u_rq.data;
*pu64 = htole64(*pu64);
*pu64 = xlate64(*pu64);
break;
case DM_ULOG_MARK_REGION:
case DM_ULOG_CLEAR_REGION:
@@ -102,13 +102,13 @@ static void v5_data_endian_switch(struct clog_request *rq, int to_network __attr
pu64 = (uint64_t *)rq->u_rq.data;
for (i = 0; i < end; i++)
pu64[i] = htole64(pu64[i]);
pu64[i] = xlate64(pu64[i]);
break;
case DM_ULOG_SET_REGION_SYNC:
pu64 = (uint64_t *)rq->u_rq.data;
pi64 = ((int64_t *)rq->u_rq.data) + 1;
*pu64 = htole64(*pu64);
*pi64 = htole64(*pi64);
*pu64 = xlate64(*pu64);
*pi64 = xlate64(*pi64);
break;
default:
LOG_ERROR("Unknown request type, %u", rq_type);
@@ -124,15 +124,15 @@ static int v5_endian_to_network(struct clog_request *rq)
size = sizeof(*rq) + u_rq->data_size;
u_rq->error = htole32(u_rq->error);
u_rq->seq = htole32(u_rq->seq);
u_rq->error = xlate32(u_rq->error);
u_rq->seq = xlate32(u_rq->seq);
rq->originator = htole32(rq->originator);
rq->originator = xlate32(rq->originator);
v5_data_endian_switch(rq, 1);
u_rq->request_type = htole32(u_rq->request_type);
u_rq->data_size = htole32(u_rq->data_size);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate32(u_rq->data_size);
return size;
}
@@ -142,7 +142,7 @@ int clog_request_to_network(struct clog_request *rq)
int r;
/* FIXME: Remove this safety check */
if (rq->u.version[0] != htole64(rq->u.version[1])) {
if (rq->u.version[0] != xlate64(rq->u.version[1])) {
LOG_ERROR("Programmer error: version[0] must be LE");
exit(EXIT_FAILURE);
}
@@ -165,12 +165,12 @@ static int v5_endian_from_network(struct clog_request *rq)
int size;
struct dm_ulog_request *u_rq = &rq->u_rq;
u_rq->error = htole32(u_rq->error);
u_rq->seq = htole32(u_rq->seq);
u_rq->request_type = htole32(u_rq->request_type);
u_rq->data_size = htole32(u_rq->data_size);
u_rq->error = xlate32(u_rq->error);
u_rq->seq = xlate32(u_rq->seq);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate32(u_rq->data_size);
rq->originator = htole32(rq->originator);
rq->originator = xlate32(rq->originator);
size = sizeof(*rq) + u_rq->data_size;
@@ -182,7 +182,7 @@ static int v5_endian_from_network(struct clog_request *rq)
int clog_request_from_network(void *data, size_t data_len)
{
uint64_t *vp = data;
uint64_t version = htole64(vp[0]);
uint64_t version = xlate64(vp[0]);
struct clog_request *rq = data;
switch (version) {

View File

@@ -8,8 +8,6 @@
#ifndef _LVM_CLOG_COMPAT_H
#define _LVM_CLOG_COMPAT_H
#include <stddef.h>
/*
* The intermachine communication structure version are:
* 0: Unused
@@ -21,8 +19,6 @@
*/
#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' because dm_bitset_t leads with a uint32_t */
/* 'lc->clean_bits + 1' becasue 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' because dm_bitset_t leads with a uint32_t */
/* 'lc->clean_bits + 1' becasue 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)) {
@@ -292,7 +292,7 @@ static int write_log(struct log_c *lc)
}
/* FIXME Rewrite this function taking advantage of the udev changes (where in use) to improve its efficiency! */
static int find_disk_path(char *major_minor_str, char *path_rtn, size_t sz, int *unlink_path __attribute__((unused)))
static int find_disk_path(char *major_minor_str, char *path_rtn, int *unlink_path __attribute__((unused)))
{
int r;
DIR *dp;
@@ -306,7 +306,7 @@ static int find_disk_path(char *major_minor_str, char *path_rtn, size_t sz, int
return -errno;
if (!S_ISBLK(statbuf.st_mode))
return -EINVAL;
dm_strncpy(path_rtn, major_minor_str, sz);
sprintf(path_rtn, "%s", major_minor_str);
return 0;
}
@@ -329,7 +329,7 @@ static int find_disk_path(char *major_minor_str, char *path_rtn, size_t sz, int
* wanted.
*/
snprintf(path_rtn, sz, "/dev/mapper/%s", dep->d_name);
sprintf(path_rtn, "/dev/mapper/%s", dep->d_name);
if (stat(path_rtn, &statbuf) < 0) {
LOG_DBG("Unable to stat %s", path_rtn);
continue;
@@ -380,8 +380,8 @@ static int _clog_ctr(char *uuid, uint64_t luid,
int disk_log;
char disk_path[PATH_MAX] = { 0 };
int unlink_path = 0;
long ps;
size_t pages, page_size;
long page_size;
int pages;
/* If core log request, then argv[0] will be region_size */
if (!strtoll(argv[0], &p, 0) || *p) {
@@ -394,7 +394,7 @@ static int _clog_ctr(char *uuid, uint64_t luid,
goto fail;
}
r = find_disk_path(argv[0], disk_path, sizeof(disk_path), &unlink_path);
r = find_disk_path(argv[0], disk_path, &unlink_path);
if (r) {
LOG_ERROR("Unable to find path to device %s", argv[0]);
goto fail;
@@ -452,7 +452,7 @@ static int _clog_ctr(char *uuid, uint64_t luid,
lc->skip_bit_warning = region_count;
lc->disk_fd = -1;
lc->log_dev_failed = 0;
if (!_dm_strncpy(lc->uuid, uuid, DM_UUID_LEN)) {
if (!dm_strncpy_check(lc->uuid, uuid, DM_UUID_LEN)) {
LOG_ERROR("Cannot use too long UUID %s.", uuid);
r = -EINVAL;
goto fail;
@@ -488,15 +488,14 @@ static int _clog_ctr(char *uuid, uint64_t luid,
lc->sync_count = (log_sync == NOSYNC) ? region_count : 0;
if (disk_log) {
if (((ps = sysconf(_SC_PAGESIZE)) <= 0) ||
(ps > (1 << 24))) {
if ((page_size = sysconf(_SC_PAGESIZE)) < 0) {
LOG_ERROR("Unable to read pagesize: %s",
strerror(errno));
r = errno;
goto fail;
}
page_size = (size_t)ps;
pages = (*(lc->clean_bits) + page_size - 1) / page_size;
pages = *(lc->clean_bits) / page_size;
pages += *(lc->clean_bits) % page_size ? 1 : 0;
pages += 1; /* for header */
r = open(disk_path, O_RDWR | O_DIRECT);
@@ -928,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 completeness
* The function is here for completness
*
* Returns: 0 on success, -EXXX on failure
*/
@@ -1019,7 +1018,7 @@ static int clog_in_sync(struct dm_ulog_request *rq)
* happen for reads is that additional read attempts may be
* taken.
*
* Further investigation may be required to determine if there are
* Futher 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

@@ -326,11 +326,10 @@ static int do_local_work(void *data __attribute__((unused)))
*
* Returns: 0 on success, -EXXX on failure
*/
int kernel_send(void *data)
int kernel_send(struct dm_ulog_request *u_rq)
{
int r;
uint16_t size;
struct dm_ulog_request *u_rq = data;
if (!u_rq)
return -EINVAL;
@@ -354,7 +353,7 @@ int kernel_send(void *data)
size = sizeof(struct dm_ulog_request);
}
r = kernel_send_helper(data, size);
r = kernel_send_helper(u_rq, size);
if (r)
LOG_ERROR("Failed to send msg to kernel.");

View File

@@ -12,11 +12,9 @@
#ifndef _LVM_CLOG_LOCAL_H
#define _LVM_CLOG_LOCAL_H
struct dm_ulog_request;
int init_local(void);
void cleanup_local(void);
int kernel_send(void *data);
int kernel_send(struct dm_ulog_request *rq);
#endif /* _LVM_CLOG_LOCAL_H */

View File

@@ -11,7 +11,7 @@
*/
#include "logging.h"
const char * const __rq_types_off_by_one[] = {
const char *__rq_types_off_by_one[] = {
"DM_ULOG_CTR",
"DM_ULOG_DTR",
"DM_ULOG_PRESUSPEND",

View File

@@ -20,7 +20,7 @@
/* SHORT_UUID - print last 8 chars of a string */
#define SHORT_UUID(x) (strlen(x) > 8) ? ((x) + (strlen(x) - 8)) : (x)
extern const char * const __rq_types_off_by_one[];
extern const char *__rq_types_off_by_one[];
#define RQ_TYPE(x) __rq_types_off_by_one[(x) - 1]
extern int log_tabbing;

View File

@@ -70,12 +70,12 @@ plugins.device-mapper: $(LIB_SHARED)
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
dmeventd: $(LIB_SHARED) dmeventd.o
$(SHOW) " [CC] $@"
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) dmeventd.o \
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS)
dmeventd.static: $(LIB_STATIC) dmeventd.o
$(SHOW) " [CC] $@"
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) $(STATIC_LDFLAGS) -static dmeventd.o \
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS) $(STATIC_LIBS)
@@ -84,27 +84,27 @@ ifeq ("@PKGCONFIG@", "yes")
endif
install_include: $(srcdir)/libdevmapper-event.h
$(SHOW) " [INSTALL] $(<F)"
@echo " [INSTALL] $(<F)"
$(Q) $(INSTALL_DATA) -D $< $(includedir)/$(<F)
install_pkgconfig: libdevmapper-event.pc
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_DATA) -D $< $(pkgconfigdir)/devmapper-event.pc
install_lib_dynamic: install_lib_shared
install_lib_static: $(LIB_STATIC)
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_DATA) -D $< $(usrlibdir)/$(<F)
install_lib: $(INSTALL_LIB_TARGETS)
install_dmeventd_dynamic: dmeventd
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_dmeventd_static: dmeventd.static
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
install_dmeventd: $(INSTALL_DMEVENTD_TARGETS)

View File

@@ -23,12 +23,12 @@
#include "libdm/misc/dm-logging.h"
#include "base/memory/zalloc.h"
#include "libdaemon/server/daemon-stray.h"
#include <dlfcn.h>
#include <pthread.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>
#include <arpa/inet.h> /* for htonl, ntohl */
@@ -92,12 +92,11 @@ static const size_t THREAD_STACK_SIZE = 300 * 1024;
/* Default idle exit timeout 1 hour (in seconds) */
static const time_t DMEVENTD_IDLE_EXIT_TIMEOUT = 60 * 60;
/* Default grace period for thread cleanup 10 seconds */
#define DMEVENTD_DEFAULT_GRACE_PERIOD 10
static time_t _grace_period = DMEVENTD_DEFAULT_GRACE_PERIOD;
static int _debug_level = 0;
static int _use_syslog = 1;
static int _systemd_activation = 0;
static int _foreground = 0;
static int _restart = 0;
static time_t _idle_since = 0;
static const char *_exit_on = DEFAULT_DMEVENTD_EXIT_ON_PATH;
static char **_initial_registrations = 0;
@@ -204,17 +203,16 @@ struct message_data {
char *dso_name; /* Name of DSO. */
char *device_uuid; /* Mapped device path. */
char *events_str; /* Events string as fetched from message. */
unsigned events_field; /* Events bitfield. */
uint32_t timeout_secs;
enum dm_event_mask events_field; /* Events bitfield. */
char *timeout_str;
uint32_t timeout_secs;
struct dm_event_daemon_message *msg; /* Pointer to message buffer. */
};
/* There are three states a thread can attain. */
enum {
DM_THREAD_REGISTERING, /* Registering, transitions to RUNNING */
DM_THREAD_RUNNING, /* Working on events, transitions to GRACE or DONE */
DM_THREAD_GRACE_PERIOD, /* Thread awaits reuse for a grace period */
DM_THREAD_RUNNING, /* Working on events, transitions to DONE */
DM_THREAD_DONE /* Terminated and cleanup is pending */
};
@@ -238,15 +236,12 @@ struct thread_status {
} device;
int processing; /* Set when event is being processed */
int status; /* See DM_THREAD_{REGISTERING,RUNNING,GRACE_PERIOD,DONE} */
int status; /* See DM_THREAD_{REGISTERING,RUNNING,DONE} */
int events; /* bitfield for event filter. */
int current_events; /* bitfield for occurred events. */
int current_events; /* bitfield for occured events. */
struct dm_task *wait_task;
int pending; /* Set when event filter change is pending */
int used; /* Count thread reusage (for debugging) */
pthread_cond_t grace_cond; /* Condition variable for grace period wait */
pthread_mutex_t grace_mutex; /* Mutex for grace period synchronization */
time_t next_time;
uint32_t timeout;
struct dm_list timeout_list;
@@ -276,7 +271,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;
@@ -403,18 +398,11 @@ static void _free_thread_status(struct thread_status *thread)
_lib_put(thread->dso_data);
if (thread->wait_task)
dm_task_destroy(thread->wait_task);
/* Clean up grace period synchronization */
pthread_cond_destroy(&thread->grace_cond);
pthread_mutex_destroy(&thread->grace_mutex);
free(thread->device.uuid);
free(thread->device.name);
free(thread);
}
static int _lock_mutex(void);
static int _unlock_mutex(void);
/* Note: events_field must not be 0, ensured by caller */
static struct thread_status *_alloc_thread_status(const struct message_data *data,
struct dso_data *dso_data)
@@ -442,18 +430,7 @@ static struct thread_status *_alloc_thread_status(const struct message_data *dat
if (!(thread->device.name = strdup(data->device_uuid)))
goto_out;
/* Initialize grace period synchronization */
if (pthread_cond_init(&thread->grace_cond, NULL)) {
log_error("Failed to initialize grace period condition variable.");
goto_out;
}
if (pthread_mutex_init(&thread->grace_mutex, NULL)) {
log_error("Failed to initialize grace period mutex.");
pthread_cond_destroy(&thread->grace_cond);
goto_out;
}
/* runs ioctl and may register lvm2 plugin */
/* runs ioctl and may register lvm2 pluging */
thread->processing = 1;
thread->status = DM_THREAD_REGISTERING;
@@ -546,7 +523,7 @@ static int _fetch_string(char **ptr, char **src, const int delimiter)
*p = delimiter;
*src = p;
}
(*src)++; /* Skip delimiter, next field */
(*src)++; /* Skip delmiter, next field */
} else if ((len = strlen(*src))) {
/* No delimiter, item ends with '\0' */
if (!(*ptr = strdup(*src))) {
@@ -632,16 +609,13 @@ static int _fill_device_data(struct thread_status *ts)
if (!dm_task_run(dmt))
goto fail;
if (!dm_task_get_info(dmt, &dmi))
goto fail;
if (!dmi.exists)
goto fail;
free(ts->device.name);
if (!(ts->device.name = strdup(dm_task_get_name(dmt))))
goto fail;
if (!dm_task_get_info(dmt, &dmi))
goto fail;
ts->device.major = dmi.major;
ts->device.minor = dmi.minor;
dm_task_set_event_nr(ts->wait_task, dmi.event_nr);
@@ -655,9 +629,9 @@ fail:
static struct dm_task *_get_device_status(struct thread_status *ts)
{
struct dm_task *dmt;
struct dm_task *dmt = dm_task_create(DM_DEVICE_STATUS);
if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
if (!dmt)
return_NULL;
if (!dm_task_set_uuid(dmt, ts->device.uuid)) {
@@ -693,21 +667,6 @@ static struct thread_status *_lookup_thread_status(struct message_data *data)
return NULL;
}
static struct thread_status *_lookup_grace_thread_status(struct message_data *data)
{
struct thread_status *thread;
dm_list_iterate_items(thread, &_thread_registry_unused)
if ((thread->status == DM_THREAD_GRACE_PERIOD) &&
!strcmp(data->device_uuid, thread->device.uuid) &&
!strcmp(data->dso_name, thread->dso_data->dso_name)) {
DEBUGLOG("Found reusable thread %x in grace period.",(int)thread->thread);
return thread;
}
return NULL;
}
static int _get_status(struct message_data *message_data)
{
struct dm_event_daemon_message *msg = message_data->msg;
@@ -724,15 +683,9 @@ static int _get_status(struct message_data *message_data)
return -EINVAL;
_lock_mutex();
if (!(count = dm_list_size(&_thread_registry))) {
_unlock_mutex();
ret = 0; /* no monitored devices */
goto out;
}
count = dm_list_size(&_thread_registry);
buffers = alloca(sizeof(char*) * count);
dm_list_iterate_items(thread, &_thread_registry) {
/* coverity[overflow_sink] - only positive 'current' is used */
if ((current = dm_asprintf(buffers + i, "0:%d %s %s %u %" PRIu32 ";",
i, thread->dso_data->dso_name,
thread->device.uuid, thread->events,
@@ -741,7 +694,6 @@ static int _get_status(struct message_data *message_data)
goto out;
}
++i;
/* coverity[overflow] - only positive 'current' is used */
size += current; /* count with trailing '\0' */
}
_unlock_mutex();
@@ -836,11 +788,7 @@ static void *_timeout_thread(void *unused __attribute__((unused)))
if (thread->next_time <= curr_time) {
thread->next_time = curr_time + thread->timeout;
_lock_mutex();
if (thread->status != DM_THREAD_RUNNING) {
/* Skip wake up of non running thread (i.e. in grace period) */
log_debug("Skipping SIGALRM to non running Thr %x for timeout.",
(int) thread->thread);
} else if (thread->processing) {
if (thread->processing) {
/* Cannot signal processing monitoring thread */
log_debug("Skipping SIGALRM to processing Thr %x for timeout.",
(int) thread->thread);
@@ -927,43 +875,6 @@ enum {
DM_WAIT_FATAL
};
/* Reset pending signal for a task/thread */
static int _reset_pending_signal(int signal)
{
sigset_t prev_mask, mask;
struct sigaction prev_act, act = { .sa_handler = SIG_IGN };
sigemptyset(&act.sa_mask);
sigemptyset(&prev_mask);
sigemptyset(&mask);
sigaddset(&mask, signal);
if (pthread_sigmask(SIG_SETMASK, &mask, &prev_mask) != 0) {
log_sys_error("pthread_sigmask", "ignore signal");
return 0; /* What better */
}
if (sigaction(signal, &act, &prev_act) < 0) {
log_sys_error("sigaction", "ignore signal");
return 0;
}
if (sigaction(signal, &prev_act, NULL) < 0) {
log_sys_error("sigaction", "restore signal");
return 0;
}
/* And also restore the process's original sigmask */
if (pthread_sigmask(SIG_SETMASK, &prev_mask, NULL) < 0) {
log_sys_error("pthread_sigmask", "restore signal");
return 0;
}
return 1;
}
/* Wait on a device until an event occurs. */
static int _event_wait(struct thread_status *thread)
{
@@ -986,9 +897,6 @@ static int _event_wait(struct thread_status *thread)
}
if (dm_task_run(thread->wait_task)) {
/* Recheck device info whether is still exists */
if (!_fill_device_data(thread))
goto disappeared; /* device is gone... */
thread->current_events |= DM_EVENT_DEVICE_ERROR;
ret = DM_WAIT_INTR;
/* Update event_nr */
@@ -997,7 +905,6 @@ static int _event_wait(struct thread_status *thread)
} else {
switch (dm_task_get_errno(thread->wait_task)) {
case ENXIO:
disappeared:
log_error("%s disappeared, detaching.",
thread->device.name);
ret = DM_WAIT_FATAL;
@@ -1054,8 +961,7 @@ static void _do_process_event(struct thread_status *thread)
if (!task)
log_error("Lost event in Thr %x.", (int)thread->thread);
else {
thread->dso_data->process_event(task, (enum dm_event_mask) thread->current_events,
&(thread->dso_private));
thread->dso_data->process_event(task, thread->current_events, &(thread->dso_private));
if (task != thread->wait_task)
dm_task_destroy(task);
}
@@ -1067,12 +973,6 @@ static void _thread_unused(struct thread_status *thread)
LINK(thread, &_thread_registry_unused);
}
static void _thread_used(struct thread_status *thread)
{
UNLINK_THREAD(thread);
LINK_THREAD(thread);
}
/* Thread cleanup handler to unregister device. */
static void _monitor_unregister(void *arg)
{
@@ -1109,11 +1009,32 @@ static void _monitor_unregister(void *arg)
kill(getpid(), SIGINT);
}
static int _monitor_events(struct thread_status *thread)
/* Device monitoring thread. */
static void *_monitor_thread(void *arg)
{
int ret = 0;
struct thread_status *thread = arg;
int ret;
sigset_t pendmask;
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
pthread_cleanup_push(_monitor_unregister, thread);
if (!_fill_device_data(thread)) {
log_error("Failed to fill device data for %s.", thread->device.uuid);
_lock_mutex();
goto out;
}
if (!_do_register_device(thread)) {
log_error("Failed to register device %s.", thread->device.name);
_lock_mutex();
goto out;
}
_lock_mutex();
thread->status = DM_THREAD_RUNNING;
thread->processing = 0;
/* Loop awaiting/analyzing device events. */
while (thread->events) {
@@ -1159,89 +1080,6 @@ static int _monitor_events(struct thread_status *thread)
break;
}
}
return ret;
}
/* Thread awaits condition wake up for a grace period */
static void _monitor_grace_period_wait(struct thread_status *thread)
{
int ret;
/* Wait during grace period */
struct timespec grace_timeout = { .tv_sec = time(NULL) + _grace_period };
DEBUGLOG("Thread %x entering grace period for %ld seconds.",
(int)thread->thread, _grace_period);
pthread_mutex_lock(&thread->grace_mutex);
ret = pthread_cond_timedwait(&thread->grace_cond, &thread->grace_mutex, &grace_timeout);
pthread_mutex_unlock(&thread->grace_mutex);
DEBUGLOG("Thread %x wakeup grace period (%d).", (int)thread->thread, ret);
}
/* Device monitoring thread. */
static void *_monitor_thread(void *arg)
{
struct thread_status *thread = arg;
int ret;
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
pthread_cleanup_push(_monitor_unregister, thread);
if (!_fill_device_data(thread)) {
log_error("Failed to fill device data for %s.", thread->device.uuid);
_lock_mutex();
goto out;
}
if (!_do_register_device(thread)) {
log_error("Failed to register device %s.", thread->device.name);
_lock_mutex();
goto out;
}
_lock_mutex();
/* Main monitoring loop with grace period support */
while (thread->events) {
DEBUGLOG("Monitoring %s with Thr %x (events: %x, used: %d).",
thread->device.name, (int)thread->thread,
thread->events, thread->used);
thread->status = DM_THREAD_RUNNING;
thread->processing = 0;
thread->used++;
ret = _monitor_events(thread);
/* No grace period when set to 0
* or there were left some processing events which is an error state
* or there is on going exit
* or there was fatal error while waiting for some event */
if (!_grace_period || thread->events || _exit_now || (ret == DM_WAIT_FATAL))
break;
thread->status = DM_THREAD_GRACE_PERIOD; /* No events - enter grace period */
_thread_unused(thread);
_unlock_mutex();
DEBUGLOG("Gracing %s with Thr %x (events: %x, used: %d).",
thread->device.name, (int)thread->thread,
thread->events, thread->used);
_monitor_grace_period_wait(thread);
_lock_mutex();
_thread_used(thread);
/* Before restarting event loop reset any pending SIGALRM signal */
if (!_reset_pending_signal(SIGALRM)) {
stack;
break; /* Something is wrong... */
}
}
out:
/* ';' fixes gcc compilation problem with older pthread macros
* "label at end of compound statement" */
@@ -1270,18 +1108,6 @@ static int _update_events(struct thread_status *thread, int events)
thread->events = events;
thread->pending = DM_EVENT_REGISTRATION_PENDING;
/* If needed, wake up thread waiting in grace period */
if ((events || _exit_now) && (thread->status == DM_THREAD_GRACE_PERIOD)) {
_unlock_mutex();
DEBUGLOG("Waking up thread %x waiting in grace period (events=%x).",
(int)thread->thread, events);
pthread_mutex_lock(&thread->grace_mutex);
pthread_cond_signal(&thread->grace_cond);
pthread_mutex_unlock(&thread->grace_mutex);
_lock_mutex();
return 0;
}
/* Only non-processing threads can be notified */
if (!thread->processing) {
DEBUGLOG("Sending SIGALRM to wakeup Thr %x.", (int)thread->thread);
@@ -1296,7 +1122,9 @@ static int _update_events(struct thread_status *thread, int events)
}
}
/* Threads with no events will enter grace period in their main loop */
/* Threads with no events has to be moved to unused */
if (!thread->events)
_thread_unused(thread);
return -ret;
}
@@ -1398,8 +1226,7 @@ static int _register_for_event(struct message_data *message_data)
_lock_mutex();
if ((thread = _lookup_thread_status(message_data)) ||
(thread = _lookup_grace_thread_status(message_data))) {
if ((thread = _lookup_thread_status(message_data))) {
/* OR event # into events bitfield. */
ret = _update_events(thread, (thread->events | message_data->events_field));
} else {
@@ -1513,13 +1340,11 @@ static int _get_registered_dev(struct message_data *message_data, int next)
/*
* If we didn't get a match, try the threads waiting to be deleted.
* Threads in grace period are skipped.
* FIXME Do something similar if 'next' is set.
*/
if (!hit && !next)
dm_list_iterate_items(thread, &_thread_registry_unused)
if ((thread->status != DM_THREAD_GRACE_PERIOD) &&
_want_registered_device(message_data->dso_name,
if (_want_registered_device(message_data->dso_name,
message_data->device_uuid, thread)) {
hit = thread;
goto reg;
@@ -1604,8 +1429,8 @@ static int _open_fifo(const char *path)
{
struct stat st;
int fd = -1;
/*
/*
* FIXME Explicitly verify the code's requirement that path is secure:
* - All parent directories owned by root without group/other write access unless sticky.
*/
@@ -1619,8 +1444,7 @@ static int _open_fifo(const char *path)
} else if (!S_ISFIFO(st.st_mode) || st.st_uid ||
(st.st_mode & (S_IEXEC | S_IRWXG | S_IRWXO))) {
log_warn("WARNING: %s has wrong attributes: Replacing.", path);
/* coverity[toctou] don't care, path is going to be recreated */
if (unlink(path) && (errno != ENOENT)) {
if (unlink(path)) {
log_sys_error("unlink", path);
return -1;
}
@@ -1628,7 +1452,6 @@ static int _open_fifo(const char *path)
/* Create fifo. */
(void) dm_prepare_selinux_context(path, S_IFIFO);
/* coverity[toctou] revalidating things again */
if ((mkfifo(path, 0600) == -1) && errno != EEXIST) {
log_sys_error("mkfifo", path);
(void) dm_prepare_selinux_context(NULL, 0);
@@ -1894,8 +1717,8 @@ static void _process_request(struct dm_event_fifos *fifos)
free(msg.data);
if (cmd == DM_EVENT_CMD_DIE) {
_exit_now = DM_SCHEDULED_EXIT; /* No grace period */
_unregister_all_threads();
_exit_now = DM_SCHEDULED_EXIT;
log_info("dmeventd exiting for restart.");
}
}
@@ -2109,30 +1932,26 @@ out:
static void _remove_files_on_exit(void)
{
if (unlink(DMEVENTD_PIDFILE) && (errno != ENOENT))
if (unlink(DMEVENTD_PIDFILE))
log_sys_debug("unlink", DMEVENTD_PIDFILE);
if (!_systemd_activation) {
if (unlink(DM_EVENT_FIFO_CLIENT) && (errno != ENOENT))
if (unlink(DM_EVENT_FIFO_CLIENT))
log_sys_debug("unlink", DM_EVENT_FIFO_CLIENT);
if (unlink(DM_EVENT_FIFO_SERVER) && (errno != ENOENT))
if (unlink(DM_EVENT_FIFO_SERVER))
log_sys_debug("unlink", DM_EVENT_FIFO_SERVER);
}
}
static void _daemonize(void)
{
int child_status, null_fd;
int child_status;
int fd;
pid_t pid;
struct rlimit rlim;
struct timeval tval;
sigset_t my_sigset;
struct custom_fds custom_fds = {
/* Do not close fds preloaded by systemd! */
.out = (_systemd_activation) ? SD_FD_FIFO_SERVER : -1,
.err = -1,
.report = (_systemd_activation) ? SD_FD_FIFO_CLIENT : -1,
};
sigemptyset(&my_sigset);
if (sigprocmask(SIG_SETMASK, &my_sigset, NULL) < 0) {
@@ -2176,28 +1995,34 @@ static void _daemonize(void)
if (chdir("/"))
exit(EXIT_CHDIR_FAILURE);
daemon_close_stray_fds("dmeventd", 0, -1, &custom_fds);
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
fd = 256; /* just have to guess */
else
fd = rlim.rlim_cur;
if ((null_fd = open("/dev/null", O_RDWR)) < 0)
for (--fd; fd >= 0; fd--) {
#ifdef __linux__
/* Do not close fds preloaded by systemd! */
if (_systemd_activation &&
(fd == SD_FD_FIFO_SERVER || fd == SD_FD_FIFO_CLIENT))
continue;
#endif
(void) close(fd);
}
/* coverity[leaked_handle] dont't care */
if ((open("/dev/null", O_RDONLY) < 0) ||
(open("/dev/null", O_WRONLY) < 0) ||
(open("/dev/null", O_WRONLY) < 0))
exit(EXIT_DESC_OPEN_FAILURE);
if ((dup2(null_fd, STDIN_FILENO) == -1) ||
(dup2(null_fd, STDOUT_FILENO) == -1) ||
(dup2(null_fd, STDERR_FILENO) == -1))
exit(EXIT_DESC_OPEN_FAILURE);
if ((null_fd > STDERR_FILENO) && close(null_fd))
exit(EXIT_DESC_CLOSE_FAILURE);
setsid();
/* coverity[leaked_handle] 'null_fd' handle is not leaking */
}
static int _reinstate_registrations(struct dm_event_fifos *fifos)
{
static const char _failed_parsing_msg[] = "Failed to parse existing event registration.\n";
static const char _delim[] = " ";
static const char *_delim = " ";
struct dm_event_daemon_message msg = { 0 };
char *endp, *dso_name, *dev_name, *mask, *timeout;
unsigned long mask_value, timeout_value;
@@ -2255,11 +2080,6 @@ static int _info_dmeventd(const char *name, struct dm_event_fifos *fifos)
int version;
int ret = 0;
if (!dm_daemon_is_running(DMEVENTD_PIDFILE)) {
fprintf(stderr, "No running dmeventd instance for status query.\n");
return 0;
}
/* Get the list of registrations from the running daemon. */
if (!init_fifos(fifos)) {
fprintf(stderr, "Could not initiate communication with existing dmeventd.\n");
@@ -2314,27 +2134,28 @@ out:
return ret;
}
/* Return 0 - fail, 1 - success, 2 - continue */
static int _restart_dmeventd(struct dm_event_fifos *fifos)
static void _restart_dmeventd(void)
{
struct dm_event_fifos fifos = {
.client = -1,
.server = -1,
/* FIXME Make these either configurable or depend directly on dmeventd_path */
.client_path = DM_EVENT_FIFO_CLIENT,
.server_path = DM_EVENT_FIFO_SERVER
};
struct dm_event_daemon_message msg = { 0 };
int i, count = 0;
char *message;
int version;
const char *e;
if (!dm_daemon_is_running(DMEVENTD_PIDFILE)) {
fprintf(stderr, "WARNING: Could not find running dmeventd associated with pid file %s.\n", DMEVENTD_PIDFILE);
return 0;
}
/* Get the list of registrations from the running daemon. */
if (!init_fifos(fifos)) {
if (!init_fifos(&fifos)) {
fprintf(stderr, "WARNING: Could not initiate communication with existing dmeventd.\n");
return 0;
exit(EXIT_FAILURE);
}
if (!dm_event_get_version(fifos, &version)) {
if (!dm_event_get_version(&fifos, &version)) {
fprintf(stderr, "WARNING: Could not communicate with existing dmeventd.\n");
goto bad;
}
@@ -2346,7 +2167,7 @@ static int _restart_dmeventd(struct dm_event_fifos *fifos)
goto bad;
}
if (daemon_talk(fifos, &msg, DM_EVENT_CMD_GET_STATUS, "-", "-", 0, 0))
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_STATUS, "-", "-", 0, 0))
goto bad;
message = strchr(msg.data, ' ') + 1;
@@ -2370,7 +2191,7 @@ static int _restart_dmeventd(struct dm_event_fifos *fifos)
}
if (version >= 2) {
if (daemon_talk(fifos, &msg, DM_EVENT_CMD_GET_PARAMETERS, "-", "-", 0, 0)) {
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_PARAMETERS, "-", "-", 0, 0)) {
fprintf(stderr, "Failed to acquire parameters from old dmeventd.\n");
goto bad;
}
@@ -2390,7 +2211,7 @@ static int _restart_dmeventd(struct dm_event_fifos *fifos)
}
#endif
if (daemon_talk(fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0)) {
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0)) {
fprintf(stderr, "Old dmeventd refused to die.\n");
goto bad;
}
@@ -2399,56 +2220,50 @@ static int _restart_dmeventd(struct dm_event_fifos *fifos)
((e = getenv(SD_ACTIVATION_ENV_VAR_NAME)) && strcmp(e, "1")))
_systemd_activation = 1;
fini_fifos(fifos);
fini_fifos(&fifos);
/* Give a few seconds dmeventd to finish */
_wait_for_new_pid();
if (!_systemd_activation)
return 2; // continue with dmeventd start up
return;
/* Reopen fifos. */
if (!init_fifos(fifos)) {
if (!init_fifos(&fifos)) {
fprintf(stderr, "Could not initiate communication with new instance of dmeventd.\n");
return 0;
exit(EXIT_FAILURE);
}
if (!_reinstate_registrations(fifos)) {
if (!_reinstate_registrations(&fifos)) {
fprintf(stderr, "Failed to reinstate monitoring with new instance of dmeventd.\n");
goto bad;
}
fini_fifos(fifos);
return 1;
fini_fifos(&fifos);
exit(EXIT_SUCCESS);
bad:
fini_fifos(fifos);
return 0;
fini_fifos(&fifos);
exit(EXIT_FAILURE);
}
static void _usage(char *prog, FILE *file)
{
fprintf(file, "Usage:\n"
"%s [-d [-d [-d]]] [-e path] [-g seconds] [-f] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
"%s [-d [-d [-d]]] [-e path] [-f] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
" -d Log debug messages to syslog (-d, -dd, -ddd)\n"
" -e Select a file path checked on exit\n"
" -g Grace period for thread cleanup (0-300 seconds, default: %d)\n"
" -f Don't fork, run in the foreground\n"
" -h Show this help information\n"
" -i Query running instance of dmeventd for info\n"
" -l Log to stdout,stderr instead of syslog\n"
" -? Show this help information on stderr\n"
" -R Restart dmeventd\n"
" -V Show version of dmeventd\n\n", prog,
(int)_grace_period);
" -V Show version of dmeventd\n\n", prog);
}
int main(int argc, char *argv[])
{
signed char opt;
int debug_level = 0;
int info = 0;
int restart = 0;
int use_syslog = 1;
struct dm_event_fifos fifos = {
.client = -1,
.server = -1,
@@ -2459,7 +2274,7 @@ int main(int argc, char *argv[])
optopt = optind = opterr = 0;
optarg = (char*) "";
while ((opt = getopt(argc, argv, ":?e:g:fhiVdlR")) != EOF) {
while ((opt = getopt(argc, argv, ":?e:fhiVdlR")) != EOF) {
switch (opt) {
case 'h':
_usage(argv[0], stdout);
@@ -2468,10 +2283,9 @@ int main(int argc, char *argv[])
_usage(argv[0], stderr);
return EXIT_SUCCESS;
case 'i':
info++;
break;
return _info_dmeventd(argv[0], &fifos) ? EXIT_SUCCESS : EXIT_FAILURE;
case 'R':
restart++;
_restart++;
break;
case 'e':
if (strchr(optarg, '"')) {
@@ -2480,21 +2294,14 @@ int main(int argc, char *argv[])
}
_exit_on=optarg;
break;
case 'g':
_grace_period = (time_t)atoi(optarg);
if (_grace_period < 0 || _grace_period > 300) {
fprintf(stderr, "dmeventd: grace period must be between 0 and 300 seconds.\n");
return EXIT_FAILURE;
}
break;
case 'f':
_foreground++;
break;
case 'd':
debug_level++;
_debug_level++;
break;
case 'l':
use_syslog = 0;
_use_syslog = 0;
break;
case 'V':
printf("dmeventd version: %s\n", DM_LIB_VERSION);
@@ -2505,16 +2312,10 @@ int main(int argc, char *argv[])
}
}
if (info) {
_foreground = 1;
use_syslog = 0;
}
if (!_foreground && !use_syslog) {
if (!_foreground && !_use_syslog) {
printf("WARNING: Ignoring logging to stdout, needs options -f\n");
use_syslog = 1;
_use_syslog = 1;
}
/*
* Switch to C locale to avoid reading large locale-archive file
* used by some glibc (on some distributions it takes over 100MB).
@@ -2523,29 +2324,21 @@ int main(int argc, char *argv[])
if (setenv("LC_ALL", "C", 1))
perror("Cannot set LC_ALL to C");
if (info)
return _info_dmeventd(argv[0], &fifos) ? EXIT_SUCCESS : EXIT_FAILURE;
if (_restart)
_restart_dmeventd();
#ifdef __linux__
_systemd_activation = _systemd_handover(&fifos);
#endif
dm_log_with_errno_init(_libdm_log);
if (restart) {
dm_event_log_set(debug_level, 0);
if ((restart = _restart_dmeventd(&fifos)) < 2)
return restart ? EXIT_SUCCESS : EXIT_FAILURE;
}
if (!_foreground)
_daemonize();
if (use_syslog)
if (_use_syslog)
openlog("dmeventd", LOG_PID, LOG_DAEMON);
dm_event_log_set(debug_level, use_syslog);
dm_event_log_set(_debug_level, _use_syslog);
dm_log_with_errno_init(_libdm_log);
(void) dm_prepare_selinux_context(DMEVENTD_PIDFILE, S_IFREG);
if (dm_create_lockfile(DMEVENTD_PIDFILE) == 0)
@@ -2641,7 +2434,7 @@ int main(int argc, char *argv[])
if (fifos.server >= 0 && close(fifos.server))
log_sys_debug("server close", fifos.server_path);
if (use_syslog)
if (_use_syslog)
closelog();
_exit_dm_lib();

View File

@@ -15,8 +15,6 @@
#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"
@@ -70,7 +68,7 @@ struct dm_event_fifos {
int daemon_talk(struct dm_event_fifos *fifos,
struct dm_event_daemon_message *msg, int cmd,
const char *dso_name, const char *dev_name,
unsigned evmask, uint32_t timeout);
enum dm_event_mask evmask, uint32_t timeout);
int init_fifos(struct dm_event_fifos *fifos);
void fini_fifos(struct dm_event_fifos *fifos);
int dm_event_get_version(struct dm_event_fifos *fifos, int *version);

View File

@@ -352,7 +352,7 @@ static int _daemon_write(struct dm_event_fifos *fifos,
int daemon_talk(struct dm_event_fifos *fifos,
struct dm_event_daemon_message *msg, int cmd,
const char *dso_name, const char *dev_name,
unsigned evmask, uint32_t timeout)
enum dm_event_mask evmask, uint32_t timeout)
{
int msg_size;
memset(msg, 0, sizeof(*msg));
@@ -400,16 +400,25 @@ int daemon_talk(struct dm_event_fifos *fifos,
return (int32_t) msg->cmd;
}
/*
* Check for usable client fifo file
* start_daemon
*
* Returns: 2 client path does not exists, dmeventd should be restarted
* 1 on success, 0 otherwise
* This function forks off a process (dmeventd) that will handle
* the events. I am currently test opening one of the fifos to
* ensure that the daemon is running and listening... I thought
* this would be less expensive than fork/exec'ing every time.
* Perhaps there is an even quicker/better way (no, checking the
* lock file is _not_ a better way).
*
* Returns: 1 on success, 0 otherwise
*/
static int _check_for_usable_fifos(char *dmeventd_path, struct dm_event_fifos *fifos)
static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
{
int pid, ret = 0;
int status;
struct stat statbuf;
char default_dmeventd_path[] = DMEVENTD_PATH;
char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
/*
* FIXME Explicitly verify the code's requirement that client_path is secure:
@@ -420,7 +429,7 @@ static int _check_for_usable_fifos(char *dmeventd_path, struct dm_event_fifos *f
if ((lstat(fifos->client_path, &statbuf) < 0)) {
if (errno == ENOENT)
/* Jump ahead if fifo does not already exist. */
return 2;
goto start_server;
else {
log_sys_error("stat", fifos->client_path);
return 0;
@@ -446,14 +455,12 @@ static int _check_for_usable_fifos(char *dmeventd_path, struct dm_event_fifos *f
log_error("%s is no longer a secure root-owned fifo with mode 0600.", fifos->client_path);
if (close(fifos->client))
log_sys_debug("close", fifos->client_path);
fifos->client = -1;
return 0;
}
/* server is running and listening */
if (close(fifos->client))
log_sys_debug("close", fifos->client_path);
fifos->client = -1;
return 1;
}
if (errno != ENXIO && errno != ENOENT) {
@@ -462,36 +469,9 @@ static int _check_for_usable_fifos(char *dmeventd_path, struct dm_event_fifos *f
return 0;
}
return 2;
}
/*
* start_daemon
*
* This function forks off a process (dmeventd) that will handle
* the events. I am currently test opening one of the fifos to
* ensure that the daemon is running and listening... I thought
* this would be less expensive than fork/exec'ing every time.
* Perhaps there is an even quicker/better way (no, checking the
* lock file is _not_ a better way).
*
* Returns: 1 on success, 0 otherwise
*/
static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
{
struct stat statbuf;
char default_dmeventd_path[] = DMEVENTD_PATH;
char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
int pid, ret = 0;
int status;
switch (_check_for_usable_fifos(dmeventd_path, fifos)) {
case 0: return_0;
case 1: return 1; /* Already running dmeventd */
}
start_server:
/* server is not running */
if ((args[0][0] == '/') && stat(args[0], &statbuf)) {
log_sys_error("stat", args[0]);
return 0;
@@ -512,17 +492,8 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
strerror(errno));
else if (WEXITSTATUS(status))
log_error("Unable to start dmeventd.");
else {
/* Loop here till forked dmeventd is serving fifos */
for (ret = 100; ret > 0; --ret)
switch (_check_for_usable_fifos(dmeventd_path, fifos)) {
case 0: return_0;
case 1: return 1;
case 2: usleep(1000); break;
}
/* ret == 0 */
log_error("Dmeventd is not serving fifos.");
}
else
ret = 1;
}
return ret;
@@ -542,7 +513,7 @@ int init_fifos(struct dm_event_fifos *fifos)
/* Lock out anyone else trying to do communication with the daemon. */
if (flock(fifos->server, LOCK_EX) < 0) {
log_sys_error("flock", fifos->server_path);
goto bad_no_unlock;
goto bad;
}
/* if ((fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK)) < 0) {*/
@@ -553,9 +524,6 @@ int init_fifos(struct dm_event_fifos *fifos)
return 1;
bad:
if (flock(fifos->server, LOCK_UN))
log_sys_debug("flock unlock", fifos->server_path);
bad_no_unlock:
if (close(fifos->server))
log_sys_debug("close", fifos->server_path);
fifos->server = -1;
@@ -754,7 +722,7 @@ static char *_fetch_string(char **src, const int delimiter)
/* Parse a device message from the daemon. */
static int _parse_message(struct dm_event_daemon_message *msg, char **dso_name,
char **uuid, unsigned *evmask)
char **uuid, enum dm_event_mask *evmask)
{
char *id;
char *p = msg->data;
@@ -779,7 +747,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
int ret = 0;
const char *uuid = NULL;
char *reply_dso = NULL, *reply_uuid = NULL;
unsigned reply_mask = 0;
enum dm_event_mask reply_mask = 0;
struct dm_task *dmt = NULL;
struct dm_event_daemon_message msg = { 0 };
struct dm_info info;
@@ -829,7 +797,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
}
dm_event_handler_set_dso(dmevh, reply_dso);
dm_event_handler_set_event_mask(dmevh, (enum dm_event_mask) reply_mask);
dm_event_handler_set_event_mask(dmevh, reply_mask);
free(reply_dso);
reply_dso = NULL;
@@ -988,7 +956,7 @@ void dm_event_log(const char *subsys, int level, const char *file,
fprintf(stream, "%28s:%4d %s", file, line, indent);
vfprintf(stream, _(format), ap);
fputc('\n', stream);
(void) fflush(stream);
fflush(stream);
}
pthread_mutex_unlock(&_log_mutex);
@@ -1007,7 +975,7 @@ void dm_event_log(const char *subsys, int level, const char *file,
static char *_skip_string(char *src, const int delimiter)
{
src = strchr(src, delimiter);
src = srtchr(src, delimiter);
if (src && *(src + 1))
return src + 1;
return NULL;

View File

@@ -29,22 +29,19 @@
*/
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 */
};
@@ -73,10 +70,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 dev_name, uuid or
* Identify the device to monitor by exactly one of device_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 *dev_name);
int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *device_name);
int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid);
@@ -112,7 +109,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 according to current debug level */
/* Log messages acroding 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 initialized.");
log_debug("lvm plugin initilized.");
}
_register_count++;
@@ -103,7 +103,7 @@ void dmeventd_lvm2_exit(void)
pthread_mutex_lock(&_register_mutex);
if (!--_register_count) {
log_debug("lvm plugin shutting down.");
log_debug("lvm plugin shuting down.");
lvm2_run(_lvm_handle, "_memlock_dec");
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;

View File

@@ -25,8 +25,6 @@
#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 synchronization failure occurred, mirror out-of-sync
* S => Sync - A sychronization 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 evmask __attribute__((unused)),
enum dm_event_mask event __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 maximum number of RAID images */
/* Hold enough elements for the mximum number of RAID images */
#define RAID_DEVS_ELEMS ((DEFAULT_RAID_MAX_IMAGES + 63) / 64)
struct dso_state {
@@ -84,7 +84,7 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
*/
if (!state->warned && status->insync_regions < status->total_regions) {
state->warned = 1;
log_warn("WARNING: Waiting for resynchronization to finish "
log_warn("WARNING: waiting for resynchronization to finish "
"before initiating repair on RAID device %s.", device);
/* Fall through to allow lvconvert to run. */
}
@@ -114,7 +114,7 @@ out:
}
void process_event(struct dm_task *dmt,
enum dm_event_mask evmask __attribute__((unused)),
enum dm_event_mask event __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 evmask __attribute__((unused)),
enum dm_event_mask event __attribute__((unused)),
void **user)
{
struct dso_state *state = *user;

View File

@@ -45,10 +45,10 @@
struct dso_state {
struct dm_pool *mem;
dm_percent_t metadata_percent_check;
dm_percent_t metadata_percent;
dm_percent_t data_percent_check;
dm_percent_t data_percent;
int metadata_percent_check;
int metadata_percent;
int data_percent_check;
int data_percent;
uint64_t known_metadata_size;
uint64_t known_data_size;
unsigned fails;
@@ -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 maintenance
* Support parallel run of 'task' and it's waitpid maintainence
* 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 evmask,
enum dm_event_mask event __attribute__((unused)),
void **user)
{
const char *device = dm_task_get_name(dmt);
@@ -179,7 +179,7 @@ void process_event(struct dm_task *dmt,
return;
}
if (evmask & DM_EVENT_DEVICE_ERROR) {
if (event & 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))
@@ -223,12 +223,10 @@ void process_event(struct dm_task *dmt,
}
#if THIN_DEBUG
log_debug("Thin pool status " FMTu64 "/" FMTu64 " (" FMTu64 ") "
FMTu64 "/" FMTu64 " (" FMTu64").",
tps->used_data_blocks, tps->total_data_blocks,
state->known_data_size,
log_debug("Thin pool status " FMTu64 "/" FMTu64 " "
FMTu64 "/" FMTu64 ".",
tps->used_metadata_blocks, tps->total_metadata_blocks,
state->known_metadata_size);
tps->used_data_blocks, tps->total_data_blocks);
#endif
/* Thin pool size had changed. Clear the threshold. */
@@ -247,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 surpassed so policy
* Only 100% is exception as it cannot be surpased so policy
* action is called for: >50%, >55% ... >95%, 100%
*/
state->metadata_percent = dm_make_percent(tps->used_metadata_blocks, tps->total_metadata_blocks);
@@ -381,13 +379,14 @@ int register_device(const char *device,
state->argv[1] = str + 1; /* 1 argument - vg/lv */
_init_thread_signals(state);
} else /* Unsupported command format */
} else /* Unuspported command format */
goto inval;
state->max_fails = 1;
state->pid = -1;
*user = state;
log_info("Monitoring thin pool %s.", device);
return 1;
inval:
log_error("Invalid command for monitoring: %s.", cmd_str);
@@ -431,6 +430,7 @@ int unregister_device(const char *device,
_restore_thread_signals(state);
dmeventd_lvm2_exit_with_pool(state);
log_info("No longer monitoring thin pool %s.", device);
return 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 against systems libdm 'older' library
* in runtime we are linked agains 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 maintenance
* Support parallel run of 'task' and it's waitpid maintainence
* 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 evmask __attribute__((unused)),
enum dm_event_mask event __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 (evmask & DM_EVENT_DEVICE_ERROR) {
if (event & 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 surpassed so policy
* Only 100% is exception as it cannot be surpased 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/* Unsupported command format */
} else/* Unuspported command format */
goto inval;
state->pid = -1;

View File

@@ -52,7 +52,7 @@ include $(top_builddir)/make.tmpl
.PHONY: install_lvmdbusd
install_lvmdbusd: $(LVMDBUSD)
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_DIR) $(sbindir)
$(Q) $(INSTALL_SCRIPT) $(LVMDBUSD) $(sbindir)
$(Q) $(INSTALL_DIR) $(lvmdbusdir) $(lvmdbusdir)/__pycache__

View File

@@ -160,8 +160,6 @@ 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))
@@ -554,14 +552,6 @@ 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 dependent upon other LVs. Otherwise, when
# dependencies to those that are dependant 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,39 +795,6 @@ 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:
# The user could be using a symlink instead of the actual
# Ths 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 daemon fd 0, 1
Checks to see if we are running under systemd, by checking damon 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.daemon = True
thread.damon = 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 hashes with different keys
# so we use multiple hashs with different keys
self._lookup_add(dbus_object, path, dbus_object.lvm_id,
dbus_object.Uuid)
@@ -272,7 +272,7 @@ class ObjectManager(AutomatedProperties):
For a given lvm asset return the dbus object path registered for it.
This method first looks up by uuid and then by lvm_id. You
can search by just one by setting uuid == lvm_id (uuid or lvm_id).
If the object is not found and path_create is not None, the
If the object is not found and path_create is a not None, the
path_create function will be called to create a new object path and
register it with the object manager for the specified uuid & lvm_id.
Note: If path create is not None, uuid and lvm_id cannot be equal
@@ -295,7 +295,7 @@ class ObjectManager(AutomatedProperties):
if uuid == lvm_id:
path = self._id_lookup(lvm_id)
else:
# We have a uuid and an lvm_id we can do sanity checks to ensure
# We have an uuid and a lvm_id we can do sanity checks to ensure
# that they are consistent
# If a PV is missing its device path is '[unknown]' or some

View File

@@ -778,7 +778,6 @@ class LockFile(object):
def __enter__(self):
try:
os.makedirs(os.path.dirname(self.lock_file), exist_ok=True)
self.fd = os.open(self.lock_file, os.O_CREAT | os.O_RDWR, stat.S_IRUSR | stat.S_IWUSR)
# Get and set the close on exec and lock the file

View File

@@ -50,25 +50,25 @@ INCLUDES += -I$(top_srcdir)/libdaemon/server
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
LIBS += $(DAEMON_LIBS) $(PTHREAD_LIBS)
ifeq ("@SD_NOTIFY_SUPPORT@", "yes")
CFLAGS += $(LIBSYSTEMD_CFLAGS)
ifneq (,$(firstword $(LIBSYSTEMD_LIBS)))
CFLAGS += $(LIBSYSTEMD_CFLAGS) -DUSE_SD_NOTIFY
LIBS += $(LIBSYSTEMD_LIBS)
endif
lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/server/libdaemonserver.a $(INTERNAL_LIBS)
$(SHOW) " [CC] $@"
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LOCK_LIBS) $(LIBS)
lvmlockctl: lvmlockctl.o $(INTERNAL_LIBS)
$(SHOW) " [CC] $@"
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
install_lvmlockd: lvmlockd
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_lvmlockctl: lvmlockctl
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_lvm2: install_lvmlockd install_lvmlockctl

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 (4 * 1024 * 1024)
#define DUMP_BUF_SIZE (1024 * 1024)
static char dump_buf[DUMP_BUF_SIZE+1];
static int dump_len;
static struct sockaddr_un dump_addr;
@@ -67,160 +67,6 @@ do { \
syslog(LOG_WARNING, fmt, ##args); \
} while (0)
/*
* Like sscanf, but requires buffer size to be specified
* for storing scanned strings, e.g.
*
* szscanf("%s", sizeof(buf), buf);
*
* Up to size-1 input bytes will be copied into buf.
* A null byte will be written to buf following the
* last copied byte. When nothing is copied to buf,
* no terminating null byte is written.
*
* If an input string matching %s is too long for the
* specified buffer size, the characters that would have
* been copied are ignored.
*
* Only recognizes: %d, %u, %s.
*/
static int szscanf(const char *input, const char *format, ...)
{
va_list args;
const char *fm;
const char *in;
int matched = 0;
int n;
va_start(args, format);
fm = format;
in = input;
while (*fm != '\0') {
/*
* format is a string containing:
* 1. %d matching int from input
* %u matching unsigned int from input
* %s matching non-whitespace characters from input
* 2. whitespace chars matching zero or more whitespace
* characters from input
* 3. non-whitespace chars matching the same input chars
*/
if (*fm == '%') {
/*
* case 1: %u, %d, or %s
*/
/* advance past '%' character, to look for 'u', 'd' or 's' */
fm++;
if (*fm == 'd') {
/*
* read an int (%d)
*/
int *dest = va_arg(args, int *);
if (sscanf(in, "%d%n", dest, &n) == 1) {
in += n;
matched++;
} else {
/* matching failure: no input int */
break;
}
} else if (*fm == 'u') {
/*
* read an unsigned int (%u)
*/
unsigned int *dest = va_arg(args, unsigned int *);
if (sscanf(in, "%u%n", dest, &n) == 1) {
in += n;
matched++;
} else {
/* matching failure: no input unsigned int */
break;
}
} else if (*fm == 's') {
/*
* read a string (%s) into dest buffer with dest_size
* copy up to dest_size-1 characters into dest buffer
* write null byte into dest buffer following the last
* character copied. When dest_size-1 bytes are copied,
* the null byte is written into the final byte of the
* dest buffer. input bytes that would have been copied
* but did not fit in the dest buffer are skipped.
*/
size_t dest_size = va_arg(args, size_t);
char *dest = va_arg(args, char *);
char *out = dest;
/* don't copy leading input whitespace to dest */
while (isspace((unsigned char)*in))
in++;
/* copy non-whitespace characters from input to dest */
n = 0;
while (*in != '\0' && !isspace((unsigned char)*in) && (n < (int)dest_size-1)) {
*out = *in;
out++;
in++;
n++;
}
if (n) {
dest[n] = '\0';
matched++;
} else {
/* matching failure: no input string chars */
break;
}
/* ignore input bytes that would have been copied but didn't fit */
while (*in != '\0' && !isspace((unsigned char)*in))
in++;
} else {
/* unsupported format specifier */
matched = -1;
break;
}
/* advance past 'd', 'u', or 's' character */
fm++;
} else if (isspace((unsigned char)*fm)) {
/*
* case 2: format whitespace skips zero or more input
* whitespace characters
*/
while (isspace((unsigned char)*in))
in++;
/* advance past whitespace character */
fm++;
} else if (*fm == *in) {
/*
* case 3: literal character match between format and input
*/
fm++;
in++;
} else {
/*
* matching failure: format and input don't match
*/
break;
}
}
va_end(args);
return matched;
}
#define MAX_LINE 512
/* copied from lvmlockd-internal.h */
@@ -251,11 +97,8 @@ static void save_client_info(char *line)
uint32_t client_id = 0;
char name[MAX_NAME+1] = { 0 };
/* info=client pid=%u fd=%d pi=%d id=%u name=%s */
if (szscanf(line, "info=client pid=%u fd=%d pi=%d id=%u name=%s",
&pid, &fd, &pi, &client_id, sizeof(name), name) < 0)
return;
(void) sscanf(line, "info=client pid=%u fd=%d pi=%d id=%u name=%s",
&pid, &fd, &pi, &client_id, name);
clients[num_clients].client_id = client_id;
clients[num_clients].pid = pid;
@@ -283,26 +126,20 @@ 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_args[MAX_ARGS+1] = { 0 };
char lm_type[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 };
/* info=ls ls_name=%s vg_name=%s vg_uuid=%s vg_args=%s lm_type=%s */
if (szscanf(line, "info=ls ls_name=%s vg_name=%s vg_uuid=%s vg_args=%s lm_type=%s",
sizeof(ls_name), ls_name,
sizeof(vg_name), vg_name,
sizeof(vg_uuid), vg_uuid,
sizeof(vg_args), vg_args,
sizeof(lm_type), lm_type) < 0)
return;
(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);
if (!first_ls)
printf("\n");
first_ls = 0;
printf("VG %s lock_type=%s %s\n", vg_name, lm_type, vg_uuid);
printf("VG %s lock_type=%s %s\n", vg_name, lock_type, vg_uuid);
printf("LS %s %s\n", lm_type, ls_name);
printf("LS %s %s\n", lock_type, ls_name);
}
static void format_info_ls_action(char *line)
@@ -314,14 +151,8 @@ static void format_info_ls_action(char *line)
uint32_t pid = 0;
char cl_name[MAX_NAME+1] = { 0 };
/* info=ls_action client_id=%u flags=%s version=%u op=%s rt=%s mode=%s lm_type=%s result=%d lm_rv=%d */
if (szscanf(line, "info=ls_action client_id=%u flags=%s version=%s op=%s",
&client_id,
sizeof(flags), flags,
sizeof(version), version,
sizeof(op), op) < 0)
return;
(void) sscanf(line, "info=ls_action client_id=%u %s %s op=%s",
&client_id, flags, version, op);
find_client_info(client_id, &pid, cl_name);
@@ -333,18 +164,11 @@ static void format_info_r(char *line, char *r_name_out, char *r_type_out)
char r_name[MAX_NAME+1] = { 0 };
char r_type[4] = { 0 };
char mode[4] = { 0 };
int sh_count = 0;
unsigned int ver = 0;
char sh_count[MAX_NAME+1] = { 0 };
uint32_t ver = 0;
/* info=r name=%s type=%s mode=%s sh_count=%d version=%s */
if (szscanf(line, "info=r name=%s type=%s mode=%s sh_count=%d version=%u",
sizeof(r_name), r_name,
sizeof(r_type), r_type,
sizeof(mode), mode,
&sh_count,
&ver) < 0)
return;
(void) sscanf(line, "info=r name=%s type=%s mode=%s %s version=%u",
r_name, r_type, mode, sh_count, &ver);
strcpy(r_name_out, r_name);
strcpy(r_type_out, r_type);
@@ -369,8 +193,8 @@ static void format_info_r(char *line, char *r_name_out, char *r_type_out)
static void format_info_lk(char *line, char *r_name, char *r_type)
{
char mode[4] = { 0 };
char flags[MAX_NAME+1] = { 0 };
uint32_t ver = 0;
char flags[MAX_NAME+1] = { 0 };
uint32_t client_id = 0;
uint32_t pid = 0;
char cl_name[MAX_NAME+1] = { 0 };
@@ -381,14 +205,8 @@ static void format_info_lk(char *line, char *r_name, char *r_type)
return;
}
/* info=lk mode=%s version=%s flags=%s client_id=%u */
if (szscanf(line, "info=lk mode=%s version=%u flags=%s client_id=%u",
sizeof(mode), mode,
&ver,
sizeof(flags), flags,
&client_id) < 0)
return;
(void) sscanf(line, "info=lk mode=%s version=%u %s client_id=%u",
mode, &ver, flags, &client_id);
find_client_info(client_id, &pid, cl_name);
@@ -411,9 +229,9 @@ static void format_info_r_action(char *line, char *r_name, char *r_type)
char op[MAX_NAME+1] = { 0 };
char rt[4] = { 0 };
char mode[4] = { 0 };
char lm_type[MAX_NAME+1] = { 0 };
int result = 0;
int lm_rv = 0;
char lm[MAX_NAME+1] = { 0 };
char result[MAX_NAME+1] = { 0 };
char lm_rv[MAX_NAME+1] = { 0 };
uint32_t pid = 0;
char cl_name[MAX_NAME+1] = { 0 };
@@ -423,19 +241,8 @@ static void format_info_r_action(char *line, char *r_name, char *r_type)
return;
}
/* info=r_action client_id=%u flags=%s version=%s op=%s rt=%s mode=%s lm_type=%s result=%d lm_rv=%d */
if (szscanf(line, "info=r_action client_id=%u flags=%s version=%s op=%s rt=%s mode=%s lm_type=%s result=%d lm_rv=%d",
&client_id,
sizeof(flags), flags,
sizeof(version), version,
sizeof(op), op,
sizeof(rt), rt,
sizeof(mode), mode,
sizeof(lm_type), lm_type,
&result,
&lm_rv) < 0)
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);
find_client_info(client_id, &pid, cl_name);
@@ -457,19 +264,19 @@ static void format_info_r_action(char *line, char *r_name, char *r_type)
static void format_info_line(char *line, char *r_name, char *r_type)
{
if (!strncmp(line, "info=structs ", sizeof("info=structs ") - 1)) {
if (!strncmp(line, "info=structs ", strlen("info=structs "))) {
/* only print this in the raw info dump */
} else if (!strncmp(line, "info=client ", sizeof("info=client ") - 1)) {
} else if (!strncmp(line, "info=client ", strlen("info=client "))) {
save_client_info(line);
} else if (!strncmp(line, "info=ls ", sizeof("info=ls ") - 1)) {
} else if (!strncmp(line, "info=ls ", strlen("info=ls "))) {
format_info_ls(line);
} else if (!strncmp(line, "info=ls_action ", sizeof("info=ls_action ") - 1)) {
} else if (!strncmp(line, "info=ls_action ", strlen("info=ls_action "))) {
format_info_ls_action(line);
} else if (!strncmp(line, "info=r ", sizeof("info=r ") - 1)) {
} else if (!strncmp(line, "info=r ", strlen("info=r "))) {
/*
* r_name/r_type are reset when a new resource is found.
* They are reused for the lock and action lines that
@@ -479,11 +286,11 @@ static void format_info_line(char *line, char *r_name, char *r_type)
memset(r_type, 0, MAX_NAME+1);
format_info_r(line, r_name, r_type);
} else if (!strncmp(line, "info=lk ", sizeof("info=lk ") - 1)) {
} else if (!strncmp(line, "info=lk ", strlen("info=lk "))) {
/* will use info from previous r */
format_info_lk(line, r_name, r_type);
} else if (!strncmp(line, "info=r_action ", sizeof("info=r_action ") - 1)) {
} else if (!strncmp(line, "info=r_action ", strlen("info=r_action "))) {
/* will use info from previous r */
format_info_r_action(line, r_name, r_type);
} else {
@@ -1133,7 +940,7 @@ static int read_options(int argc, char *argv[])
int option_index = 0;
int c;
static const struct option _long_options[] = {
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
{"quit", no_argument, 0, 'q' },
{"info", no_argument, 0, 'i' },
@@ -1155,7 +962,7 @@ static int read_options(int argc, char *argv[])
}
while (1) {
c = getopt_long(argc, argv, "hqidE:D:w:k:r:Se", _long_options, &option_index);
c = getopt_long(argc, argv, "hqidE:D:w:k:r:Se", long_options, &option_index);
if (c == -1)
break;

View File

@@ -16,12 +16,9 @@
#define LVMLOCKD_SOCKET DEFAULT_RUN_DIR "/lvmlockd.socket"
#define LVMLOCKD_ADOPT_FILE DEFAULT_RUN_DIR "/lvmlockd.adopt"
#define LVMLOCKD_USE_SANLOCK_LVB 0
/* Wrappers to open/close connection */
static inline __attribute__((always_inline))
daemon_handle lvmlockd_open(const char *sock)
static inline daemon_handle lvmlockd_open(const char *sock)
{
daemon_info lvmlockd_info = {
.path = "lvmlockd",
@@ -54,10 +51,5 @@ static inline void lvmlockd_close(daemon_handle h)
#define EREMOVED 219
#define EDEVOPEN 220 /* sanlock failed to open lvmlock LV */
#define ELMERR 221
#define EORPHAN 222
#define EADOPT_NONE 223
#define EADOPT_RETRY 224
#define EIOTIMEOUT 225
#define ELOCKREPAIR 226
#endif /* _LVM_LVMLOCKD_CLIENT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@
#include "tools/tool.h"
#include "libdaemon/server/daemon-server.h"
#include "daemon-server.h"
#include "lib/mm/xlate.h"
#include "lvmlockd-internal.h"
@@ -31,6 +31,7 @@
#include <errno.h>
#include <endian.h>
#include <fcntl.h>
#include <byteswap.h>
#include <syslog.h>
#include <dirent.h>
@@ -95,6 +96,7 @@ static int check_args_version(char *vg_args)
static int read_cluster_name(char *clustername)
{
static const char close_error_msg[] = "read_cluster_name: close_error %d";
char *n;
int fd;
int rv;
@@ -113,19 +115,18 @@ static int read_cluster_name(char *clustername)
rv = read(fd, clustername, MAX_ARGS);
if (rv < 0) {
log_error("read_cluster_name: cluster name read error %d, check dlm_controld", fd);
goto out;
if (close(fd))
log_error(close_error_msg, fd);
return rv;
}
clustername[rv] = 0;
n = strstr(clustername, "\n");
if (n)
*n = '\0';
rv = 0;
out:
if (close(fd))
log_error("read_cluster_name: close_error %d", fd);
return rv;
log_error(close_error_msg, fd);
return 0;
}
#define MAX_VERSION 16
@@ -168,10 +169,8 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls)
struct lm_dlm *lmd;
int rv;
if (daemon_test) {
log_debug("lm_prepare_lockspace_dlm test");
if (daemon_test)
goto skip_args;
}
memset(sys_clustername, 0, sizeof(sys_clustername));
memset(arg_clustername, 0, sizeof(arg_clustername));
@@ -306,27 +305,20 @@ fail:
return rv;
}
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt_only, int adopt_ok)
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
if (daemon_test)
return 0;
if (adopt_only || adopt_ok) {
if (adopt)
lmd->dh = dlm_open_lockspace(ls->name);
if (!lmd->dh && adopt_ok)
lmd->dh = dlm_new_lockspace(ls->name, 0600, DLM_LSFL_NEWEXCL);
if (!lmd->dh)
log_error("add_lockspace_dlm adopt_only %d adopt_ok %d %s error",
adopt_only, adopt_ok, ls->name);
} else {
else
lmd->dh = dlm_new_lockspace(ls->name, 0600, DLM_LSFL_NEWEXCL);
if (!lmd->dh)
log_error("add_lockspace_dlm %s error", ls->name);
}
if (!lmd->dh) {
log_error("add_lockspace_dlm %s adopt %d error", ls->name, adopt);
free(lmd);
ls->lm_data = NULL;
return -1;
@@ -362,7 +354,7 @@ int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
return 0;
}
int lm_add_resource_dlm(struct lockspace *ls, struct resource *r, int with_lock_nl)
static 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;
@@ -394,7 +386,7 @@ int lm_add_resource_dlm(struct lockspace *ls, struct resource *r, int with_lock_
r->name, strlen(r->name),
0, NULL, NULL, NULL);
if (rv < 0) {
log_error("%s:%s add_resource_dlm lock error %d", ls->name, r->name, rv);
log_error("S %s R %s add_resource_dlm lock error %d", ls->name, r->name, rv);
return rv;
}
out:
@@ -418,7 +410,7 @@ int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r)
rv = dlm_ls_unlock_wait(lmd->dh, lksb->sb_lkid, 0, lksb);
if (rv < 0) {
log_error("%s:%s rem_resource_dlm unlock error %d", ls->name, r->name, rv);
log_error("S %s R %s rem_resource_dlm unlock error %d", ls->name, r->name, rv);
}
out:
free(rdd->vb);
@@ -473,7 +465,7 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
goto fail;
}
log_debug("%s:%s adopt_dlm", ls->name, r->name);
log_debug("S %s R %s adopt_dlm", ls->name, r->name);
if (daemon_test)
return 0;
@@ -482,29 +474,29 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
* dlm returns 0 for success, -EAGAIN if an orphan is
* found with another mode, and -ENOENT if no orphan.
*
* cast/bast/param are (void (*)(void*))1 because the kernel
* cast/bast/param are (void *)1 because the kernel
* returns errors if some are null.
*/
rv = dlm_ls_lockx(lmd->dh, mode, lksb, flags,
r->name, strlen(r->name), 0,
(void (*)(void*))1, (void (*)(void*))1, (void (*)(void*))1,
(void *)1, (void *)1, (void *)1,
NULL, NULL);
if (rv == -1 && (errno == EAGAIN)) {
log_debug("%s:%s adopt_dlm adopt mode %d try other mode",
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
ls->name, r->name, ld_mode);
rv = -EADOPT_RETRY;
rv = -EUCLEAN;
goto fail;
}
if (rv == -1 && (errno == ENOENT)) {
log_debug("%s:%s adopt_dlm adopt mode %d no lock",
log_debug("S %s R %s adopt_dlm adopt mode %d no lock",
ls->name, r->name, ld_mode);
rv = -EADOPT_NONE;
rv = -ENOENT;
goto fail;
}
if (rv < 0) {
log_debug("%s:%s adopt_dlm mode %d flags %x error %d errno %d",
log_debug("S %s R %s adopt_dlm mode %d flags %x error %d errno %d",
ls->name, r->name, mode, flags, rv, errno);
goto fail;
}
@@ -534,7 +526,7 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
*/
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, int adopt_only, int adopt_ok)
struct val_blk *vb_out, int adopt)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
@@ -544,13 +536,7 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
int mode;
int rv;
if (adopt_ok) {
log_debug("%s:%s lock_dlm adopt_ok not supported", ls->name, r->name);
return -1;
}
if (adopt_only) {
log_debug("%s:%s lock_dlm adopt_only", ls->name, r->name);
if (adopt) {
/* When adopting, we don't follow the normal method
of acquiring a NL lock then converting it to the
desired mode. */
@@ -579,13 +565,13 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
return -EINVAL;
}
log_debug("%s:%s lock_dlm", ls->name, r->name);
log_debug("S %s R %s lock_dlm", ls->name, r->name);
if (daemon_test) {
if (rdd->vb) {
vb_out->version = le16toh(rdd->vb->version);
vb_out->flags = le16toh(rdd->vb->flags);
vb_out->r_version = le32toh(rdd->vb->r_version);
vb_out->version = le16_to_cpu(rdd->vb->version);
vb_out->flags = le16_to_cpu(rdd->vb->flags);
vb_out->r_version = le32_to_cpu(rdd->vb->r_version);
}
return 0;
}
@@ -599,7 +585,7 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
if (rv == -1) {
log_debug("%s:%s lock_dlm acquire mode PR for %d rv %d",
log_debug("S %s R %s lock_dlm acquire mode PR for %d rv %d",
ls->name, r->name, mode, rv);
goto lockrv;
}
@@ -612,17 +598,17 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
0, NULL, NULL, NULL);
lockrv:
if (rv == -1 && errno == EAGAIN) {
log_debug("%s:%s lock_dlm acquire mode %d rv EAGAIN", ls->name, r->name, mode);
log_debug("S %s R %s lock_dlm acquire mode %d rv EAGAIN", ls->name, r->name, mode);
return -EAGAIN;
}
if (rv < 0) {
log_error("%s:%s lock_dlm acquire error %d errno %d", ls->name, r->name, rv, errno);
log_error("S %s R %s lock_dlm acquire error %d errno %d", ls->name, r->name, rv, errno);
return -ELMERR;
}
if (rdd->vb) {
if (lksb->sb_flags & DLM_SBF_VALNOTVALID) {
log_debug("%s:%s lock_dlm VALNOTVALID", ls->name, r->name);
log_debug("S %s R %s lock_dlm VALNOTVALID", ls->name, r->name);
memset(rdd->vb, 0, sizeof(struct val_blk));
memset(vb_out, 0, sizeof(struct val_blk));
goto out;
@@ -637,9 +623,9 @@ lockrv:
memcpy(&vb, lksb->sb_lvbptr, sizeof(struct val_blk));
memcpy(rdd->vb, &vb, sizeof(vb));
vb_out->version = le16toh(vb.version);
vb_out->flags = le16toh(vb.flags);
vb_out->r_version = le32toh(vb.r_version);
vb_out->version = le16_to_cpu(vb.version);
vb_out->flags = le16_to_cpu(vb.flags);
vb_out->r_version = le32_to_cpu(vb.r_version);
}
out:
return 0;
@@ -655,7 +641,7 @@ int lm_convert_dlm(struct lockspace *ls, struct resource *r,
uint32_t flags = 0;
int rv;
log_debug("%s:%s convert_dlm", ls->name, r->name);
log_debug("S %s R %s convert_dlm", ls->name, r->name);
flags |= LKF_CONVERT;
flags |= LKF_NOQUEUE;
@@ -664,12 +650,12 @@ int lm_convert_dlm(struct lockspace *ls, struct resource *r,
if (rdd->vb && r_version && (r->mode == LD_LK_EX)) {
if (!rdd->vb->version) {
/* first time vb has been written */
rdd->vb->version = htole16(VAL_BLK_VERSION);
rdd->vb->version = cpu_to_le16(VAL_BLK_VERSION);
}
rdd->vb->r_version = htole32(r_version);
rdd->vb->r_version = cpu_to_le32(r_version);
memcpy(lksb->sb_lvbptr, rdd->vb, sizeof(struct val_blk));
log_debug("%s:%s convert_dlm set r_version %u",
log_debug("S %s R %s convert_dlm set r_version %u",
ls->name, r->name, r_version);
flags |= LKF_VALBLK;
@@ -687,11 +673,11 @@ int lm_convert_dlm(struct lockspace *ls, struct resource *r,
0, NULL, NULL, NULL);
if (rv == -1 && errno == EAGAIN) {
/* FIXME: When does this happen? Should something different be done? */
log_error("%s:%s convert_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
log_error("S %s R %s convert_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
return -EAGAIN;
}
if (rv < 0) {
log_error("%s:%s convert_dlm error %d", ls->name, r->name, rv);
log_error("S %s R %s convert_dlm error %d", ls->name, r->name, rv);
rv = -ELMERR;
}
return rv;
@@ -723,17 +709,17 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
memcpy(&vb_next, rdd->vb, sizeof(struct val_blk));
if (!vb_prev.version) {
vb_next.version = htole16(VAL_BLK_VERSION);
vb_next.version = cpu_to_le16(VAL_BLK_VERSION);
new_vb = 1;
}
if ((lmu_flags & LMUF_FREE_VG) && (r->type == LD_RT_VG)) {
vb_next.flags = htole16(VBF_REMOVED);
vb_next.flags = cpu_to_le16(VBF_REMOVED);
new_vb = 1;
}
if (r_version) {
vb_next.r_version = htole32(r_version);
vb_next.r_version = cpu_to_le32(r_version);
new_vb = 1;
}
@@ -741,21 +727,21 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
memcpy(rdd->vb, &vb_next, sizeof(struct val_blk));
memcpy(lksb->sb_lvbptr, &vb_next, sizeof(struct val_blk));
log_debug("%s:%s unlock_dlm vb old %x %x %u new %x %x %u",
log_debug("S %s R %s unlock_dlm vb old %x %x %u new %x %x %u",
ls->name, r->name,
le16toh(vb_prev.version),
le16toh(vb_prev.flags),
le32toh(vb_prev.r_version),
le16toh(vb_next.version),
le16toh(vb_next.flags),
le32toh(vb_next.r_version));
le16_to_cpu(vb_prev.version),
le16_to_cpu(vb_prev.flags),
le32_to_cpu(vb_prev.r_version),
le16_to_cpu(vb_next.version),
le16_to_cpu(vb_next.flags),
le32_to_cpu(vb_next.r_version));
} else {
log_debug("%s:%s unlock_dlm vb unchanged", ls->name, r->name);
log_debug("S %s R %s unlock_dlm vb unchanged", ls->name, r->name);
}
flags |= LKF_VALBLK;
} else {
log_debug("%s:%s unlock_dlm", ls->name, r->name);
log_debug("S %s R %s unlock_dlm", ls->name, r->name);
}
if (daemon_test)
@@ -765,7 +751,7 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
if (rv < 0) {
log_error("%s:%s unlock_dlm error %d", ls->name, r->name, rv);
log_error("S %s R %s unlock_dlm error %d", ls->name, r->name, rv);
rv = -ELMERR;
}
@@ -798,16 +784,9 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
* the stale lockspaces on the others eventually.)
*/
/*
* On error, returns < 0
*
* On success:
* If other hosts are found, returns the number.
* If no other hosts are found (only ourself), returns 0.
*/
int lm_hosts_dlm(struct lockspace *ls, int notify)
{
static const char closedir_err_msg[] = "lm_hosts_dlm: closedir failed";
char ls_nodes_path[PATH_MAX];
struct dirent *de;
DIR *ls_dir;
@@ -830,7 +809,7 @@ int lm_hosts_dlm(struct lockspace *ls, int notify)
}
if (closedir(ls_dir))
log_error("lm_hosts_dlm: closedir failed");
log_error(closedir_err_msg);
if (!count) {
log_error("lm_hosts_dlm found no nodes in %s", ls_nodes_path);
@@ -847,10 +826,10 @@ int lm_hosts_dlm(struct lockspace *ls, int notify)
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
{
static const char closedir_err_msg[] = "lm_get_lockspace_dlm: closedir failed";
struct lockspace *ls;
struct dirent *de;
DIR *ls_dir;
int ret = 0;
if (!(ls_dir = opendir(DLM_LOCKSPACES_PATH)))
return -ECONNREFUSED;
@@ -863,8 +842,9 @@ int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
continue;
if (!(ls = alloc_lockspace())) {
ret = -ENOMEM;
goto out;
if (closedir(ls_dir))
log_error(closedir_err_msg);
return -ENOMEM;
}
ls->lm_type = LD_LM_DLM;
@@ -872,11 +852,10 @@ int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
dm_strncpy(ls->vg_name, ls->name + strlen(LVM_LS_PREFIX), sizeof(ls->vg_name));
list_add_tail(&ls->list, ls_rejoin);
}
out:
if (closedir(ls_dir))
log_error("lm_get_lockspace_dlm: closedir failed");
return ret;
if (closedir(ls_dir))
log_error(closedir_err_msg);
return 0;
}
int lm_is_running_dlm(void)

View File

@@ -13,7 +13,7 @@
#include "tools/tool.h"
#include "libdaemon/server/daemon-server.h"
#include "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_directory(const char *block_path)
static int lm_idm_scsi_find_block_dirctory(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_directory(blk_path);
ret = lm_idm_scsi_find_block_dirctory(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 precision and the time
* synchronization with microsecond prcision and the time
* is going backward. For this case, simply increment the
* existing timestamp and write out to drive.
*/
@@ -391,7 +391,7 @@ int lm_prepare_lockspace_idm(struct lockspace *ls)
return 0;
}
int lm_add_lockspace_idm(struct lockspace *ls, int adopt_only, int adopt_ok)
int lm_add_lockspace_idm(struct lockspace *ls, int adopt)
{
char killpath[IDM_FAILURE_PATH_LEN];
char killargs[IDM_FAILURE_ARGS_LEN];
@@ -490,7 +490,7 @@ out:
return rv;
}
int lm_add_resource_idm(struct lockspace *ls, struct resource *r)
static int lm_add_resource_idm(struct lockspace *ls, struct resource *r)
{
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
@@ -530,7 +530,7 @@ static int to_idm_mode(int ld_mode)
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)
int adopt)
{
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
@@ -556,9 +556,9 @@ int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
if (daemon_test) {
if (rdi->vb) {
vb_out->version = le16toh(rdi->vb->version);
vb_out->flags = le16toh(rdi->vb->flags);
vb_out->r_version = le32toh(rdi->vb->r_version);
vb_out->version = le16_to_cpu(rdi->vb->version);
vb_out->flags = le16_to_cpu(rdi->vb->flags);
vb_out->r_version = le32_to_cpu(rdi->vb->r_version);
}
return 0;
}

View File

@@ -13,9 +13,6 @@
#include "base/memory/container_of.h"
#include <stdint.h>
#include <pthread.h>
#define MAX_NAME 64
#define MAX_ARGS 64
@@ -62,7 +59,6 @@ enum {
LD_OP_BUSY,
LD_OP_QUERY_LOCK,
LD_OP_REFRESH_LV,
LD_OP_VG_STATUS,
};
/* resource types */
@@ -111,14 +107,11 @@ struct client {
#define LD_AF_SEARCH_LS 0x00000200
#define LD_AF_WAIT_STARTING 0x00001000
#define LD_AF_DUP_GL_LS 0x00002000
#define LD_AF_ADOPT 0x00010000 /* adopt ok but not required */
#define LD_AF_ADOPT 0x00010000
#define LD_AF_WARN_GL_REMOVED 0x00020000
#define LD_AF_LV_LOCK 0x00040000
#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
#define LD_AF_REPAIR 0x00800000
/*
* Number of times to repeat a lock request after
@@ -132,24 +125,12 @@ struct pvs {
int num;
};
#define OWNER_NAME_SIZE 64
#define OWNER_STATE_SIZE 32
struct owner {
uint32_t host_id;
uint32_t generation;
uint32_t timestamp;
char state[OWNER_STATE_SIZE];
char name[OWNER_NAME_SIZE];
};
struct action {
struct list_head list;
uint32_t client_id;
uint32_t flags; /* LD_AF_ */
uint32_t version;
uint32_t host_id;
uint64_t lv_size_bytes;
uint64_t host_id;
int8_t op; /* operation type LD_OP_ */
int8_t rt; /* resource type LD_RT_ */
int8_t mode; /* lock mode LD_LK_ */
@@ -158,7 +139,6 @@ 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];
@@ -166,8 +146,7 @@ struct action {
char lv_uuid[MAX_NAME+1];
char vg_args[MAX_ARGS+1];
char lv_args[MAX_ARGS+1];
char prev_lv_args[MAX_ARGS+1];
struct owner owner;
char vg_sysid[MAX_NAME+1];
struct pvs pvs; /* PV list for idm */
};
@@ -180,7 +159,6 @@ 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;
@@ -207,11 +185,13 @@ 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;
uint32_t host_id;
uint64_t generation;
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 */
@@ -231,7 +211,6 @@ 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 */
@@ -298,15 +277,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 */
@@ -414,12 +393,11 @@ static inline const char *mode_str(int x)
int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
int lm_prepare_lockspace_dlm(struct lockspace *ls);
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt_only, int adopt_ok);
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt);
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);
struct val_blk *vb_out, int adopt);
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version);
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
@@ -441,102 +419,69 @@ 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)
static inline int lm_add_lockspace_dlm(struct lockspace *ls, int adopt)
{
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)
struct val_blk *vb_out, int adopt)
{
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;
}
@@ -559,17 +504,15 @@ 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 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_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_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, uint64_t *prev_generation, int repair);
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok, int nodelay);
int lm_prepare_lockspace_sanlock(struct lockspace *ls);
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt);
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, struct owner *owner,
int adopt_only, int adopt_ok, int repair);
struct val_blk *vb_out, int *retry, int adopt);
int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version);
int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
@@ -582,8 +525,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 lv_size_bytes);
int lm_vg_status_sanlock(struct lockspace *ls, struct action *act);
int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size);
static inline int lm_support_sanlock(void)
{
@@ -592,12 +534,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, int opt_align_mb)
static inline int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
{
return -1;
}
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)
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)
{
return -1;
}
@@ -612,12 +554,12 @@ static inline int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t fl
return -1;
}
static inline int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation, int repair)
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, int nodelay)
static inline int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt)
{
return -1;
}
@@ -627,14 +569,8 @@ 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, struct owner *owner,
int adopt_only, int adopt_ok, int repair)
struct val_blk *vb_out, int *retry, int adopt)
{
return -1;
}
@@ -691,12 +627,7 @@ static inline int lm_is_running_sanlock(void)
return 0;
}
static inline int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes)
{
return -1;
}
static inline int lm_vg_status_sanlock(struct lockspace *ls, struct action *act)
static inline int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size)
{
return -1;
}
@@ -713,12 +644,11 @@ static inline int lm_support_sanlock(void)
int lm_data_size_idm(void);
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_add_lockspace_idm(struct lockspace *ls, int adopt);
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);
int adopt);
int lm_convert_idm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version);
int lm_unlock_idm(struct lockspace *ls, struct resource *r,
@@ -751,7 +681,7 @@ static inline int lm_prepare_lockspace_idm(struct lockspace *ls)
return -1;
}
static inline int lm_add_lockspace_idm(struct lockspace *ls, int adopt_only, int adopt_ok)
static inline int lm_add_lockspace_idm(struct lockspace *ls, int adopt)
{
return -1;
}
@@ -761,14 +691,9 @@ 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)
int adopt)
{
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -32,11 +32,11 @@ LDFLAGS += $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
LIBS += $(DAEMON_LIBS) $(PTHREAD_LIBS)
lvmpolld: $(OBJECTS) $(top_builddir)/libdaemon/server/libdaemonserver.a $(INTERNAL_LIBS)
$(SHOW) " [CC] $@"
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
install_lvmpolld: lvmpolld
$(SHOW) " [INSTALL] $<"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_lvm2: install_lvmpolld

View File

@@ -19,7 +19,7 @@
#define MIN_ARGV_SIZE 8
static const char *const _polling_ops[] = {
static const char *const polling_ops[] = {
[PVMOVE] = LVMPD_REQ_PVMOVE,
[CONVERT] = LVMPD_REQ_CONVERT,
[MERGE] = LVMPD_REQ_MERGE,
@@ -28,7 +28,7 @@ static const char *const _polling_ops[] = {
const char *polling_op(enum poll_type type)
{
return type < POLL_TYPE_MAX ? _polling_ops[type] : "<undefined>";
return type < POLL_TYPE_MAX ? polling_ops[type] : "<undefined>";
}
static int add_to_cmd_arr(const char ***cmdargv, const char *str, unsigned *ind)
@@ -81,7 +81,7 @@ const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary,
/* one of: "convert", "pvmove", "merge", "merge_thin" */
if (!add_to_cmd_arr(&cmd_argv, "--polloperation", &i) ||
!add_to_cmd_arr(&cmd_argv, _polling_ops[pdlv->type], &i))
!add_to_cmd_arr(&cmd_argv, polling_ops[pdlv->type], &i))
goto err;
/* vg/lv name */

View File

@@ -15,8 +15,8 @@
#include "lvmpolld-common.h"
#include "lvm-version.h"
#include "libdaemon/server/daemon-server.h"
#include "libdaemon/server/daemon-log.h"
#include "daemon-server.h"
#include "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 = infinite)\n\n", prog, prog);
" -t|--timeout Time to wait in seconds before shutdown on idle (missing or 0 = inifinite)\n\n", prog, prog);
}
static int _init(struct daemon_state *s)
@@ -390,11 +390,6 @@ 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---");
@@ -786,7 +781,7 @@ struct log_line_baton {
const char *prefix;
};
static daemon_handle _lvmpolld = { .error = 0 };
daemon_handle _lvmpolld = { .error = 0 };
static daemon_handle _lvmpolld_open(const char *socket)
{
@@ -872,14 +867,14 @@ enum action_index {
ACTION_MAX /* keep at the end */
};
static const action_fn_t actions[ACTION_MAX] = { [ACTION_DUMP] = action_dump };
static int _make_action(enum action_index idx, void *args)
{
static const action_fn_t _actions[ACTION_MAX] = { [ACTION_DUMP] = action_dump };
return idx < ACTION_MAX ? _actions[idx](args) : 0;
return idx < ACTION_MAX ? actions[idx](args) : 0;
}
static int _lvmpolld_client(const char *socket, enum action_index action)
static int _lvmpolld_client(const char *socket, unsigned action)
{
int r;
@@ -897,9 +892,10 @@ static int _lvmpolld_client(const char *socket, enum action_index action)
return r ? EXIT_SUCCESS : EXIT_FAILURE;
}
static const struct option _long_options[] = {
static int action_idx = ACTION_MAX;
static struct option long_options[] = {
/* Have actions always at the beginning of the array. */
{"dump", no_argument, 0, ACTION_DUMP }, /* or an option_index ? */
{"dump", no_argument, &action_idx, ACTION_DUMP }, /* or an option_index ? */
/* other options */
{"binary", required_argument, 0, 'B' },
@@ -918,7 +914,7 @@ int main(int argc, char *argv[])
int opt;
int option_index = 0;
int client = 0, server = 0;
enum action_index action = ACTION_MAX;
unsigned action = ACTION_MAX;
struct timespec timeout;
daemon_idle di = { .ptimeout = &timeout };
struct lvmpolld_state ls = { .log_config = "" };
@@ -934,16 +930,16 @@ int main(int argc, char *argv[])
.socket_path = getenv("LVM_LVMPOLLD_SOCKET") ?: LVMPOLLD_SOCKET,
};
while ((opt = getopt_long(argc, argv, "fhVl:p:s:B:t:", _long_options, &option_index)) != -1) {
while ((opt = getopt_long(argc, argv, "fhVl:p:s:B:t:", long_options, &option_index)) != -1) {
switch (opt) {
case 0 :
if (action != ACTION_MAX) {
if (action < ACTION_MAX) {
fprintf(stderr, "Can't perform more actions. Action already requested: %s\n",
_long_options[action].name);
long_options[action].name);
_usage(argv[0], stderr);
exit(EXIT_FAILURE);
}
action = ACTION_DUMP;
action = action_idx;
client = 1;
break;
case '?':

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) + sizeof(LVM_SYSTEM_DIR): 1;
size_t l = sysdir ? strlen(sysdir) + 16 : 1;
char *env = (char *) malloc(l * sizeof(char));
if (!env)
@@ -89,17 +89,6 @@ 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,
@@ -107,26 +96,30 @@ 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 = 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),
.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 */
.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.lvmpolld_id || !tmp.lvname || !tmp.lvm_system_dir_env || !tmp.sinterval)
if (!pdlv || !tmp.lvid || !tmp.lvname || !tmp.lvm_system_dir_env || !tmp.sinterval)
goto err;
tmp.lvid = _get_lvid(tmp.lvmpolld_id, sysdir),
*pdlv = tmp;
memcpy(pdlv, &tmp, sizeof(*pdlv));
if (pthread_mutex_init(&pdlv->lock, NULL))
goto err;
@@ -134,20 +127,29 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
return pdlv;
err:
_free_lvmpolld_lv(&tmp);
free(pdlv);
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);
return NULL;
}
void pdlv_destroy(struct lvmpolld_lv *pdlv)
{
_free_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);
pthread_mutex_destroy(&pdlv->lock);
free(pdlv);
free((void *)pdlv);
}
unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv)
@@ -271,12 +273,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_occurred=%d\n", pdlv->error) > 0)
if (dm_snprintf(tmp, sizeof(tmp), "\t\terror_occured=%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_command-section { */
/* lvm_commmand-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");
@@ -288,7 +290,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_command-section */
/* } lvm_commmand-section */
buffer_append(buff, "\t}\n");
/* } pdlv-section */

View File

@@ -15,10 +15,7 @@
#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;
@@ -71,7 +68,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 occurred in lvmpolld */
unsigned error:1; /* unrecoverable error occured in lvmpolld */
};
typedef void (*lvmpolld_parse_output_fn_t) (struct lvmpolld_lv *pdlv, const char *line);
@@ -96,7 +93,7 @@ struct lvmpolld_thread_data {
struct lvmpolld_lv *pdlv;
};
char *construct_id(const char *sysdir, const char *uuid);
char *construct_id(const char *sysdir, const char *lvid);
/* 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 signal */
#define LVMPD_REAS_SIGNAL "signal" /* lvm cmd terminating singal */
#define LVMPD_RET_DUP_FAILED 100
#define LVMPD_RET_EXC_FAILED 101

View File

@@ -25,7 +25,6 @@ DEVICE_MAPPER_SOURCE=\
device_mapper/libdm-targets.c \
device_mapper/libdm-timestamp.c \
device_mapper/mm/pool.c \
device_mapper/raid/raid_parser.c \
device_mapper/regex/matcher.c \
device_mapper/regex/parse_rx.c \
device_mapper/regex/ttree.c \
@@ -45,10 +44,10 @@ CLEAN_TARGETS += $(DEVICE_MAPPER_DEPENDS) $(DEVICE_MAPPER_OBJECTS) \
#$(DEVICE_MAPPER_OBJECTS): INCLUDES+=$(VDO_INCLUDES)
$(DEVICE_MAPPER_TARGET): $(DEVICE_MAPPER_OBJECTS)
$(SHOW) " [AR] $@"
@echo " [AR] $@"
$(Q) $(RM) $@
$(Q) $(AR) rsv $@ $(DEVICE_MAPPER_OBJECTS) > /dev/null
ifeq ("$(USE_TRACKING)","yes")
ifeq ("$(DEPENDS)","yes")
-include $(DEVICE_MAPPER_DEPENDS)
endif

View File

@@ -19,7 +19,6 @@
#include "base/data-struct/list.h"
#include "base/data-struct/hash.h"
#include "raid/target.h"
#include "vdo/target.h"
#include <inttypes.h>
@@ -176,11 +175,12 @@ struct dm_names {
struct dm_active_device {
struct dm_list list;
dev_t devno;
const char *name; /* device name */
int major;
int minor;
char *name; /* device name */
uint32_t event_nr; /* valid when DM_DEVICE_LIST_HAS_EVENT_NR is set */
const char *uuid; /* valid uuid when DM_DEVICE_LIST_HAS_UUID is set */
char *uuid; /* valid uuid when DM_DEVICE_LIST_HAS_UUID is set */
};
struct dm_versions {
@@ -192,7 +192,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 *info);
int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi);
/*
* This function returns dm device's UUID based on the value
@@ -230,6 +230,13 @@ struct dm_names *dm_task_get_names(struct dm_task *dmt);
#define DM_DEVICE_LIST_HAS_UUID 2
int dm_task_get_device_list(struct dm_task *dmt, struct dm_list **devs_list,
unsigned *devs_features);
/*
* -1: no idea about uuid (not provided by DM_DEVICE_LIST ioctl)
* 0: uuid not present
* 1: listed and dm_active_device will be set for not NULL pointer
*/
int dm_device_list_find_by_uuid(struct dm_list *devs_list, const char *uuid,
const struct dm_active_device **dev);
/* Release all associated memory with list of active DM devices */
void dm_device_list_destroy(struct dm_list **devs_list);
@@ -305,15 +312,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 retrieve target information returned from a STATUS call */
/* Use this to retrive 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 appropriate status structure
* Following dm_get_status_* functions will allocate approriate status structure
* from passed mempool together with the necessary character arrays.
* Destroying the mempool will release all associated allocation.
* Destroying the mempool will release all asociated allocation.
*/
/* Parse params from STATUS call for mirror target */
@@ -542,7 +549,7 @@ const char *dm_sysfs_dir(void);
/*
* Configure default UUID prefix string.
* Conventionally this is a short capitalized prefix indicating the subsystem
* Conventionally this is a short capitalised 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.
@@ -585,7 +592,7 @@ int dm_device_has_mounted_fs(uint32_t major, uint32_t minor);
/*
* Callback is invoked for individual mountinfo lines,
* Callback is invoked for individal mountinfo lines,
* minor, major and mount target are parsed and unmangled.
*/
typedef int (*dm_mountinfo_line_callback_fn) (char *line, unsigned maj, unsigned min,
@@ -699,7 +706,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.
* Returns -1 when node or any of its children has reduced size.
* Rerurns -1 when node or any of its children has reduced size.
*/
int dm_tree_node_size_changed(const struct dm_tree_node *dnode);
@@ -886,7 +893,7 @@ struct dm_tree_node_raid_params {
};
/*
* Version 2 of above node raid params struct to keep API compatibility.
* Version 2 of above node raid params struct to keeep API compatibility.
*
* Extended for more than 64 legs (max 253 in the MD kernel runtime!),
* delta_disks for disk add/remove reshaping,
@@ -909,7 +916,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 ourselves by choosing a lower value
* We limit ourselvs by choosing a lower value
* for DEFAULT_RAID_MAX_IMAGES.
*/
uint64_t rebuilds[RAID_BITMAP_SIZE];
@@ -946,7 +953,7 @@ struct dm_config_node;
*
* policy_settings {
* migration_threshold=2048
* sequential_threshold=100
* sequention_threashold=100
* ...
* }
*
@@ -1024,7 +1031,6 @@ 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;
@@ -1033,7 +1039,6 @@ 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,
@@ -1052,7 +1057,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 *vtp);
const struct dm_vdo_target_params *param);
/*
* FIXME Add individual cache policy pairs <key> = value, like:
@@ -1095,7 +1100,7 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
/* End of Replicator API */
/*
* FIXME: Defines below are based on kernel's dm-thin.c defines
* FIXME: Defines bellow 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)
*/
@@ -1161,7 +1166,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 below are based on kernel's dm-thin.c defines
* FIXME: Defines bellow 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))
@@ -1179,9 +1184,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 *uuid,
uint64_t offset);
const char *dev_name,
const char *dlid,
uint64_t offset);
/*
* Only for temporarily-missing raid devices where changes are tracked.
@@ -1591,9 +1596,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 **result, const char *format, ...)
int dm_asprintf(char **buf, const char *format, ...)
__attribute__ ((format(printf, 2, 3)));
int dm_vasprintf(char **result, const char *format, va_list aq)
int dm_vasprintf(char **buf, const char *format, va_list ap)
__attribute__ ((format(printf, 2, 0)));
/*
@@ -1942,7 +1947,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 *output_field_name_prefix);
const char *report_prefix);
int dm_report_set_selection(struct dm_report *rh, const char *selection);
@@ -2035,7 +2040,6 @@ 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);
@@ -2060,7 +2064,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 advanced output with config node reference. */
/* More advaced output with config node reference. */
typedef int (*dm_config_node_out_fn)(const struct dm_config_node *cn, const char *line, void *baton);
/*
@@ -2082,7 +2086,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 *rem_node);
int dm_config_remove_node(struct dm_config_node *parent, struct dm_config_node *remove);
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);
@@ -2114,7 +2118,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 *cn, int siblings);
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_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);
@@ -2123,7 +2127,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 contrast to "key=value" for better readability */
#define DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES 0x00000002 /* add spaces in "key = value" pairs in constrast to "key=value" for better readability */
/*
* Type-related config node formatting flags (higher 16 bits).
@@ -2169,7 +2173,7 @@ struct dm_pool *dm_config_memory(struct dm_config_tree *cft);
*/
#define DM_UDEV_DISABLE_DM_RULES_FLAG 0x0001
/*
* DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG is set in case we need to disable
* DM_UDEV_DISABLE_SUBSYTEM_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,7 +70,6 @@ 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
@@ -88,8 +87,10 @@ static int _version_checked = 0;
static int _version_ok = 1;
static unsigned _ioctl_buffer_double_factor = 0;
const int _dm_compat = 0;
/* *INDENT-OFF* */
static const struct cmd_data _cmd_data_v4[] = {
static struct cmd_data _cmd_data_v4[] = {
{"create", DM_DEV_CREATE, {4, 0, 0}},
{"reload", DM_TABLE_LOAD, {4, 0, 0}},
{"remove", DM_DEV_REMOVE, {4, 0, 0}},
@@ -199,7 +200,6 @@ static int _get_proc_number(const char *file, const char *name,
char *line = NULL;
size_t len;
uint32_t num;
unsigned blocksection = (strcmp(file, PROC_DEVICES) == 0) ? 0 : 1;
if (!(fl = fopen(file, "r"))) {
log_sys_error("fopen", file);
@@ -207,9 +207,7 @@ static int _get_proc_number(const char *file, const char *name,
}
while (getline(&line, &len, fl) != -1) {
if (!blocksection && (line[0] == 'B'))
blocksection = 1;
else if (sscanf(line, "%u %255s\n", &num, &nm[0]) == 2) {
if (sscanf(line, "%u %255s\n", &num, &nm[0]) == 2) {
if (!strcmp(name, nm)) {
if (number) {
*number = num;
@@ -249,16 +247,6 @@ static int _control_device_number(uint32_t *major, uint32_t *minor)
return 1;
}
static int _control_unlink(const char *control)
{
if (unlink(control) && (errno != ENOENT)) {
log_sys_error("unlink", control);
return -1;
}
return 0;
}
/*
* Returns 1 if it exists on returning; 0 if it doesn't; -1 if it's wrong.
*/
@@ -274,7 +262,10 @@ static int _control_exists(const char *control, uint32_t major, uint32_t minor)
if (!S_ISCHR(buf.st_mode)) {
log_verbose("%s: Wrong inode type", control);
return _control_unlink(control);
if (!unlink(control))
return 0;
log_sys_error("unlink", control);
return -1;
}
if (major && buf.st_rdev != MKDEV(major, minor)) {
@@ -282,7 +273,10 @@ static int _control_exists(const char *control, uint32_t major, uint32_t minor)
"(%u, %u)", control,
MAJOR(buf.st_mode), MINOR(buf.st_mode),
major, minor);
return _control_unlink(control);
if (!unlink(control))
return 0;
log_sys_error("unlink", control);
return -1;
}
return 1;
@@ -486,7 +480,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);
}
}
@@ -495,7 +489,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);
}
}
@@ -599,9 +593,23 @@ int dm_check_version(void)
_version_checked = 1;
if (_check_version(dmversion, sizeof(dmversion), 0))
if (_check_version(dmversion, sizeof(dmversion), _dm_compat))
return 1;
if (!_dm_compat)
goto_bad;
log_verbose("device-mapper ioctl protocol version %u failed. "
"Trying protocol version 1.", _dm_version);
_dm_version = 1;
if (_check_version(dmversion, sizeof(dmversion), 0)) {
log_verbose("Using device-mapper ioctl protocol version 1");
return 1;
}
compat = "(compat)";
bad:
dm_get_library_version(libversion, sizeof(libversion));
log_error("Incompatible libdevmapper %s%s and kernel driver %s.",
@@ -660,7 +668,7 @@ void *dm_get_next_target(struct dm_task *dmt, void *next,
return t->next;
}
/* Unmarshal the target info returned from a status call */
/* Unmarshall 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;
@@ -749,11 +757,6 @@ uint32_t dm_task_get_read_ahead(const struct dm_task *dmt, uint32_t *read_ahead)
struct dm_deps *dm_task_get_deps(struct dm_task *dmt)
{
if (!dmt) {
log_error(INTERNAL_ERROR "Missing dm_task.");
return NULL;
}
return (struct dm_deps *) (((char *) dmt->dmi.v4) +
dmt->dmi.v4->data_start);
}
@@ -770,7 +773,7 @@ static size_t _align_val(size_t val)
}
static void *_align_ptr(void *ptr)
{
return (void *)(uintptr_t)_align_val((size_t)ptr);
return (void *)_align_val((size_t)ptr);
}
static int _check_has_event_nr(void) {
@@ -783,12 +786,19 @@ static int _check_has_event_nr(void) {
return _has_event_nr;
}
struct dm_device_list {
struct dm_list list;
unsigned count;
unsigned features;
struct dm_hash_table *uuids;
};
int dm_task_get_device_list(struct dm_task *dmt, struct dm_list **devs_list,
unsigned *devs_features)
{
struct dm_names *names, *names1;
struct dm_active_device *dm_dev, *dm_new_dev;
struct dm_list *devs;
struct dm_device_list *devs;
unsigned next = 0;
uint32_t *event_nr;
char *uuid_ptr;
@@ -809,12 +819,12 @@ int dm_task_get_device_list(struct dm_task *dmt, struct dm_list **devs_list,
} while (next);
}
/* buffer for devs + sorted ptrs + dm_devs + aligned strings */
if (!(devs = malloc(sizeof(*devs) + cnt * (2 * sizeof(void*) + sizeof(*dm_dev)) +
(cnt ? (char*)names1 - (char*)names + 256 : 0))))
if (!(devs = malloc(sizeof(*devs) + (cnt ? cnt * sizeof(*dm_dev) + (char*)names1 - (char*)names + 256 : 0))))
return_0;
dm_list_init(devs);
dm_list_init(&devs->list);
devs->count = cnt;
devs->uuids = NULL;
if (!cnt) {
/* nothing in the list -> mark all features present */
@@ -822,22 +832,27 @@ int dm_task_get_device_list(struct dm_task *dmt, struct dm_list **devs_list,
goto out; /* nothing else to do */
}
/* Shift position where to store individual dm_devs */
dm_dev = (struct dm_active_device *) ((long*) (devs + 1) + cnt);
dm_dev = (struct dm_active_device *) (devs + 1);
do {
names = (struct dm_names *)((char *) names + next);
dm_dev->devno = (dev_t) names->dev;
dm_dev->name = (const char *)(dm_dev + 1);
dm_dev->major = MAJOR(names->dev);
dm_dev->minor = MINOR(names->dev);
dm_dev->name = (char*)(dm_dev + 1);
dm_dev->event_nr = 0;
dm_dev->uuid = "";
dm_dev->uuid = NULL;
len = strlen(names->name) + 1;
memcpy((char*)dm_dev->name, names->name, len);
memcpy(dm_dev->name, names->name, len);
dm_new_dev = _align_ptr((char*)(dm_dev + 1) + len);
if (_check_has_event_nr()) {
/* Hash for UUIDs with some more bits to reduce colision count */
if (!devs->uuids && !(devs->uuids = dm_hash_create(cnt * 8))) {
free(devs);
return_0;
}
*devs_features |= DM_DEVICE_LIST_HAS_EVENT_NR;
event_nr = _align_ptr(names->name + len);
@@ -846,29 +861,55 @@ int dm_task_get_device_list(struct dm_task *dmt, struct dm_list **devs_list,
if ((event_nr[1] & DM_NAME_LIST_FLAG_HAS_UUID)) {
*devs_features |= DM_DEVICE_LIST_HAS_UUID;
uuid_ptr = _align_ptr(event_nr + 2);
dm_dev->uuid = (char*) dm_new_dev;
len = strlen(uuid_ptr) + 1;
memcpy(dm_new_dev, uuid_ptr, len);
dm_dev->uuid = (const char *) dm_new_dev;
dm_new_dev = _align_ptr((char*)dm_new_dev + len);
memcpy(dm_dev->uuid, uuid_ptr, len);
if (!dm_hash_insert(devs->uuids, dm_dev->uuid, dm_dev))
return_0; // FIXME
#if 0
log_debug("Active %s (%s) %d:%d event:%u",
dm_dev->name, dm_dev->uuid,
dm_dev->major, dm_dev->minor, dm_dev->event_nr);
#endif
}
}
dm_list_add(devs, &dm_dev->list);
dm_list_add(&devs->list, &dm_dev->list);
dm_dev = dm_new_dev;
next = names->next;
} while (next);
out:
*devs_list = devs;
*devs_list = (struct dm_list *)devs;
return 1;
}
int dm_device_list_find_by_uuid(struct dm_list *devs_list, const char *uuid,
const struct dm_active_device **dev)
{
struct dm_device_list *devs = (struct dm_device_list *) devs_list;
struct dm_active_device *dm_dev;
if (devs->uuids &&
(dm_dev = dm_hash_lookup(devs->uuids, uuid))) {
if (dev)
*dev = dm_dev;
return 1;
}
return 0;
}
void dm_device_list_destroy(struct dm_list **devs_list)
{
struct dm_device_list *devs = (struct dm_device_list *) *devs_list;
if (devs) {
if (devs->uuids)
dm_hash_destroy(devs->uuids);
free(devs);
*devs_list = NULL;
}
@@ -1215,7 +1256,7 @@ static int _lookup_dev_name(uint64_t dev, char *buf, size_t len)
do {
names = (struct dm_names *)((char *) names + next);
if (names->dev == dev) {
memccpy(buf, names->name, 0, len);
strncpy(buf, names->name, len);
r = 1;
break;
}
@@ -1384,10 +1425,12 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
/* FIXME Until resume ioctl supplies name, use dev_name for readahead */
if (DEV_NAME(dmt) && (dmt->type != DM_DEVICE_RESUME || dmt->minor < 0 ||
dmt->major < 0))
memccpy(dmi->name, DEV_NAME(dmt), 0, sizeof(dmi->name));
/* coverity[buffer_size_warning] */
strncpy(dmi->name, DEV_NAME(dmt), sizeof(dmi->name));
if (DEV_UUID(dmt))
memccpy(dmi->uuid, DEV_UUID(dmt), 0, sizeof(dmi->uuid));
/* coverity[buffer_size_warning] */
strncpy(dmi->uuid, DEV_UUID(dmt), sizeof(dmi->uuid));
if (dmt->type == DM_DEVICE_SUSPEND)
dmi->flags |= DM_SUSPEND_FLAG;
@@ -1413,23 +1456,22 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
}
if (dmt->query_inactive_table) {
if (!_dm_inactive_supported())
log_warn_suppress(_dm_warn_inactive_suppress++,
"WARNING: Inactive table query unsupported by kernel. "
"It will use live table.");
log_warn("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("Setting UUID unsupported by kernel. "
"Aborting operation.");
log_error("WARNING: 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("IMA measurement unsupported by kernel. "
"Aborting operation.");
log_error("WARNING: IMA measurement unsupported by "
"kernel. Aborting operation.");
goto bad;
}
dmi->flags |= DM_IMA_MEASUREMENT_FLAG;
@@ -1652,7 +1694,6 @@ static int _create_and_load_v4(struct dm_task *dmt)
dmt->uuid = NULL;
free(dmt->mangled_uuid);
dmt->mangled_uuid = NULL;
/* coverity[double_free] recursive function call */
_dm_task_free_targets(dmt);
if (dm_task_run(dmt))
@@ -1664,7 +1705,6 @@ static int _create_and_load_v4(struct dm_task *dmt)
dmt->uuid = NULL;
free(dmt->mangled_uuid);
dmt->mangled_uuid = NULL;
/* coverity[double_free] recursive function call */
_dm_task_free_targets(dmt);
/*

View File

@@ -16,8 +16,6 @@
#ifndef LIB_DMTARGETS_H
#define LIB_DMTARGETS_H
#include "device_mapper/all.h"
#include <inttypes.h>
#include <sys/types.h>
@@ -81,7 +79,7 @@ struct dm_task {
};
struct cmd_data {
const char name[16];
const char *name;
const unsigned cmd;
const int version[3];
};

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 + 1];
char str_rest[DM_NAME_LEN];
size_t i, j;
unsigned int code;
int r = 0;
@@ -537,8 +537,7 @@ int unmangle_string(const char *str, const char *str_name, size_t len,
}
if (str[i] == '\\' && str[i+1] == 'x') {
if (!sscanf(&str[i+2], "%2x%" DM_TO_STRING(DM_NAME_LEN) "s",
&code, str_rest)) {
if (!sscanf(&str[i+2], "%2x%s", &code, str_rest)) {
log_debug_activation("Hex encoding mismatch detected in %s \"%s\" "
"while trying to unmangle it.", str_name, str);
goto out;
@@ -1061,8 +1060,9 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
if (info.st_rdev == dev)
return 1;
if (unlink(path) && (errno != ENOENT)) {
log_sys_error("unlink", path);
if (unlink(path) < 0) {
log_error("Unable to unlink device node for '%s'",
dev_name);
return 0;
}
} else if (_warn_if_op_needed(warn_if_udev_failed))
@@ -1106,8 +1106,8 @@ static int _rm_dev_node(const char *dev_name, int warn_if_udev_failed)
"Falling back to direct node removal.", path);
/* udev may already have deleted the node. Ignore ENOENT. */
if (unlink(path) && (errno != ENOENT)) {
log_sys_error("unlink", path);
if (unlink(path) < 0 && errno != ENOENT) {
log_error("Unable to unlink device node for '%s'", dev_name);
return 0;
}
@@ -1451,10 +1451,9 @@ struct node_op_parms {
static void _store_str(char **pos, char **ptr, const char *str)
{
size_t len = strlen(str) + 1;
memcpy(*pos, str, len);
strcpy(*pos, str);
*ptr = *pos;
*pos += len;
*pos += strlen(*ptr) + 1;
}
static void _del_node_op(struct node_op_parms *nop)
@@ -1704,17 +1703,15 @@ const char *dm_sysfs_dir(void)
*/
int dm_set_uuid_prefix(const char *uuid_prefix)
{
size_t len;
if (!uuid_prefix)
return_0;
if ((len = strlen(uuid_prefix)) > DM_MAX_UUID_PREFIX_LEN) {
if (strlen(uuid_prefix) > DM_MAX_UUID_PREFIX_LEN) {
log_error("New uuid prefix %s too long.", uuid_prefix);
return 0;
}
memcpy(_default_uuid_prefix, uuid_prefix, len + 1);
strcpy(_default_uuid_prefix, uuid_prefix);
return 1;
}
@@ -1743,9 +1740,6 @@ static void _unmangle_mountinfo_string(const char *src, char *buf)
*buf = '\0';
}
/* coverity[+tainted_string_sanitize_content:arg-0] */
static int _sanitize_line(const char *line) { return 1; }
/* Parse one line of mountinfo and unmangled target line */
static int _mountinfo_parse_line(const char *line, unsigned *maj, unsigned *min, char *buf)
{
@@ -1796,7 +1790,7 @@ static int _mountinfo_parse_line(const char *line, unsigned *maj, unsigned *min,
}
/*
* Function to operate on individual mountinfo line,
* Function to operate on individal 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)
@@ -1816,8 +1810,7 @@ int dm_mountinfo_read(dm_mountinfo_line_callback_fn read_fn, void *cb_data)
}
while (!feof(minfo) && fgets(buffer, sizeof(buffer), minfo))
if (!_sanitize_line(buffer) ||
!_mountinfo_parse_line(buffer, &maj, &min, target) ||
if (!_mountinfo_parse_line(buffer, &maj, &min, target) ||
!read_fn(buffer, maj, min, target, cb_data)) {
stack;
r = 0;
@@ -1832,27 +1825,32 @@ int dm_mountinfo_read(dm_mountinfo_line_callback_fn read_fn, void *cb_data)
static int _sysfs_get_dm_name(uint32_t major, uint32_t minor, char *buf, size_t buf_size)
{
char sysfs_path[PATH_MAX], temp_buf[2 * DM_NAME_LEN];
char *sysfs_path, *temp_buf = NULL;
FILE *fp = NULL;
int r = 0;
size_t len;
if (dm_snprintf(sysfs_path, sizeof(sysfs_path),
"%sdev/block/%" PRIu32 ":%" PRIu32
if (!(sysfs_path = malloc(PATH_MAX)) ||
!(temp_buf = malloc(PATH_MAX))) {
log_error("_sysfs_get_dm_name: failed to allocate temporary buffers");
goto bad;
}
if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32 ":%" PRIu32
"/dm/name", _sysfs_dir, major, minor) < 0) {
log_error("_sysfs_get_dm_name: dm_snprintf failed.");
log_error("_sysfs_get_dm_name: dm_snprintf failed");
goto bad;
}
if (!(fp = fopen(sysfs_path, "r"))) {
if (errno == ENOENT)
log_sys_debug("fopen", sysfs_path);
else
if (errno != ENOENT)
log_sys_error("fopen", sysfs_path);
else
log_sys_debug("fopen", sysfs_path);
goto bad;
}
if (!fgets(temp_buf, sizeof(temp_buf), fp)) {
if (!fgets(temp_buf, PATH_MAX, fp)) {
log_sys_error("fgets", sysfs_path);
goto bad;
}
@@ -1860,21 +1858,20 @@ static int _sysfs_get_dm_name(uint32_t major, uint32_t minor, char *buf, size_t
len = strlen(temp_buf);
if (len > buf_size) {
log_error("_sysfs_get_dm_name: supplied buffer too small.");
log_error("_sysfs_get_dm_name: supplied buffer too small");
goto bad;
}
if (len)
--len; /* strip \n */
memcpy(buf, temp_buf, len);
buf[len] = '\0';
temp_buf[len ? len - 1 : 0] = '\0'; /* \n */
strcpy(buf, temp_buf);
r = 1;
bad:
if (fp && fclose(fp))
log_sys_error("fclose", sysfs_path);
free(temp_buf);
free(sysfs_path);
return r;
}
@@ -1957,7 +1954,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, "queue") ||
!strcmp(name_dev, "queueu") ||
!strcmp(name_dev, "md") ||
!strcmp(name_dev, "mq") ||
!strcmp(name_dev, "power") ||
@@ -2412,7 +2409,7 @@ static int _get_cookie_sem(uint32_t cookie, int *semid)
break;
case EACCES:
log_error("No permission to access "
"notification semaphore identified "
"notificaton semaphore identified "
"by cookie value %" PRIu32 " (0x%x)",
cookie, cookie);
break;
@@ -2433,20 +2430,20 @@ static int _udev_notify_sem_inc(uint32_t cookie, int semid)
int val;
if (semop(semid, &sb, 1) < 0) {
log_error("cookie inc: semid %d: semop failed for cookie 0x%" PRIx32 ": %s",
log_error("semid %d: semop failed for cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
return 0;
}
if ((val = semctl(semid, 0, GETVAL)) < 0) {
log_warn("cookie inc: semid %d: sem_ctl GETVAL failed for "
log_error("semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
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 0;
}
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
cookie, semid, val);
return 1;
}
@@ -2456,21 +2453,23 @@ 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_warn("cookie dec: semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
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 (semop(semid, &sb, 1) < 0) {
switch (errno) {
case EAGAIN:
log_error("cookie dec: semid %d: semop failed for cookie "
log_error("semid %d: semop failed for cookie "
"0x%" PRIx32 ": "
"incorrect semaphore state",
semid, cookie);
break;
default:
log_error("cookie dec: semid %d: semop failed for cookie "
log_error("semid %d: semop failed for cookie "
"0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
break;
@@ -2478,12 +2477,9 @@ static int _udev_notify_sem_dec(uint32_t cookie, int semid)
return 0;
}
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);
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) decremented to %d",
cookie, semid, val - 1);
return 1;
}
@@ -2560,7 +2556,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("cookie create: semid %d: semctl failed: %s", gen_semid, strerror(errno));
log_error("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);
@@ -2568,10 +2564,9 @@ static int _udev_notify_sem_create(uint32_t *cookie, int *semid)
}
if ((val = semctl(gen_semid, 0, GETVAL)) < 0) {
log_error("cookie create: semid %d: sem_ctl GETVAL failed for "
log_error("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 major, uint32_t minor,
int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major,
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,8 +53,6 @@ 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 {
@@ -72,11 +70,12 @@ 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_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 struct dm_config_node *_create_node(struct dm_pool *mem);
static char *_dup_tok(struct parser *p);
static char *_dup_token(struct dm_pool *mem, const char *b, const char *e);
static const int _sep = '/';
#define MAX_INDENT 32
#define match(t) do {\
@@ -87,24 +86,20 @@ 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 (b < e) {
if (!*str ||
(*str != *b))
while (*str && (b != e)) {
if (*str++ != *b++)
return 0;
++str;
++b;
}
return !*str; /* token is matching for \0 end */
return !(*str || (b != e));
}
struct dm_config_tree *dm_config_create(void)
{
struct dm_config_tree *cft;
struct dm_pool *mem = dm_pool_create("config", 63 * 1024);
struct dm_pool *mem = dm_pool_create("config", 10 * 1024);
if (!mem) {
log_error("Failed to allocate config pool.");
@@ -178,24 +173,23 @@ 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, const char *section)
static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, const char *end, int no_dup_node_check)
{
/* TODO? if (start == end) return 1; */
struct parser p = {
.mem = cft->mem,
.tb = start,
.te = start,
.fb = start,
.fe = end,
.line = 1,
.stop_after_section = section,
.no_dup_node_check = no_dup_node_check
};
struct parser *p;
if (!(p = dm_pool_zalloc(cft->mem, sizeof(*p))))
return_0;
_get_token(&p, TOK_SECTION_E);
if (!(cft->root = _file(&p)))
p->mem = cft->mem;
p->fb = start;
p->fe = end;
p->tb = p->te = p->fb;
p->line = 1;
p->no_dup_node_check = no_dup_node_check;
_get_token(p, TOK_SECTION_E);
if (!(cft->root = _file(p)))
return_0;
cft->root = _config_reverse(cft->root);
@@ -205,23 +199,12 @@ 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, NULL);
return _do_dm_config_parse(cft, start, end, 0);
}
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, 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);
return _do_dm_config_parse(cft, start, end, 1);
}
struct dm_config_tree *dm_config_from_string(const char *config_settings)
@@ -487,33 +470,23 @@ int dm_config_write_node_out(const struct dm_config_node *cn,
/*
* parser
*/
static const char *_string_tok(struct parser *p, size_t *len)
static char *_dup_string_tok(struct parser *p)
{
ptrdiff_t d = p->te - p->tb;
char *str;
if (d < 2) {
p->tb++, p->te--; /* strip "'s */
if (p->te < p->tb) {
log_error("Parse error at byte %" PRIptrdiff_t " (line %d): "
"expected a string token.",
p->tb - p->fb + 1, p->line);
return NULL;
}
*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)))
if (!(str = _dup_tok(p)))
return_NULL;
if (!(str = _dup_token(p->mem, tok, tok + len)))
return_NULL;
p->te++;
return str;
}
@@ -535,9 +508,10 @@ static struct dm_config_node *_make_node(struct dm_pool *mem,
{
struct dm_config_node *n;
if (!(n = _create_node(mem, key_b, key_e - key_b)))
if (!(n = _create_node(mem)))
return_NULL;
n->key = _dup_token(mem, key_b, key_e);
if (parent) {
n->parent = parent;
n->sib = parent->child;
@@ -552,18 +526,17 @@ static struct dm_config_node *_find_or_make_node(struct dm_pool *mem,
const char *path,
int no_dup_node_check)
{
const int sep = '/';
const char *e;
struct dm_config_node *cn = parent ? parent->child : NULL;
struct dm_config_node *cn_found = NULL;
while (cn || mem) {
/* trim any leading slashes */
while (*path && (*path == sep))
while (*path && (*path == _sep))
path++;
/* find the end of this segment */
for (e = path; *e && (*e != sep); e++) ;
for (e = path; *e && (*e != _sep); e++) ;
/* hunt for the node */
cn_found = NULL;
@@ -607,8 +580,6 @@ 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)))
@@ -622,16 +593,9 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
match(TOK_STRING);
} else {
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;
}
if (!(str = _dup_tok(p)))
return_NULL;
match(TOK_IDENTIFIER);
}
@@ -645,28 +609,12 @@ 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;
@@ -723,14 +671,16 @@ 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;
const char *str;
size_t len;
struct dm_config_value *v = _create_value(p->mem);
char *str;
if (!v) {
log_error("Failed to allocate type value");
return NULL;
}
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 */
@@ -751,8 +701,6 @@ 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 */
@@ -764,31 +712,31 @@ static struct dm_config_value *_type(struct parser *p)
break;
case TOK_STRING:
if (!(str = _string_tok(p, &len)))
v->type = DM_CFG_STRING;
if (!(v->v.str = _dup_string_tok(p)))
return_NULL;
if ((v = _create_str_value(p->mem, str, len))) {
v->type = DM_CFG_STRING;
match(TOK_STRING);
}
match(TOK_STRING);
break;
case 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);
}
v->type = DM_CFG_STRING;
if (!(v->v.str = _dup_tok(p)))
return_NULL;
match(TOK_STRING_BARE);
break;
case TOK_STRING_ESCAPED:
if (!(str = _string_tok(p, &len)))
return_NULL;
v->type = DM_CFG_STRING;
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);
}
if (!(str = _dup_string_tok(p)))
return_NULL;
dm_unescape_double_quotes(str);
v->v.str = str;
match(TOK_STRING_ESCAPED);
break;
default:
@@ -796,12 +744,6 @@ 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;
}
@@ -819,52 +761,60 @@ static int _match_aux(struct parser *p, int t)
*/
static void _get_token(struct parser *p, int tok_prev)
{
/* 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);
int values_allowed = 0;
const char *te;
char c;
p->tb = p->te;
_eat_space(p);
if (p->tb == p->fe ||
!((c = *p->tb))) {
if (p->tb == p->fe || !*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 */
switch (c) {
te = p->te;
switch (*te) {
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))
@@ -878,6 +828,7 @@ static void _get_token(struct parser *p, int tok_prev)
case '\'':
p->t = TOK_STRING;
te++;
while ((te != p->fe) && (*te) && (*te != '\''))
te++;
@@ -901,7 +852,7 @@ static void _get_token(struct parser *p, int tok_prev)
case '+':
case '-':
if (values_allowed) {
for (; te != p->fe; ++te) {
while (++te != p->fe) {
if (!isdigit((int) *te)) {
if (*te == '.') {
if (p->t != TOK_FLOAT) {
@@ -918,10 +869,10 @@ static void _get_token(struct parser *p, int tok_prev)
default:
p->t = TOK_IDENTIFIER;
while ((te != p->fe) && ((c = *te)) && !isspace(c) &&
(c != '#') && (c != '=') &&
(c != SECTION_B_CHAR) &&
(c != SECTION_E_CHAR))
while ((te != p->fe) && (*te) && !isspace(*te) &&
(*te != '#') && (*te != '=') &&
(*te != SECTION_B_CHAR) &&
(*te != SECTION_E_CHAR))
te++;
if (values_allowed)
p->t = TOK_STRING_BARE;
@@ -934,19 +885,16 @@ static void _get_token(struct parser *p, int tok_prev)
static void _eat_space(struct parser *p)
{
while (p->tb != p->fe) {
if (!isspace(*p->te)) {
if (*p->te != '#')
break;
if (*p->te == '#')
while ((p->te != p->fe) && (*p->te != '\n') && (*p->te))
++p->te;
}
while (p->te != p->fe) {
else if (!isspace(*p->te))
break;
while ((p->te != p->fe) && isspace(*p->te)) {
if (*p->te == '\n')
++p->line;
else if (!isspace(*p->te))
break;
++p->te;
}
@@ -962,44 +910,9 @@ 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_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)
{
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;
return dm_pool_zalloc(mem, sizeof(struct dm_config_node));
}
static char *_dup_token(struct dm_pool *mem, const char *b, const char *e)
@@ -1416,20 +1329,19 @@ static struct dm_config_value *_clone_config_value(struct dm_pool *mem,
{
struct dm_config_value *new_cv;
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;
if (!(new_cv = _create_value(mem))) {
log_error("Failed to clone config value.");
return NULL;
}
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;
@@ -1446,11 +1358,16 @@ struct dm_config_node *dm_config_clone_node_with_mem(struct dm_pool *mem, const
return NULL;
}
if (!(new_cn = _create_node(mem, cn->key, cn->key ? strlen(cn->key) : 0))) {
if (!(new_cn = _create_node(mem))) {
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))) ||
@@ -1461,20 +1378,23 @@ 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 *cn, int sib)
struct dm_config_node *dm_config_clone_node(struct dm_config_tree *cft, const struct dm_config_node *node, int sib)
{
return dm_config_clone_node_with_mem(cft->mem, cn, sib);
return dm_config_clone_node_with_mem(cft->mem, node, 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, key, strlen(key)))) {
if (!(cn = _create_node(cft->mem))) {
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

@@ -19,6 +19,7 @@
#include "misc/dm-ioctl.h"
#include "vdo/target.h"
#include <stdarg.h>
#include <string.h>
#include <sys/utsname.h>
@@ -151,17 +152,15 @@ struct thin_message {
struct load_segment {
struct dm_list list;
uint64_t size;
unsigned type;
uint64_t size;
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 */
@@ -169,6 +168,7 @@ 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 +265,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' extended space
* there can be no i/o flying to this 'new' extedend 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 +277,7 @@ struct load_properties {
/*
* When comparing table lines to decide if a reload is
* needed, ignore any differences between the lvm device
* needed, ignore any differences betwen 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 +288,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 transaction_id is passed as 0 are never validated, this
* allows external management of thin-pool TID.
* where transation_id is passed as 0 are never validated, this
* allows external managment of thin-pool TID.
*/
unsigned send_messages;
/* Skip suspending node's children, used when sending messages to thin-pool */
@@ -348,7 +348,7 @@ struct dm_tree {
int retry_remove; /* 1 retries remove if not successful */
uint32_t cookie;
char buf[DM_NAME_LEN + 32]; /* print buffer for device_name (major:minor) */
const char * const *optional_uuid_suffixes; /* uuid suffixes ignored when matching */
const char **optional_uuid_suffixes; /* uuid suffixes ignored when matching */
};
/*
@@ -540,8 +540,7 @@ static struct dm_tree_node *_create_dm_tree_node(struct dm_tree *dtree,
struct dm_tree_node *node;
dev_t dev;
if (!dtree || !dtree->mem ||
!(node = dm_pool_zalloc(dtree->mem, sizeof(*node))) ||
if (!(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.");
@@ -599,9 +598,9 @@ static struct dm_tree_node *_find_dm_tree_node_by_uuid(struct dm_tree *dtree,
const char *default_uuid_prefix;
size_t default_uuid_prefix_len;
const char *suffix, *suffix_position;
char uuid_without_suffix[DM_UUID_LEN + 1];
char uuid_without_suffix[DM_UUID_LEN];
unsigned i = 0;
const char * const *suffix_list = dtree->optional_uuid_suffixes;
const char **suffix_list = dtree->optional_uuid_suffixes;
if ((node = dm_hash_lookup(dtree->uuids, uuid))) {
log_debug_activation("Matched uuid %s %s in deptree.", uuid, _node_name(node));
@@ -613,7 +612,7 @@ static struct dm_tree_node *_find_dm_tree_node_by_uuid(struct dm_tree *dtree,
if (strcmp(suffix_position + 1, suffix))
continue;
dm_strncpy(uuid_without_suffix, uuid, sizeof(uuid_without_suffix));
(void) strncpy(uuid_without_suffix, uuid, sizeof(uuid_without_suffix));
uuid_without_suffix[suffix_position - uuid] = '\0';
if ((node = dm_hash_lookup(dtree->uuids, uuid_without_suffix))) {
@@ -969,7 +968,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 = "contains a filesystem in use";
reason = "constains a filesystem in use";
else
return 1;
@@ -1817,7 +1816,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 correct udev rules
/* On some old udev systems without corrrect 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
@@ -2183,7 +2182,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 transaction_id message fails,
* the submission of transation_id message fails,
* resume should continue further, just whole command
* has to report failure.
*/
@@ -2275,7 +2274,7 @@ static int _build_dev_string(char *devbuf, size_t bufsize, struct dm_tree_node *
return 1;
}
/* simplify string emitting code */
/* simplify string emiting code */
#define EMIT_PARAMS(p, str...)\
do {\
int w;\
@@ -2869,8 +2868,6 @@ 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,
@@ -2890,7 +2887,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, " interleave_sectors:%u", set->interleave_sectors);
EMIT_PARAMS(pos, " ineterleave_sectors:%u", set->interleave_sectors);
if (set->buffer_sectors_set)
EMIT_PARAMS(pos, " buffer_sectors:%u", set->buffer_sectors);
@@ -2907,9 +2904,6 @@ 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;
@@ -2971,7 +2965,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 recognize 'right' size.
* NOTE: ATM VDO virtual size can be ONLY extended thus it's simple to recongnize '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))) {
@@ -3383,7 +3377,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 extended child node */
/* Propagate delayed resume from exteded child node */
if (child->props.delay_resume_if_extended)
dnode->props.delay_resume_if_extended = 1;
@@ -3819,7 +3813,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 with odd numbers of raid10 disks
* - data_copies to cope witth odd numbers of raid10 disks
*/
int dm_tree_node_add_raid_target_with_params_v2(struct dm_tree_node *node,
uint64_t size,
@@ -3870,7 +3864,7 @@ int dm_tree_node_add_cache_target(struct dm_tree_node *node,
{
struct dm_config_node *cn;
struct load_segment *seg;
const uint64_t modemask =
static const uint64_t _modemask =
DM_CACHE_FEATURE_PASSTHROUGH |
DM_CACHE_FEATURE_WRITETHROUGH |
DM_CACHE_FEATURE_WRITEBACK;
@@ -3882,12 +3876,12 @@ int dm_tree_node_add_cache_target(struct dm_tree_node *node,
return 0;
}
switch (feature_flags & modemask) {
switch (feature_flags & _modemask) {
case DM_CACHE_FEATURE_PASSTHROUGH:
case DM_CACHE_FEATURE_WRITEBACK:
if (strcmp(policy_name, "cleaner") == 0) {
/* Enforce writethrough mode for cleaner policy */
feature_flags = ~modemask;
feature_flags = ~_modemask;
feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
}
/* Fall through */
@@ -4083,7 +4077,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 target is unsupported.");
log_error("Replicator targer is unsupported.");
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -169,7 +169,7 @@ int dm_vasprintf(char **result, const char *format, va_list aq)
}
if (i > 1) {
/* Reallocating more than once? */
/* Reallocating more then once? */
if (!(*result = strdup(buf))) {
free(buf);
return -1;
@@ -385,7 +385,7 @@ char *dm_build_dm_uuid(struct dm_pool *mem, const char *uuid_prefix, const char
return NULL;
}
snprintf(dmuuid, len, "%s%s%s%s", uuid_prefix, lvid, (*layer) ? "-" : "", layer);
sprintf(dmuuid, "%s%s%s%s", uuid_prefix, lvid, (*layer) ? "-" : "", layer);
return dmuuid;
}
@@ -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;
char *size_buf = NULL;
char new_unit_type = '\0', unit_type_buf[2];
const char *prefix = "";
static const char _size_str[][3][12] = {
const char * const size_str[][3] = {
/* 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] : "");
sprintf(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 than 1.9949G prints <2.00G
* i.e. 2043M is more then 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 than real number of legs in a case
/* Raid target can actually report more then 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;
@@ -335,19 +335,11 @@ int dm_get_status_cache(struct dm_pool *mem, const char *params,
/* Read in policy args */
pp = p;
if (!(p = _skip_fields(p, 1)))
goto_bad;
i = p - pp;
if ((i < 1) ||
!(s->policy_name = dm_pool_zalloc(mem, i)))
goto_bad;
dm_strncpy(s->policy_name, pp, i);
if (sscanf(p, "%d", &s->policy_argc) != 1)
if (!(p = _skip_fields(p, 1)) ||
!(s->policy_name = dm_pool_zalloc(mem, (p - pp))))
goto bad;
if (sscanf(pp, "%s %d", s->policy_name, &s->policy_argc) != 2)
goto bad;
if (s->policy_argc &&
(!(s->policy_argv = dm_pool_zalloc(mem, sizeof(char *) * s->policy_argc)) ||
!(p = _skip_fields(p, 1)) ||
@@ -409,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 %15s",
if (sscanf(params, "%llu %llu %s",
(unsigned long long *)&s->number_of_mismatches,
(unsigned long long *)&s->provided_data_sectors,
recalc_str) != 3) {
@@ -536,21 +528,6 @@ int dm_get_status_thin(struct dm_pool *mem, const char *params,
return 1;
}
static dm_status_mirror_health_t _get_health(char c)
{
switch (c) {
case 'A': return DM_STATUS_MIRROR_ALIVE;
case 'F': return DM_STATUS_MIRROR_FLUSH_FAILED;
case 'D': return DM_STATUS_MIRROR_WRITE_FAILED;
case 'S': return DM_STATUS_MIRROR_SYNC_FAILED;
case 'R': return DM_STATUS_MIRROR_READ_FAILED;
default:
log_warn("WARNING: Unknown mirror health status char: %c", c);
/* fall through */
case 'U': return DM_STATUS_MIRROR_UNCLASSIFIED;
}
}
/*
* dm core parms: 0 409600 mirror
* Mirror core parms: 2 253:4 253:5 400/400
@@ -579,7 +556,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 than " DM_TO_STRING(DM_MIRROR_MAX_IMAGES)
log_error(INTERNAL_ERROR "More then " DM_TO_STRING(DM_MIRROR_MAX_IMAGES)
" reported in mirror status.");
goto out;
}
@@ -604,7 +581,7 @@ int dm_get_status_mirror(struct dm_pool *mem, const char *params,
pos += used;
for (i = 0; i < num_devs ; ++i)
s->devs[i].health = _get_health(pos[i]);
s->devs[i].health = pos[i];
if (!(pos = _skip_fields(pos, argc)))
goto_out;
@@ -649,7 +626,7 @@ int dm_get_status_mirror(struct dm_pool *mem, const char *params,
goto_out;
for (i = 0; i < s->log_count; ++i)
s->logs[i].health = _get_health(pos[i]);
s->logs[i].health = pos[i];
}
}

View File

@@ -13,8 +13,6 @@
# 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
@@ -211,7 +209,7 @@ struct dm_name_list {
};
#define DM_NAME_LIST_FLAG_HAS_UUID 1
#define DM_NAME_LIST_FLAG_DOES_NOT_HAVE_UUID 2
#define DM_NAME_LIST_FLAG_DOESNT_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 association with the instance created.
* record this assotiation 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,8 +13,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "base/memory/zalloc.h"
#include "device_mapper/misc/dmlib.h"
#include "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 properly locked, 0 otherwise.
* 1 (success) when the pool was preperly locked, 0 otherwise.
*/
int dm_pool_lock(struct dm_pool *p, int crc)
{

View File

@@ -1,165 +0,0 @@
/*
* Copyright (C) 2024 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Support counting number of failed device bits in dm-raid superblock bit arrays or clear them out.
*/
#include "device_mapper/misc/dmlib.h"
#include "device_mapper/all.h"
#include "device_mapper/raid/target.h"
#include "lib/mm/xlate.h"
#include <fcntl.h>
#include <unistd.h>
/* Copied/derived from kernel's drivers/md/dm-raid.c so this is prone to out-of-sync (factor out to header file?). */
#define MAX_RAID_DEVICES 253 /* md-raid kernel limit? */
#define UINT64_BITS (sizeof(uint64_t) * 8)
#define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (UINT64_BITS - 1)) / UINT64_BITS)
#define DM_RAID_SB_MAGIC 0x446D5264 /* "DmRd" */
#define FEATURE_FLAG_SUPPORTS_V190 0x1 /* Supports extended superblock */
/* RAID superblock at beginning of rmeta SubLVs trimmed down to mandatory members. */
struct dm_raid_superblock {
__le32 magic; /* "DmRd" */
__le32 compat_features; /* Used to indicate compatible features (like 1.9.0 ondisk metadata extension) */
__le32 dummy[4];
__le64 failed_devices; /* Pre 1.9.0 part of bit field of devices to */
/* indicate device failures (see extension below) */
__le32 dummy1[7];
/********************************************************************
* BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
*
* FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist
*/
__le32 flags; /* Flags defining array states for reshaping */
__le32 dummy2[14];
__le64 extended_failed_devices[DISKS_ARRAY_ELEMS - 1];
__le32 dummy3;
/* Always set rest up to logical block size to 0 when writing ... */
} __packed;
/* END: Copied from ... */
/* Superblock I/O buffer size to be able to Cope with 4K native devices... */
#define SB_BUFSZ 4096
static size_t _get_sb_size(const struct dm_raid_superblock *sb)
{
return (FEATURE_FLAG_SUPPORTS_V190 & le32toh(sb->compat_features)) ?
sizeof(*sb) : ((char *) &sb->flags - (char *) sb);
}
static uint32_t _hweight64(__le64 v)
{
uint32_t r = 0;
while (v) {
r += v & 1;
v >>= 1;
}
return r;
}
static uint32_t _hweight_failed(struct dm_raid_superblock *sb)
{
uint32_t r = _hweight64(sb->failed_devices);
if (_get_sb_size(sb) == sizeof(*sb)) {
int i = (int)DM_ARRAY_SIZE(sb->extended_failed_devices);
while (i--)
r = max(r, _hweight64(sb->extended_failed_devices[i]));
}
return r;
}
static void _clear_failed_devices(struct dm_raid_superblock *sb)
{
sb->failed_devices = 0;
if (_get_sb_size(sb) == sizeof(*sb))
memset(sb->extended_failed_devices, 0, sizeof(sb->extended_failed_devices));
}
static int _count_or_clear_failed_devices(const char *dev_path, bool clear, uint32_t *nr_failed)
{
struct dm_raid_superblock *sb = NULL;
size_t sz;
int fd, r = 0;
if (posix_memalign((void *) &sb, SB_BUFSZ, SB_BUFSZ)) {
log_sys_error("Failed to allocate RAID superblock buffer", dev_path);
return 0;
}
fd = open(dev_path, O_EXCL | ((clear) ? O_RDWR : O_RDONLY) | O_DIRECT);
if (fd < 0) {
log_sys_error("Failed to open RAID metadata volume", dev_path);
goto out;
}
if (read(fd, sb, SB_BUFSZ) != SB_BUFSZ) {
log_sys_error("Failed to read RAID metadata volume", dev_path);
goto out;
}
/* FIXME: big endian??? */
if (sb->magic != htobe32(DM_RAID_SB_MAGIC)) {
log_error("No RAID signature on %s.", dev_path);
goto out;
}
if (nr_failed)
*nr_failed = _hweight_failed(sb);
if (clear) {
if (lseek(fd, 0, SEEK_SET) < 0) {
log_sys_error("Failed to seek RAID metadata volume", dev_path);
goto out;
}
sz = _get_sb_size(sb);
memset((void *)((char *) sb + sz), 0, SB_BUFSZ - sz);
_clear_failed_devices(sb);
if (write(fd, sb, SB_BUFSZ) != SB_BUFSZ) {
log_sys_error("Failed to clear RAID metadata volume", dev_path);
goto out;
}
}
r = 1;
out:
if ((fd >= 0) && close(fd))
log_sys_debug("close", dev_path);
free(sb);
return r;
}
int dm_raid_count_failed_devices(const char *dev_path, uint32_t *nr_failed)
{
return _count_or_clear_failed_devices(dev_path, false, nr_failed);
}
int dm_raid_clear_failed_devices(const char *dev_path, uint32_t *nr_failed)
{
return _count_or_clear_failed_devices(dev_path, true, nr_failed);
}

View File

@@ -1,23 +0,0 @@
/*
* Copyright (C) 2024 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef DEVICE_MAPPER_RAID_TARGET_H
#define DEVICE_MAPPER_RAID_TARGET_H
#include <stdint.h>
int dm_raid_count_failed_devices(const char *dev_path, uint32_t *nr_failed);
int dm_raid_clear_failed_devices(const char *dev_path, uint32_t *nr_failed);
#endif

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 + 1) < num_patterns)
if (i < (num_patterns - 1))
*ptr++ = '|';
}

View File

@@ -13,6 +13,7 @@
* 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,8 +16,6 @@
#ifndef _DM_PARSE_REGEX_H
#define _DM_PARSE_REGEX_H
#include "device_mapper/misc/dmlib.h"
enum {
CAT,
STAR,

View File

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

@@ -28,6 +28,11 @@
#include "target.h"
#include "lib/mm/xlate.h"
//#include "linux/byteorder/big_endian.h"
//#include "linux/byteorder/little_endian.h"
//#define le32_to_cpu __le32_to_cpu
//#define le64_to_cpu __le64_to_cpu
#include <errno.h>
#include <fcntl.h>
@@ -67,7 +72,7 @@ enum {
struct vdo_header {
uint32_t id; /* The component this is a header for */
struct vdo_version_number version; /* The version of the data format */
uint64_t size; /* The size of the data following this header */
size_t size; /* The size of the data following this header */
} __packed;
struct vdo_geometry_block {
@@ -131,40 +136,40 @@ struct vdo_volume_geometry_4 {
struct vdo_index_config index_config;
} __packed;
/* Decoding mostly only some used structure members */
/* Decoding mostly only some used stucture members */
static void _vdo_decode_version(struct vdo_version_number *v)
{
v->major_version = le32toh(v->major_version);
v->minor_version = le32toh(v->minor_version);
v->major_version = le32_to_cpu(v->major_version);
v->minor_version = le32_to_cpu(v->minor_version);
}
static void _vdo_decode_header(struct vdo_header *h)
{
h->id = le32toh(h->id);
h->id = le32_to_cpu(h->id);
_vdo_decode_version(&h->version);
h->size = le64toh(h->size);
h->size = le64_to_cpu(h->size);
}
static void _vdo_decode_geometry_region(struct vdo_volume_region *vr)
{
vr->id = (enum vdo_volume_region_id) le32toh(vr->id);
vr->start_block = le64toh(vr->start_block);
vr->id = le32_to_cpu(vr->id);
vr->start_block = le64_to_cpu(vr->start_block);
}
static void _vdo_decode_volume_geometry(struct vdo_volume_geometry *vg)
{
vg->release_version = le32toh(vg->release_version);
vg->nonce = le64toh(vg->nonce);
vg->bio_offset = le64toh(vg->bio_offset);
vg->release_version = le32_to_cpu(vg->release_version);
vg->nonce = le64_to_cpu(vg->nonce);
vg->bio_offset = le64_to_cpu(vg->bio_offset);
_vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]);
}
static void _vdo_decode_volume_geometry_4(struct vdo_volume_geometry *vg,
struct vdo_volume_geometry_4 *vg_4)
{
vg->release_version = le32toh(vg_4->release_version);
vg->nonce = le64toh(vg_4->nonce);
vg->release_version = le32_to_cpu(vg_4->release_version);
vg->nonce = le64_to_cpu(vg_4->nonce);
vg->bio_offset = 0;
vg->regions[VDO_DATA_REGION] = vg_4->regions[VDO_DATA_REGION];
_vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]);
@@ -172,17 +177,17 @@ static void _vdo_decode_volume_geometry_4(struct vdo_volume_geometry *vg,
static void _vdo_decode_config(struct vdo_config *vc)
{
vc->logical_blocks = le64toh(vc->logical_blocks);
vc->physical_blocks = le64toh(vc->physical_blocks);
vc->slab_size = le64toh(vc->slab_size);
vc->recovery_journal_size = le64toh(vc->recovery_journal_size);
vc->slab_journal_blocks = le64toh(vc->slab_journal_blocks);
vc->logical_blocks = le64_to_cpu(vc->logical_blocks);
vc->physical_blocks = le64_to_cpu(vc->physical_blocks);
vc->slab_size = le64_to_cpu(vc->slab_size);
vc->recovery_journal_size = le64_to_cpu(vc->recovery_journal_size);
vc->slab_journal_blocks = le64_to_cpu(vc->slab_journal_blocks);
}
static void _vdo_decode_pvc(struct vdo_component_41_0 *pvc)
{
_vdo_decode_config(&pvc->config);
pvc->nonce = le64toh(pvc->nonce);
pvc->nonce = le64_to_cpu(pvc->nonce);
}
bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks)
@@ -221,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)) < (int)(MAGIC_NUMBER_SIZE + sizeof(h))) {
if (read(fh, buffer, sizeof(buffer)) < 0) {
log_sys_debug("read", vdo_path);
goto err;
}
@@ -265,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)) < (int)(sizeof(struct vdo_geometry_block) + sizeof(vn))) {
if (read(fh, buffer, sizeof(buffer)) < 0) {
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 << SECTOR_SHIFT));
vtp->minimum_io_size);
valid = false;
}

View File

@@ -1,24 +0,0 @@
# Common problems
## Duplicate PVs in the system
LVM tries to detect the common sources of duplicates, mdadm RAID and multipath,
there are cases where duplicate PV appears on the system.
There are two solutions to this problem:
* Setting a *global_filter* configuration option.
* Using of *devices_file* (See [lvmdevices(8)](https://man7.org/linux/man-pages/man8/lvmdevices.8.html))
## Device Filtering
*filter* and *global_filter* are meant to be used in two ways:
* as an allow list, listing patterns for devices which will be accepted
* `a|/dev/sdX|`, and rejecting the rest `r|.*|`,
* as a reject list, listing only patterns for devices which will be rejected
* `r|/dev/sdX|`,
Even though there are situations where it works, mixing reject and accept
patterns is not recommended.

View File

@@ -1,34 +0,0 @@
LVM2 Wiki Documentation
=======================
If you are looking for information about LVM2 visit the [[Index]] page,
There are only some notes about writing stuff under *./doc* here:
* If possible use [[MarkDown]] for formatting, use *.md* (or *.mdwn*) suffix.
* For linking between files, use [[IkiWiki]] syntax `[[FileName]]` or
`[[FileName#Anchor]]`, or `[[link text|FileName]]`
Markdown
--------
* Use `<!-- comment -->` to keep notes, which will not be rendered.
* Use `[[TODO]]` for anything what needs attention. This will be accessible
through the linked [[TODO]] page.
IkiWiki
-------
* Install ikiwiki:
yum install ikiwiki
* To generate the content, run following in the LVM2 top directory:
ikiwiki --setup ikiwiki.setup
Internal Stuff:
---------------
* [[TODO]] Can we have a section which is hidden by default? Like this one?
* [[TODO]] Add basic IkiWiki and MarkDown How To.

View File

@@ -1,152 +0,0 @@
# LVM - Logical Volume Manager for Linux
<!--
* TODO: Add banner for Important News: Critical Bugs, Important Announcements,...
-->
<!--
* TODO: Add a feed for latest articles/release-notes on the right
-->
<!--
## About LVM2
-->
LVM aka LVM2 refers to the userspace toolset that provide logical volume
management facilities on linux.
<!--
It is reasonably backwards-compatible with the
original LVM1 toolset.
* TODO: Add information about LVM1 metadata format conversion!
-->
LVM offers more flexibility than using partitions, allowing one to
* grow and, where supported by filesystem, shrink volumes,
* create snapshots of existing volumes,
* mirror data on multiple disks including RAID levels 5 or 6,
* striping data on multiple disks,
* create a read or write cache.
To use LVM2 you need 3 things:
* [device-mapper](https://sourceware.org/dm/) in your kernel (upstream since long ago)
* the userspace device-mapper support library (*libdevmapper*) (part of lvm2)
* and the userspace LVM2 tools.
## Getting LVM
Most of linux distribution offer packaged LVM tools.
Depending on your distribution use
# RPM based distributions (Fedora):
yum install lvm2
# DEB based distributions (Debian, Ubuntu):
apt-get install lvm2
Tarballs of the userspace LVM2 source code releases are available from [sourceware.org](https://sourceware.org/pub/lvm2/) [ftp](ftp://sourceware.org/pub/lvm2/).
List of official [mirror sites](https://sourceware.org/mirrors.html) (including http and rsync protocols).
### LVM Releases
[[!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]]
## Getting Started
<!--
TODO: We are missing a lvm(7) man page explaining this, I think it would be a nic addition!
And perhaps so would be a lvmtroubleshooting(7) guide.
-->
Word of warning first! Even though LVM errs on the side of data safety it is a
tool with low level access and one may seriously harm their data when used
incorrectly!
* Physical Volume (PV) is underlying disk, local or remote, encrypted or even
a mdadm RAID volume. PV is divided into so called Physical Extents (PE) which
are a basic allocation unit.
List PVs using [pvs(8)](https://man7.org/linux/man-pages/man8/pvs.8.html) or
[pvdisplay(8)](https://man7.org/linux/man-pages/man8/pvdisplay.8.html).
Make one by running `pvcreate /dev/sdX`.
See [pvcreate(8)](https://man7.org/linux/man-pages/man8/pvcreate.8.html). This step is optional.
* Volume Group (VG) consisting of one or more PVs is used as a pool from which LVs are allocated.
List VGs using [vgs(8)](https://man7.org/linux/man-pages/man8/vgs.8.html) or
[vgdisplay(8)](https://man7.org/linux/man-pages/man8/vgdisplay.8.html).
Make one by running `vgcreate VGNAME /dev/sdX...`, add PVs to existing one by `vgextend VGNAME /dev/sdX`.
To use LVM at least one Volume Group must be present on the system.
See [vgcreate(8)](https://man7.org/linux/man-pages/man8/vgcreate.8.html), and
[vgextend(8)](https://man7.org/linux/man-pages/man8/vgextend.8.html).
* Logical Volume (LV) is the block device usually visible to user to be used for file system.
List PVs using [lvs(8)](https://man7.org/linux/man-pages/man8/lvs.8.html) or
[lvdisplay(8)](https://man7.org/linux/man-pages/man8/lvdisplay.8.html).
Make one by running `lvcreate [-n LVNAME] -L SIZE VGNAME`, and you are done!
See [vgcreate(8)](https://man7.org/linux/man-pages/man8/vgcreate.8.html).
## Avoiding Problems
Good start is to avoid using `{--force|-f}` and `{--yes|-y}` options which are
often seen on internet discussions.
there is a possibility of data loss, LVM tools usually ask, so read the prompts
carefully! Using `--yes` removes these safety.
Also in some cases where it is too dangerous to proceed, e.g. device is used,
LVM refuses to do so, which can be overridden by `--force`.
Second, when resizing and especially when shrinking LVs it is always a good
idea to use `--resizefs` option which ensures the devices are resized in
correct order.
Third, if you still make a mess, never ever run fsck on damaged LV/FS, this is
usually the final blow to your data. It is always better to ask first!
## Documentation
## Resolving Problems
* Backup if possible!
* Search the problem first, check the list of [[common problems|Problems]]
* Never run `fsck` on damaged LV, LV must be recovered first!
* When asking for help describe exactly how the system got corrupted. It really
does not help trying to cover one's mistakes in such situation, it takes
longer to get help and also you are likely to get wrong answer making repair
impossible.
## Reporting Bugs
* When you find a problem there is often something specific about your system.
If the problem is reproducible run the failing command(s) with verbose flag
`-vvvv` which gives developers clue where the problem might be.
There is a [lvmdump(8)](https://man7.org/linux/man-pages/man8/lvmdump.8.html)
tool to help collect data about your system, block devices and LVM setup.
* Please report upstream bugs or request features in [Red Hat Bugzilla](https://bugzilla.redhat.com/enter_bug.cgi?product=LVM%20and%20device-mapper)
<!--
TODO:
* Add links to other documentation
* Add links to git
* Add links to mailing lists
* Resolving problems
* Backup if possible!
* Newer run fsck! Do the research first!
* List of Common issues
* Resizing in wrong order
* Thin pool running out of space
* Configuration - duplicates
* Mailing list
* IRC?
* Reporting Bugs
* sosreport/lvmdump
* BZ
* Contributing
* gitlab MR
* Add latest articles
-->

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 reusable
The persistent-data library is an attempt to provide a re-usable
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 usable capacity to the user.
Metadata zones are not reported as useable 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

@@ -1,4 +0,0 @@
.page {
max-width: 1280px;
margin: auto;
}

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 referenced-but-missing device/PV - and operations will still be
due to the refernced-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 reuse devices in a way that would trip up LVM in this
won't blindly try to re-use 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 reuse
replies will be well-formed "config file" style strings, so we can re-use
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
practice' stuff in here. For instance this is the code that decides to use the
practise' 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 practices stuff is going to require splitting at least
out the dm best practises 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.

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