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

Compare commits

..

51 Commits

Author SHA1 Message Date
David Teigland
2634b35ff4 man: add files with description information
The text in the .des files will be included in
the DESCRIPTION section.
2017-02-09 16:53:10 -06:00
David Teigland
3364166a6c command-lines.in: fix typo 2017-02-09 13:29:14 -06:00
David Teigland
20b3e8153c command-lines.in: add license header 2017-02-09 13:29:14 -06:00
David Teigland
485e2999db makefile: fixes, improvements, see also section 2017-02-09 13:29:01 -06:00
David Teigland
fec9641436 man: break long lines that would wrap
When all the required command line elements would go
beyond 80 chars and wrap to a new line, insert a line
break and indent, and continue the required elements
on a second line.
2017-02-09 13:29:00 -06:00
David Teigland
5b733c953e man: add examples from previous man pages 2017-02-09 13:28:57 -06:00
David Teigland
985d73b03d man: use .end suffix instead of .notes 2017-02-09 12:10:24 -06:00
David Teigland
24cf2a6127 man: fix generation of builtin commands 2017-02-09 12:10:20 -06:00
David Teigland
0d929d5a3d commands: remove debugging output
Remove the command id from the error messages.
2017-02-08 10:56:07 -06:00
David Teigland
c8945374d5 commands: rename structure fields
remove "line" from command_line_id/command_line_enum
2017-02-08 10:33:16 -06:00
David Teigland
1f67df932d args: use arg parsing function for region size
Consolidate the validation of the region size arg
in a new arg parsing function.
2017-02-08 09:57:13 -06:00
David Teigland
1bef87796f lvconvert: remove code for changing region size
from the generic raid type conversion code.
2017-02-07 15:01:30 -06:00
David Teigland
cfbbb4bee9 lvconvert: add command to change region size of a raid LV 2017-02-07 13:27:58 -06:00
David Teigland
058b53cdf4 vgchange: fix uint32 parsing of logicalvolume arg 2017-02-07 10:38:30 -06:00
David Teigland
2b8019fd43 commands: recognize raid variations 2017-02-07 10:38:30 -06:00
David Teigland
c213aa76c4 commands: move command def parsing into lvm binary 2017-02-07 10:38:30 -06:00
David Teigland
15e69fae19 lvconvert: remove unused code
For "split" which is not an alias for splitmirrors.
2017-02-07 10:38:30 -06:00
David Teigland
fe0ad1157d args: split is a synonym for splitcache
also tidy the other synonyms
2017-02-07 10:38:30 -06:00
David Teigland
88a2b1dc37 man: add vgsplit notes
from previous man page
2017-02-07 10:38:30 -06:00
David Teigland
03970369c5 man: add vgimportclone notes
from previous man page
2017-02-07 10:38:30 -06:00
David Teigland
c2147bda74 man: add vgimport notes
from previous man page
2017-02-07 10:38:30 -06:00
David Teigland
a61bc922a9 man: add vgexport notes
from previous man page
2017-02-07 10:38:30 -06:00
David Teigland
d41a2e6f30 man: add pvscan notes
from previous man page
2017-02-07 10:38:30 -06:00
David Teigland
55d6e9ebb7 man: add pvmove notes
Copied from the previous man page.
2017-02-07 10:38:30 -06:00
David Teigland
0a61ea395f man: lvmlockd/clvmd notes about activation
activation details about lvmlockd and clvmd that were
previously in the generic lvchange -a section are now
moved to these man pages.
2017-02-07 10:38:30 -06:00
David Teigland
e61f84cd1f generate man pages 2017-02-07 10:38:30 -06:00
David Teigland
ca8e344041 man: lvmthin updates
Some minor changes to some of the command syntaxes
to use more standard forms.
2017-02-07 10:38:30 -06:00
David Teigland
14838f584f ccmd: split into multiple files 2017-02-07 10:38:30 -06:00
David Teigland
6033e894e2 command struct: remove command name refs
Change run time access to the command_name struct
cmd->cname instead of indirectly through
cmd->command->cname. This removes the two run time
fields from struct command.
2017-02-07 10:38:30 -06:00
David Teigland
9b4c2027bf command.h comment tidying 2017-02-07 10:38:30 -06:00
David Teigland
61e0925844 lvm shell: clear argv for each command 2017-02-07 10:38:30 -06:00
David Teigland
214f48aa96 help: accept positional args
lvm help <commandname> ...
2017-02-07 10:38:30 -06:00
David Teigland
29ee87987c fix lvmcmdline warning
declaration of ‘usage’ shadows a globa
2017-02-07 10:38:30 -06:00
David Teigland
2391324196 Makefile: clean up create-command parts 2017-02-07 10:38:30 -06:00
David Teigland
e8230719ee man lvm: remove options
all options are now included in commands
2017-02-07 10:38:30 -06:00
David Teigland
2c5f6b8a02 args: add man page descriptions 2017-02-07 10:38:30 -06:00
David Teigland
fe3b2f5ead args: use uint32 arg for maxphysicalvolumes 2017-02-07 10:38:30 -06:00
David Teigland
91a1273d56 lvconvert: remove unused code 2017-02-07 10:38:30 -06:00
David Teigland
5507307b5f lvconvert: use command defs for raid/mirror types
All lvconvert functionality has been moved out of the
previous monolithic lvconvert code, except conversions
related to raid/mirror/striped/linear.  This switches
that remaining code to be based on command defs, and
standard process_each_lv arg processing.  This final
switch results in quite a bit of dead code that is
also removed.
2017-02-07 10:38:30 -06:00
David Teigland
91b71a8b02 tests: use swapmetadata
and some other pool/cache/thin related changes
2017-02-07 10:38:30 -06:00
David Teigland
3057fe9fec lvconvert: use command defs for mergemirrors
and route the generic --merge to one of the
specific merge functions
2017-02-07 10:38:30 -06:00
David Teigland
258027d1b1 toollib: find VG name in option values when needed 2017-02-07 10:38:30 -06:00
David Teigland
2da0f6110d lvconvert: use command defs for thin/cache/pool creation
Everything related to thin and cache.
2017-02-07 10:38:30 -06:00
David Teigland
09d6229350 lvconvert: add startpoll command using command def
This is a new explicit version of 'lvconvert LV'
which has been an obscure way of triggering polling
to be restarted on an LV that was previously converted.
2017-02-07 10:38:30 -06:00
David Teigland
6312e0872c lvconvert: snapshot: use command definitions
Lift all the snapshot utilities (merge, split, combine)
out of the monolithic lvconvert implementation, using
the command definitions.  The old code associated with
these commands is now unused and will be removed separately.
2017-02-07 10:38:30 -06:00
David Teigland
c752f4e1eb lvconvert: remove unused calls for repair and replace
repair and replace are no longer called from the
monolithic lvconvert code, so remove the unused code.
2017-02-07 10:38:30 -06:00
David Teigland
cd36b1c698 lvconvert: repair and replace: use command definitions
This lifts the lvconvert --repair and --replace commands
out of the monolithic lvconvert implementation.  The
previous calls into repair/replace can no longer be
reached and will be removed in a separate commit.
2017-02-07 10:36:18 -06:00
David Teigland
310d9a09fd lvchange: make use of command definitions
Reorganize the lvchange code to take advantage of
the command definition, and remove the validation
that is done by the command definintion rules.
2017-02-07 10:36:18 -06:00
David Teigland
81e84556b5 process_each_lv: add check_single_lv function
The new check_single_lv() function is called prior to the
existing process_single_lv().  If the check function returns 0,
the LV will not be processed.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

View File

@@ -59,8 +59,6 @@ liblvm: lib
daemons: lib libdaemon tools
tools: lib libdaemon device-mapper
po: tools daemons
man: tools
all_man: tools
scripts: liblvm libdm
lib.device-mapper: include.device-mapper
@@ -100,7 +98,7 @@ CLEAN_DIRS += autom4te.cache
check check_system check_cluster check_local check_lvmetad check_lvmpolld check_lvmlockd_test check_lvmlockd_dlm check_lvmlockd_sanlock unit: all
$(MAKE) -C test $(@)
conf.generate man.generate: tools
conf.generate: tools
# how to use parenthesis in makefiles
leftparen:=(
@@ -130,9 +128,8 @@ rpm: dist
$(top_srcdir)/spec/source.inc >$(rpmbuilddir)/SOURCES/source.inc
rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
generate: conf.generate man.generate
generate: conf.generate
$(MAKE) -C conf generate
$(MAKE) -C man generate
all_man:
$(MAKE) -C man all_man

5
README
View File

@@ -6,12 +6,11 @@ Installation instructions are in INSTALL.
There is no warranty - see COPYING and COPYING.LIB.
Tarballs are available from:
ftp://sourceware.org/pub/lvm2/
ftp://sources.redhat.com/pub/lvm2/
The source code is stored in git:
https://sourceware.org/git/?p=lvm2.git
git clone git://sourceware.org/git/lvm2.git
http://git.fedorahosted.org/git/lvm2.git
git clone git://git.fedorahosted.org/git/lvm2.git
Mailing list for general discussion related to LVM2:
linux-lvm@redhat.com

View File

@@ -1 +1 @@
2.02.174(2)-git (2017-07-20)
2.02.169(2)-git (2016-11-30)

View File

@@ -1 +1 @@
1.02.143-git (2017-07-20)
1.02.138-git (2016-11-30)

132
WHATS_NEW
View File

@@ -1,132 +1,6 @@
Version 2.02.174 -
=================================
Fix check for 2nd mda at end of disk fits if using pvcreate --restorefile.
Use maximum metadataarea size that fits with pvcreate --restorefile.
Always clear cached bootloaderarea when wiping label e.g. in pvcreate.
Disallow --bootloaderareasize with pvcreate --restorefile.
Fix lvmlockd check for running lock managers during lock adoption.
Add --withgeneralpreamble and --withlocalpreamble to lvmconfig.
Improve makefiles' linking.
Fix some paths in generated makefiles to respected configured settings.
Add warning when creating thin-pool with zeroing and chunk size >= 512KiB.
Introduce exit code 4 EINIT_FAILED to replace -1 when initialisation fails.
Add synchronization points with udev during reshape of raid LVs.
Version 2.02.173 - 20th July 2017
=================================
Add synchronization points with udev during conversion of raid LVs.
Improve --size args validation and report more detailed error message.
Initialize debugging mutex before any debug message in clvmd.
Log error instead of warn when noticing connection problem with lvmetad.
Fix memory leak in lvmetad when working with duplicates.
Remove restrictions on reshaping open and clustered raid devices.
Add incompatible data_offset to raid metadata to fix reshape activation.
Accept 'lvm -h' and 'lvm --help' as well as 'lvm help' for help.
Suppress error message from accept() on clean lvmetad shutdown.
Tidy clvmd client list processing and fix segfaults.
Protect clvmd debug log messages with mutex and add client id.
Fix shellcheck reported issues for script files.
Version 2.02.172 - 28th June 2017
=================================
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.
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".
Improve lvcreate --cachepool arg validation.
Limit maximum size of thin-pool for specific chunk size.
Print a warning about in-use PVs with no VG using them.
Disable automatic clearing of PVs that look like in-use orphans.
Cache format2 flag is now using segment name type field.
Support storing status flags via segtype name field.
Stop using '--yes' mode when fsadm runs without terminal.
Extend validation of filesystems resized by fsadm.
Enhance lvconvert automatic settings of possible (raid) LV types.
Allow lvchange to change properties on a thin pool data sub LV.
Fix lvcreate extent percentage calculation for mirrors.
Don't reinstate still-missing devices when correcting inconsistent metadata.
Properly handle subshell return codes in fsadm.
Disallow cachepool creation with policy cleaner and mode writeback.
Version 2.02.171 - 3rd May 2017
===============================
Fix memory warnings by using mempools for command definition processing.
Fix running commands from a script file.
Add pvcreate prompt when device size doesn't match setphysicalvolumesize.
lvconvert - preserve region size on raid1 image count changes
Adjust pvresize/pvcreate messages and prompt if underlying dev size differs.
raid - sanely handle insufficient space on takeover.
Fix configure --enable-notify-dbus status message.
Change configure option name prefix from --enable-lockd to --enable-lvmlockd.
lvcreate - raise mirror/raid default regionsize to 2MiB
Add missing configurable prefix to configuration file installation directory.
Version 2.02.170 - 13th April 2017
==================================
Introduce global/fsadm_executable to make fsadm path configurable.
Look for limited thin pool metadata size when using 16G metadata.
Add lvconvert pool creation rule disallowing options with poolmetadata.
Fix lvconvert when the same LV is incorrectly reused in options.
Fix lvconvert VG name validation in option values.
Fix missing lvmlockd LV locks in lvchange and lvconvert.
Fix dmeventd setup for lvchange --poll.
Fix use of --poll and --monitor with lvchange and vgchange.
Disallow lvconvert of hidden LV to a pool.
Ignore --partial option when not used for activation.
Allow --activationmode option with lvchange --refresh.
Better message on lvconvert --regionsize
Allow valid lvconvert --regionsize change
Add raid10 alias raid10_near
Handle insufficient PVs on lvconvert takeover
Fix SIGINT blocking to prevent corrupted metadata
Fix systemd unit existence check for lvmconf --services --startstopservices.
Check and use PATH_MAX buffers when creating vgrename device paths.
Version 2.02.169 - 28th March 2017
==================================
Automatically decide whether '-' in a man page is a hyphen or a minus sign.
Add build-time configuration command line to 'lvm version' output.
Handle known table line parameter order change in specific raid target vsns.
Conditionally reject raid convert to striped/raid0* after reshape.
Ensure raid6 upconversion restrictions.
Adjust mirror & raid dmeventd plugins for new lvconvert --repair behaviour.
Disable lvmetad when lvconvert --repair is run.
Remove obsolete lvmchange binary - convert to built-in command.
Show more information for cached volumes in lvdisplay [-m].
Add option for lvcreate/lvconvert --cachemetadataformat auto|1|2.
Support cache segment with configurable metadata format.
Add allocation/cache_metadata_format profilable settings.
Use function cache_set_params() for both lvcreate and lvconvert.
Skip rounding on cache chunk size boudary when create cache LV.
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.
Upstream git moved to https://sourceware.org/git/?p=lvm2
Support conversion of raid type, stripesize and number of disks
Reject writemostly/writebehind in lvchange during resynchronization.
Deactivate active origin first before removal for improved workflow.
Fix regression of accepting both --type and -m with lvresize. (2.02.158)
Add lvconvert --swapmetadata, new specific way to swap pool metadata LVs.
Add lvconvert --startpoll, new specific way to start polling conversions.
Add lvconvert --mergethin, new specific way to merge thin snapshots.
Add lvconvert --mergemirrors, new specific way to merge split mirrors.
Add lvconvert --mergesnapshot, new specific way to combine cow LVs.
Split up lvconvert code based on command definitions.
Split up lvchange code based on command definitions.
Generate help output and man pages from command definitions.
Verify all command line items against command definition.
Match every command run to one command definition.
Specify every allowed command definition/syntax in command-lines.in.
Add extra memory page when limiting pthread stack size in clvmd.
Support striped/raid0* <-> raid10_near conversions.
Support shrinking of RaidLVs.
Support region size changes on existing RaidLVs.
Version 2.02.169 -
=====================================
Support region size changes on existing RaidLVs
Avoid parallel usage of cpg_mcast_joined() in clvmd with corosync.
Support raid6_{ls,rs,la,ra}_6 segment types and conversions from/to it.
Support raid6_n_6 segment type and conversions from/to it.

View File

@@ -1,56 +1,16 @@
Version 1.02.143 -
=================================
Add --concise to dmsetup create for many devices with tables in one command.
Accept minor number without major in library when it knows dm major number.
Introduce single-line concise table output format: dmsetup table --concise
Version 1.02.142 - 20th July 2017
=================================
Create /dev/disk/by-part{uuid,label} and gpt-auto-root symlinks with udev.
Version 1.02.141 - 28th June 2017
=================================
Fix reusing of dm_task structure for status reading (used by dmeventd).
Add dm_percent_to_round_float for adjusted percentage rounding.
Reset array with dead rimage devices once raid gets in sync.
Drop unneeded --config option from raid dmeventd plugin.
dm_get_status_raid() handle better some incosistent md statuses.
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).
Version 1.02.140 - 3rd May 2017
===============================
Add missing configure --enable-dmfilemapd status message and fix --disable.
Version 1.02.139 - 13th April 2017
==================================
Fix assignment in _target_version() when dm task can't run.
Flush stdout on each iteration when using --count or --interval.
Show detailed error message when execvp fails while starting dmfilemapd.
Fix segmentation fault when dmfilemapd is run with no arguments.
Numerous minor dmfilemapd fixes from coverity.
Version 1.02.138 - 28th March 2017
==================================
Support additional raid5/6 configurations.
Provide dm_tree_node_add_cache_target@base compatible symbol.
Support DM_CACHE_FEATURE_METADATA2, new cache metadata format 2.
Improve code to handle mode mask for cache nodes.
Cache status check for passthrough also require trailing space.
Add extra memory page when limiting pthread stack size in dmeventd.
Avoids immediate resume when preloaded device is smaller.
Do not suppress kernel key description in dmsetup table output for dm-crypt.
Version 1.02.138 -
=====================================
Support configurable command executed from dmeventd thin plugin.
Support new R|r human readable units output format.
Thin dmeventd plugin reacts faster on lvextend failure path with umount.
Add dm_stats_bind_from_fd() to bind a stats handle from a file descriptor.
Do not try call callback when reverting activation on error path.
Fix file mapping for extents with physically adjacent extents in dmstats.
Fix file mapping for extents with physically adjacent extents.
Validation vsnprintf result in runtime translate of dm_log (1.02.136).
Separate filemap extent allocation from region table in dmstats.
Fix segmentation fault when filemap region creation fails in dmstats.
Fix performance of region cleanup for failed filemap creation in dmstats.
Fix very slow region deletion with many regions in dmstats.
Separate filemap extent allocation from region table.
Fix segmentation fault when filemap region creation fails.
Fix performance of region cleanup for failed filemap creation.
Fix very slow region deletion with many regions.
Version 1.02.137 - 30th November 2016
=====================================

View File

@@ -32,8 +32,8 @@ include $(top_builddir)/make.tmpl
.PHONY: install_conf install_localconf install_profiles
generate:
LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withgeneralpreamble --withcomments --ignorelocal --withspaces > example.conf.in
LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withlocalpreamble --withcomments --withspaces local > lvmlocal.conf.in
(cat $(top_srcdir)/conf/example.conf.base && LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withcomments --ignorelocal --withspaces) > example.conf.in
(cat $(top_srcdir)/conf/lvmlocal.conf.base && LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withcomments --withspaces local) > lvmlocal.conf.in
install_conf: $(CONFSRC)
@if [ ! -e $(confdir)/$(CONFDEST) ]; then \
@@ -48,8 +48,8 @@ install_localconf: $(CONFLOCAL)
fi
install_profiles: $(PROFILES)
$(INSTALL_DIR) $(profiledir)
$(INSTALL_DATA) $(PROFILES) $(profiledir)/
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_PROFILE_DIR)
$(INSTALL_DATA) $(PROFILES) $(DESTDIR)$(DEFAULT_PROFILE_DIR)/
install_lvm2: install_conf install_localconf install_profiles

View File

@@ -9,6 +9,6 @@ allocation {
cache_mode = "writethrough"
cache_policy = "smq"
cache_settings {
# currently no settings for "smq" policy
# currently no settins for "smq" policy
}
}

23
conf/example.conf.base Normal file
View File

@@ -0,0 +1,23 @@
# This is an example configuration file for the LVM2 system.
# It contains the default settings that would be used if there was no
# @DEFAULT_SYS_DIR@/lvm.conf file.
#
# Refer to 'man lvm.conf' for further information including the file layout.
#
# Refer to 'man lvm.conf' for information about how settings configured in
# this file are combined with built-in values and command line options to
# arrive at the final values used by LVM.
#
# Refer to 'man lvmconfig' for information about displaying the built-in
# and configured values used by LVM.
#
# If a default value is set in this file (not commented out), then a
# new version of LVM using this file will continue using that value,
# even if the new version of LVM changes the built-in default value.
#
# To put this file in a different directory and override @DEFAULT_SYS_DIR@ set
# the environment variable LVM_SYSTEM_DIR before running the tools.
#
# N.B. Take care that each setting only appears once if uncommenting
# example settings in this file.

View File

@@ -379,9 +379,8 @@ allocation {
# Configuration option allocation/raid_stripe_all_devices.
# Stripe across all PVs when RAID stripes are not specified.
# If enabled, all PVs in the VG or on the command line are used for
# raid0/4/5/6/10 when the command does not specify the number of
# stripes to use.
# If enabled, all PVs in the VG or on the command line are used for raid0/4/5/6/10
# when the command does not specify the number of stripes to use.
# This was the default behaviour until release 2.02.162.
# This configuration option has an automatic default value.
# raid_stripe_all_devices = 0
@@ -390,17 +389,6 @@ allocation {
# Cache pool metadata and data will always use different PVs.
cache_pool_metadata_require_separate_pvs = 0
# Configuration option allocation/cache_metadata_format.
# Sets default metadata format for new cache.
#
# Accepted values:
# 0 Automatically detected best available format
# 1 Original format
# 2 Improved 2nd. generation format
#
# This configuration option has an automatic default value.
# cache_metadata_format = 0
# Configuration option allocation/cache_mode.
# The default cache mode used for new cache.
#
@@ -417,7 +405,7 @@ allocation {
# Configuration option allocation/cache_policy.
# The default cache policy used for new cache volume.
# Since kernel 4.2 the default policy is smq (Stochastic multiqueue),
# Since kernel 4.2 the default policy is smq (Stochastic multique),
# otherwise the older mq (Multiqueue) policy is selected.
# This configuration option does not have a default value defined.
@@ -940,7 +928,7 @@ global {
use_lvmetad = @DEFAULT_USE_LVMETAD@
# Configuration option global/lvmetad_update_wait_time.
# Number of seconds a command will wait for lvmetad update to finish.
# The number of seconds a command will wait for lvmetad update to finish.
# After waiting for this period, a command will not use lvmetad, and
# will revert to disk scanning.
# This configuration option has an automatic default value.
@@ -1025,7 +1013,7 @@ global {
# Configuration option global/cache_disabled_features.
# Features to not use in the cache driver.
# This can be helpful for testing, or to avoid using a feature that is
# causing problems. Features include: policy_mq, policy_smq, metadata2.
# causing problems. Features include: policy_mq, policy_smq.
#
# Example
# cache_disabled_features = [ "policy_smq" ]
@@ -1070,12 +1058,6 @@ global {
# This configuration option has an automatic default value.
# cache_repair_options = [ "" ]
# Configuration option global/fsadm_executable.
# The full path to the fsadm command.
# LVM uses this command to help with lvresize -r operations.
# This configuration option has an automatic default value.
# fsadm_executable = "@FSADM_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,
@@ -1295,10 +1277,9 @@ activation {
# Configuration option activation/raid_region_size.
# Size in KiB of each raid or mirror synchronization region.
# The clean/dirty state of data is tracked for each region.
# The value is rounded down to a power of two if necessary, and
# is ignored if it is not a multiple of the machine memory page size.
raid_region_size = 2048
# For raid or mirror segment types, this is the amount of data that is
# copied at once when initializing, or moved at once by pvmove.
raid_region_size = 512
# Configuration option activation/error_when_full.
# Return errors if a thin pool runs out of space.
@@ -2073,7 +2054,6 @@ dmeventd {
# or metadata volume gets above 50%.
# Command which starts with 'lvm ' prefix is internal lvm command.
# You can write your own handler to customise behaviour in more details.
# User handler is specified with the full path starting with '/'.
# This configuration option has an automatic default value.
# thin_command = "lvm lvextend --use-policies"

19
conf/lvmlocal.conf.base Normal file
View File

@@ -0,0 +1,19 @@
# This is a local configuration file template for the LVM2 system
# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .
#
# Refer to 'man lvm.conf' for information about the file layout.
#
# To put this file in a different directory and override
# @DEFAULT_SYS_DIR@ set the environment variable LVM_SYSTEM_DIR before
# running the tools.
#
# The lvmlocal.conf file is normally expected to contain only the
# "local" section which contains settings that should not be shared or
# repeated among different hosts. (But if other sections are present,
# they *will* get processed. Settings in this file override equivalent
# ones in lvm.conf and are in turn overridden by ones in any enabled
# lvm_<tag>.conf files.)
#
# Please take care that each setting only appears once if uncommenting
# example settings in this file and never copy this file between hosts.

544
configure vendored
View File

@@ -660,7 +660,7 @@ SELINUX_PC
SELINUX_LIBS
REPLICATORS
READLINE_LIBS
RT_LIBS
RT_LIB
RAID
PYTHON3DIR
PYTHON2DIR
@@ -699,11 +699,11 @@ HAVE_VALGRIND
HAVE_REALTIME
HAVE_LIBDL
BLKDEACTIVATE
FSADM_PATH
FSADM
ELDFLAGS
DM_LIB_PATCHLEVEL
DMEVENTD_PATH
DMEVENTD
DL_LIBS
DEVMAPPER
DEFAULT_USE_LVMLOCKD
@@ -736,7 +736,7 @@ CLDWHOLEARCHIVE
CLDNOWHOLEARCHIVE
CLDFLAGS
CACHE
BUILD_DMFILEMAPD
BUILD_NOTIFYDBUS
BUILD_LOCKDDLM
BUILD_LOCKDSANLOCK
BUILD_LVMLOCKD
@@ -819,14 +819,11 @@ THIN_CHECK_CMD
HAVE_FULL_RELRO
HAVE_PIE
POW_LIB
ALLOCA
LIBOBJS
SORT
WC
ALLOCA
CHMOD
CSCOPE_CMD
CFLOW_CMD
AR
RANLIB
MKDIR_P
SET_MAKE
@@ -953,15 +950,14 @@ enable_valgrind_pool
enable_devmapper
enable_lvmetad
enable_lvmpolld
enable_lvmlockd_sanlock
enable_lvmlockd_dlm
enable_lockd_sanlock
enable_lockd_dlm
enable_use_lvmlockd
with_lvmlockd_pidfile
enable_use_lvmetad
with_lvmetad_pidfile
enable_use_lvmpolld
with_lvmpolld_pidfile
enable_dmfilemapd
enable_notify_dbus
enable_blkid_wiping
enable_udev_systemd_background_jobs
@@ -1691,13 +1687,11 @@ Optional Features:
--disable-devmapper disable LVM2 device-mapper interaction
--enable-lvmetad enable the LVM Metadata Daemon
--enable-lvmpolld enable the LVM Polling Daemon
--enable-lvmlockd-sanlock
enable the LVM lock daemon using sanlock
--enable-lvmlockd-dlm enable the LVM lock daemon using dlm
--enable-lockd-sanlock enable the LVM lock daemon using sanlock
--enable-lockd-dlm enable the LVM lock daemon using dlm
--disable-use-lvmlockd disable usage of LVM lock daemon
--disable-use-lvmetad disable usage of LVM Metadata Daemon
--disable-use-lvmpolld disable usage of LVM Poll Daemon
--enable-dmfilemapd enable the dmstats filemap daemon
--enable-notify-dbus enable LVM notification using dbus
--disable-blkid_wiping disable libblkid detection of signatures when wiping
and use native code instead
@@ -3015,7 +3009,6 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
CONFIGURE_LINE="$0 $@"
ac_config_headers="$ac_config_headers include/configure.h"
@@ -3169,7 +3162,6 @@ fi
case "$host_os" in
linux*)
CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym"
# equivalent to -rdynamic
ELDFLAGS="-Wl,--export-dynamic"
# FIXME Generate list and use --dynamic-list=.dlopen.sym
CLDWHOLEARCHIVE="-Wl,-whole-archive"
@@ -4948,98 +4940,6 @@ else
RANLIB="$ac_cv_prog_RANLIB"
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AR"; then
ac_cv_prog_AR="$AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
$as_echo "$AR" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_prog_AR"; then
ac_ct_AR=$AR
# Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_AR"; then
ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
$as_echo "$ac_ct_AR" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_ct_AR" = x; then
AR=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
AR=$ac_ct_AR
fi
else
AR="$ac_cv_prog_AR"
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}cflow", so it can be a program name with args.
set dummy ${ac_tool_prefix}cflow; ac_word=$2
@@ -5334,202 +5234,6 @@ else
CHMOD="$ac_cv_path_CHMOD"
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}wc", so it can be a program name with args.
set dummy ${ac_tool_prefix}wc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_WC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $WC in
[\\/]* | ?:[\\/]*)
ac_cv_path_WC="$WC" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_WC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
WC=$ac_cv_path_WC
if test -n "$WC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $WC" >&5
$as_echo "$WC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_path_WC"; then
ac_pt_WC=$WC
# Extract the first word of "wc", so it can be a program name with args.
set dummy wc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_WC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_WC in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_WC="$ac_pt_WC" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_WC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ac_pt_WC=$ac_cv_path_ac_pt_WC
if test -n "$ac_pt_WC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_WC" >&5
$as_echo "$ac_pt_WC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_pt_WC" = x; then
WC=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
WC=$ac_pt_WC
fi
else
WC="$ac_cv_path_WC"
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}sort", so it can be a program name with args.
set dummy ${ac_tool_prefix}sort; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_SORT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $SORT in
[\\/]* | ?:[\\/]*)
ac_cv_path_SORT="$SORT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_SORT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
SORT=$ac_cv_path_SORT
if test -n "$SORT"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SORT" >&5
$as_echo "$SORT" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_path_SORT"; then
ac_pt_SORT=$SORT
# Extract the first word of "sort", so it can be a program name with args.
set dummy sort; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_SORT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_SORT in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_SORT="$ac_pt_SORT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_SORT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ac_pt_SORT=$ac_cv_path_ac_pt_SORT
if test -n "$ac_pt_SORT"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_SORT" >&5
$as_echo "$ac_pt_SORT" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_pt_SORT" = x; then
SORT=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
SORT=$ac_pt_SORT
fi
else
SORT="$ac_cv_path_SORT"
fi
################################################################################
ac_header_dirent=no
@@ -6172,7 +5876,7 @@ fi
done
for ac_header in termios.h sys/statvfs.h sys/timerfd.h sys/vfs.h linux/magic.h linux/fiemap.h
for ac_header in termios.h sys/statvfs.h sys/timerfd.h linux/magic.h linux/fiemap.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -6365,26 +6069,6 @@ _ACEOF
fi
ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default"
if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRUCT_STAT_ST_BLOCKS 1
_ACEOF
$as_echo "#define HAVE_ST_BLOCKS 1" >>confdefs.h
else
case " $LIBOBJS " in
*" fileblocks.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fileblocks.$ac_objext"
;;
esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
if ${ac_cv_struct_tm+:} false; then :
@@ -9349,11 +9033,6 @@ $as_echo "$as_me: WARNING: $CACHE_CHECK_CMD: Old version \"$CACHE_CHECK_VSN\" fo
CACHE_CHECK_VERSION_WARN=y
CACHE_CHECK_NEEDS_CHECK=no
fi
if test "$CACHE_CHECK_VSN_MINOR" -lt 7 ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $CACHE_CHECK_CMD: Old version \"$CACHE_CHECK_VSN\" does not support new cache format V2" >&5
$as_echo "$as_me: WARNING: $CACHE_CHECK_CMD: Old version \"$CACHE_CHECK_VSN\" does not support new cache format V2" >&2;}
CACHE_CHECK_VERSION_WARN=y
fi
fi
fi
# Empty means a config way to ignore cache dumping
@@ -9716,6 +9395,8 @@ _ACEOF
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable readline" >&5
$as_echo_n "checking whether to enable readline... " >&6; }
# Check whether --enable-readline was given.
if test "${enable_readline+set}" = set; then :
enableval=$enable_readline; READLINE=$enableval
@@ -9723,6 +9404,8 @@ else
READLINE=maybe
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE" >&5
$as_echo "$READLINE" >&6; }
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable realtime support" >&5
@@ -11867,11 +11550,11 @@ $as_echo "$BUILD_LVMPOLLD" >&6; }
################################################################################
BUILD_LVMLOCKD=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockdsanlock" >&5
$as_echo_n "checking whether to build lvmlockdsanlock... " >&6; }
# Check whether --enable-lvmlockd-sanlock was given.
if test "${enable_lvmlockd_sanlock+set}" = set; then :
enableval=$enable_lvmlockd_sanlock; LOCKDSANLOCK=$enableval
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lockdsanlock" >&5
$as_echo_n "checking whether to build lockdsanlock... " >&6; }
# Check whether --enable-lockd-sanlock was given.
if test "${enable_lockd_sanlock+set}" = set; then :
enableval=$enable_lockd_sanlock; LOCKDSANLOCK=$enableval
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDSANLOCK" >&5
@@ -11958,11 +11641,11 @@ $as_echo "#define LOCKDSANLOCK_SUPPORT 1" >>confdefs.h
fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockddlm" >&5
$as_echo_n "checking whether to build lvmlockddlm... " >&6; }
# Check whether --enable-lvmlockd-dlm was given.
if test "${enable_lvmlockd_dlm+set}" = set; then :
enableval=$enable_lvmlockd_dlm; LOCKDDLM=$enableval
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lockddlm" >&5
$as_echo_n "checking whether to build lockddlm... " >&6; }
# Check whether --enable-lockd-dlm was given.
if test "${enable_lockd_dlm+set}" = set; then :
enableval=$enable_lockd_dlm; LOCKDDLM=$enableval
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDDLM" >&5
@@ -12193,55 +11876,28 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build dmfilemapd" >&5
$as_echo_n "checking whether to build dmfilemapd... " >&6; }
# Check whether --enable-dmfilemapd was given.
if test "${enable_dmfilemapd+set}" = set; then :
enableval=$enable_dmfilemapd; BUILD_DMFILEMAPD=$enableval
else
BUILD_DMFILEMAPD=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_DMFILEMAPD" >&5
$as_echo "$BUILD_DMFILEMAPD" >&6; }
$as_echo "#define DMFILEMAPD \$BUILD_DMFILEMAPD" >>confdefs.h
if test "$BUILD_DMFILEMAPD" = yes; then
ac_fn_c_check_header_mongrel "$LINENO" "linux/fiemap.h" "ac_cv_header_linux_fiemap_h" "$ac_includes_default"
if test "x$ac_cv_header_linux_fiemap_h" = xyes; then :
else
as_fn_error $? "--enable-dmfilemapd requires fiemap.h" "$LINENO" 5
fi
fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build notifydbus" >&5
$as_echo_n "checking whether to build notifydbus... " >&6; }
# Check whether --enable-notify-dbus was given.
if test "${enable_notify_dbus+set}" = set; then :
enableval=$enable_notify_dbus; NOTIFYDBUS_SUPPORT=$enableval
else
NOTIFYDBUS_SUPPORT=no
enableval=$enable_notify_dbus; NOTIFYDBUS=$enableval
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $NOTIFYDBUS_SUPPORT" >&5
$as_echo "$NOTIFYDBUS_SUPPORT" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $NOTIFYDBUS" >&5
$as_echo "$NOTIFYDBUS" >&6; }
if test "$NOTIFYDBUS_SUPPORT" = yes; then
BUILD_NOTIFYDBUS=$NOTIFYDBUS
if test "$BUILD_NOTIFYDBUS" = yes; then
$as_echo "#define NOTIFYDBUS_SUPPORT 1" >>confdefs.h
SYSTEMD_LIBS="-lsystemd"
LIBS="-lsystemd $LIBS"
fi
################################################################################
if test "$NOTIFYDBUS_SUPPORT" = yes; then
if test "$BUILD_NOTIFYDBUS" = yes; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NOTIFY_DBUS" >&5
@@ -12317,6 +11973,8 @@ fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable libblkid detection of signatures when wiping" >&5
$as_echo_n "checking whether to enable libblkid detection of signatures when wiping... " >&6; }
# Check whether --enable-blkid_wiping was given.
if test "${enable_blkid_wiping+set}" = set; then :
enableval=$enable_blkid_wiping; BLKID_WIPING=$enableval
@@ -12324,8 +11982,9 @@ else
BLKID_WIPING=maybe
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BLKID_WIPING" >&5
$as_echo "$BLKID_WIPING" >&6; }
DEFAULT_USE_BLKID_WIPING=0
if test "$BLKID_WIPING" != no; then
pkg_config_init
@@ -12405,19 +12064,20 @@ else
BLKID_LIBS=$pkg_cv_BLKID_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
BLKID_WIPING=yes
BLKID_PC="blkid"
DEFAULT_USE_BLKID_WIPING=1
test "$BLKID_WIPING" = maybe && BLKID_WIPING=yes
fi
if test "$BLKID_WIPING" = yes; then
BLKID_PC="blkid"
DEFAULT_USE_BLKID_WIPING=1
$as_echo "#define BLKID_WIPING_SUPPORT 1" >>confdefs.h
else
DEFAULT_USE_BLKID_WIPING=0
fi
else
DEFAULT_USE_BLKID_WIPING=0
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable libblkid detection of signatures when wiping" >&5
$as_echo_n "checking whether to enable libblkid detection of signatures when wiping... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BLKID_WIPING" >&5
$as_echo "$BLKID_WIPING" >&6; }
cat >>confdefs.h <<_ACEOF
#define DEFAULT_USE_BLKID_WIPING $DEFAULT_USE_BLKID_WIPING
@@ -12425,6 +12085,8 @@ _ACEOF
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use udev-systemd protocol for jobs in background" >&5
$as_echo_n "checking whether to use udev-systemd protocol for jobs in background... " >&6; }
# Check whether --enable-udev-systemd-background-jobs was given.
if test "${enable_udev_systemd_background_jobs+set}" = set; then :
enableval=$enable_udev_systemd_background_jobs; UDEV_SYSTEMD_BACKGROUND_JOBS=$enableval
@@ -12432,6 +12094,8 @@ else
UDEV_SYSTEMD_BACKGROUND_JOBS=maybe
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UDEV_SYSTEMD_BACKGROUND_JOBS" >&5
$as_echo "$UDEV_SYSTEMD_BACKGROUND_JOBS" >&6; }
if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" != no; then
pkg_config_init
@@ -12512,15 +12176,10 @@ else
SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
UDEV_SYSTEMD_BACKGROUND_JOBS=yes
test "$UDEV_SYSTEMD_BACKGROUND_JOBS" = maybe && UDEV_SYSTEMD_BACKGROUND_JOBS=yes
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use udev-systemd protocol for jobs in background" >&5
$as_echo_n "checking whether to use udev-systemd protocol for jobs in background... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UDEV_SYSTEMD_BACKGROUND_JOBS" >&5
$as_echo "$UDEV_SYSTEMD_BACKGROUND_JOBS" >&6; }
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable synchronisation with udev processing" >&5
$as_echo_n "checking whether to enable synchronisation with udev processing... " >&6; }
@@ -13916,15 +13575,15 @@ $as_echo "$BLKDEACTIVATE" >&6; }
$as_echo_n "checking whether to use dmeventd... " >&6; }
# Check whether --enable-dmeventd was given.
if test "${enable_dmeventd+set}" = set; then :
enableval=$enable_dmeventd; BUILD_DMEVENTD=$enableval
else
BUILD_DMEVENTD=no
enableval=$enable_dmeventd; DMEVENTD=$enableval
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_DMEVENTD" >&5
$as_echo "$BUILD_DMEVENTD" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DMEVENTD" >&5
$as_echo "$DMEVENTD" >&6; }
if test "$BUILD_DMEVENTD" = yes; then
BUILD_DMEVENTD=$DMEVENTD
if test "$DMEVENTD" = yes; then
if test "$MIRRORS" != internal; then
as_fn_error $? "--enable-dmeventd currently requires --with-mirrors=internal" "$LINENO" 5
fi
@@ -14315,24 +13974,8 @@ fi
fi
################################################################################
RT_LIBS=
HAVE_REALTIME=no
if test "$REALTIME" = yes; then
for ac_func in clock_gettime
do :
ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
if test "x$ac_cv_func_clock_gettime" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_CLOCK_GETTIME 1
_ACEOF
HAVE_REALTIME=yes
fi
done
if test "$HAVE_REALTIME" != yes; then :
# try again with -lrt
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
if ${ac_cv_lib_rt_clock_gettime+:} false; then :
$as_echo_n "(cached) " >&6
@@ -14369,15 +14012,18 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
RT_LIBS="-lrt"; HAVE_REALTIME=yes
HAVE_REALTIME=yes
else
HAVE_REALTIME=no
fi
fi
if test "$HAVE_REALTIME" = yes; then
$as_echo "#define HAVE_REALTIME 1" >>confdefs.h
LIBS="-lrt $LIBS"
RT_LIB="-lrt"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Disabling realtime clock" >&5
$as_echo "$as_me: WARNING: Disabling realtime clock" >&2;}
@@ -14546,8 +14192,7 @@ if test "x$ac_cv_lib_readline_readline" = xyes; then :
$as_echo "#define READLINE_SUPPORT 1" >>confdefs.h
READLINE=yes
LIBS=$lvm_saved_libs
LIBS=$lvm_saved_libs
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_line_buffer in -lreadline" >&5
$as_echo_n "checking for rl_line_buffer in -lreadline... " >&6; }
if ${ac_cv_lib_readline_rl_line_buffer+:} false; then :
@@ -14867,10 +14512,6 @@ fi
done
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable readline" >&5
$as_echo_n "checking whether to enable readline... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE" >&5
$as_echo "$READLINE" >&6; }
if test "$BUILD_CMIRRORD" = yes; then
for ac_func in atexit
@@ -14889,15 +14530,13 @@ done
fi
if test "$BUILD_LVMLOCKD" = yes; then
if test "$HAVE_REALTIME" != yes; then :
as_fn_error $? "Realtime clock support is mandatory for lvmlockd." "$LINENO" 5
fi
for ac_func in strtoull
for ac_func in clock_gettime strtoull
do :
ac_fn_c_check_func "$LINENO" "strtoull" "ac_cv_func_strtoull"
if test "x$ac_cv_func_strtoull" = xyes; then :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRTOULL 1
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
else
@@ -15217,7 +14856,7 @@ done
fi
if test "$BUILD_DMEVENTD" = yes; then
if test "$DMEVENTD" = yes; then
for ac_header in arpa/inet.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default"
@@ -15286,23 +14925,6 @@ done
fi
if test "$BUILD_DMFILEMAPD" = yes; then
for ac_header in sys/inotify.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default"
if test "x$ac_cv_header_sys_inotify_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_SYS_INOTIFY_H 1
_ACEOF
else
hard_bailout
fi
done
fi
################################################################################
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}modprobe", so it can be a program name with args.
@@ -15431,14 +15053,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
FSADM_PATH="$lvm_exec_prefix/sbin/fsadm"
cat >>confdefs.h <<_ACEOF
#define FSADM_PATH "$FSADM_PATH"
_ACEOF
################################################################################
if test "$BUILD_DMEVENTD" = yes; then
@@ -15614,12 +15228,6 @@ LVM_MINOR=`echo "$VER" | $AWK -F '.' '{print $2}'`
LVM_PATCHLEVEL=`echo "$VER" | $AWK -F '[(.]' '{print $3}'`
LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
cat >>confdefs.h <<_ACEOF
#define LVM_CONFIGURE_LINE "$CONFIGURE_LINE"
_ACEOF
################################################################################
@@ -15777,11 +15385,10 @@ _ACEOF
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmfilemapd/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile include/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile include/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -16489,7 +16096,6 @@ do
"daemons/dmeventd/plugins/mirror/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/mirror/Makefile" ;;
"daemons/dmeventd/plugins/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/snapshot/Makefile" ;;
"daemons/dmeventd/plugins/thin/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/thin/Makefile" ;;
"daemons/dmfilemapd/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmfilemapd/Makefile" ;;
"daemons/lvmdbusd/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmdbusd/Makefile" ;;
"daemons/lvmdbusd/path.py") CONFIG_FILES="$CONFIG_FILES daemons/lvmdbusd/path.py" ;;
"daemons/lvmetad/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmetad/Makefile" ;;
@@ -17158,8 +16764,8 @@ $as_echo "$as_me: WARNING: Support for thin provisioning is limited since some t
fi
if test -n "$THIN_CHECK_VERSION_WARN"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You should also install latest thin_check vsn 0.7.0 (or later) for lvm2 thin provisioning" >&5
$as_echo "$as_me: WARNING: You should also install latest thin_check vsn 0.7.0 (or later) for lvm2 thin provisioning" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning" >&5
$as_echo "$as_me: WARNING: You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning" >&2;}
fi
if test -n "$CACHE_CONFIGURE_WARN"; then :
@@ -17167,12 +16773,6 @@ if test -n "$CACHE_CONFIGURE_WARN"; then :
$as_echo "$as_me: WARNING: Support for cache is limited since some cache tools are missing!" >&2;}
fi
if test -n "$CACHE_CHECK_VERSION_WARN"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You should install latest cache_check vsn 0.7.0 to use lvm2 cache metadata format 2" >&5
$as_echo "$as_me: WARNING: You should install latest cache_check vsn 0.7.0 to use lvm2 cache metadata format 2" >&2;}
fi
if test "$ODIRECT" != yes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&5
$as_echo "$as_me: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&2;}

View File

@@ -15,7 +15,6 @@ AC_PREREQ(2.69)
################################################################################
dnl -- Process this file with autoconf to produce a configure script.
AC_INIT
CONFIGURE_LINE="$0 $@"
AC_CONFIG_SRCDIR([lib/device/dev-cache.h])
AC_CONFIG_HEADERS([include/configure.h])
@@ -31,7 +30,6 @@ AS_IF([test -z "$CFLAGS"], [COPTIMISE_FLAG="-O2"])
case "$host_os" in
linux*)
CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym"
# equivalent to -rdynamic
ELDFLAGS="-Wl,--export-dynamic"
# FIXME Generate list and use --dynamic-list=.dlopen.sym
CLDWHOLEARCHIVE="-Wl,-whole-archive"
@@ -85,12 +83,9 @@ AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_MKDIR_P
AC_PROG_RANLIB
AC_CHECK_TOOL(AR, ar)
AC_PATH_TOOL(CFLOW_CMD, cflow)
AC_PATH_TOOL(CSCOPE_CMD, cscope)
AC_PATH_TOOL(CHMOD, chmod)
AC_PATH_TOOL(WC, wc)
AC_PATH_TOOL(SORT, sort)
################################################################################
dnl -- Check for header files.
@@ -108,7 +103,7 @@ AC_CHECK_HEADERS([assert.h ctype.h dirent.h errno.h fcntl.h float.h \
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
unistd.h], , [AC_MSG_ERROR(bailing out)])
AC_CHECK_HEADERS(termios.h sys/statvfs.h sys/timerfd.h sys/vfs.h linux/magic.h linux/fiemap.h)
AC_CHECK_HEADERS(termios.h sys/statvfs.h sys/timerfd.h linux/magic.h linux/fiemap.h)
case "$host_os" in
linux*)
@@ -123,7 +118,6 @@ AC_C_CONST
AC_C_INLINE
AC_CHECK_MEMBERS([struct stat.st_rdev])
AC_CHECK_TYPES([ptrdiff_t])
AC_STRUCT_ST_BLOCKS
AC_STRUCT_TM
AC_TYPE_OFF_T
AC_TYPE_PID_T
@@ -619,10 +613,6 @@ case "$CACHE" in
CACHE_CHECK_VERSION_WARN=y
CACHE_CHECK_NEEDS_CHECK=no
fi
if test "$CACHE_CHECK_VSN_MINOR" -lt 7 ; then
AC_MSG_WARN([$CACHE_CHECK_CMD: Old version "$CACHE_CHECK_VSN" does not support new cache format V2])
CACHE_CHECK_VERSION_WARN=y
fi
fi
fi
# Empty means a config way to ignore cache dumping
@@ -676,9 +666,11 @@ AC_DEFINE_UNQUOTED([CACHE_RESTORE_CMD], ["$CACHE_RESTORE_CMD"],
################################################################################
dnl -- Disable readline
AC_MSG_CHECKING(whether to enable readline)
AC_ARG_ENABLE([readline],
AC_HELP_STRING([--disable-readline], [disable readline support]),
READLINE=$enableval, READLINE=maybe)
AC_MSG_RESULT($READLINE)
################################################################################
dnl -- Disable realtime clock support
@@ -1154,10 +1146,10 @@ AC_MSG_RESULT($BUILD_LVMPOLLD)
################################################################################
BUILD_LVMLOCKD=no
dnl -- Build lvmlockdsanlock
AC_MSG_CHECKING(whether to build lvmlockdsanlock)
AC_ARG_ENABLE(lvmlockd-sanlock,
AC_HELP_STRING([--enable-lvmlockd-sanlock],
dnl -- Build lockdsanlock
AC_MSG_CHECKING(whether to build lockdsanlock)
AC_ARG_ENABLE(lockd-sanlock,
AC_HELP_STRING([--enable-lockd-sanlock],
[enable the LVM lock daemon using sanlock]),
LOCKDSANLOCK=$enableval)
AC_MSG_RESULT($LOCKDSANLOCK)
@@ -1172,10 +1164,10 @@ if test "$BUILD_LOCKDSANLOCK" = yes; then
fi
################################################################################
dnl -- Build lvmlockddlm
AC_MSG_CHECKING(whether to build lvmlockddlm)
AC_ARG_ENABLE(lvmlockd-dlm,
AC_HELP_STRING([--enable-lvmlockd-dlm],
dnl -- Build lockddlm
AC_MSG_CHECKING(whether to build lockddlm)
AC_ARG_ENABLE(lockd-dlm,
AC_HELP_STRING([--enable-lockd-dlm],
[enable the LVM lock daemon using dlm]),
LOCKDDLM=$enableval)
AC_MSG_RESULT($LOCKDDLM)
@@ -1277,80 +1269,75 @@ fi
AC_DEFINE_UNQUOTED(DEFAULT_USE_LVMPOLLD, [$DEFAULT_USE_LVMPOLLD],
[Use lvmpolld by default.])
################################################################################
dnl -- Check dmfilemapd
AC_MSG_CHECKING(whether to build dmfilemapd)
AC_ARG_ENABLE(dmfilemapd, AC_HELP_STRING([--enable-dmfilemapd],
[enable the dmstats filemap daemon]),
BUILD_DMFILEMAPD=$enableval, BUILD_DMFILEMAPD=no)
AC_MSG_RESULT($BUILD_DMFILEMAPD)
AC_DEFINE([DMFILEMAPD], $BUILD_DMFILEMAPD, [Define to 1 to enable the device-mapper filemap daemon.])
dnl -- dmfilemapd requires FIEMAP
if test "$BUILD_DMFILEMAPD" = yes; then
AC_CHECK_HEADER([linux/fiemap.h], , [AC_MSG_ERROR(--enable-dmfilemapd requires fiemap.h)])
fi
################################################################################
dnl -- Build notifydbus
AC_MSG_CHECKING(whether to build notifydbus)
AC_ARG_ENABLE(notify-dbus,
AC_HELP_STRING([--enable-notify-dbus],
[enable LVM notification using dbus]),
NOTIFYDBUS_SUPPORT=$enableval, NOTIFYDBUS_SUPPORT=no)
AC_MSG_RESULT($NOTIFYDBUS_SUPPORT)
NOTIFYDBUS=$enableval)
AC_MSG_RESULT($NOTIFYDBUS)
if test "$NOTIFYDBUS_SUPPORT" = yes; then
BUILD_NOTIFYDBUS=$NOTIFYDBUS
if test "$BUILD_NOTIFYDBUS" = yes; then
AC_DEFINE([NOTIFYDBUS_SUPPORT], 1, [Define to 1 to include code that uses dbus notification.])
SYSTEMD_LIBS="-lsystemd"
LIBS="-lsystemd $LIBS"
fi
################################################################################
dnl -- Look for dbus libraries
if test "$NOTIFYDBUS_SUPPORT" = yes; then
if test "$BUILD_NOTIFYDBUS" = yes; then
PKG_CHECK_MODULES(NOTIFY_DBUS, systemd >= 221, [HAVE_NOTIFY_DBUS=yes], $bailout)
fi
################################################################################
dnl -- Enable blkid wiping functionality
AC_MSG_CHECKING(whether to enable libblkid detection of signatures when wiping)
AC_ARG_ENABLE(blkid_wiping,
AC_HELP_STRING([--disable-blkid_wiping],
[disable libblkid detection of signatures when wiping and use native code instead]),
BLKID_WIPING=$enableval, BLKID_WIPING=maybe)
AC_MSG_RESULT($BLKID_WIPING)
DEFAULT_USE_BLKID_WIPING=0
if test "$BLKID_WIPING" != no; then
pkg_config_init
PKG_CHECK_MODULES(BLKID, blkid >= 2.24,
[ BLKID_WIPING=yes
BLKID_PC="blkid"
DEFAULT_USE_BLKID_WIPING=1
AC_DEFINE([BLKID_WIPING_SUPPORT], 1, [Define to 1 to use libblkid detection of signatures when wiping.])
], [if test "$BLKID_WIPING" = maybe; then
[test "$BLKID_WIPING" = maybe && BLKID_WIPING=yes],
[if test "$BLKID_WIPING" = maybe; then
BLKID_WIPING=no
else
AC_MSG_ERROR([bailing out... blkid library >= 2.24 is required])
fi])
if test "$BLKID_WIPING" = yes; then
BLKID_PC="blkid"
DEFAULT_USE_BLKID_WIPING=1
AC_DEFINE([BLKID_WIPING_SUPPORT], 1, [Define to 1 to use libblkid detection of signatures when wiping.])
else
DEFAULT_USE_BLKID_WIPING=0
fi
else
DEFAULT_USE_BLKID_WIPING=0
fi
AC_MSG_CHECKING([whether to enable libblkid detection of signatures when wiping])
AC_MSG_RESULT($BLKID_WIPING)
AC_DEFINE_UNQUOTED(DEFAULT_USE_BLKID_WIPING, [$DEFAULT_USE_BLKID_WIPING],
[Use blkid wiping by default.])
################################################################################
dnl -- Enable udev-systemd protocol to instantiate a service for background jobs
dnl -- Requires systemd version 205 at least (including support for systemd-run)
AC_MSG_CHECKING(whether to use udev-systemd protocol for jobs in background)
AC_ARG_ENABLE(udev-systemd-background-jobs,
AC_HELP_STRING([--disable-udev-systemd-background-jobs],
[disable udev-systemd protocol to instantiate a service for background job]),
UDEV_SYSTEMD_BACKGROUND_JOBS=$enableval,
UDEV_SYSTEMD_BACKGROUND_JOBS=maybe)
AC_MSG_RESULT($UDEV_SYSTEMD_BACKGROUND_JOBS)
if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" != no; then
pkg_config_init
PKG_CHECK_MODULES(SYSTEMD, systemd >= 205,
[UDEV_SYSTEMD_BACKGROUND_JOBS=yes],
[test "$UDEV_SYSTEMD_BACKGROUND_JOBS" = maybe && UDEV_SYSTEMD_BACKGROUND_JOBS=yes],
[if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" = maybe; then
UDEV_SYSTEMD_BACKGROUND_JOBS=no
else
@@ -1358,9 +1345,6 @@ if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" != no; then
fi])
fi
AC_MSG_CHECKING(whether to use udev-systemd protocol for jobs in background)
AC_MSG_RESULT($UDEV_SYSTEMD_BACKGROUND_JOBS)
################################################################################
dnl -- Enable udev synchronisation
AC_MSG_CHECKING(whether to enable synchronisation with udev processing)
@@ -1581,11 +1565,13 @@ dnl -- enable dmeventd handling
AC_MSG_CHECKING(whether to use dmeventd)
AC_ARG_ENABLE(dmeventd, AC_HELP_STRING([--enable-dmeventd],
[enable the device-mapper event daemon]),
BUILD_DMEVENTD=$enableval, BUILD_DMEVENTD=no)
AC_MSG_RESULT($BUILD_DMEVENTD)
DMEVENTD=$enableval)
AC_MSG_RESULT($DMEVENTD)
BUILD_DMEVENTD=$DMEVENTD
dnl -- dmeventd currently requires internal mirror support
if test "$BUILD_DMEVENTD" = yes; then
if test "$DMEVENTD" = yes; then
if test "$MIRRORS" != internal; then
AC_MSG_ERROR([--enable-dmeventd currently requires --with-mirrors=internal])
fi
@@ -1669,16 +1655,13 @@ fi
################################################################################
dnl -- Check for realtime clock support
RT_LIBS=
HAVE_REALTIME=no
if test "$REALTIME" = yes; then
AC_CHECK_FUNCS([clock_gettime], HAVE_REALTIME=yes)
AS_IF([test "$HAVE_REALTIME" != yes], [ # try again with -lrt
AC_CHECK_LIB([rt], [clock_gettime], RT_LIBS="-lrt"; HAVE_REALTIME=yes)])
AC_CHECK_LIB(rt, clock_gettime, HAVE_REALTIME=yes, HAVE_REALTIME=no)
if test "$HAVE_REALTIME" = yes; then
AC_DEFINE([HAVE_REALTIME], 1, [Define to 1 to include support for realtime clock.])
LIBS="-lrt $LIBS"
RT_LIB="-lrt"
else
AC_MSG_WARN(Disabling realtime clock)
fi
@@ -1722,7 +1705,6 @@ Note: (n)curses also seems to work as a substitute for termcap. This was
AC_DEFINE([READLINE_SUPPORT], 1,
[Define to 1 to include the LVM readline shell.])
dnl -- Try only with -lreadline and check for different symbol
READLINE=yes
LIBS=$lvm_saved_libs
AC_CHECK_LIB([readline], [rl_line_buffer],
[ READLINE_LIBS="-lreadline" ], [
@@ -1829,16 +1811,13 @@ dnl -- Ensure additional headers required
if test "$READLINE" = yes; then
AC_CHECK_HEADERS(readline/readline.h readline/history.h,,hard_bailout)
fi
AC_MSG_CHECKING(whether to enable readline)
AC_MSG_RESULT($READLINE)
if test "$BUILD_CMIRRORD" = yes; then
AC_CHECK_FUNCS(atexit,,hard_bailout)
fi
if test "$BUILD_LVMLOCKD" = yes; then
AS_IF([test "$HAVE_REALTIME" != yes], [AC_MSG_ERROR([Realtime clock support is mandatory for lvmlockd.])])
AC_CHECK_FUNCS(strtoull,,hard_bailout)
AC_CHECK_FUNCS(clock_gettime strtoull,,hard_bailout)
fi
if test "$BUILD_LVMPOLLD" = yes; then
@@ -1858,7 +1837,7 @@ if test "$CLUSTER" != none; then
AC_CHECK_FUNCS(socket,,hard_bailout)
fi
if test "$BUILD_DMEVENTD" = yes; then
if test "$DMEVENTD" = yes; then
AC_CHECK_HEADERS(arpa/inet.h,,hard_bailout)
fi
@@ -1874,10 +1853,6 @@ if test "$UDEV_SYNC" = yes; then
AC_CHECK_HEADERS(sys/ipc.h sys/sem.h,,hard_bailout)
fi
if test "$BUILD_DMFILEMAPD" = yes; then
AC_CHECK_HEADERS([sys/inotify.h],,hard_bailout)
fi
################################################################################
AC_PATH_TOOL(MODPROBE_CMD, modprobe)
@@ -1897,10 +1872,6 @@ test "$prefix" != NONE && clvmd_prefix=$prefix
CLVMD_PATH="$clvmd_prefix/sbin/clvmd"
AC_DEFINE_UNQUOTED(CLVMD_PATH, ["$CLVMD_PATH"], [Path to clvmd binary.])
FSADM_PATH="$lvm_exec_prefix/sbin/fsadm"
AC_DEFINE_UNQUOTED(FSADM_PATH, ["$FSADM_PATH"], [Path to fsadm binary.])
################################################################################
dnl -- dmeventd pidfile and executable path
if test "$BUILD_DMEVENTD" = yes; then
@@ -2009,8 +1980,6 @@ LVM_MINOR=`echo "$VER" | $AWK -F '.' '{print $2}'`
LVM_PATCHLEVEL=`echo "$VER" | $AWK -F '[[(.]]' '{print $3}'`
LVM_LIBAPI=`echo "$VER" | $AWK -F '[[()]]' '{print $2}'`
AC_DEFINE_UNQUOTED(LVM_CONFIGURE_LINE, "$CONFIGURE_LINE", [configure command line used])
################################################################################
AC_SUBST(APPLIB)
AC_SUBST(AWK)
@@ -2023,7 +1992,7 @@ AC_SUBST(BUILD_LVMPOLLD)
AC_SUBST(BUILD_LVMLOCKD)
AC_SUBST(BUILD_LOCKDSANLOCK)
AC_SUBST(BUILD_LOCKDDLM)
AC_SUBST(BUILD_DMFILEMAPD)
AC_SUBST(BUILD_NOTIFYDBUS)
AC_SUBST(CACHE)
AC_SUBST(CFLAGS)
AC_SUBST(CFLOW_CMD)
@@ -2070,11 +2039,11 @@ AC_SUBST(DEVMAPPER)
AC_SUBST(DLM_CFLAGS)
AC_SUBST(DLM_LIBS)
AC_SUBST(DL_LIBS)
AC_SUBST(DMEVENTD)
AC_SUBST(DMEVENTD_PATH)
AC_SUBST(DM_LIB_PATCHLEVEL)
AC_SUBST(ELDFLAGS)
AC_SUBST(FSADM)
AC_SUBST(FSADM_PATH)
AC_SUBST(BLKDEACTIVATE)
AC_SUBST(HAVE_LIBDL)
AC_SUBST(HAVE_REALTIME)
@@ -2119,7 +2088,7 @@ AC_SUBST(PYTHON3DIR)
AC_SUBST(QUORUM_CFLAGS)
AC_SUBST(QUORUM_LIBS)
AC_SUBST(RAID)
AC_SUBST(RT_LIBS)
AC_SUBST(RT_LIB)
AC_SUBST(READLINE_LIBS)
AC_SUBST(REPLICATORS)
AC_SUBST(SACKPT_CFLAGS)
@@ -2128,7 +2097,6 @@ AC_SUBST(SALCK_CFLAGS)
AC_SUBST(SALCK_LIBS)
AC_SUBST(SELINUX_LIBS)
AC_SUBST(SELINUX_PC)
AC_SUBST(SYSTEMD_LIBS)
AC_SUBST(SNAPSHOTS)
AC_SUBST(STATICDIR)
AC_SUBST(STATIC_LINK)
@@ -2188,7 +2156,6 @@ daemons/dmeventd/plugins/raid/Makefile
daemons/dmeventd/plugins/mirror/Makefile
daemons/dmeventd/plugins/snapshot/Makefile
daemons/dmeventd/plugins/thin/Makefile
daemons/dmfilemapd/Makefile
daemons/lvmdbusd/Makefile
daemons/lvmdbusd/path.py
daemons/lvmetad/Makefile
@@ -2265,14 +2232,10 @@ AS_IF([test -n "$THIN_CONFIGURE_WARN"],
[AC_MSG_WARN([Support for thin provisioning is limited since some thin provisioning tools are missing!])])
AS_IF([test -n "$THIN_CHECK_VERSION_WARN"],
[AC_MSG_WARN([You should also install latest thin_check vsn 0.7.0 (or later) for lvm2 thin provisioning])])
[AC_MSG_WARN([You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning])])
AS_IF([test -n "$CACHE_CONFIGURE_WARN"],
[AC_MSG_WARN([Support for cache is limited since some cache tools are missing!])])
AS_IF([test -n "$CACHE_CHECK_VERSION_WARN"],
[AC_MSG_WARN([You should install latest cache_check vsn 0.7.0 to use lvm2 cache metadata format 2])])
AS_IF([test "$ODIRECT" != yes],
[AC_MSG_WARN([O_DIRECT disabled: low-memory pvmove may lock up])])

View File

@@ -41,19 +41,6 @@ struct lv_segment *last_seg(const struct logical_volume *lv)
return ((struct lv_segment **)lv)[0];
}
const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile *profile)
{
return "STRING";
}
struct logical_volume *origin_from_cow(const struct logical_volume *lv)
{
if (lv)
return lv;
__coverity_panic__();
}
/* simple_memccpy() from glibc */
void *memccpy(void *dest, const void *src, int c, size_t n)
{
@@ -84,17 +71,6 @@ void model_FD_ZERO(void *fdset)
((long*)fdset)[i] = 0;
}
/* Resent Coverity reports quite weird errors... */
int *__errno_location(void)
{
}
const unsigned short **__ctype_b_loc (void)
{
}
/*
* Added extra pointer check to not need these models,
* for now just keep then in file

View File

@@ -48,12 +48,8 @@ ifeq ("@BUILD_LVMDBUSD@", "yes")
SUBDIRS += lvmdbusd
endif
ifeq ("@BUILD_DMFILEMAPD@", "yes")
SUBDIRS += dmfilemapd
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld lvmlockd lvmdbusd dmfilemapd
SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld lvmlockd lvmdbusd
endif
include $(top_builddir)/make.tmpl

View File

@@ -31,9 +31,9 @@ SALCK_LIBS = @SALCK_LIBS@
SALCK_CFLAGS = @SALCK_CFLAGS@
SOURCES = \
clvmd-command.c\
clvmd.c\
lvm-functions.c\
clvmd-command.c \
clvmd.c \
lvm-functions.c \
refresh_clvmd.c
ifneq (,$(findstring cman,, "@CLVMD@,"))
@@ -72,17 +72,26 @@ endif
TARGETS = \
clvmd
LVMLIBS = $(LVMINTERNAL_LIBS)
ifeq ("@DMEVENTD@", "yes")
LVMLIBS += -ldevmapper-event
endif
include $(top_builddir)/make.tmpl
LIBS += $(LVMINTERNAL_LIBS) -ldevmapper $(PTHREAD_LIBS)
LVMLIBS += -ldevmapper
LIBS += $(PTHREAD_LIBS)
CFLAGS += -fno-strict-aliasing $(EXTRA_EXEC_CFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
INSTALL_TARGETS = \
install_clvmd
clvmd: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) \
-o clvmd $(OBJECTS) $(LMLIBS) $(LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o clvmd $(OBJECTS) \
$(LVMLIBS) $(LMLIBS) $(LIBS)
.PHONY: install_clvmd

View File

@@ -206,7 +206,7 @@ static int lock_vg(struct local_client *client)
lock_mode = ((int) lock_cmd & LCK_TYPE_MASK);
/* lock_flags = args[1]; */
lockname = &args[2];
DEBUGLOG("(%p) doing PRE command LOCK_VG '%s' at %x\n", client, lockname, lock_cmd);
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
if (lock_mode == LCK_UNLOCK) {
if (!(lkid = (int) (long) dm_hash_lookup(lock_hash, lockname)))
@@ -323,7 +323,7 @@ void cmd_client_cleanup(struct local_client *client)
int lkid;
char *lockname;
DEBUGLOG("(%p) Client thread cleanup\n", client);
DEBUGLOG("Client thread cleanup (%p)\n", client);
if (!client->bits.localsock.private)
return;
@@ -332,7 +332,7 @@ void cmd_client_cleanup(struct local_client *client)
dm_hash_iterate(v, lock_hash) {
lkid = (int)(long)dm_hash_get_data(lock_hash, v);
lockname = dm_hash_get_key(lock_hash, v);
DEBUGLOG("(%p) Cleanup: Unlocking lock %s %x\n", client, lockname, lkid);
DEBUGLOG("Cleanup (%p): Unlocking lock %s %x\n", client, lockname, lkid);
(void) sync_unlock(lockname, lkid);
}

View File

@@ -425,6 +425,8 @@ static void _add_up_node(const char *csid)
DEBUGLOG("openais_add_up_node %d\n", ninfo->nodeid);
ninfo->state = NODE_CLVMD;
return;
}
/* Call a callback for each node, so the caller knows whether it's up or down */

View File

@@ -58,7 +58,6 @@
/* Head of the fd list. Also contains
the cluster_socket details */
static struct local_client local_client_head;
static int _local_client_count = 0;
static unsigned short global_xid = 0; /* Last transaction ID issued */
@@ -69,37 +68,6 @@ static unsigned max_csid_len;
static unsigned max_cluster_message;
static unsigned max_cluster_member_name_len;
static void _add_client(struct local_client *new_client, struct local_client *existing_client)
{
_local_client_count++;
DEBUGLOG("(%p) Adding listener for fd %d. (Now %d monitored fds.)\n", new_client, new_client->fd, _local_client_count);
new_client->next = existing_client->next;
existing_client->next = new_client;
}
int add_client(struct local_client *new_client)
{
_add_client(new_client, &local_client_head);
return 0;
}
/* Returns 0 if delfd is found and removed from list */
static int _del_client(struct local_client *delfd)
{
struct local_client *lastfd, *thisfd;
for (lastfd = &local_client_head; (thisfd = lastfd->next); lastfd = thisfd)
if (thisfd == delfd) {
DEBUGLOG("(%p) Removing listener for fd %d\n", thisfd, thisfd->fd);
lastfd->next = delfd->next;
_local_client_count--;
return 0;
}
return 1;
}
/* Structure of items on the LVM thread list */
struct lvm_thread_cmd {
struct dm_list list;
@@ -124,7 +92,6 @@ static const size_t STACK_SIZE = 128 * 1024;
static pthread_attr_t stack_attr;
static int lvm_thread_exit = 0;
static pthread_mutex_t lvm_thread_mutex;
static pthread_mutex_t _debuglog_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t lvm_thread_cond;
static pthread_barrier_t lvm_start_barrier;
static struct dm_list lvm_cmd_head;
@@ -251,17 +218,14 @@ void debuglog(const char *fmt, ...)
switch (clvmd_get_debug()) {
case DEBUG_STDERR:
pthread_mutex_lock(&_debuglog_mutex);
va_start(ap,fmt);
time(&P);
fprintf(stderr, "CLVMD[%x]: %.15s ", (int)pthread_self(), ctime_r(&P, buf_ctime) + 4);
vfprintf(stderr, fmt, ap);
va_end(ap);
fflush(stderr);
pthread_mutex_unlock(&_debuglog_mutex);
break;
case DEBUG_SYSLOG:
pthread_mutex_lock(&_debuglog_mutex);
if (!syslog_init) {
openlog("clvmd", LOG_PID, LOG_DAEMON);
syslog_init = 1;
@@ -270,7 +234,6 @@ void debuglog(const char *fmt, ...)
va_start(ap,fmt);
vsyslog(LOG_DEBUG, fmt, ap);
va_end(ap);
pthread_mutex_unlock(&_debuglog_mutex);
break;
case DEBUG_OFF:
break;
@@ -554,7 +517,7 @@ int main(int argc, char *argv[])
/* Initialise the LVM thread variables */
dm_list_init(&lvm_cmd_head);
if (pthread_attr_init(&stack_attr) ||
pthread_attr_setstacksize(&stack_attr, STACK_SIZE + getpagesize())) {
pthread_attr_setstacksize(&stack_attr, STACK_SIZE)) {
log_sys_error("pthread_attr_init", "");
exit(1);
}
@@ -621,7 +584,6 @@ int main(int argc, char *argv[])
local_client_head.fd = clops->get_main_cluster_fd();
local_client_head.type = CLUSTER_MAIN_SOCK;
local_client_head.callback = clops->cluster_fd_callback;
_local_client_count++;
/* Add the local socket to the list */
if (!(newfd = dm_zalloc(sizeof(struct local_client)))) {
@@ -632,14 +594,14 @@ int main(int argc, char *argv[])
newfd->fd = local_sock;
newfd->type = LOCAL_RENDEZVOUS;
newfd->callback = local_rendezvous_callback;
(void) add_client(newfd);
newfd->next = local_client_head.next;
local_client_head.next = newfd;
/* This needs to be started after cluster initialisation
as it may need to take out locks */
DEBUGLOG("Starting LVM thread\n");
DEBUGLOG("(%p) Main cluster socket fd %d with local socket %d (%p)\n",
&local_client_head, local_client_head.fd, newfd->fd, newfd);
DEBUGLOG("Main cluster socket fd %d (%p) with local socket %d (%p)\n",
local_client_head.fd, &local_client_head, newfd->fd, newfd);
/* Don't let anyone else to do work until we are started */
if (pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params)) {
@@ -675,7 +637,6 @@ int main(int argc, char *argv[])
while ((delfd = local_client_head.next)) {
local_client_head.next = delfd->next;
_local_client_count--;
/* Failing cleanup_zombie leaks... */
if (delfd->type == LOCAL_SOCK && !cleanup_zombie(delfd))
cmd_client_cleanup(delfd); /* calls sync_unlock */
@@ -737,13 +698,13 @@ static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
pthread_mutex_init(&newfd->bits.localsock.mutex, NULL);
if (fcntl(client_fd, F_SETFD, 1))
DEBUGLOG("(%p) Setting CLOEXEC on client fd %d failed: %s\n", thisfd, client_fd, strerror(errno));
DEBUGLOG("Setting CLOEXEC on client fd failed: %s\n", strerror(errno));
newfd->fd = client_fd;
newfd->type = LOCAL_SOCK;
newfd->callback = local_sock_callback;
newfd->bits.localsock.all_success = 1;
DEBUGLOG("(%p) Got new connection on fd %d\n", newfd, newfd->fd);
DEBUGLOG("Got new connection on fd %d (%p)\n", newfd->fd, newfd);
*new_client = newfd;
}
return 1;
@@ -765,8 +726,8 @@ static int local_pipe_callback(struct local_client *thisfd, char *buf,
if (len == sizeof(int))
memcpy(&status, buffer, sizeof(int));
DEBUGLOG("(%p) Read on pipe %d, %d bytes, status %d\n",
thisfd, thisfd->fd, len, status);
DEBUGLOG("Read on pipe %d, %d bytes, status %d\n",
thisfd->fd, len, status);
/* EOF on pipe or an error, close it */
if (len <= 0) {
@@ -789,11 +750,11 @@ static int local_pipe_callback(struct local_client *thisfd, char *buf,
}
return -1;
} else {
DEBUGLOG("(%p) Background routine status was %d, sock_client %p\n",
thisfd, status, sock_client);
DEBUGLOG("Background routine status was %d, sock_client (%p)\n",
status, sock_client);
/* But has the client gone away ?? */
if (!sock_client) {
DEBUGLOG("(%p) Got pipe response for dead client, ignoring it\n", thisfd);
DEBUGLOG("Got pipe response for dead client, ignoring it\n");
} else {
/* If error then just return that code */
if (status)
@@ -833,7 +794,7 @@ static void timedout_callback(struct local_client *client, const char *csid,
return;
clops->name_from_csid(csid, nodename);
DEBUGLOG("(%p) Checking for a reply from %s\n", client, nodename);
DEBUGLOG("Checking for a reply from %s\n", nodename);
pthread_mutex_lock(&client->bits.localsock.mutex);
reply = client->bits.localsock.replies;
@@ -843,7 +804,7 @@ static void timedout_callback(struct local_client *client, const char *csid,
pthread_mutex_unlock(&client->bits.localsock.mutex);
if (!reply) {
DEBUGLOG("(%p) Node %s timed-out\n", client, nodename);
DEBUGLOG("Node %s timed-out\n", nodename);
add_reply_to_list(client, ETIMEDOUT, csid,
"Command timed out", 18);
}
@@ -858,7 +819,7 @@ static void timedout_callback(struct local_client *client, const char *csid,
*/
static void request_timed_out(struct local_client *client)
{
DEBUGLOG("(%p) Request timed-out. padding\n", client);
DEBUGLOG("Request timed-out. padding\n");
clops->cluster_do_node_callback(client, timedout_callback);
if (!client->bits.localsock.threadid)
@@ -892,11 +853,13 @@ static void main_loop(int cmd_timeout)
while (!quit) {
fd_set in;
int select_status;
struct local_client *thisfd, *nextfd;
struct local_client *thisfd;
struct timeval tv = { cmd_timeout, 0 };
int quorate = clops->is_quorate();
int client_count = 0;
int max_fd = 0;
struct local_client *lastfd = &local_client_head;
struct local_client *nextfd = local_client_head.next;
/* Wait on the cluster FD and all local sockets/pipes */
local_client_head.fd = clops->get_main_cluster_fd();
@@ -912,22 +875,21 @@ static void main_loop(int cmd_timeout)
fprintf(stderr, "WARNING: Your cluster may freeze up if the number of clvmd file descriptors (%d) exceeds %d.\n", max_fd + 1, FD_SETSIZE);
}
for (thisfd = &local_client_head; thisfd; thisfd = nextfd) {
nextfd = thisfd->next;
for (thisfd = &local_client_head; thisfd; thisfd = nextfd, nextfd = thisfd ? thisfd->next : NULL) {
if (thisfd->removeme && !cleanup_zombie(thisfd)) {
/* cleanup_zombie might have removed the next list element */
nextfd = thisfd->next;
(void) _del_client(thisfd);
DEBUGLOG("(%p) removeme set with %d monitored fds remaining\n", thisfd, _local_client_count);
struct local_client *free_fd = thisfd;
lastfd->next = nextfd;
DEBUGLOG("removeme set for %p with %d monitored fds remaining\n", free_fd, client_count - 1);
/* Queue cleanup, this also frees the client struct */
add_to_lvmqueue(thisfd, NULL, 0, NULL);
add_to_lvmqueue(free_fd, NULL, 0, NULL);
continue;
}
lastfd = thisfd;
if (thisfd->removeme)
continue;
@@ -977,15 +939,16 @@ static void main_loop(int cmd_timeout)
type == CLUSTER_INTERNAL)
goto closedown;
DEBUGLOG("(%p) ret == %d, errno = %d. removing client\n",
thisfd, ret, errno);
DEBUGLOG("ret == %d, errno = %d. removing client\n",
ret, errno);
thisfd->removeme = 1;
continue;
}
/* New client...simply add it to the list */
if (newfd) {
_add_client(newfd, thisfd);
newfd->next = thisfd->next;
thisfd->next = newfd;
thisfd = newfd;
}
}
@@ -1003,8 +966,8 @@ static void main_loop(int cmd_timeout)
thisfd->bits.localsock.expected_replies !=
thisfd->bits.localsock.num_replies) {
/* Send timed out message + replies we already have */
DEBUGLOG("Request to client %p timed-out (send: %ld, now: %ld)\n",
thisfd, thisfd->bits.localsock.sent_time, the_time);
DEBUGLOG("Request timed-out (send: %ld, now: %ld)\n",
thisfd->bits.localsock.sent_time, the_time);
thisfd->bits.localsock.all_success = 0;
@@ -1216,8 +1179,8 @@ static int cleanup_zombie(struct local_client *thisfd)
if (!thisfd->bits.localsock.cleanup_needed)
return 0;
DEBUGLOG("(%p) EOF on local socket %d: inprogress=%d\n",
thisfd, thisfd->fd, thisfd->bits.localsock.in_progress);
DEBUGLOG("EOF on local socket: inprogress=%d\n",
thisfd->bits.localsock.in_progress);
if ((pipe_client = thisfd->bits.localsock.pipe_client))
pipe_client = pipe_client->bits.pipe.client;
@@ -1239,7 +1202,7 @@ static int cleanup_zombie(struct local_client *thisfd)
/* Kill the subthread & free resources */
if (thisfd->bits.localsock.threadid) {
DEBUGLOG("(%p) Waiting for pre&post thread\n", pipe_client);
DEBUGLOG("Waiting for pre&post thread (%p)\n", pipe_client);
pthread_mutex_lock(&thisfd->bits.localsock.mutex);
thisfd->bits.localsock.state = PRE_COMMAND;
thisfd->bits.localsock.finished = 1;
@@ -1250,22 +1213,26 @@ static int cleanup_zombie(struct local_client *thisfd)
(void **) &status)))
log_sys_error("pthread_join", "");
DEBUGLOG("(%p) Joined pre&post thread\n", pipe_client);
DEBUGLOG("Joined pre&post thread\n");
thisfd->bits.localsock.threadid = 0;
/* Remove the pipe client */
if (thisfd->bits.localsock.pipe_client) {
struct local_client *delfd = thisfd->bits.localsock.pipe_client;
struct local_client *delfd;
struct local_client *lastfd;
(void) close(delfd->fd); /* Close pipe */
(void) close(thisfd->bits.localsock.pipe_client->fd); /* Close pipe */
(void) close(thisfd->bits.localsock.pipe);
/* Remove pipe client */
if (!_del_client(delfd)) {
dm_free(delfd);
thisfd->bits.localsock.pipe_client = NULL;
}
for (lastfd = &local_client_head; (delfd = lastfd->next); lastfd = delfd)
if (thisfd->bits.localsock.pipe_client == delfd) {
thisfd->bits.localsock.pipe_client = NULL;
lastfd->next = delfd->next;
dm_free(delfd);
break;
}
}
}
@@ -1296,7 +1263,7 @@ static int read_from_local_sock(struct local_client *thisfd)
if (len == -1 && errno == EINTR)
return 1;
DEBUGLOG("(%p) Read on local socket %d, len = %d\n", thisfd, thisfd->fd, len);
DEBUGLOG("Read on local socket %d, len = %d\n", thisfd->fd, len);
if (len && verify_message(buffer, len) < 0) {
log_error("read_from_local_sock from %d len %d bad verify.",
@@ -1370,15 +1337,15 @@ static int read_from_local_sock(struct local_client *thisfd)
char *argptr = inheader->node + strlen(inheader->node) + 1;
while (missing_len > 0) {
DEBUGLOG("(%p) got %d bytes, need another %d (total %d)\n",
thisfd, argslen, missing_len, inheader->arglen);
DEBUGLOG("got %d bytes, need another %d (total %d)\n",
argslen, missing_len, inheader->arglen);
len = read(thisfd->fd, argptr + argslen, missing_len);
if (len == -1 && errno == EINTR)
continue;
if (len <= 0) {
/* EOF or error on socket */
DEBUGLOG("(%p) EOF on local socket\n", thisfd);
DEBUGLOG("EOF on local socket\n");
dm_free(thisfd->bits.localsock.cmd);
thisfd->bits.localsock.cmd = NULL;
return 0;
@@ -1406,7 +1373,7 @@ static int read_from_local_sock(struct local_client *thisfd)
.status = ENOENT
};
DEBUGLOG("(%p) Unknown node: '%s'\n", thisfd, inheader->node);
DEBUGLOG("Unknown node: '%s'\n", inheader->node);
send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
"Error sending ENOENT reply to local user");
thisfd->bits.localsock.expected_replies = 0;
@@ -1432,7 +1399,7 @@ static int read_from_local_sock(struct local_client *thisfd)
.status = EBUSY
};
DEBUGLOG("(%p) Creating pipe failed: %s\n", thisfd, strerror(errno));
DEBUGLOG("Creating pipe failed: %s\n", strerror(errno));
send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
"Error sending EBUSY reply to local user");
return len;
@@ -1452,7 +1419,7 @@ static int read_from_local_sock(struct local_client *thisfd)
return len;
}
DEBUGLOG("(%p) Creating pipe, [%d, %d]\n", thisfd, comms_pipe[0], comms_pipe[1]);
DEBUGLOG("Creating pipe, [%d, %d]\n", comms_pipe[0], comms_pipe[1]);
if (fcntl(comms_pipe[0], F_SETFD, 1))
DEBUGLOG("setting CLOEXEC on pipe[0] failed: %s\n", strerror(errno));
@@ -1463,8 +1430,8 @@ static int read_from_local_sock(struct local_client *thisfd)
newfd->type = THREAD_PIPE;
newfd->callback = local_pipe_callback;
newfd->bits.pipe.client = thisfd;
_add_client(newfd, thisfd);
newfd->next = thisfd->next;
thisfd->next = newfd;
/* Store a cross link to the pipe */
thisfd->bits.localsock.pipe_client = newfd;
@@ -1477,10 +1444,10 @@ static int read_from_local_sock(struct local_client *thisfd)
thisfd->bits.localsock.in_progress = TRUE;
thisfd->bits.localsock.state = PRE_COMMAND;
thisfd->bits.localsock.cleanup_needed = 1;
DEBUGLOG("(%p) Creating pre&post thread for pipe fd %d\n", newfd, newfd->fd);
DEBUGLOG("Creating pre&post thread for pipe fd %d (%p)\n", newfd->fd, newfd);
status = pthread_create(&thisfd->bits.localsock.threadid,
&stack_attr, pre_and_post_thread, thisfd);
DEBUGLOG("(%p) Created pre&post thread, state = %d\n", newfd, status);
DEBUGLOG("Created pre&post thread, state = %d\n", status);
return len;
}
@@ -1488,6 +1455,13 @@ static int read_from_local_sock(struct local_client *thisfd)
/* Add a file descriptor from the cluster or comms interface to
our list of FDs for select
*/
int add_client(struct local_client *new_client)
{
new_client->next = local_client_head.next;
local_client_head.next = new_client;
return 0;
}
/* Called when the pre-command has completed successfully - we
now execute the real command on all the requested nodes */
@@ -1498,8 +1472,8 @@ static int distribute_command(struct local_client *thisfd)
int len = thisfd->bits.localsock.cmd_len;
thisfd->xid = global_xid++;
DEBUGLOG("(%p) distribute command: XID = %d, flags=0x%x (%s%s)\n",
thisfd, thisfd->xid, inheader->flags,
DEBUGLOG("distribute command: XID = %d, flags=0x%x (%s%s)\n",
thisfd->xid, inheader->flags,
(inheader->flags & CLVMD_FLAG_LOCAL) ? "LOCAL" : "",
(inheader->flags & CLVMD_FLAG_REMOTE) ? "REMOTE" : "");
@@ -1521,7 +1495,7 @@ static int distribute_command(struct local_client *thisfd)
*/
add_to_lvmqueue(thisfd, inheader, len, NULL);
DEBUGLOG("(%p) Sending message to all cluster nodes\n", thisfd);
DEBUGLOG("Sending message to all cluster nodes\n");
inheader->xid = thisfd->xid;
send_message(inheader, len, NULL, -1,
"Error forwarding message to cluster");
@@ -1540,11 +1514,11 @@ static int distribute_command(struct local_client *thisfd)
/* Are we the requested node ?? */
if (memcmp(csid, our_csid, max_csid_len) == 0) {
DEBUGLOG("(%p) Doing command on local node only\n", thisfd);
DEBUGLOG("Doing command on local node only\n");
add_to_lvmqueue(thisfd, inheader, len, NULL);
} else {
DEBUGLOG("(%p) Sending message to single node: %s\n",
thisfd, inheader->node);
DEBUGLOG("Sending message to single node: %s\n",
inheader->node);
inheader->xid = thisfd->xid;
send_message(inheader, len, csid, -1,
"Error forwarding message to cluster node");
@@ -1555,7 +1529,7 @@ static int distribute_command(struct local_client *thisfd)
thisfd->bits.localsock.in_progress = TRUE;
thisfd->bits.localsock.expected_replies = 1;
thisfd->bits.localsock.num_replies = 0;
DEBUGLOG("(%p) Doing command explicitly on local node only\n", thisfd);
DEBUGLOG("Doing command explicitly on local node only\n");
add_to_lvmqueue(thisfd, inheader, len, NULL);
}
@@ -1681,7 +1655,7 @@ static void add_reply_to_list(struct local_client *client, int status,
reply->status = status;
clops->name_from_csid(csid, reply->node);
DEBUGLOG("(%p) Reply from node %s: %d bytes\n", client, reply->node, len);
DEBUGLOG("Reply from node %s: %d bytes\n", reply->node, len);
if (len > 0) {
if (!(reply->replymsg = dm_malloc(len)))
@@ -1708,8 +1682,8 @@ static void add_reply_to_list(struct local_client *client, int status,
client->bits.localsock.state = POST_COMMAND;
pthread_cond_signal(&client->bits.localsock.cond);
}
DEBUGLOG("(%p) Got %d replies, expecting: %d\n",
client, client->bits.localsock.num_replies,
DEBUGLOG("Got %d replies, expecting: %d\n",
client->bits.localsock.num_replies,
client->bits.localsock.expected_replies);
}
pthread_mutex_unlock(&client->bits.localsock.mutex);
@@ -1724,7 +1698,7 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
sigset_t ss;
int pipe_fd = client->bits.localsock.pipe;
DEBUGLOG("(%p) Pre&post thread pipe fd %d\n", client, pipe_fd);
DEBUGLOG("Pre&post thread (%p), pipe fd %d\n", client, pipe_fd);
pthread_mutex_lock(&client->bits.localsock.mutex);
/* Ignore SIGUSR1 (handled by master process) but enable
@@ -1744,7 +1718,7 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
if ((status = do_pre_command(client)))
client->bits.localsock.all_success = 0;
DEBUGLOG("(%p) Pre&post thread writes status %d down to pipe fd %d\n",
DEBUGLOG("Pre&post thread (%p) writes status %d down to pipe fd %d\n",
client, status, pipe_fd);
/* Tell the parent process we have finished this bit */
@@ -1762,13 +1736,13 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
/* We may need to wait for the condition variable before running the post command */
if (client->bits.localsock.state != POST_COMMAND &&
!client->bits.localsock.finished) {
DEBUGLOG("(%p) Pre&post thread waiting to do post command, state = %d\n",
DEBUGLOG("Pre&post thread (%p) waiting to do post command, state = %d\n",
client, client->bits.localsock.state);
pthread_cond_wait(&client->bits.localsock.cond,
&client->bits.localsock.mutex);
}
DEBUGLOG("(%p) Pre&post thread got post command condition...\n", client);
DEBUGLOG("Pre&post thread (%p) got post command condition...\n", client);
/* POST function must always run, even if the client aborts */
status = 0;
@@ -1782,15 +1756,15 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
next_pre:
if (client->bits.localsock.state != PRE_COMMAND &&
!client->bits.localsock.finished) {
DEBUGLOG("(%p) Pre&post thread waiting for next pre command\n", client);
DEBUGLOG("Pre&post thread (%p) waiting for next pre command\n", client);
pthread_cond_wait(&client->bits.localsock.cond,
&client->bits.localsock.mutex);
}
DEBUGLOG("(%p) Pre&post thread got pre command condition...\n", client);
DEBUGLOG("Pre&post thread (%p) got pre command condition...\n", client);
}
pthread_mutex_unlock(&client->bits.localsock.mutex);
DEBUGLOG("(%p) Pre&post thread finished\n", client);
DEBUGLOG("Pre&post thread (%p) finished\n", client);
pthread_exit(NULL);
}
@@ -1808,8 +1782,8 @@ static int process_local_command(struct clvm_header *msg, int msglen,
if (!(replybuf = dm_malloc(max_cluster_message)))
return -1;
DEBUGLOG("(%p) process_local_command: %s msg=%p, msglen =%d\n",
client, decode_cmd(msg->cmd), msg, msglen);
DEBUGLOG("process_local_command: %s msg=%p, msglen =%d, client=%p\n",
decode_cmd(msg->cmd), msg, msglen, client);
/* If remote flag is set, just set a successful status code. */
if (msg->flags & CLVMD_FLAG_REMOTE)
@@ -1824,8 +1798,8 @@ static int process_local_command(struct clvm_header *msg, int msglen,
if (xid == client->xid)
add_reply_to_list(client, status, our_csid, replybuf, replylen);
else
DEBUGLOG("(%p) Local command took too long, discarding xid %d, current is %d\n",
client, xid, client->xid);
DEBUGLOG("Local command took too long, discarding xid %d, current is %d\n",
xid, client->xid);
dm_free(replybuf);
@@ -1867,7 +1841,7 @@ static void send_local_reply(struct local_client *client, int status, int fd)
char *ptr;
int message_len = 0;
DEBUGLOG("(%p) Send local reply\n", client);
DEBUGLOG("Send local reply\n");
/* Work out the total size of the reply */
while (thisreply) {
@@ -1884,7 +1858,7 @@ static void send_local_reply(struct local_client *client, int status, int fd)
/* Add in the size of our header */
message_len = message_len + sizeof(struct clvm_header);
if (!(replybuf = dm_malloc(message_len))) {
DEBUGLOG("(%p) Memory allocation fails\n", client);
DEBUGLOG("Memory allocation fails\n");
return;
}
@@ -2013,7 +1987,6 @@ static int send_message(void *buf, int msglen, const char *csid, int fd,
(void) nanosleep (&delay, &remtime);
continue;
}
DEBUGLOG("%s", errtext);
log_error("%s", errtext);
break;
}
@@ -2027,7 +2000,7 @@ static int process_work_item(struct lvm_thread_cmd *cmd)
{
/* If msg is NULL then this is a cleanup request */
if (cmd->msg == NULL) {
DEBUGLOG("(%p) process_work_item: free\n", cmd->client);
DEBUGLOG("process_work_item: free %p\n", cmd->client);
cmd_client_cleanup(cmd->client);
pthread_mutex_destroy(&cmd->client->bits.localsock.mutex);
pthread_cond_destroy(&cmd->client->bits.localsock.cond);
@@ -2036,11 +2009,11 @@ static int process_work_item(struct lvm_thread_cmd *cmd)
}
if (!cmd->remote) {
DEBUGLOG("(%p) process_work_item: local\n", cmd->client);
DEBUGLOG("process_work_item: local\n");
process_local_command(cmd->msg, cmd->msglen, cmd->client,
cmd->xid);
} else {
DEBUGLOG("(%p) process_work_item: remote\n", cmd->client);
DEBUGLOG("process_work_item: remote\n");
process_remote_command(cmd->msg, cmd->msglen, cmd->client->fd,
cmd->csid);
}
@@ -2134,8 +2107,8 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
} else
cmd->remote = 0;
DEBUGLOG("(%p) add_to_lvmqueue: cmd=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
client, cmd, msg, msglen, csid, cmd->xid);
DEBUGLOG("add_to_lvmqueue: cmd=%p. client=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
cmd, client, msg, msglen, csid, cmd->xid);
pthread_mutex_lock(&lvm_thread_mutex);
if (lvm_thread_exit) {
pthread_mutex_unlock(&lvm_thread_mutex);
@@ -2271,8 +2244,7 @@ static void check_all_callback(struct local_client *client, const char *csid,
If not, returns -1 and prints out a list of errant nodes */
static int check_all_clvmds_running(struct local_client *client)
{
DEBUGLOG("(%p) check_all_clvmds_running\n", client);
DEBUGLOG("check_all_clvmds_running\n");
return clops->cluster_do_node_callback(client, check_all_callback);
}
@@ -2311,11 +2283,13 @@ static void ntoh_clvm(struct clvm_header *hdr)
static void sigusr2_handler(int sig)
{
DEBUGLOG("SIGUSR2 received\n");
return;
}
static void sigterm_handler(int sig)
{
quit = 1;
return;
}
static void sighup_handler(int sig)

View File

@@ -29,7 +29,7 @@ include $(top_builddir)/make.tmpl
LIBS += -ldevmapper
LMLIBS += $(CPG_LIBS) $(SACKPT_LIBS)
CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS) $(EXTRA_EXEC_CFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
cmirrord: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \

View File

@@ -182,7 +182,7 @@ int cluster_send(struct clog_request *rq)
}
/*
* Once the request heads for the cluster, the luid loses
* Once the request heads for the cluster, the luid looses
* all its meaning.
*/
rq->u_rq.luid = 0;

View File

@@ -377,7 +377,7 @@ static int _clog_ctr(char *uuid, uint64_t luid,
uint32_t block_on_error = 0;
int disk_log;
char disk_path[PATH_MAX];
char disk_path[128];
int unlink_path = 0;
long page_size;
int pages;

View File

@@ -56,16 +56,18 @@ include $(top_builddir)/make.tmpl
all: device-mapper
device-mapper: $(TARGETS)
LIBS += -ldevmapper
LVMLIBS += -ldevmapper-event $(PTHREAD_LIBS)
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
LIBS += -ldevmapper $(PTHREAD_LIBS)
dmeventd: $(LIB_SHARED) dmeventd.o
$(CC) $(CFLAGS) -L. $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) dmeventd.o \
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) -L. -o $@ dmeventd.o \
$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
dmeventd.static: $(LIB_STATIC) dmeventd.o $(interfacebuilddir)/libdevmapper.a
$(CC) $(CFLAGS) $(LDFLAGS) -static -L. -L$(interfacebuilddir) dmeventd.o \
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS) $(STATIC_LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -static -L. -L$(interfacebuilddir) -o $@ \
dmeventd.o $(DL_LIBS) $(LVMLIBS) $(LIBS) $(STATIC_LIBS)
ifeq ("@PKGCONFIG@", "yes")
INSTALL_LIB_TARGETS += install_pkgconfig

View File

@@ -468,7 +468,7 @@ static int _pthread_create_smallstack(pthread_t *t, void *(*fun)(void *), void *
/*
* We use a smaller stack since it gets preallocated in its entirety
*/
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE + getpagesize());
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
/*
* If no-one will be waiting, we need to detach.
@@ -2252,8 +2252,7 @@ int main(int argc, char *argv[])
"for %ld second(s), exiting.",
(long) (time(NULL) - _idle_since));
break;
}
if (idle_exit_timeout) {
} else if (idle_exit_timeout) {
now = time(NULL);
if (now < _idle_since)
_idle_since = now; /* clock change? */

View File

@@ -250,9 +250,10 @@ static int _daemon_read(struct dm_event_fifos *fifos,
if (ret < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
log_error("Unable to read from event server.");
return 0;
else {
log_error("Unable to read from event server.");
return 0;
}
}
bytes += ret;
@@ -328,9 +329,10 @@ static int _daemon_write(struct dm_event_fifos *fifos,
if (ret < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
log_error("Unable to talk to event daemon.");
return 0;
else {
log_error("Unable to talk to event daemon.");
return 0;
}
}
bytes += ret;
@@ -452,8 +454,7 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
if (close(fifos->client))
log_sys_debug("close", fifos->client_path);
return 1;
}
if (errno != ENXIO && errno != ENOENT) {
} else if (errno != ENXIO && errno != ENOENT) {
/* problem */
log_sys_error("open", fifos->client_path);
return 0;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -25,6 +25,7 @@
struct dso_state {
struct dm_pool *mem;
char cmd_lvscan[512];
char cmd_lvconvert[512];
};
@@ -98,8 +99,12 @@ static int _get_mirror_event(struct dso_state *state, char *params)
return r;
}
static int _remove_failed_devices(const char *cmd_lvconvert, const char *device)
static int _remove_failed_devices(const char *cmd_lvscan, const char *cmd_lvconvert,
const char *device)
{
if (!dmeventd_lvm2_run_with_lock(cmd_lvscan))
log_warn("WARNING: Re-scan of mirrored device %s failed.", device);
/* if repair goes OK, report success even if lvscan has failed */
if (!dmeventd_lvm2_run_with_lock(cmd_lvconvert)) {
log_error("Repair of mirrored device %s failed.", device);
@@ -146,7 +151,9 @@ void process_event(struct dm_task *dmt,
break;
case ME_FAILURE:
log_error("Device failure in %s.", device);
if (!_remove_failed_devices(state->cmd_lvconvert, device))
if (!_remove_failed_devices(state->cmd_lvscan,
state->cmd_lvconvert,
device))
/* FIXME Why are all the error return codes unused? Get rid of them? */
log_error("Failed to remove faulty devices in %s.",
device);
@@ -176,10 +183,17 @@ int register_device(const char *device,
if (!dmeventd_lvm2_init_with_pool("mirror_state", state))
goto_bad;
/* CANNOT use --config as this disables cached content */
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --repair --use-policies", device))
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
"lvscan --cache", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --repair --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
*user = state;
@@ -189,9 +203,6 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor mirror %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2005-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -22,6 +22,7 @@
struct dso_state {
struct dm_pool *mem;
char cmd_lvscan[512];
char cmd_lvconvert[512];
uint64_t raid_devs[RAID_DEVS_ELEMS];
int failed;
@@ -58,23 +59,6 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
dead = 1;
}
/*
* if we are converting from non-RAID to RAID (e.g. linear -> raid1)
* and too many original devices die, such that we cannot continue
* the "recover" operation, the sync action will go to "idle", the
* unsynced devs will remain at 'a', and the original devices will
* NOT SWITCH TO 'D', but will remain at 'A' - hoping to be revived.
*
* This is simply the way the kernel works...
*/
if (!strcmp(status->sync_action, "idle") &&
(status->dev_health[0] == 'a') &&
(status->insync_regions < status->total_regions)) {
log_error("Primary sources for new RAID, %s, have failed.",
device);
dead = 1; /* run it through LVM repair */
}
if (dead) {
if (status->insync_regions < status->total_regions) {
if (!state->warned) {
@@ -90,6 +74,8 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
goto out; /* already reported */
state->failed = 1;
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvscan))
log_warn("WARNING: Re-scan of RAID device %s failed.", device);
/* if repair goes OK, report success even if lvscan has failed */
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvconvert)) {
@@ -98,8 +84,6 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
}
} else {
state->failed = 0;
if (status->insync_regions == status->total_regions)
memset(&state->raid_devs, 0, sizeof(state->raid_devs));
log_info("%s array, %s, is %s in-sync.",
status->raid_type, device,
(status->insync_regions == status->total_regions) ? "now" : "not");
@@ -152,9 +136,14 @@ int register_device(const char *device,
if (!dmeventd_lvm2_init_with_pool("raid_state", state))
goto_bad;
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --repair --use-policies", device))
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
"lvscan --cache", device) ||
!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
*user = state;
@@ -164,9 +153,6 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor RAID %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -231,7 +231,7 @@ void process_event(struct dm_task *dmt,
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
log_warn("WARNING: Snapshot %s is now %.2f%% full.",
device, dm_percent_to_round_float(percent, 2));
device, dm_percent_to_float(percent));
/* Try to extend the snapshot, in accord with user-set policies */
if (!_extend(state->cmd_lvextend))
@@ -254,8 +254,10 @@ int register_device(const char *device,
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvextend,
sizeof(state->cmd_lvextend),
"lvextend --use-policies", device))
"lvextend --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
state->percent_check = CHECK_MINIMUM;
*user = state;
@@ -266,9 +268,6 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor snapshot %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -18,6 +18,7 @@
#include <sys/wait.h>
#include <stdarg.h>
#include <pthread.h>
/* TODO - move this mountinfo code into library to be reusable */
#ifdef __linux__
@@ -47,8 +48,10 @@ struct dso_state {
struct dm_pool *mem;
int metadata_percent_check;
int metadata_percent;
int metadata_warn_once;
int data_percent_check;
int data_percent;
int data_warn_once;
uint64_t known_metadata_size;
uint64_t known_data_size;
unsigned fails;
@@ -56,8 +59,8 @@ struct dso_state {
int restore_sigset;
sigset_t old_sigset;
pid_t pid;
char *argv[3];
char *cmd_str;
char **argv;
char cmd_str[1024];
};
DM_EVENT_LOG_FN("thin")
@@ -83,7 +86,7 @@ static int _run_command(struct dso_state *state)
} else {
/* For an error event it's for a user to check status and decide */
env[1] = NULL;
log_debug("Error event processing.");
log_debug("Error event processing");
}
log_verbose("Executing command: %s", state->cmd_str);
@@ -113,7 +116,7 @@ static int _use_policy(struct dm_task *dmt, struct dso_state *state)
#if THIN_DEBUG
log_debug("dmeventd executes: %s.", state->cmd_str);
#endif
if (state->argv[0])
if (state->argv)
return _run_command(state);
if (!dmeventd_lvm2_run_with_lock(state->cmd_str)) {
@@ -172,8 +175,8 @@ void process_event(struct dm_task *dmt,
#if THIN_DEBUG
log_debug("Watch for tp-data:%.2f%% tp-metadata:%.2f%%.",
dm_percent_to_round_float(state->data_percent_check, 2),
dm_percent_to_round_float(state->metadata_percent_check, 2));
dm_percent_to_float(state->data_percent_check),
dm_percent_to_float(state->metadata_percent_check));
#endif
if (!_wait_for_pid(state)) {
log_warn("WARNING: Skipping event, child %d is still running (%s).",
@@ -251,10 +254,11 @@ void process_event(struct dm_task *dmt,
* action is called for: >50%, >55% ... >95%, 100%
*/
state->metadata_percent = dm_make_percent(tps->used_metadata_blocks, tps->total_metadata_blocks);
if ((state->metadata_percent > WARNING_THRESH) &&
(state->metadata_percent > state->metadata_percent_check))
if (state->metadata_percent <= WARNING_THRESH)
state->metadata_warn_once = 0; /* Dropped bellow threshold, reset warn once */
else if (!state->metadata_warn_once++) /* Warn once when raised above threshold */
log_warn("WARNING: Thin pool %s metadata is now %.2f%% full.",
device, dm_percent_to_round_float(state->metadata_percent, 2));
device, dm_percent_to_float(state->metadata_percent));
if (state->metadata_percent > CHECK_MINIMUM) {
/* Run action when usage raised more than CHECK_STEP since the last time */
if (state->metadata_percent > state->metadata_percent_check)
@@ -266,10 +270,11 @@ void process_event(struct dm_task *dmt,
state->metadata_percent_check = CHECK_MINIMUM;
state->data_percent = dm_make_percent(tps->used_data_blocks, tps->total_data_blocks);
if ((state->data_percent > WARNING_THRESH) &&
(state->data_percent > state->data_percent_check))
if (state->data_percent <= WARNING_THRESH)
state->data_warn_once = 0;
else if (!state->data_warn_once++)
log_warn("WARNING: Thin pool %s data is now %.2f%% full.",
device, dm_percent_to_round_float(state->data_percent, 2));
device, dm_percent_to_float(state->data_percent));
if (state->data_percent > CHECK_MINIMUM) {
/* Run action when usage raised more than CHECK_STEP since the last time */
if (state->data_percent > state->data_percent_check)
@@ -348,41 +353,34 @@ int register_device(const char *device,
void **user)
{
struct dso_state *state;
int maxcmd;
char *str;
char cmd_str[PATH_MAX + 128 + 2]; /* cmd ' ' vg/lv \0 */
if (!dmeventd_lvm2_init_with_pool("thin_pool_state", state))
goto_bad;
if (!dmeventd_lvm2_command(state->mem, cmd_str, sizeof(cmd_str),
"_dmeventd_thin_command", device))
if (!dmeventd_lvm2_command(state->mem, state->cmd_str,
sizeof(state->cmd_str),
"_dmeventd_thin_command", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
if (strncmp(cmd_str, "lvm ", 4) == 0) {
if (!(state->cmd_str = dm_pool_strdup(state->mem, cmd_str + 4))) {
log_error("Failed to copy lvm command.");
goto bad;
}
} else if (cmd_str[0] == '/') {
if (!(state->cmd_str = dm_pool_strdup(state->mem, cmd_str))) {
log_error("Failed to copy thin command.");
if (strncmp(state->cmd_str, "lvm ", 4)) {
maxcmd = 2; /* space for last NULL element */
for (str = state->cmd_str; *str; str++)
if (*str == ' ')
maxcmd++;
if (!(str = dm_pool_strdup(state->mem, state->cmd_str)) ||
!(state->argv = dm_pool_zalloc(state->mem, maxcmd * sizeof(char *)))) {
log_error("Failed to allocate memory for command.");
goto bad;
}
/* Find last space before 'vg/lv' */
if (!(str = strrchr(state->cmd_str, ' ')))
goto inval;
if (!(state->argv[0] = dm_pool_strndup(state->mem, state->cmd_str,
str - state->cmd_str))) {
log_error("Failed to copy command.");
goto bad;
}
state->argv[1] = str + 1; /* 1 argument - vg/lv */
dm_split_words(str, maxcmd - 1, 0, state->argv);
_init_thread_signals(state);
} else /* Unuspported command format */
goto inval;
} else
memmove(state->cmd_str, state->cmd_str + 4, strlen(state->cmd_str + 4) + 1);
state->pid = -1;
*user = state;
@@ -390,14 +388,9 @@ int register_device(const char *device,
log_info("Monitoring thin pool %s.", device);
return 1;
inval:
log_error("Invalid command for monitoring: %s.", cmd_str);
bad:
log_error("Failed to monitor thin pool %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -1 +0,0 @@
dmfilemapd

View File

@@ -1,66 +0,0 @@
#
# Copyright (C) 2016 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES = dmfilemapd.c
TARGETS = dmfilemapd
.PHONY: install_dmfilemapd install_dmfilemapd_static
INSTALL_DMFILEMAPD_TARGETS = install_dmfilemapd_dynamic
CLEAN_TARGETS = dmfilemapd.static
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
CFLOW_TARGET = dmfilemapd
include $(top_builddir)/make.tmpl
all: device-mapper
device-mapper: $(TARGETS)
CFLAGS_dmfilemapd.o += $(EXTRA_EXEC_CFLAGS)
LIBS += -ldevmapper
dmfilemapd: $(LIB_SHARED) dmfilemapd.o
$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) \
-o $@ dmfilemapd.o $(DL_LIBS) $(LIBS)
dmfilemapd.static: $(LIB_STATIC) dmfilemapd.o $(interfacebuilddir)/libdevmapper.a
$(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -static -L$(interfacebuilddir) \
-o $@ dmfilemapd.o $(DL_LIBS) $(LIBS) $(STATIC_LIBS)
ifneq ("$(CFLOW_CMD)", "")
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
-include $(top_builddir)/libdm/libdevmapper.cflow
-include $(top_builddir)/lib/liblvm-internal.cflow
-include $(top_builddir)/lib/liblvm2cmd.cflow
-include $(top_builddir)/daemons/dmfilemapd/$(LIB_NAME).cflow
endif
install_dmfilemapd_dynamic: dmfilemapd
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_dmfilemapd_static: dmfilemapd.static
$(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
install_dmfilemapd: $(INSTALL_DMFILEMAPD_TARGETS)
install: install_dmfilemapd
install_device-mapper: install_dmfilemapd

View File

@@ -1,834 +0,0 @@
/*
* Copyright (C) 2016 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* It includes tree drawing code based on pstree: http://psmisc.sourceforge.net/
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tool.h"
#include "dm-logging.h"
#include "defaults.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/inotify.h>
#include <dirent.h>
#include <ctype.h>
#ifdef __linux__
# include "kdev_t.h"
#else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
# define MKDEV(x,y) makedev((x),(y))
#endif
/* limit to two updates/sec */
#define FILEMAPD_WAIT_USECS 500000
/* how long to wait for unlinked files */
#define FILEMAPD_NOFILE_WAIT_USECS 100000
#define FILEMAPD_NOFILE_WAIT_TRIES 10
struct filemap_monitor {
dm_filemapd_mode_t mode;
const char *program_id;
uint64_t group_id;
char *path;
int fd;
int inotify_fd;
int inotify_watch_fd;
/* monitoring heuristics */
int64_t blocks; /* allocated blocks, from stat.st_blocks */
uint64_t nr_regions;
int deleted;
};
static int _foreground;
static int _verbose;
const char *const _usage = "dmfilemapd <fd> <group_id> <abs_path> <mode> "
"[<foreground>[<log_level>]]";
/*
* Daemon logging. By default, all messages are thrown away: messages
* are only written to the terminal if the daemon is run in the foreground.
*/
__attribute__((format(printf, 5, 0)))
static void _dmfilemapd_log_line(int level,
const char *file __attribute__((unused)),
int line __attribute__((unused)),
int dm_errno_or_class,
const char *f, va_list ap)
{
static int _abort_on_internal_errors = -1;
FILE *out = log_stderr(level) ? stderr : stdout;
level = log_level(level);
if (level <= _LOG_WARN || _verbose) {
if (level < _LOG_WARN)
out = stderr;
vfprintf(out, f, ap);
fputc('\n', out);
}
if (_abort_on_internal_errors < 0)
/* Set when env DM_ABORT_ON_INTERNAL_ERRORS is not "0" */
_abort_on_internal_errors =
strcmp(getenv("DM_ABORT_ON_INTERNAL_ERRORS") ? : "0", "0");
if (_abort_on_internal_errors &&
!strncmp(f, INTERNAL_ERROR, sizeof(INTERNAL_ERROR) - 1))
abort();
}
__attribute__((format(printf, 5, 6)))
static void _dmfilemapd_log_with_errno(int level,
const char *file, int line,
int dm_errno_or_class,
const char *f, ...)
{
va_list ap;
va_start(ap, f);
_dmfilemapd_log_line(level, file, line, dm_errno_or_class, f, ap);
va_end(ap);
}
/*
* Only used for reporting errors before daemonise().
*/
__attribute__((format(printf, 1, 2)))
static void _early_log(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
va_end(ap);
}
static void _setup_logging(void)
{
dm_log_init_verbose(_verbose - 1);
dm_log_with_errno_init(_dmfilemapd_log_with_errno);
}
#define PROC_FD_DELETED_STR "(deleted)"
/*
* Scan the /proc/<pid>/fd directory for pid and check for an fd
* symlink whose contents match path.
*/
static int _is_open_in_pid(pid_t pid, const char *path)
{
char deleted_path[PATH_MAX + sizeof(PROC_FD_DELETED_STR)];
struct dirent *pid_dp = NULL;
char path_buf[PATH_MAX];
char link_buf[PATH_MAX];
DIR *pid_d = NULL;
ssize_t len;
if (pid == getpid())
return 0;
if (dm_snprintf(path_buf, sizeof(path_buf),
DEFAULT_PROC_DIR "%d/fd", pid) < 0) {
log_error("Could not format pid path.");
return 0;
}
/*
* Test for the kernel 'file (deleted)' form when scanning.
*/
if (dm_snprintf(deleted_path, sizeof(deleted_path), "%s %s",
path, PROC_FD_DELETED_STR) < 0) {
log_error("Could not format check path.");
return 0;
}
pid_d = opendir(path_buf);
if (!pid_d) {
log_error("Could not open proc path: %s.", path_buf);
return 0;
}
while ((pid_dp = readdir(pid_d)) != NULL) {
if (pid_dp->d_name[0] == '.')
continue;
if ((len = readlinkat(dirfd(pid_d), pid_dp->d_name, link_buf,
sizeof(link_buf))) < 0) {
log_error("readlink failed for " DEFAULT_PROC_DIR
"/%d/fd/.", pid);
goto bad;
}
link_buf[len] = '\0';
if (!strcmp(deleted_path, link_buf)) {
if (closedir(pid_d))
log_sys_error("closedir", path_buf);
return 1;
}
}
bad:
if (closedir(pid_d))
log_sys_error("closedir", path_buf);
return 0;
}
/*
* Attempt to determine whether a file is open by any process by
* scanning symbolic links in /proc/<pid>/fd.
*
* This is a heuristic since it cannot guarantee to detect brief
* access in all cases: a process that opens and then closes the
* file rapidly may never be seen by the scan.
*
* The method will also give false-positives if a process exists
* that has a deleted file open that had the same path, but a
* different inode number, to the file being monitored.
*
* For this reason the daemon only uses _is_open() for unlinked
* files when the mode is DM_FILEMAPD_FOLLOW_INODE, since these
* files can no longer be newly opened by processes.
*
* In this situation !is_open(path) provides an indication that
* the daemon should shut down: the file has been unlinked from
* the file system and we appear to hold the final reference.
*/
static int _is_open(const char *path)
{
struct dirent *proc_dp = NULL;
DIR *proc_d = NULL;
pid_t pid;
proc_d = opendir(DEFAULT_PROC_DIR);
if (!proc_d)
return 0;
while ((proc_dp = readdir(proc_d)) != NULL) {
if (!isdigit(proc_dp->d_name[0]))
continue;
errno = 0;
pid = (pid_t) strtol(proc_dp->d_name, NULL, 10);
if (errno || !pid)
continue;
if (_is_open_in_pid(pid, path)) {
if (closedir(proc_d))
log_sys_error("closedir", DEFAULT_PROC_DIR);
return 1;
}
}
if (closedir(proc_d))
log_sys_error("closedir", DEFAULT_PROC_DIR);
return 0;
}
static void _filemap_monitor_wait(uint64_t usecs)
{
if (_verbose) {
if (usecs == FILEMAPD_WAIT_USECS)
log_very_verbose("Waiting for check interval");
if (usecs == FILEMAPD_NOFILE_WAIT_USECS)
log_very_verbose("Waiting for unlinked path");
}
usleep((useconds_t) usecs);
}
static int _parse_args(int argc, char **argv, struct filemap_monitor *fm)
{
char *endptr;
/* we don't care what is in argv[0]. */
argc--;
argv++;
if (argc < 5) {
_early_log("Wrong number of arguments.");
_early_log("usage: %s", _usage);
return 0;
}
/*
* We don't know the true nr_regions at daemon start time,
* and it is not worth a dm_stats_list()/group walk to count:
* we can assume that there is at least one region or the
* daemon would not have been started.
*
* A correct value will be obtained following the first update
* of the group's regions.
*/
fm->nr_regions = 1;
/* parse <fd> */
errno = 0;
fm->fd = (int) strtol(argv[0], &endptr, 10);
if (errno || *endptr) {
_early_log("Could not parse file descriptor: %s", argv[0]);
return 0;
}
argc--;
argv++;
/* parse <group_id> */
errno = 0;
fm->group_id = strtoull(argv[0], &endptr, 10);
if (*endptr || errno) {
_early_log("Could not parse group identifier: %s", argv[0]);
return 0;
}
argc--;
argv++;
/* parse <path> */
if (!argv[0] || !strlen(argv[0])) {
_early_log("Path argument is required.");
return 0;
}
if (*argv[0] != '/') {
_early_log("Path argument must specify an absolute path.");
return 0;
}
fm->path = dm_strdup(argv[0]);
if (!fm->path) {
_early_log("Could not allocate memory for path argument.");
return 0;
}
argc--;
argv++;
/* parse <mode> */
if (!argv[0] || !strlen(argv[0])) {
_early_log("Mode argument is required.");
return 0;
}
fm->mode = dm_filemapd_mode_from_string(argv[0]);
if (fm->mode == DM_FILEMAPD_FOLLOW_NONE)
return 0;
argc--;
argv++;
/* parse [<foreground>[<verbose>]] */
if (argc) {
errno = 0;
_foreground = (int) strtol(argv[0], &endptr, 10);
if (errno || *endptr) {
_early_log("Could not parse debug argument: %s.",
argv[0]);
return 0;
}
argc--;
argv++;
if (argc) {
errno = 0;
_verbose = (int) strtol(argv[0], &endptr, 10);
if (errno || *endptr) {
_early_log("Could not parse verbose "
"argument: %s", argv[0]);
return 0;
}
if (_verbose < 0 || _verbose > 3) {
_early_log("Verbose argument out of range: %d.",
_verbose);
return 0;
}
}
}
return 1;
}
static int _filemap_fd_update_blocks(struct filemap_monitor *fm)
{
struct stat buf;
if (fm->fd < 0) {
log_error("Filemap fd is not open.");
return 0;
}
if (fstat(fm->fd, &buf)) {
log_error("Failed to fstat filemap file descriptor.");
return 0;
}
fm->blocks = buf.st_blocks;
return 1;
}
static int _filemap_fd_check_changed(struct filemap_monitor *fm)
{
int64_t old_blocks;
old_blocks = fm->blocks;
if (!_filemap_fd_update_blocks(fm))
return -1;
return (fm->blocks != old_blocks);
}
static void _filemap_monitor_close_fd(struct filemap_monitor *fm)
{
if (close(fm->fd))
log_error("Error closing file descriptor.");
fm->fd = -1;
}
static void _filemap_monitor_end_notify(struct filemap_monitor *fm)
{
inotify_rm_watch(fm->inotify_fd, fm->inotify_watch_fd);
}
static int _filemap_monitor_set_notify(struct filemap_monitor *fm)
{
int inotify_fd, watch_fd;
/*
* Set IN_NONBLOCK since we do not want to block in event read()
* calls. Do not set IN_CLOEXEC as dmfilemapd is single-threaded
* and does not fork or exec.
*/
if ((inotify_fd = inotify_init1(IN_NONBLOCK)) < 0) {
log_sys_error("inotify_init1", "IN_NONBLOCK");
return 0;
}
if ((watch_fd = inotify_add_watch(inotify_fd, fm->path,
IN_MODIFY | IN_DELETE_SELF)) < 0) {
log_sys_error("inotify_add_watch", fm->path);
return 0;
}
fm->inotify_fd = inotify_fd;
fm->inotify_watch_fd = watch_fd;
return 1;
}
static int _filemap_monitor_reopen_fd(struct filemap_monitor *fm)
{
int tries = FILEMAPD_NOFILE_WAIT_TRIES;
/*
* In DM_FILEMAPD_FOLLOW_PATH mode, inotify watches must be
* re-established whenever the file at the watched path is
* changed.
*
* FIXME: stat file and skip if inode is unchanged.
*/
if (fm->fd > 0)
log_error("Filemap file descriptor already open.");
while ((fm->fd < 0) && --tries)
if (((fm->fd = open(fm->path, O_RDONLY)) < 0) && tries)
_filemap_monitor_wait(FILEMAPD_NOFILE_WAIT_USECS);
if (!tries && (fm->fd < 0)) {
log_error("Could not re-open file descriptor.");
return 0;
}
return _filemap_monitor_set_notify(fm);
}
static int _filemap_monitor_get_events(struct filemap_monitor *fm)
{
/* alignment as per man(7) inotify */
char buf[sizeof(struct inotify_event) + NAME_MAX + 1]
__attribute__ ((aligned(__alignof__(struct inotify_event))));
struct inotify_event *event;
int check = 0;
ssize_t len;
char *ptr;
/*
* Close the file descriptor for the file being monitored here
* when mode=path: this will allow the inode to be de-allocated,
* and an IN_DELETE_SELF event generated in the case that the
* daemon is holding the last open reference to the file.
*/
if (fm->mode == DM_FILEMAPD_FOLLOW_PATH) {
_filemap_monitor_end_notify(fm);
_filemap_monitor_close_fd(fm);
}
len = read(fm->inotify_fd, (void *) &buf, sizeof(buf));
/* no events to read? */
if (len < 0 && (errno == EAGAIN))
goto out;
/* interrupted by signal? */
if (len < 0 && (errno == EINTR))
goto out;
if (len < 0)
return -1;
if (!len)
goto out;
for (ptr = buf; ptr < buf + len; ptr += sizeof(*event) + event->len) {
event = (struct inotify_event *) ptr;
if (event->mask & IN_DELETE_SELF)
fm->deleted = 1;
if (event->mask & IN_MODIFY)
check = 1;
/*
* Event IN_IGNORED is generated when a file has been deleted
* and IN_DELETE_SELF generated, and indicates that the file
* watch has been automatically removed.
*
* This can only happen for the DM_FILEMAPD_FOLLOW_PATH mode,
* since inotify IN_DELETE events are generated at the time
* the inode is destroyed: DM_FILEMAPD_FOLLOW_INODE will hold
* the file descriptor open, meaning that the event will not
* be generated until after the daemon closes the file.
*
* The event is ignored here since inotify monitoring will
* be reestablished (or the daemon will terminate) following
* deletion of a DM_FILEMAPD_FOLLOW_PATH monitored file.
*/
if (event->mask & IN_IGNORED)
log_very_verbose("Inotify watch removed: IN_IGNORED "
"in event->mask");
}
out:
/*
* Re-open file descriptor if required and log disposition.
*/
if (fm->mode == DM_FILEMAPD_FOLLOW_PATH)
if (!_filemap_monitor_reopen_fd(fm))
return -1;
log_very_verbose("exiting _filemap_monitor_get_events() with "
"deleted=%d, check=%d", fm->deleted, check);
return check;
}
static void _filemap_monitor_destroy(struct filemap_monitor *fm)
{
if (fm->fd > 0) {
_filemap_monitor_end_notify(fm);
_filemap_monitor_close_fd(fm);
}
dm_free((void *) fm->program_id);
dm_free(fm->path);
}
static int _filemap_monitor_check_same_file(int fd1, int fd2)
{
struct stat buf1, buf2;
if ((fd1 < 0) || (fd2 < 0))
return 0;
if (fstat(fd1, &buf1)) {
log_error("Failed to fstat file descriptor %d", fd1);
return -1;
}
if (fstat(fd2, &buf2)) {
log_error("Failed to fstat file descriptor %d", fd2);
return -1;
}
return ((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino));
}
static int _filemap_monitor_check_file_unlinked(struct filemap_monitor *fm)
{
char path_buf[PATH_MAX];
char link_buf[PATH_MAX];
int same, fd;
ssize_t len;
fm->deleted = 0;
same = 0;
if ((fd = open(fm->path, O_RDONLY)) < 0)
goto check_unlinked;
same = _filemap_monitor_check_same_file(fm->fd, fd);
if (close(fd))
log_error("Error closing fd %d", fd);
if (same < 0)
return 0;
if (same)
return 1;
check_unlinked:
/*
* The file has been unlinked from its original location: test
* whether it is still reachable in the filesystem, or if it is
* unlinked and anonymous.
*/
if (dm_snprintf(path_buf, sizeof(path_buf), DEFAULT_PROC_DIR
"/%d/fd/%d", getpid(), fm->fd) < 0) {
log_error("Could not format pid path.");
return 0;
}
if ((len = readlink(path_buf, link_buf, sizeof(link_buf) - 1)) < 0) {
log_error("readlink failed for " DEFAULT_PROC_DIR "/%d/fd/%d.",
getpid(), fm->fd);
return 0;
}
link_buf[len] = '\0';
/*
* Try to re-open the file, from the path now reported in /proc/pid/fd.
*/
if ((fd = open(link_buf, O_RDONLY)) < 0)
fm->deleted = 1;
else
same = _filemap_monitor_check_same_file(fm->fd, fd);
if ((fd >= 0) && close(fd))
log_error("Error closing fd %d", fd);
if (same < 0)
return 0;
/* Should not happen with normal /proc. */
if ((fd > 0) && !same) {
log_error("File descriptor mismatch: %d and %s (read from %s) "
"are not the same file!", fm->fd, link_buf, path_buf);
return 0;
}
return 1;
}
static int _daemonise(struct filemap_monitor *fm)
{
pid_t pid = 0, sid;
int fd;
if (!(sid = setsid())) {
_early_log("setsid failed.");
return 0;
}
if ((pid = fork()) < 0) {
_early_log("Failed to fork daemon process.");
return 0;
}
if (pid > 0) {
if (_verbose)
_early_log("Started dmfilemapd with pid=%d", pid);
exit(0);
}
if (chdir("/")) {
_early_log("Failed to change directory.");
return 0;
}
if (!_verbose) {
if (close(STDIN_FILENO))
_early_log("Error closing stdin");
if (close(STDOUT_FILENO))
_early_log("Error closing stdout");
if (close(STDERR_FILENO))
_early_log("Error closing stderr");
if ((open("/dev/null", O_RDONLY) < 0) ||
(open("/dev/null", O_WRONLY) < 0) ||
(open("/dev/null", O_WRONLY) < 0)) {
_early_log("Error opening stdio streams.");
return 0;
}
}
/* TODO: Use libdaemon/server/daemon-server.c _daemonise() */
for (fd = (int) sysconf(_SC_OPEN_MAX) - 1; fd > STDERR_FILENO; fd--) {
if (fd == fm->fd)
continue;
(void) close(fd);
}
return 1;
}
static int _update_regions(struct dm_stats *dms, struct filemap_monitor *fm)
{
uint64_t *regions = NULL, *region, nr_regions = 0;
regions = dm_stats_update_regions_from_fd(dms, fm->fd, fm->group_id);
if (!regions) {
log_error("Failed to update filemap regions for group_id="
FMTu64 ".", fm->group_id);
return 0;
}
for (region = regions; *region != DM_STATS_REGIONS_ALL; region++)
nr_regions++;
if (!nr_regions)
log_warn("File contains no extents: exiting.");
if (nr_regions && (regions[0] != fm->group_id)) {
log_warn("group_id changed from " FMTu64 " to " FMTu64,
fm->group_id, regions[0]);
fm->group_id = regions[0];
}
dm_free(regions);
fm->nr_regions = nr_regions;
return 1;
}
static int _dmfilemapd(struct filemap_monitor *fm)
{
int running = 1, check = 0, open = 0;
const char *program_id;
struct dm_stats *dms;
/*
* The correct program_id is retrieved from the group leader
* following the call to dm_stats_list().
*/
if (!(dms = dm_stats_create(NULL)))
goto_bad;
if (!dm_stats_bind_from_fd(dms, fm->fd)) {
log_error("Could not bind dm_stats handle to file descriptor "
"%d", fm->fd);
goto bad;
}
if (!_filemap_monitor_set_notify(fm))
goto bad;
if (!_filemap_fd_update_blocks(fm))
goto bad;
if (!dm_stats_list(dms, DM_STATS_ALL_PROGRAMS)) {
log_error("Failed to list stats handle.");
goto bad;
}
/*
* Take the program_id for new regions (created by calls to
* dm_stats_update_regions_from_fd()) from the value used by
* the group leader.
*/
program_id = dm_stats_get_region_program_id(dms, fm->group_id);
if (program_id)
fm->program_id = dm_strdup(program_id);
else
fm->program_id = NULL;
dm_stats_set_program_id(dms, 1, program_id);
do {
if (!dm_stats_group_present(dms, fm->group_id)) {
log_info("Filemap group removed: exiting.");
running = 0;
continue;
}
if ((check = _filemap_monitor_get_events(fm)) < 0)
goto bad;
if (!check)
goto wait;
if ((check = _filemap_fd_check_changed(fm)) < 0)
goto bad;
if (check && !_update_regions(dms, fm))
goto bad;
running = !!fm->nr_regions;
if (!running)
continue;
wait:
_filemap_monitor_wait(FILEMAPD_WAIT_USECS);
/* mode=inode termination condions */
if (fm->mode == DM_FILEMAPD_FOLLOW_INODE) {
if (!_filemap_monitor_check_file_unlinked(fm))
goto bad;
if (fm->deleted && !(open = _is_open(fm->path))) {
log_info("File unlinked and closed: exiting.");
running = 0;
} else if (fm->deleted && open)
log_verbose("File unlinked and open: "
"continuing.");
}
if (!dm_stats_list(dms, NULL)) {
log_error("Failed to list stats handle.");
goto bad;
}
} while (running);
_filemap_monitor_destroy(fm);
dm_stats_destroy(dms);
return 0;
bad:
_filemap_monitor_destroy(fm);
dm_stats_destroy(dms);
log_error("Exiting");
return 1;
}
static const char * _mode_names[] = {
"inode",
"path"
};
/*
* dmfilemapd <fd> <group_id> <path> <mode> [<foreground>[<log_level>]]
*/
int main(int argc, char **argv)
{
struct filemap_monitor fm;
memset(&fm, 0, sizeof(fm));
if (!_parse_args(argc, argv, &fm)) {
dm_free(fm.path);
return 1;
}
_setup_logging();
log_info("Starting dmfilemapd with fd=%d, group_id=" FMTu64 " "
"mode=%s, path=%s", fm.fd, fm.group_id,
_mode_names[fm.mode], fm.path);
if (!_foreground && !_daemonise(&fm))
return 1;
return _dmfilemapd(&fm);
}

View File

@@ -38,7 +38,7 @@ class AutomatedProperties(dbus.service.Object):
props = {}
for i in self.interface():
props[i] = AutomatedProperties._get_all_prop(self, i)
props[i] = self.GetAll(i)
return self._ap_o_path, props
@@ -65,52 +65,31 @@ class AutomatedProperties(dbus.service.Object):
return self._ap_interface
@staticmethod
def _get_prop(obj, interface_name, property_name):
value = getattr(obj, property_name)
# Properties
# noinspection PyUnusedLocal
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='ss', out_signature='v')
def Get(self, interface_name, property_name):
value = getattr(self, property_name)
# Note: If we get an exception in this handler we won't know about it,
# only the side effect of no returned value!
log_debug('Get (%s), type (%s), value(%s)' %
(property_name, str(type(value)), str(value)))
return value
# Properties
# noinspection PyUnusedLocal
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='ss', out_signature='v',
async_callbacks=('cb', 'cbe'))
def Get(self, interface_name, property_name, cb, cbe):
# Note: If we get an exception in this handler we won't know about it,
# only the side effect of no returned value!
r = cfg.create_request_entry(
-1, AutomatedProperties._get_prop,
(self, interface_name, property_name),
cb, cbe, False)
cfg.worker_q.put(r)
@staticmethod
def _get_all_prop(obj, interface_name):
if interface_name in obj.interface(True):
in_signature='s', out_signature='a{sv}')
def GetAll(self, interface_name):
if interface_name in self.interface(True):
# Using introspection, lets build this dynamically
properties = get_properties(obj)
properties = get_properties(self)
if interface_name in properties:
return properties[interface_name][1]
return {}
raise dbus.exceptions.DBusException(
obj._ap_interface,
self._ap_interface,
'The object %s does not implement the %s interface'
% (obj.__class__, interface_name))
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='s', out_signature='a{sv}',
async_callbacks=('cb', 'cbe'))
def GetAll(self, interface_name, cb, cbe):
r = cfg.create_request_entry(
-1, AutomatedProperties._get_all_prop,
(self, interface_name),
cb, cbe, False)
cfg.worker_q.put(r)
% (self.__class__, interface_name))
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='ssv')

View File

@@ -9,13 +9,11 @@
import subprocess
from . import cfg
from .cmdhandler import options_to_cli_args, LvmExecutionMeta
from .cmdhandler import options_to_cli_args
import dbus
from .utils import pv_range_append, pv_dest_ranges, log_error, log_debug,\
add_no_notify
from .utils import pv_range_append, pv_dest_ranges, log_error, log_debug
import os
import threading
import time
def pv_move_lv_cmd(move_options, lv_full_name,
@@ -44,15 +42,6 @@ def _move_merge(interface_name, command, job_state):
# the command always as we will be getting periodic output from them on
# the status of the long running operation.
command.insert(0, cfg.LVM_CMD)
# Instruct lvm to not register an event with us
command = add_no_notify(command)
#(self, start, ended, cmd, ec, stdout_txt, stderr_txt)
meta = LvmExecutionMeta(time.time(), 0, command, -1000, None, None)
cfg.blackbox.add(meta)
process = subprocess.Popen(command, stdout=subprocess.PIPE,
env=os.environ,
stderr=subprocess.PIPE, close_fds=True)
@@ -70,21 +59,12 @@ def _move_merge(interface_name, command, job_state):
(device, ignore, percentage) = line_str.split(':')
job_state.Percent = round(
float(percentage.strip()[:-1]), 1)
# While the move is in progress we need to periodically update
# the state to reflect where everything is at.
cfg.load()
except ValueError:
log_error("Trying to parse percentage which failed for %s" %
line_str)
out = process.communicate()
with meta.lock:
meta.ended = time.time()
meta.ec = process.returncode
meta.stderr_txt = out[1]
if process.returncode == 0:
job_state.Percent = 100
else:

View File

@@ -26,7 +26,7 @@ bus = None
args = None
# Set to true if we are depending on external events for updates
got_external_event = False
ee = False
# Shared state variable across all processes
run = multiprocessing.Value('i', 1)
@@ -84,6 +84,3 @@ db = None
# lvm flight recorder
blackbox = None
# RequestEntry ctor
create_request_entry = None

View File

@@ -16,7 +16,7 @@ import traceback
import os
from lvmdbusd import cfg
from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error, add_no_notify
from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error
from lvmdbusd.lvm_shell_proxy import LVMShellProxy
try:
@@ -37,7 +37,6 @@ cmd_lock = threading.RLock()
class LvmExecutionMeta(object):
def __init__(self, start, ended, cmd, ec, stdout_txt, stderr_txt):
self.lock = threading.RLock()
self.start = start
self.ended = ended
self.cmd = cmd
@@ -46,13 +45,12 @@ class LvmExecutionMeta(object):
self.stderr_txt = stderr_txt
def __str__(self):
with self.lock:
return "EC= %d for %s\n" \
"STARTED: %f, ENDED: %f\n" \
"STDOUT=%s\n" \
"STDERR=%s\n" % \
(self.ec, str(self.cmd), self.start, self.ended, self.stdout_txt,
self.stderr_txt)
return "EC= %d for %s\n" \
"STARTED: %f, ENDED: %f\n" \
"STDOUT=%s\n" \
"STDERR=%s\n" % \
(self.ec, str(self.cmd), self.start, self.ended, self.stdout_txt,
self.stderr_txt)
class LvmFlightRecorder(object):
@@ -95,7 +93,6 @@ def call_lvm(command, debug=False):
# Prepend the full lvm executable so that we can run different versions
# in different locations on the same box
command.insert(0, cfg.LVM_CMD)
command = add_no_notify(command)
process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=True,
env=os.environ)
@@ -281,7 +278,7 @@ def vg_lv_create(vg_name, create_options, name, size_bytes, pv_dests):
cmd = ['lvcreate']
cmd.extend(options_to_cli_args(create_options))
cmd.extend(['--size', str(size_bytes) + 'B'])
cmd.extend(['--name', name, vg_name, '--yes'])
cmd.extend(['--name', name, vg_name])
pv_dest_ranges(cmd, pv_dests)
return call(cmd)
@@ -306,8 +303,6 @@ def _vg_lv_create_common_cmd(create_options, size_bytes, thin_pool):
cmd.extend(['--size', str(size_bytes) + 'B'])
else:
cmd.extend(['--thin', '--size', str(size_bytes) + 'B'])
cmd.extend(['--yes'])
return cmd
@@ -344,7 +339,7 @@ def _vg_lv_create_raid(vg_name, create_options, name, raid_type, size_bytes,
if stripe_size_kb != 0:
cmd.extend(['--stripesize', str(stripe_size_kb)])
cmd.extend(['--name', name, vg_name, '--yes'])
cmd.extend(['--name', name, vg_name])
return call(cmd)
@@ -365,7 +360,7 @@ def vg_lv_create_mirror(
cmd.extend(['--type', 'mirror'])
cmd.extend(['--mirrors', str(num_copies)])
cmd.extend(['--size', str(size_bytes) + 'B'])
cmd.extend(['--name', name, vg_name, '--yes'])
cmd.extend(['--name', name, vg_name])
return call(cmd)
@@ -419,7 +414,7 @@ def lv_lv_create(lv_full_name, create_options, name, size_bytes):
cmd = ['lvcreate']
cmd.extend(options_to_cli_args(create_options))
cmd.extend(['--virtualsize', str(size_bytes) + 'B', '-T'])
cmd.extend(['--name', name, lv_full_name, '--yes'])
cmd.extend(['--name', name, lv_full_name])
return call(cmd)
@@ -555,7 +550,7 @@ def pv_resize(device, size_bytes, create_options):
cmd.extend(options_to_cli_args(create_options))
if size_bytes != 0:
cmd.extend(['--yes', '--setphysicalvolumesize', str(size_bytes) + 'B'])
cmd.extend(['--setphysicalvolumesize', str(size_bytes) + 'B'])
cmd.extend([device])
return call(cmd)
@@ -620,10 +615,10 @@ def vg_reduce(vg_name, missing, pv_devices, reduce_options):
cmd = ['vgreduce']
cmd.extend(options_to_cli_args(reduce_options))
if len(pv_devices) == 0:
cmd.append('--all')
if missing:
cmd.append('--removemissing')
elif len(pv_devices) == 0:
cmd.append('--all')
cmd.append(vg_name)
cmd.extend(pv_devices)

View File

@@ -82,10 +82,10 @@ class StateUpdate(object):
@staticmethod
def update_thread(obj):
queued_requests = []
while cfg.run.value != 0:
# noinspection PyBroadException
try:
queued_requests = []
refresh = True
emit_signal = True
cache_refresh = True
@@ -96,7 +96,7 @@ class StateUpdate(object):
wait = not obj.deferred
obj.deferred = False
if len(queued_requests) == 0 and wait:
if wait:
queued_requests.append(obj.queue.get(True, 2))
# Ok we have one or the deferred queue has some,
@@ -131,17 +131,11 @@ class StateUpdate(object):
for i in queued_requests:
i.set_result(num_changes)
# Only clear out the requests after we have given them a result
# otherwise we can orphan the waiting threads and they never
# wake up if we get an exception
queued_requests = []
except queue.Empty:
pass
except Exception:
st = traceback.format_exc()
log_error("update_thread exception: \n%s" % st)
cfg.blackbox.dump()
def __init__(self):
self.lock = threading.RLock()

View File

@@ -29,7 +29,7 @@ except ImportError:
from lvmdbusd.cfg import LVM_CMD
from lvmdbusd.utils import log_debug, log_error, add_no_notify
from lvmdbusd.utils import log_debug, log_error
SHELL_PROMPT = "lvm> "
@@ -206,8 +206,6 @@ class LVMShellProxy(object):
self.lvm_shell.returncode,
"Underlying lvm shell process is not present!")
argv = add_no_notify(argv)
# create the command string
cmd = " ".join(_quote_arg(arg) for arg in argv)
cmd += "\n"

View File

@@ -30,7 +30,6 @@ import argparse
import os
import sys
from .cmdhandler import LvmFlightRecorder
from .request import RequestEntry
class Lvm(objectmanager.ObjectManager):
@@ -98,7 +97,6 @@ def main():
os.environ["LC_ALL"] = "C"
cfg.args = parser.parse_args()
cfg.create_request_entry = RequestEntry
# We create a flight recorder in cmdhandler too, but we replace it here
# as the user may be specifying a different size. The default one in
@@ -146,6 +144,7 @@ def main():
thread_list.append(updater.thread)
cfg.load = updater.load
cfg.event = updater.event
cfg.loop = GLib.MainLoop()

View File

@@ -6,6 +6,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from .automatedproperties import AutomatedProperties
from . import utils
@@ -47,7 +48,7 @@ class Manager(AutomatedProperties):
pv = cfg.om.get_object_path_by_uuid_lvm_id(device, device)
if pv:
raise dbus.exceptions.DBusException(
MANAGER_INTERFACE, "PV %s Already exists!" % device)
MANAGER_INTERFACE, "PV Already exists!")
rc, out, err = cmdhandler.pv_create(create_options, [device])
Manager.handle_execute(rc, out, err)
@@ -131,28 +132,11 @@ class Manager(AutomatedProperties):
r = RequestEntry(-1, Manager._refresh, (), cb, cbe, False)
cfg.worker_q.put(r)
@dbus.service.method(
dbus_interface=MANAGER_INTERFACE)
def FlightRecorderDump(self):
"""
Dump the flight recorder to syslog
"""
cfg.blackbox.dump()
@staticmethod
def _lookup_by_lvm_id(key):
p = cfg.om.get_object_path_by_uuid_lvm_id(key, key)
if not p:
p = '/'
utils.log_debug('LookUpByLvmId: key = %s, result = %s' % (key, p))
return p
@dbus.service.method(
dbus_interface=MANAGER_INTERFACE,
in_signature='s',
out_signature='o',
async_callbacks=('cb', 'cbe'))
def LookUpByLvmId(self, key, cb, cbe):
out_signature='o')
def LookUpByLvmId(self, key):
"""
Given a lvm id in one of the forms:
@@ -166,8 +150,10 @@ class Manager(AutomatedProperties):
:param key: The lookup value
:return: Return the object path. If object not found you will get '/'
"""
r = RequestEntry(-1, Manager._lookup_by_lvm_id, (key,), cb, cbe, False)
cfg.worker_q.put(r)
p = cfg.om.get_object_path_by_uuid_lvm_id(key, key)
if p:
return p
return '/'
@staticmethod
def _use_lvm_shell(yes_no):
@@ -183,33 +169,25 @@ class Manager(AutomatedProperties):
:param yes_no:
:param cb: dbus python call back parameter, not client visible
:param cbe: dbus python error call back parameter, not client visible
:return: Boolean
:return: Nothing
"""
r = RequestEntry(-1, Manager._use_lvm_shell, (yes_no,), cb, cbe, False)
cfg.worker_q.put(r)
@staticmethod
def _external_event(command):
utils.log_debug("Processing _external_event= %s" % command,
'bg_black', 'fg_orange')
cfg.load()
@dbus.service.method(
dbus_interface=MANAGER_INTERFACE,
in_signature='s', out_signature='i')
def ExternalEvent(self, command):
utils.log_debug("ExternalEvent %s" % command)
# If a user didn't explicitly specify udev, we will turn it off now.
if not cfg.args.use_udev:
if udevwatch.remove():
utils.log_debug("ExternalEvent received, disabling "
"udev monitoring")
# We are dependent on external events now to stay current!
cfg.got_external_event = True
r = RequestEntry(
-1, Manager._external_event, (command,), None, None, False)
cfg.worker_q.put(r)
cfg.ee = True
utils.log_debug("ExternalEvent %s" % command)
cfg.event()
return dbus.Int32(0)
@staticmethod

View File

@@ -32,12 +32,14 @@ class ObjectManager(AutomatedProperties):
self._id_to_object_path = {}
self.rlock = threading.RLock()
@staticmethod
def _get_managed_objects(obj):
with obj.rlock:
@dbus.service.method(
dbus_interface="org.freedesktop.DBus.ObjectManager",
out_signature='a{oa{sa{sv}}}')
def GetManagedObjects(self):
with self.rlock:
rc = {}
try:
for k, v in list(obj._objects.items()):
for k, v in list(self._objects.items()):
path, props = v[0].emit_data()
rc[path] = props
except Exception:
@@ -45,14 +47,6 @@ class ObjectManager(AutomatedProperties):
sys.exit(1)
return rc
@dbus.service.method(
dbus_interface="org.freedesktop.DBus.ObjectManager",
out_signature='a{oa{sa{sv}}}', async_callbacks=('cb', 'cbe'))
def GetManagedObjects(self, cb, cbe):
r = cfg.create_request_entry(-1, ObjectManager._get_managed_objects,
(self, ), cb, cbe, False)
cfg.worker_q.put(r)
def locked(self):
"""
If some external code need to run across a number of different
@@ -223,9 +217,8 @@ class ObjectManager(AutomatedProperties):
:param lvm_id: The lvm identifier
"""
with self.rlock:
lookup_rc = self._id_lookup(lvm_id)
if lookup_rc:
return self.get_object_by_path(lookup_rc)
if lvm_id in self._id_to_object_path:
return self.get_object_by_path(self._id_to_object_path[lvm_id])
return None
def get_object_path_by_lvm_id(self, lvm_id):
@@ -235,9 +228,8 @@ class ObjectManager(AutomatedProperties):
:return: Object path or '/' if not found
"""
with self.rlock:
lookup_rc = self._id_lookup(lvm_id)
if lookup_rc:
return lookup_rc
if lvm_id in self._id_to_object_path:
return self._id_to_object_path[lvm_id]
return '/'
def _uuid_verify(self, path, uuid, lvm_id):

View File

@@ -10,41 +10,10 @@
import pyudev
import threading
from . import cfg
from .request import RequestEntry
from . import utils
observer = None
observer_lock = threading.RLock()
_udev_lock = threading.RLock()
_udev_count = 0
def udev_add():
global _udev_count
with _udev_lock:
if _udev_count == 0:
_udev_count += 1
# Place this on the queue so any other operations will sequence
# behind it
r = RequestEntry(
-1, _udev_event, (), None, None, False)
cfg.worker_q.put(r)
def udev_complete():
global _udev_count
with _udev_lock:
if _udev_count > 0:
_udev_count -= 1
def _udev_event():
utils.log_debug("Processing udev event")
udev_complete()
cfg.load()
# noinspection PyUnusedLocal
def filter_event(action, device):
@@ -68,7 +37,7 @@ def filter_event(action, device):
refresh = True
if refresh:
udev_add()
cfg.event()
def add():

View File

@@ -499,35 +499,6 @@ def validate_tag(interface, tag):
% (tag, _ALLOWABLE_TAG_CH))
def add_no_notify(cmdline):
"""
Given a command line to execute we will see if `--config` is present, if it
is we will add the global/notify_dbus=0 to it, otherwise we will append it
to the end of the list.
:param: cmdline: The command line to inspect
:type: cmdline: list
:return: cmdline with notify_dbus config option present
:rtype: list
"""
# Only after we have seen an external event will be disable lvm from sending
# us one when we call lvm
if cfg.got_external_event:
if 'help' in cmdline:
return cmdline
if '--config' in cmdline:
for i, arg in enumerate(cmdline):
if arg == '--config':
if len(cmdline) <= i+1:
raise dbus.exceptions.DBusException("Missing value for --config option.")
cmdline[i+1] += " global/notify_dbus=0"
break
else:
cmdline.extend(['--config', 'global/notify_dbus=0'])
return cmdline
# The methods below which start with mt_* are used to execute the desired code
# on the the main thread of execution to alleviate any issues the dbus-python
# library with regards to multi-threaded access. Essentially, we are trying to

View File

@@ -16,7 +16,7 @@ top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES = lvmetad-core.c
SOURCES2 = lvmetactl.c
SOURCES2 = testclient.c
TARGETS = lvmetad lvmetactl
@@ -28,19 +28,22 @@ CFLOW_TARGET = lvmetad
include $(top_builddir)/make.tmpl
CFLAGS_lvmetactl.o += $(EXTRA_EXEC_CFLAGS)
CFLAGS_lvmetad-core.o += $(EXTRA_EXEC_CFLAGS)
INCLUDES += -I$(top_srcdir)/libdaemon/server
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
LIBS += $(RT_LIBS) $(DAEMON_LIBS) -ldevmapper $(PTHREAD_LIBS)
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
LIBS += $(PTHREAD_LIBS)
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS)
CLDFLAGS += -L$(top_builddir)/libdaemon/server
CFLAGS += $(EXTRA_EXEC_CFLAGS)
lvmetad: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) -ldaemonserver $(LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LVMLIBS) $(LIBS)
lvmetactl: lvmetactl.o $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmetactl.o $(LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmetactl.o $(LVMLIBS)
CLEAN_TARGETS += lvmetactl.o

View File

@@ -25,7 +25,6 @@
#define LVMETAD_DISABLE_REASON_LVM1 "LVM1"
#define LVMETAD_DISABLE_REASON_DUPLICATES "DUPLICATES"
#define LVMETAD_DISABLE_REASON_VGRESTORE "VGRESTORE"
#define LVMETAD_DISABLE_REASON_REPAIR "REPAIR"
struct volume_group;

View File

@@ -203,9 +203,8 @@ struct vg_info {
#define GLFL_DISABLE_REASON_LVM1 0x00000008
#define GLFL_DISABLE_REASON_DUPLICATES 0x00000010
#define GLFL_DISABLE_REASON_VGRESTORE 0x00000020
#define GLFL_DISABLE_REASON_REPAIR 0x00000040
#define GLFL_DISABLE_REASON_ALL (GLFL_DISABLE_REASON_DIRECT | GLFL_DISABLE_REASON_REPAIR | GLFL_DISABLE_REASON_LVM1 | GLFL_DISABLE_REASON_DUPLICATES | GLFL_DISABLE_REASON_VGRESTORE)
#define GLFL_DISABLE_REASON_ALL (GLFL_DISABLE_REASON_DIRECT | GLFL_DISABLE_REASON_LVM1 | GLFL_DISABLE_REASON_DUPLICATES | GLFL_DISABLE_REASON_VGRESTORE)
#define VGFL_INVALID 0x00000001
@@ -258,21 +257,6 @@ static void destroy_metadata_hashes(lvmetad_state *s)
dm_hash_iterate(n, s->pvid_to_pvmeta)
dm_config_destroy(dm_hash_get_data(s->pvid_to_pvmeta, n));
dm_hash_iterate(n, s->vgid_to_vgname)
dm_free(dm_hash_get_data(s->vgid_to_vgname, n));
dm_hash_iterate(n, s->vgname_to_vgid)
dm_free(dm_hash_get_data(s->vgname_to_vgid, n));
dm_hash_iterate(n, s->vgid_to_info)
dm_free(dm_hash_get_data(s->vgid_to_info, n));
dm_hash_iterate(n, s->device_to_pvid)
dm_free(dm_hash_get_data(s->device_to_pvid, n));
dm_hash_iterate(n, s->pvid_to_vgid)
dm_free(dm_hash_get_data(s->pvid_to_vgid, n));
dm_hash_destroy(s->pvid_to_pvmeta);
dm_hash_destroy(s->vgid_to_metadata);
dm_hash_destroy(s->vgid_to_vgname);
@@ -808,8 +792,7 @@ static int _update_pvid_to_vgid(lvmetad_state *s, struct dm_config_tree *vg,
if ((mode == REMOVE_EMPTY) && vgid_old) {
/* This copies the vgid_old string, doesn't reference it. */
if ((dm_hash_lookup(to_check, vgid_old) != (void*) 1) &&
!dm_hash_insert(to_check, vgid_old, (void*) 1)) {
if (!dm_hash_insert(to_check, vgid_old, (void*) 1)) {
ERROR(s, "update_pvid_to_vgid out of memory for hash insert vgid_old %s", vgid_old);
goto abort_daemon;
}
@@ -885,13 +868,16 @@ static int remove_metadata(lvmetad_state *s, const char *vgid, int update_pvids)
/* free the unmapped data */
if (info_lookup)
dm_free(info_lookup);
if (meta_lookup)
dm_config_destroy(meta_lookup);
if (name_lookup)
dm_free(name_lookup);
if (outdated_pvs_lookup)
dm_config_destroy(outdated_pvs_lookup);
dm_free(info_lookup);
dm_free(name_lookup);
dm_free(vgid_lookup);
if (vgid_lookup)
dm_free(vgid_lookup);
return 1;
}
@@ -1218,8 +1204,10 @@ static int _update_metadata_add_new(lvmetad_state *s, const char *new_name, cons
out:
out_free:
if (!new_name_dup || !new_vgid_dup || abort_daemon) {
dm_free(new_name_dup);
dm_free(new_vgid_dup);
if (new_name_dup)
dm_free(new_name_dup);
if (new_vgid_dup)
dm_free(new_vgid_dup);
ERROR(s, "lvmetad could not be updated and is aborting.");
exit(EXIT_FAILURE);
}
@@ -1809,7 +1797,8 @@ static response pv_gone(lvmetad_state *s, request r)
}
dm_config_destroy(pvmeta);
dm_free(old_pvid);
if (old_pvid)
dm_free(old_pvid);
return daemon_reply_simple("OK", NULL );
}
@@ -1922,7 +1911,7 @@ static response pv_found(lvmetad_state *s, request r)
const char *arg_pvid = NULL;
const char *arg_pvid_lookup = NULL;
const char *new_pvid = NULL;
char *new_pvid_dup = NULL;
const char *new_pvid_dup = NULL;
const char *arg_name = NULL;
const char *arg_vgid = NULL;
const char *arg_vgid_lookup = NULL;
@@ -2085,7 +2074,7 @@ static response pv_found(lvmetad_state *s, request r)
if (!(new_pvid_dup = dm_strdup(new_pvid)))
goto nomem_free1;
if (!dm_hash_insert_binary(s->device_to_pvid, &new_device, sizeof(new_device), new_pvid_dup))
if (!dm_hash_insert_binary(s->device_to_pvid, &new_device, sizeof(new_device), (char *)new_pvid_dup))
goto nomem_free2;
if (!dm_hash_insert(s->pvid_to_pvmeta, new_pvid, new_pvmeta))
@@ -2121,8 +2110,6 @@ static response pv_found(lvmetad_state *s, request r)
DEBUGLOG(s, "pv_found ignore duplicate device %" PRIu64 " of existing PV for pvid %s",
arg_device, arg_pvid);
dm_config_destroy(new_pvmeta);
/* device_to_pvid no longer references prev_pvid_lookup */
dm_free((void*)prev_pvid_on_dev);
s->flags |= GLFL_DISABLE;
s->flags |= GLFL_DISABLE_REASON_DUPLICATES;
return reply_fail("Ignore duplicate PV");
@@ -2133,7 +2120,7 @@ static response pv_found(lvmetad_state *s, request r)
if (!(new_pvid_dup = dm_strdup(new_pvid)))
goto nomem_free1;
if (!dm_hash_insert_binary(s->device_to_pvid, &arg_device, sizeof(arg_device), new_pvid_dup))
if (!dm_hash_insert_binary(s->device_to_pvid, &arg_device, sizeof(arg_device), (char *)new_pvid_dup))
goto nomem_free2;
if (!dm_hash_insert(s->pvid_to_pvmeta, new_pvid, new_pvmeta))
@@ -2233,7 +2220,8 @@ static response pv_found(lvmetad_state *s, request r)
}
/* This was unhashed from device_to_pvid above. */
dm_free((void *)prev_pvid_on_dev);
if (prev_pvid_on_dev)
dm_free((void *)prev_pvid_on_dev);
return daemon_reply_simple("OK",
"status = %s", vg_status,
@@ -2245,7 +2233,7 @@ static response pv_found(lvmetad_state *s, request r)
NULL);
nomem_free2:
dm_free(new_pvid_dup);
dm_free((char *)new_pvid_dup);
nomem_free1:
dm_config_destroy(new_pvmeta);
nomem:
@@ -2367,8 +2355,6 @@ static response set_global_info(lvmetad_state *s, request r)
if ((reason = daemon_request_str(r, "disable_reason", NULL))) {
if (strstr(reason, LVMETAD_DISABLE_REASON_DIRECT))
reason_flags |= GLFL_DISABLE_REASON_DIRECT;
if (strstr(reason, LVMETAD_DISABLE_REASON_REPAIR))
reason_flags |= GLFL_DISABLE_REASON_REPAIR;
if (strstr(reason, LVMETAD_DISABLE_REASON_LVM1))
reason_flags |= GLFL_DISABLE_REASON_LVM1;
if (strstr(reason, LVMETAD_DISABLE_REASON_DUPLICATES))
@@ -2432,9 +2418,8 @@ static response get_global_info(lvmetad_state *s, request r)
pid = (int)daemon_request_int(r, "pid", 0);
if (s->flags & GLFL_DISABLE) {
snprintf(reason, REASON_BUF_SIZE - 1, "%s%s%s%s%s",
snprintf(reason, REASON_BUF_SIZE - 1, "%s%s%s%s",
(s->flags & GLFL_DISABLE_REASON_DIRECT) ? LVMETAD_DISABLE_REASON_DIRECT "," : "",
(s->flags & GLFL_DISABLE_REASON_REPAIR) ? LVMETAD_DISABLE_REASON_REPAIR "," : "",
(s->flags & GLFL_DISABLE_REASON_LVM1) ? LVMETAD_DISABLE_REASON_LVM1 "," : "",
(s->flags & GLFL_DISABLE_REASON_DUPLICATES) ? LVMETAD_DISABLE_REASON_DUPLICATES "," : "",
(s->flags & GLFL_DISABLE_REASON_VGRESTORE) ? LVMETAD_DISABLE_REASON_VGRESTORE "," : "");
@@ -2572,12 +2557,14 @@ static void _dump_pairs(struct buffer *buf, struct dm_hash_table *ht, const char
dm_hash_iterate(n, ht) {
const char *key = dm_hash_get_key(ht, n),
*val = dm_hash_get_data(ht, n);
buffer_append(buf, " ");
if (int_key)
(void) dm_asprintf(&append, " %d = \"%s\"\n", *(const int*)key, val);
(void) dm_asprintf(&append, "%d = \"%s\"", *(const int*)key, val);
else
(void) dm_asprintf(&append, " %s = \"%s\"\n", key, val);
(void) dm_asprintf(&append, "%s = \"%s\"", key, val);
if (append)
buffer_append(buf, append);
buffer_append(buf, "\n");
dm_free(append);
}
buffer_append(buf, "}\n");
@@ -2595,9 +2582,11 @@ static void _dump_info_version(struct buffer *buf, struct dm_hash_table *ht, con
while (n) {
const char *key = dm_hash_get_key(ht, n);
info = dm_hash_get_data(ht, n);
(void) dm_asprintf(&append, " %s = %lld\n", key, (long long)info->external_version);
buffer_append(buf, " ");
(void) dm_asprintf(&append, "%s = %lld", key, (long long)info->external_version);
if (append)
buffer_append(buf, append);
buffer_append(buf, "\n");
dm_free(append);
n = dm_hash_get_next(ht, n);
}
@@ -2616,9 +2605,11 @@ static void _dump_info_flags(struct buffer *buf, struct dm_hash_table *ht, const
while (n) {
const char *key = dm_hash_get_key(ht, n);
info = dm_hash_get_data(ht, n);
(void) dm_asprintf(&append, " %s = %llx\n", key, (long long)info->flags);
buffer_append(buf, " ");
(void) dm_asprintf(&append, "%s = %llx", key, (long long)info->flags);
if (append)
buffer_append(buf, append);
buffer_append(buf, "\n");
dm_free(append);
n = dm_hash_get_next(ht, n);
}

View File

@@ -19,12 +19,10 @@ SOURCES = lvmlockd-core.c
ifeq ("@BUILD_LOCKDSANLOCK@", "yes")
SOURCES += lvmlockd-sanlock.c
LOCK_LIBS += -lsanlock_client
endif
ifeq ("@BUILD_LOCKDDLM@", "yes")
SOURCES += lvmlockd-dlm.c
LOCK_LIBS += -ldlm_lt
endif
TARGETS = lvmlockd lvmlockctl
@@ -33,17 +31,29 @@ TARGETS = lvmlockd lvmlockctl
include $(top_builddir)/make.tmpl
CFLAGS += $(EXTRA_EXEC_CFLAGS)
INCLUDES += -I$(top_srcdir)/libdaemon/server
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
LIBS += $(RT_LIBS) $(DAEMON_LIBS) -ldevmapper $(PTHREAD_LIBS)
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
LIBS += $(PTHREAD_LIBS)
ifeq ("@BUILD_LOCKDSANLOCK@", "yes")
LIBS += -lsanlock_client
endif
ifeq ("@BUILD_LOCKDDLM@", "yes")
LIBS += -ldlm_lt
endif
LDFLAGS += -L$(top_builddir)/libdaemon/server
CLDFLAGS += -L$(top_builddir)/libdaemon/server
lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LOCK_LIBS) -ldaemonserver $(LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LVMLIBS) $(LIBS)
lvmlockctl: lvmlockctl.o $(top_builddir)/libdaemon/client/libdaemonclient.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmlockctl.o $(LIBS)
lvmlockctl: lvmlockctl.o $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmlockctl.o $(LVMLIBS)
install_lvmlockd: lvmlockd
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)

View File

@@ -19,7 +19,6 @@
#include "lvm-version.h"
#include "lvmetad-client.h"
#include "lvmlockd-client.h"
#include "dm-ioctl.h" /* for DM_UUID_LEN */
/* #include <assert.h> */
#include <errno.h>
@@ -3304,6 +3303,7 @@ static int work_init_lv(struct action *act)
lm_type = ls->lm_type;
memcpy(vg_args, ls->vg_args, MAX_ARGS);
free_offset = ls->free_lock_offset;
ls->free_lock_offset = 0;
}
pthread_mutex_unlock(&lockspaces_mutex);
@@ -4907,10 +4907,14 @@ static int get_lockd_vgs(struct list_head *vg_lockd)
continue;
for (lv_cn = md_cn->child; lv_cn; lv_cn = lv_cn->sib) {
snprintf(find_str_path, PATH_MAX, "%s/lock_type", lv_cn->key);
lock_type = dm_config_find_str(lv_cn, find_str_path, NULL);
if (!lock_type)
continue;
snprintf(find_str_path, PATH_MAX, "%s/lock_args", lv_cn->key);
lock_args = dm_config_find_str(lv_cn, find_str_path, NULL);
if (!lock_args)
continue;
snprintf(find_str_path, PATH_MAX, "%s/id", lv_cn->key);
lv_uuid = dm_config_find_str(lv_cn, find_str_path, NULL);
@@ -4956,7 +4960,7 @@ out:
return rv;
}
static char _dm_uuid[DM_UUID_LEN];
static char _dm_uuid[64];
static char *get_dm_uuid(char *dm_name)
{
@@ -5175,17 +5179,20 @@ static void adopt_locks(void)
* Get list of lockspaces from lock managers.
* Get list of VGs from lvmetad with a lockd type.
* Get list of active lockd type LVs from /dev.
*
* ECONNREFUSED means the lock manager is not running.
* This is expected for at least one of them.
*/
if (lm_support_dlm() && lm_is_running_dlm()) {
if (lm_support_dlm()) {
rv = lm_get_lockspaces_dlm(&ls_found);
if (rv < 0)
if ((rv < 0) && (rv != -ECONNREFUSED))
goto fail;
}
if (lm_support_sanlock() && lm_is_running_sanlock()) {
if (lm_support_sanlock()) {
rv = lm_get_lockspaces_sanlock(&ls_found);
if (rv < 0)
if ((rv < 0) && (rv != -ECONNREFUSED))
goto fail;
}
@@ -5262,7 +5269,7 @@ static void adopt_locks(void)
list_for_each_entry_safe(ls1, l1safe, &ls_found, list) {
/* The dlm global lockspace is special and doesn't match a VG. */
if ((ls1->lm_type == LD_LM_DLM) && !strcmp(ls1->name, gl_lsname_dlm)) {
if (!strcmp(ls1->name, gl_lsname_dlm)) {
list_del(&ls1->list);
free(ls1);
continue;

View File

@@ -224,10 +224,7 @@ static int lock_lv_offset_from_args(char *lv_args, uint64_t *lock_lv_offset)
if (rv < 0)
return rv;
errno = 0;
*lock_lv_offset = strtoull(offset_str, NULL, 10);
if (errno)
return -1;
return 0;
}
@@ -938,9 +935,7 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset)
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
struct sanlk_resourced rd;
uint64_t offset;
uint64_t start_offset;
int rv;
int round = 0;
if (daemon_test) {
*free_offset = (1048576 * LV_LOCK_BEGIN) + (1048576 * (daemon_test_lv_count + 1));
@@ -953,22 +948,9 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset)
rd.rs.num_disks = 1;
strncpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
if (ls->free_lock_offset)
offset = ls->free_lock_offset;
else
offset = lms->align_size * LV_LOCK_BEGIN;
start_offset = offset;
offset = lms->align_size * LV_LOCK_BEGIN;
while (1) {
if (offset >= start_offset && round) {
/* This indicates the all space are allocated. */
log_debug("S %s init_lv_san read back to start offset %llu",
ls->name, (unsigned long long)offset);
rv = -EMSGSIZE;
return rv;
}
rd.rs.disks[0].offset = offset;
memset(rd.rs.name, 0, SANLK_NAME_LEN);
@@ -978,14 +960,7 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset)
/* This indicates the end of the device is reached. */
log_debug("S %s find_free_lock_san read limit offset %llu",
ls->name, (unsigned long long)offset);
/* remember the NO SPACE offset, if no free area left,
* search from this offset after extend */
*free_offset = offset;
offset = lms->align_size * LV_LOCK_BEGIN;
round = 1;
continue;
return -EMSGSIZE;
}
/*

View File

@@ -27,14 +27,18 @@ CFLOW_TARGET = lvmpolld
include $(top_builddir)/make.tmpl
CFLAGS += $(EXTRA_EXEC_CFLAGS)
INCLUDES += -I$(top_srcdir)/libdaemon/server
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
LIBS += $(DAEMON_LIBS) -ldaemonserver -ldevmapper $(PTHREAD_LIBS)
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
LIBS += $(PTHREAD_LIBS)
LDFLAGS += -L$(top_builddir)/libdaemon/server $(DAEMON_LDFLAGS)
CLDFLAGS += -L$(top_builddir)/libdaemon/server
CFLAGS += $(DAEMON_CFLAGS)
lvmpolld: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LVMLIBS) $(LIBS)
install_lvmpolld: lvmpolld
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)

View File

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

View File

@@ -207,10 +207,6 @@ Optional feature arguments are:
block, then the cache block is invalidated.
To enable passthrough mode the cache must be clean.
metadata2 : use version 2 of the metadata. This stores the dirty bits
in a separate btree, which improves speed of shutting
down the cache.
A policy called 'default' is always registered. This is an alias for
the policy we currently think is giving best all round performance.
@@ -290,7 +286,7 @@ message, which takes an arbitrary number of cblock ranges. Each cblock
range's end value is "one past the end", meaning 5-10 expresses a range
of values from 5 to 9. Each cblock must be expressed as a decimal
value, in the future a variant message that takes cblock ranges
expressed in hexadecimal may be needed to better support efficient
expressed in hexidecimal may be needed to better support efficient
invalidation of larger caches. The cache must be in passthrough mode
when invalidate_cblocks is used.

View File

@@ -11,57 +11,23 @@ Parameters: <cipher> <key> <iv_offset> <device path> \
<offset> [<#opt_params> <opt_params>]
<cipher>
Encryption cipher, encryption mode and Initial Vector (IV) generator.
The cipher specifications format is:
cipher[:keycount]-chainmode-ivmode[:ivopts]
Encryption cipher and an optional IV generation mode.
(In format cipher[:keycount]-chainmode-ivmode[:ivopts]).
Examples:
des
aes-cbc-essiv:sha256
aes-xts-plain64
serpent-xts-plain64
twofish-ecb
Cipher format also supports direct specification with kernel crypt API
format (selected by capi: prefix). The IV specification is the same
as for the first format type.
This format is mainly used for specification of authenticated modes.
The crypto API cipher specifications format is:
capi:cipher_api_spec-ivmode[:ivopts]
Examples:
capi:cbc(aes)-essiv:sha256
capi:xts(aes)-plain64
Examples of authenticated modes:
capi:gcm(aes)-random
capi:authenc(hmac(sha256),xts(aes))-random
capi:rfc7539(chacha20,poly1305)-random
The /proc/crypto contains a list of curently loaded crypto modes.
/proc/crypto contains supported crypto modes
<key>
Key used for encryption. It is encoded either as a hexadecimal number
or it can be passed as <key_string> prefixed with single colon
character (':') for keys residing in kernel keyring service.
Key used for encryption. It is encoded as a hexadecimal number.
You can only use key sizes that are valid for the selected cipher
in combination with the selected iv mode.
Note that for some iv modes the key string can contain additional
keys (for example IV seed) so the key contains more parts concatenated
into a single string.
<key_string>
The kernel keyring key is identified by string in following format:
<key_size>:<key_type>:<key_description>.
<key_size>
The encryption key size in bytes. The kernel key payload size must match
the value passed in <key_size>.
<key_type>
Either 'logon' or 'user' kernel key type.
<key_description>
The kernel keyring key description crypt target should look for
when loading key of <key_type>.
<keycount>
Multi-key compatibility mode. You can define <keycount> keys and
then sectors are encrypted according to their offsets (sector 0 uses key0;
@@ -110,32 +76,6 @@ submit_from_crypt_cpus
thread because it benefits CFQ to have writes submitted using the
same context.
integrity:<bytes>:<type>
The device requires additional <bytes> metadata per-sector stored
in per-bio integrity structure. This metadata must by provided
by underlying dm-integrity target.
The <type> can be "none" if metadata is used only for persistent IV.
For Authenticated Encryption with Additional Data (AEAD)
the <type> is "aead". An AEAD mode additionally calculates and verifies
integrity for the encrypted device. The additional space is then
used for storing authentication tag (and persistent IV if needed).
sector_size:<bytes>
Use <bytes> as the encryption unit instead of 512 bytes sectors.
This option can be in range 512 - 4096 bytes and must be power of two.
Virtual device will announce this size as a minimal IO and logical sector.
iv_large_sectors
IV generators will use sector number counted in <sector_size> units
instead of default 512 bytes sectors.
For example, if <sector_size> is 4096 bytes, plain64 IV for the second
sector will be 8 (without flag) and 1 if iv_large_sectors is present.
The <iv_offset> must be multiple of <sector_size> (in 512 bytes units)
if this flag is specified.
Example scripts
===============
LUKS (Linux Unified Key Setup) is now the preferred way to set up disk
@@ -145,13 +85,7 @@ https://gitlab.com/cryptsetup/cryptsetup
[[
#!/bin/sh
# Create a crypt device using dmsetup
dmsetup create crypt1 --table "0 `blockdev --getsz $1` crypt aes-cbc-essiv:sha256 babebabebabebabebabebabebabebabe 0 $1 0"
]]
[[
#!/bin/sh
# Create a crypt device using dmsetup when encryption key is stored in keyring service
dmsetup create crypt2 --table "0 `blockdev --getsize $1` crypt aes-cbc-essiv:sha256 :32:logon:my_prefix:my_key 0 $1 0"
dmsetup create crypt1 --table "0 `blockdev --getsize $1` crypt aes-cbc-essiv:sha256 babebabebabebabebabebabebabebabe 0 $1 0"
]]
[[

View File

@@ -16,12 +16,12 @@ Example scripts
[[
#!/bin/sh
# Create device delaying rw operation for 500ms
echo "0 `blockdev --getsz $1` delay $1 0 500" | dmsetup create delayed
echo "0 `blockdev --getsize $1` delay $1 0 500" | dmsetup create delayed
]]
[[
#!/bin/sh
# Create device delaying only write operation for 500ms and
# splitting reads and writes to different devices $1 $2
echo "0 `blockdev --getsz $1` delay $1 0 0 $2 0 500" | dmsetup create delayed
echo "0 `blockdev --getsize $1` delay $1 0 0 $2 0 500" | dmsetup create delayed
]]

View File

@@ -42,7 +42,7 @@ Optional feature parameters:
<direction>: Either 'r' to corrupt reads or 'w' to corrupt writes.
'w' is incompatible with drop_writes.
<value>: The value (from 0-255) to write.
<flags>: Perform the replacement only if bio->bi_opf has all the
<flags>: Perform the replacement only if bio->bi_rw has all the
selected flags set.
Examples:

View File

@@ -1,199 +0,0 @@
The dm-integrity target emulates a block device that has additional
per-sector tags that can be used for storing integrity information.
A general problem with storing integrity tags with every sector is that
writing the sector and the integrity tag must be atomic - i.e. in case of
crash, either both sector and integrity tag or none of them is written.
To guarantee write atomicity, the dm-integrity target uses journal, it
writes sector data and integrity tags into a journal, commits the journal
and then copies the data and integrity tags to their respective location.
The dm-integrity target can be used with the dm-crypt target - in this
situation the dm-crypt target creates the integrity data and passes them
to the dm-integrity target via bio_integrity_payload attached to the bio.
In this mode, the dm-crypt and dm-integrity targets provide authenticated
disk encryption - if the attacker modifies the encrypted device, an I/O
error is returned instead of random data.
The dm-integrity target can also be used as a standalone target, in this
mode it calculates and verifies the integrity tag internally. In this
mode, the dm-integrity target can be used to detect silent data
corruption on the disk or in the I/O path.
When loading the target for the first time, the kernel driver will format
the device. But it will only format the device if the superblock contains
zeroes. If the superblock is neither valid nor zeroed, the dm-integrity
target can't be loaded.
To use the target for the first time:
1. overwrite the superblock with zeroes
2. load the dm-integrity target with one-sector size, the kernel driver
will format the device
3. unload the dm-integrity target
4. read the "provided_data_sectors" value from the superblock
5. load the dm-integrity target with the the target size
"provided_data_sectors"
6. if you want to use dm-integrity with dm-crypt, load the dm-crypt target
with the size "provided_data_sectors"
Target arguments:
1. the underlying block device
2. the number of reserved sector at the beginning of the device - the
dm-integrity won't read of write these sectors
3. the size of the integrity tag (if "-" is used, the size is taken from
the internal-hash algorithm)
4. mode:
D - direct writes (without journal) - in this mode, journaling is
not used and data sectors and integrity tags are written
separately. In case of crash, it is possible that the data
and integrity tag doesn't match.
J - journaled writes - data and integrity tags are written to the
journal and atomicity is guaranteed. In case of crash,
either both data and tag or none of them are written. The
journaled mode degrades write throughput twice because the
data have to be written twice.
R - recovery mode - in this mode, journal is not replayed,
checksums are not checked and writes to the device are not
allowed. This mode is useful for data recovery if the
device cannot be activated in any of the other standard
modes.
5. the number of additional arguments
Additional arguments:
journal_sectors:number
The size of journal, this argument is used only if formatting the
device. If the device is already formatted, the value from the
superblock is used.
interleave_sectors:number
The number of interleaved sectors. This values is rounded down to
a power of two. If the device is already formatted, the value from
the superblock is used.
buffer_sectors:number
The number of sectors in one buffer. The value is rounded down to
a power of two.
The tag area is accessed using buffers, the buffer size is
configurable. The large buffer size means that the I/O size will
be larger, but there could be less I/Os issued.
journal_watermark:number
The journal watermark in percents. When the size of the journal
exceeds this watermark, the thread that flushes the journal will
be started.
commit_time:number
Commit time in milliseconds. When this time passes, the journal is
written. The journal is also written immediatelly if the FLUSH
request is received.
internal_hash:algorithm(:key) (the key is optional)
Use internal hash or crc.
When this argument is used, the dm-integrity target won't accept
integrity tags from the upper target, but it will automatically
generate and verify the integrity tags.
You can use a crc algorithm (such as crc32), then integrity target
will protect the data against accidental corruption.
You can also use a hmac algorithm (for example
"hmac(sha256):0123456789abcdef"), in this mode it will provide
cryptographic authentication of the data without encryption.
When this argument is not used, the integrity tags are accepted
from an upper layer target, such as dm-crypt. The upper layer
target should check the validity of the integrity tags.
journal_crypt:algorithm(:key) (the key is optional)
Encrypt the journal using given algorithm to make sure that the
attacker can't read the journal. You can use a block cipher here
(such as "cbc(aes)") or a stream cipher (for example "chacha20",
"salsa20", "ctr(aes)" or "ecb(arc4)").
The journal contains history of last writes to the block device,
an attacker reading the journal could see the last sector nubmers
that were written. From the sector numbers, the attacker can infer
the size of files that were written. To protect against this
situation, you can encrypt the journal.
journal_mac:algorithm(:key) (the key is optional)
Protect sector numbers in the journal from accidental or malicious
modification. To protect against accidental modification, use a
crc algorithm, to protect against malicious modification, use a
hmac algorithm with a key.
This option is not needed when using internal-hash because in this
mode, the integrity of journal entries is checked when replaying
the journal. Thus, modified sector number would be detected at
this stage.
block_size:number
The size of a data block in bytes. The larger the block size the
less overhead there is for per-block integrity metadata.
Supported values are 512, 1024, 2048 and 4096 bytes. If not
specified the default block size is 512 bytes.
The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can
be changed when reloading the target (load an inactive table and swap the
tables with suspend and resume). The other arguments should not be changed
when reloading the target because the layout of disk data depend on them
and the reloaded target would be non-functional.
The layout of the formatted block device:
* reserved sectors (they are not used by this target, they can be used for
storing LUKS metadata or for other purpose), the size of the reserved
area is specified in the target arguments
* superblock (4kiB)
* magic string - identifies that the device was formatted
* version
* log2(interleave sectors)
* integrity tag size
* the number of journal sections
* provided data sectors - the number of sectors that this target
provides (i.e. the size of the device minus the size of all
metadata and padding). The user of this target should not send
bios that access data beyond the "provided data sectors" limit.
* flags - a flag is set if journal_mac is used
* journal
The journal is divided into sections, each section contains:
* metadata area (4kiB), it contains journal entries
every journal entry contains:
* logical sector (specifies where the data and tag should
be written)
* last 8 bytes of data
* integrity tag (the size is specified in the superblock)
every metadata sector ends with
* mac (8-bytes), all the macs in 8 metadata sectors form a
64-byte value. It is used to store hmac of sector
numbers in the journal section, to protect against a
possibility that the attacker tampers with sector
numbers in the journal.
* commit id
* data area (the size is variable; it depends on how many journal
entries fit into the metadata area)
every sector in the data area contains:
* data (504 bytes of data, the last 8 bytes are stored in
the journal entry)
* commit id
To test if the whole journal section was written correctly, every
512-byte sector of the journal ends with 8-byte commit id. If the
commit id matches on all sectors in a journal section, then it is
assumed that the section was written correctly. If the commit id
doesn't match, the section was written partially and it should not
be replayed.
* one or more runs of interleaved tags and data. Each run contains:
* tag area - it contains integrity tags. There is one tag for each
sector in the data area
* data area - it contains data sectors. The number of data sectors
in one run must be a power of two. log2 of this value is stored
in the superblock.

View File

@@ -16,15 +16,15 @@ Example scripts
[[
#!/bin/sh
# Create an identity mapping for a device
echo "0 `blockdev --getsz $1` linear $1 0" | dmsetup create identity
echo "0 `blockdev --getsize $1` linear $1 0" | dmsetup create identity
]]
[[
#!/bin/sh
# Join 2 devices together
size1=`blockdev --getsz $1`
size2=`blockdev --getsz $2`
size1=`blockdev --getsize $1`
size2=`blockdev --getsize $2`
echo "0 $size1 linear $1 0
$size1 $size2 linear $2 0" | dmsetup create joined
]]
@@ -44,7 +44,7 @@ if (!defined($dev)) {
die("Please specify a device.\n");
}
my $dev_size = `blockdev --getsz $dev`;
my $dev_size = `blockdev --getsize $dev`;
my $extents = int($dev_size / $extent_size) -
(($dev_size % $extent_size) ? 1 : 0);

View File

@@ -14,14 +14,14 @@ Log Ordering
We log things in order of completion once we are sure the write is no longer in
cache. This means that normal WRITE requests are not actually logged until the
next REQ_PREFLUSH request. This is to make it easier for userspace to replay
the log in a way that correlates to what is on disk and not what is in cache,
to make it easier to detect improper waiting/flushing.
next REQ_FLUSH request. This is to make it easier for userspace to replay the
log in a way that correlates to what is on disk and not what is in cache, to
make it easier to detect improper waiting/flushing.
This works by attaching all WRITE requests to a list once the write completes.
Once we see a REQ_PREFLUSH request we splice this list onto the request and once
Once we see a REQ_FLUSH request we splice this list onto the request and once
the FLUSH request completes we log all of the WRITEs and then the FLUSH. Only
completed WRITEs, at the time the REQ_PREFLUSH is issued, are added in order to
completed WRITEs, at the time the REQ_FLUSH is issued, are added in order to
simulate the worst case scenario with regard to power failures. Consider the
following example (W means write, C means complete):

View File

@@ -14,12 +14,8 @@ The target is named "raid" and it accepts the following parameters:
<#raid_devs> <metadata_dev0> <dev0> [.. <metadata_devN> <devN>]
<raid_type>:
raid0 RAID0 striping (no resilience)
raid1 RAID1 mirroring
raid4 RAID4 with dedicated last parity disk
raid5_n RAID5 with dedicated last parity disk supporting takeover
Same as raid4
-Transitory layout
raid4 RAID4 dedicated parity disk
raid5_la RAID5 left asymmetric
- rotating parity 0 with data continuation
raid5_ra RAID5 right asymmetric
@@ -34,19 +30,7 @@ The target is named "raid" and it accepts the following parameters:
- rotating parity N (right-to-left) with data restart
raid6_nc RAID6 N continue
- rotating parity N (right-to-left) with data continuation
raid6_n_6 RAID6 with dedicate parity disks
- parity and Q-syndrome on the last 2 disks;
layout for takeover from/to raid4/raid5_n
raid6_la_6 Same as "raid_la" plus dedicated last Q-syndrome disk
- layout for takeover from raid5_la from/to raid6
raid6_ra_6 Same as "raid5_ra" dedicated last Q-syndrome disk
- layout for takeover from raid5_ra from/to raid6
raid6_ls_6 Same as "raid5_ls" dedicated last Q-syndrome disk
- layout for takeover from raid5_ls from/to raid6
raid6_rs_6 Same as "raid5_rs" dedicated last Q-syndrome disk
- layout for takeover from raid5_rs from/to raid6
raid10 Various RAID10 inspired algorithms chosen by additional params
(see raid10_format and raid10_copies below)
- RAID10: Striped Mirrors (aka 'Striping on top of mirrors')
- RAID1E: Integrated Adjacent Stripe Mirroring
- RAID1E: Integrated Offset Stripe Mirroring
@@ -132,57 +116,10 @@ The target is named "raid" and it accepts the following parameters:
Here we see layouts closely akin to 'RAID1E - Integrated
Offset Stripe Mirroring'.
[delta_disks <N>]
The delta_disks option value (-251 < N < +251) triggers
device removal (negative value) or device addition (positive
value) to any reshape supporting raid levels 4/5/6 and 10.
RAID levels 4/5/6 allow for addition of devices (metadata
and data device tuple), raid10_near and raid10_offset only
allow for device addition. raid10_far does not support any
reshaping at all.
A minimum of devices have to be kept to enforce resilience,
which is 3 devices for raid4/5 and 4 devices for raid6.
[data_offset <sectors>]
This option value defines the offset into each data device
where the data starts. This is used to provide out-of-place
reshaping space to avoid writing over data whilst
changing the layout of stripes, hence an interruption/crash
may happen at any time without the risk of losing data.
E.g. when adding devices to an existing raid set during
forward reshaping, the out-of-place space will be allocated
at the beginning of each raid device. The kernel raid4/5/6/10
MD personalities supporting such device addition will read the data from
the existing first stripes (those with smaller number of stripes)
starting at data_offset to fill up a new stripe with the larger
number of stripes, calculate the redundancy blocks (CRC/Q-syndrome)
and write that new stripe to offset 0. Same will be applied to all
N-1 other new stripes. This out-of-place scheme is used to change
the RAID type (i.e. the allocation algorithm) as well, e.g.
changing from raid5_ls to raid5_n.
[journal_dev <dev>]
This option adds a journal device to raid4/5/6 raid sets and
uses it to close the 'write hole' caused by the non-atomic updates
to the component devices which can cause data loss during recovery.
The journal device is used as writethrough thus causing writes to
be throttled versus non-journaled raid4/5/6 sets.
Takeover/reshape is not possible with a raid4/5/6 journal device;
it has to be deconfigured before requesting these.
[journal_mode <mode>]
This option sets the caching mode on journaled raid4/5/6 raid sets
(see 'journal_dev <dev>' above) to 'writethrough' or 'writeback'.
If 'writeback' is selected the journal device has to be resilient
and must not suffer from the 'write hole' problem itself (e.g. use
raid1 or raid10) to avoid a single point of failure.
<#raid_devs>: The number of devices composing the array.
Each device consists of two entries. The first is the device
containing the metadata (if any); the second is the one containing the
data. A Maximum of 64 metadata/data device entries are supported
up to target version 1.8.0.
1.9.0 supports up to 253 which is enforced by the used MD kernel runtime.
data.
If a drive has failed or is missing at creation time, a '-' can be
given for both the metadata and data drives for a given position.
@@ -258,14 +195,6 @@ recovery. Here is a fuller description of the individual fields:
in RAID1/10 or wrong parity values found in RAID4/5/6.
This value is valid only after a "check" of the array
is performed. A healthy array has a 'mismatch_cnt' of 0.
<data_offset> The current data offset to the start of the user data on
each component device of a raid set (see the respective
raid parameter to support out-of-place reshaping).
<journal_char> 'A' - active write-through journal device.
'a' - active write-back journal device.
'D' - dead journal device.
'-' - no journal device.
Message Interface
-----------------
@@ -278,6 +207,7 @@ include:
"recover"- Initiate/continue a recover process.
"check" - Initiate a check (i.e. a "scrub") of the array.
"repair" - Initiate a repair of the array.
"reshape"- Currently unsupported (-EINVAL).
Discard Support
@@ -327,19 +257,3 @@ Version History
1.5.2 'mismatch_cnt' is zero unless [last_]sync_action is "check".
1.6.0 Add discard support (and devices_handle_discard_safely module param).
1.7.0 Add support for MD RAID0 mappings.
1.8.0 Explicitly check for compatible flags in the superblock metadata
and reject to start the raid set if any are set by a newer
target version, thus avoiding data corruption on a raid set
with a reshape in progress.
1.9.0 Add support for RAID level takeover/reshape/region size
and set size reduction.
1.9.1 Fix activation of existing RAID 4/10 mapped devices
1.9.2 Don't emit '- -' on the status table line in case the constructor
fails reading a superblock. Correctly emit 'maj:min1 maj:min2' and
'D' on the status line. If '- -' is passed into the constructor, emit
'- -' on the table line and '-' as the status line health character.
1.10.0 Add support for raid4/5/6 journal device
1.10.1 Fix data corruption on reshape request
1.11.0 Fix table line argument order
(wrong raid10_copies/raid10_format sequence)
1.11.1 Add raid4/5/6 journal write-back support via journal_mode option

View File

@@ -37,9 +37,9 @@ if (!$num_devs) {
die("Specify at least one device\n");
}
$min_dev_size = `blockdev --getsz $devs[0]`;
$min_dev_size = `blockdev --getsize $devs[0]`;
for ($i = 1; $i < $num_devs; $i++) {
my $this_size = `blockdev --getsz $devs[$i]`;
my $this_size = `blockdev --getsize $devs[$i]`;
$min_dev_size = ($min_dev_size < $this_size) ?
$min_dev_size : $this_size;
}

View File

@@ -123,7 +123,7 @@ Assume that you have volumes vg1/switch0 vg1/switch1 vg1/switch2 with
the same size.
Create a switch device with 64kB region size:
dmsetup create switch --table "0 `blockdev --getsz /dev/vg1/switch0`
dmsetup create switch --table "0 `blockdev --getsize /dev/vg1/switch0`
switch 3 128 0 /dev/vg1/switch0 0 /dev/vg1/switch1 0 /dev/vg1/switch2 0"
Set mappings for the first 7 entries to point to devices switch0, switch1,

View File

@@ -1,144 +0,0 @@
dm-zoned
========
The dm-zoned device mapper target exposes a zoned block device (ZBC and
ZAC compliant devices) as a regular block device without any write
pattern constraints. In effect, it implements a drive-managed zoned
block device which hides from the user (a file system or an application
doing raw block device accesses) the sequential write constraints of
host-managed zoned block devices and can mitigate the potential
device-side performance degradation due to excessive random writes on
host-aware zoned block devices.
For a more detailed description of the zoned block device models and
their constraints see (for SCSI devices):
http://www.t10.org/drafts.htm#ZBC_Family
and (for ATA devices):
http://www.t13.org/Documents/UploadedDocuments/docs2015/di537r05-Zoned_Device_ATA_Command_Set_ZAC.pdf
The dm-zoned implementation is simple and minimizes system overhead (CPU
and memory usage as well as storage capacity loss). For a 10TB
host-managed disk with 256 MB zones, dm-zoned memory usage per disk
instance is at most 4.5 MB and as little as 5 zones will be used
internally for storing metadata and performaing reclaim operations.
dm-zoned target devices are formatted and checked using the dmzadm
utility available at:
https://github.com/hgst/dm-zoned-tools
Algorithm
=========
dm-zoned implements an on-disk buffering scheme to handle non-sequential
write accesses to the sequential zones of a zoned block device.
Conventional zones are used for caching as well as for storing internal
metadata.
The zones of the device are separated into 2 types:
1) Metadata zones: these are conventional zones used to store metadata.
Metadata zones are not reported as useable capacity to the user.
2) Data zones: all remaining zones, the vast majority of which will be
sequential zones used exclusively to store user data. The conventional
zones of the device may be used also for buffering user random writes.
Data in these zones may be directly mapped to the conventional zone, but
later moved to a sequential zone so that the conventional zone can be
reused for buffering incoming random writes.
dm-zoned exposes a logical device with a sector size of 4096 bytes,
irrespective of the physical sector size of the backend zoned block
device being used. This allows reducing the amount of metadata needed to
manage valid blocks (blocks written).
The on-disk metadata format is as follows:
1) The first block of the first conventional zone found contains the
super block which describes the on disk amount and position of metadata
blocks.
2) Following the super block, a set of blocks is used to describe the
mapping of the logical device blocks. The mapping is done per chunk of
blocks, with the chunk size equal to the zoned block device size. The
mapping table is indexed by chunk number and each mapping entry
indicates the zone number of the device storing the chunk of data. Each
mapping entry may also indicate if the zone number of a conventional
zone used to buffer random modification to the data zone.
3) A set of blocks used to store bitmaps indicating the validity of
blocks in the data zones follows the mapping table. A valid block is
defined as a block that was written and not discarded. For a buffered
data chunk, a block is always valid only in the data zone mapping the
chunk or in the buffer zone of the chunk.
For a logical chunk mapped to a conventional zone, all write operations
are processed by directly writing to the zone. If the mapping zone is a
sequential zone, the write operation is processed directly only if the
write offset within the logical chunk is equal to the write pointer
offset within of the sequential data zone (i.e. the write operation is
aligned on the zone write pointer). Otherwise, write operations are
processed indirectly using a buffer zone. In that case, an unused
conventional zone is allocated and assigned to the chunk being
accessed. Writing a block to the buffer zone of a chunk will
automatically invalidate the same block in the sequential zone mapping
the chunk. If all blocks of the sequential zone become invalid, the zone
is freed and the chunk buffer zone becomes the primary zone mapping the
chunk, resulting in native random write performance similar to a regular
block device.
Read operations are processed according to the block validity
information provided by the bitmaps. Valid blocks are read either from
the sequential zone mapping a chunk, or if the chunk is buffered, from
the buffer zone assigned. If the accessed chunk has no mapping, or the
accessed blocks are invalid, the read buffer is zeroed and the read
operation terminated.
After some time, the limited number of convnetional zones available may
be exhausted (all used to map chunks or buffer sequential zones) and
unaligned writes to unbuffered chunks become impossible. To avoid this
situation, a reclaim process regularly scans used conventional zones and
tries to reclaim the least recently used zones by copying the valid
blocks of the buffer zone to a free sequential zone. Once the copy
completes, the chunk mapping is updated to point to the sequential zone
and the buffer zone freed for reuse.
Metadata Protection
===================
To protect metadata against corruption in case of sudden power loss or
system crash, 2 sets of metadata zones are used. One set, the primary
set, is used as the main metadata region, while the secondary set is
used as a staging area. Modified metadata is first written to the
secondary set and validated by updating the super block in the secondary
set, a generation counter is used to indicate that this set contains the
newest metadata. Once this operation completes, in place of metadata
block updates can be done in the primary metadata set. This ensures that
one of the set is always consistent (all modifications committed or none
at all). Flush operations are used as a commit point. Upon reception of
a flush request, metadata modification activity is temporarily blocked
(for both incoming BIO processing and reclaim process) and all dirty
metadata blocks are staged and updated. Normal operation is then
resumed. Flushing metadata thus only temporarily delays write and
discard requests. Read requests can be processed concurrently while
metadata flush is being executed.
Usage
=====
A zoned block device must first be formatted using the dmzadm tool. This
will analyze the device zone configuration, determine where to place the
metadata sets on the device and initialize the metadata sets.
Ex:
dmzadm --format /dev/sdxx
For a formatted device, the target can be created normally with the
dmsetup utility. The only parameter that dm-zoned requires is the
underlying zoned block device name. Ex:
echo "0 `blockdev --getsize ${dev}` zoned ${dev}" | dmsetup create dmz-`basename ${dev}`

View File

@@ -127,9 +127,6 @@
/* Path to dmeventd pidfile. */
#undef DMEVENTD_PIDFILE
/* Define to 1 to enable the device-mapper filemap daemon. */
#undef DMFILEMAPD
/* Define to enable compat protocol */
#undef DM_COMPAT
@@ -148,9 +145,6 @@
/* Library version */
#undef DM_LIB_VERSION
/* Path to fsadm binary. */
#undef FSADM_PATH
/* Define to 1 if you have the `alarm' function. */
#undef HAVE_ALARM
@@ -494,9 +488,6 @@
/* Define to 1 if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
/* Define to 1 if you have the <sys/inotify.h> header file. */
#undef HAVE_SYS_INOTIFY_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
@@ -632,9 +623,6 @@
/* Define to 1 to include code that uses lvmpolld. */
#undef LVMPOLLD_SUPPORT
/* configure command line used */
#undef LVM_CONFIGURE_LINE
/* Path to lvm binary. */
#undef LVM_PATH

View File

@@ -48,10 +48,6 @@ ifeq ("@CACHE@", "shared")
SUBDIRS += cache_segtype
endif
ifeq ("@CLUSTER@", "shared")
SUBDIRS += locking
endif
SOURCES =\
activate/activate.c \
cache/lvmcache.c \
@@ -153,6 +149,10 @@ ifeq ("@CLUSTER@", "internal")
SOURCES += locking/cluster_locking.c
endif
ifeq ("@CLUSTER@", "shared")
SUBDIRS += locking
endif
ifeq ("@SNAPSHOTS@", "internal")
SOURCES += snapshot/snapshot.c
endif
@@ -204,6 +204,11 @@ ifeq ("@BUILD_LVMLOCKD@", "yes")
locking/lvmlockd.c
endif
ifeq ("@DMEVENTD@", "yes")
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd
LIBS += -ldevmapper-event
endif
LIB_NAME = liblvm-internal
LIB_STATIC = $(LIB_NAME).a
@@ -224,10 +229,10 @@ endif
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
PROGS_CFLAGS = $(BLKID_CFLAGS) $(UDEV_CFLAGS)
include $(top_builddir)/make.tmpl
CFLAGS += $(BLKID_CFLAGS) $(UDEV_CFLAGS) $(VALGRIND_CFLAGS)
$(SUBDIRS): $(LIB_STATIC)
CLEAN_TARGETS += misc/configure.h misc/lvm-version.h

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -150,15 +150,15 @@ static int _lv_passes_volumes_filter(struct cmd_context *cmd, const struct logic
|| str_list_match_list(&cmd->tags,
&lv->vg->tags, NULL))
return 1;
continue;
else
continue;
}
/* If supplied tag matches LV or VG tag, activate */
if (str_list_match_item(&lv->tags, str) ||
str_list_match_item(&lv->vg->tags, str))
return 1;
continue;
else
continue;
}
/* If supplied name is vgname[/lvname] */
@@ -272,18 +272,10 @@ int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
{
return 0;
}
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
{
return 0;
}
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
{
return 0;
}
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
{
return 0;
}
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
{
return 0;
@@ -781,8 +773,7 @@ int lv_info_with_seg_status(struct cmd_context *cmd,
if (lv_is_used_cache_pool(lv)) {
/* INFO is not set as cache-pool cannot be active.
* STATUS is collected from cache LV */
if (!(lv_seg = get_only_segment_using_this_lv(lv)))
return_0;
lv_seg = get_only_segment_using_this_lv(lv);
(void) _lv_info(cmd, lv_seg->lv, 1, NULL, lv_seg, &status->seg_status, 0, 0);
return 1;
}
@@ -797,18 +788,14 @@ int lv_info_with_seg_status(struct cmd_context *cmd,
status->info.exists = 0; /* So pool LV is not active */
}
return 1;
}
if (lv_is_external_origin(lv)) {
} else if (lv_is_external_origin(lv)) {
if (!_lv_info(cmd, lv, 0, &status->info, NULL, NULL,
with_open_count, with_read_ahead))
return_0;
(void) _lv_info(cmd, lv, 1, NULL, lv_seg, &status->seg_status, 0, 0);
return 1;
}
if (lv_is_origin(lv)) {
} else if (lv_is_origin(lv)) {
/* Query segment status for 'layered' (-real) device most of the time,
* only for merging snapshot, query its progress.
* TODO: single LV may need couple status to be exposed at once....
@@ -825,9 +812,7 @@ int lv_info_with_seg_status(struct cmd_context *cmd,
/* Grab STATUS from layered -real */
(void) _lv_info(cmd, lv, 1, NULL, lv_seg, &status->seg_status, 0, 0);
return 1;
}
if (lv_is_cow(lv)) {
} else if (lv_is_cow(lv)) {
if (lv_is_merging_cow(lv)) {
olv = origin_from_cow(lv);
@@ -842,6 +827,7 @@ int lv_info_with_seg_status(struct cmd_context *cmd,
* When merge is in progress, query merging origin LV instead.
* COW volume is already mapped as error target in this case.
*/
status->lv = olv;
return 1;
}
@@ -998,30 +984,6 @@ int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
return lv_mirror_percent(lv->vg->cmd, lv, 0, percent, NULL);
}
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
{
int r;
struct dev_manager *dm;
struct dm_status_raid *status;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
log_debug_activation("Checking raid data offset and dev sectors for LV %s/%s",
lv->vg->name, lv->name);
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!(r = dev_manager_raid_status(dm, lv, &status)))
stack;
*data_offset = status->data_offset;
dev_manager_destroy(dm);
return r;
}
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
{
int r;
@@ -1051,32 +1013,6 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
return r;
}
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
{
struct dev_manager *dm;
struct dm_status_raid *status;
*dev_cnt = 0;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
log_debug_activation("Checking raid device count for LV %s/%s",
lv->vg->name, lv->name);
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!dev_manager_raid_status(dm, lv, &status)) {
dev_manager_destroy(dm);
return_0;
}
*dev_cnt = status->dev_count;
dev_manager_destroy(dm);
return 1;
}
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
{
struct dev_manager *dm;
@@ -1855,15 +1791,12 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
* However in case command would have crashed, such LV is
* left unmonitored and may potentially require dmeventd.
*/
if (lv_is_cache_pool_data(lv) || lv_is_cache_pool_metadata(lv)) {
if (!(seg = find_pool_seg(first_seg(lv))))
return_0;
if (!lv_is_used_cache_pool(seg->lv)) {
log_debug_activation("Skipping %smonitor of %s.%s",
(monitor) ? "" : "un", display_lvname(lv),
(monitor) ? " Cache pool activation for clearing only." : "");
return 1;
}
if ((lv_is_cache_pool_data(lv) || lv_is_cache_pool_metadata(lv)) &&
!lv_is_used_cache_pool((find_pool_seg(first_seg(lv))->lv))) {
log_debug_activation("Skipping %smonitor of %s.%s",
(monitor) ? "" : "un", display_lvname(lv),
(monitor) ? " Cache pool activation for clearing only." : "");
return 1;
}
/*
@@ -2015,13 +1948,16 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
/* Check [un]monitor results */
/* Try a couple times if pending, but not forever... */
for (i = 0;; i++) {
for (i = 0; i < 40; i++) {
pending = 0;
monitored = seg->segtype->ops->target_monitored(seg, &pending);
if (!pending || i >= 40)
if (pending ||
(!monitored && monitor) ||
(monitored && !monitor))
log_very_verbose("%s %smonitoring still pending: waiting...",
display_lvname(lv), monitor ? "" : "un");
else
break;
log_very_verbose("%s %smonitoring still pending: waiting...",
display_lvname(lv), monitor ? "" : "un");
usleep(10000 * i);
}

View File

@@ -168,13 +168,11 @@ int lv_snapshot_percent(const struct logical_volume *lv, dm_percent_t *percent);
int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
int wait, dm_percent_t *percent, uint32_t *event_nr);
int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent);
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt);
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset);
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health);
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt);
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action);
int lv_raid_message(const struct logical_volume *lv, const char *msg);
int lv_cache_status(const struct logical_volume *cache_lv,
int lv_cache_status(const struct logical_volume *lv,
struct lv_status_cache **status);
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
dm_percent_t *percent);
@@ -202,12 +200,12 @@ int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer, const char *target_type);
int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume *lv,
const struct lv_activate_opts *laopts, int monitor);
const struct lv_activate_opts *laopts, int do_reg);
#ifdef DMEVENTD
# include "libdevmapper-event.h"
char *get_monitor_dso_path(struct cmd_context *cmd, const char *libpath);
int target_registered_with_dmeventd(struct cmd_context *cmd, const char *dso,
int target_registered_with_dmeventd(struct cmd_context *cmd, const char *libpath,
const struct logical_volume *lv, int *pending);
int target_register_events(struct cmd_context *cmd, const char *dso, const struct logical_volume *lv,
int evmask __attribute__((unused)), int set, int timeout);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -214,14 +214,6 @@ typedef enum {
STATUS, /* DM_DEVICE_STATUS ioctl */
} info_type_t;
/* Return length of segment depending on type and reshape_len */
static uint32_t _seg_len(const struct lv_segment *seg)
{
uint32_t reshape_len = seg_is_raid(seg) ? ((seg->area_count - seg->segtype->parity_devs) * seg->reshape_len) : 0;
return seg->len - reshape_len;
}
static int _info_run(const char *dlid, struct dm_info *dminfo,
uint32_t *read_ahead,
struct lv_seg_status *seg_status,
@@ -258,12 +250,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
if (seg_status && dminfo->exists) {
start = length = seg_status->seg->lv->vg->extent_size;
start *= seg_status->seg->le;
length *= _seg_len(seg_status->seg);
/* Uses max DM_THIN_MAX_METADATA_SIZE sectors for metadata device */
if (lv_is_thin_pool_metadata(seg_status->seg->lv) &&
(length > DM_THIN_MAX_METADATA_SIZE))
length = DM_THIN_MAX_METADATA_SIZE;
length *= seg_status->seg->len;
do {
target = dm_get_next_target(dmt, target, &target_start,
@@ -275,8 +262,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
target_params = NULL; /* Marking this target_params unusable */
} while (target);
if (!target_name ||
!_get_segment_status_from_target_params(target_name, target_params, seg_status))
if (!_get_segment_status_from_target_params(target_name, target_params, seg_status))
stack;
}
@@ -1038,8 +1024,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
goto_out;
}
log_debug_activation("LV percent: %s",
display_percent(dm->cmd, *overall_percent));
log_debug_activation("LV percent: %.2f", dm_percent_to_float(*overall_percent));
r = 1;
out:
@@ -1056,11 +1041,10 @@ static int _percent(struct dev_manager *dm, const char *name, const char *dlid,
if (_percent_run(dm, NULL, dlid, target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported))
return 1;
if (_original_uuid_format_check_required(dm->cmd) &&
_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1,
target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported))
else if (_original_uuid_format_check_required(dm->cmd) &&
_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1,
target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported))
return 1;
}
@@ -1324,13 +1308,14 @@ int dev_manager_raid_message(struct dev_manager *dm,
return 0;
}
/* These are the supported RAID messages for dm-raid v1.9.0 */
/* These are the supported RAID messages for dm-raid v1.5.0 */
if (strcmp(msg, "idle") &&
strcmp(msg, "frozen") &&
strcmp(msg, "resync") &&
strcmp(msg, "recover") &&
strcmp(msg, "check") &&
strcmp(msg, "repair")) {
strcmp(msg, "repair") &&
strcmp(msg, "reshape")) {
log_error(INTERNAL_ERROR "Unknown RAID message: %s.", msg);
return 0;
}
@@ -2229,7 +2214,7 @@ static char *_add_error_or_zero_device(struct dev_manager *dm, struct dm_tree *d
struct lv_segment *seg_i;
struct dm_info info;
int segno = -1, i = 0;
uint64_t size = (uint64_t) _seg_len(seg) * seg->lv->vg->extent_size;
uint64_t size = (uint64_t) seg->len * seg->lv->vg->extent_size;
dm_list_iterate_items(seg_i, &seg->lv->segments) {
if (seg == seg_i) {
@@ -2515,7 +2500,7 @@ static int _add_target_to_dtree(struct dev_manager *dm,
return seg->segtype->ops->add_target_line(dm, dm->mem, dm->cmd,
&dm->target_state, seg,
laopts, dnode,
extent_size * _seg_len(seg),
extent_size * seg->len,
&dm->pvmove_mirror_count);
}
@@ -2708,7 +2693,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
/* Replace target and all its used devs with error mapping */
log_debug_activation("Using error for pending delete %s.",
display_lvname(seg->lv));
if (!dm_tree_node_add_error_target(dnode, (uint64_t)seg->lv->vg->extent_size * _seg_len(seg)))
if (!dm_tree_node_add_error_target(dnode, (uint64_t)seg->lv->vg->extent_size * seg->len))
return_0;
} else if (!_add_target_to_dtree(dm, dnode, seg, laopts))
return_0;
@@ -3180,6 +3165,7 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
log_error(INTERNAL_ERROR "_tree_action: Action %u not supported.", action);
goto out;
}
r = 1;
out:

View File

@@ -186,11 +186,11 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
!stat(lv_path, &buf)) {
if (buf_lp.st_rdev == buf.st_rdev)
return 1;
log_warn("Symlink %s that should have been "
"created by udev does not have "
"correct target. Falling back to "
"direct link creation", lv_path);
else
log_warn("Symlink %s that should have been "
"created by udev does not have "
"correct target. Falling back to "
"direct link creation", lv_path);
} else
log_warn("Symlink %s that should have been "
"created by udev could not be checked "
@@ -239,9 +239,7 @@ static int _rm_link(const char *dev_dir, const char *vg_name,
return 1;
log_sys_error("lstat", lv_path);
return 0;
}
if (dm_udev_get_sync_support() && udev_checking() && check_udev)
} else if (dm_udev_get_sync_support() && udev_checking() && check_udev)
log_warn("The link %s should have been removed by udev "
"but it is still present. Falling back to "
"direct link removal.", lv_path);
@@ -480,9 +478,9 @@ int fs_rename_lv(const struct logical_volume *lv, const char *dev,
_fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name,
lv->name, dev, "", lv->vg->cmd->current_settings.udev_rules));
}
return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, old_lvname, lv->vg->cmd->current_settings.udev_rules);
else
return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, old_lvname, lv->vg->cmd->current_settings.udev_rules);
}
void fs_unlock(void)

11
lib/cache/lvmcache.c vendored
View File

@@ -1600,6 +1600,8 @@ void lvmcache_del(struct lvmcache_info *info)
info->label->labeller->ops->destroy_label(info->label->labeller,
info->label);
dm_free(info);
return;
}
/*
@@ -1896,7 +1898,8 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
info->vginfo->creation_host))
goto set_lock_type;
dm_free(info->vginfo->creation_host);
if (info->vginfo->creation_host)
dm_free(info->vginfo->creation_host);
if (!(info->vginfo->creation_host = dm_strdup(creation_host))) {
log_error("cache creation host alloc failed for %s.",
@@ -1915,7 +1918,8 @@ set_lock_type:
if (info->vginfo->lock_type && !strcmp(lock_type, info->vginfo->lock_type))
goto set_system_id;
dm_free(info->vginfo->lock_type);
if (info->vginfo->lock_type)
dm_free(info->vginfo->lock_type);
if (!(info->vginfo->lock_type = dm_strdup(lock_type))) {
log_error("cache lock_type alloc failed for %s", lock_type);
@@ -1933,7 +1937,8 @@ set_system_id:
if (info->vginfo->system_id && !strcmp(system_id, info->vginfo->system_id))
goto out;
dm_free(info->vginfo->system_id);
if (info->vginfo->system_id)
dm_free(info->vginfo->system_id);
if (!(info->vginfo->system_id = dm_strdup(system_id))) {
log_error("cache system_id alloc failed for %s", system_id);

View File

@@ -181,7 +181,7 @@ int lvmcache_foreach_ba(struct lvmcache_info *info,
int (*fun)(struct disk_locn *, void *),
void *baton);
int lvmcache_foreach_pv(struct lvmcache_vginfo *vginfo,
int lvmcache_foreach_pv(struct lvmcache_vginfo *vg,
int (*fun)(struct lvmcache_info *, void *), void * baton);
uint64_t lvmcache_device_size(struct lvmcache_info *info);

22
lib/cache/lvmetad.c vendored
View File

@@ -66,7 +66,7 @@ static int _log_debug_inequality(const char *name, struct dm_config_node *a, str
log_debug_lvmetad("VG %s metadata inequality at %s / %s: %s / %s",
name, a->key, b->key, av->v.str, bv->v.str);
else if (a->v->type == DM_CFG_INT && b->v->type == DM_CFG_INT)
log_debug_lvmetad("VG %s metadata inequality at %s / %s: " FMTd64 " / " FMTd64,
log_debug_lvmetad("VG %s metadata inequality at %s / %s: " FMTi64 " / " FMTi64,
name, a->key, b->key, av->v.i, bv->v.i);
else
log_debug_lvmetad("VG %s metadata inequality at %s / %s: type %d / type %d",
@@ -145,14 +145,13 @@ int lvmetad_connect(struct cmd_context *cmd)
_lvmetad_use = 1;
_lvmetad_cmd = cmd;
return 1;
} else {
log_debug_lvmetad("Failed to connect to lvmetad: %s", strerror(_lvmetad.error));
_lvmetad_connected = 0;
_lvmetad_use = 0;
_lvmetad_cmd = NULL;
return 0;
}
log_debug_lvmetad("Failed to connect to lvmetad: %s", strerror(_lvmetad.error));
_lvmetad_connected = 0;
_lvmetad_use = 0;
_lvmetad_cmd = NULL;
return 0;
}
int lvmetad_used(void)
@@ -663,7 +662,7 @@ static int _lvmetad_handle_reply(daemon_reply reply, const char *id, const char
}
if (reply.error) {
log_error("lvmetad cannot be used due to error: %s", strerror(reply.error));
log_warn("WARNING: lvmetad cannot be used due to error: %s", strerror(reply.error));
goto fail;
}
@@ -1305,7 +1304,7 @@ int lvmetad_vg_remove_pending(struct volume_group *vg)
reply = _lvmetad_send(vg->cmd, "set_vg_info",
"name = %s", vg->name,
"uuid = %s", uuid,
"version = %"PRId64, (int64_t)0,
"version = %d", 0,
NULL);
if (!_lvmetad_handle_reply(reply, "set_vg_info", vg->name, NULL)) {
@@ -2875,9 +2874,6 @@ int lvmetad_is_disabled(struct cmd_context *cmd, const char **reason)
} else if (strstr(reply_reason, LVMETAD_DISABLE_REASON_DIRECT)) {
*reason = "the disable flag was set directly";
} else if (strstr(reply_reason, LVMETAD_DISABLE_REASON_REPAIR)) {
*reason = "a repair command was run";
} else if (strstr(reply_reason, LVMETAD_DISABLE_REASON_LVM1)) {
*reason = "LVM1 metadata was found";

View File

@@ -36,38 +36,6 @@ static unsigned _feature_mask;
log_error(t " segment %s of logical volume %s.", ## p, \
dm_config_parent_name(sn), seg->lv->name), 0;
static int _cache_out_line(const char *line, void *_f)
{
log_print(" Setting\t\t%s", line);
return 1;
}
static void _cache_display(const struct lv_segment *seg)
{
const struct dm_config_node *n;
const struct lv_segment *pool_seg =
seg_is_cache_pool(seg) ? seg : first_seg(seg->pool_lv);
log_print(" Chunk size\t\t%s",
display_size(seg->lv->vg->cmd, pool_seg->chunk_size));
if (pool_seg->cache_metadata_format != CACHE_METADATA_FORMAT_UNSELECTED)
log_print(" Metadata format\t%u", pool_seg->cache_metadata_format);
if (pool_seg->cache_mode != CACHE_MODE_UNSELECTED)
log_print(" Mode\t\t%s", get_cache_mode_name(pool_seg));
if (pool_seg->policy_name)
log_print(" Policy\t\t%s", pool_seg->policy_name);
if (pool_seg->policy_settings &&
(n = pool_seg->policy_settings->child))
dm_config_write_node(n, _cache_out_line, NULL);
log_print(" ");
}
/*
* When older metadata are loaded without newer settings,
* set then to default settings (the one that could have been
@@ -84,13 +52,7 @@ static void _fix_missing_defaults(struct lv_segment *cpool_seg)
cpool_seg->policy_name);
}
if (cpool_seg->cache_metadata_format == CACHE_METADATA_FORMAT_UNSELECTED) {
cpool_seg->cache_metadata_format = CACHE_METADATA_FORMAT_1;
log_verbose("Cache pool %s uses implicit metadata format %u.",
display_lvname(cpool_seg->lv), cpool_seg->cache_metadata_format);
}
if (cpool_seg->cache_mode == CACHE_MODE_UNSELECTED) {
if (cpool_seg->cache_mode == CACHE_MODE_UNDEFINED) {
cpool_seg->cache_mode = CACHE_MODE_WHEN_MISSING;
log_verbose("Cache pool %s is missing cache mode, using %s.",
display_lvname(cpool_seg->lv),
@@ -145,16 +107,6 @@ static int _cache_pool_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Failed to duplicate policy in");
}
if (dm_config_has_node(sn, "metadata_format")) {
if (!dm_config_get_uint32(sn, "metadata_format", &seg->cache_metadata_format) ||
((seg->cache_metadata_format != CACHE_METADATA_FORMAT_1) &&
(seg->cache_metadata_format != CACHE_METADATA_FORMAT_2)))
return SEG_LOG_ERROR("Unknown cache metadata format %u number in",
seg->cache_metadata_format);
if (seg->cache_metadata_format == CACHE_METADATA_FORMAT_2)
seg->lv->status |= LV_METADATA_FORMAT;
}
/*
* Read in policy args:
* policy_settings {
@@ -212,31 +164,12 @@ static int _cache_pool_text_export(const struct lv_segment *seg,
outf(f, "metadata = \"%s\"", seg->metadata_lv->name);
outf(f, "chunk_size = %" PRIu32, seg->chunk_size);
switch (seg->cache_metadata_format) {
case CACHE_METADATA_FORMAT_UNSELECTED:
/* Unselected format is not printed */
break;
case CACHE_METADATA_FORMAT_1:
/* If format 1 was already specified with cache pool, store it,
* otherwise format gets stored when LV is cached.
* NB: format 1 could be lost anytime, it's a default format.
* Older lvm2 tool can easily drop it.
*/
case CACHE_METADATA_FORMAT_2: /* more in future ? */
outf(f, "metadata_format = " FMTu32, seg->cache_metadata_format);
break;
default:
log_error(INTERNAL_ERROR "LV %s is using unknown cache metadada format %u.",
display_lvname(seg->lv), seg->cache_metadata_format);
return 0;
}
/*
* Cache pool used by a cache LV holds data. Not ideal,
* but not worth to break backward compatibility, by shifting
* content to cache segment
*/
if (seg->cache_mode != CACHE_MODE_UNSELECTED) {
if (seg->cache_mode != CACHE_MODE_UNDEFINED) {
if (!(cache_mode = get_cache_mode_name(seg)))
return_0;
outf(f, "cache_mode = \"%s\"", cache_mode);
@@ -265,39 +198,6 @@ static void _destroy(struct segment_type *segtype)
}
#ifdef DEVMAPPER_SUPPORT
/*
* Parse and look for kernel symbol in /proc/kallsyms
* this could be our only change to figure out there is
* cache policy symbol already in the monolithic kernel
* where 'modprobe dm-cache-smq' will simply not work
*/
static int _lookup_kallsyms(const char *symbol)
{
static const char _syms[] = "/proc/kallsyms";
int ret = 0;
char *line = NULL;
size_t len;
FILE *s;
if (!(s = fopen(_syms, "r")))
log_sys_debug("fopen", _syms);
else {
while (getline(&line, &len, s) != -1)
if (strstr(line, symbol)) {
ret = 1; /* Found symbol */
log_debug("Found kernel symbol%s.", symbol); /* space is in symbol */
break;
}
free(line);
if (fclose(s))
log_sys_debug("fclose", _syms);
}
return ret;
}
static int _target_present(struct cmd_context *cmd,
const struct lv_segment *seg __attribute__((unused)),
unsigned *attributes __attribute__((unused)))
@@ -310,15 +210,13 @@ static int _target_present(struct cmd_context *cmd,
unsigned cache_alias;
const char feature[12];
const char module[12]; /* check dm-%s */
const char ksymbol[12]; /* check for kernel symbol */
const char *aliasing;
} _features[] = {
{ 1, 10, CACHE_FEATURE_METADATA2, 0, "metadata2" },
/* Assumption: cache >=1.9 always aliases MQ policy */
{ 1, 9, CACHE_FEATURE_POLICY_SMQ, CACHE_FEATURE_POLICY_MQ, "policy_smq", "cache-smq",
" smq_exit", " and aliases cache-mq" },
{ 1, 8, CACHE_FEATURE_POLICY_SMQ, 0, "policy_smq", "cache-smq", " smq_exit" },
{ 1, 3, CACHE_FEATURE_POLICY_MQ, 0, "policy_mq", "cache-mq", " mq_init" },
" and aliases cache-mq" },
{ 1, 8, CACHE_FEATURE_POLICY_SMQ, 0, "policy_smq", "cache-smq" },
{ 1, 3, CACHE_FEATURE_POLICY_MQ, 0, "policy_mq", "cache-mq" },
};
static const char _lvmconf[] = "global/cache_disabled_features";
static unsigned _attrs = 0;
@@ -352,20 +250,9 @@ static int _target_present(struct cmd_context *cmd,
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i) {
if (_attrs & _features[i].cache_feature)
continue; /* already present */
if (!_features[i].module[0]) {
if ((maj > _features[i].maj) ||
(maj == _features[i].maj && min >= _features[i].min)) {
log_debug_activation("Cache supports %s.",
_features[i].feature);
_attrs |= _features[i].cache_feature;
}
continue;
}
if (((maj > _features[i].maj) ||
(maj == _features[i].maj && min >= _features[i].min)) &&
((_features[i].ksymbol[0] && _lookup_kallsyms(_features[i].ksymbol)) ||
module_present(cmd, _features[i].module))) {
module_present(cmd, _features[i].module)) {
log_debug_activation("Cache policy %s is available%s.",
_features[i].module,
_features[i].aliasing ? : "");
@@ -423,7 +310,6 @@ static int _modules_needed(struct dm_pool *mem,
#endif /* DEVMAPPER_SUPPORT */
static struct segtype_handler _cache_pool_ops = {
.display = _cache_display,
.text_import = _cache_pool_text_import,
.text_import_area_count = _cache_pool_text_import_area_count,
.text_export = _cache_pool_text_export,
@@ -513,7 +399,6 @@ static int _cache_add_target_line(struct dev_manager *dm,
struct lv_segment *cache_pool_seg;
char *metadata_uuid, *data_uuid, *origin_uuid;
uint64_t feature_flags = 0;
unsigned attr;
if (!seg->pool_lv || !seg_is_cache(seg)) {
log_error(INTERNAL_ERROR "Passed segment is not cache.");
@@ -541,26 +426,6 @@ static int _cache_add_target_line(struct dev_manager *dm,
break;
}
switch (cache_pool_seg->cache_metadata_format) {
case CACHE_METADATA_FORMAT_1: break;
case CACHE_METADATA_FORMAT_2:
if (!_target_present(cmd, NULL, &attr))
return_0;
if (!(attr & CACHE_FEATURE_METADATA2)) {
log_error("LV %s has metadata format %u unsuported by kernel.",
display_lvname(seg->lv), cache_pool_seg->cache_metadata_format);
return 0;
}
feature_flags |= DM_CACHE_FEATURE_METADATA2;
log_debug_activation("Using metadata2 format for %s.", display_lvname(seg->lv));
break;
default:
log_error(INTERNAL_ERROR "LV %s has unknown metadata format %u.",
display_lvname(seg->lv), cache_pool_seg->cache_metadata_format);
return 0;
}
if (!(metadata_uuid = build_dm_uuid(mem, cache_pool_seg->metadata_lv, NULL)))
return_0;
@@ -587,7 +452,6 @@ static int _cache_add_target_line(struct dev_manager *dm,
#endif /* DEVMAPPER_SUPPORT */
static struct segtype_handler _cache_ops = {
.display = _cache_display,
.text_import = _cache_text_import,
.text_import_area_count = _cache_text_import_area_count,
.text_export = _cache_text_export,

View File

@@ -474,12 +474,10 @@ bad:
int process_profilable_config(struct cmd_context *cmd)
{
const char *units;
if (!(cmd->default_settings.unit_factor =
dm_units_to_factor(units = find_config_tree_str(cmd, global_units_CFG, NULL),
dm_units_to_factor(find_config_tree_str(cmd, global_units_CFG, NULL),
&cmd->default_settings.unit_type, 1, NULL))) {
log_error("Unrecognised configuration setting for global/units: %s", units);
log_error("Invalid units specification");
return 0;
}
@@ -2011,6 +2009,7 @@ out:
cmd = NULL;
}
return cmd;
}

View File

@@ -65,11 +65,11 @@ struct config_source {
* Map each ID to respective definition of the configuration item.
*/
static struct cfg_def_item _cfg_def_items[CFG_COUNT + 1] = {
#define cfg_section(id, name, parent, flags, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_SECTION, {0}, (flags), since_version, {0}, deprecated_since_version, deprecation_comment, comment},
#define cfg(id, name, parent, flags, type, default_value, since_version, unconfigured_value, deprecated_since_version, deprecation_comment, comment) {id, parent, name, type, {.v_##type = (default_value)}, (flags), since_version, {.v_UNCONFIGURED = (unconfigured_value)}, deprecated_since_version, deprecation_comment, comment},
#define cfg_runtime(id, name, parent, flags, type, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, type, {.fn_##type = get_default_##id}, (flags) | CFG_DEFAULT_RUN_TIME, since_version, {.fn_UNCONFIGURED = get_default_unconfigured_##id}, deprecated_since_version, (deprecation_comment), comment},
#define cfg_array(id, name, parent, flags, types, default_value, since_version, unconfigured_value, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_ARRAY | (types), {.v_CFG_TYPE_STRING = (default_value)}, (flags), (since_version), {.v_UNCONFIGURED = (unconfigured_value)}, deprecated_since_version, deprecation_comment, comment},
#define cfg_array_runtime(id, name, parent, flags, types, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_ARRAY | (types), {.fn_CFG_TYPE_STRING = get_default_##id}, (flags) | CFG_DEFAULT_RUN_TIME, (since_version), {.fn_UNCONFIGURED = get_default_unconfigured_##id}, deprecated_since_version, deprecation_comment, comment},
#define cfg_section(id, name, parent, flags, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_SECTION, {0}, flags, since_version, {0}, deprecated_since_version, deprecation_comment, comment},
#define cfg(id, name, parent, flags, type, default_value, since_version, unconfigured_value, deprecated_since_version, deprecation_comment, comment) {id, parent, name, type, {.v_##type = default_value}, flags, since_version, {.v_UNCONFIGURED = unconfigured_value}, deprecated_since_version, deprecation_comment, comment},
#define cfg_runtime(id, name, parent, flags, type, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, type, {.fn_##type = get_default_##id}, flags | CFG_DEFAULT_RUN_TIME, since_version, {.fn_UNCONFIGURED = get_default_unconfigured_##id}, deprecated_since_version, deprecation_comment, comment},
#define cfg_array(id, name, parent, flags, types, default_value, since_version, unconfigured_value, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_ARRAY | types, {.v_CFG_TYPE_STRING = default_value}, flags, since_version, {.v_UNCONFIGURED = unconfigured_value}, deprecated_since_version, deprecation_comment, comment},
#define cfg_array_runtime(id, name, parent, flags, types, since_version, deprecated_since_version, deprecation_comment, comment) {id, parent, name, CFG_TYPE_ARRAY | types, {.fn_CFG_TYPE_STRING = get_default_##id}, flags | CFG_DEFAULT_RUN_TIME, since_version, {.fn_UNCONFIGURED = get_default_unconfigured_##id}, deprecated_since_version, deprecation_comment, comment},
#include "config_settings.h"
#undef cfg_section
#undef cfg
@@ -481,8 +481,7 @@ int override_config_tree_from_profile(struct cmd_context *cmd,
if (profile->source == CONFIG_PROFILE_COMMAND)
return _override_config_tree_from_command_profile(cmd, profile);
if (profile->source == CONFIG_PROFILE_METADATA)
else if (profile->source == CONFIG_PROFILE_METADATA)
return _override_config_tree_from_metadata_profile(cmd, profile);
log_error(INTERNAL_ERROR "override_config_tree_from_profile: incorrect profile source type");
@@ -620,9 +619,9 @@ struct timespec config_file_timestamp(struct dm_config_tree *cft)
}
#define cfg_def_get_item_p(id) (&_cfg_def_items[id])
#define cfg_def_get_default_unconfigured_value_hint(cmd,item) (((item)->flags & CFG_DEFAULT_RUN_TIME) ? (item)->default_unconfigured_value.fn_UNCONFIGURED(cmd) : (item)->default_unconfigured_value.v_UNCONFIGURED)
#define cfg_def_get_default_value_hint(cmd,item,type,profile) (((item)->flags & CFG_DEFAULT_RUN_TIME) ? (item)->default_value.fn_##type(cmd,profile) : (item)->default_value.v_##type)
#define cfg_def_get_default_value(cmd,item,type,profile) ((item)->flags & CFG_DEFAULT_UNDEFINED ? 0 : cfg_def_get_default_value_hint(cmd,item,type,profile))
#define cfg_def_get_default_unconfigured_value_hint(cmd,item) ((item->flags & CFG_DEFAULT_RUN_TIME) ? item->default_unconfigured_value.fn_UNCONFIGURED(cmd) : item->default_unconfigured_value.v_UNCONFIGURED)
#define cfg_def_get_default_value_hint(cmd,item,type,profile) ((item->flags & CFG_DEFAULT_RUN_TIME) ? item->default_value.fn_##type(cmd,profile) : item->default_value.v_##type)
#define cfg_def_get_default_value(cmd,item,type,profile) (item->flags & CFG_DEFAULT_UNDEFINED ? 0 : cfg_def_get_default_value_hint(cmd,item,type,profile))
static int _cfg_def_make_path(char *buf, size_t buf_size, int id, cfg_def_item_t *item, int xlate)
{
@@ -743,16 +742,14 @@ static struct dm_config_value *_get_def_array_values(struct cmd_context *cmd,
switch (toupper(token[0])) {
case 'I':
case 'B':
errno = 0;
v->v.i = strtoll(token + 1, &r, 10);
if (errno || *r)
if (*r)
goto bad;
v->type = DM_CFG_INT;
break;
case 'F':
errno = 0;
v->v.f = strtod(token + 1, &r);
if (errno || *r)
if (*r)
goto bad;
v->type = DM_CFG_FLOAT;
break;
@@ -1880,12 +1877,6 @@ int config_write(struct dm_config_tree *cft,
}
log_verbose("Dumping configuration to %s", file);
if (tree_spec->withgeneralpreamble)
fprintf(baton.fp, CFG_PREAMBLE_GENERAL);
if (tree_spec->withlocalpreamble)
fprintf(baton.fp, CFG_PREAMBLE_LOCAL);
if (!argc) {
if (!dm_config_write_node_out(cft->root, &_out_spec, &baton)) {
log_error("Failure while writing to %s", file);
@@ -2451,13 +2442,21 @@ const char *get_default_activation_mirror_image_fault_policy_CFG(struct cmd_cont
int get_default_allocation_thin_pool_chunk_size_CFG(struct cmd_context *cmd, struct profile *profile)
{
const char *str;
uint32_t chunk_size;
int chunk_size_calc_method;
if (!get_default_allocation_thin_pool_chunk_size(cmd, profile, &chunk_size,
&chunk_size_calc_method)) {
stack; /* Ignore this error, never happens... */
if (!(str = find_config_tree_str(cmd, allocation_thin_pool_chunk_size_policy_CFG, profile))) {
log_error(INTERNAL_ERROR "Cannot find configuration.");
return 0;
}
if (!strcasecmp(str, "generic"))
chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE * 2;
else if (!strcasecmp(str, "performance"))
chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE * 2;
else {
log_error("Thin pool chunk size calculation policy \"%s\" is unrecognised.", str);
return 0;
}
return (int) chunk_size;

View File

@@ -141,7 +141,6 @@ typedef struct cfg_def_item {
uint16_t deprecated_since_version; /* version since this item is deprecated */
const char *deprecation_comment; /* comment about reasons for deprecation and settings that supersede this one */
const char *comment; /* comment */
const char *file_premable; /* comment text to use at the start of the file */
} cfg_def_item_t;
/* configuration definition tree types */
@@ -174,8 +173,6 @@ struct config_def_tree_spec {
unsigned withversions:1; /* include versions */
unsigned withspaces:1; /* add more spaces in output for better readability */
unsigned unconfigured:1; /* use unconfigured path strings */
unsigned withgeneralpreamble:1; /* include preamble for a general config file */
unsigned withlocalpreamble:1; /* include preamble for a local config file */
uint8_t *check_status; /* status of last tree check (currently needed for CFG_DEF_TREE_MISSING only) */
};

View File

@@ -121,30 +121,6 @@
cfg_section(root_CFG_SECTION, "(root)", root_CFG_SECTION, 0, vsn(0, 0, 0), 0, NULL, NULL)
#define CFG_PREAMBLE_GENERAL \
"# This is an example configuration file for the LVM2 system.\n" \
"# It contains the default settings that would be used if there was no\n" \
"# @DEFAULT_SYS_DIR@/lvm.conf file.\n" \
"#\n" \
"# Refer to 'man lvm.conf' for further information including the file layout.\n" \
"#\n" \
"# Refer to 'man lvm.conf' for information about how settings configured in\n" \
"# this file are combined with built-in values and command line options to\n" \
"# arrive at the final values used by LVM.\n" \
"#\n" \
"# Refer to 'man lvmconfig' for information about displaying the built-in\n" \
"# and configured values used by LVM.\n" \
"#\n" \
"# If a default value is set in this file (not commented out), then a\n" \
"# new version of LVM using this file will continue using that value,\n" \
"# even if the new version of LVM changes the built-in default value.\n" \
"#\n" \
"# To put this file in a different directory and override @DEFAULT_SYS_DIR@ set\n" \
"# the environment variable LVM_SYSTEM_DIR before running the tools.\n" \
"#\n" \
"# N.B. Take care that each setting only appears once if uncommenting\n" \
"# example settings in this file.\n\n"
cfg_section(config_CFG_SECTION, "config", root_CFG_SECTION, 0, vsn(2, 2, 99), 0, NULL,
"How LVM configuration settings are handled.\n")
@@ -185,26 +161,6 @@ cfg_section(tags_CFG_SECTION, "tags", root_CFG_SECTION, CFG_DEFAULT_COMMENTED, v
cfg_section(local_CFG_SECTION, "local", root_CFG_SECTION, 0, vsn(2, 2, 117), 0, NULL,
"LVM settings that are specific to the local host.\n")
#define CFG_PREAMBLE_LOCAL \
"# This is a local configuration file template for the LVM2 system\n" \
"# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .\n" \
"#\n" \
"# Refer to 'man lvm.conf' for information about the file layout.\n" \
"#\n" \
"# To put this file in a different directory and override\n" \
"# @DEFAULT_SYS_DIR@ set the environment variable LVM_SYSTEM_DIR before\n" \
"# running the tools.\n" \
"#\n" \
"# The lvmlocal.conf file is normally expected to contain only the\n" \
"# \"local\" section which contains settings that should not be shared or\n" \
"# repeated among different hosts. (But if other sections are present,\n" \
"# they *will* get processed. Settings in this file override equivalent\n" \
"# ones in lvm.conf and are in turn overridden by ones in any enabled\n" \
"# lvm_<tag>.conf files.)\n" \
"#\n" \
"# Please take care that each setting only appears once if uncommenting\n" \
"# example settings in this file and never copy this file between hosts.\n\n"
cfg(config_checks_CFG, "checks", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 99), NULL, 0, NULL,
"If enabled, any LVM configuration mismatch is reported.\n"
"This implies checking that the configuration key is understood by\n"
@@ -513,28 +469,18 @@ cfg(allocation_mirror_logs_require_separate_pvs_CFG, "mirror_logs_require_separa
cfg(allocation_raid_stripe_all_devices_CFG, "raid_stripe_all_devices", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_ALLOCATION_STRIPE_ALL_DEVICES, vsn(2, 2, 162), NULL, 0, NULL,
"Stripe across all PVs when RAID stripes are not specified.\n"
"If enabled, all PVs in the VG or on the command line are used for\n"
"raid0/4/5/6/10 when the command does not specify the number of\n"
"stripes to use.\n"
"If enabled, all PVs in the VG or on the command line are used for raid0/4/5/6/10\n"
"when the command does not specify the number of stripes to use.\n"
"This was the default behaviour until release 2.02.162.\n")
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL, 0, NULL,
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL, 0, NULL,
"Cache pool metadata and data will always use different PVs.\n")
cfg(allocation_cache_pool_cachemode_CFG, "cache_pool_cachemode", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 113), NULL, vsn(2, 2, 128),
cfg(allocation_cache_pool_cachemode_CFG, "cache_pool_cachemode", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 113), NULL, vsn(2, 2, 128),
"This has been replaced by the allocation/cache_mode setting.\n",
"Cache mode.\n")
cfg(allocation_cache_metadata_format_CFG, "cache_metadata_format", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_CACHE_METADATA_FORMAT, vsn(2, 2, 169), NULL, 0, NULL,
"Sets default metadata format for new cache.\n"
"#\n"
"Accepted values:\n"
" 0 Automatically detected best available format\n"
" 1 Original format\n"
" 2 Improved 2nd. generation format\n"
"#\n")
cfg(allocation_cache_mode_CFG, "cache_mode", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 128), NULL, 0, NULL,
cfg(allocation_cache_mode_CFG, "cache_mode", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 128), NULL, 0, NULL,
"The default cache mode used for new cache.\n"
"#\n"
"Accepted values:\n"
@@ -546,20 +492,20 @@ cfg(allocation_cache_mode_CFG, "cache_mode", allocation_CFG_SECTION, CFG_PROFILA
"#\n"
"This setting replaces allocation/cache_pool_cachemode.\n")
cfg(allocation_cache_policy_CFG, "cache_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, 0, vsn(2, 2, 128), NULL, 0, NULL,
cfg(allocation_cache_policy_CFG, "cache_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, 0, vsn(2, 2, 128), NULL, 0, NULL,
"The default cache policy used for new cache volume.\n"
"Since kernel 4.2 the default policy is smq (Stochastic multiqueue),\n"
"Since kernel 4.2 the default policy is smq (Stochastic multique),\n"
"otherwise the older mq (Multiqueue) policy is selected.\n")
cfg_section(allocation_cache_settings_CFG_SECTION, "cache_settings", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
cfg_section(allocation_cache_settings_CFG_SECTION, "cache_settings", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
"Settings for the cache policy.\n"
"See documentation for individual cache policies for more info.\n")
cfg_section(policy_settings_CFG_SUBSECTION, "policy_settings", allocation_cache_settings_CFG_SECTION, CFG_NAME_VARIABLE | CFG_SECTION_NO_CHECK | CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
cfg_section(policy_settings_CFG_SUBSECTION, "policy_settings", allocation_cache_settings_CFG_SECTION, CFG_NAME_VARIABLE | CFG_SECTION_NO_CHECK | CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
"Replace this subsection name with a policy name.\n"
"Multiple subsections for different policies can be created.\n")
cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 106), 0, NULL,
cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 106), 0, NULL,
"The minimal chunk size in KiB for cache pool volumes.\n"
"Using a chunk_size that is too large can result in wasteful use of\n"
"the cache, where small reads and writes can cause large sections of\n"
@@ -570,7 +516,7 @@ cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", alloc
"on the smaller end of the spectrum. Supported values range from\n"
"32KiB to 1GiB in multiples of 32.\n")
cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, 0, vsn(2, 2, 165), NULL, 0, NULL,
cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, 0, vsn(2, 2, 165), NULL, 0, NULL,
"The maximum number of chunks in a cache pool.\n"
"For cache target v1.9 the recommended maximumm is 1000000 chunks.\n"
"Using cache pool with more chunks may degrade cache performance.\n")
@@ -979,7 +925,7 @@ cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL,
"devices/global_filter.\n")
cfg(global_lvmetad_update_wait_time_CFG, "lvmetad_update_wait_time", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_LVMETAD_UPDATE_WAIT_TIME, vsn(2, 2, 151), NULL, 0, NULL,
"Number of seconds a command will wait for lvmetad update to finish.\n"
"The number of seconds a command will wait for lvmetad update to finish.\n"
"After waiting for this period, a command will not use lvmetad, and\n"
"will revert to disk scanning.\n")
@@ -1046,7 +992,7 @@ cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CF
cfg_array(global_cache_disabled_features_CFG, "cache_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 128), NULL, 0, NULL,
"Features to not use in the cache driver.\n"
"This can be helpful for testing, or to avoid using a feature that is\n"
"causing problems. Features include: policy_mq, policy_smq, metadata2.\n"
"causing problems. Features include: policy_mq, policy_smq.\n"
"#\n"
"Example\n"
"cache_disabled_features = [ \"policy_smq\" ]\n"
@@ -1080,10 +1026,6 @@ cfg_array(global_cache_check_options_CFG, "cache_check_options", global_CFG_SECT
cfg_array(global_cache_repair_options_CFG, "cache_repair_options", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_REPAIR_OPTIONS_CONFIG, vsn(2, 2, 108), NULL, 0, NULL,
"List of options passed to the cache_repair command.\n")
cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FSADM_PATH, vsn(2, 2, 170), "@FSADM_PATH@", 0, NULL,
"The full path to the fsadm command.\n"
"LVM uses this command to help with lvresize -r operations.\n")
cfg(global_system_id_source_CFG, "system_id_source", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_SYSTEM_ID_SOURCE, vsn(2, 2, 117), NULL, 0, NULL,
"The method LVM uses to set the local system ID.\n"
"Volume Groups can also be given a system ID (by vgcreate, vgchange,\n"
@@ -1922,9 +1864,7 @@ cfg(dmeventd_thin_command_CFG, "thin_command", dmeventd_CFG_SECTION, CFG_DEFAULT
"The plugin runs command with each 5% increment when thin-pool data volume\n"
"or metadata volume gets above 50%.\n"
"Command which starts with 'lvm ' prefix is internal lvm command.\n"
"You can write your own handler to customise behaviour in more details.\n"
"User handler is specified with the full path starting with '/'.\n")
/* TODO: systemd service handler */
"You can write your own handler to customise behaviour in more details.\n")
cfg(dmeventd_executable_CFG, "executable", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_PATH, vsn(2, 2, 73), "@DMEVENTD_PATH@", 0, NULL,
"The full path to the dmeventd binary.\n")

View File

@@ -71,7 +71,7 @@
* FIXME: Increase these to 64 and further to the MD maximum
* once the SubLVs split and name shift got enhanced
*/
#define DEFAULT_RAID1_MAX_IMAGES 64
#define DEFAULT_RAID1_MAX_IMAGES 10
#define DEFAULT_RAID_MAX_IMAGES 64
#define DEFAULT_ALLOCATION_STRIPE_ALL_DEVICES 0 /* Don't stripe across all devices if not -i/--stripes given */
@@ -104,9 +104,9 @@
#define DEFAULT_THIN_REPAIR_OPTION1 ""
#define DEFAULT_THIN_REPAIR_OPTIONS_CONFIG "#S" DEFAULT_THIN_REPAIR_OPTION1
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (DM_THIN_MAX_METADATA_SIZE / 2) /* KB */
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE (128 * 1024) /* KB */
#define DEFAULT_THIN_POOL_OPTIMAL_SIZE (128 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_CHUNK_SIZE_POLICY "generic"
#define DEFAULT_THIN_POOL_CHUNK_SIZE 64 /* KB */
#define DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE 512 /* KB */
@@ -132,11 +132,8 @@
#define DEFAULT_CACHE_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_CACHE_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_CACHE_POLICY "mq"
#define DEFAULT_CACHE_METADATA_FORMAT CACHE_METADATA_FORMAT_UNSELECTED /* Autodetect */
#define DEFAULT_CACHE_MODE "writethrough"
#define DEFAULT_FSADM_PATH FSADM_PATH
#define DEFAULT_UMASK 0077
#define DEFAULT_FORMAT "lvm2"
@@ -202,7 +199,7 @@
#define DEFAULT_ACTIVATION_MODE "degraded"
#define DEFAULT_USE_LINEAR_TARGET 1
#define DEFAULT_STRIPE_FILLER "error"
#define DEFAULT_RAID_REGION_SIZE 2048 /* KB */
#define DEFAULT_RAID_REGION_SIZE 512 /* KB */
#define DEFAULT_INTERVAL 15
#define DEFAULT_MAX_HISTORY 100

View File

@@ -320,8 +320,8 @@ static int _compare_paths(const char *path0, const char *path1)
/* ASCII comparison */
if (strcmp(path0, path1) < 0)
return 0;
return 1;
else
return 1;
}
static int _add_alias(struct device *dev, const char *path)
@@ -706,12 +706,6 @@ static int _insert_dev(const char *path, dev_t d)
}
}
if (dm_hash_lookup(_cache.names, path) == dev) {
/* Hash already has matching entry present */
log_debug("Path already cached %s.", path);
return 1;
}
if (!(path_copy = dm_pool_strdup(_cache.mem, path))) {
log_error("Failed to duplicate path string.");
return 0;
@@ -898,10 +892,10 @@ int dev_cache_index_devs(void)
if (errno == ENOENT) {
sysfs_has_dev_block = 0;
return 1;
} else {
log_sys_error("stat", path);
return 0;
}
log_sys_error("stat", path);
return 0;
}
} else if (!sysfs_has_dev_block)
return 1;

View File

@@ -405,8 +405,8 @@ int dev_get_size(struct device *dev, uint64_t *size)
if ((dev->flags & DEV_REGULAR))
return _dev_get_size_file(dev, size);
return _dev_get_size_dev(dev, size);
else
return _dev_get_size_dev(dev, size);
}
int dev_get_read_ahead(struct device *dev, uint32_t *read_ahead)

View File

@@ -28,7 +28,7 @@
#define MD_SB_MAGIC 0xa92b4efc
#define MD_RESERVED_BYTES (64 * 1024ULL)
#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)
#define MD_NEW_SIZE_SECTORS(x) (((x) & ~(MD_RESERVED_SECTORS - 1)) \
#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) \
- MD_RESERVED_SECTORS)
#define MD_MAX_SYSFS_SIZE 64

View File

@@ -76,7 +76,7 @@ struct dev_types *create_dev_types(const char *proc_dir,
i++;
/* If it's not a number it may be name of section */
line_maj = atoi(line + i);
line_maj = atoi(((char *) (line + i)));
if (line_maj < 0 || line_maj >= NUMBER_OF_MAJORS) {
/*
@@ -615,38 +615,38 @@ static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
if (force < DONT_PROMPT) {
log_error(MSG_FAILED_SIG_OFFSET, type, name);
return 0;
} else {
log_error("WARNING: " MSG_FAILED_SIG_OFFSET MSG_WIPING_SKIPPED, type, name);
return 2;
}
log_error("WARNING: " MSG_FAILED_SIG_OFFSET MSG_WIPING_SKIPPED, type, name);
return 2;
}
if (blkid_probe_lookup_value(probe, "SBMAGIC", &magic, &len)) {
if (force < DONT_PROMPT) {
log_error(MSG_FAILED_SIG_LENGTH, type, name);
return 0;
} else {
log_warn("WARNING: " MSG_FAILED_SIG_LENGTH MSG_WIPING_SKIPPED, type, name);
return 2;
}
log_warn("WARNING: " MSG_FAILED_SIG_LENGTH MSG_WIPING_SKIPPED, type, name);
return 2;
}
} else if (!blkid_probe_lookup_value(probe, "PTTYPE", &type, NULL)) {
if (blkid_probe_lookup_value(probe, "PTMAGIC_OFFSET", &offset, NULL)) {
if (force < DONT_PROMPT) {
log_error(MSG_FAILED_SIG_OFFSET, type, name);
return 0;
} else {
log_warn("WARNING: " MSG_FAILED_SIG_OFFSET MSG_WIPING_SKIPPED, type, name);
return 2;
}
log_warn("WARNING: " MSG_FAILED_SIG_OFFSET MSG_WIPING_SKIPPED, type, name);
return 2;
}
if (blkid_probe_lookup_value(probe, "PTMAGIC", &magic, &len)) {
if (force < DONT_PROMPT) {
log_error(MSG_FAILED_SIG_LENGTH, type, name);
return 0;
} else {
log_warn("WARNING: " MSG_FAILED_SIG_LENGTH MSG_WIPING_SKIPPED, type, name);
return 2;
}
log_warn("WARNING: " MSG_FAILED_SIG_LENGTH MSG_WIPING_SKIPPED, type, name);
return 2;
}
usage = "partition table";
} else

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -152,30 +152,6 @@ const char *display_lvname(const struct logical_volume *lv)
return name;
}
/* Display percentage with (TODO) configurable precision */
const char *display_percent(struct cmd_context *cmd, dm_percent_t percent)
{
char *buf;
int r;
/* Reusing same ring buffer we use for displaying LV names */
if ((cmd->display_lvname_idx + NAME_LEN) >= sizeof((cmd->display_buffer)))
cmd->display_lvname_idx = 0;
buf = cmd->display_buffer + cmd->display_lvname_idx;
/* TODO: Make configurable hardcoded 2 digits */
r = dm_snprintf(buf, NAME_LEN, "%.2f", dm_percent_to_round_float(percent, 2));
if (r < 0) {
log_error("Percentage %d does not fit.", percent);
return NULL;
}
cmd->display_lvname_idx += r + 1;
return buf;
}
/* Size supplied in sectors */
static const char *_display_size(const struct cmd_context *cmd,
uint64_t size, dm_size_suffix_t suffix_type)
@@ -410,7 +386,6 @@ int lvdisplay_full(struct cmd_context *cmd,
dm_percent_t thin_data_percent, thin_metadata_percent;
int thin_active = 0;
dm_percent_t thin_percent;
struct lv_status_cache *cache_status = NULL;
if (lv_is_historical(lv))
return _lvdisplay_historical_full(cmd, lv);
@@ -516,19 +491,6 @@ int lvdisplay_full(struct cmd_context *cmd,
seg = first_seg(lv);
log_print("LV Pool metadata %s", seg->metadata_lv->name);
log_print("LV Pool data %s", seg_lv(seg, 0)->name);
} else if (lv_is_cache_origin(lv)) {
if ((seg = get_only_segment_using_this_lv(lv)))
log_print("LV origin of Cache LV %s", seg->lv->name);
} else if (lv_is_cache(lv)) {
seg = first_seg(lv);
if (inkernel && !lv_cache_status(lv, &cache_status))
return_0;
log_print("LV Cache pool name %s", seg->pool_lv->name);
log_print("LV Cache origin name %s", seg_lv(seg, 0)->name);
} else if (lv_is_cache_pool(lv)) {
seg = first_seg(lv);
log_print("LV Pool metadata %s", seg->metadata_lv->name);
log_print("LV Pool data %s", seg_lv(seg, 0)->name);
}
if (inkernel && info.suspended)
@@ -548,38 +510,17 @@ int lvdisplay_full(struct cmd_context *cmd,
display_size(cmd,
snap_seg ? snap_seg->origin->size : lv->size));
if (cache_status) {
log_print("Cache used blocks %s%%",
display_percent(cmd, cache_status->data_usage));
log_print("Cache metadata blocks %s%%",
display_percent(cmd, cache_status->metadata_usage));
log_print("Cache dirty blocks %s%%",
display_percent(cmd, cache_status->dirty_usage));
log_print("Cache read hits/misses " FMTu64 " / " FMTu64,
cache_status->cache->read_hits,
cache_status->cache->read_misses);
log_print("Cache wrt hits/misses " FMTu64 " / " FMTu64,
cache_status->cache->write_hits,
cache_status->cache->write_misses);
log_print("Cache demotions " FMTu64,
cache_status->cache->demotions);
log_print("Cache promotions " FMTu64,
cache_status->cache->promotions);
dm_pool_destroy(cache_status->mem);
}
if (thin_data_active)
log_print("Allocated pool data %s%%",
display_percent(cmd, thin_data_percent));
log_print("Allocated pool data %.2f%%",
dm_percent_to_float(thin_data_percent));
if (thin_metadata_active)
log_print("Allocated metadata %s%%",
display_percent(cmd, thin_metadata_percent));
log_print("Allocated metadata %.2f%%",
dm_percent_to_float(thin_metadata_percent));
if (thin_active)
log_print("Mapped size %s%%",
display_percent(cmd, thin_percent));
log_print("Mapped size %.2f%%",
dm_percent_to_float(thin_percent));
log_print("Current LE %u",
snap_seg ? snap_seg->origin->le_count : lv->le_count);
@@ -590,8 +531,8 @@ int lvdisplay_full(struct cmd_context *cmd,
log_print("COW-table LE %u", lv->le_count);
if (snap_active)
log_print("Allocated to snapshot %s%%",
display_percent(cmd, snap_percent));
log_print("Allocated to snapshot %.2f%%",
dm_percent_to_float(snap_percent));
log_print("Snapshot chunk size %s",
display_size(cmd, (uint64_t) snap_seg->chunk_size));

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -24,8 +24,6 @@
const char *display_lvname(const struct logical_volume *lv);
const char *display_percent(struct cmd_context *cmd, dm_percent_t percent);
/* Specify size in KB */
const char *display_size(const struct cmd_context *cmd, uint64_t size);
const char *display_size_long(const struct cmd_context *cmd, uint64_t size);

View File

@@ -274,9 +274,8 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
if (!_set_lookup(ds, dev->dev)) {
log_debug_devs("%s: Skipping (sysfs)", dev_name(dev));
return 0;
}
return 1;
} else
return 1;
}
static void _destroy(struct dev_filter *f)

View File

@@ -128,8 +128,8 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
int generate_lvm1_system_id(struct cmd_context *cmd, char *s, const char *prefix)
{
if (dm_snprintf(s, NAME_LEN, "%s%s" FMTu64,
prefix, cmd->hostname, (uint64_t)time(NULL)) < 0) {
if (dm_snprintf(s, NAME_LEN, "%s%s%lu",
prefix, cmd->hostname, time(NULL)) < 0) {
log_error("Generated LVM1 format system_id too long");
return 0;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -134,35 +134,37 @@ static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
if (lv_num == UNMAPPED_EXTENT)
continue;
lv_num--;
lvm = lvms[lv_num];
else {
lv_num--;
lvm = lvms[lv_num];
if (!lvm) {
log_error("Invalid LV in extent map "
"(PV %s, PE %" PRIu32
", LV %" PRIu32
", LE %" PRIu32 ")",
dev_name(pv->dev), i,
lv_num, e[i].le_num);
return 0;
if (!lvm) {
log_error("Invalid LV in extent map "
"(PV %s, PE %" PRIu32
", LV %" PRIu32
", LE %" PRIu32 ")",
dev_name(pv->dev), i,
lv_num, e[i].le_num);
return 0;
}
le = e[i].le_num;
if (le >= lvm->lv->le_count) {
log_error("logical extent number "
"out of bounds");
return 0;
}
if (lvm->map[le].pv) {
log_error("logical extent (%u) "
"already mapped.", le);
return 0;
}
lvm->map[le].pv = pv;
lvm->map[le].pe = i;
}
le = e[i].le_num;
if (le >= lvm->lv->le_count) {
log_error("logical extent number "
"out of bounds");
return 0;
}
if (lvm->map[le].pv) {
log_error("logical extent (%u) "
"already mapped.", le);
return 0;
}
lvm->map[le].pv = pv;
lvm->map[le].pe = i;
}
}
@@ -223,8 +225,8 @@ static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
while (le < lvm->lv->le_count) {
len = _area_length(lvm, le);
if (!(seg = alloc_lv_segment(segtype, lvm->lv, le, len, 0, 0, 0,
NULL, 1, len, 0, 0, 0, 0, NULL))) {
if (!(seg = alloc_lv_segment(segtype, lvm->lv, le, len, 0, 0,
NULL, 1, len, 0, 0, 0, NULL))) {
log_error("Failed to allocate linear segment.");
return 0;
}
@@ -295,10 +297,10 @@ static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
if (!(seg = alloc_lv_segment(segtype, lvm->lv,
lvm->stripes * first_area_le,
lvm->stripes * area_len, 0,
lvm->stripes * area_len,
0, lvm->stripe_size, NULL,
lvm->stripes,
area_len, 0, 0, 0, 0, NULL))) {
area_len, 0, 0, 0, NULL))) {
log_error("Failed to allocate striped segment.");
return 0;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -192,9 +192,9 @@ static int _add_stripe_seg(struct dm_pool *mem,
return_0;
if (!(seg = alloc_lv_segment(segtype, lv, *le_cur,
area_len * usp->num_devs, 0, 0,
area_len * usp->num_devs, 0,
usp->striping, NULL, usp->num_devs,
area_len, 0, 0, 0, 0, NULL))) {
area_len, 0, 0, 0, NULL))) {
log_error("Unable to allocate striped lv_segment structure");
return 0;
}
@@ -232,8 +232,8 @@ static int _add_linear_seg(struct dm_pool *mem,
area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
if (!(seg = alloc_lv_segment(segtype, lv, *le_cur,
area_len, 0, 0, usp->striping,
NULL, 1, area_len, 0,
area_len, 0, usp->striping,
NULL, 1, area_len,
POOL_PE_SIZE, 0, 0, NULL))) {
log_error("Unable to allocate linear lv_segment "
"structure");

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -42,7 +42,7 @@ typedef int (*nl_fn) (struct formatter * f);
#define _out_with_comment(f, buffer, fmt, ap) \
do { \
va_start(ap, fmt); \
r = (f)->out_with_comment((f), (buffer), (fmt), ap); \
r = f->out_with_comment(f, buffer, fmt, ap); \
va_end(ap); \
} while (r == -1)
@@ -350,7 +350,7 @@ static int _print_header(struct cmd_context *cmd, struct formatter *f,
_utsname.version, _utsname.machine);
if (cmd->system_id && *cmd->system_id)
outf(f, "creation_host_system_id = \"%s\"", cmd->system_id);
outf(f, "creation_time = " FMTu64 "\t# %s", (uint64_t)t, ctime(&t));
outf(f, "creation_time = %lu\t# %s", t, ctime(&t));
return 1;
}
@@ -358,12 +358,11 @@ static int _print_header(struct cmd_context *cmd, struct formatter *f,
static int _print_flag_config(struct formatter *f, uint64_t status, int type)
{
char buffer[4096];
if (!print_flags(buffer, sizeof(buffer), type, STATUS_FLAG, status))
if (!print_flags(status, type | STATUS_FLAG, buffer, sizeof(buffer)))
return_0;
outf(f, "status = %s", buffer);
if (!print_flags(buffer, sizeof(buffer), type, COMPATIBLE_FLAG, status))
if (!print_flags(status, type, buffer, sizeof(buffer)))
return_0;
outf(f, "flags = %s", buffer);
@@ -502,13 +501,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
*/
static const char *_get_pv_name_from_uuid(struct formatter *f, char *uuid)
{
const char *pv_name = dm_hash_lookup(f->pv_names, uuid);
if (!pv_name)
log_error(INTERNAL_ERROR "PV name for uuid %s missing from text metadata export hash table.",
uuid);
return pv_name;
return dm_hash_lookup(f->pv_names, uuid);
}
static const char *_get_pv_name(struct formatter *f, struct physical_volume *pv)
@@ -584,23 +577,15 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
static int _print_segment(struct formatter *f, struct volume_group *vg,
int count, struct lv_segment *seg)
{
char buffer[2048];
if (!print_segtype_lvflags(buffer, sizeof(buffer), seg->lv->status))
return_0;
outf(f, "segment%u {", count);
_inc_indent(f);
outf(f, "start_extent = %u", seg->le);
outsize(f, (uint64_t) seg->len * vg->extent_size,
"extent_count = %u", seg->len);
outnl(f);
if (seg->reshape_len)
outsize(f, (uint64_t) seg->reshape_len * vg->extent_size,
"reshape_count = %u", seg->reshape_len);
outf(f, "type = \"%s%s\"", seg->segtype->name, buffer);
outnl(f);
outf(f, "type = \"%s\"", seg->segtype->name);
if (!_out_list(f, &seg->tags, "tags"))
return_0;
@@ -620,7 +605,6 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
{
const char *name;
unsigned int s;
struct physical_volume *pv;
outnl(f);
@@ -630,13 +614,7 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
for (s = 0; s < seg->area_count; s++) {
switch (seg_type(seg, s)) {
case AREA_PV:
if (!(pv = seg_pv(seg, s))) {
log_error(INTERNAL_ERROR "Missing PV for area %" PRIu32 " of %s segment of LV %s.",
s, type, display_lvname(seg->lv));
return 0;
}
if (!(name = _get_pv_name(f, pv)))
if (!(name = _get_pv_name(f, seg_pv(seg, s))))
return_0;
outf(f, "\"%s\", %u%s", name,
@@ -670,8 +648,6 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
break;
case AREA_UNASSIGNED:
log_error(INTERNAL_ERROR "Invalid type for area %" PRIu32 " of %s segment of LV %s.",
s, type, display_lvname(seg->lv));
return 0;
}
}
@@ -910,8 +886,8 @@ static int _print_historical_lv(struct formatter *f, struct historical_logical_v
r = 1;
out:
dm_free(descendants_buffer);
if (descendants_buffer)
dm_free(descendants_buffer);
return r;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -47,7 +47,6 @@ static const struct flag _pv_flags[] = {
{ALLOCATABLE_PV, "ALLOCATABLE", STATUS_FLAG},
{EXPORTED_VG, "EXPORTED", STATUS_FLAG},
{MISSING_PV, "MISSING", COMPATIBLE_FLAG},
{MISSING_PV, "MISSING", STATUS_FLAG},
{UNLABELLED_PV, NULL, 0},
{0, NULL, 0}
};
@@ -62,15 +61,9 @@ static const struct flag _lv_flags[] = {
{LOCKED, "LOCKED", STATUS_FLAG},
{LV_NOTSYNCED, "NOTSYNCED", STATUS_FLAG},
{LV_REBUILD, "REBUILD", STATUS_FLAG},
{LV_RESHAPE, "RESHAPE", SEGTYPE_FLAG},
{LV_RESHAPE_DATA_OFFSET, "RESHAPE_DATA_OFFSET", SEGTYPE_FLAG},
{LV_RESHAPE_DELTA_DISKS_PLUS, "RESHAPE_DELTA_DISKS_PLUS", SEGTYPE_FLAG},
{LV_RESHAPE_DELTA_DISKS_MINUS, "RESHAPE_DELTA_DISKS_MINUS", SEGTYPE_FLAG},
{LV_REMOVE_AFTER_RESHAPE, "REMOVE_AFTER_RESHAPE", SEGTYPE_FLAG},
{LV_WRITEMOSTLY, "WRITEMOSTLY", STATUS_FLAG},
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
{LV_METADATA_FORMAT, "METADATA_FORMAT", SEGTYPE_FLAG},
{LV_NOSCAN, NULL, 0},
{LV_TEMPORARY, NULL, 0},
{POOL_METADATA_SPARE, NULL, 0},
@@ -104,9 +97,9 @@ static const struct flag _lv_flags[] = {
{0, NULL, 0}
};
static const struct flag *_get_flags(enum pv_vg_lv_e type)
static const struct flag *_get_flags(int type)
{
switch (type) {
switch (type & ~STATUS_FLAG) {
case VG_FLAGS:
return _vg_flags;
@@ -117,7 +110,7 @@ static const struct flag *_get_flags(enum pv_vg_lv_e type)
return _lv_flags;
}
log_error(INTERNAL_ERROR "Unknown flag set requested.");
log_error("Unknown flag set requested.");
return NULL;
}
@@ -126,7 +119,7 @@ static const struct flag *_get_flags(enum pv_vg_lv_e type)
* using one of the tables defined at the top of
* the file.
*/
int print_flags(char *buffer, size_t size, enum pv_vg_lv_e type, int mask, uint64_t status)
int print_flags(uint64_t status, int type, char *buffer, size_t size)
{
int f, first = 1;
const struct flag *flags;
@@ -135,13 +128,13 @@ int print_flags(char *buffer, size_t size, enum pv_vg_lv_e type, int mask, uint6
return_0;
if (!emit_to_buffer(&buffer, &size, "["))
return_0;
return 0;
for (f = 0; flags[f].mask; f++) {
if (status & flags[f].mask) {
status &= ~flags[f].mask;
if (mask != flags[f].kind)
if ((type & STATUS_FLAG) != flags[f].kind)
continue;
/* Internal-only flag? */
@@ -150,18 +143,18 @@ int print_flags(char *buffer, size_t size, enum pv_vg_lv_e type, int mask, uint6
if (!first) {
if (!emit_to_buffer(&buffer, &size, ", "))
return_0;
return 0;
} else
first = 0;
if (!emit_to_buffer(&buffer, &size, "\"%s\"",
flags[f].description))
return_0;
flags[f].description))
return 0;
}
}
if (!emit_to_buffer(&buffer, &size, "]"))
return_0;
return 0;
if (status)
log_warn(INTERNAL_ERROR "Metadata inconsistency: "
@@ -170,9 +163,9 @@ int print_flags(char *buffer, size_t size, enum pv_vg_lv_e type, int mask, uint6
return 1;
}
int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm_config_value *cv)
int read_flags(uint64_t *status, int type, const struct dm_config_value *cv)
{
unsigned f;
int f;
uint64_t s = UINT64_C(0);
const struct flag *flags;
@@ -189,8 +182,7 @@ int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm
}
for (f = 0; flags[f].description; f++)
if ((flags[f].kind & mask) &&
!strcmp(flags[f].description, cv->v.str)) {
if (!strcmp(flags[f].description, cv->v.str)) {
s |= flags[f].mask;
break;
}
@@ -204,7 +196,7 @@ int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm
* by this case.
*/
s |= PARTIAL_VG;
} else if (!flags[f].description && (mask & STATUS_FLAG)) {
} else if (!flags[f].description && (type & STATUS_FLAG)) {
log_error("Unknown status flag '%s'.", cv->v.str);
return 0;
}
@@ -216,71 +208,3 @@ int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm
*status |= s;
return 1;
}
/*
* Parse extra status flags from segment "type" string.
* These flags are seen as INCOMPATIBLE by any older lvm2 code.
* All flags separated by '+' are trimmed from passed string.
* All UNKNOWN flags will again cause the "UNKNOWN" segtype.
*
* Note: using these segtype status flags instead of actual
* status flags ensures wanted incompatiblity.
*/
int read_segtype_lvflags(uint64_t *status, char *segtype_str)
{
unsigned i;
const struct flag *flags = _lv_flags;
char *delim;
char *flag, *buffer, *str;
if (!(str = strchr(segtype_str, '+')))
return 1; /* No flags */
if (!(buffer = dm_strdup(str + 1))) {
log_error("Cannot duplicate segment string.");
return 0;
}
delim = buffer;
do {
flag = delim;
if ((delim = strchr(delim, '+')))
*delim++ = '\0';
for (i = 0; flags[i].description; i++)
if ((flags[i].kind & SEGTYPE_FLAG) &&
!strcmp(flags[i].description, flag)) {
*status |= flags[i].mask;
break;
}
} while (delim && flags[i].description); /* Till no more flags in type appear */
if (!flags[i].description)
/* Unknown flag is incompatible - returns unmodified segtype_str */
log_warn("WARNING: Unrecognised flag %s in segment type %s.",
flag, segtype_str);
else
*str = '\0'; /* Cut away 1st. '+' */
dm_free(buffer);
return 1;
}
int print_segtype_lvflags(char *buffer, size_t size, uint64_t status)
{
unsigned i;
const struct flag *flags = _lv_flags;
buffer[0] = 0;
for (i = 0; flags[i].mask; i++)
if ((flags[i].kind & SEGTYPE_FLAG) &&
(status & flags[i].mask) &&
!emit_to_buffer(&buffer, &size, "+%s",
flags[i].description))
return 0;
return 1;
}

View File

@@ -152,8 +152,8 @@ static uint64_t _get_prev_sector_circular(uint64_t region_start,
{
if (region_ptr >= region_start + SECTOR_SIZE)
return region_ptr - SECTOR_SIZE;
return (region_start + region_size - SECTOR_SIZE);
else
return (region_start + region_size - SECTOR_SIZE);
}
/*
@@ -268,7 +268,8 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
r = 1;
out:
dm_free(buf);
if (buf)
dm_free(buf);
if (!dev_close(area->dev))
stack;
return r;
@@ -447,9 +448,9 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{'))
return rlocn;
log_debug_metadata("Volume group name found in metadata does "
"not match expected name %s.", vgname);
else
log_debug_metadata("Volume group name found in metadata does "
"not match expected name %s.", vgname);
bad:
if ((info = lvmcache_info_from_pvid(dev_area->dev->pvid, dev_area->dev, 0)) &&
@@ -893,9 +894,8 @@ static struct volume_group *_vg_read_file_name(struct format_instance *fid,
log_error("'%s' does not contain volume group '%s'.",
read_path, vgname);
return NULL;
}
log_debug_metadata("Read volume group %s from %s", vg->name, read_path);
} else
log_debug_metadata("Read volume group %s from %s", vg->name, read_path);
return vg;
}
@@ -1043,11 +1043,6 @@ static int _vg_commit_file(struct format_instance *fid, struct volume_group *vg,
if (strcmp(slash, vg->name)) {
len = slash - tc->path_live;
if ((len + strlen(vg->name)) > (sizeof(new_name) - 1)) {
log_error("Renaming path %s is too long for VG %s.",
tc->path_live, vg->name);
return 0;
}
strncpy(new_name, tc->path_live, len);
strcpy(new_name + len, vg->name);
log_debug_metadata("Renaming %s to %s", tc->path_live, new_name);
@@ -1635,10 +1630,10 @@ static int _text_pv_initialise(const struct format_type *fmt,
log_error("%s: Bootloader area would overlap "
"data area.", pv_dev_name(pv));
return 0;
} else {
pv->ba_start = pva->ba_start ? : final_alignment;
pv->ba_size = pva->ba_size;
}
pv->ba_start = pva->ba_start ? : final_alignment;
pv->ba_size = pva->ba_size;
}
}
@@ -2002,9 +1997,6 @@ static int _create_vg_text_instance(struct format_instance *fid,
*/
if (!critical_section())
/* Scan PVs in VG for any further MDAs */
/*
* FIXME Only scan PVs believed to be in the VG.
*/
lvmcache_label_scan(fid->fmt->cmd);
if (!(vginfo = lvmcache_vginfo_from_vgname(vg_name, vg_id)))
@@ -2013,7 +2005,7 @@ static int _create_vg_text_instance(struct format_instance *fid,
goto_out;
}
/* FIXME If PV list or raw metadata area count are not as expected rescan */
/* FIXME Check raw metadata area count - rescan if required */
}
out:
@@ -2078,7 +2070,7 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt,
{
struct format_instance *fid = pv->fid;
const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
uint64_t ba_size, pe_start, first_unallocated;
uint64_t ba_size, pe_start, pe_end;
uint64_t alignment, alignment_offset;
uint64_t disk_size;
uint64_t mda_start;
@@ -2213,24 +2205,14 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt,
* if defined or locked. If pe_start is not defined yet, count
* with any existing MDA0. If MDA0 does not exist, just use
* LABEL_SCAN_SIZE.
*
* The first_unallocated here is the first unallocated byte
* beyond existing pe_end if there is any preallocated data area
* reserved already so we can take that as lower limit for our MDA1
* start calculation. If data area is not reserved yet, we set
* first_unallocated to 0, meaning this is not our limiting factor
* and we will look at other limiting factors if they exist.
* Of course, if we have preallocated data area, we also must
* have pe_start assigned too (simply, data area needs its start
* and end specification).
*/
first_unallocated = pv->pe_count ? (pv->pe_start + pv->pe_count *
(uint64_t)pv->pe_size) << SECTOR_SHIFT
: 0;
pe_end = pv->pe_count ? (pv->pe_start +
pv->pe_count * (uint64_t)pv->pe_size - 1) << SECTOR_SHIFT
: 0;
if (pe_start || pe_start_locked) {
limit = first_unallocated ? first_unallocated : pe_start;
limit_name = first_unallocated ? "pe_end" : "pe_start";
limit = pe_end ? pe_end : pe_start;
limit_name = pe_end ? "pe_end" : "pe_start";
} else {
if ((mda = fid_get_mda_indexed(fid, pvid, ID_LEN, 0)) &&
(mdac = mda->metadata_locn)) {
@@ -2249,7 +2231,7 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt,
}
}
if (limit >= disk_size)
if (limit > disk_size)
goto bad;
if (mda_size > disk_size) {
@@ -2275,6 +2257,16 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt,
mda_start = disk_size - mda_size;
}
}
/*
* If PV's pe_end not set yet, set it to the end of the
* area that precedes the MDA1 we've just calculated.
* FIXME: do we need to set this? Isn't it always set before?
*/
/*if (!pe_end) {
pe_end = mda_start;
pv->pe_end = pe_end >> SECTOR_SHIFT;
}*/
}
if (limit_applied)
@@ -2291,9 +2283,9 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt,
}
/* Wipe metadata area with zeroes. */
if (!dev_set(pv->dev, mda_start,
(size_t) ((mda_size > wipe_size) ?
wipe_size : mda_size), 0)) {
if (!dev_set((struct device *) pv->dev, mda_start,
(size_t) ((mda_size > wipe_size) ?
wipe_size : mda_size), 0)) {
log_error("Failed to wipe new metadata area "
"at the %s of the %s",
mda_index ? "end" : "start",

View File

@@ -35,16 +35,14 @@
* VGs, PVs and LVs all have status bitsets, we gather together
* common code for reading and writing them.
*/
enum pv_vg_lv_e {
PV_FLAGS = 1,
enum {
COMPATIBLE_FLAG = 0x0,
VG_FLAGS,
PV_FLAGS,
LV_FLAGS,
STATUS_FLAG = 0x8,
};
#define COMPATIBLE_FLAG 0x01
#define STATUS_FLAG 0x02
#define SEGTYPE_FLAG 0x04
struct text_vg_version_ops {
int (*check_version) (const struct dm_config_tree * cf);
struct volume_group *(*read_vg) (struct format_instance * fid,
@@ -60,11 +58,8 @@ struct text_vg_version_ops {
struct text_vg_version_ops *text_vg_vsn1_init(void);
int print_flags(char *buffer, size_t size, enum pv_vg_lv_e type, int mask, uint64_t status);
int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm_config_value *cv);
int print_segtype_lvflags(char *buffer, size_t size, uint64_t status);
int read_segtype_lvflags(uint64_t *status, char *segtype_str);
int print_flags(uint64_t status, int type, char *buffer, size_t size);
int read_flags(uint64_t *status, int type, const struct dm_config_value *cv);
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -37,13 +37,13 @@ typedef int (*section_fn) (struct format_instance * fid,
unsigned report_missing_devices);
#define _read_int32(root, path, result) \
dm_config_get_uint32(root, path, (uint32_t *) (result))
dm_config_get_uint32(root, path, (uint32_t *) result)
#define _read_uint32(root, path, result) \
dm_config_get_uint32(root, path, (result))
dm_config_get_uint32(root, path, result)
#define _read_uint64(root, path, result) \
dm_config_get_uint64(root, path, (result))
dm_config_get_uint64(root, path, result)
/*
* Logs an attempt to read an invalid format file.
@@ -140,14 +140,13 @@ static int _read_flag_config(const struct dm_config_node *n, uint64_t *status, i
return 0;
}
/* For backward compatible metadata accept both type of flags */
if (!(read_flags(status, type, STATUS_FLAG | SEGTYPE_FLAG, cv))) {
if (!(read_flags(status, type | STATUS_FLAG, cv))) {
log_error("Could not read status flags.");
return 0;
}
if (dm_config_get_list(n, "flags", &cv)) {
if (!(read_flags(status, type, COMPATIBLE_FLAG, cv))) {
if (!(read_flags(status, type, cv))) {
log_error("Could not read flags.");
return 0;
}
@@ -355,10 +354,9 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
struct lv_segment *seg;
const struct dm_config_node *sn_child = sn->child;
const struct dm_config_value *cv;
uint32_t area_extents, start_extent, extent_count, reshape_count, data_copies;
uint32_t start_extent, extent_count;
struct segment_type *segtype;
const char *segtype_str;
char *segtype_with_flags;
if (!sn_child) {
log_error("Empty segment section.");
@@ -377,12 +375,6 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
return 0;
}
if (!_read_int32(sn_child, "reshape_count", &reshape_count))
reshape_count = 0;
if (!_read_int32(sn_child, "data_copies", &data_copies))
data_copies = 1;
segtype_str = SEG_TYPE_NAME_STRIPED;
if (!dm_config_get_str(sn_child, "type", &segtype_str)) {
@@ -390,33 +382,16 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
return 0;
}
/* Locally duplicate to parse out status flag bits */
if (!(segtype_with_flags = dm_pool_strdup(mem, segtype_str))) {
log_error("Cannot duplicate segtype string.");
return 0;
}
if (!read_segtype_lvflags(&lv->status, segtype_with_flags)) {
log_error("Couldn't read segtype for logical volume %s.",
display_lvname(lv));
return 0;
}
if (!(segtype = get_segtype_from_string(lv->vg->cmd, segtype_with_flags)))
if (!(segtype = get_segtype_from_string(lv->vg->cmd, segtype_str)))
return_0;
/* Can drop temporary string here as nothing has allocated from VGMEM meanwhile */
dm_pool_free(mem, segtype_with_flags);
if (segtype->ops->text_import_area_count &&
!segtype->ops->text_import_area_count(sn_child, &area_count))
return_0;
area_extents = segtype->parity_devs ?
raid_rimage_extents(segtype, extent_count, area_count - segtype->parity_devs, data_copies) : extent_count;
if (!(seg = alloc_lv_segment(segtype, lv, start_extent,
extent_count, reshape_count, 0, 0, NULL, area_count,
area_extents, data_copies, 0, 0, 0, NULL))) {
extent_count, 0, 0, NULL, area_count,
extent_count, 0, 0, 0, NULL))) {
log_error("Segment allocation failed");
return 0;
}

View File

@@ -202,7 +202,6 @@ int label_remove(struct device *dev)
int wipe;
struct labeller_i *li;
struct label_header *lh;
struct lvmcache_info *info;
memset(buf, 0, LABEL_SIZE);
@@ -246,13 +245,8 @@ int label_remove(struct device *dev)
if (wipe) {
log_very_verbose("%s: Wiping label at sector %" PRIu64,
dev_name(dev), sector);
if (dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE,
if (!dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE,
buf)) {
/* Also remove the PV record from cache. */
info = lvmcache_info_from_pvid(dev->pvid, dev, 0);
if (info)
lvmcache_del(info);
} else {
log_error("Failed to remove label from %s at "
"sector %" PRIu64, dev_name(dev),
sector);

View File

@@ -519,14 +519,11 @@ static int decode_lock_type(const char *response)
{
if (!response)
return LCK_NULL;
if (!strcmp(response, "EX"))
else if (!strcmp(response, "EX"))
return LCK_EXCL;
if (!strcmp(response, "CR"))
else if (!strcmp(response, "CR"))
return LCK_READ;
if (!strcmp(response, "PR"))
else if (!strcmp(response, "PR"))
return LCK_PREAD;
return_0;

View File

@@ -187,9 +187,9 @@ int init_locking(int type, struct cmd_context *cmd, int suppress_messages)
"be inaccessible.");
if (init_file_locking(&_locking, cmd, suppress_messages))
return 1;
log_error_suppress(suppress_messages,
"File-based locking initialisation failed.");
else
log_error_suppress(suppress_messages,
"File-based locking initialisation failed.");
}
if (!ignorelockingfailure())
@@ -232,9 +232,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
log_error("%s exists: Is the original LVM driver using "
"this volume group?", path);
return 0;
}
if (errno != ENOENT && errno != ENOTDIR) {
} else if (errno != ENOENT && errno != ENOTDIR) {
log_sys_error("stat", path);
return 0;
}

View File

@@ -134,7 +134,7 @@ static void _flags_str_to_lockd_flags(const char *flags_str, uint32_t *lockd_fla
* will not return. daemon_reply_int reverts to this
* value if it finds no result value.
*/
#define NO_LOCKD_RESULT (-1000)
#define NO_LOCKD_RESULT -1000
static int _lockd_result(daemon_reply reply, int *result, uint32_t *lockd_flags)
{
@@ -365,9 +365,6 @@ static int _remove_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg)
static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg, int extend_mb)
{
struct device *dev;
char path[PATH_MAX];
uint64_t old_size_bytes, new_size_bytes;
struct logical_volume *lv = vg->sanlock_lv;
struct lvresize_params lp = {
.sign = SIGN_NONE,
@@ -377,49 +374,12 @@ static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
.force = 1,
};
old_size_bytes = lv->size * SECTOR_SIZE;
if (!lv_resize(lv, &lp, &vg->pvs)) {
log_error("Extend sanlock LV %s to size %s failed.",
log_error("Extend LV %s to size %s failed.",
display_lvname(lv), display_size(cmd, lp.size));
return 0;
}
new_size_bytes = lv->size * SECTOR_SIZE;
if (dm_snprintf(path, sizeof(path), "%s/mapper/%s-%s", lv->vg->cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Extend sanlock LV %s name too long - extended size not zeroed.",
display_lvname(lv));
return 0;
}
log_debug("Extend sanlock LV zeroing blocks from offset " FMTu64 " bytes len %u bytes",
old_size_bytes, (uint32_t)(new_size_bytes - old_size_bytes));
log_print("Zeroing %u MiB on extended internal lvmlock LV...", extend_mb);
if (!(dev = dev_cache_get(path, NULL))) {
log_error("Extend sanlock LV %s cannot find device.", display_lvname(lv));
return 0;
}
if (!dev_open_quiet(dev)) {
log_error("Extend sanlock LV %s cannot open device.", display_lvname(lv));
return 0;
}
if (!dev_set(dev, old_size_bytes, new_size_bytes - old_size_bytes, 0)) {
log_error("Extend sanlock LV %s cannot zero device.", display_lvname(lv));
dev_close_immediate(dev);
return 0;
}
dev_flush(dev);
if (!dev_close_immediate(dev))
stack;
return 1;
}
@@ -1636,15 +1596,15 @@ int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags)
*/
log_error("Global lock failed: held by other host.");
return 0;
} else {
/*
* We don't intend to reach this. We should check
* any known/possible error specifically and print
* a more helpful message. This is for completeness.
*/
log_error("Global lock failed: error %d.", result);
return 0;
}
/*
* We don't intend to reach this. We should check
* any known/possible error specifically and print
* a more helpful message. This is for completeness.
*/
log_error("Global lock failed: error %d.", result);
return 0;
}
allow:
@@ -2117,10 +2077,6 @@ static int _lockd_lv_thin(struct cmd_context *cmd, struct logical_volume *lv,
} else if (lv_is_thin_pool(lv)) {
pool_lv = lv;
} else if (lv_is_thin_pool_data(lv)) {
/* FIXME: there should be a function to get pool lv from data lv. */
pool_lv = lv_parent(lv);
} else {
/* This should not happen AFAIK. */
log_error("Lock on incorrect thin lv type %s/%s",
@@ -2370,16 +2326,15 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
if (!_lvmlockd_connected)
return 0;
if (!lp->needs_lockd_init)
if (!lp->needs_lockd_init) {
/* needs_lock_init is set for LVs that need a lockd lock. */
return 1;
if (seg_is_cache(lp) || seg_is_cache_pool(lp)) {
} else if (seg_is_cache(lp) || seg_is_cache_pool(lp)) {
log_error("Use lvconvert for cache with lock type %s", vg->lock_type);
return 0;
}
if (!seg_is_thin_volume(lp) && lp->snapshot) {
} else if (!seg_is_thin_volume(lp) && lp->snapshot) {
struct logical_volume *origin_lv;
/*
@@ -2404,9 +2359,8 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
}
lv->lock_args = NULL;
return 1;
}
if (seg_is_thin(lp)) {
} else if (seg_is_thin(lp)) {
if ((seg_is_thin_volume(lp) && !lp->create_pool) ||
(!seg_is_thin_volume(lp) && lp->snapshot)) {
struct lv_list *lvl;
@@ -2427,9 +2381,8 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
}
lv->lock_args = NULL;
return 1;
}
if (seg_is_thin_volume(lp) && lp->create_pool) {
} else if (seg_is_thin_volume(lp) && lp->create_pool) {
/*
* Creating a thin pool and a thin lv in it. We could
* probably make this work.
@@ -2437,21 +2390,21 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
log_error("Create thin pool and thin LV separately with lock type %s",
vg->lock_type);
return 0;
}
if (!seg_is_thin_volume(lp) && lp->create_pool) {
} else if (!seg_is_thin_volume(lp) && lp->create_pool) {
/* Creating a thin pool only. */
/* lv_name_lock = lp->pool_name; */
} else {
log_error("Unknown thin options for lock init.");
return 0;
}
log_error("Unknown thin options for lock init.");
return 0;
} else {
/* Creating a normal lv. */
/* lv_name_lock = lv_name; */
}
/* Creating a normal lv. */
/* lv_name_lock = lv_name; */
/*
* The LV gets its own lock, so set lock_args to non-NULL.
*

View File

@@ -375,8 +375,8 @@ void fin_syslog(void)
void init_msg_prefix(const char *prefix)
{
if (prefix)
dm_strncpy(_msg_prefix, prefix, sizeof(_msg_prefix));
strncpy(_msg_prefix, prefix, sizeof(_msg_prefix) - 1);
_msg_prefix[sizeof(_msg_prefix) - 1] = '\0';
}
void init_indent(int indent)

View File

@@ -22,7 +22,6 @@
#include "activate.h"
#include "defaults.h"
#include "lv_alloc.h"
#include "lvm-signal.h"
/* https://github.com/jthornber/thin-provisioning-tools/blob/master/caching/cache_metadata_size.cc */
#define DM_TRANSACTION_OVERHEAD 4096 /* KiB */
@@ -36,7 +35,7 @@ const char *display_cache_mode(const struct lv_segment *seg)
seg = first_seg(seg->pool_lv);
if (!seg_is_cache_pool(seg) ||
(seg->cache_mode == CACHE_MODE_UNSELECTED))
(seg->cache_mode == CACHE_MODE_UNDEFINED))
return "";
return get_cache_mode_name(seg);
@@ -78,14 +77,13 @@ int set_cache_mode(cache_mode_t *mode, const char *cache_mode)
int cache_set_cache_mode(struct lv_segment *seg, cache_mode_t mode)
{
struct cmd_context *cmd = seg->lv->vg->cmd;
struct profile *profile = seg->lv->profile;
const char *str;
int id;
if (seg_is_cache(seg))
seg = first_seg(seg->pool_lv);
else if (seg_is_cache_pool(seg)) {
if (mode == CACHE_MODE_UNSELECTED)
if (mode == CACHE_MODE_UNDEFINED)
return 1; /* Defaults only for cache */
} else {
log_error(INTERNAL_ERROR "Cannot set cache mode for non cache volume %s.",
@@ -93,12 +91,12 @@ int cache_set_cache_mode(struct lv_segment *seg, cache_mode_t mode)
return 0;
}
if (mode != CACHE_MODE_UNSELECTED) {
if (mode != CACHE_MODE_UNDEFINED) {
seg->cache_mode = mode;
return 1;
}
if (seg->cache_mode != CACHE_MODE_UNSELECTED)
if (seg->cache_mode != CACHE_MODE_UNDEFINED)
return 1; /* Default already set in cache pool */
/* Figure default settings from config/profiles */
@@ -109,7 +107,7 @@ int cache_set_cache_mode(struct lv_segment *seg, cache_mode_t mode)
find_config_node(cmd, cmd->cft, allocation_cache_pool_cachemode_CFG))
id = allocation_cache_pool_cachemode_CFG;
if (!(str = find_config_tree_str(cmd, id, profile))) {
if (!(str = find_config_tree_str(cmd, id, NULL))) {
log_error(INTERNAL_ERROR "Cache mode is not determined.");
return 0;
}
@@ -154,30 +152,25 @@ static uint64_t _cache_min_metadata_size(uint64_t data_size, uint32_t chunk_size
return min_meta_size;
}
int update_cache_pool_params(struct cmd_context *cmd,
struct profile *profile,
uint32_t extent_size,
const struct segment_type *segtype,
unsigned attr,
uint32_t pool_data_extents,
int update_cache_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned attr,
int passed_args, uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int *chunk_size_calc_method, uint32_t *chunk_size)
{
uint64_t min_meta_size;
uint32_t extent_size = vg->extent_size;
uint64_t pool_metadata_size = (uint64_t) *pool_metadata_extents * extent_size;
uint64_t pool_data_size = (uint64_t) pool_data_extents * extent_size;
const uint64_t max_chunks =
get_default_allocation_cache_pool_max_chunks_CFG(cmd, profile);
uint64_t max_chunks =
get_default_allocation_cache_pool_max_chunks_CFG(vg->cmd, vg->profile);
/* min chunk size in a multiple of DM_CACHE_MIN_DATA_BLOCK_SIZE */
uint64_t min_chunk_size = (((pool_data_size + max_chunks - 1) / max_chunks +
DM_CACHE_MIN_DATA_BLOCK_SIZE - 1) /
DM_CACHE_MIN_DATA_BLOCK_SIZE) * DM_CACHE_MIN_DATA_BLOCK_SIZE;
if (!*chunk_size) {
if (!(*chunk_size = find_config_tree_int(cmd, allocation_cache_pool_chunk_size_CFG,
profile) * 2))
*chunk_size = get_default_allocation_cache_pool_chunk_size_CFG(cmd,
profile);
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
*chunk_size = DEFAULT_CACHE_POOL_CHUNK_SIZE * 2;
if (*chunk_size < min_chunk_size) {
/*
* When using more then 'standard' default,
@@ -185,25 +178,25 @@ int update_cache_pool_params(struct cmd_context *cmd,
*/
log_print_unless_silent("Using %s chunk size instead of default %s, "
"so cache pool has less then " FMTu64 " chunks.",
display_size(cmd, min_chunk_size),
display_size(cmd, *chunk_size),
display_size(vg->cmd, min_chunk_size),
display_size(vg->cmd, *chunk_size),
max_chunks);
*chunk_size = min_chunk_size;
} else
log_verbose("Setting chunk size to %s.",
display_size(cmd, *chunk_size));
display_size(vg->cmd, *chunk_size));
} else if (*chunk_size < min_chunk_size) {
log_error("Chunk size %s is less then required minimal chunk size %s "
"for a cache pool of %s size and limit " FMTu64 " chunks.",
display_size(cmd, *chunk_size),
display_size(cmd, min_chunk_size),
display_size(cmd, pool_data_size),
display_size(vg->cmd, *chunk_size),
display_size(vg->cmd, min_chunk_size),
display_size(vg->cmd, pool_data_size),
max_chunks);
log_error("To allow use of more chunks, see setting allocation/cache_pool_max_chunks.");
return 0;
}
if (!validate_cache_chunk_size(cmd, *chunk_size))
if (!validate_pool_chunk_size(vg->cmd, segtype, *chunk_size))
return_0;
min_meta_size = _cache_min_metadata_size((uint64_t) pool_data_extents * extent_size, *chunk_size);
@@ -217,31 +210,22 @@ int update_cache_pool_params(struct cmd_context *cmd,
if (pool_metadata_size > (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE)) {
pool_metadata_size = 2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE;
if (*pool_metadata_extents)
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Maximum supported pool metadata size is %s.",
display_size(cmd, pool_metadata_size));
display_size(vg->cmd, pool_metadata_size));
} else if (pool_metadata_size < min_meta_size) {
if (*pool_metadata_extents)
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Minimum required pool metadata size is %s "
"(needs extra %s).",
display_size(cmd, min_meta_size),
display_size(cmd, min_meta_size - pool_metadata_size));
display_size(vg->cmd, min_meta_size),
display_size(vg->cmd, min_meta_size - pool_metadata_size));
pool_metadata_size = min_meta_size;
}
if (!(*pool_metadata_extents =
extents_from_size(cmd, pool_metadata_size, extent_size)))
extents_from_size(vg->cmd, pool_metadata_size, extent_size)))
return_0;
if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) {
log_error("Size of %s data volume cannot be smaller than chunk size %s.",
segtype->name, display_size(cmd, *chunk_size));
return 0;
}
log_verbose("Preferred pool metadata size %s.",
display_size(cmd, (uint64_t)*pool_metadata_extents * extent_size));
return 1;
}
@@ -252,7 +236,7 @@ int update_cache_pool_params(struct cmd_context *cmd,
int validate_lv_cache_chunk_size(struct logical_volume *pool_lv, uint32_t chunk_size)
{
struct volume_group *vg = pool_lv->vg;
const uint64_t max_chunks = get_default_allocation_cache_pool_max_chunks_CFG(vg->cmd, pool_lv->profile);
uint64_t max_chunks = get_default_allocation_cache_pool_max_chunks_CFG(vg->cmd, vg->profile);
uint64_t min_size = _cache_min_metadata_size(pool_lv->size, chunk_size);
uint64_t chunks = pool_lv->size / chunk_size;
int r = 1;
@@ -308,7 +292,7 @@ int validate_lv_cache_create_pool(const struct logical_volume *pool_lv)
if (!dm_list_empty(&pool_lv->segs_using_this_lv)) {
seg = get_only_segment_using_this_lv(pool_lv);
log_error("Logical volume %s is already in use by %s.",
log_error("Logical volume %s is already in use by %s",
display_lvname(pool_lv),
seg ? display_lvname(seg->lv) : "another LV");
return 0;
@@ -349,30 +333,6 @@ int validate_lv_cache_create_origin(const struct logical_volume *origin_lv)
return 1;
}
int validate_cache_chunk_size(struct cmd_context *cmd, uint32_t chunk_size)
{
const uint32_t min_size = DM_CACHE_MIN_DATA_BLOCK_SIZE;
const uint32_t max_size = DM_CACHE_MAX_DATA_BLOCK_SIZE;
int r = 1;
if ((chunk_size < min_size) || (chunk_size > max_size)) {
log_error("Cache chunk size %s is not in the range %s to %s.",
display_size(cmd, chunk_size),
display_size(cmd, min_size),
display_size(cmd, max_size));
r = 0;
}
if (chunk_size & (min_size - 1)) {
log_error("Cache chunk size %s must be a multiple of %s.",
display_size(cmd, chunk_size),
display_size(cmd, min_size));
r = 0;
}
return r;
}
/*
* lv_cache_create
* @pool
@@ -410,9 +370,6 @@ struct logical_volume *lv_cache_create(struct logical_volume *pool_lv,
if (!attach_pool_lv(seg, pool_lv, NULL, NULL, NULL))
return_NULL;
if (!seg->lv->profile) /* Inherit profile from cache-pool */
seg->lv->profile = seg->pool_lv->profile;
return cache_lv;
}
@@ -432,20 +389,6 @@ int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean)
//FIXME: use polling to do this...
for (;;) {
sigint_allow();
sigint_restore();
if (sigint_caught()) {
sigint_clear();
log_error("Flushing of %s aborted.", display_lvname(cache_lv));
if (cache_seg->cleaner_policy) {
cache_seg->cleaner_policy = 0;
/* Restore normal table */
if (!lv_update_and_reload_origin(cache_lv))
stack;
}
return 0;
}
if (!lv_cache_status(cache_lv, &status))
return_0;
@@ -467,12 +410,9 @@ int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean)
log_print_unless_silent("Flushing " FMTu64 " blocks for cache %s.",
dirty_blocks, display_lvname(cache_lv));
if (cleaner_policy) {
/* TODO: Use centralized place */
sigint_allow();
usleep(500000);
sigint_restore();
continue;
}
@@ -693,26 +633,6 @@ static const char *_get_default_cache_policy(struct cmd_context *cmd)
return def;
}
/* Autodetect best available cache metadata format for a user */
static cache_metadata_format_t _get_default_cache_metadata_format(struct cmd_context *cmd)
{
const struct segment_type *segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_CACHE);
unsigned attr;
cache_metadata_format_t f;
if (!segtype ||
!segtype->ops->target_present ||
!segtype->ops->target_present(cmd, NULL, &attr)) {
f = CACHE_METADATA_FORMAT_1;
log_warn("WARNING: Cannot detect default cache metadata format, using format: %u.", f);
} else {
f = (attr & CACHE_FEATURE_METADATA2) ? CACHE_METADATA_FORMAT_2 : CACHE_METADATA_FORMAT_1;
log_debug_metadata("Detected default cache metadata format: %u.", f);
}
return f;
}
int cache_set_policy(struct lv_segment *seg, const char *name,
const struct dm_config_tree *settings)
{
@@ -720,36 +640,28 @@ int cache_set_policy(struct lv_segment *seg, const char *name,
const struct dm_config_node *cns;
struct dm_config_tree *old = NULL, *new = NULL, *tmp = NULL;
int r = 0;
struct profile *profile = seg->lv->profile;
const int passed_seg_is_cache = seg_is_cache(seg);
if (seg_is_cache(seg))
if (passed_seg_is_cache)
seg = first_seg(seg->pool_lv);
else if (seg_is_cache_pool(seg)) {
if (!name && !settings)
return 1; /* Policy and settings can be selected later when caching LV */
} else {
log_error(INTERNAL_ERROR "Cannot set cache metadata format for non cache volume %s.",
display_lvname(seg->lv));
return 0;
}
if (name) {
if (!(seg->policy_name = dm_pool_strdup(seg->lv->vg->vgmem, name))) {
log_error("Failed to duplicate policy name.");
return 0;
}
} else if (!seg->policy_name) {
if (!(seg->policy_name = find_config_tree_str(seg->lv->vg->cmd, allocation_cache_policy_CFG,
profile)) &&
} else if (!seg->policy_name && passed_seg_is_cache) {
if (!(seg->policy_name = find_config_tree_str(seg->lv->vg->cmd, allocation_cache_policy_CFG, NULL)) &&
!(seg->policy_name = _get_default_cache_policy(seg->lv->vg->cmd)))
return_0;
}
if (settings) {
if (!seg->policy_name) {
log_error(INTERNAL_ERROR "Can't set policy settings without policy name.");
return 0;
}
}
if (settings) {
if (seg->policy_settings) {
if (!(old = dm_config_create()))
goto_out;
@@ -765,26 +677,30 @@ int cache_set_policy(struct lv_segment *seg, const char *name,
if ((cn = dm_config_find_node((tmp) ? tmp->root : settings->root, "policy_settings")) &&
!(seg->policy_settings = dm_config_clone_node_with_mem(seg->lv->vg->vgmem, cn, 0)))
goto_out;
} else if (!seg->policy_settings) {
if ((cns = find_config_tree_node(seg->lv->vg->cmd, allocation_cache_settings_CFG_SECTION,
profile))) {
/* Try to find our section for given policy */
for (cn = cns->child; cn; cn = cn->sib) {
if (!cn->child)
continue; /* Ignore section without settings */
} else if (passed_seg_is_cache && /* Look for command's profile cache_policies */
(cns = find_config_tree_node(seg->lv->vg->cmd, allocation_cache_settings_CFG_SECTION, NULL))) {
/* Try to find our section for given policy */
for (cn = cns->child; cn; cn = cn->sib) {
/* Only matching section names */
if (cn->v || strcmp(cn->key, seg->policy_name) != 0)
continue;
if (cn->v || strcmp(cn->key, seg->policy_name) != 0)
continue; /* Ignore mismatching sections */
if (!cn->child)
break;
/* Clone nodes with policy name */
if (!(seg->policy_settings = dm_config_clone_node_with_mem(seg->lv->vg->vgmem,
cn, 0)))
return_0;
if (!(new = dm_config_create()))
goto_out;
/* Replace policy name key with 'policy_settings' */
seg->policy_settings->key = "policy_settings";
break; /* Only first match counts */
}
if (!(new->root = dm_config_clone_node_with_mem(new->mem,
cn->child, 1)))
goto_out;
if (!(seg->policy_settings = dm_config_create_node(new, "policy_settings")))
goto_out;
seg->policy_settings->child = new->root;
break; /* Only first match counts */
}
}
@@ -811,94 +727,17 @@ out:
return r;
}
/*
* Sets metadata format on cache pool segment with these rules:
* 1. When 'cache-pool' segment is passed, sets only for selected formats (1 or 2).
* 2. For 'cache' segment passed in we know cache pool segment.
* When passed format is 0 (UNSELECTED) with 'cache' segment - it's the moment
* lvm2 has to figure out 'default' metadata format (1 or 2) from
* configuration or profiles.
* 3. If still unselected or selected format is != 1, figure the best supported format
* and either use it or validate users settings is possible.
*
* Reasoning: A user may create cache-pool and may or may not specify CMFormat.
* If the CMFormat has been selected (1 or 2) store this in metadata, otherwise
* for an unused cache-pool UNSELECTED CMFormat is used. When caching LV, CMFormat
* must be decided and from this moment it's always stored. To support backward
* compatibility 'CMFormat 1' is used when it is NOT specified for a cached LV in
* lvm2 metadata (no metadata_format=#F element in cache-pool segment).
*/
int cache_set_metadata_format(struct lv_segment *seg, cache_metadata_format_t format)
{
cache_metadata_format_t best;
struct profile *profile = seg->lv->profile;
if (seg_is_cache(seg))
seg = first_seg(seg->pool_lv);
else if (seg_is_cache_pool(seg)) {
if (format == CACHE_METADATA_FORMAT_UNSELECTED)
return 1; /* Format can be selected later when caching LV */
} else {
log_error(INTERNAL_ERROR "Cannot set cache metadata format for non cache volume %s.",
display_lvname(seg->lv));
return 0;
}
/* Check if we need to search for configured cache metadata format */
if (format == CACHE_METADATA_FORMAT_UNSELECTED) {
if (seg->cache_metadata_format != CACHE_METADATA_FORMAT_UNSELECTED)
return 1; /* Format already selected in cache pool */
/* Check configurations and profiles */
format = find_config_tree_int(seg->lv->vg->cmd, allocation_cache_metadata_format_CFG,
profile);
}
/* See what is a 'best' available cache metadata format
* when the specifed format is other then always existing CMFormat 1 */
if (format != CACHE_METADATA_FORMAT_1) {
best = _get_default_cache_metadata_format(seg->lv->vg->cmd);
/* Format was not selected, so use best present on a system */
if (format == CACHE_METADATA_FORMAT_UNSELECTED)
format = best;
else if (format != best) {
/* Format is not valid (Only Format 1 or 2 is supported ATM) */
log_error("Cache metadata format %u is not supported by kernel target.", format);
return 0;
}
}
switch (format) {
case CACHE_METADATA_FORMAT_2: seg->lv->status |= LV_METADATA_FORMAT; break;
case CACHE_METADATA_FORMAT_1: seg->lv->status &= ~LV_METADATA_FORMAT; break;
default:
log_error(INTERNAL_ERROR "Invalid cache metadata format %u for cache volume %s.",
format, display_lvname(seg->lv));
return 0;
}
seg->cache_metadata_format = format;
return 1;
}
/*
* Universal 'wrapper' function do-it-all
* to update all commonly specified cache parameters
*/
int cache_set_params(struct lv_segment *seg,
uint32_t chunk_size,
cache_metadata_format_t format,
cache_mode_t mode,
const char *policy_name,
const struct dm_config_tree *policy_settings)
const struct dm_config_tree *policy_settings,
uint32_t chunk_size)
{
struct lv_segment *pool_seg;
struct cmd_context *cmd = seg->lv->vg->cmd;
if (!cache_set_metadata_format(seg, format))
return_0;
if (!cache_set_cache_mode(seg, mode))
return_0;
@@ -909,35 +748,16 @@ int cache_set_params(struct lv_segment *seg,
pool_seg = seg_is_cache(seg) ? first_seg(seg->pool_lv) : seg;
if (chunk_size) {
if (seg_is_cache(seg) &&
!validate_lv_cache_chunk_size(pool_seg->lv, chunk_size))
if (!validate_lv_cache_chunk_size(pool_seg->lv, chunk_size))
return_0;
pool_seg->chunk_size = chunk_size;
} else if (seg_is_cache(seg)) {
/* Chunk size in profile has priority over cache-pool chunk size */
if ((chunk_size = find_config_tree_int(cmd, allocation_cache_pool_chunk_size_CFG,
seg->lv->profile) * 2)) {
if (!validate_lv_cache_chunk_size(pool_seg->lv, chunk_size))
return_0;
if (pool_seg->chunk_size != chunk_size)
log_verbose("Replacing chunk size %s in cache pool %s with "
"chunk size %s from profile.",
display_size(cmd, pool_seg->chunk_size),
display_lvname(seg->lv),
display_size(cmd, chunk_size));
pool_seg->chunk_size = chunk_size;
}
} else if (seg_is_cache_pool(seg)) {
if (!pool_seg->chunk_size &&
/* TODO: some calc_policy solution for cache ? */
!recalculate_pool_chunk_size_with_dev_hints(pool_seg->lv,
} else {
/* TODO: some calc_policy solution for cache ? */
if (!recalculate_pool_chunk_size_with_dev_hints(pool_seg->lv, 0,
THIN_CHUNK_SIZE_CALC_METHOD_GENERIC))
return_0;
}
if (seg_is_cache(seg))
cache_check_for_warns(seg);
return 1;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -220,35 +220,19 @@ char *lvseg_segtype_dup(struct dm_pool *mem, const struct lv_segment *seg)
char *lvseg_discards_dup(struct dm_pool *mem, const struct lv_segment *seg)
{
if (lv_is_thin_pool(seg->lv))
return dm_pool_strdup(mem, get_pool_discards_name(seg->discards));
log_error("Cannot query non thin-pool segment of LV %s for discards property.",
display_lvname(seg->lv));
return NULL;
return dm_pool_strdup(mem, get_pool_discards_name(seg->discards));
}
char *lvseg_kernel_discards_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm)
{
const char *s = "";
char *ret;
thin_discards_t d;
if (lvdm->seg_status.type == SEG_STATUS_THIN_POOL) {
switch (lvdm->seg_status.thin_pool->discards) {
case DM_THIN_DISCARDS_IGNORE: d = THIN_DISCARDS_IGNORE; break;
case DM_THIN_DISCARDS_NO_PASSDOWN: d = THIN_DISCARDS_NO_PASSDOWN; break;
case DM_THIN_DISCARDS_PASSDOWN: d = THIN_DISCARDS_PASSDOWN; break;
default:
log_error("Kernel reports unknown discards status %u.",
lvdm->seg_status.thin_pool->discards);
return 0;
}
s = get_pool_discards_name(d);
}
if (lvdm->seg_status.type == SEG_STATUS_THIN_POOL)
s = get_pool_discards_name(lvdm->seg_status.thin_pool->discards);
if (!(ret = dm_pool_strdup(mem, s))) {
log_error("lvseg_kernel_discards_dup_with_info_and_seg_status: dm_pool_strdup failed.");
log_error("lvseg_kernel_discards_dup_with_info_and_seg_status: dm_pool_strdup failed");
return NULL;
}
@@ -395,15 +379,6 @@ dm_percent_t lvseg_percent_with_info_and_seg_status(const struct lv_with_info_an
}
}
break;
case SEG_STATUS_RAID:
switch (type) {
case PERCENT_GET_DIRTY:
p = dm_make_percent(s->raid->insync_regions, s->raid->total_regions);
break;
default:
p = DM_PERCENT_INVALID;
}
break;
case SEG_STATUS_SNAPSHOT:
if (s->snapshot->merge_failed)
p = DM_PERCENT_INVALID;
@@ -581,8 +556,8 @@ static char *_do_lv_origin_dup(struct dm_pool *mem, const struct logical_volume
if (uuid)
return lv_uuid_dup(mem, origin_lv);
return lv_name_dup(mem, origin_lv);
else
return lv_name_dup(mem, origin_lv);
}
char *lv_origin_dup(struct dm_pool *mem, const struct logical_volume *lv)
@@ -650,7 +625,6 @@ char *lv_modules_dup(struct dm_pool *mem, const struct logical_volume *lv)
if (!list_lv_modules(mem, lv, modules))
return_NULL;
return tags_format_and_copy(mem, modules);
}
@@ -676,8 +650,8 @@ static char *_do_lv_mirror_log_dup(struct dm_pool *mem, const struct logical_vol
if (uuid)
return lv_uuid_dup(mem, mirror_log_lv);
return lv_name_dup(mem, mirror_log_lv);
else
return lv_name_dup(mem, mirror_log_lv);
}
char *lv_mirror_log_dup(struct dm_pool *mem, const struct logical_volume *lv)
@@ -709,8 +683,8 @@ static char *_do_lv_pool_lv_dup(struct dm_pool *mem, const struct logical_volume
if (uuid)
return lv_uuid_dup(mem, pool_lv);
return lv_name_dup(mem, pool_lv);
else
return lv_name_dup(mem, pool_lv);
}
char *lv_pool_lv_dup(struct dm_pool *mem, const struct logical_volume *lv)
@@ -742,8 +716,8 @@ static char *_do_lv_data_lv_dup(struct dm_pool *mem, const struct logical_volume
if (uuid)
return lv_uuid_dup(mem, data_lv);
return lv_name_dup(mem, data_lv);
else
return lv_name_dup(mem, data_lv);
}
char *lv_data_lv_dup(struct dm_pool *mem, const struct logical_volume *lv)
@@ -775,8 +749,8 @@ static char *_do_lv_metadata_lv_dup(struct dm_pool *mem, const struct logical_vo
if (uuid)
return lv_uuid_dup(mem, metadata_lv);
return lv_name_dup(mem, metadata_lv);
else
return lv_name_dup(mem, metadata_lv);
}
char *lv_metadata_lv_dup(struct dm_pool *mem, const struct logical_volume *lv)
@@ -793,8 +767,7 @@ const char *lv_layer(const struct logical_volume *lv)
{
if (lv_is_thin_pool(lv))
return "tpool";
if (lv_is_origin(lv) || lv_is_external_origin(lv))
else if (lv_is_origin(lv) || lv_is_external_origin(lv))
return "real";
return NULL;
@@ -843,8 +816,8 @@ static char *_do_lv_convert_lv_dup(struct dm_pool *mem, const struct logical_vol
if (uuid)
return lv_uuid_dup(mem, convert_lv);
return lv_name_dup(mem, convert_lv);
else
return lv_name_dup(mem, convert_lv);
}
char *lv_convert_lv_dup(struct dm_pool *mem, const struct logical_volume *lv)
@@ -879,8 +852,8 @@ static char *_do_lv_move_pv_dup(struct dm_pool *mem, const struct logical_volume
if (uuid)
return pv_uuid_dup(mem, pvseg->pv);
return pv_name_dup(mem, pvseg->pv);
else
return pv_name_dup(mem, pvseg->pv);
}
}
@@ -1098,7 +1071,7 @@ int lv_raid_healthy(const struct logical_volume *lv)
}
if (!seg_is_raid(raid_seg)) {
log_error(INTERNAL_ERROR "%s on %s is not a RAID segment.",
log_error("%s on %s is not a RAID segment",
raid_seg->lv->name, lv->name);
return 0;
}
@@ -1106,8 +1079,12 @@ int lv_raid_healthy(const struct logical_volume *lv)
if (!lv_raid_dev_health(raid_seg->lv, &raid_health))
return_0;
if (lv_is_raid(lv))
return (strchr(raid_health, 'D')) ? 0 : 1;
if (lv_is_raid(lv)) {
if (strchr(raid_health, 'D'))
return 0;
else
return 1;
}
/* Find out which sub-LV this is. */
for (s = 0; s < raid_seg->area_count; s++)
@@ -1127,19 +1104,6 @@ int lv_raid_healthy(const struct logical_volume *lv)
return 1;
}
/* Helper: check for any sub LVs after a disk removing reshape */
static int _sublvs_remove_after_reshape(const struct logical_volume *lv)
{
uint32_t s;
struct lv_segment *seg = first_seg(lv);
for (s = seg->area_count -1; s; s--)
if (seg_lv(seg, s)->status & LV_REMOVE_AFTER_RESHAPE)
return 1;
return 0;
}
char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm)
{
const struct logical_volume *lv = lvdm->lv;
@@ -1291,7 +1255,7 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
if (((lv_is_thin_volume(lv) && (seg = first_seg(lv)) && seg->pool_lv && (seg = first_seg(seg->pool_lv))) ||
(lv_is_thin_pool(lv) && (seg = first_seg(lv)))) &&
(seg->zero_new_blocks == THIN_ZERO_YES))
seg->zero_new_blocks)
repstr[7] = 'z';
else
repstr[7] = '-';
@@ -1305,8 +1269,6 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
repstr[8] = 'p';
else if (lv_is_raid_type(lv)) {
uint64_t n;
char *sync_action;
if (!activation())
repstr[8] = 'X'; /* Unknown */
else if (!lv_raid_healthy(lv))
@@ -1314,17 +1276,8 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
else if (lv_is_raid(lv)) {
if (lv_raid_mismatch_count(lv, &n) && n)
repstr[8] = 'm'; /* RAID has 'm'ismatches */
else if (lv_raid_sync_action(lv, &sync_action) &&
!strcmp(sync_action, "reshape"))
repstr[8] = 's'; /* LV is re(s)haping */
else if (_sublvs_remove_after_reshape(lv))
repstr[8] = 'R'; /* sub-LV got freed from raid set by reshaping
and has to be 'R'emoved */
} else if (lv->status & LV_WRITEMOSTLY)
repstr[8] = 'w'; /* sub-LV has 'w'ritemostly */
else if (lv->status & LV_REMOVE_AFTER_RESHAPE)
repstr[8] = 'R'; /* sub-LV got freed from raid set by reshaping
and has to be 'R'emoved */
} else if (lvdm->seg_status.type == SEG_STATUS_CACHE) {
if (lvdm->seg_status.cache->fail)
repstr[8] = 'F';

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